[Ch03] 04. nn.Module로 구현하는 선형회귀

SoYeong Gwon·2022년 6월 14일
0

DeepLearning Introduction

목록 보기
1/12
post-thumbnail
본 게시글은 다음 링크(https://wikidocs.net/book/2788)의 wiki docs를 참고하여 작성되었습니다.
  • 파이토치에서 이미 구현되어 제공되는 함수를 불러오는 것으로 쉽게 선형회귀모델을 구현.
  • 파이토치에서 사용
    • 선형 회귀 모델: nn.Linear()
    • 평균 제곱오차: nn.functional.mse_loss()

1. 단순 선형 회귀 구현하기

(1) 필요한 패키지 import 및 초기화

import torch
import torch.nn as nn
import torch.nn.functional as F

torch.manual_seed(1)

torch.manual_seed(1)

Sets the seed for generating random numbers. Returns a torch.Generator object.
난수를 생성할때, 고정된 값을 얻을 수 있도록 seed를 고정시키는 함수
주로 초기화 작업에서 사용됨.


(2) 훈련데이터 선언

#w=2, b=0인 모델
x_train=torch.FloatTensor([[1],[2],[3]])
y_train=torch.FloatTensor([[2],[4],[6]])
  • 예측 모델의 가중치(w)를 2, 편향(b)을 0으로 고정하였음.

(3) 모델 선언 및 초기화

# 모델을 선언 및 초기화
model=nn.Linear(1,1)
  • 하나의 입력 xx에 대해서 하나의 출력 yy를 예측하는 모델
  • input_dim은 1, output_dim은 1
print(list(model.parameters())) #랜덤 초기화 됨 
  • model.parameters 함수로 모델의 가중치(w)와 편향(b)을 확인할 수 있음.

(4) 최적화: 경사하강법으로

nb_epochs=2000
for epoch in range(nb_epochs+1):
    # H(x)
    prediction=model(x_train)
    
    #cost
    cost=F.mse_loss(prediction,y_train) # 파이토치에서 제공하는 평균 제곱 오차 함수 

    # cost로 H(x) 개선
    optimizer.zero_grad()
    cost.backward() 
    optimizer.step()
    
    if epoch % 100==0:
        print('Epoch {:4d}/{} Cost: {:.6f}'.format(epoch,nb_epochs,cost.item()))

points: 최적화 단계 관련

point 1

  • 가설 H(x)
    • modelx_train 데이터를 넣어서 가설 함수 생성
  • 비용 cost
    • prediction(예측값)과 y_train(실제값)의 평균제곱오차를 구함.
    • 이때 파이토치에서 제공하는 함수 사용.
      • F.mse_losss()

point 2

  • 어떻게 Wb를 갱신시키는가?
    • step
      1. optimizer.zero_grad()
      • 기존의 최적화 함수의 파라메터를 0으로 초기화
      • 파라메터 값이 누적되기 때문에 0으로 초기화하지 않으면 최적화된 값으로 갱신 불가
      1. cost.backward()
      • 비용함수를 미분하여 gradient 계산
      • 기울기를 연산함.
        • x.grad+=\frac{d(cost)}{d(x)}
      1. optimizer.step()
      • 인수로 들어갔던 W와 b가 리턴되는 변수들의 기울기에 lr(learning rate)를 곱하여 빼주면서 업데이트
      • 연산된 기울기를 통해 x를 갱신함.
        • x-= lr * x.grad

(5) 모델 테스트 및 파라메터 확인

(5-1) 모델 테스트

#임의의 입력 4를 선언
new_var=torch.FloatTensor([[4.0]])
# 입력한 값 4에 대해서 예측값 y를 리턴, pred_y에 저장
pred_y=model(new_var)

print('훈련 후 입력이 4일때의 예측값: ', pred_y)
훈련 후 입력이 4일때의 예측값:  tensor([[7.9989]], grad_fn=<AddmmBackward0>)
  • 임의의 입력 4를 선언하고, model에 input으로 넣었음.
  • 결과는 7.9989로 8과 근사한 값을 반환함.

(5-2) 파라메터 확인

print(list(model.parameters()))
[Parameter containing:
tensor([[1.9994]], requires_grad=True), Parameter containing:
tensor([0.0014], requires_grad=True)] 
  • w는 1.9994, b는 0.0014의 값을 가짐.
  • 처음의 의도대로 각각 2와 0에 근사한 모델을 생성함.

(Insgihts)

Forward 연산

  • H(x) 식에 입력 x로부터 예측된 y를 얻는 것을 forward 연산이라고 함.
  • 학습 전, prediction=model(x_train)x_train으로부터 예측값을 리턴하므로 forward 연산이라고 함.
  • 학습 후, pred_y=model(new_var)은 임의의 값 new_var로부터 예측값을 리턴하므로 forward 연산이라고 함.

Backward 연산

  • 학습 과정에서 비용 함수를 미분하여 기울기를 구하는 것을 backward 연산이라고 함.
  • cost.backward()는 비용함수로부터 기울기를 구하라는 의미이며, backward 연산임.

2. 다중 선형 회귀 구현하기

  • 다중선형회귀모델을 구현하는 것으로, 3개의 입력과 1개의 출력이 있음.
  • 가설 수식
    • 3개의 x로부터 1개의 y를 예측하는 문제
    • 수식: H(x)=w1x1+w2x2+w3x3+bH(x)=w_1x_1+w_2x_2+w_3x_3+b

(1) 필요한 패키지 import 및 초기화

import torch
import torch.nn as nn
import torch.nn.functional as F

torch.manual_seed(1)

(2) 훈련데이터 선언

#데이터
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]])

(3) 모델 선언 및 초기화

model=nn.Linear(3,1)
print(list(model.parameters()))
[Parameter containing:
tensor([[ 0.2975, -0.2548, -0.1119]], requires_grad=True), Parameter containing:
tensor([0.2710], requires_grad=True)]

(4) 최적화: 경사하강법으로

(4-1) optim 선언

optimizer=torch.optim.SGD(model.parameters(),lr=1e-5)

(4-2) 최적화

nb_epochs=2000
for epoch in range(nb_epochs+1):

    #H(x)
    prediction=model(x_train) 
    # (동일) prediction=model.forward(x_train)

    #cost
    cost=F.mse_loss(prediction,y_train) # 파이토치에서 제공하는 평균 제곱 오차 함수

    #cost로 H(x) 개선
    optimizer.zero_grad()
    cost.backward()
    optimizer.step()

    if epoch % 100==0:
        print('Epoch {:4d}/{} Cost: {:.6f}'.format(epoch,nb_epochs,cost.item()))

(5) 모델 테스트 및 파라메터 확인

(5-1) 모델 테스트

# 임의의 입력 [73,80,75] 선언
new_var=torch.FloatTensor([[73,80,75]])
# 입력한 값에 대한 예측값을 pred_y에 저장
pred_y=model(new_var)
print('훈련 후 입력이 [73,80,75]일때의 예측값:',pred_y)
훈련 후 입력이 [73,80,75]일때의 예측값: tensor([[151.2306]], grad_fn=<AddmmBackward0>)
  • [73,80,75]의 임의의 입력을 넣어 pred_y 값 확인
  • 해당 임의의 입력은 훈련에 사용되었던 데이터로 당시 y값 152와 비교하면 근사한 값을 예측했음을 알 수 있음.

(5-2) 파라메터 확인

print(list(model.parameters()))
[Parameter containing:
tensor([[0.9778, 0.4539, 0.5768]], requires_grad=True), Parameter containing:
tensor([0.2802], requires_grad=True)]

0개의 댓글