본문 바로가기
Python

파이토치, 미분 자동추적 기능 (Autograd) 에 대하여

by 슬통이 2020. 7. 18.
반응형

예제 함수

\(n\) 개의 데이터 \(x_1,..., x_n\)이 주어졌다고 할 때, 우리는 다음의 함수 \(f\)를 정의 할 수 있다.

\[ y = f(\beta) = \frac{1}{n}\sum_{i=1}^{n}(x_i - \beta)^2 \]

위의 함수는 통계학에서는 유명한 함수인데, 왜냐하면 데이터의 평균, 즉 표본 평균이 위의 함숫값을 최소화시키는 함수이기 때문이다. 오늘은 이 함수를 통하여 파이 토치의 auto.grad 기능에 대하여 알아보고자 한다.

데이터 생성

파이토치를 불러 데이터를 생성한다.

import torch

# set seed
torch.random.manual_seed(1234)
## <torch._C.Generator object at 0x7f8146cf0910>
data = torch.rand(10) * 10
data
## tensor([0.2898, 4.0190, 2.5984, 3.6664, 0.5830, 7.0064, 0.5180, 4.6814, 6.7381,
##         3.3146])

코드에서 쓰인 함수 두 개를 알아보자.

  • torch.rand(): R에서 runif() 함수와 같다. Uniform 분포에서 원하는 수만큼 숫자를 뽑는다.
  • .manual_seed(): R에서 set.seed() 함수와 같다. 시뮬레이션할 때 시드를 고정하는 역할을 한다.

함수 설정

우리가 선언하고자하는 함수는 베타의 함수이고, 우리는 이 베타값에 대응하는 기울기 값 (gradient)을 알고자 한다. 파이 토치에는 기울기 값을 자동으로 계산해주는 기능이 있는데, 뉴럴 넷의 학습이 백 프랍 (backpropagation)을 이용하여 구현되기 때문에 딥러닝 라이브러리의 핵심 패키지 중 하나라고 할 수 있다.

기울기 값을 추적할 텐서를 선언할 때 requires_grad = True 옵션을 붙여줘서 선언하면 끝이다. 우리는 베타에 대한 그레이디언트를 구하고 싶으므로, 다음과 같이 선언한다.

beta = torch.rand(1, requires_grad=True)
beta
## tensor([0.7837], requires_grad=True)

베타 텐서가 기울기 추적 옵션을 달고 있어서, 이와 관련되어 생성되는 모든 텐서에 기울기 추적 옵션 grad_fn 태그가 달려서 생성된다. 다음과 같이 y를 정의를 하면, y에도 역시 grad_fn이 붙어서 생성되는 것을 알 수 있다.

y = torch.mean((data - beta)**2)
y
## tensor(11.8199, grad_fn=<MeanBackward0>)

기울기 값 계산 - w/o Autograd

먼저 파이토치를 사용해서 기울기 값 계산을 하기에 앞서, 계산 결과를 구해보자. \(y\)\(\beta\)에 대하여 미분하면 다음과 같다.

