클래스로 파이토치 모델 구현하기

In [2]:
import torch
import torch.nn as nn
import torch.nn.functional as F
In [3]:
# 모델을 클래스로 구현화
# 모델을 선언 및 초기화
# 단순 선형 회귀이므로 input_dim=1, output_dim=1
model = nn.Linear(1,1)
In [4]:
# torch.nn.Module을 상속받는 파이썬 클래스

class LinearRegressionModel(nn.Module): 
    def __init__(self): 
        super().__init__()
        self.linear = nn.Linear(1, 1) # 단순 선형 회귀이므로 input_dim=1, output_dim=1.

    def forward(self, x):
        return self.linear(x)
In [6]:
x_train = torch.FloatTensor([[1],[2],[3]])
y_train = torch.FloatTensor([[2],[4],[6]])
In [7]:
model = LinearRegressionModel()
In [8]:
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
In [9]:
# 전체 훈련 데이터에 대해 경사 하강법을 2,000회 반복

nb_epochs = 2000

for epoch in range(nb_epochs+1):

    # H(x) 계산
    prediction = model(x_train)

    # cost 계산
    cost = F.mse_loss(prediction, y_train) # <== 파이토치에서 제공하는 평균 제곱 오차 함수

    # cost로 H(x) 개선하는 부분
    # gradient를 0으로 초기화
    optimizer.zero_grad()
    # 비용 함수를 미분하여 gradient 계산
    cost.backward() # backward 연산
    # W와 b를 업데이트
    optimizer.step()

    if epoch % 100 == 0:
    # 100번마다 로그 출력
      print('Epoch {:4d}/{} Cost: {:.6f}'.format(
          epoch, nb_epochs, cost.item()
      ))
Epoch    0/2000 Cost: 22.750006
Epoch  100/2000 Cost: 0.185047
Epoch  200/2000 Cost: 0.114348
Epoch  300/2000 Cost: 0.070660
Epoch  400/2000 Cost: 0.043663
Epoch  500/2000 Cost: 0.026981
Epoch  600/2000 Cost: 0.016673
Epoch  700/2000 Cost: 0.010303
Epoch  800/2000 Cost: 0.006366
Epoch  900/2000 Cost: 0.003934
Epoch 1000/2000 Cost: 0.002431
Epoch 1100/2000 Cost: 0.001502
Epoch 1200/2000 Cost: 0.000928
Epoch 1300/2000 Cost: 0.000574
Epoch 1400/2000 Cost: 0.000354
Epoch 1500/2000 Cost: 0.000219
Epoch 1600/2000 Cost: 0.000135
Epoch 1700/2000 Cost: 0.000084
Epoch 1800/2000 Cost: 0.000052
Epoch 1900/2000 Cost: 0.000032
Epoch 2000/2000 Cost: 0.000020
In [10]:
# 다중 선형 회귀의 경우
# 모델 선언 및 초기화
# 다중 선형 회귀이므로 input_dim=3, output_dim=1.
model = nn.Linear(3,1)
In [11]:
# 클래스로 구현

class MultivariateLinearRegressionModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(3, 1) # 다중 선형 회귀이므로 input_dim=3, output_dim=1.

    def forward(self, x):
        return self.linear(x)
In [12]:
model = MultivariateLinearRegressionModel()

미니 배치와 데이터 로드(Mini Batch and Data Load)

In [14]:
# 시험점수 샘플 데이터
x_train = torch.FloatTensor([[73, 80, 75],
                             [93, 88, 93],
                             [89, 91, 90],
                             [96, 98, 100],
                             [73, 66, 70]])
y_train = torch.FloatTensor([[152], [185], [180], [196], [142]])
In [15]:
from torch.utils.data import TensorDataset # 텐서데이터셋
from torch.utils.data import DataLoader # 데이터로더
In [16]:
dataset = TensorDataset(x_train, y_train)
In [17]:
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
In [18]:
# 모델 설계
model = nn.Linear(3,1)
In [20]:
# 옵티마이저 설계
optimizer = torch.optim.SGD(model.parameters(), lr=1e-5)
In [25]:
# 총 20번 훈련
nb_epochs = 20

for epoch in range(nb_epochs + 1):
    for batch_idx, samples in enumerate(dataloader):
        print(batch_idx)
        print(samples)
0
[tensor([[73., 80., 75.],
        [93., 88., 93.]]), tensor([[152.],
        [185.]])]
