신경망을 학습할 때 가장 자주 사용되는 알고리즘은 역전파 입니다.
이 알고리즘에서, 매개변수 (모델가중치)는 주어진 매개변수에 대한 손실 함수의 변화도(gradient)에 따라 조정됩니다.
-역전파: 먼저 계산 결과와 정답의 오차를 구해 이 오차에 관여하는 값들의 가중치를 수정하여 오차가 적어지는 방향으로 일정 횟수를 반복해 수정하는 방법
-가중치: 처음 들어오는 데이터에서 다음 노드로 넘어갈 때 모두 같은 값이면 계속 같은 값이 나올 수 밖에 없다. 각기 다르게 곱해야 한다는 것이 바로 가중치 입니다. 값을 변화시켜주는 것 입니다.
이러한 변화도를 계산하기위해 Pytorch는 torch.autograd
라고 불리는 자동 미분 엔진이 내장되어 있습니다
- 이는 모든 계산 그래프에 대한 변화도의 자동 계산을 지원합니다.
입력 x
, 매개변수 w
와 b
, 그리고 일부 손실 함수가 있는 가장 간단한 단일 계층 신경망을 가정하겠습니다.
코드
import torch
x = torch.ones(5) # input tensor
y = torch.zeros(3) # expected output
w = torch.randn(5, 3, requires_grad=True)
b = torch.randn(3, requires_grad=True)
z = torch.matmul(x, w)+b
loss = torch.nn.functional.binary_cross_entropy_with_logits(z, y)
requires_grad = True
는 자동미분 여부입니다. True면 자동미분을 하는 것을 의미합니다.bias
편향입니다matmul
의 경우 행렬 곱을 의미합니다.loss
변수가 손실함수 값을 도출해냅니다. binary_cross_entropy_with_logits 여기서 binary_cross_entropy가 손실 함수이번에 볼 코드는 연산 그래프를 정의합니다.
정의되는 연산 그래프
이 신경망에서 w
와 b
는 최적화를 해야하는 매개변수 입니다. 따라서 이러한 변수들에 대한 손실 함수의 변화도를 계산할 수 있어야 합니다.
-이를 위해 해당 텐서에 requires_grad
속성을 설정합니다.
-그림의 z는 타겟값, CE는 손실 값으로 보면됨
requires_grad
의 값은 텐서를 생성할 때 설정하거나, 나중에 x.requiresgrad(True) 메서드를 사용하여 나중에 설정핧 수도 있음
연산 그래프를 구성하기 위해 텐서에 적용하는 함수는 사실 Fuction
클래스의 객체입니다.
-이 객체는 순전파 방향으로 함수를 계산하는 방법과, 역전파 단께에서 도함수(derivative)를 계산하는 방법을 알고 있습니다.
-역방향 전파 함수에 대한 참조는 텐서의 grad_fn
속성에 저장됩니다.
Function
에 대한 자세한 정보는 Function 이 문서에서 확인 가능합니다.-코드
print(f"Gradient function for z = {z.grad_fn}")
print(f"Gradient function for loss = {loss.grad_fn}")
-결과
x
와 y
의 일부 고정값에서 loss.backward
를 호출한 다음 w.grad
와 b.grad
에서 값을 가져옵니다.-코드
loss.backward()
print(w.grad)
print(b.grad)
-결과
requires_grad=True
인 모든 텐서들은 연산 기록을 추적하고 변화도 계산을 지원합니다. torch.no_grad()
로 둘러싸 더이상 연산 추적을 불가능하게 만들어서 False가 나옵니다. 블록으로 둘러싸서 연산 추적을 멈출 수 있습니다.-코드
z = torch.matmul(x, w)+b
print(z.requires_grad)
with torch.no_grad():
- z = torch.matmul(x, w)+b
print(z.requires_grad)
requires_grad=True
로 정의 했기에 True로 나오고torch.no_grad()
로 둘러싸 더이상 연산 추적을 불가능하게 만들어서 False가 나옵니다.-결과
detach()
메소드를 사용하는 것 입니다.-코드
z = torch.matmul(x, w)+b
z_det = z.detach()
print(z_det.requires_grad)
-결과
-순전파 단계에서 autograd는 다음 두 가지 작업을 동시에 수행합니다.
-역전파 단계는 DAG의 root에서 .backward()
가 호출될 때 시작됩니다. autograd
는 이때
.grad_fn
으로부터 변화도를 계산하고.grad
속성에 계산 결과를 쌓고** Pytorch에서 DAG들은 동적입니다.