딥 러닝 프레임워크인 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 xsuper(클래스명, 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
2nn.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 모델을 설계 하는 방법을 알아 보겠습니다.