Pytorch - Simple Regression
Simple Linear Regression
import torch
import numpy as np
Dataset
x = torch.FloatTensor([[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]])
y = x * 2
Linear Model
$y = Wx + b$
W = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
print(W, b)
tensor([0.], requires_grad=True) tensor([0.], requires_grad=True)
y_hat = x * W + b
print(y_hat.ravel())
tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], grad_fn=<ViewBackward>)
Loss Function
$loss(W, b) = \frac{1}{n} \sum_{i=1}^{n}[y^{(i)} - H(x^{(i)})]^{2}$
loss_fn = torch.mean((y_hat-y) ** 2)
print(loss_fn)
tensor(154., grad_fn=<MeanBackward0>)
SGD
optimizer = torch.optim.SGD([W, b], lr=0.01)
print(W.data, W.grad, b.data, b.grad)
tensor([0.]) None tensor([0.]) None
optimizer.zero_grad() # gradient를 0으로 초기화
loss_fn.backward() # loss_fn을 미분하여 gradient 계산
optimizer.step() # W, b update
print(W.data, W.grad, b.data, b.grad)
tensor([1.5400]) tensor([-154.0000]) tensor([0.2200]) tensor([-22.])
Summary
x = torch.FloatTensor([[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]])
y = x * 2
W = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
optimizer = torch.optim.SGD([W, b], lr=0.01)
epochs = 4000
for epoch in range(epochs+1):
y_hat = x * W + b
loss_fn = torch.mean((y_hat-y) ** 2)
optimizer.zero_grad()
loss_fn.backward()
optimizer.step()
if epoch % 500 == 0:
print('Epoch {:4d}/{} W: {:.3f}, b: {:.3f}, Loss: {:.6f}'.format(epoch, epochs, W.item(), b.item(), loss_fn.item()))
Epoch 0/4000 W: 1.540, b: 0.220, Loss: 154.000000
Epoch 500/4000 W: 1.995, b: 0.034, Loss: 0.000252
Epoch 1000/4000 W: 1.999, b: 0.004, Loss: 0.000004
Epoch 1500/4000 W: 2.000, b: 0.001, Loss: 0.000000
Epoch 2000/4000 W: 2.000, b: 0.000, Loss: 0.000000
Epoch 2500/4000 W: 2.000, b: 0.000, Loss: 0.000000
Epoch 3000/4000 W: 2.000, b: 0.000, Loss: 0.000000
Epoch 3500/4000 W: 2.000, b: 0.000, Loss: 0.000000
Epoch 4000/4000 W: 2.000, b: 0.000, Loss: 0.000000
y_hat.ravel()
tensor([ 2.0000, 4.0000, 6.0000, 8.0000, 10.0000, 12.0000, 14.0000, 16.0000,
18.0000, 20.0000], grad_fn=<ViewBackward>)
y.ravel()
tensor([ 2., 4., 6., 8., 10., 12., 14., 16., 18., 20.])
Multivariable Linear regression
$ y = w_{1}x_{1} + w_{2}x_{2} + w_{3}x_{3} + b$
x1 = torch.FloatTensor([[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]])
x2 = x1 / 2
x3 = x1 * 3
y = x1 + x2 + x3
w1 = torch.zeros(1, requires_grad = True)
w2 = torch.zeros(1, requires_grad = True)
w3 = torch.zeros(1, requires_grad = True)
b = torch.zeros(1, requires_grad = True)
optimizer = torch.optim.SGD([w1, w2, w3, b], lr=1e-5)
epochs = 1000
for epoch in range(epochs+1):
y_hat = x1*w1 + x2*w2 + x3*w3 + b
loss = torch.mean((y_hat - y) **2)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
print('Epoch {:4d}/{} [ w1: {:.6f}, w2: {:.6f}, w3: {:.6f}, b: {:.6f}, Loss: {:.6f}]'.format(
epoch, epochs, w1.item(), w2.item(), w3.item(), b.item(), loss.item() ))
Epoch 0/1000 [ w1: 0.003465, w2: 0.001732, w3: 0.010395, b: 0.000495, Loss: 779.625000]
Epoch 100/1000 [ w1: 0.241652, w2: 0.120826, w3: 0.724957, b: 0.034513, Loss: 159.315308]
Epoch 200/1000 [ w1: 0.349325, w2: 0.174662, w3: 1.047974, b: 0.049877, Loss: 32.556362]
Epoch 300/1000 [ w1: 0.397998, w2: 0.198999, w3: 1.193994, b: 0.056807, Loss: 6.653516]
Epoch 400/1000 [ w1: 0.420001, w2: 0.210001, w3: 1.260003, b: 0.059925, Loss: 1.360293]
Epoch 500/1000 [ w1: 0.429948, w2: 0.214974, w3: 1.289842, b: 0.061320, Loss: 0.278642]
Epoch 600/1000 [ w1: 0.434444, w2: 0.217222, w3: 1.303332, b: 0.061936, Loss: 0.057607]
Epoch 700/1000 [ w1: 0.436477, w2: 0.218238, w3: 1.309430, b: 0.062200, Loss: 0.012437]
Epoch 800/1000 [ w1: 0.437396, w2: 0.218698, w3: 1.312188, b: 0.062304, Loss: 0.003205]
Epoch 900/1000 [ w1: 0.437812, w2: 0.218906, w3: 1.313435, b: 0.062337, Loss: 0.001318]
Epoch 1000/1000 [ w1: 0.438000, w2: 0.219000, w3: 1.314000, b: 0.062337, Loss: 0.000932]
y_hat.ravel()
tensor([ 4.5518, 9.0413, 13.5308, 18.0203, 22.5098, 26.9993, 31.4887, 35.9782,
40.4677, 44.9572], grad_fn=<ViewBackward>)
y.ravel()
tensor([ 4.5000, 9.0000, 13.5000, 18.0000, 22.5000, 27.0000, 31.5000, 36.0000,
40.5000, 45.0000])
Linear Regression with Module
import torch.nn as nn
import torch.nn.functional as F
x = torch.FloatTensor([[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]])
y = x * 2
model = nn.Linear(1, 1)
print(list(model.parameters()))
[Parameter containing:
tensor([[0.6426]], requires_grad=True), Parameter containing:
tensor([0.6916], requires_grad=True)]
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
epochs = 1000
for epoch in range(epochs+1):
y_hat = model(x)
loss = F.mse_loss(y_hat, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
w, b = list(model.parameters())
if epoch % 100 == 0:
print('Epoch {:4d}/{} W: {:.3f}, b: {:.3f}, Loss: {:.6f}'.format(epoch, epochs, w.item(), b.item(), loss.item()))
Epoch 0/1000 W: 1.612, b: 0.827, Loss: 61.086681
Epoch 100/1000 W: 1.918, b: 0.568, Loss: 0.069697
Epoch 200/1000 W: 1.946, b: 0.373, Loss: 0.030038
Epoch 300/1000 W: 1.965, b: 0.245, Loss: 0.012946
Epoch 400/1000 W: 1.977, b: 0.161, Loss: 0.005580
Epoch 500/1000 W: 1.985, b: 0.105, Loss: 0.002405
Epoch 600/1000 W: 1.990, b: 0.069, Loss: 0.001036
Epoch 700/1000 W: 1.993, b: 0.045, Loss: 0.000447
Epoch 800/1000 W: 1.996, b: 0.030, Loss: 0.000193
Epoch 900/1000 W: 1.997, b: 0.020, Loss: 0.000083
Epoch 1000/1000 W: 1.998, b: 0.013, Loss: 0.000036
y_hat.ravel()
tensor([ 2.0111, 4.0092, 6.0074, 8.0055, 10.0036, 12.0018, 13.9999, 15.9981,
17.9962, 19.9944], grad_fn=<ViewBackward>)
y.ravel()
tensor([ 2., 4., 6., 8., 10., 12., 14., 16., 18., 20.])
new_data = torch.FloatTensor([[20]])
target = model(new_data)
target
tensor([[39.9759]], grad_fn=<AddmmBackward>)
print(list(model.parameters()))
[Parameter containing:
tensor([[1.9982]], requires_grad=True), Parameter containing:
tensor([0.0129], requires_grad=True)]
Multivariates Linear Regression with Module
x1 = torch.FloatTensor([[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]])
x2 = x1 / 2
x3 = x1 * 3
x = torch.cat([x1, x2, x3], axis=1)
y = x1 + x2 + x3
model = nn.Linear(3, 1)
list(model.parameters())
[Parameter containing:
tensor([[-0.0295, -0.4642, 0.2788]], requires_grad=True),
Parameter containing:
tensor([-0.2519], requires_grad=True)]
optimizer = torch.optim.SGD(model.parameters(), lr=1e-5)
epochs = 5000
for epoch in range(epochs+1):
y_hat = model(x)
loss = F.mse_loss(y_hat, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
w, b = list(model.parameters())
w1, w2, w3 = w[0]
if epoch % 500 == 0:
print('Epoch {:4d}/{} [ w1: {:.6f}, w2: {:.6f}, w3: {:.6f}, b: {:.6f}, Loss: {:.6f}]'.format(epoch, epochs, w1.item(), w2.item(), w3.item(), b.item(), loss.item() ))
Epoch 0/5000 [ w1: -0.026445, w2: -0.462709, w3: 0.287969, b: -0.251455, Loss: 604.103333]
Epoch 500/5000 [ w1: 0.348962, w2: -0.275006, w3: 1.414190, b: -0.197376, Loss: 0.223519]
Epoch 1000/5000 [ w1: 0.356043, w2: -0.271466, w3: 1.435432, b: -0.195943, Loss: 0.008302]
Epoch 1500/5000 [ w1: 0.356171, w2: -0.271402, w3: 1.435814, b: -0.195506, Loss: 0.008191]
Epoch 2000/5000 [ w1: 0.356165, w2: -0.271402, w3: 1.435810, b: -0.195088, Loss: 0.008156]
Epoch 2500/5000 [ w1: 0.356151, w2: -0.271402, w3: 1.435795, b: -0.194671, Loss: 0.008121]
Epoch 3000/5000 [ w1: 0.356136, w2: -0.271402, w3: 1.435781, b: -0.194254, Loss: 0.008086]
Epoch 3500/5000 [ w1: 0.356121, w2: -0.271402, w3: 1.435766, b: -0.193837, Loss: 0.008051]
Epoch 4000/5000 [ w1: 0.356106, w2: -0.271402, w3: 1.435751, b: -0.193423, Loss: 0.008017]
Epoch 4500/5000 [ w1: 0.356091, w2: -0.271402, w3: 1.435736, b: -0.193013, Loss: 0.007983]
Epoch 5000/5000 [ w1: 0.356076, w2: -0.271402, w3: 1.435722, b: -0.192604, Loss: 0.007949]
y_hat.ravel()
tensor([ 4.3349, 8.8625, 13.3900, 17.9176, 22.4451, 26.9726, 31.5002, 36.0277,
40.5553, 45.0828], grad_fn=<ViewBackward>)
y.ravel()
tensor([ 4.5000, 9.0000, 13.5000, 18.0000, 22.5000, 27.0000, 31.5000, 36.0000,
40.5000, 45.0000])
print(list(model.parameters()))
[Parameter containing:
tensor([[ 0.3561, -0.2714, 1.4357]], requires_grad=True), Parameter containing:
tensor([-0.1926], requires_grad=True)]
Simple Linear Regression with class
x = torch.FloatTensor([[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]])
y = x * 2
class simple_linear_regression(nn.Module): # nn.Module을 상속받는다.
def __init__(self): # 모델의 구조와 동작을 정의하는 생성자를 정의한다.
super().__init__()
self.linear = nn.Linear(1,1) # input_dim = 1, output_dim = 1
def forward(self, x): # 모델이 학습데이터를 입력 받아서 forward연산을 진행시키는 함수
return self.linear(x)
model = simple_linear_regression()
model
simple_linear_regression(
(linear): Linear(in_features=1, out_features=1, bias=True)
)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
epochs = 1000
for epoch in range(epochs+1):
y_hat = model(x)
loss = F.mse_loss(y_hat, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
w, b = list(model.parameters())
if epoch % 100 == 0:
print('Epoch {:4d}/{} W: {:.3f}, b: {:.3f}, Loss: {:.6f}'.format(epoch, epochs, w.item(), b.item(), loss.item()))
Epoch 0/1000 W: 1.775, b: -0.265, Loss: 57.871025
Epoch 100/1000 W: 2.021, b: -0.150, Loss: 0.004836
Epoch 200/1000 W: 2.014, b: -0.098, Loss: 0.002084
Epoch 300/1000 W: 2.009, b: -0.064, Loss: 0.000898
Epoch 400/1000 W: 2.006, b: -0.042, Loss: 0.000387
Epoch 500/1000 W: 2.004, b: -0.028, Loss: 0.000167
Epoch 600/1000 W: 2.003, b: -0.018, Loss: 0.000072
Epoch 700/1000 W: 2.002, b: -0.012, Loss: 0.000031
Epoch 800/1000 W: 2.001, b: -0.008, Loss: 0.000013
Epoch 900/1000 W: 2.001, b: -0.005, Loss: 0.000006
Epoch 1000/1000 W: 2.000, b: -0.003, Loss: 0.000002
Multivariate Linear Regression with class
x1 = torch.FloatTensor([[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]])
x2 = x1 / 2
x3 = x1 * 3
x = torch.cat([x1, x2, x3], axis=1)
y = x1 + x2 + x3
class multivariate_linear_regression(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(3, 1)
def forward(self, x):
return self.linear(x)
model = multivariate_linear_regression()
model
multivariate_linear_regression(
(linear): Linear(in_features=3, out_features=1, bias=True)
)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-5)
epochs = 5000
for epoch in range(epochs+1):
y_hat = model(x)
loss = F.mse_loss(y_hat, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
w, b = list(model.parameters())
w1, w2, w3 = w[0]
if epoch % 500 == 0:
print('Epoch {:4d}/{} [ w1: {:.6f}, w2: {:.6f}, w3: {:.6f}, b: {:.6f}, Loss: {:.6f}]'.format(epoch, epochs, w1.item(), w2.item(), w3.item(), b.item(), loss.item() ))
Epoch 0/5000 [ w1: -0.035776, w2: -0.500726, w3: 0.147928, b: -0.241821, Loss: 749.372070]
Epoch 500/5000 [ w1: 0.382341, w2: -0.291667, w3: 1.402279, b: -0.181670, Loss: 0.274007]
Epoch 1000/5000 [ w1: 0.390228, w2: -0.287723, w3: 1.425941, b: -0.180157, Loss: 0.007048]
Epoch 1500/5000 [ w1: 0.390373, w2: -0.287652, w3: 1.426371, b: -0.179751, Loss: 0.006924]
Epoch 2000/5000 [ w1: 0.390368, w2: -0.287652, w3: 1.426369, b: -0.179366, Loss: 0.006894]
Epoch 2500/5000 [ w1: 0.390353, w2: -0.287652, w3: 1.426356, b: -0.178986, Loss: 0.006865]
Epoch 3000/5000 [ w1: 0.390338, w2: -0.287652, w3: 1.426343, b: -0.178606, Loss: 0.006836]
Epoch 3500/5000 [ w1: 0.390323, w2: -0.287652, w3: 1.426330, b: -0.178226, Loss: 0.006807]
Epoch 4000/5000 [ w1: 0.390309, w2: -0.287652, w3: 1.426316, b: -0.177846, Loss: 0.006778]
Epoch 4500/5000 [ w1: 0.390294, w2: -0.287652, w3: 1.426303, b: -0.177466, Loss: 0.006749]
Epoch 5000/5000 [ w1: 0.390279, w2: -0.287652, w3: 1.426290, b: -0.177086, Loss: 0.006720]