파이토치에서 MLP 구현하는 방법

파이토치에서 MLP 구현하는 방법

How to construct MLP in PyTorch

라이브러리

import torch
import torch.nn as nn
import torch.nn.functional as F

nnnn.functional에는 뉴럴 네트워크를 구성하는 여러가지 레이어, 손실함수, 활성화 함수 등이 포함되어있다.

인공신경망 정의

fully connected layer 3개를, relu 활성화 함수를 써서 쌓은 MLPmulti layer perceptron를 만들고 싶다면 다음과 같은 코드로 구현할 수 있다.

class Custom_Net(nn.Module):
    def __init__(self):
        super(Custom_Net, self).__init__()

        self.fully_cnnected_1 = nn.Linear(1024, 1024, bias=False)
        self.fully_cnnected_2 = nn.Linear(1024, 512, bias=False)
        self.fully_cnnected_3 = nn.Linear(512, 10, bias=True)
                        
    def forward(self, x):

        x = f.view(-1,1024)

        x = self.fully_cnnected_1(x)
        x = F.relu(x)
        x = self.fully_cnnected_2(x)
        x = F.relu(x)
        x = self.fully_cnnected_2(x)
        x = F.relu(x)
        
        return x

nn.Linear(m, n, bias=True)에서 m은 입력값의 차원, n은 출력값의 차원을 의미한다. 가중치를 원하는 방법으로 초기화할 수도 있다.

만약 MLP에서 이미지 등의 2차원 배열을 입력으로 사용할거라면 x = x.view(-1,m)을 사용하여 입력 데이터를 한 줄로 펴주어야 한다. -1은 나머지 값을 알아서 처리하라는 의미이며, 배치 학습을 시킬 경우 배치 사이즈와 같아진다.

옵티마이저와 손실함수 정의

위에서 만든 모델, 옵티마이저, 손실함수 등을 다음과 같이 정의한다. 만약 GPU를 사용한다면 .to(DEVICE)를 써서 GPU에 올려야한다. 당연히 DEVICE는 사용할 GPU로 위에서 미리 정의해야한다. lr러닝 레이트를 의미한다.

model = Custom_Net().to(DEVICE)

optimizer = torch.optim.Adam(model.parameters()), lr = 0.0001)
criterion = nn.MSELoss()

print로 뉴럴 네트워크가 어떻게 구성됐는지 확인할 수 있다.

>>> print(model)
Custom_Net(
  (fully_cnnected_1): Linear(in_features=1024, out_features=1024, bias=False)
  (fully_cnnected_2): Linear(in_features=1024, out_features=512, bias=False)
  (fully_cnnected_3): Linear(in_features=512, out_features=10, bias=True)
)

학습

입력 $X$와 출력 $Y$로 구성된 적당한 데이터 셋 Data_set이 주어졌다고 하자. 그러면 정의한 모델을 학습시키는 함수를 다음과 같이 구현할 수 있다.

def train():
    model.train()
            
    for batch_idx, (X, Y) in enumerate(Data_set):
        
        optimizer.zero_grad()

        output = model(X)
        
        loss = criterion(output, Y)
        loss.backward()
        optimizer.step()

    return loss
  • model.train(): 모델을 학습 모드로 바꾸어준다. 모델 안의 가중치를 수정할 수 있게된다.
  • optimizer.zero_grad(): 옵티마이저가 이전에 계산했던 것을 초기화한다.
  • loss = criterion(output, Y): 미리 정의해둔 손실함수로 loss를 계산한다.
  • loss.backward(): 역 전파 알고리즘으로 loss에 대한 $\delta$ 값들을 계산한다.
  • optimizer.step(): 계산한 $\delta$를 바탕으로 옵티마이저를 최적화 한다.

전체코드

#필요한 라이브러리 import
import torch
import torch.nn as nn
import torch.nn.functional as F

#모델 정의
class Custom_Net(nn.Module):
    def __init__(self):
        super(Custom_Net, self).__init__()

        self.fully_cnnected_1 = nn.Linear(1024, 1024, bias=False)
        self.fully_cnnected_2 = nn.Linear(1024, 512, bias=False)
        self.fully_cnnected_3 = nn.Linear(512, 10, bias=True)
                        
    def forward(self, x):

        x = f.view(-1,1024)

        x = self.fully_cnnected_1(x)
        x = F.relu(x)
        x = self.fully_cnnected_2(x)
        x = F.relu(x)
        x = self.fully_cnnected_2(x)
        x = F.relu(x)
        
        return x

model = Custom_Net().to(DEVICE)

#옵티마이저, 손실함수 설정
optimizer = torch.optim.Adam(model.parameters()), lr = 0.0001)
criterion = nn.MSELoss()
EPOCHS = 1000

#학습함수 정의
def train():
    model.train()
            
    for batch_idx, (X, Y) in enumerate(Data_set):
        
        optimizer.zero_grad()

        output = model(X)
        
        loss = criterion(output, Y)
        loss.backward()
        optimizer.step()

        print(loss)

    return loss

#학습
for epoch in range(1, EPOCHS):
    loss = train()

환경

  • OS: Windows10
  • Version: Python 3.9.2, torch 1.8.1+cu111
댓글