1
[tensor([[ 96.,  98., 100.],
        [ 89.,  91.,  90.]]), tensor([[196.],
        [180.]])]
2
[tensor([[73., 66., 70.]]), tensor([[142.]])]
0
[tensor([[ 89.,  91.,  90.],
        [ 96.,  98., 100.]]), tensor([[180.],
        [196.]])]
1
[tensor([[73., 66., 70.],
        [93., 88., 93.]]), tensor([[142.],
        [185.]])]
2
[tensor([[73., 80., 75.]]), tensor([[152.]])]
0
[tensor([[93., 88., 93.],
        [73., 66., 70.]]), tensor([[185.],
        [142.]])]
1
[tensor([[ 89.,  91.,  90.],
        [ 96.,  98., 100.]]), tensor([[180.],
        [196.]])]
2
[tensor([[73., 80., 75.]]), tensor([[152.]])]
0
[tensor([[73., 80., 75.],
        [93., 88., 93.]]), tensor([[152.],
        [185.]])]
1
[tensor([[ 89.,  91.,  90.],
        [ 96.,  98., 100.]]), tensor([[180.],
        [196.]])]
2
[tensor([[73., 66., 70.]]), tensor([[142.]])]
0
[tensor([[ 96.,  98., 100.],
        [ 93.,  88.,  93.]]), tensor([[196.],
        [185.]])]
1
[tensor([[73., 66., 70.],
        [89., 91., 90.]]), tensor([[142.],
        [180.]])]
2
[tensor([[73., 80., 75.]]), tensor([[152.]])]
0
[tensor([[73., 80., 75.],
        [89., 91., 90.]]), tensor([[152.],
        [180.]])]
1
[tensor([[ 93.,  88.,  93.],
        [ 96.,  98., 100.]]), tensor([[185.],
        [196.]])]
2
[tensor([[73., 66., 70.]]), tensor([[142.]])]
0
[tensor([[93., 88., 93.],
        [89., 91., 90.]]), tensor([[185.],
        [180.]])]
1
[tensor([[73., 66., 70.],
        [73., 80., 75.]]), tensor([[142.],
        [152.]])]
2
[tensor([[ 96.,  98., 100.]]), tensor([[196.]])]
0
[tensor([[73., 80., 75.],
        [93., 88., 93.]]), tensor([[152.],
        [185.]])]
1
[tensor([[ 96.,  98., 100.],
        [ 73.,  66.,  70.]]), tensor([[196.],
        [142.]])]
2
[tensor([[89., 91., 90.]]), tensor([[180.]])]
0
[tensor([[ 73.,  80.,  75.],
        [ 96.,  98., 100.]]), tensor([[152.],
        [196.]])]
1
[tensor([[93., 88., 93.],
        [73., 66., 70.]]), tensor([[185.],
        [142.]])]
2
[tensor([[89., 91., 90.]]), tensor([[180.]])]
0
[tensor([[73., 80., 75.],
        [89., 91., 90.]]), tensor([[152.],
        [180.]])]
1
[tensor([[ 93.,  88.,  93.],
        [ 96.,  98., 100.]]), tensor([[185.],
        [196.]])]
2
[tensor([[73., 66., 70.]]), tensor([[142.]])]
0
[tensor([[93., 88., 93.],
        [73., 80., 75.]]), tensor([[185.],
        [152.]])]
1
[tensor([[ 96.,  98., 100.],
        [ 89.,  91.,  90.]]), tensor([[196.],
        [180.]])]
2
[tensor([[73., 66., 70.]]), tensor([[142.]])]
0
[tensor([[93., 88., 93.],
        [73., 66., 70.]]), tensor([[185.],
        [142.]])]
1
[tensor([[ 96.,  98., 100.],
        [ 89.,  91.,  90.]]), tensor([[196.],
        [180.]])]
2
[tensor([[73., 80., 75.]]), tensor([[152.]])]
0
[tensor([[ 96.,  98., 100.],
        [ 89.,  91.,  90.]]), tensor([[196.],
        [180.]])]
1
[tensor([[73., 80., 75.],
        [73., 66., 70.]]), tensor([[152.],
        [142.]])]
2
[tensor([[93., 88., 93.]]), tensor([[185.]])]
0
[tensor([[73., 80., 75.],
        [73., 66., 70.]]), tensor([[152.],
        [142.]])]
1
[tensor([[ 96.,  98., 100.],
        [ 89.,  91.,  90.]]), tensor([[196.],
        [180.]])]
