
딥러닝 아키텍처, 특히 합성곱 신경망(Convolutional Neural Networks, CNN)을 설계할 때 초보자와 숙련자를 막론하고 가장 자주 마주치는 난관은 바로 '레이어를 통과한 후 데이터의 차원(Dimension)이 어떻게 변하는가'입니다. PyTorch에서 RuntimeError: size mismatch 메시지를 마주하지 않으려면, Padding과 Stride가 출력 크기에 미치는 영향을 수학적으로 완벽히 이해해야 합니다. 본 가이드에서는 실무에서 즉시 활용 가능한 계산 공식과 최적의 하이퍼파라미터 조합법을 상세히 다룹니다.
1. CNN 출력 크기 계산의 기본 메커니즘
CNN 레이어의 출력 크기는 입력 데이터의 크기($W$), 커널(필터) 크기($F$), 패딩($P$), 그리고 스트라이드($S$)의 네 가지 변수에 의해 결정됩니다. 이를 공식화하면 다음과 같습니다.
표준 출력 크기 계산 공식:
$$OH = \lfloor \frac{H + 2P - F}{S} \rfloor + 1$$ $$OW = \lfloor \frac{W + 2P - F}{S} \rfloor + 1$$ * $H, W$: 입력 높이/너비, $P$: 패딩, $F$: 커널 크기, $S$: 스트라이드
2. Padding과 Stride의 역할 및 차이점 요약
두 파라미터는 공간적 해상도를 제어한다는 공통점이 있지만, 그 목적과 결과는 판이하게 다릅니다.
| 특성 | 패딩 (Padding) | 스트라이드 (Stride) |
|---|---|---|
| 주요 목적 | 외곽 정보 보존 및 출력 크기 유지 | 데이터 다운샘플링 및 연산량 감소 |
| 데이터 변화 | 입력 데이터 가장자리에 특정 값(보통 0) 추가 | 필터가 이동하는 간격을 넓힘 |
| 출력 크기 영향 | 값이 커질수록 출력 크기가 커짐 | 값이 커질수록 출력 크기가 작아짐 |
| 해결하는 문제 | 레이어를 거칠수록 피쳐맵이 작아지는 현상 방지 | 차원 축소를 통한 계산 효율성 증대 |
3. 개발자를 위한 실무 적용 PyTorch Example (7가지)
다양한 시나리오에서 출력 크기를 계산하고 검증하는 실무 코드를 확인해 보십시오.
Example 1: 'Same' Padding 구현 (입력과 출력 크기 동일화)
가장 많이 쓰이는 기법으로, 필터 크기가 $K$일 때 패딩을 $(K-1)/2$로 설정합니다.
import torch
import torch.nn as nn
# 입력: 32x32, 커널: 3, 패딩: 1, 스트라이드: 1
conv_same = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)
input_data = torch.randn(1, 3, 32, 32)
output = conv_same(input_data)
print(output.shape) # torch.Size([1, 16, 32, 32])
Example 2: Stride를 이용한 빠른 차원 축소
Pooling 레이어 대신 Stride 2를 사용하여 Feature Map을 절반으로 줄이는 기법입니다.
# 입력: 64x64 -> 출력: 32x32
conv_stride = nn.Conv2d(3, 16, kernel_size=3, stride=2, padding=1)
input_data = torch.randn(1, 3, 64, 64)
output = conv_stride(input_data)
print(output.shape) # torch.Size([1, 16, 32, 32])
Example 3: Dileted Convolution(공동 합성곱)에서의 크기 계산
Dilation($D$)이 적용될 경우 유효 커널 크기는 $F_{eff} = F + (F-1)(D-1)$이 됩니다.
# Dilation 2 적용 시 수용 영역 확장
conv_dilated = nn.Conv2d(3, 16, kernel_size=3, dilation=2, padding=0)
output = conv_dilated(torch.randn(1, 3, 10, 10))
# (10 + 2*0 - 5)/1 + 1 = 6
print(output.shape) # torch.Size([1, 16, 6, 6])
Example 4: 짝수 크기 커널과 비대칭 패딩 해결
PyTorch의 기본 padding은 양방향 동일 적용이므로, 비대칭이 필요할 땐 ZeroPad2d를 활용합니다.
pad_layer = nn.ZeroPad2d((1, 2, 1, 2)) # 좌, 우, 상, 하 비대칭 패딩
conv = nn.Conv2d(3, 16, kernel_size=4)
# 별도의 패딩 레이어를 먼저 통과시킨 후 Conv 연산 수행
Example 5: Transposed Convolution (Upsampling) 공식
생성 모델(GAN) 등에서 크기를 키울 때 사용하며, 공식이 일반 Conv의 역순입니다.
# 입력: 10x10 -> 출력: 21x21 (S=2, P=1, K=3)
upconv = nn.ConvTranspose2d(16, 8, kernel_size=3, stride=2, padding=1, output_padding=0)
output = upconv(torch.randn(1, 16, 10, 10))
print(output.shape) # torch.Size([1, 8, 19, 19])
Example 6: 계산기를 통한 자동 검증 유틸리티 제작
네트워크 설계 시 수동 계산 실수를 방지하기 위한 파이썬 함수입니다.
def calc_output_size(w, k, p, s):
return ((w + 2*p - k) // s) + 1
print(f"Result: {calc_output_size(w=224, k=7, p=3, s=2)}") # ResNet 첫 레이어 예시
Example 7: 정수형 출력이 나오지 않는 설정 오류 방지
공식 결과가 소수점이 나올 경우 PyTorch는 내림(floor)을 수행하므로, 정보 손실에 주의해야 합니다.
# 입력 5x5, 커널 3, 스트라이드 2, 패딩 0 -> (5-3)/2 + 1 = 2
# 만약 입력 6x6이면 (6-3)/2 + 1 = 2.5 -> 2로 처리됨
conv_error_check = nn.Conv2d(1, 1, kernel_size=3, stride=2)
print(conv_error_check(torch.randn(1, 1, 6, 6)).shape)
4. 전문적인 최적화 제언
성능 극대화를 위해서는 단순히 크기 계산에 그치지 않고 하드웨어 가속(cuDNN)이 선호하는 크기를 고려해야 합니다. 대개 8의 배수나 2의 거듭제곱 형태로 채널과 피쳐맵 크기를 유지하는 것이 메모리 정렬 및 연산 효율성 측면에서 유리합니다.
5. 출처 및 참고 문헌
- Dumoulin, V., & Visin, F. (2016). A guide to convolution arithmetic for deep learning. arXiv.
- PyTorch Official Documentation: torch.nn.modules.conv.
- CS231n: Convolutional Neural Networks for Visual Recognition, Stanford University.
'Artificial Intelligence > 21. PyTorch' 카테고리의 다른 글
| [PYTORCH] 드롭아웃(Dropout) 학습 및 테스트 동작 차이 2가지와 실무 해결 방법 7가지 (0) | 2026.03.24 |
|---|---|
| [PYTORCH] 배치 정규화(Batch Normalization)의 3가지 핵심 역할과 최적 위치 선정을 위한 해결 방법 (0) | 2026.03.24 |
| [PYTORCH] nn.Conv2d 입력 및 출력 채널 설정의 2가지 핵심 원칙과 차원 불일치 해결 방법 (0) | 2026.03.24 |
| [PYTORCH] Max Pooling과 Average Pooling의 3가지 결정적 차이와 상황 별 해결 방법 (0) | 2026.03.24 |
| [PYTORCH] LSTM vs GRU: 3가지 결정적 차이와 프로젝트 별 최적의 RNN 선택 방법 (0) | 2026.03.24 |