파이토치를 이용한 경사하강법과 단순선형회귀분석

Sung Dong Kim·2021년 7월 17일
0

ai

목록 보기
3/3

파이토치에서 경사하강법을 이용한 단순선형회귀분석을 하는 방법을 알아보자

import torch

x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[2], [4], [6]])

우선 y = 2x 라는 아주 간단한 선형관계를 가진 데이터를 준비한다.

W = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)

가중치는 하나일 것이므로 1의 shape를 가진 0 토치 텐서 변수를 만들어준다. 얘는 두 개의 파라미터를 받는데 모양과 학습 가능 여부를 뜻하는 requires_grad이다.

편향 b는 사실 0일 것이므로 없어도 되지만 연습삼아 들어가있다.

optimizer = torch.optim.SGD([W, b], lr=0.01)

파이토치의 torch.optim 안에는 여러가지 옵티마이저들이 들어있다. 모델을 컴파일 할 때 옵티마이저와 학습률을 정해주는 텐서플로우와 다르게 옵티마이저를 독립적으로 정의해줄 때 최적화할 변수와 학습률을 미리 정해준다.

epochs = 1000

for i in range(epochs):
    hyphothesis = x_train * W + b
    cost = torch.mean((hyphothesis - y_train) ** 2)

    optimizer.zero_grad() # 옵티마이저의 모든 변수를 0으로 초기화
    cost.backward() # 변수의 손실함수에 대한 기울기를 계산
    optimizer.step() # gradient descent 실행
    # 이 세 줄은 붙어 다니는 경우가 많다.

다음은 에포크만큼 훈련을 반복해주면 된다.
매 훈련 스텝마다 우리의 가설 함수(회귀식)와 비용(여기선 MSE)를 정의해주고 옵티마이저를 0으로 초기화한 뒤 비용함수를 변수들로 미분하고 경사하강을 실행한다.

x_train = torch.FloatTensor([
                             [73, 80, 75],
                             [93, 88, 93],
                             [89, 91, 90],
                             [96, 98, 100],
                             [73, 66, 70]
])

y_train = torch.FloatTensor([
                             [152], [185], [180], [196], [142]
])

W = torch.zeros((3, 1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)

epochs = 100

optimizer = torch.optim.SGD([W, b], lr=1e-5)

for i in range(epochs):
    # hyphothesis = x_train[0] * w1 + x_train[1] * w2 + x_train[2] * w3 + b # 가장 단순한 방법
    hyphothesis = x_train.matmul(W) + b # 행렬곱인 matmul로 간단하게 작성
    cost = torch.mean((hyphothesis - y_train) ** 2)
    
    optimizer.zero_grad()
    cost.backward()
    optimizer.step()

다중회귀분석은 앞에꺼를 그냥 확장만 해주면 된다.

torch.nn.Module, torch.nn.functional을 이용한 리팩토링

torch.nn.Module은 신경망 모델을 클래스형으로 만들 때 계속 상속하게 될 기본 클래스이다.

nn.functional (F라는 네임스페이스로 하는 것이 관행) 안에는 여러 가지 손실함수를 포함한 다양한 함수들이 들어있다.

위의 식을 nn.Modulenn.functional을 이용하여 바꾸면 다음과 같이 된다.

# 훈련 데이터셋 생략(위와같음)
import torch.nn as nn
import torch.nn.functional as F

class MLR(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(3, 1)

    def forward(self, x):
        return self.linear(x)
 

cost = F.mse_loss(hyphothesis, y_train)

optimizer = torch.optim.SGD([W, b], lr=1e-5)
model = MLR()

for i in range(epochs):
    hyphothesis = model(x_train)
    cost = F.mse_loss(hyphothesis, y_train)

    optimizer.zero_grad()
    cost.backward()
    optimizer.step()

MLR이라는 nn.Module 클래스를 상속한 클래스에서는 __init__에서 층들을 초기화해주고 forward 메서드는 모델이 순전파될 때 자동으로 실행된다.

nn.Linear 를 사용하면 선형 회귀식을 일일히 세울 필요 없이 입력 차원과 출력 차원을 정해주면 자동으로 선형 회귀식을 만들 수 있다.

referance
https://tutorials.pytorch.kr/beginner/nn_tutorial.html#nn-module

profile
notion으로 이사갔어요

0개의 댓글