2
[tensor([[93., 88., 93.]]), tensor([[185.]])]
0
[tensor([[93., 88., 93.],
        [89., 91., 90.]]), tensor([[185.],
        [180.]])]
1
[tensor([[73., 66., 70.],
        [73., 80., 75.]]), tensor([[142.],
        [152.]])]
2
[tensor([[ 96.,  98., 100.]]), tensor([[196.]])]
0
[tensor([[ 93.,  88.,  93.],
        [ 96.,  98., 100.]]), tensor([[185.],
        [196.]])]
1
[tensor([[89., 91., 90.],
        [73., 80., 75.]]), tensor([[180.],
        [152.]])]
2
[tensor([[73., 66., 70.]]), tensor([[142.]])]
0
[tensor([[73., 66., 70.],
        [93., 88., 93.]]), tensor([[142.],
        [185.]])]
1
[tensor([[ 73.,  80.,  75.],
        [ 96.,  98., 100.]]), tensor([[152.],
        [196.]])]
2
[tensor([[89., 91., 90.]]), tensor([[180.]])]
0
[tensor([[73., 80., 75.],
        [89., 91., 90.]]), tensor([[152.],
        [180.]])]
1
[tensor([[73., 66., 70.],
        [93., 88., 93.]]), tensor([[142.],
        [185.]])]
2
[tensor([[ 96.,  98., 100.]]), tensor([[196.]])]
0
[tensor([[73., 66., 70.],
        [93., 88., 93.]]), tensor([[142.],
        [185.]])]
1
[tensor([[ 89.,  91.,  90.],
        [ 96.,  98., 100.]]), tensor([[180.],
        [196.]])]
2
[tensor([[73., 80., 75.]]), tensor([[152.]])]
0
[tensor([[ 73.,  66.,  70.],
        [ 96.,  98., 100.]]), tensor([[142.],
        [196.]])]
1
[tensor([[73., 80., 75.],
        [89., 91., 90.]]), tensor([[152.],
        [180.]])]
2
[tensor([[93., 88., 93.]]), tensor([[185.]])]
0
[tensor([[93., 88., 93.],
        [73., 66., 70.]]), tensor([[185.],
        [142.]])]
1
[tensor([[ 96.,  98., 100.],
        [ 73.,  80.,  75.]]), tensor([[196.],
        [152.]])]
2
[tensor([[89., 91., 90.]]), tensor([[180.]])]
In [26]:
nb_epochs = 20

for epoch in range(nb_epochs + 1):
    for batch_idx, samples in enumerate(dataloader):
        # print(batch_idx)
        # print(samples)
        x_train, y_train = samples
        # H(x) 계산
        prediction = model(x_train)

        # cost 계산
        cost = F.mse_loss(prediction, y_train)

        # cost로 H(x) 계산
        optimizer.zero_grad()
        cost.backward()
        optimizer.step()

        print('Epoch {:4d}/{} Batch {}/{} Cost: {:.6f}'.format(
            epoch, nb_epochs, batch_idx+1, len(dataloader),
            cost.item()
            ))