\[ \begin{align*} f'(\beta) & =\frac{d}{d\beta}\left(\frac{1}{n}\sum_{i=1}^{n}\left(x_{i}-\beta\right)^{2}\right)\\ & =\frac{1}{n}\sum_{i=1}^{n}\frac{d}{d\beta}\left(x_{i}-\beta\right)^{2}\\ & =-\frac{1}{n}\sum_{i=1}^{n}2\left(x_{i}-\beta\right) \end{align*} \]

현재 주어진 베타값은 다음과 같다.

beta.item()
## 0.7837080359458923

따라서 우리가 구하는 정답은 다음과 같을 것이다.

answer = -torch.mean(2 * (data - beta))
answer.item()
## -5.1156110763549805

기울기값 계산 - w/ Autograd

파이 토치는 우리가 계산한 위의 과정들을 자동으로 해준다. 기울기 값 계산을 위해서 해야 할 일은 기울기 계산을 activate 해주는 함수를 실행시켜주기만 하면 된다. y에 대한 베타의 기울기값을 구하는 것이므로, 다음과 같이 .backward()를 이용하여 backward prop. 을 시켜준다.

y.backward()

이 함수를 실행시키면, 중간 과정에 생성된 모든 텐서에 대하여 기울기 벡터 값들을 구할 수 있다. auto grad가 구한 베타의 기울기 값이 우리가 구한 값과 동일한지 확인해보자.

beta.grad.item()
## -5.1156110763549805

Auto grad 패키지 관련 알아두어야할 함수들

기울기 자동 추적기능을 사용한다는 것은 메모리를 많이 차지한다는 이야기이다. 따라서 우리가 생각하는 변수에 대한 것에만 옵션을 붙여야 하고, 더 이상 필요가 없어지면 기능을 꺼주기도 해야 할 것이다.

.detach_()

현재 y는 기울기 자동추적 기능이 붙어있다. 우리가 y를 사용해서 텐서를 생성하면 그 역시 옵션이 딸려 생성이 될 테지만, y 텐서 이후부터는 추적 기능을 사용하고 싶지 않을때, .detach()를 사용하자.

z = y ** 2
z
## tensor(139.7109, grad_fn=<PowBackward0>)
z.detach_()
## tensor(139.7109)

.requires_grad_()

자동 추적 기능이 없이 생성된 텐서에 추적 기능을 붙일 때에는. requires_grad_() 함수를 사용한다.

a = torch.randn(2, 2)
a
## tensor([[-1.2923, -0.0366],
##         [-0.7331,  0.2195]])
a.requires_grad
## False
a.requires_grad_(True)
## tensor([[-1.2923, -0.0366],
##         [-0.7331,  0.2195]], requires_grad=True)
a.requires_grad
## True
z = y * y * 3
out = z.mean()
z
## tensor(419.1328, grad_fn=<MulBackward0>)
out
## tensor(419.1328, grad_fn=<MeanBackward0>)

.requires_grad() 기능

a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
a
## tensor([[-5.0913,  1.3896],
##         [ 5.5178, -2.8634]])
a.requires_grad
## False
a.requires_grad_(True)
## tensor([[-5.0913,  1.3896],
##         [ 5.5178, -2.8634]], requires_grad=True)
a.requires_grad
## True
b = (a * a).sum()
b.grad_fn
## <SumBackward0 object at 0x7f81979ea400>

with torch.no_grad()

y 계산을 할 경우, 기울기 추적 기능이 붙어있기 때문에 메모리가 그냥 계산을 할 경우보다 더 소모된다. 지금이야 함수가 작아서 문제가 없지만, 뉴럴 넷의 크기가 큰 경우에는 문제가 달라진다. 만약 특정 코드를 실행함에 있어서 추적 기능을 떼고 계산하고 싶은 경우, with torch.no_grad()가 유용하다.

y
## tensor(11.8199, grad_fn=<MeanBackward0>)
y**2
## tensor(139.7109, grad_fn=<PowBackward0>)
with torch.no_grad():
    y**2
## tensor(139.7109)

아래는 현재 검색 가능한 파이토치 딥러닝 책 광고입니다! 파트너스 활동을 통해서 일정액의 수수료를 받을 수 있다고 하네요.ㅎㅎ 언젠가 제가 쓰는 이 블로그도 저 자리에 끼어있었으면 좋겠네요ㅎㅎ 밑에 책들은 한번 사서 읽어보고, 리뷰를 올려보도록 하겠습니다. =]

 

파이토치 첫걸음:딥러닝 기초부터 RNN 오토인코더 GAN 실전 기법까지, 한빛미디어 펭귄브로의 3분 딥러닝 파이토치맛:PyTorch 코드로 맛보는, 한빛미디어 딥러닝에 목마른 사람들을 위한 PyTorch:개인용 GPU 학습 서버 구축부터 딥러닝까지, 비제이퍼블릭 PyTorch로 시작하는 딥러닝:딥러닝 기초에서 최신 모던 아키텍처까지, 에이콘출판 [제이펍] 파이토치 첫걸음

반응형

댓글