728x90

파이토치에서 모델을 정의하기 위해서는 Module을 상속한 클래스를 사용한다. 모델과 모듈의 차이는 무엇일까?

  • 계층(layer) : 모듈 또는 모듈을 구성하는 한 개의 계층으로 합성곱층, 선형계층 등이 있다.
  • 모듈(module) : 한 개 이상의 계층이 모여서 구성된 것으로, 모듈이 모여 새로운 모듈을 만들 수도 있다.
  • 모델(model) : 최종적으로 원하는 네트워크로, 한 개의 모듈이 모델이 될 수도 있다.

1. 단순 신경망을 정의하는 방법

nn.Module을 상속받지 않는 매우 단순한 모델을 만들 때 사용한다. 구현이 쉽고 단순하다는 장점이 있다.

model = nn.Linear(in_features=1, out_features=1, bias=True)

2. nn.Module()을 상속하여 정의하는 방법

파이토치에서 nn.Module을 상속받는 모델은 기본적으로 __init__()과 forward() 함수를 포함한다. __init__()에서는 모델에서 사용될 모듈, 활성화 함수 등을 정의하고, forward() 함수에서는 모델에서 실행되어야 하는 연산을 정의한다.

다음은 파이토치에서 모델을 정의하는 코드이다.

class MLP(Module):
    def __init__(self, inputs):
        super(MLP, self).__init__()
        self.layer = Linear(inputs, 1) # 계층 정의
        self.activation = Sigmoid() # 활성화 함수 정의
        
    def forward(self, X):
        X = self.layer(X)
        X = self.activation(X)
        return X

3. Sequential 신경망을 정의하는 방법

nn.Sequential을 사용하면 __init__()에서 사용할 네트워크 모델들을 정의해 줄 뿐만 아니라 forward() 함수에서는 모델에서 실행되어야 할 계산을 좀 더 가독성이 뛰어나게 코드로 작성할 수 있다.

또한, Sequential 객체는 그 안에 포함된 각 모듈을 순차적으로 실행해 주는데 다음과 같이 코드를 작성할 수 있다.

import torch.nn as nn

class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=64, kernel_size=5),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2))
        
        self.layer2 = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=64, kernel_size=5),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2))
        
        self.layer3 = nn.Sequential(
            nn.Linear(in_features=30*5*5, out_features=10, bias=True),
            nn.ReLU(inplace=True))
        
        
        def forward(self, x):
            x = self.layer1(x)
            x = self.layer2(x)
            x = x.view(x.shape[0], -1)
            x = self.layer3(x)
            
            return x
        
model = MLP()

print('printing children \n-------------------------')
print(list(model.children()))
print('\n\nprinting Modules\n-------------------------')
print(list(model.modules()))
printing children 
-------------------------
[Sequential(
  (0): Conv2d(3, 64, kernel_size=(5, 5), stride=(1, 1))
  (1): ReLU(inplace=True)
  (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
), Sequential(
  (0): Conv2d(3, 64, kernel_size=(5, 5), stride=(1, 1))
  (1): ReLU(inplace=True)
  (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
), Sequential(
  (0): Linear(in_features=750, out_features=10, bias=True)
  (1): ReLU(inplace=True)
)]


printing Modules
-------------------------
[MLP(
  (layer1): Sequential(
    (0): Conv2d(3, 64, kernel_size=(5, 5), stride=(1, 1))
    (1): ReLU(inplace=True)
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (layer2): Sequential(
    (0): Conv2d(3, 64, kernel_size=(5, 5), stride=(1, 1))
    (1): ReLU(inplace=True)
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (layer3): Sequential(
    (0): Linear(in_features=750, out_features=10, bias=True)
    (1): ReLU(inplace=True)
  )
), Sequential(
  (0): Conv2d(3, 64, kernel_size=(5, 5), stride=(1, 1))
  (1): ReLU(inplace=True)
  (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
), Conv2d(3, 64, kernel_size=(5, 5), stride=(1, 1)), ReLU(inplace=True), MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False), Sequential(
  (0): Conv2d(3, 64, kernel_size=(5, 5), stride=(1, 1))
  (1): ReLU(inplace=True)
  (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
), Conv2d(3, 64, kernel_size=(5, 5), stride=(1, 1)), ReLU(inplace=True), MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False), Sequential(
  (0): Linear(in_features=750, out_features=10, bias=True)
  (1): ReLU(inplace=True)
), Linear(in_features=750, out_features=10, bias=True), ReLU(inplace=True)]

 

Note. model.modules() & model.children()

model.modules()는 모델의 네트워크에 대한 모든 노드를 반환하며, model.children()은 같은 수준의 하위 노드를 반환한다.

728x90

'딥러닝 > Pytorch' 카테고리의 다른 글

Pytorch 기본 문법 - 모델 훈련  (0) 2022.05.23
Pytorch 기본 문법 - 파라미터 정의  (0) 2022.05.23
Pytorch 기본 문법 - 데이터 준비  (1) 2022.05.18
Pytorch 기본 문법 - 텐서  (0) 2022.05.18
Pytorch 개요  (0) 2022.05.18

+ Recent posts