데알못정을

pytorch-SGD(확률적 경사하강법 구현) 본문

Coding

pytorch-SGD(확률적 경사하강법 구현)

쩡을이 2022. 9. 30. 17:15
728x90
  • 파이토치의 구성
 
torch numpy와 같은 구성
torch.autograd 자동 미분을 위한 함수 포함
torch.nn 신경망을 구축하기 위한 다양한 데이터 구조나 레이어등이 정의돼 있다.(활성함수, MSEloss 등)
torch.optim SGD(확률적 경사하강법) 을 중심으로 한 파라미터 최적화 알고리즘이 구현돼 있다
torch.utils.data SGD의 반복 연산을 실핼할 때 사용하는 미니 배치용 유틸리티 함수가 포함돼 있다.
 
1. torch.nn , optim 모듈을 사용하지 않고 수동으로 SGD를 구현하기
 
import torch

y = 1 + 2x_1 + 3x_2 #우리가 만들 함수
w_true = torch.Tensor([1,2,3]) # 정답 파라미터
X = torch.cat([torch.ones(100,1),torch.randn(100,2)],axis = 1) #X데이터 생성

y = torch.mv(X, w_true) #y의 실제값
w = torch.randn(3,requires_grad=True) #추정할 w 값, requires_grad=True 를 해야 w로 미분이 가능함

"""추정해야할 w와 학습률을 정의 해준다."""
gamma = 0.1 #학습률

# 경사하강법
losses = []
for epoc in range(100):
    w.grad = None
    y_pred = torch.mv(X, w)
    loss = torch.mean((y - y_pred)**2)
    loss.backward() # w로 loss를 미분 한다는 뜻(아까 requires_grad = True 이거랑 커플)
    w.data = w.data-gamma*w.grad.data 
    losses.append(loss.item())
이렇게 하면 수동으로 경사하강법을 구현할 수 있다. 이제 정답이 맞는지 잘 작동했는지 확인하기 위해 랜덤 데이터 3개로 채웠던 w가 실제 파라미터인 [1, 2, 3]과 동일한지, loss가 줄어 들었는지 확인해야 한다.
 
loss가 시행횟수가 추가되면서 0에 가까워지고 있고, 랜덤 데이터로 채웠던 w도 1, 2, 3에 정확히 맞아 떨어졌으므로
경사하강법이 잘 작동됬음을 확인할 수 있다.
 
2. torch.nn , optim 모듈을 사용해서 자동으로 SGD를 구현하기
from torch import nn, optim

net = nn.Linear(in_features=3, out_features=1, bias = False) # 입력차원 3, 아웃풋 1, 절편 = 0

optimizer = optim.SGD(net.parameters(), lr=0.1) # 파라미터를 전달해서 sgd 수행
loss_fn = nn.MSELoss() #loss 정의

losses=[]
for epoc in range(100):
    optimizer.zero_grad() #계산된 경사 값 초기화
    y_pred = net(X) loss = loss_fn(y_pred.view_as(y),y)
    loss.backward() #미분
    optimizer.step() #경사 갱신
    losses.append(loss.item())
loss가 시행횟수가 추가되면서 0에 가까워지고 있고, 랜덤 데이터로 채웠던 w도 1, 2, 3에 정확히 맞아 떨어졌으므로 이 방법 역시 경사하강법이 잘 작동됬음을 확인할 수 있다. 확실히 모듈을 쓰니까 코드가 짧고 쉽다. 잘 활용해야겠다.
728x90
Comments