Real Late Starter

[PyTorch] 2. Autograd & Variable 본문

PyTorch

[PyTorch] 2. Autograd & Variable

조슈아박 2020. 1. 18. 21:38

1. Autograd

autograd 패키지는 Tensor의 모든 연산에 대해 자동 미분을 제공합니다. 이는 실행-기반-정의(define-by-run) 프레임워크로, 이는 코드를 어떻게 작성하여 실행하느냐에 따라 역전파가 정의된다는 뜻이며, 역전파는 학습 과정의 매 단계마다 달라집니다. 
- PyTorch 공식 튜토리얼

Autograd : automatic differentitaion

  • Autograd는 Auto Gradient의 약자로써 미분값을 자동으로 계산해주는 기능이다.
  • 자동 계산을 위해서 사용하는 변수는 torch.autograd 패키지 안에 있는 Variable를 사용해야된다. 
autograd 패키지는 Tensor로 수행한 모든 연산에 대하여 자동-미분(Autimatic differentiation) 기능을 제공합니다. autograd는 실행 시점에 정의되는(define-by-run) 프레임워크입니다. 이것은 코드가 어떻게 실행되는가에 따라서 역전파(backprop)가 정의됨을 의미합니다. 즉 반복마다1 역전파가 달라질 수 있다는 것을 의미합니다. - http://taewan.kim/trans/pytorch/tutorial/blits/02_autograd/

 

2. Variable

import torch
from torch.autograd import Variable
a = torch.rand(5)
a = Variable(a)
autograd.Variable은 autograd 패키지의 핵심 클래스입니다. Variable 클래스는 Tensor를 감싸고 있으며, Tensor에 정의된 거의 모든 연산을 지원합니다. 모든 계산을 마친 후에 .backward()를 호출하면, 자동으로 모든 기울기가 계산됩니다.
Variable 객체의 .data 속성으로 Tensor의 실제 데이터에 접근할 수 있습니다. Variable에 대한 기울기는 .grad 속성에 저장됩니다.

autograd 구현에 있어서 중요한 클래스가 하나 더 있습니다. 바로 Function 입니다.
Variable과 Function 클래스는 상호 연결되어 있고 비순환 그래프를 구성합니다. 연산을 위한 완전한 히스토리를 담고 있습니다. 각 Variable 객체에는 .grad_fn 속성이 있습니다. 이 속성은 해당 Variable 객체를 생성하는 Function 객체를 참조합니다. (예외 상황, Variable을 사용자가 직접 생성한 경우에는 grad_fn이 값은 None입니다.)
미분계수를 계산해야 한다면, Variable 객체의 .backward()를 호출합니다. Variable이 스칼라 일 경우(한 개의 요소만을 갖는 상황)에는, backward()에 별도 인자를 지정할 필요가 없습니다. 이와 다르게 여러 요소를 갖는다면, 텐서의 크기를 gradient 인수로 지정해야 합니다.

 

autograd.Variable은 3가지로 구성되어있다. 

  • data : Tensor 형태의 데이터가 담기는 곳이다. 선언한 Tensor Value들이 저장된다.
  • grad : Data가 거쳐온 Layer에 대한 미분값이 축적된다. Update를 위한 Gradient Descent Value가 저장된다.
  • grad_fn : 미분 값을 계산한 함수에 대한 정보가 들어간다. 어떤 연산에 대한 backward를 진행했는지가 저장된다.

위의 코드에서 requires_grad = True가 의미하는 것은 a 변수가 gradient 값이 필요하다는 것을 의미한다.

여기서 equires_grad = True로 선언해주지 않으면 gradient값이 필요가 없다고 인식하기 때문에 꼭 넣어줘야 한다.

이번에는 autograd.Variable을 구성하고 있는 data, grad, grad_fn을 확인해본다.

지금은 아무런 연산을 진행하지 않았기 때문에 grad와 grad_fn은 None으로 나오게된다.

 

이어서 a를 가지고 b와 c를 선언하고 out을 만들어준다. 다음으로 out에 backward를 진행해준다.

이것이 의미하는 것은 지금까지 선언한 변수들이 a→b→c→out으로 변수들을 만들어줬기 때문에 backpropagation으로 미분값을 계산하는 것이다.

 

out.backward()를 수행하게 되면 grad가 변경된다. grad_fn이 None으로 나오는 이유는 a가 직접적으로 수행한 연산은 없기 때문에 None으로 나타나는 것이다. gradient를 계산할 함수가 없기 때문이다.

 

b에 대한 데이터는 a + 2였기 때문에 전부 3으로 들어가 있다. grad는 None인데 gradient가 필요하지 않았기 때문이다.

b.grad_fn은 AddBackward0라고 되어있는데, b가 a + 2였기 때문에 연산에 대한 내용을 담고있는 것이다.

 

c에 대한 것을 보면 grad_fn이 PowBackward0로 되어있고 out의 grad_fn은 SumBackward0으로 나타난다. c는 제곱이였고 out은 sum이기 때문에 위와 같이 나타나는 것이다.