Language-LAB/Pytorch

torch.nn.Sequential

JS LAB 2025. 3. 23. 02:26
728x90
반응형

torch.nn.Sequential 설명과 예시

torch.nn.Sequential은 PyTorch에서 신경망 레이어를 순차적으로 연결하기 위한 컨테이너 모듈입니다. 복잡한 네트워크 구조를 간결하게 정의하고, 데이터가 레이어를 통과하는 순서를 명확하게 지정할 수 있습니다.

기본 개념

  • 여러 레이어를 순서대로 연결하여 하나의 모듈로 관리
  • 입력 데이터가 첫 번째 레이어부터 마지막 레이어까지 순차적으로 통과
  • 각 레이어의 출력이 다음 레이어의 입력으로 자동 전달
  • 모듈 전체를 하나의 함수처럼 호출 가능

간단한 예시 1: 기본 사용법

import torch
import torch.nn as nn

# Sequential을 사용하여 간단한 신경망 정의
model = nn.Sequential(
    nn.Linear(10, 20),  # 입력 차원: 10, 출력 차원: 20
    nn.ReLU(),          # 활성화 함수
    nn.Linear(20, 15),  # 입력 차원: 20, 출력 차원: 15
    nn.ReLU(),
    nn.Linear(15, 1)    # 출력 레이어
)

# 입력 데이터 생성 (배치 크기: 5, 입력 차원: 10)
x = torch.randn(5, 10)

# 순전파 수행
output = model(x)
print(output.shape)  # torch.Size([5, 1])

이 예시에서 데이터의 흐름은:

  • 입력 x: [5, 10]
  • 첫 번째 Linear: [5, 10] → [5, 20]
  • ReLU: [5, 20] → [5, 20] (값만 변경)
  • 두 번째 Linear: [5, 20] → [5, 15]
  • ReLU: [5, 15] → [5, 15] (값만 변경)
  • 세 번째 Linear: [5, 15] → [5, 1]
  • 최종 출력: [5, 1]

예시 2: 명명된 레이어 사용

OrderedDict를 사용하여 각 레이어에 이름을 부여할 수 있습니다:

from collections import OrderedDict

named_model = nn.Sequential(OrderedDict([
    ('fc1', nn.Linear(10, 20)),
    ('relu1', nn.ReLU()),
    ('fc2', nn.Linear(20, 15)),
    ('relu2', nn.ReLU()),
    ('fc3', nn.Linear(15, 1))
]))

# 레이어 접근
print(named_model.fc1)  # Linear(in_features=10, out_features=20, bias=True)

# 동일하게 사용
output = named_model(x)
print(output.shape)  # torch.Size([5, 1])

예시 3: 리스트의 레이어 사용

리스트에 레이어를 추가한 후 * 연산자로 풀어서 전달하는 방식:

layers = []
layers.append(nn.Linear(10, 20))
layers.append(nn.ReLU())
layers.append(nn.Linear(20, 15))
layers.append(nn.ReLU())
layers.append(nn.Linear(15, 1))

# *layers는 리스트의 원소들을 개별 인자로 풀어서 전달
list_model = nn.Sequential(*layers)

output = list_model(x)
print(output.shape)  # torch.Size([5, 1])

이 방식은 MultiLayerPerceptron 클래스에서 사용된 방법과 동일합니다.

예시 4: 조건부 레이어 추가

조건에 따라 레이어를 추가하는 예:

def create_model(input_dim, hidden_dims, output_dim, use_batchnorm=True):
    layers = []

    # 첫 번째 레이어
    layers.append(nn.Linear(input_dim, hidden_dims[0]))

    # 조건부로 배치 정규화 추가
    if use_batchnorm:
        layers.append(nn.BatchNorm1d(hidden_dims[0]))

    layers.append(nn.ReLU())

    # 나머지 은닉층
    for i in range(1, len(hidden_dims)):
        layers.append(nn.Linear(hidden_dims[i-1], hidden_dims[i]))
        if use_batchnorm:
            layers.append(nn.BatchNorm1d(hidden_dims[i]))
        layers.append(nn.ReLU())

    # 출력 레이어
    layers.append(nn.Linear(hidden_dims[-1], output_dim))

    return nn.Sequential(*layers)

# 사용 예
model = create_model(10, [20, 15], 1, use_batchnorm=True)
print(model)  # 모델 구조 출력

Sequential의 장점

  1. 간결함: 복잡한 forward 메서드 없이 네트워크 구조 정의 가능
  2. 가독성: 데이터 흐름이 명확하게 시각화됨
  3. 모듈성: 레이어 그룹을 쉽게 교체하거나 재사용 가능
  4. 편의성: 레이어 추가/삭제가 간단함

제한사항

  1. 단순 순차 구조만 가능: 분기, 스킵 연결 등 복잡한 구조는 직접 구현 필요
  2. 중간 출력 접근 제한: 중간 레이어 출력을 별도로 사용하기 어려움

복잡한 네트워크 구조(ResNet, U-Net 등)는 일반적으로 사용자 정의 Module 클래스로 구현하며, Sequential은 간단한 선형 흐름을 가진 구성 요소에 주로 사용됩니다.

728x90
반응형