딥 러닝 프레임워크인 Pytorch
에선 신경망 구축을 위한 API를 제공합니다. 이는 torch.nn
패키지를 import
하여 사용 가능합니다.
import torch
import torch.nn as nn
import torch.nn.functional as F
이번 시간의 목차는 다음과 같습니다.
신경망 클래스를 선언하는 방법은 nn.Module
을 상속받음으로써 가능합니다. 이는 신경망 클래스의 기본이 되는 클래스 입니다. 사용 방법은 다음과 같습니다.
class DNN(nn.Module):
def __init__(self):
super(DNN, self).__init__()
def forward(self, x):
return x
super(클래스명, self).__init__()
은 무조건 클래스 생성자에 입력 해 주어야 합니다.
신경망 클래스의 멤버 변수, 멤버 함수를 선언 하기 전에, 어떻게 신경망을 설계를 할 것인지 먼저 정해야 합니다.
이에 따라서 신경망 클래스의 멤버 변수를 어떻게 설정 할 것인지는 천지차이로 달라 질 수 있습니다.
일단 털, 날개의 유무를 통해 종을 분류하는 신경망을 만든다고 가정 해 보겠습니다. 그렇다면 input
의 size는 (n, 2) 가 될 것입니다. 그리고 종의 종류가 3개라고 가정 하면, 최종 output
은 softmax
함수를 사용하여 분류된 세가지 값 중에 하나 일 것입니다. 또한, 은닉층을 한 개 놓는다고 가정하고, 활성화 함수로는 ReLU를 사용 하겠습니다. 그리고 Dropout을 이용하여, Overfitting 현상을 막아 보겠습니다. 대충 과정을 요약하면 이렇게 되겠군요.
input -> affine1 -> ReLU -> dropout -> affine2 -> softmax
한 번 구현해 볼까요?
class DNN(nn.Module):
def __init__(self):
super(DNN, self).__init__() # 필수
self.w1 = nn.Linear(2, 20) # Linear한 1차원 값의 행렬곱을 할 때 사용 한다.
self.w2 = nn.Linear(20, 3) # y = xA + b, bias 값을 가지고 있다.bias 비활성화를 원하면 bias=False를 파라미터에 입력 하면 된다.
self.relu = nn.ReLU() # ReLU 활성화 함수
self.softmax = nn.Softmax(dim=0) # Softmax 함수
self.dropout = nn.Dropout(0.5) # Dropout을 위함
def forward(self, x): # 값을 도출하는 함수
y = self.w1(x) + self.bias1
y = self.relu(y)
y = self.dropout(y)
y = self.w2(y) + self.bias2
y = self.softmax(y)
return y
이제 학습을 시킬 차례입니다. 순서는 다음과 같습니다.
model = DNN() # 객체 선언
criterion = torch.nn.CrossEntropyLoss() # loss function 설정
optim = torch.optim.Adam(model.parameters(), lr=0.01) # Optimizer 설정
x_data = torch.Tensor([
[0, 0],
[1, 0],
[1, 1],
[0, 0],
[0, 0],
[0, 1]
])
y_data = torch.LongTensor([
0, # etc
1, # mammal
2, # birds
0,
0,
2
])
for epoch in range(1000):
output = model(x_data) # model의 forward 함수 호출
loss = criterion(output, y_data) # loss function으로 값 계산
optim.zero_grad() # 변화도를 0으로 만듦
loss.backward() # 역전파
optim.step() # 역전파로 알아낸 변화도를 model에 적용
print("progress:", epoch, "loss=", loss.item())
for x in x_data:
y_pred = model(x) # 결과
print(y_pred.max(dim=0)[1].item()) # Softmax로 나온 최고 값의 Item 반환
결과는 다음과 같습니다. 원래 분류값과 같습니다.
...
progress: 999 loss= 0.8048997521400452
0
1
2
0
0
2
nn.Module.parameters()
함수를 이용하여, 신경망 내 파라미터를 확인 할 수 있습니다. 이는 iterable
한 객체를 반환 합니다. nn.Linear
같은 경우 Bias
값도 같이 가지고 있습니다.
In
for p in model.parameters():
print(p)
Out
Parameter containing:
tensor([[ 1.7096, -1.7123],
[-0.6805, 0.0985],
[ 0.1440, 1.9562],
[ 1.8654, 0.4950],
[ 0.5621, 1.7321],
[ 1.0138, 1.2981],
[-0.5106, -0.3613],
[-0.7362, 1.9065],
[ 0.4817, 1.8496],
[-0.2222, 0.3298],
[-0.2911, -0.0461],
[ 0.0025, -0.4711],
[ 0.1412, 0.3408],
[ 1.4825, -1.5597],
[-0.3180, 1.9836],
[-1.2678, -1.1919],
[ 0.2207, -0.2972],
[ 1.6377, -1.6504],
[ 1.5434, -1.5627],
[-0.6680, 0.4963]], requires_grad=True)
Parameter containing:
tensor([-0.0138, -0.3932, -0.1902, -0.0206, -0.0475, -0.0151, -0.3948, 0.5054,
-0.0722, -0.4243, -0.0933, -0.6166, -0.6943, -0.0642, 0.0584, 1.1297,
-0.6891, -0.0328, -0.0174, -0.5061], requires_grad=True)
Parameter containing:
tensor([[-4.4640e-01, -9.9519e-02, -1.4001e+00, -1.3389e+00, -1.5929e+00,
-1.4062e+00, -1.8384e-01, -2.6385e-01, -8.5617e-01, -1.5454e-01,
2.1536e-01, -1.6306e-01, -1.1615e-01, -1.0810e+00, -8.3832e-01,
2.2192e-01, -1.3481e-01, -5.9061e-01, -1.2475e+00, 1.1666e-01],
[ 1.2246e+00, -1.6060e-03, -5.1957e-01, 5.3110e-01, -1.5496e-01,
6.3452e-02, 9.0574e-03, -2.1007e+00, -1.9217e-01, 1.7074e-01,
2.0107e-01, 8.5908e-02, -6.8430e-02, 1.3706e+00, -1.3454e+00,
-1.6898e+00, -7.8466e-02, 1.2772e+00, 1.5808e+00, -4.7245e-02],
[-7.1529e-01, 2.0121e-01, 6.2016e-01, 3.4047e-01, 5.1581e-01,
4.6319e-01, -7.1984e-02, 5.3509e-01, 4.9709e-01, -1.2095e-01,
1.3305e-01, -1.1810e-01, -1.4068e-01, -2.6007e-01, 6.0926e-01,
-9.6860e-01, 3.2639e-02, -5.9985e-01, -9.6767e-01, -8.5310e-02]],
requires_grad=True)
Parameter containing:
tensor([ 0.0040, -0.0931, -0.2043], requires_grad=True)
여러 가지 Loss Function
들은 해당 링크에서 확인 할 수 있고, 다른 Optimizer
들은 해당 링크에서 확인 할 수 있습니다. 다음 시간에는 Pytorch
로 CNN
모델을 설계 하는 방법을 알아 보겠습니다.