Neural Networks

ML 문서 번역 > PyTorch Tutorial > PyTorch와 함께하는 딥러닝: 60분 리뷰 > 신경망


torch.nn 패키지를 사용하여 신경망을 만들 수 있습니다.

지금까지 autograd에 대하여 살펴보았습니다. nn 패지지는 autograd를 사용하여 모델을 정의하고 미분합니다. nn.Module은 여러 레이어와 forward(input) 메서드를 포함합니다. 이 forward 메서드는 output을 반환합니다.

다음 이미지는 디지틀 사진을 분류하는 신경망입니다.

convnet1

위 신경망은 단순한 feed-forward 네트워크입니다. 이 신경망은 입력된 데이터를 순차적으로 여러 레이어에 데이터를 공급합니다. 그리고 마지막에 결과 데이터를 제공합니다.

신경망의 일반적인 전형적인 학습 절차는 다음과 같습니다.

  • 학습 파라미터(weight)를 갖는 신경망 정의
  • 데이터셋 입력 반복
  • 네트워크 상에서 입력 데이터 처리
  • 오차(손실) 계산 (출력과 정답의 차이)
  • 네트워크 파라미터에 대한 역전파
  • 네트워크 파라미터 업데이트, 일반적으로 단순 업데이트 규칙 사용 (weight = weight - learning_rate * gradient) 사용

네트워크 정의

네트워크는 다음과 같이 정의 됩니다.

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F


class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # 입력 이미지: 1개
        # 출력 체널: 6개
        # 커널 크기: 5X5
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        # 선형 모델: y = Wx + b
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # (2, 2) 윈도우로 MaxPooling
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        # 사이즈가 정사작형이라면 하나의 숫자로 지정
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = x.view(-1, self.num_flat_features(x))
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

    def num_flat_features(self, x):
        size = x.size()[1:]  # 배치 차원을 제외한 모든 차원
        num_features = 1
        for s in size:
            num_features *= s
        return num_features


net = Net()
print(net)

출력:

Net(
  (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear(in_features=400, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)

네트워크를 정의할 때, forward 함수를 정의해야 합니다.. 기울기를 계산하는 backward 함수는 autograd를 사용하여 자동으로 정의됩니다. forward 함수에서는 모든 Tensor 연산을 사용할 수 있습니다.

모델의 모든 학습 파라미터는 net.parameters()로 얻을 수 있습니다.

params = list(net.parameters())
print(len(params))
print(params[0].size())  # conv1의 가중치 크기

출력:

10
torch.Size([6, 1, 5, 5])

forward 함수의 입력은 autograd.Variable입니다. 따라서 output도 autograd.Variable입니다. 주의할 점은 우리가 사용하는 네트워크는(LeNet)의 입력 사이즈는 32X32라는 것입니다. MNIST 데이터셋을 이 네트워크에 사용할 경우 데이터셋 이미지 크기를 32X32로 조정해야 합니다.

The input to the forward is an autograd.Variable, and so is the output. Note: Expected input size to this net(LeNet) is 32x32. To use this net on MNIST dataset, please resize the images from the dataset to 32x32.

input = Variable(torch.randn(1, 1, 32, 32))
out = net(input)
print(out)

출력:

Variable containing:
-0.0317 -0.0173  0.0242  0.0273  0.0097 -0.1078  0.0296 -0.1399 -0.0066  0.0212
[torch.FloatTensor of size 1x10]

모든 파라미터의 기울기 버퍼를 0으로 설정하고 랜덤 기울기로 역전파합니다.

net.zero_grad()
out.backward(torch.randn(1, 10))

torch.nn은 mini-batch만을 지원합니다. torch.nn 패키지 전체는 mini-batch 형태인 입력만을 지원합니다. 단일 데이터는 입력으로 취급하지 않습니다. 예를 들어서, nn.Conv2d데이터건수 x 채널수 x 높이 x 너비 형식의 4D Tensor를 취합니다. 1개 데이터를 네트웍에 입력해야 한다면, input.unsqueexe(0)을 이용하여 가짜 임시 배치 차원을 추가해서 사용합니다.

진도를 더 나가기 앞서, 지금까지 설명한 모든 절차를 요약하겠습니다.

  • 요약

    • torch.Tensor - 다차원 배열
    • augograde.Variable - Tensor 클래스를 감싸고, Tensor에 적용되는 연산의 순서를 기록, backward()와 같은 추가적인 함수를 제공. Tensor에 대한 기울기를 보관
    • nn.Module - 신경망 모듈. 파라미터를 은닉하는 편리한 방법, 파라미터의 GPU로 이동, 내보내기 및 로딩 지원 기능 제공
    • nn.Parameter - Variable의 한 유형으로 모듈의 속성으로 할당 될 때 매개 변수로 자등 등록됨.
    • autograd.Function - autograd 연산의 forward와 backward 정의를 구현. 모든 Variable 연산. 모든 Variable 연산은 Variable을 생성하고 그 히스토리를 인코딩하는 함수에 연결하는 적어도 하나의 Function 노드를 생성.
  • 지금 까지 학습한 것

    • 신경망 정의
    • 입력 처리와 backward 호출
  • 앞으로 다룰 것

    • 오차 계산
    • 네트워크 가중치 업데이트

오차 함수

손실 함수의 입력 데이터는 (출력, 타겟) 쌍입니다. 출력이 타겟과 얼마나 멀리 떨어져 있는지 추정하는 갓을 계산합니다.

nn 패키지에는 여러 오차 함수가 있습니다. 단숞ㄴ 오차 함수는 nn.MSELoss입니다. 이 함수는 입력과 타켓의 평균 제곱 오차를 계산합니다.

사용 예:

output = net(input)
target = Variable(torch.arange(1, 11))  # 예제로 사용할 더미 타켓
target = target.view(1, -1)  # 동일한 형태의
criterion = nn.MSELoss()

loss = criterion(output, target)
print(loss)

출력:

Variable containing:
 38.7519
[torch.FloatTensor of size 1]

지금, .grad_fn 속성을 이용하여 반대 방향으로 loss를 따라 가면, 다음과 같은 계산 그래프를 볼 수 있습니다.

input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d
      -> view -> linear -> relu -> linear -> relu -> linear
      -> MSELoss
      -> loss

따라서 loss.backward()를 호출하면, 전체 그래프

변수의 일종으로 모듈에 속성으로 할당 될 때 매개 변수로 자동 등록됩니다.

다음에 읽어 볼거리

VariableFunction에 대한 문서는 다음에서 찾을 수 있습니다.

코드 다운로드


  1. [역자주] Convolution Neural Network의 약자입니다. [return]
김태완 avatar
작성자: 김태완
1999년 부터 Java, Framework, Middleware, SOA, DB Replication, Cache, CEP, NoSQL, Big Data, Cloud를 키워드로 살아왔습니다. 현재는 빅데이터와 Machine Learning을 중점에 두고 있습니다.
E-mail: taewanme@gmail.com