import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
# 컴퓨터에 있는 random seed table은 컴퓨터마다 다르므로,
# 현재 실습하고 있는 파이썬 코드를 재실행해도 다음에도 같은 결과가 나오도록 랜덤 시드(random seed)를 줍니다.
torch.manual_seed(1)
# 데이터가 1, 2, 3 즉 3개가 있고, 정답 값도 2, 4, 6으로 3개가 있는걸 확인할 수 있다.
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[2], [4], [6]])
# torch.FloatTensor : 토치에서는 텐서만 가능 (numpy는 안 됨)
print(x_train)
print(x_train.shape)
print(y_train)
print(y_train.shape)
# 가중치 W를 0으로 초기화하고, 학습(back prop)을 통해 값이 변경되는 변수임(requires_grad=True)을 명시함.
W = torch.zeros(1, requires_grad=True)
# 가중치 W를 출력
print(W)
# 가중치 b를 0으로 초기화하고, 학습을 통해 값이 변경되는 변수임을 명시함.
b = torch.zeros(1, requires_grad=True)
# 가중치 b를 출력
print(b)
# 확률적 경사하강법(SGD), 첫번째 인자는 최적화 시킬 learnable parameter를 주고([W, b]), 두번째 인자는 학습률(lr)을 명시해준다.
optimizer = optim.SGD([W, b], lr=0.01)
nb_epochs = 100 # 원하는만큼 경사 하강법을 반복
for epoch in range(nb_epochs + 1):
# 선형회귀 모델
predict = x_train * W + b
'''
x_train * w => x_train * w + b = predict
[[1], * [0] => [[0]. + [0] = [[0],
[2], [0], [0],
[3]] [0]] [0]]
'''
# cost 계산 (Mean Square Error)
cost = torch.mean((predict - y_train) ** 2) # ** : 제곱
'''
predict - y_train = (predict-y_train)**2
[[0], - [[2], = ([[-2],
[0], [4], [-4],
[0]] [6]] [-6]) ** 2
'''
# cost로 모델 개선
optimizer.zero_grad() # (n번 학습할 때마다) 기울기 초기화
cost.backward() # cost를 기반으로 미분(접선의 기울기) 계산
optimizer.step() # 오차역전파법(back prop) 실행
# 10번마다 로그 출력
if epoch % 10 == 0:
print('Epoch {:4d}/{} W: {:.3f}, b: {:.3f} Cost: {:.6f}'.format(
epoch, nb_epochs, W.item(), b.item(), cost.item()
))