티스토리 뷰

▶딥러닝 선형회귀

선형 회귀의 핵심은 학습 데이트와 가장 잘 맞는 직선을 찾는 작업이라고 할 수 있습니다.

 

▷라이브러리 import

우선 필요한 라이브러리를 import 해주겠습니다.

import torch
import torch.nn as nn
import torch.nn.function as F
import torch.optim as optim

간단한 학습 데이터셋을 만들겠습니다.

1시간 공부해서 점수가 50점, 2시간 공부해서 점수가 70점 이런 관계입니다.

X_train = torch.FloatTensor([[1], [2], [3], [4]])
y_train = torch.FloatTensor([[50], [70], [90], [85]])

 

▷W와 b 초기화, 선형식 작성

위 그림에서 보이는 선형식을 작성해보겠습니다.

# W(가줃치)와 b(편향)을 0으로 초기화 해줍니다.
# requires_grad=True :  학습을 통해 변경되는 변수(값이 업데이트 가능하도록 변수로 설정)

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

H = x_train * W + b

이제 비용함수를 선언해 주겠습니다.

비용함수는 실제값과 예측값의 차이를 측정하는 방법입니다.

cost = torch.mean((H - y_train) ** 2)

 

▷옵티마이저(Optimizer)

optimizer는 비용 함수의 값을 최소화 하는 W(기울기)와 b(절편)을 찾는 방법입니다.

최적화 알고리즘은 이 과정이 수행되는 방식(여기에서는 확률적 경사하강법(SGD))을 정의합니다.

모든 최적화 절차(logic)은 optimizer 객체에 캡슐화(encapsulate)됩니다.

여기에서는 SGD 옵티마이저를 사용하고 있으며, PyTorch에는 ADAM이나 RMSProp과 같은 다른 종류의 모델과 데이터에서 더 잘 동작하는 다양한 옵티마이저가 있습니다.

 

학습하려는 모델의 매개변수와 학습률(learning rate) 하이퍼파라미터를 등록하여 옵티마이저를 초기화합니다.

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

학습 단계(loop)에서 최적화는 3단계로 이뤄집니다.

  • optimizer_zero_grad() : 모델 매개변수의 변화도를 재설정합니다. 기본적으로 변화도는 더해지기 때문에 중복 계산을 막기 위해 반복할 때마다 명시적으로 0으로 설정합니다.
  • cost.backward() : 예측 비용을 역전파합니다. PyTorch는 각 매개변수에 대한 비용의 변화도를 저장합니다.
  • optimizer.step() : 변화도를 계산한 뒤 역전파 단계에서 수집된 변화도를 매개변수로 조정합니다.
# 에폭을 한번 돌 때마다 gradient를 0으로 초기화
optimizer.zero_grad()

# 비용함수를 미분하여 gradient 계산
cost.backward()

# W와 b를 업데이트
optimizer.step()

 

▷전체 구현

x_train = torch.FloatTensor([[1], [2], [3], [4]]) # 시간
y_train = torch.FloatTensor([[50], [70], [90], [85]]) # 점수

W = torch.zeros(1, requires_grad=True) # 변수 취급. 0으로 세팅
b = torch.zeros(1, requires_grad=True) # 변수 취급. 0으로 세팅

optimizer = optim.SGD([W, b], lr=0.01) # SGD 최적화 사용.

for epoch in range(1, 2001): # 2000바퀴

    H = x_train * W + b
    cost = torch.mean((H - y_train) ** 2) # 오차값

    optimizer.zero_grad() # 초기화
    cost.backward() # 역전파
    optimizer.step() # W, b 값을 업데이트

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

out:

 

▷nn.Linear 이용하여 리팩토링

nn.Linear를 선형 레이어로 사용하여 self.weights 및 self.bias를 수동으로 정의 및 초기화합니다.

# 입력 데이터 수와 출력 데이터 수를 입력
model = nn.Linear(1, 1) # 데이터 1개 넣어서 1개 결과 출력
class LinearRegressionModel(nn.Module): # nn.Module을 상속받음
  def __init__(self):
    super().__init__() # nn.Module의 부모 클래스를 불러옴
    self.linear = nn.Linear(1, 1) # __setattr__ 함수를 실행
        
  def forward(self, x): # forward()함수는 nn,Module 내부에 있는 함수여서 여기서 오버라이딩 해주는 것
    return self.linear(x) # x값 계산해서 결과값 리턴
    
model = LinearRegressionModel()

# model.parameters() : 입력 받고 레이어를 넘길 때의 가중치를 뽑아내는 메소드.
optimizer = optim.SGD(model.parameters(), lr=0.01)

for epoch in range(1, 2001):
  H = model(x_train)
  cost = F.mse_loss(H, y_train)

  optimizer.zero_grad() # 초기화
  cost.backward() # 역전파
  optimizer.step() # W, b 값을 업데이트

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

out:

 

▷모델 확인해보기

val = torch.FloatTensor([[5.0]])
pred = model(val)
print('학습 후 5시간 공부하면 예상되는 성적: ', pred)

out:

최종적으로 업데이트된 W와 b도 학인해 보겠습니다.

print(list(model.parameters()))

out:

최종적으로 W는 12.5297, b는 42.4155로 업데이트된 걸 확인할 수 있습니다.

 


여기까지 딥러닝 선형회귀에 대해 알아보았습니다 :)

728x90
LIST
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함