Stats & AI tech blog - '일단 시도함'

[Python] PyTorch에서 신경망 모델 정의 본문

Programming/Python

[Python] PyTorch에서 신경망 모델 정의

justdoit ok? 2024. 4. 5. 11:28

이번 포스팅에서는 파이토치(PyTorch)에서 신경망 모델을 정의하는 방법에 대해 알아보려고 한다.

모델을 정의할 때는 계층(Layer), 모듈(Module), 모델(Model) 3가지 개념을 먼저 알아야 한다.

 

  • 계층 (Layer)
    합성곱층이나 선형계층 등이 있고 계층이 모여 모듈이나 모델을 구성한다.
  • 모듈 (Module)
    하나 이상의 계층이 모여 모듈이 되거나, 모듈이 모여 새로운 모듈을 만들 수도 있다.
  • 모델 (Model)
    최종적으로 원하는 신경망 구조로 한 개의 모듈이 모델이 될 수도 있다.

 

계층과 모듈을 사용해서 신경망 모델을 정의하는 방법에도 여러 가지가 있는데 하나씩 알아보겠다.

 

1. 단순 신경망 정의 

모듈을 상속받지 않는 아주 간단한 모델을 만들 때 사용하는 방법으로 구현이 쉽고 단순하다는 장점이 있다.

# 입력 텐서와 출력 텐서의 크기가 1인, 선형 변환을 수행하는 모델
model = nn.Linear(in_features=1, out_features=1, bias=True)

 

 

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

nn.Module을 상속받는 모델에는 기본적으로 __init__()forward() 함수를 포함해야한다.

__init__()에서는 모델에서 사용할 모듈(nn.Linear, nn.Conv2d)들을 정의하고, forward()에서는 모델에서 수행할 연산을 정의한다.

# nn.Module을 상속받아 선형 변환 후 시그모이드 변환하는 순전파 모델 구현
class MLP(nn.Module):
	def __init__(self, inputs):
    	super(MLP, self).__init__() # module 상속
        self.layer = nn.Linear(inputs, 1) # layer 정의
        self.activation = Sigmoid() # 활성화함수 정의
        
    def forward(self, X): # 모델의 순전파 동작 구현    
    	X = self.layer(X) 
        X = self.activation(X)
        return X

 

3. Sequential 신경망 정의

nn.Sequential을 사용하면 nn.Module처럼 __init__()에서 사용할 신경망 모델들을 정의해줄 수 있다.

차이점은 forward() 함수에서 실행할 연산을 더 가독성있게 작성할 수 있고, 꼭 forward()를 정의하지 않아도 자동으로 순전파 동작이 실행된다는 특징이 있다는 점이다. nn.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=64, out_channels=30, 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() # 모델에 대한 객체 생성

 

 

4. 함수로 신경망 정의

앞의 3가지 방식은 모두 모듈을 상속받아 클래스를 정의하는 방식으로 신경망을 만들었다.

비슷한 방법이지만 클래스가 아닌 함수 형태로 모델을 정의할 수도 있는데, 이 경우엔 변수에 저장해놓은 계층들을 재사용할 수 있다는 장점이 있지만, 모델이 복잡해지는 단점도 존재한다.

따라서 복잡한 모델을 정의할 때는 함수보다는 모듈 상속 클래스를 사용하는게 편리하다.

def MLP(in_feature=1, hidden_features=2, out_features=1):
    hidden = nn.Linear(in_features=in_features, out_features=hidden_features, bias=True)
    activation = nn.ReLU()
    output = nn.Linear(in_features=hidden_features, out_features=out_features, bias=True)
    
    net = nn.Sequential(hidden, activation, output)
    return net

 

 

여기까지 파이토치(PyTorch)에서 신경망 모델을 정의하기 위한 몇 가지 방법을 알아보았다.

정리해 보자면,

 - 모듈 상속 없이 모델 정의 (아주 단순한 모델일 때)

 - nn.Module, nn.Sequential을 상속받는 클래스로 모델 정의 (일반적으로 사용)

 - 클래스가 아닌 함수 형태로 모델 정의 (모델이 복잡하지 않고 계층 재사용이 필요할 때)

 

다음 포스팅에서는 모델 학습 전에 정의해야 할 모델 파라미터에 대해 알아보도록 하겠다.

2024.04.05 - [Programming/Python] - [Python] PyTorch에서 신경망 모델 파라미터 정의 (손실함수/옵티마이저/학습률 스케줄러)

 

 

 

 

 

* Reference

 - 딥러닝 파이토치 교과서