검색
← 모듈 로드맵

스탠퍼드 CS231n 강의 노트(합성곱 신경망)

강의 · 입문자 · Stanford

원제 · CS231n: Deep Learning for Computer Vision

합성곱 한 칸 · 출력 크기 · 파라미터 수 · 풀링 · 수용 영역을 손계산으로 익히는 CNN 수업

먼저 알아야 할 것

행렬 곱완전 연결 층 · ReLU소프트맥스 분류파이썬 · NumPy

다루는 내용

CS231n 노트의 합성곱 신경망 편을 바탕으로 한 자체 수업입니다. 이미지 텐서와 완전 연결 층의 파라미터 폭발을 숫자로 보고, 3×3 필터 합성곱과 최대 풀링을 손으로 계산합니다. 출력 크기 공식 (W−F+2P)/S+1과 파라미터 수, AlexNet 첫 층 계산, 3×3 세 겹 대 7×7 한 겹(27C² 대 49C²), CNN 층 쌓기 패턴과 VGGNet 사례를 다룹니다.

해설

스탠퍼드 CS231n 강의 노트(합성곱 신경망) — 수업: 합성곱 층을 손으로 계산하기

스탠퍼드 CS231n 공개 노트의 「Convolutional Neural Networks」 편을 중심으로, 이미지를 다루는 합성곱 신경망(CNN)의 계산을 우리 말로 다시 짠 수업입니다. 합성곱 한 칸을 손으로 계산하고, 출력 크기 공식과 파라미터 수를 직접 세고, 풀링과 수용 영역, 층을 쌓는 패턴까지 이 페이지에서 익힙니다.

항목내용
출처CS231n: Deep Learning for Computer Vision 강의 노트 · Stanford · cs231n.github.io · 중심 노트 Convolutional Neural Networks
트랙 · 수준딥러닝 기초 · 기초
이 수업이 다루는 범위이미지 텐서, 완전 연결 층의 한계, 합성곱 연산 · 출력 크기 · 파라미터 공유, 풀링, 수용 영역, 층 쌓기 패턴, 사례(AlexNet 첫 층 · VGGNet)
형식원문 번역이 아닌 자체 해설 · 숫자 예는 해설용으로 직접 만든 것(노트에서 가져온 수치는 따로 표시)

들어가기 전에

한눈에 보기

  • 이미지는 가로 × 세로 × 채널의 3차원 텐서이고, 완전 연결 층으로 다루면 파라미터가 폭발한다는 것을 숫자로 봅니다.
  • 3×3 필터 합성곱을 손으로 계산하고, 필터가 '무늬 탐지기'라는 뜻을 이해합니다.
  • 출력 크기 (W−F+2P)/S+1(W - F + 2P)/S + 1과 파라미터 수 (F⋅F⋅D1)⋅K+K(F \cdot F \cdot D_1) \cdot K + K를 직접 계산할 수 있습니다.
  • 풀링이 무엇을 버리고 무엇을 남기는지, 3×3을 세 번 쌓으면 왜 7×7 하나보다 나은지 압니다.
  • INPUT → [[CONV → RELU]*N → POOL?]*M → [FC → RELU]*K → FC 패턴으로 CNN 구조를 읽습니다.

1. 이미지는 텐서, 완전 연결 층은 너무 크다

직관(해설용 비유): 사진 한 장을 숫자 한 줄로 길게 펴서 넣으면, 모델은 "이웃한 픽셀끼리 관계가 깊다"는 사실을 모른 채 모든 픽셀 쌍의 관계를 처음부터 배워야 합니다. 돋보기로 작은 부분씩 보는 편이 훨씬 효율적입니다.

컬러 이미지는 가로 WW × 세로 HH × 채널 DD(빨강 · 초록 · 파랑 3개)의 숫자 덩어리, 즉 3차원 텐서입니다. 노트는 이것을 '부피(volume)'라고 부릅니다.

숫자로 해 보기: 32×32×3 이미지(CIFAR-10 크기)를 완전 연결 뉴런 하나에 넣으면 가중치가 32⋅32⋅3=3,07232 \cdot 32 \cdot 3 = 3{,}072개입니다(노트에도 나오는 계산). 이런 뉴런 100개짜리 층이면 3,072×100+100=307,3003{,}072 \times 100 + 100 = 307{,}300개 파라미터입니다(해설용). 200×200×3 이미지라면 뉴런 하나에 120,000120{,}000개가 필요합니다. 큰 이미지에서는 금세 감당이 안 되고 과적합도 쉬워집니다.