Epoch    0/20 Batch 1/3 Cost: 17436.300781
Epoch    0/20 Batch 2/3 Cost: 3903.776367
Epoch    0/20 Batch 3/3 Cost: 1090.520264
Epoch    1/20 Batch 1/3 Cost: 482.782837
Epoch    1/20 Batch 2/3 Cost: 199.102127
Epoch    1/20 Batch 3/3 Cost: 69.264931
Epoch    2/20 Batch 1/3 Cost: 13.036790
Epoch    2/20 Batch 2/3 Cost: 5.832646
Epoch    2/20 Batch 3/3 Cost: 3.540158
Epoch    3/20 Batch 1/3 Cost: 1.887493
Epoch    3/20 Batch 2/3 Cost: 1.109560
Epoch    3/20 Batch 3/3 Cost: 0.004109
Epoch    4/20 Batch 1/3 Cost: 0.865739
Epoch    4/20 Batch 2/3 Cost: 1.043862
Epoch    4/20 Batch 3/3 Cost: 2.012496
Epoch    5/20 Batch 1/3 Cost: 1.291710
Epoch    5/20 Batch 2/3 Cost: 1.772859
Epoch    5/20 Batch 3/3 Cost: 0.001439
Epoch    6/20 Batch 1/3 Cost: 0.444582
Epoch    6/20 Batch 2/3 Cost: 1.688465
Epoch    6/20 Batch 3/3 Cost: 1.515105
Epoch    7/20 Batch 1/3 Cost: 0.417474
Epoch    7/20 Batch 2/3 Cost: 0.507494
Epoch    7/20 Batch 3/3 Cost: 2.910258
Epoch    8/20 Batch 1/3 Cost: 1.457374
Epoch    8/20 Batch 2/3 Cost: 1.373271
Epoch    8/20 Batch 3/3 Cost: 0.013876
Epoch    9/20 Batch 1/3 Cost: 0.747692
Epoch    9/20 Batch 2/3 Cost: 0.635660
Epoch    9/20 Batch 3/3 Cost: 2.519120
Epoch   10/20 Batch 1/3 Cost: 1.340709
Epoch   10/20 Batch 2/3 Cost: 1.148947
Epoch   10/20 Batch 3/3 Cost: 0.086610
Epoch   11/20 Batch 1/3 Cost: 1.409131
Epoch   11/20 Batch 2/3 Cost: 0.058976
Epoch   11/20 Batch 3/3 Cost: 1.400786
Epoch   12/20 Batch 1/3 Cost: 0.323716
Epoch   12/20 Batch 2/3 Cost: 0.525199
Epoch   12/20 Batch 3/3 Cost: 3.127516
Epoch   13/20 Batch 1/3 Cost: 1.058225
Epoch   13/20 Batch 2/3 Cost: 1.397694
Epoch   13/20 Batch 3/3 Cost: 0.153495
Epoch   14/20 Batch 1/3 Cost: 0.848465
Epoch   14/20 Batch 2/3 Cost: 2.012510
Epoch   14/20 Batch 3/3 Cost: 0.001327
Epoch   15/20 Batch 1/3 Cost: 1.170562
Epoch   15/20 Batch 2/3 Cost: 0.993953
Epoch   15/20 Batch 3/3 Cost: 1.158967
Epoch   16/20 Batch 1/3 Cost: 0.519465
Epoch   16/20 Batch 2/3 Cost: 1.821032
Epoch   16/20 Batch 3/3 Cost: 0.004090
Epoch   17/20 Batch 1/3 Cost: 1.053149
Epoch   17/20 Batch 2/3 Cost: 0.851477
Epoch   17/20 Batch 3/3 Cost: 1.064232
Epoch   18/20 Batch 1/3 Cost: 0.318000
Epoch   18/20 Batch 2/3 Cost: 0.526773
Epoch   18/20 Batch 3/3 Cost: 3.144485
Epoch   19/20 Batch 1/3 Cost: 1.192781
Epoch   19/20 Batch 2/3 Cost: 0.710361
Epoch   19/20 Batch 3/3 Cost: 1.762214
Epoch   20/20 Batch 1/3 Cost: 0.442626
Epoch   20/20 Batch 2/3 Cost: 1.705996
Epoch   20/20 Batch 3/3 Cost: 0.116554

커스텀 데이터 셋(Custom Dataset)

In [27]:
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
In [29]:
# Dataset 상속
class CustomDataset(Dataset): 
    def __init__(self):
        self.x_data = [[73, 80, 75],
                       [93, 88, 93],
                       [89, 91, 90],
                       [96, 98, 100],
                       [73, 66, 70]]
        self.y_data = [[152], [185], [180], [196], [142]]

  # 총 데이터의 개수를 리턴
    def __len__(self): 
        return len(self.x_data)

  # 인덱스를 입력받아 그에 맵핑되는 입출력 데이터를 파이토치의 Tensor 형태로 리턴
    def __getitem__(self, idx): 
        x = torch.FloatTensor(self.x_data[idx])
        y = torch.FloatTensor(self.y_data[idx])
        return x, y
In [30]:
dataset = CustomDataset()
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
In [31]:
model = torch.nn.Linear(3,1)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-5)
In [32]:
# 총 20회 훈련
nb_epochs = 20

for epoch in range(nb_epochs + 1):
    for batch_idx, samples in enumerate(dataloader):
        # print(batch_idx)
        # print(samples)
        x_train, y_train = samples
        # H(x) 계산
        prediction = model(x_train)

        # cost 계산
        cost = F.mse_loss(prediction, y_train)

        # cost로 H(x) 계산
        optimizer.zero_grad()
        cost.backward()
        optimizer.step()

        print('Epoch {:4d}/{} Batch {}/{} Cost: {:.6f}'.format(
            epoch, nb_epochs, batch_idx+1, len(dataloader),
            cost.item()
            ))
