Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

덕배의 블로그

딥러닝 선형 회귀(Linear Regression), 경사 하강법을 알고 파이토치로 실습해보자 본문

인공지능

딥러닝 선형 회귀(Linear Regression), 경사 하강법을 알고 파이토치로 실습해보자

김덕배_KDB 2023. 8. 9. 18:12
반응형

선형 회귀(Linear Regression)

선형 회귀에 대해서 알아볼 건데 선형 회귀가 뭔지 또 평균 제곱 오차, 경사하강법과 손실함수에 대해서 알아보려고 한다.

선형 회귀는 학습 데이터와 가장 잘 맞는 하나의 직선을 찾는 것을 말한다.

 

Hypothesis(가설)

 

y = Wx + b

 

  • W - 가중치 (weight)
  • b - 편향 (bias)

 

비용함수, 손실함수

비용함수(cost function)이나 손실함수(loss function)이나 똑같은 개념이다.

 

선형 회귀
선형 회귀

 

  • 수많은 직선이 있지만 누구는 검은색 직선이 4개의 점이랑 가장 가깝다고 생각하고 누구는 빨간색 직선이라고 생각할 수 있다.
  • 그러나 우리는 증명해야 하기에 우리는 오차를 사용
  • 오차 = 예측값 - 실제값
  • 오차를 계산해 봤으나 음수가 나오는 경우가 생겨 제곱을 해준 뒤 덧셈

 

MSE(평균 제곱 오차) - 오차의 제곱 합/ 데이터 개수

  • 평균 제곱 오차는 회귀에서 적절한 W와 b를 찾기 위한 식
  • 평균 제곱 오차의 값을 최솟값으로 만드는 W와 b를 찾는다면 그것이 가장 훈련 데이터를 잘 반영한 직선을 찾는 것
  • 평균 제곱 오차가 낮으면 낮을수록 우리가 찾는 적합한 식

 

MSE 사진
MSE

 

경사하강법( Gradient Descent)

비용 함수(손실 함수) 값을 최소로 하는 W와 b를 찾는 방법은 경사하강법(옵티마이저 알고리즘)이다.

 

경사하강법
경사하강법

 

  • 기울기 W가 커지면 커질수록 cost 값도 커지고 기울기가 작아지면 작아질수록 cost 값도 증가
  • 우리의 목표는 cost 값이 가장 작을 때를 찾는 것이기에 맨 아래의 볼록한 부분을 찾아야 한다.
  • 경사하강법은 맨 아래의 볼록한 부분을 향해 W값을 수정해 나가는 방법
  • 결국은 미분을 하면서 기울기가 0이 되는 부분을 찾아야 한다.

 

기울기 설명
접선의 기울기

 

  • 맨 아래로 가면 갈수록 기울기가 낮아지며 가장 아랫부분은 0이 된다.
  • 기울기가 음수일 때 - W의 값 증가
  • 기울기가 양수일 때 - W의 값 감소
    • W - a x 음수 기울기 = W + a x 양수 기울기
      1. a = 학습률(learning rate)
      2. W를 그래프의 한 점이라 생각하고 접선의 기울기가 0이 될 때까지 경사를 따라 내려가는 관점에서 얼마나 큰 폭으로 이동할지 결정
      3. 크게 하면 좋을 것이라고 생각하지만 지나치게 높으면 cost값이 발산
      4. 너무 낮게 하면 학습 속도 느려지므로 적당한 a값을 찾는 것이 중요

 

코랩을 통한 파이토치로 경사하강법 실습

 

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

# 데이터
x_train = torch.FloatTensor([[1], [2], [3]]) #(3 x 1)
y_train = torch.FloatTensor([[2], [4], [6]]) #(3 x 1)
# 모델 초기화
W = torch.zeros(1, requires_grad=True) #weight 초기화
b = torch.zeros(1, requires_grad=True) #requires_grad=True 학습을 통해 계속 값이 변경되는 변수

# optimizer 경사하경법 설정 lr=학습률
optimizer = optim.SGD([W, b], lr=0.01)

nb_epochs = 1999 # 원하는만큼 경사 하강법을 반복
for epoch in range(nb_epochs + 1):

    # 가설
    hypothesis = x_train * W + b

    # cost function 평균제곱오차 선언
    cost = torch.mean((hypothesis - y_train) ** 2)

    # cost로 H(x) 개선
    optimizer.zero_grad() #기울기 0으로 초기화를 해야 이전에 계산된 기울기 값이 누적이 안
    cost.backward()       #w와 b에 대한 기울기 계산
    optimizer.step()      #lr을 곱하면서 업데이트

    # 100번마다 로그 출력
    if epoch % 100 == 0:
        print('Epoch {:4d}/{} W: {:.3f}, b: {:.3f} Cost: {:.6f}'.format(
            epoch, nb_epochs, W.item(), b.item(), cost.item()
        ))

 

  • torch.manual_seed()를 하는 이유
    • torch.manual_seed()를 사용하면 다른 컴퓨터에서 실행시켜도 동일한 결과가 나온다.
    • 난수 발생 순서와 값을 동일하게 보장하는 특징

 

  • optimizer.zero_grad()를 하는 이유
    • 파이토치는 미분을 통해 기울기를 이전에 계산된 기울기 값에 누적시키는 특징
    • 그러기에 optimizer.zero_grad()를 이용해 미분값을 계속 0으로 초기화해야 한다.

 

  • requires_grad = True
    • 자동 미분 기능
    • 계산 그래프 생성

 

  • backward
    • 그래프로부터 자동으로 미분 계산

 

 

 

이렇게 선형 회귀와 손실함수, 경사하강법, 평균 제곱 오차에 대해서 알아보았다.