선형 분류기의 한계: 이미지를 펴서 Wx+bW\mathbf{x} + \mathbf{b}로 점수를 내는 선형 분류기는 클래스마다 '평균 그림' 하나와 겹쳐 보는 템플릿 대조에 가깝습니다. 말이 왼쪽을 보든 오른쪽을 보든 템플릿 하나로 맞춰야 하니 한계가 큽니다. 위치가 바뀌어도 같은 무늬를 찾는 구조가 필요합니다.

2. 합성곱 연산

직관: 작은 필터(예: 3×3)를 이미지 위에 놓고, 겹치는 칸끼리 곱해 더한 값 하나를 적습니다. 필터를 한 칸씩 밀며 반복하면 '이 무늬가 어디에 얼마나 있나'를 나타내는 지도(활성화 지도, activation map)가 나옵니다.

단계:

  1. 필터 크기 FF, 개수 KK, 이동 간격(스트라이드) SS, 가장자리 0 덧대기(패딩) PP를 정합니다.
  2. 필터를 입력의 왼쪽 위에 놓고, 겹친 F×F×D1F \times F \times D_1개 값을 곱해 모두 더하고 편향을 더합니다.
  3. SS칸씩 옮기며 반복해 2차원 지도 하나를 만듭니다.
  4. 필터 KK개마다 지도를 하나씩 만들어 깊이 방향으로 쌓으면 출력 부피가 됩니다.
yi,j=∑a=0F−1∑b=0F−1∑c=1D1wa,b,c  xiS+a, jS+b, c+b0y_{i,j} = \sum_{a=0}^{F-1}\sum_{b=0}^{F-1}\sum_{c=1}^{D_1} w_{a,b,c}\; x_{iS+a,\ jS+b,\ c} + b_0
기호뜻
xx입력 부피(패딩 포함), 첨자는 (행, 열, 채널)
ww필터 하나의 가중치, 크기 F×F×D1F \times F \times D_1
b0b_0그 필터의 편향
yi,jy_{i,j}출력 지도의 (i,j)(i, j) 칸
SS스트라이드
D1D_1입력 채널 수 — 필터는 항상 입력의 깊이 전체를 덮음

숫자로 해 보기(해설용): 채널 1개짜리 4×4 입력에 세로 경계를 찾는 3×3 필터를 스트라이드 1, 패딩 0으로 적용합니다.

X=(1201013121001012),K=(10−110−110−1)X = \begin{pmatrix} 1 & 2 & 0 & 1\\ 0 & 1 & 3 & 1\\ 2 & 1 & 0 & 0\\ 1 & 0 & 1 & 2 \end{pmatrix}, \qquad K = \begin{pmatrix} 1 & 0 & -1\\ 1 & 0 & -1\\ 1 & 0 & -1 \end{pmatrix}
  • 왼쪽 위 칸: 3×3 창의 왼쪽 열 합 1+0+2=31 + 0 + 2 = 3, 오른쪽 열 합 0+3+0=30 + 3 + 0 = 3 → 3−3=03 - 3 = 0
  • 오른쪽 위 칸: 창은 열 2~4, 왼쪽 열 2+1+1=42 + 1 + 1 = 4, 오른쪽 열 1+1+0=21 + 1 + 0 = 2 → 22
  • 왼쪽 아래: 행 2~4, 열 1~3, 왼쪽 열 0+2+1=30 + 2 + 1 = 3, 오른쪽 열 3+0+1=43 + 0 + 1 = 4 → −1-1
  • 오른쪽 아래: 왼쪽 열 1+1+0=21 + 1 + 0 = 2, 오른쪽 열 1+0+2=31 + 0 + 2 = 3 → −1-1

출력은 (02−1−1)\begin{pmatrix} 0 & 2\\ -1 & -1\end{pmatrix}입니다. 이 필터는 "왼쪽이 밝고 오른쪽이 어두운 세로 경계"에서 큰 양수를 냅니다.

