7.3. Padding and Stride
7.3.1. Padding
import torch
from torch import nn
def comp_conv2d(conv2d, X):
X = X.reshape((1, 1) + X.shape)
Y = conv2d(X)
return Y.reshape(Y.shape[2:])
conv2d = nn.LazyConv2d(1, kernel_size=3, padding=1)
X = torch.rand(size=(8, 8))
comp_conv2d(conv2d, X).shape
conv2d = nn.LazyConv2d(1, kernel_size=(5, 3), padding=(2, 1))
comp_conv2d(conv2d, X).shape
7.3.2. Stride
conv2d = nn.LazyConv2d(1, kernel_size=3, padding=1, stride=2)
comp_conv2d(conv2d, X).shape
conv2d = nn.LazyConv2d(1, kernel_size=(3, 5), padding=(0, 1), stride=(3, 4))
comp_conv2d(conv2d, X).shape
1. 커널 크기 (3, 5), 패딩 (0, 1), 스트라이드 (3, 4)에서 출력 크기 계산
출력 높이 = (입력 높이 - 커널 높이 + 2*패딩 높이)/(스트라이드 높이) + 1 = 3.67
출력 너비 = (입력 너비 - 커널 너비 + 2*패딩 너비)/(스트라이드 너비) + 1 = 2
출력 크기는 (3, 2)
2. Audio signal에서 stride=2는 샘플 간격을 2배로 늘려 두 샘플 중 하나만 사용해 데이터를 처리하는 것을 의미. 이는 입력 신호의 길이를 절반으로 줄여 데이터를 더 적게 사용하므로 연산량이 줄고, 처리 속도는 빨라지지만 세부 정보가 덜 반영될 수 있다.
3. Mirror padding은 경계의 값을 반사하는 방식으로 패딩을 추가하는 것.
import torch.nn.functional as F
X = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
X_padded = F.pad(X, (1, 1, 1, 1), mode='reflect')
print(X_padded)
4. stride가 1보다 큰 경우의 계산적 이점: 데이터의 중복된 계산을 피할 수 있어 연산 효율이 좋아진다. 모델을 더 빠르게 학습시키고, 메모리 사용량을 줄이는 데 효과적이다.
5. stride 가 1보다 큰 경우의 통계적 이점: 입력 데이터의 특정 구역에서 더 전역적인 특징을 추출할 수 있다. 특히 연속성이 강한 데이터에서는 더 큰 간격의 정보를 얻어 과적합을 방지할 수 있으며, 데이터를 압축하면서 중요한 특징만을 뽑아내는 효과가 있다.
6. stride=1/2 를 구현하는 방법: 합성곱 연산에서 바로 구현할 수는 없지만, upsampling 기법을 사용하여 비슷한 효과를 낼 수 있다. 예를 들어 입력 데이터 사이사이에 0을 채워넣는 방식으로 크기를 두 배로 늘린 다음, 일반적인 합성곱 연산을 수행하면 된다. 이는 Transposed convolution, Fractional stride 라고 부르기도 한다. 이 방식은 주로 이미지를 고해상도로 복원하거나 더 세밀한 정보를 필요로 하는 경우에 유용하다.
+++ 개념 정리
1. LazyConv2d: Pytorch 에서 제공하는 합성곱 계층의 변형으로, 초기화 시 입력 채널 수를 명시적으로 지정하지 않고 나중에 데이터가 실제로 입력될 때 자동으로 입력 채널 수를 설정하는 계층. 주로 네트워크으 ㅣ입력 형태를 미리 알기 어려운 경우에 유용하게 사용된다.