시각 피질 안의 많은 뉴런이 작은 국부 수용장을 가진다.
-> 뉴런들이 시야의 일부 범위 안에 있는 시각 자극에만 반응한다.
뉴런의 수용장들은 서로 겹칠 수 있어서, 합치면 전체 시야를 감싸게 된다. 또한, 어떤 뉴런은 수평선의 이미지에만 반응하고 또 다른 뉴런은 다른 각도의 선분에 반응한다는 점을 보였다.
-> 두 뉴런은 동일한 수용장을 가지지만 다른 각도의 선분에 반응한다.
합성곱 층의 뉴런은 입력 이미지의 모든 픽셀에 연결되는 것이 아니라 합성곱 층 뉴런의 수용장 안에 있는 픽셀에만 연결된다.
두 번째 합성곱 층의 뉴런은 첫 번째 합성곱 층의 작은 사각 영역 안에 위치한 뉴런에 연결된다. 이런 구조는 네트워크가 첫 번째 은닉층에서는 작은 저수준 특성에 집중하고, 그 다음 은닉층에서는 더 큰 고수준 특성으로 조합해 나가도록 도와준다.
이미지의 공간적인 구조 정보를 유지하면서 모델을 학습시킬 수 있는 방법이다.
합성곱 연산을 수행하고 활성화 함수를 수행하는 계층이다.
필터(합성곱 커널) : 가중치 세트
합성곱 층l에 있는 k특성 맵의 i행, j열에 위치한 뉴런은 이전 l-1층에 있는 특성 맵의 i x s(h)부터 i x s(h) + f(h) - 1까지의 행과 i x s(w)부터 ix s(w) + f(w) -1까지의 열에 있는 뉴런의 출력에 연결된다. 특성맵은 커널을 사용한 합성곱 연산을 통해 나온 결과를 말한다.
s : 스트라이드(필터의 이동범위)
f(h) : 필터의 세로 길이
f(w) : 필터의 가로 길이
-> 간단하게 설명하면 크기가 인 필터로 이미지를 왼쪽 위부터 오른쪽 아래까지 순차적으로 훑는다. 훑으면서 필터의 크기에 해당하는 값들을 곱해서 더한 값을 출력한다. 그렇게 되면 현재 계층의 한 데이터는 이전 계층의 해당하는 위치에 개의 데이터를 곱하고 더한 값이다.


합성곱 이전에 입력의 가장자리에 지정된 개수의 폭만큼 행과 열을 추가하는 것을 의마한다.