왜 이렇게 하나 — 두 가지 가정:

  • 국소 연결(local connectivity): 뉴런 하나는 입력의 작은 공간 영역(수용 영역)만 봅니다. 이웃 픽셀의 관계가 가장 중요하기 때문입니다. 단, 깊이 방향으로는 항상 전체 채널을 봅니다.
  • 파라미터 공유(parameter sharing): 같은 지도 안의 모든 위치가 같은 필터를 씁니다. "세로 경계를 찾는 법"은 왼쪽 위에서나 오른쪽 아래에서나 같다는 가정입니다. 노트는 얼굴처럼 위치마다 다른 특징이 필요한 경우엔 이 가정을 완화하기도 한다고 덧붙입니다.

3. 출력 크기와 파라미터 수

노트가 정리한 합성곱 층 요약입니다.

W2=W1−F+2PS+1,H2=H1−F+2PS+1,D2=KW_2 = \frac{W_1 - F + 2P}{S} + 1, \qquad H_2 = \frac{H_1 - F + 2P}{S} + 1, \qquad D_2 = K
가중치 수=(F⋅F⋅D1)⋅K,편향 수=K\text{가중치 수} = (F \cdot F \cdot D_1) \cdot K, \qquad \text{편향 수} = K
기호뜻
W1,H1,D1W_1, H_1, D_1입력의 가로 · 세로 · 깊이
W2,H2,D2W_2, H_2, D_2출력의 가로 · 세로 · 깊이
KK필터 개수
F,S,PF, S, P필터 크기 · 스트라이드 · 패딩

노트에 따르면 흔한 설정은 F=3,S=1,P=1F = 3, S = 1, P = 1이고, S=1S = 1일 때 P=(F−1)/2P = (F-1)/2로 두면 공간 크기가 그대로 유지됩니다. 공식 결과가 정수가 아니면 그 설정은 맞지 않는 것입니다.

숫자로 해 보기:

  • (해설용) 32×32×3 입력, F=5F = 5, S=1S = 1, P=2P = 2, K=16K = 16: 출력 (32−5+4)/1+1=32(32 - 5 + 4)/1 + 1 = 32, 즉 32×32×16입니다.
  • (해설용) 같은 입력에 F=3F = 3, K=16K = 16이면 파라미터는 3⋅3⋅3⋅16+16=4483 \cdot 3 \cdot 3 \cdot 16 + 16 = 448개입니다. 1절의 완전 연결 층(307,300개)과 비교해 보세요.
  • (노트의 실제 예) AlexNet 첫 층: 227×227×3 입력, F=11F = 11, S=4S = 4, P=0P = 0, 필터 96개 → (227−11)/4+1=55(227 - 11)/4 + 1 = 55, 출력 55×55×96. 파라미터 공유가 없다면 뉴런 55⋅55⋅96=290,40055 \cdot 55 \cdot 96 = 290{,}400개가 각자 11⋅11⋅3=36311 \cdot 11 \cdot 3 = 363개 가중치와 편향 1개를 가져 290,400×364=105,705,600290{,}400 \times 364 = 105{,}705{,}600개입니다. 공유하면 96⋅11⋅11⋅3=34,84896 \cdot 11 \cdot 11 \cdot 3 = 34{,}848개 가중치 + 편향 96개, 합계 34,944개입니다.

4. 풀링

직관: 지도를 작은 칸으로 나눠 각 칸에서 대표값(보통 최댓값) 하나만 남깁니다. "정확히 어느 픽셀인가"는 버리고 "이 근처에 그 무늬가 있었나"만 남겨, 크기를 줄이고 작은 위치 변화에 덜 민감하게 만듭니다.

숫자로 해 보기(해설용): 2절의 4×4 입력 XX에 2×2 최대 풀링, 스트라이드 2를 적용하면

(max⁡(1,2,0,1)max⁡(0,1,3,1)max⁡(2,1,1,0)max⁡(0,0,1,2))=(2322)\begin{pmatrix} \max(1,2,0,1) & \max(0,1,3,1)\\ \max(2,1,1,0) & \max(0,0,1,2) \end{pmatrix} = \begin{pmatrix} 2 & 3\\ 2 & 2\end{pmatrix}

