오늘로 Machine Learning에 대한 이론 수업은 모두 끝났고, PyTorch를 사용해서 직접 모델을 만들어보는 시간을 가졌다. 이론으로만 들었던 내용을 코드로 구현해가니까 상당히 재미있었고, 이론을 알고 있으니 코드를 작성하면서 어떤 기능인지 바로바로 알 수 있어서 꽤 만족스러운 이론 학습이었던 것 같다.
requires_grad : Tensor의 속성으로, True로 설정해야 자동미분이 가능tensor.backward() : 미분 실행tensor.grad : 미분값을 확인할 수 있는 속성x = torch.tensor([1.], requires_grad=True)
y = x ** 2
print(y)
print(x.grad)
# tensor([1.], grad_fn=<PowBackward0>)
# None
z = 3 * y
print(z)
# tensor([3.], grad_fn=<MulBackward0>)
z.backward()
print(x.grad)
# tensor([6.])
x = torch.tensor([1.], requires_grad=True)
a = x ** 2
b = a + 1
c = b ** 2
c.backward()
print(x.grad)
# tensor([8.])
result = x.grad.detach()
print(result)
print(result.requires_grad)
print(result.item())
# tensor([8.])
# False
# 8.0
x = torch.tensor([1.], requires_grad=True)
y = torch.tensor([3.], requires_grad=True)
z = (2 * (x ** 2)) + (y ** 2)
print(z)
# tensor([11.], grad_fn=<AddBackward0>)
z.backward()
print(x.grad)
print(y.grad)
# tensor([4.])
# tensor([6.])
with torch.no_grad()x = torch.tensor([1.], requires_grad=True)
with torch.no_grad():
y = x ** 2
print(x.requires_grad)
print(y)
# True
# tensor([1.])
print(x.requires_grad)
# True
y.backward() # with 구문 안쪽의 y로 미분 시도시 에러 발생
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
import numpy as np
x = torch.linspace(0,10,100).view(-1,1) # 입력데이터
y = 3 * x + 2 + torch.randn(100, 1) * 2 # 라벨
class LinearRegressionModel(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(1,1) # 입력 1개, 출력 1개 노드 생성
def forward(self, x):
return self.linear(x)
model = LinearRegressionModel()
class LinearRegressionModel(nn.Module):
def __init__(self):
super().__init__()
self.hidden = nn.Linear(1,10) # 입력 1개, 출력 10개 노드 생성
self.relu = nn.ReLU()
self.output = nn.Linear(10,1)
def forward(self, x):
x = self.hidden(x)
x = self.relu(x)
x = self.output(x)
return x
criterion = nn.MSELoss() # 평균 제곱 오차
# Weight, Bias 포함 / 학습률
optimizer = optim.SGD(model.parameters(), lr=0.01) # 확률적 경사 하강법
epochs = 500 # 학습 반복 횟수
losses = []
for epoch in range(epochs):
optimizer.zero_grad() # 기울기 초기화
outputs = model(x) # 예측값 계산
loss = criterion(outputs, y) # 손실 계산
loss.backward() # 역전파
optimizer.step() # 가중치 업데이트
losses.append(loss.item())
# 100번에 한번씩 로그 출력
if (epoch + 1) % 100 == 0:
print(f"Eporch [{epoch+1} / {epochs}], Loss : {loss.item() : .4f}")
plt.figure(figsize=(10,5))
# 손실 감소 그래프
plt.subplot(1, 2, 1)
plt.ylim(0, 5)
plt.plot(losses)
plt.title("Loss over Epochs")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.grid()
# 데이터와 예측 결과
plt.subplot(1, 2, 2)
plt.scatter(x.numpy(), y.numpy(), label="Original Data")
plt.plot(x.numpy(), model(x).detach().numpy(), color="r", label="Fitted Line")
plt.title("Linear Regression Fit")
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.show()
print("Model Parameters :")
for name, param in model.named_parameters():
print(f"{name} : {param.data}")
약간의 이슈는 있었지만 상당히 재미있는 수업이었다. 내일은 더 다양한 모델들을 구현해본다고 해서 더 재미있을 것 같다.