값을 0으로 채우는 제로 패딩(zero padding)을 많이 사용한다.
필터의 크기를 3x3 또는 5x5를 사용하는데 스트라이드가 1일 때, 3x3일 때는 폭이 1인 제로 패딩을 사용하고, 5x5일 때는 폭이 2인 제로 패딩을 사용하면 입력과 출력의 크기를 보존할 수 있다.
풀링 층은 계산량과 메모리 사용량, 파라미터 수를 줄이기 위해 입력 이미지의 부표본(축소본)을 만드는 것이다.
풀링 뉴런은 가중치가 없다. -> 최대나 평균과 같은 합산 함수를 사용해 입력값을 더하는 것 뿐이다.
이외에도 최대 풀링은 작은 변화에도 일정 수준의 불변성을 만들어준다.
최대 풀링은 의미 없는 것은 제거하고 가장 큰 특징만 유지한다.(최대값 추출) 따라서 다음 층이 조금 더 명확한 신호로 작업이 가능하다. 또한, 강력한 불변성을 제공하고 연산 비용이 적게 든다.
평균 풀링은 평균값을 추출하는 것이므로 최대 풀링보다 정보 손실이 적다.
합성곱 층을 몇 개씩 쌓으면서 각각 ReLU층을 그 뒤에 놓고, 풀링 층을 쌓고 위 구조를 반복하는 식이다.
-> 합성곱 층에 너무 큰 커널을 사용하는 것은 좋지 않다.
ex) 5x5 커널의 합성곱 층 대신 3x3 커널 2개를 사용하는 것이 파라미터와 계산량이 적고 일반적으로 더 나은 성능을 낸다.
-> 한 가지 예외는 첫 번째 합성곱 층이다. 이 곳에는 큰 크기의 커널과 2이상의 스트라이드를 사용한다.
패션 MNIST 데이터셋 문제를 해결하기 위한 간단한 CNN이다.
model = keras.models.Sequential([
keras.layers.Conv2D(64, 7, activation="relu", padding="SAME",
input_shape=[28, 28, 1]),
keras.layers.MaxPooling2D(2),
keras.layers.Conv2D(128, 3, activation="relu", padding="SAME"),
keras.layers.Conv2D(128, 3, activation="relu", padding="SAME"),
keras.layers.MaxPooling2D(2),
keras.layers.Conv2D(256, 3, activation="relu", padding="SAME"),
keras.layers.Conv2D(256, 3, activation="relu", padding="SAME"),
keras.layers.MaxPooling2D(2),
keras.layers.Flatten(),
keras.layers.Dense(64, activation="relu"),
keras.layers.Dropout(0.5),
keras.layers.Dense(64, activation="relu"),
keras.layers.Dropout(0.5),
keras.layers.Dense(64, activation="softmax")
])
첫 번째 층은 64개의 큰 필터(7x7)와 스트라이드 1을 사용한다.
이미지가 28x28 픽셀 크기이고 하나의 컬러 채널(그레이스케일)이므로 input_shpae = [28, 28, 1]로 작성한다.
크기가 2인 맥스풀링 층을 사용해서 공간 방향 차원을 절반으로 줄인다.
이 과정을 반복한다. 맥스풀링 층 다음 합성곱 층이 두 번 등장한다. 이미지가 클 때는 이 구조를 더 많이 반복할 수 있다.
출력층에 가까울수록 필터 개수가 늘어난다.(64 -> 128 -> 256)
풀링 층 다음에 필터 개수를 두 배로 늘리는 것이 일반적인 방법이다.
이 방법이 저수준 특성(동심원, 수평선 등)의 개수는 적지만 이를 연결하여 고수준 특성을 만들 수 있는 방법이 많다.
풀링 층이 공간 방향 차원을 절반으로 줄이므로 이어지는 층에서 파라미터 개수, 메모리 사용량, 계산 비용을 크게 늘리지 않고 특성 맵 개수를 두 배로 늘릴 수 있다.
두 개의 은닉층과 하나의 출력층으로 구성된 완전 연결 네트워크이다. 밀집 네트워크는 샘플의 특성을 1D 배열로 입력에 넣어줘야 한다. 또, 밀칩 층 사이에 과대적합을 줄이기 위해 50%의 드롭아웃 비율을 가진 드롭아웃 층을 추가한다.
CNN구조로 손글씨 숫자 인식(MNIST)에 널리 사용되었다.
LeNet-5 구조
| 층 | 종류 | 특성 맵 | 크기 | 커널 크기 | 스트라이드 | 활성화 함수 |
|---|---|---|---|---|---|---|
| 입력 | 입력 | 1 | 32x32 | - | - | - |
| C1 | 합성곱 | 6 | 28x28 | 5x5 | 1 | tanh |
| S2 | 평균 풀링 | 6 | 14x14 | 2x2 | 2 | tanh |
| C3 | 합성곱 | 16 | 10x10 | 5x5 | 1 | tanh |
| S4 | 평균 풀링 | 16 | 5x5 | 2x2 | 2 | tanh |
| C5 | 합성곱 | 120 | 1x1 | 5x5 | 1 | tanh |
| F6 | 완전 연결 | - | 84 | - | - | tanh |
| 출력 | 완전 연결 | - | 10 | - | - | RBF |
LeNet-5와 구조는 비슷하나, 더 크고 깊다. 처음으로 합성곱 층 위에 풀링 층을 쌓지 않고 합성곱 층끼리 쌓았다.
AlexNet 구조
| 층 | 종류 | 특성 맵 | 크기 | 커널 크기 | 스트라이드 | 패딩 | 활성화 함수 |
|---|---|---|---|---|---|---|---|
| 입력 | 입력 | 3(RGB) | 227x227 | - | - | - | - |
| C1 | 합성곱 | 96 | 55x55 | 11x11 | 4 | valid | ReLU |
| S2 | 최대 풀링 | 96 | 27x27 | 3x3 | 2 | valid | - |
| C3 | 합성곱 | 256 | 27x27 | 5x5 | 1 | same | ReLU |
| S4 | 최대 풀링 | 256 | 13x13 | 3x3 | 2 | valid | - |
| C5 | 합성곱 | 384 | 13x13 | 3x3 | 1 | same | ReLU |
| C6 | 합성곱 | 384 | 13x13 | 3x3 | 1 | same | ReLU |
| C7 | 합성곱 | 256 | 13x13 | 3x3 | 1 | same | ReLU |
| F8 | 합성곱 | 256 | 6x6 | 3x3 | 2 | valid | - |
| F9 | 완전 연결 | - | 4,096 | - | - | - | ReLU |
| F10 | 완전 연결 | - | 4,096 | - | - | - | ReLU |
| 출력 | 완전 연결 | - | 1,000 | - | - | - | Softmax |

과대적합을 줄이기 위해 두 가지 규제 기법을 사용했다.
1. 훈련하는 동안 F9와 F10의 출력에 드롭아웃 50% 비율로 적용
2. 훈련 이미지를 랜덤하게 여러 간격으로 이동하거나 수평으로 뒤집고 조명을 바꾸는 식으로 데이터 증식을 수행
데이터 증식은 진짜 같은 훈련 샘플을 인공적으로 생성하여 훈련 세트의 크기를 늘립니다. 데이터 증식은 과대적합을 줄이므로 규제 기법으로 사용할 수 있습니다. 생성된 샘플은 가능한 진짜에 가까워야 합니다. 이상적으로는 증식된 훈련 세트에서 이미지를 뽑았을 때 증식된 것인지 아닌지를 구분할 수 없어야 합니다. 단순한 백색 잡읍을 추가하는 것은 도움이 되지 않습니다. 증식 방식은 학습이 가능해야 합니다.(백색 잡은은 학습이 불가능합니다.)
예를 들어, 각기 다른 양으로 훈련 세트에 있는 모든 이미지의 크기를 조금 변경하거나 이동, 회전합니다. 이렇게 만든 이미지를 훈련 세트에 추가합니다. 이렇게 하면 모델이 그림에 있는 물체의 위치, 방향, 크기 변화에 덜 민감해집니다. 조명 조건에 민감하지 않은 모델을 만들기 위해 비슷하게 여러 가지 명암을 가진 이미지를 생성할 수 있습니다. 일반적으로 이미지는 수평으로 뒤집을 수 있습니다. 이런 변환을 연결하여 훈련 세트의 크기를 많이 늘릴 수 있습니다.
AlexNet은 C1과 C3 층의 ReLU 단계 후에 바로 LRN(Local Response Normalization)이라 부르는 경쟁적인 정규화 단계를 적용했다. 가장 강하게 활성화된 뉴런이 다른 특성 맵에 있는 같은 위치의 뉴런을 억제한다. 이는 특정 맵을 각기 특별하게 다른 것과 구분되게 하고, 더 넓은 시각에서 특징을 탐색하도록 만들어 결국 일반화 성능을 향상한다.

bi는 i 특성 맵, 특정 행열에 위치한 뉴런의 정규화된 출력
ai는 ReLU 단계를 지나고 정규화 단계는 거치기 전인 뉴런의 활성화 값
k, α, β, r는 하이퍼파라미터이다. k는 편향, r은 깊이 반경을 의미한다.
fn은 특성 맵의 수이다.
AlexNet에서 하이퍼파라미터는 r=2, k=1, α=0.00002, β=0.75로 설정되어 있다.
tf.nn.local_response_normalization()을 사용하여 구현할 수 있다.
인셉션 모듈이라는 서브 네트워크를 가지고 있어서 이전의 구조보다 훨씬 효과적으로 파라미터를 사용한다. 실제로 GoogLeNet은 AlexNet보다 10배나 적은 파라미터를 가진다.

3x3+1(S) 표현은 3x3커널, 스트라이드1, SAME 패딩을 사용한다는 뜻이다.
모든 합성곱 층은 ReLU 함수를 사용한다.
두 번째 합성곱 층은 각기 다른 커널 크기를 사용하여 다른 크기의 패턴을 잡는다.
모든 층은 스트라이드 1과 SAME 패딩을 사용하므로 출력의 높이와 너비가 모두 입력과 같습니다. 이렇게 하면 모든 출력을 깊이 연결 층에서 깊이방향으로 연결할 수 있다. 이 연결 층은 tf.concat() 연산을 사용하여 구현할 수 있다.

실제로는 하나로 길게 쌓은 구조이며, 9개의 인셉션 모듈을 포함한다. 인셉션 모듈에 있는 6개의 숫자는 모듈 안에 있는 합성곱 층에서 출력하는 특성 맵의 수이다. 모든 합성곱 층은 ReLU 함수를 사용한다.