입니다. 노트의 설명대로 F=2,S=2F = 2, S = 2 풀링은 깊이 조각마다 가로 · 세로를 절반으로 줄여 활성값의 75%를 버립니다. 풀링에는 학습할 파라미터가 없고 깊이는 그대로입니다.

5. 수용 영역과 '작은 필터를 여러 겹'

직관: 3×3 필터 층 위에 또 3×3 층을 얹으면, 두 번째 층 뉴런 하나는 원래 입력의 5×5를 간접적으로 봅니다. 세 겹이면 7×7입니다. 이것이 수용 영역(receptive field)입니다.

노트는 3×3 합성곱 세 겹과 7×7 합성곱 한 겹을 비교합니다. 둘 다 입력의 7×7을 보지만, 채널이 모두 CC개라면 파라미터는 다음과 같습니다.

7×7 한 겹: C×(7⋅7⋅C)=49C2,3×3 세 겹: 3×C×(3⋅3⋅C)=27C2\text{7×7 한 겹: } C \times (7 \cdot 7 \cdot C) = 49C^2, \qquad \text{3×3 세 겹: } 3 \times C \times (3 \cdot 3 \cdot C) = 27C^2

숫자로 해 보기(해설용): C=64C = 64이면 7×7 한 겹은 200,704200{,}704개, 3×3 세 겹은 110,592110{,}592개입니다. 게다가 세 겹 사이에 ReLU가 두 번 더 들어가 더 복잡한 특징을 표현할 수 있습니다. 노트는 이 두 이유로 큰 필터 하나보다 작은 필터 여러 겹을 권합니다.

6. 층을 쌓는 패턴과 사례

노트가 제시하는 가장 흔한 구조는 다음 패턴입니다.

코드
INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC

여기서 N≥0N \ge 0(보통 N≤3N \le 3), M≥0M \ge 0, K≥0K \ge 0(보통 K<3K < 3)이고 POOL?은 풀링이 선택이라는 뜻입니다. 앞쪽은 합성곱 · 풀링으로 공간을 줄이며 채널(특징 종류)을 늘리고, 끝에서 완전 연결 층이 클래스 점수를 냅니다.

mermaid
flowchart LR
  I[입력 32×32×3] --> C1[CONV 3×3, K=16, P=1 → 32×32×16]
  C1 --> R1[ReLU]
  R1 --> P1[POOL 2×2, S=2 → 16×16×16]
  P1 --> C2[CONV 3×3, K=32, P=1 → 16×16×32]
  C2 --> R2[ReLU]
  R2 --> P2[POOL → 8×8×32]
  P2 --> F[FC → 클래스 점수]
  F --> S[소프트맥스 · 교차 엔트로피]

(위 그림의 크기는 해설용 예입니다. 각 크기를 3절 공식으로 직접 확인해 보세요.)

사례: 노트는 LeNet · AlexNet · ZFNet · GoogLeNet · VGGNet · ResNet을 차례로 소개합니다. VGGNet에 대해서는 층별 메모리 · 파라미터 표를 보여 주며, 합계를 파라미터 약 138M개, 이미지 한 장 순전파에 약 93MB(역전파까지 하면 약 2배)로 적습니다. 파라미터 대부분이 첫 완전 연결 층에 몰려 있다는 점도 짚습니다. 이후 구조들이 끝의 완전 연결 층을 평균 풀링으로 바꾼 이유가 여기에 있습니다.

연습 문제

문제 1. 입력 64×64×3, F=3F = 3, S=2S = 2, P=1P = 1, 필터 32개인 합성곱 층의 출력 크기와 파라미터 수는? 풀이: (64−3+2)/2+1=32.5(64 - 3 + 2)/2 + 1 = 32.5로 정수가 아니므로 이 설정은 맞지 않습니다. 패딩을 0으로 하면 (64−3)/2+1=31.5(64 - 3)/2 + 1 = 31.5로 역시 안 됩니다. 입력이 65×65라면 P=1P=1에서 (65−3+2)/2+1=33(65 - 3 + 2)/2 + 1 = 33이 됩니다. 파라미터 수는 크기와 무관하게 3⋅3⋅3⋅32+32=8963 \cdot 3 \cdot 3 \cdot 32 + 32 = 896개입니다.

