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 |