먼저 필자는 Embedded SW개발로 6~7년차이며,
AI 도메인에서 일한지는 1년 정도의 경력이라고 보면된다.
그간 일하면서 Tensorflow와 Pytorch를 번갈아 사용했는데
이번 기회에 Pytorch만을 사용하게 되면서 정리하려 한다.
딥러닝 파이토치의 전체 시나리오를 나타내는 자료다.
Autograd-자동미분
Autograd 패키지에 대해 알아보겠습니다😃
PyTorch의 모든 신경망의 중심에는 autograd 패키지가 있다. 먼저 이것을 가볍게 살펴본 뒤, 첫 번째 신경망을 학습시켜보겠다.(주의! 가볍지 않을 수 있음😑)
autograd패키지는 Tensor의 모든 연산에 대해 자동 미분을 제공한다. 이는 실행-기반-정의(define-by-run)프레임워크로, 코드를 어떻게 작성하여 실행하느냐에 따라 역전파가 정의된다는 뜻이며, 역전파는 학습 과정의 매 단계마다 달라진다.
😃 더 간단한 용어로 몇 가지 예를 살펴보자.
Tensor
📝Note
Tensor 클래스
- 패키지의 중심에는 torch.Tensor 클래스가 있다. 만약 .requires_grad속성을 True로 설정하면, 그 tensor에서 이뤄진 모든 연산들을 추적(track)하기 시작한다.
.requires_grad=True
<- 뒤에서 많이 보게 될 것이다.- 계산이 완료된 후 .backward()를 호출하여 모든 변화도(gradient)를 자동으로 계산할 수 있다. 이 Tensor의 변화도는 .grad 속성에 누적된다.
- Tensor가 기록을 추적하는 것을 중단하려면, .detach()를 호출하여 연산 기록으로부터 분리(detach)하여 이후 연산들이 추적되는 것을 방지할 수 있다.
- 기록을 추적하는 것과 메모리를 사용하는 것을 방지하기 위해, 코드 블럭을 with torch.no_grad():로 감쌀 수 있다. 특히 변화도(gradient)는 필요 없지만, requires_grad=True가 설정되어 학습 가능한 매개변수를 갖는 모델을 평가(evaluate)할 때 유용하다.
Function 클래스
- Autograd 구현에서 매우 중요한 클래스가 하나 더 있다. 바로 Function 클래스이다.
- Tensor와 Function은 서로 연결되어 있으며, 모든 연산 과정을 부호화(encode)하여 순환하지 않는 그래프(acyclic graph)를 생성한다. 각 tensor는 .grad_fn속성을 갖고 있는데, 이는 Tensor를 생성한 Function을 참조하고 있다.(단, 사용자가 만든 Tensor는 예외로, 이 때 grad_fn은 None)이다.
🤨 이 말은 도통 설명만 들어서 모르겠군... - 도함수를 계산하기 위해서는 Tensor의 .backward()를 호출하면 된다. 만약 Tensor가 스칼라(scalar)인 경우(예. 하나의 요소 값만 갖는 등) 에는 인자를 정해줄 필요가 없다. 하지만 여러 개의 요소를 갖고 있을 때는 tensor의 모양을 gradient의 인자로 지정할 필요가 있다.
Tutorial
👨🏻💻 Tutorial Start!
import torch
torch를 생성하고 requires_grad=True를 설정하여 연산을 기록한다.
x = torch.ones(2, 2, requires_grad=True) # 요소값이 1인 2x2행렬을 선언한다.
print(x)
tensor([[1., 1.],
[1., 1.]], requires_grad=True)
tensor에 연산을 수행한다. requires_grad=True를 설정했기 때문에 연산을 기록한다.
y = x + 2
print(y)
tensor([[3., 3.],
[3., 3.]], grad_fn=<AddBackward0>)
y는 연산의 결과로 생성된 것이므로 grad_fn을 갖는다
grad_fn이 생성된다.
print(y.grad_fn)
<AddBackward0 object at 0x000001EBCC2EC208>
y에 다른 연산을 수행한다.
z = y * y * 3
out = z.mean()
print(z, out)
tensor([[27., 27.],
[27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)
.requires_grad(...)
등장
.requires_grad(...)는 기존 Tensor의 requires_grad 값을 바꿔치기 (in-place)하여 변경한다. 입력값이 지정되지 않으면 기본값은 False이다.
🤷🏻♂️ 뭔 말이냐... 20.02.19.Wed pm4:43
아래의 예제를 통해 살펴보자 pm6:52
a = torch.randn(2, 2) # standard normal distribution (2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True) # .requires_grad(...)는 기존 Tensor의 requires_grad 값을 바꿔치기(in-place)하여 변경한다.
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn) # a.requires_grad_(True)로 변경해줬기 떄문에 이제 추적이 되는거다.
False
True
<SumBackward0 object at 0x000001EBCC32D908>
🤔 Q1. requires_grad(...)함수가 False일 때와 True일 때, 무엇이 다른 걸까?
🤔 Q2. grad_fn은 뭔가...?
✍️ A1. requires_grad=True를 설정하면 연산을 기록할 수 있다. True일 때, 연산을 기록할 수 있다면 False일 때는 연산을 기록할 수 없다는 것이겠지!
✍️ A2. requires_grad=True로 설정한 변수로 다른 연산을 할 경우 생성되는 것 같다.(확실하지는 않다.)
Reference
🙆♂️ Updata(20.02.20.Thur) .requires_grad=True Tensor로 계산한 Funcion을 참조하는 것이다
출처: https://deepinsight.tistory.com/84 [Steve-Lee's Deep Insight:티스토리]
'개발자 > AI' 카테고리의 다른 글
[PyTorch] Dataset 과 Dataloader (0) | 2022.11.27 |
---|---|
ResNet 논문 리뷰[퍼옴] (0) | 2022.08.07 |