[PyTorch] 단순 선형 회귀
Posted: Updated:
AI 스터디를 하며 ‘파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습’ 교재를 정리한 글입니다.
단순 선형 회귀
손실 함수 정의
평균 제곱 오차 (Mean Squared Error, MSE)
$y_i$: 실제 값 $\hat{y_i} = weight \cdot x_i + bias $: 예측 값
\[J(weight, bias) = \frac{1}{n} \sum_{i=1}^n (y_i - \hat{y_i})^2\]Chain Rule 을 활용해 가중치, 편향에 대한 편미분
$\hat{y_i}$을 $weight \cdot x_i + bias$로 치환
\[\frac{1}{n} \sum_{i=1}^n (y_i - (weight \cdot x_i + bias))^2\]- $Gradient(w_n)$
- $weight$에 대해 편미분
- 코드로 표현
2 * ((y_hat - y) * x).mean()
- $Gradient(b_n)$
- $bias$에 대해 편미분
- 코드로 표현
2 * (y_hat - y).mean()
가중치, 편향 갱신
(업데이트할 파라미터) - (학습률) * (손실함수의 파라미터에 대한 편미분) 편미분 후 생긴 상수 2는 학습률($\alpha$)로 대체
- $w_{n+1}$
- $b_{n+1}$
넘파이로 구현한 단순 선형 회귀
import numpy as np
x = np.array([
[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]
])
y = np.array([
[0.94], [1.98], [2.88], [3.92], [3.96], [4.55], [5.64], [6.3], [7.44], [9.1],
[8.46], [9.5], [10.67], [11.16], [14], [11.83], [14.4], [14.25], [16.2], [16.32],
[17.46], [19.8], [18], [21.34], [22], [22.5], [24.57], [26.04], [21.6], [28.8]
])
weight = 0.0
bias = 0.0
learning_rate = 0.001
# learning_rate = 0.005
for epoch in range(10000):
y_hat = weight * x + bias # batch size: 30
cost = ((y - y_hat) ** 2).mean()
weight = weight - learning_rate * ((y_hat - y) * x).mean()
bias = bias - learning_rate * (y_hat - y).mean()
if (epoch + 1) % 1000 == 0:
print(f"Epoch : {epoch+1:4d}, Weight : {weight:.3f}, Bias : {bias:.3f}, Cost : {cost:.3f}")
출력
Epoch : 1000, Weight : 0.860, Bias : -0.059, Cost : 1.406
Epoch : 2000, Weight : 0.864, Bias : -0.138, Cost : 1.393
Epoch : 3000, Weight : 0.867, Bias : -0.201, Cost : 1.385
Epoch : 4000, Weight : 0.870, Bias : -0.251, Cost : 1.380
Epoch : 5000, Weight : 0.872, Bias : -0.290, Cost : 1.377
Epoch : 6000, Weight : 0.873, Bias : -0.321, Cost : 1.375
Epoch : 7000, Weight : 0.874, Bias : -0.345, Cost : 1.374
Epoch : 8000, Weight : 0.875, Bias : -0.364, Cost : 1.373
Epoch : 9000, Weight : 0.876, Bias : -0.379, Cost : 1.373
Epoch : 10000, Weight : 0.877, Bias : -0.391, Cost : 1.373
파이토치 기능으로 구현한 단순 선형 회귀
- 확률적 경사 하강법 (Stochastic Gradient Descent, SGD) 사용: 미니 배치(Mini-Batch) 형태로 전체 대이터를 N등분하여 학습 진행
import torch
from torch import optim
x = torch.FloatTensor([
[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]
])
y = torch.FloatTensor([
[0.94], [1.98], [2.88], [3.92], [3.96], [4.55], [5.64], [6.3], [7.44], [9.1],
[8.46], [9.5], [10.67], [11.16], [14], [11.83], [14.4], [14.25],
[16.2], [16.32], [17.46], [19.8], [18], [21.34], [22], [22.5],
[24.57], [26.04], [21.6], [28.8]
])
weight = torch.zeros(1, requires_grad=True)
bias = torch.zeros(1, requires_grad=True)
learning_rate = 0.001
optimizer = optim.SGD([weight, bias], lr=learning_rate) # 최적화 선언
for epoch in range(10000):
hypothesis = weight * x + bias
cost = torch.mean((hypothesis - y) ** 2)
optimizer.zero_grad() # weight, bias 에 저장된 기존 기울기값 초기화
cost.backward() # 역전파 수행, cost에 대한 각 파라미터의 gradient 계산
optimizer.step() # optimizer에 등록된 파라미터들에 대해 역전파로 계산된 파라미터 갱신
if (epoch + 1) % 1000 == 0:
print(f"Epoch: {epoch + 1:4d}, Weight: {weight.item():.3f}, Bias: {bias.item():.3f}, Cost: {cost.item():.3f}")
출력
Epoch: 1000, Weight: 0.864, Bias: -0.138, Cost: 1.393
Epoch: 2000, Weight: 0.870, Bias: -0.251, Cost: 1.380
Epoch: 3000, Weight: 0.873, Bias: -0.321, Cost: 1.375
Epoch: 4000, Weight: 0.875, Bias: -0.364, Cost: 1.373
Epoch: 5000, Weight: 0.877, Bias: -0.391, Cost: 1.373
Epoch: 6000, Weight: 0.878, Bias: -0.408, Cost: 1.372
Epoch: 7000, Weight: 0.878, Bias: -0.419, Cost: 1.372
Epoch: 8000, Weight: 0.878, Bias: -0.425, Cost: 1.372
Epoch: 9000, Weight: 0.879, Bias: -0.429, Cost: 1.372
Epoch: 10000, Weight: 0.879, Bias: -0.432, Cost: 1.372
신경망 패키지
신경망 생성, 학습 과정을 빠르게 구현 가능
- 네트워크(Net) 정의 모듈
- 자동 미분, 계층 등 정의를 위한 모듈
선형 변환 클래스
- 선형 변환(Linear Transformation): 기하학적으로 벡터의 크기 스케일링, 방향 회전, 좌표 이동 시키는 연산
- 머신러닝에서는 다음 레이어에서 학습 가능하도록 하기 위한 입력 데이터의 차원 변환, 선형 회귀에서 데이터 예측에 사용
layer = nn.Linear(
in_features=10,
out_features=5,
bias=True,
device=None,
dtype=None
)
평균 제곱 오차 클래스
criterion = nn.MSELoss()
신경망 패키지로 구현한 단순 선형 회귀
- weight, bias 변수를 사용하지 않음
- 학습 결과는 model.parameters() 로 확인
x = torch.FloatTensor([
[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]
])
y = torch.FloatTensor([
[0.94], [1.98], [2.88], [3.92], [3.96], [4.55], [5.64], [6.3], [7.44], [9.1],
[8.46], [9.5], [10.67], [11.16], [14], [11.83], [14.4], [14.25], [16.2], [16.32],
[17.46], [19.8], [18], [21.34], [22], [22.5], [24.57], [26.04], [21.6], [28.8]
])
model = nn.Linear(1, 1)
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.001)
for epoch in range(10000):
output = model(x) # 모델에 입력 데이터 전달, 출력 데이터 차원 크기와 동일한 output(= y_hat)
cost = criterion(output, y) # input: output, target: y (MSE에서 y_hat, y 의미)
optimizer.zero_grad()
cost.backward()
optimizer.step()
if (epoch + 1) % 1000 == 0:
print(f"Epoch : {epoch + 1:4d}, Model : {list(model.parameters())}, Cost : {cost:.3f}")
출력
Epoch : 1000, Model : [Parameter containing:
tensor([[0.8888]], requires_grad=True), Parameter containing:
tensor([-0.6379], requires_grad=True)], Cost : 1.382
Epoch : 2000, Model : [Parameter containing:
tensor([[0.8851]], requires_grad=True), Parameter containing:
tensor([-0.5616], requires_grad=True)], Cost : 1.376
Epoch : 3000, Model : [Parameter containing:
tensor([[0.8827]], requires_grad=True), Parameter containing:
tensor([-0.5141], requires_grad=True)], Cost : 1.374
Epoch : 4000, Model : [Parameter containing:
tensor([[0.8813]], requires_grad=True), Parameter containing:
tensor([-0.4846], requires_grad=True)], Cost : 1.373
Epoch : 5000, Model : [Parameter containing:
tensor([[0.8804]], requires_grad=True), Parameter containing:
tensor([-0.4662], requires_grad=True)], Cost : 1.372
Epoch : 6000, Model : [Parameter containing:
tensor([[0.8798]], requires_grad=True), Parameter containing:
tensor([-0.4548], requires_grad=True)], Cost : 1.372
Epoch : 7000, Model : [Parameter containing:
tensor([[0.8795]], requires_grad=True), Parameter containing:
tensor([-0.4477], requires_grad=True)], Cost : 1.372
Epoch : 8000, Model : [Parameter containing:
tensor([[0.8793]], requires_grad=True), Parameter containing:
tensor([-0.4432], requires_grad=True)], Cost : 1.372
Epoch : 9000, Model : [Parameter containing:
tensor([[0.8791]], requires_grad=True), Parameter containing:
tensor([-0.4405], requires_grad=True)], Cost : 1.372
Epoch : 10000, Model : [Parameter containing:
tensor([[0.8790]], requires_grad=True), Parameter containing:
tensor([-0.4388], requires_grad=True)], Cost : 1.372
댓글남기기