Epoch    0/20 Batch 1/3 Cost: 18661.630859
Epoch    0/20 Batch 2/3 Cost: 7757.506348
Epoch    0/20 Batch 3/3 Cost: 3393.791260
Epoch    1/20 Batch 1/3 Cost: 522.996094
Epoch    1/20 Batch 2/3 Cost: 113.886185
Epoch    1/20 Batch 3/3 Cost: 51.355717
Epoch    2/20 Batch 1/3 Cost: 10.510319
Epoch    2/20 Batch 2/3 Cost: 9.564117
Epoch    2/20 Batch 3/3 Cost: 1.025243
Epoch    3/20 Batch 1/3 Cost: 0.196345
Epoch    3/20 Batch 2/3 Cost: 1.825134
Epoch    3/20 Batch 3/3 Cost: 0.048414
Epoch    4/20 Batch 1/3 Cost: 0.027883
Epoch    4/20 Batch 2/3 Cost: 1.484302
Epoch    4/20 Batch 3/3 Cost: 0.197597
Epoch    5/20 Batch 1/3 Cost: 0.048371
Epoch    5/20 Batch 2/3 Cost: 1.453142
Epoch    5/20 Batch 3/3 Cost: 0.127412
Epoch    6/20 Batch 1/3 Cost: 1.249126
Epoch    6/20 Batch 2/3 Cost: 0.284550
Epoch    6/20 Batch 3/3 Cost: 0.068425
Epoch    7/20 Batch 1/3 Cost: 1.360838
Epoch    7/20 Batch 2/3 Cost: 0.211188
Epoch    7/20 Batch 3/3 Cost: 0.080784
Epoch    8/20 Batch 1/3 Cost: 0.020930
Epoch    8/20 Batch 2/3 Cost: 1.472850
Epoch    8/20 Batch 3/3 Cost: 0.189170
Epoch    9/20 Batch 1/3 Cost: 0.035691
Epoch    9/20 Batch 2/3 Cost: 1.424941
Epoch    9/20 Batch 3/3 Cost: 0.166045
Epoch   10/20 Batch 1/3 Cost: 0.060686
Epoch   10/20 Batch 2/3 Cost: 1.396403
Epoch   10/20 Batch 3/3 Cost: 0.231907
Epoch   11/20 Batch 1/3 Cost: 0.037148
Epoch   11/20 Batch 2/3 Cost: 0.016655
Epoch   11/20 Batch 3/3 Cost: 2.973856
Epoch   12/20 Batch 1/3 Cost: 0.619767
Epoch   12/20 Batch 2/3 Cost: 0.119254
Epoch   12/20 Batch 3/3 Cost: 2.519507
Epoch   13/20 Batch 1/3 Cost: 0.768937
Epoch   13/20 Batch 2/3 Cost: 0.174395
Epoch   13/20 Batch 3/3 Cost: 2.452912
Epoch   14/20 Batch 1/3 Cost: 0.833871
Epoch   14/20 Batch 2/3 Cost: 0.154394
Epoch   14/20 Batch 3/3 Cost: 2.421468
Epoch   15/20 Batch 1/3 Cost: 0.978392
Epoch   15/20 Batch 2/3 Cost: 0.593329
Epoch   15/20 Batch 3/3 Cost: 0.245716
Epoch   16/20 Batch 1/3 Cost: 0.072675
Epoch   16/20 Batch 2/3 Cost: 0.022312
Epoch   16/20 Batch 3/3 Cost: 2.895699
Epoch   17/20 Batch 1/3 Cost: 0.596071
Epoch   17/20 Batch 2/3 Cost: 1.056587
Epoch   17/20 Batch 3/3 Cost: 0.373797
Epoch   18/20 Batch 1/3 Cost: 0.122755
Epoch   18/20 Batch 2/3 Cost: 1.330193
Epoch   18/20 Batch 3/3 Cost: 0.157963
Epoch   19/20 Batch 1/3 Cost: 0.059935
Epoch   19/20 Batch 2/3 Cost: 1.359773
Epoch   19/20 Batch 3/3 Cost: 0.199119
Epoch   20/20 Batch 1/3 Cost: 0.094536
Epoch   20/20 Batch 2/3 Cost: 1.359781
Epoch   20/20 Batch 3/3 Cost: 0.145077
In [ ]: