convCases = ({
"기본 예제": { img: [[1,1,1,0,0],[0,1,1,1,0],[0,0,1,1,1],[0,0,1,1,0],[0,1,1,0,0]], ker: [[1,0,1],[0,1,0],[1,0,1]] },
"에지 검출": { img: [[10,10,0,0,0],[10,10,0,0,0],[10,10,0,0,0],[10,10,0,0,0],[10,10,0,0,0]], ker: [[1,0,-1],[1,0,-1],[1,0,-1]] }
})
viewof convCase = Inputs.radio(Object.keys(convCases), { label: "예제", value: "기본 예제" })콘볼루션 연산
입력값: 이미지
앞 장은 “위치가 달라도 같은 특성을 같은 방법으로 찾아내는 연산이 필요하다”로 끝났다. 그 연산이 콘볼루션이다. 연산의 재료부터 놓는다. 입력은 앞 장에서 본 대로 픽셀 값의 2차원 행렬이다. 계산이 보이도록 \(5 \times 5\) 흑백 이미지를 쓴다.
\[\text{이미지} = \begin{bmatrix} 1 & 1 & 1 & 0 & 0 \\ 0 & 1 & 1 & 1 & 0 \\ 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 1 & 1 & 0 \\ 0 & 1 & 1 & 0 & 0 \end{bmatrix}\]
커널
이 장에서 쓸 \(3 \times 3\) 커널은 다음과 같다.
\[\mathbf{K} = \begin{bmatrix} 1 & 0 & 1 \\ 0 & 1 & 0 \\ 1 & 0 & 1 \end{bmatrix}\]
콘볼루션 연산
시작 위치의 계산
커널을 왼쪽 위에 놓으면 이미지의 왼쪽 위 \(3 \times 3\) 부분과 겹친다. 그 부분을 떼어 커널과 같은 자리끼리 곱한다.
\[\underbrace{\begin{bmatrix} 1 & 1 & 1 \\ 0 & 1 & 1 \\ 0 & 0 & 1 \end{bmatrix}}_{\text{이미지의 왼쪽 위}} \ \otimes\ \underbrace{\begin{bmatrix} 1 & 0 & 1 \\ 0 & 1 & 0 \\ 1 & 0 & 1 \end{bmatrix}}_{\text{커널}} \ =\ \begin{bmatrix} 1{\cdot}1 & 1{\cdot}0 & 1{\cdot}1 \\ 0{\cdot}0 & 1{\cdot}1 & 1{\cdot}0 \\ 0{\cdot}1 & 0{\cdot}0 & 1{\cdot}1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & 1 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}\]
아홉 개를 모두 더하면 \(1 + 0 + 1 + 0 + 1 + 0 + 0 + 0 + 1 = \mathbf{4}\). 이것이 결과의 첫 칸이다.
훑어가기
커널을 한 칸씩 옮기며 같은 계산을 반복한다. 커널이 놓일 수 있는 자리는 가로 3곳, 세로 3곳이므로 모두 9번이다.
9번이 끝나면 \(3 \times 3\) 행렬이 채워진다.
연산의 결과: 특성 맵
\[\text{Feature Map} = \begin{bmatrix} 4 & 3 & 4 \\ 2 & 4 & 3 \\ 2 & 3 & 4 \end{bmatrix}\]
세 요소를 정리하면 다음과 같다. 1~3장의 틀과 같다. 입력은 주어지고, 파라미터는 학습하고, 출력이 나온다.
| 역할 | 콘볼루션에서 | 크기 |
|---|---|---|
| 입력 | 이미지 | \(5 \times 5\) |
| 파라미터 | 커널 | \(3 \times 3\) |
| 출력 | 특성 맵 | \(3 \times 3\) |
특성 맵의 의미
특성 맵은 커널과 이미지의 콘볼루션을 거쳐 얻어진 또 하나의 이미지라고 볼 수 있다. 그 값은 무슨 뜻인가?
에지 검출 커널
패턴이 분명한 커널 하나를 읽어 보자.
\[\mathbf{K}_{\text{edge}} = \begin{bmatrix} 1 & 0 & -1 \\ 1 & 0 & -1 \\ 1 & 0 & -1 \end{bmatrix}\]
왼쪽 열은 \(+1\), 오른쪽 열은 \(-1\)이다. 커널이 덮은 곳의 왼쪽이 밝으면 큰 값이 더해지고, 오른쪽이 밝으면 큰 값이 빠진다. 그러므로 이 커널은 왼쪽이 밝고 오른쪽이 어두운 곳, 즉 밝음에서 어두움으로 바뀌는 세로 경계(에지)에서 큰 값을 낸다. 밝기가 고른 곳에서는 더한 값과 뺀 값이 상쇄되어 0에 가깝다. (앞의 단계별 보드에서 “에지 검출”을 고르면 \(5 \times 5\) 예제로 한 칸씩 계산해 볼 수 있다.)
실제 이미지에 커널을 적용하면
실제 이미지에 여러 종류의 커널을 적용해 특성 맵을 이미지로 그려 보자. 특성 맵의 값이 클수록 밝게 칠한다.
건물 사진: Daniel Büchele, Flickr, CC BY 2.0 · 손글씨: MNIST, CC BY-SA 3.0
세로 에지 커널을 고르면 건물의 세로 기둥과 벽의 왼쪽 경계만 밝게 남고, 가로 에지 커널을 고르면 지붕선과 처마만 밝게 남는다. 방향을 반대로 뒤집은 커널은 반대쪽 경계를 잡아낸다. 같은 이미지인데 커널마다 하이라이팅되는 곳이 다르다. 커널 하나가 특성 하나를 골라내고, 특성 맵은 그 특성이 어디에 있는지를 밝기로 보여 준다. 평균 커널을 고르면 어디에도 특별히 반응하지 않고 이미지가 뭉개지기만 한다. 특성을 골라내는 커널이 아니기 때문이다.
옛 컴퓨터 비전에서는 이런 커널을 사람이 직접 설계했다. CNN에서는 커널의 값을 데이터로부터 학습한다. 어떤 패턴이 분류에 유용한지를 데이터가 정한다.
여러 개의 커널을 함께 쓴다
커널 하나는 특성 하나를 골라낸다. 앞 장에서 사람은 눈·코·입처럼 특성을 여러 개 본다고 했다. 이미지에서 서로 다른 특성을 여러 개 포착하려면 여러 개의 커널을 같은 이미지에 적용한다. 커널이 3개면 특성 맵도 3장이다.
세 장의 특성 맵은 각각 세로 경계, 가로 경계, 대각선 경계가 어디에 있는지를 따로 기록한다. 커널이 \(K\)개면 특성 맵도 \(K\)장이고, 이 \(K\)장이 다음 단계의 재료가 된다.
콘볼루션 연산의 파라미터
지금까지는 \(5 \times 5\) 이미지에 \(3 \times 3\) 커널을 한 칸씩 옮겼다. 이 셋을 바꾸면 특성 맵의 크기가 달라진다. 세 가지를 차례로 정한다.
커널 크기 (Kernel Size)
같은 이미지에 커널 크기만 바꿔 보자. 노란 칸이 커널이 처음 놓이는 자리, 빨간 점이 커널이 놓일 수 있는 모든 자리의 중심이다. 슬라이더로 커널을 키우면 놓일 자리가 줄어 특성 맵이 작아진다.
\(7 \times 7\) 이미지에서 커널 크기 2, 3, 4, 5이면 특성 맵은 각각 \(6 \times 6\), \(5 \times 5\), \(4 \times 4\), \(3 \times 3\)이다. 커널이 한 칸 커질 때마다 특성 맵이 한 칸 줄어든다.
스트라이드 (Stride)
재생을 누르면 커널(노랑)이 스트라이드만큼 건너뛰며 이동하고, 특성 맵의 칸이 하나씩 채워진다. 스트라이드 1이면 자리가 \(5 \times 5\), 2면 \(3 \times 3\), 3이면 \(2 \times 2\)다.
패딩 (Padding)
회색 점선 칸이 둘러 준 0이다. 재생을 누르면 커널이 0으로 채운 테두리까지 밟고 지나가는 것이 보인다. 패딩 없이 \(5 \times 5\)에 \(3 \times 3\) 커널이면 \(3 \times 3\)으로 줄지만, 0을 한 겹 두르면(\(P=1\)) 커널이 놓일 자리가 \(5 \times 5\)로 늘어 원본 크기가 유지된다. 두 겹이면 원본보다 커진다.
특성 맵의 크기 공식
세 파라미터를 하나씩 바꿔 보았다. 셋을 한 식으로 묶으면 특성 맵의 크기를 바로 계산할 수 있다. 입력 크기 \(N\), 커널 크기 \(K\), 패딩 \(P\), 스트라이드 \(S\)일 때
\[\text{출력 크기} = \left\lfloor \frac{N - K + 2P}{S} \right\rfloor + 1\]
읽는 법: 패딩까지 포함한 이미지 폭 \(N + 2P\)에서 커널 폭 \(K\)를 빼면 커널이 더 움직일 수 있는 거리다. 그것을 보폭 \(S\)로 나누면 더 움직일 수 있는 횟수고, 처음 놓인 자리 1을 더한다.
앞의 세 그림을 공식으로 확인하면 커널 크기 3에서 \(\lfloor (7-3)/1 \rfloor + 1 = 5\), 스트라이드 2에서 \(\lfloor (7-3)/2 \rfloor + 1 = 3\), 패딩 1에서 \(\lfloor (5-3+2)/1 \rfloor + 1 = 5\)다. 그림의 빨간 점 개수와 같다.
크기를 유지하는 패딩
공식에서 스트라이드 1일 때 출력이 입력과 같아지려면 \(N - K + 2P + 1 = N\), 즉
\[P = \frac{K - 1}{2}\]
이다. 이렇게 크기를 유지하는 패딩을 코드에서는 same, 패딩 없음을 valid라 부른다. \(P\)가 정수가 되려면 \(K\)가 홀수여야 한다. 커널 크기로 3, 5, 7을 쓰는 이유가 이것이다. 홀수면 커널의 중심 픽셀도 하나로 정해진다.
✍️ 손으로 따라 계산하기 — 출력 크기
연습 1 — 기본. \(N=7,\ K=3,\ P=0,\ S=1\)
\[\left\lfloor \frac{7 - 3 + 0}{1} \right\rfloor + 1 = 4 + 1 = \mathbf{5}\]
연습 2 — 나누어떨어지지 않는 경우. \(N=32,\ K=5,\ P=2,\ S=2\)
\[\left\lfloor \frac{32 - 5 + 4}{2} \right\rfloor + 1 = \lfloor 15.5 \rfloor + 1 = 15 + 1 = \mathbf{16}\]
\(15.5\)를 16으로 반올림하면 오답이다. 버려서 15, 거기에 1을 더해 16이다.
연습 3 — 크기 유지 (same). \(N=28,\ K=3,\ P=1,\ S=1\)
\[\left\lfloor \frac{28 - 3 + 2}{1} \right\rfloor + 1 = 27 + 1 = \mathbf{28}\]
✍️ 직접 해보기
\(N=64,\ K=7,\ P=3,\ S=2\)일 때 출력 크기는? 정답을 보기 전에 손으로 먼저 계산하라.
\(\left\lfloor \dfrac{64 - 7 + 6}{2} \right\rfloor + 1 = \lfloor 31.5 \rfloor + 1 = 31 + 1 = \mathbf{32}\). 스트라이드 2가 크기를 대략 절반으로 줄인다.
3차원 이미지의 콘볼루션
채널이 있는 이미지
앞 장에서 컬러 이미지는 R, G, B 세 장의 행렬을 겹친 \(5 \times 5 \times 3\) 같은 3차원 이미지라 했다. 겹친 한 장 한 장이 채널이다. 3차원 이미지에 콘볼루션을 하려면 커널도 채널 수만큼의 층을 가진 3차원이어야 한다.
채널별로 계산하고 합친다
- R 채널: 이미지의 R 채널(\(5 \times 5\))과 커널의 R 층(\(3 \times 3\))을 콘볼루션 → \(3 \times 3\)
- G 채널: 같은 방법으로 → \(3 \times 3\)
- B 채널: 같은 방법으로 → \(3 \times 3\)
- 세 결과를 같은 자리끼리 더한다 → 특성 맵 \(3 \times 3 \times \mathbf{1}\)
채널별 결과는 따로 남지 않고 더해져서 한 장이 된다. 3차원 커널 하나는 2차원 특성 맵 하나를 만든다.
한 칸씩 계산해 보기 — 2채널 콘볼루션
작은 숫자로 확인한다. 채널 2개짜리 \(3 \times 3\) 입력에 \(2 \times 2 \times 2\) 커널 하나를 적용한다. 출력 크기는 \(\lfloor (3-2)/1 \rfloor + 1 = 2\), 즉 \(2 \times 2 \times 1\)이다. 아래 보드에서 한 칸씩 진행하면, 각 채널이 자기 층의 커널과 스칼라 곱을 하고 그 두 결과가 더해져 특성 맵의 한 칸이 되는 것을 볼 수 있다.
두 채널의 결과가 따로 남지 않고 더해져 한 칸이 된다. 그래서 채널이 2개인 입력에서 채널이 1개인 특성 맵이 나온다.
\[\text{특성 맵} = \begin{bmatrix} 5 & 6 \\ 2 & 5 \end{bmatrix} \quad (2 \times 2 \times 1)\]
커널이 여러 개일 때
컬러 이미지 \(5 \times 5 \times 3\)에 \(3 \times 3 \times 3\) 커널을 두 개 적용해 보자. 커널 하나가 특성 맵 한 장을 만드므로 특성 맵이 두 장 나오고, 두 장을 겹치면 출력은 \(3 \times 3 \times 2\)다.
- 커널 1은 세 채널을 각각 계산해 더한 한 장을 만든다. 커널 2도 마찬가지로 한 장을 만든다
- 두 장이 겹쳐 출력은 \(3 \times 3 \times 2\). 출력의 채널 수 = 커널 개수다
- 이 출력이 다음 콘볼루션의 입력이 된다. 채널이 2이므로 다음 커널은 \(k \times k \times 2\)여야 한다
커널을 32개 쓰면 출력은 \(3 \times 3 \times 32\)이고, 다음 커널은 \(k \times k \times 32\)가 된다. 이렇게 앞 층의 출력 채널 수가 다음 층의 커널 채널 수를 정하면서 콘볼루션이 여러 층 쌓인다.
콘볼루션 층의 파라미터 수
콘볼루션의 파라미터는 커널 안의 값이다. 2장의 퍼셉트론에 가중치 외에 편향이 있었듯이, 콘볼루션에도 편향이 있다.
앞의 2채널 예제의 커널은 \(2 \times 2 \times 2 + 1 = 9\)개, 커널 3개면 27개다.
완전연결 신경망과 비교
앞 장의 \(224 \times 224 \times 3\) 컬러 이미지로 돌아가 첫 층의 파라미터를 비교한다.
| 방식 | 구성 | 첫 층의 파라미터 수 |
|---|---|---|
| 완전연결 | 입력 150,528 노드 → 은닉 256 노드 | \(150{,}528 \times 256 + 256 =\) 38,535,424 |
| 콘볼루션 | \(3 \times 3 \times 3\) 커널 32개 | \((3 \times 3 \times 3 + 1) \times 32 =\) 896 |
약 4만 배 차이다. 콘볼루션의 파라미터 수는 커널의 크기와 개수로만 정해지므로, 이미지가 아무리 커져도 늘어나지 않는다.
5장의 두 문제는 어떻게 풀렸나
문제 2, 파라미터 폭발은 방금 봤다. 3,850만 개가 896개가 되었다.
문제 1, 공간 정보 손실을 보자. 5장에서 완전연결 신경망은 노드 번호마다 따로 가중치를 두어, 같은 무늬가 다른 위치에 오면 알아보지 못했다. 콘볼루션에서는 커널 하나(가중치 9개)가 모든 위치를 훑는다. 인터랙티브에서 커널이 9번 이동하는 동안 커널 안의 값은 한 번도 바뀌지 않았다. 왼쪽에서 경계를 잡아내던 커널은 오른쪽에서도 그대로 경계를 잡아낸다. 위치가 달라도 같은 특성을 같은 방법으로 찾아낸다. 앞 장이 요구한 연산이 바로 이것이다. 이 성질에 붙는 이름(가중치 공유, 이동 불변성)과 그 결과는 다음 장에서 정리한다.
핵심 요약
| 개념 | 핵심 내용 |
|---|---|
| 커널 | 특성을 포착하는 작은 행렬. 칸의 값이 가중치이고 학습으로 정해진다 |
| 콘볼루션 연산 | 커널을 왼쪽 위부터 훑으며 겹친 부분과 같은 자리끼리 곱해 더한다 |
| 특성 맵 | 연산 결과 행렬. 값이 클수록 그 위치가 커널의 패턴과 일치. 또 하나의 이미지 |
| 에지 검출 | 왼쪽 \(+1\), 오른쪽 \(-1\) 커널은 “왼쪽이 밝고 오른쪽이 어두운 경계” 위치에서 큰 값 |
| 여러 커널 | 커널 \(K\)개 → 특성 맵 \(K\)장. 특성마다 커널 하나 |
| 커널 크기·스트라이드·패딩 | 특성 맵 크기를 정하는 셋. \(\lfloor (N-K+2P)/S \rfloor + 1\), 버림과 \(+1\) 주의 |
| 3차원 콘볼루션 | 커널 채널 수 = 입력 채널 수. 채널별로 계산해 더하면 한 장. 출력 채널 수 = 커널 개수 |
| 파라미터 수 | 커널 하나 \(K \times K \times C + 1\). 이미지 크기와 무관 |
| 두 문제의 해결 | 가중치 공유로 위치 무관 인식, 파라미터 3,850만 → 896 |
다음 장 예고: 콘볼루션 뒤에 활성화 함수(ReLU)와 풀링을 붙이고, 마지막에 펼쳐서 완전연결층으로 분류하는 CNN의 전체 구조를 만든다.