덕배의 블로그
딥러닝 선형 회귀(Linear Regression), 경사 하강법을 알고 파이토치로 실습해보자 본문
반응형
선형 회귀(Linear Regression)
선형 회귀에 대해서 알아볼 건데 선형 회귀가 뭔지 또 평균 제곱 오차, 경사하강법과 손실함수에 대해서 알아보려고 한다.
선형 회귀는 학습 데이터와 가장 잘 맞는 하나의 직선을 찾는 것을 말한다.
Hypothesis(가설)
y = Wx + b
- W - 가중치 (weight)
- b - 편향 (bias)
비용함수, 손실함수
비용함수(cost function)이나 손실함수(loss function)이나 똑같은 개념이다.
- 수많은 직선이 있지만 누구는 검은색 직선이 4개의 점이랑 가장 가깝다고 생각하고 누구는 빨간색 직선이라고 생각할 수 있다.
- 그러나 우리는 증명해야 하기에 우리는 오차를 사용
- 오차 = 예측값 - 실제값
- 오차를 계산해 봤으나 음수가 나오는 경우가 생겨 제곱을 해준 뒤 덧셈
MSE(평균 제곱 오차) - 오차의 제곱 합/ 데이터 개수
- 평균 제곱 오차는 회귀에서 적절한 W와 b를 찾기 위한 식
- 평균 제곱 오차의 값을 최솟값으로 만드는 W와 b를 찾는다면 그것이 가장 훈련 데이터를 잘 반영한 직선을 찾는 것
- 평균 제곱 오차가 낮으면 낮을수록 우리가 찾는 적합한 식
경사하강법( Gradient Descent)
비용 함수(손실 함수) 값을 최소로 하는 W와 b를 찾는 방법은 경사하강법(옵티마이저 알고리즘)이다.
- 기울기 W가 커지면 커질수록 cost 값도 커지고 기울기가 작아지면 작아질수록 cost 값도 증가
- 우리의 목표는 cost 값이 가장 작을 때를 찾는 것이기에 맨 아래의 볼록한 부분을 찾아야 한다.
- 경사하강법은 맨 아래의 볼록한 부분을 향해 W값을 수정해 나가는 방법
- 결국은 미분을 하면서 기울기가 0이 되는 부분을 찾아야 한다.
- 맨 아래로 가면 갈수록 기울기가 낮아지며 가장 아랫부분은 0이 된다.
- 기울기가 음수일 때 - W의 값 증가
- 기울기가 양수일 때 - W의 값 감소
- W - a x 음수 기울기 = W + a x 양수 기울기
- a = 학습률(learning rate)
- W를 그래프의 한 점이라 생각하고 접선의 기울기가 0이 될 때까지 경사를 따라 내려가는 관점에서 얼마나 큰 폭으로 이동할지 결정
- 크게 하면 좋을 것이라고 생각하지만 지나치게 높으면 cost값이 발산
- 너무 낮게 하면 학습 속도 느려지므로 적당한 a값을 찾는 것이 중요
- W - a x 음수 기울기 = W + a x 양수 기울기
코랩을 통한 파이토치로 경사하강법 실습
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
- 그래프로부터 자동으로 미분 계산
이렇게 선형 회귀와 손실함수, 경사하강법, 평균 제곱 오차에 대해서 알아보았다.
'인공지능' 카테고리의 다른 글
파이토치 nn.Module 라이브러리를 이용한 선형 회귀 (0) | 2023.08.13 |
---|---|
다중 선형 회귀, 벡터 내적에 대해서 알아보고 파이토치로 실습해보기 (0) | 2023.08.12 |
텐서 연결, 스택킹을 파이토치(pytorch) 실습해보기 (0) | 2023.08.08 |
텐서 크기 변경, 차원 제거, 타입 캐스팅 파이토치(pytorch)로 실습하기 (0) | 2023.08.07 |
벡터, 행렬, 텐서의 개념 pytorch(파이토치) 실습해보기 (2) | 2023.08.06 |