문제 2. 입력 16×16×32에 F=1F = 1, K=8K = 8인 1×1 합성곱을 쓰면 출력과 파라미터 수는? 풀이: 출력 16×16×8, 파라미터 1⋅1⋅32⋅8+8=2641 \cdot 1 \cdot 32 \cdot 8 + 8 = 264개입니다. 1×1 합성곱은 공간은 그대로 두고 채널만 섞어 줄입니다.

문제 3. 2절 필터 KK의 부호를 모두 뒤집으면 출력은? 풀이: (0−211)\begin{pmatrix} 0 & -2\\ 1 & 1\end{pmatrix}입니다. 이번엔 "왼쪽이 어둡고 오른쪽이 밝은" 경계에서 양수가 나옵니다.

문제 4. 3×3 합성곱(스트라이드 1)을 다섯 겹 쌓으면 마지막 층 뉴런의 수용 영역은? 풀이: 한 겹마다 2씩 늘어 3+2×4=113 + 2 \times 4 = 11, 즉 11×11입니다.

스스로 점검

  1. 합성곱 층이 완전 연결 층보다 파라미터가 훨씬 적은 두 가지 이유는?
    • 답: 뉴런이 입력의 작은 영역만 보는 국소 연결과, 한 지도 안의 모든 위치가 같은 필터를 쓰는 파라미터 공유 때문입니다.
  2. 필터 하나의 깊이는 무엇으로 정해지나요?
    • 답: 입력 부피의 깊이 D1D_1과 같습니다. 필터는 공간으로는 작지만 깊이로는 입력 채널 전체를 덮습니다.
  3. 최대 풀링이 주는 이점과 대가는?
    • 답: 크기를 줄여 계산을 아끼고 작은 위치 변화에 덜 민감해집니다. 대신 정확한 위치 정보 일부(2×2, 스트라이드 2면 활성값의 75%)를 버립니다.

용어 정리

용어쉬운 뜻
텐서 · 부피(volume)가로 × 세로 × 깊이로 쌓인 숫자 덩어리
필터 · 커널(filter, kernel)이미지 위를 미끄러지며 무늬를 찾는 작은 가중치 묶음
활성화 지도(activation map)필터 하나가 만든 2차원 결과
스트라이드(stride)필터를 옮기는 간격
제로 패딩(zero-padding)가장자리에 0을 덧대 크기를 조절하는 것
국소 연결(local connectivity)뉴런이 입력의 작은 영역에만 연결되는 것
파라미터 공유(parameter sharing)모든 위치가 같은 필터 가중치를 쓰는 것
풀링(pooling)작은 영역을 대표값 하나로 줄이는 연산
수용 영역(receptive field)뉴런 하나가 원래 입력에서 영향받는 범위
완전 연결 층(FC)앞 층 모든 값과 연결된 층

더 깊이 보려면

  • 노트 모듈 1 — 이미지 분류 · 선형 분류(SVM · 소프트맥스) · 최적화 · 역전파 직관 · 신경망 학습 요령
  • 노트 모듈 2 — 「Convolutional Neural Networks」(이 수업의 본문), 「Understanding and Visualizing CNNs」, 「Transfer Learning」
  • 노트 본문의 계산 고려 사항 절 — 메모리가 어디서 많이 드는지(활성값 · 파라미터 · 기타)

다음에 볼 것

라이선스

CS231n 노트 저장소(cs231n.github.io)는 MIT 라이선스(Copyright (c) 2015 Andrej Karpathy)입니다. 이 페이지는 노트를 번역한 것이 아니라 그 내용을 바탕으로 새로 쓴 해설이며, 노트에서 가져온 수치(AlexNet 첫 층 계산, 49C² 대 27C², VGGNet 138M · 93MB, 층 패턴)는 출처를 밝혀 인용했습니다. 그림은 옮기지 않았습니다.

출처

AI 원리부터 이해하기 · 딥러닝 기초 모듈

딥러닝 기초 모듈 학습

이 글은 딥러닝 기초 모듈의 학습 자료입니다. 전체 29개 자료 중 15번째입니다.

AI 기초 과정은 현재 진도 저장을 지원하지 않습니다.

출처·원문

원문 보기

번역가능

MIT