본문 바로가기
C.W.K.
Stream
Lesson 02 of 12 · published

합성곱: 필터 공유

~22 min · conv, filters, stride

Level 0호기심
0 XP0/73 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

합성곱이 실제로 하는 일

2-D 합성곱은 작은 필터(예: 3×3 가중치)를 입력 이미지 위로 이동시키며, 각 위치에 놓인 주변 픽셀 조각의 가중합을 계산해. 같은 필터를 모든 위치에서 재사용하는 매개변수 공유 덕분에 CNN이 효율적으로 작동하지. 입력 채널이 32개이고 출력 채널이 64개인 단일 3×3 합성곱의 매개변수 수는 이미지 크기와 상관없이 3*3*32*64 + 64 = 18496개야.

층마다 채널 방향으로 여러 필터를 두고, 이런 층을 깊게 쌓으면서 그 사이에 비선형성을 넣어. 초기 층은 가장자리 검출기와 색상 덩어리를 학습하고, 중간 층은 질감과 형태의 부분을 학습하며, 깊은 층은 물체 형태의 특징을 학습해.

팁: 모든 nn.Conv2d를 ‘k×k 크기의 학습된 필터 N개를 공간 방향으로 stride s와 padding p를 적용해 움직이고, [B, N, H_out, W_out] 크기의 출력을 만든다’고 읽어. 정확한 출력 크기는 floor((H + 2p - k)/s) + 1이야.

중요한 하이퍼파라미터

  • kernel_size — 보통 3을 쓰고, 채널을 섞을 때는 가끔 1, 초기 층에서는 가끔 7을 써.
  • stride — 공간 크기를 유지할 때는 1, 다운샘플링할 때는 2를 써.
  • padding — 보통 k//2로 설정하는 ‘same’ padding을 써. stride=1이면 출력 크기가 입력과 같아져.
  • in_channels / out_channels — 이 층에서 신경망의 너비를 정해.
  • groups — 표준 합성곱에서는 1을 쓰고, 효율적인 모바일 아키텍처의 depthwise 합성곱에서는 in_channels를 써.

합성곱이 일반화하는 이유

이유는 두 가지야. 첫째는 평행이동 등변성이야. 입력을 옮기면 출력도 같은 방식으로 옮겨지므로, 모델이 위치마다 같은 특징을 다시 학습할 필요가 없어. 둘째는 매개변수 공유야. 각 필터를 이미지 전체에서 재사용하므로 매개변수가 훨씬 적고, 각 매개변수는 완전 연결층에서보다 훨씬 많은 데이터로 학습돼.

원칙: 합성곱은 지역성과 평행이동을 기본 가정으로 구조에 담아. 이미지나 오디오 스펙트로그램처럼 이 가정이 데이터에 맞으면 CNN은 완전 연결 모델보다 훨씬 적은 매개변수로 효율적으로 학습해. 표 형식 데이터나 집합값 데이터처럼 가정이 맞지 않으면 다른 아키텍처를 써.

Code

직접 추적하는 Conv2d 출력 크기·python
import torch
import torch.nn as nn

x = torch.randn(8, 3, 224, 224)              # [B, C, H, W]

conv = nn.Conv2d(in_channels=3, out_channels=64,
                 kernel_size=3, stride=2, padding=1)
y = conv(x)
print(y.shape)  # torch.Size([8, 64, 112, 112])
# H_out = floor((224 + 2*1 - 3) / 2) + 1 = 112

# Channel-mix 1x1 conv (no spatial change, just learns linear combos of channels)
conv1x1 = nn.Conv2d(64, 32, kernel_size=1)
print(conv1x1(y).shape)  # torch.Size([8, 32, 112, 112])
깊이별 분리 합성곱(모바일 효율화 기법)·python
class DepthwiseSeparable(nn.Module):
    def __init__(self, in_ch, out_ch):
        super().__init__()
        self.dw = nn.Conv2d(in_ch, in_ch, 3, padding=1, groups=in_ch, bias=False)
        self.pw = nn.Conv2d(in_ch, out_ch, 1, bias=False)
    def forward(self, x):
        return self.pw(self.dw(x))
# Far fewer params than a full Conv2d(in_ch, out_ch, 3) — same receptive field

External links

Exercise

nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)를 [B, 3, 224, 224] 입력에 적용했을 때의 출력 크기를 손으로 계산해. PyTorch로 결과를 확인해. 그런 다음 stride와 padding을 바꾸고, 코드를 실행하기 전에 매번 출력 크기를 예측해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.