강의 초반에 역사에 대해서 다루는데 직접 영상 보는 걸 추천드립니다. (~14:00)
https://www.youtube.com/watch?v=bNb2fEVKeEo&list=PL3FW7Lu3i5JvHM8ljYj-zLfQRF3EO8sYv&index=5
오늘은 CNN에 대해 살펴볼건데 우선 저번 인공신경망 때처럼 뇌 관련 유사성은 배제하고 함수적인 측면에서 다뤄보겠습니다.
FC Layer

저번 시간에 fc layer에 대해 다뤘는데 what we're doing is we operate on top of these vectors, 32 x 32 x 3의 이미지를 예를 들었을 때 모든 픽셀들을 쭉 길게 늘려서 3072차원의 벡터를 얻을 수 있습니다. 이후에 10 x 3072 가중치 행렬과 곱한 후 해당 레이어의 출력값인 activations를 얻습니다.

이후에 하나의 숫자를 얻게 되는데 이 숫자는 해당 뉴런의 값입니다. 위에서 말한 경우에는 이런 숫자들을 10개 얻게됩니다.
Convolution Layer

Convolution Layer와 FC layer의 주요한 차이점은 Convolution Layer는 공간적 특성을 보존한다는 것입니다. 이전에 했던 것처럼 픽셀을 길게 늘려 하나의 벡터를 얻는 대신에 이미지의 구조를 유지합니다.

가중치는 하나의 작은 필터가 됩니다. 위의 경우에는 5x5x3 짜리 필터입니다. 이 필터를 가지고 이미지를 슬라이드 하게 됩니다. 그리고 모든 공간적 위치에서 dot product를 계산합니다. 좀 더 디테일하게 다뤄보겠습니다.

첫번째로 필터는 항상 input 크기의 전체 깊이 만큼 확장합니다. 필터는 단순히 입력 이미지 보다 작은 공간입니다. 하지만 항상 입력 이미지와 동일한 깊이를 가집니다. 위 경우에서는 3 만큼의 깊이를 가집니다.

이 필터를 가지고 주어진 공간적 위치에서 dot product를 합니다. 그 결과로 하나의 이미지 청크를 얻습니다.
Q. 5 x 5 x 3 크기의 필터를 하나의 벡터로 변환하는 겁니까?
A. 맞습니다. 입력 이미지 위에 필터를 올리고 해당 위치에서 element-wise multiplication을 수행한 후 그 결과를 모두 더하는 방식으로 이해할 수 있는데 이 연산은 결국 필터를 일렬로 펼쳐 벡터 형태로 만들고 입력 볼륨의 해당 부분도 같은 방식으로 벡터로 펼친 다음 두 벡터 간의 dot product를 수행하는 것과 동일한 결과를 제공합니다.

가장 최상단 좌측 코너에서부터 시작해 입력 이미지를 돌며 각 위치에서 dot product를 수행합니다. 출력값은 activation map의 하나의 값이 됩니다. 가장 단순한 버전은 단순히 모든 픽셀에서 위의 작업을 수행한 후 activation map에 대응하는 위치를 채워넣는 것입니다. 위의 그림에서 볼 수 있듯이 우리가 예상한 것과는 다르게 나옵니다. 입력이 32 by 32 였는데 28 by 28의 출력이 나왔습니다. 이에 대해서는 이후에 수학적으로 실제로 어떻게 동작하는지 알아보도록 하겠습니다. 하지만 기본적으로 원하는 출력 사이즈를 얻기 위해 어떻게 슬라이드할 것인지, 모든 픽셀에 대해 계산할 것인지, 두 픽셀을 동시에 계산할 것인지에 대한 선택을 할 수 있습니다.

방금까지는 하나의 필터를 가지고 이미지의 모든 위치를 돌아서 activation map을 얻었습니다. Convolutional Layer에서는 각 필터가 입력 데이터의 특정한 template이나 concept을 추출하도록 설계되기 때문에, 다양한 정보를 효과적으로 포착하기 위해 여러 개의 필터를 사용합니다. 따라서 우리는 여러개의 필터셋을 갖게됩니다. 위의 예에서는 두번째 필터(5 x 5 x 3 사이즈의 초록색 필터)를 가지고 모든 위치를 돌아 동일한 크기의 초록색 activation map을 얻습니다.
이와 동일하게 한 레이어에서 여러개의 필터를 가지고도 할 수 있습니다. 예를들어 만약 6개의 5 x 5 필터를 가지고 있다면 총 6개의 activation map을 얻을 수 있습니다. 최종적으로 해당 레이어의 출력 크기는 6 x 28 x 28이 됩니다.

ConvNet은 기본적으로 이 Convolutional Layer들의 시퀀스입니다. 그리고 이 레이어들을 사이에 활성화함수(예를 들어 ReLU 함수)들을 끼워넣습니다.
각각의 레이어들은 이전에 말했던 것처럼 많은 필터를 가집니다. 그리고 각 필터들은 activation map을 만들어냅니다. ConvNet에서는 이러한 레이더들이 여러 개 쌓이면서 필터들의 계층적인 구조를 학습하게 됩니다.

초기의 layer들에 있는 필터들은 보통 엣지 같은 low-lever feature들을 표현합니다. mid-level 에서는 코너나 blob 같은 좀 더 복잡한 특성들을 얻게됩니다. higher-lever에서는 단순한 형태가 아니라 점점 더 개념적인 것들을 포착하게됩니다. 이후 수업에서는 어떻게 이런 feature들을 시각화하고 네트워크가 어떤 feature들을 학습하는지 해석할것입니다. 일단 여기서 가장 중요한 부분은 이런 레이어들을 쌓을 수록 간단한 특성에서 복잡한 특성을 얻을 수 있다는 것입니다.

위 사진은 각 필터들이 만들어낸 activation map의 예들입니다. 빨간색 필터를 보면 oriented edge같은 template을 기대하는 것으로 보입니다. 따라서 이 필터를 이미지 위로 슬라이드하면, 이 특정 방향의 에지가 있는 영역에서 더 높은 점수 즉 더 밝은(하얀) 값을 가지게 됩니다. 그래서 각각의 activation map은 이러한 필터 중 하나를 이미지 위로 슬라이딩하면서 해당 템플릿이 이미지에 더 뚜렷하게 나타나는 위치에서 높은 출력을 가지는 결과라고 볼 수 있습니다.
위 연산을 합성곱이라고 부르는 이유는 두 신호 간의 합성곱 연산과 수학적으로 연관이 있기 때문입니다. 위에 제시된 식은 합성곱 연산에 익숙한 분들에게는 익숙한 형태로 전형적인 합성곱 정의에 해당합니다.
실제 구현에서는 필터를 뒤집지 않고 사용하는 경우가 많아 수학적으로는 교차상관에 더 가깝지만, 이러한 차이는 비교적 미묘하며 이 강의에서는 중요한 부분이 아닙니다.
결국 이 연산은 하나의 필터를 이미지 위에 공간적으로 이동시키면서 각 위치에서 필터와 해당 이미지 영역 간의 dot product를 계산하는 방식으로 이루어집니다.

CNN의 전체적인 모습은 입력 이미지가 있고 레이어들을 순차적으로 통과합니다. CONV 레이어가 있고 이후에 비선형성 레이어가 있고, CONV RELU CONV RELU 하다가 중간중간 pooling 레이어가 있습니다. 마지막으로 나온 값을 FC 레이어를 통과시켜 score function을 얻게됩니다.
이제 공간적 차원이 어떻게 계산되는지 몇가지 예를 통해 알아보겠습니다.

아까 전의 32 x 32 x 3 이미지와 5 x 5 x 3 필터를 가지고 어떻게 28 x 28 사이즈의 활성화 맵을 만들어내는지 알아보겠습니다.
좀 더 단순하게 알아보기 위해 7 x 7 의 예를 보겠습니다.

위의 사진처럼 3 x 3의 필터를 픽셀 하나 단위로 왼쪽 위부터 슬라이딩 합니다. 수평으로 5 수직으로 5만큼 필터가 딱 들어맞기 때문에 최종적으로 5 x 5의 activation map을 얻게됩니다.
방금 전의 예시에서는 한 픽셀 단위로 슬라이딩 했는데 이를 설계함에 있어서 여러 선택을 할 수 있습니다.
그렇게 정한 슬라이딩 간격을 stride라고 부릅니다. 아래 예시에서 stride를 2로 했을 경우를 확인해보겠습니다.

위의 예시와 다르게 3 x 3의 activation map을 얻을 수 있습니다.
이번엔 stride를 3으로 해보겠습니다.

위의 두 경우와 다르게 stride를 3으로 했을 경우에는 딱 맞지 않습니다. 이런식으로 Convolution을 할 경우에는 비대칭적인 output을 낼 것이기 때문에 이런식으로는 계산하지 않습니다.

위의 식처럼 입력 이미지의 크기, 필터의 크기 그리고 stride를 통해 출력 사이즈를 계산할 수 있습니다. 위에서 했던 값들을 넣어보면 N=7, F=3, stride=3 일때 딱 맞아 떨어지지 않는 것을 확인할 수 있습니다.

실제로는 zero-padding 기법을 사용합니다. 입력 이미지룰 0으로 pad하여 코너나 엣지에도 필터의 중심을 위치 시킬 수 있습니다. zero-padding을 통해 입력 이미지의 사이즈를 유지시킬 수 있습니다. 주로 사용하는 필터 크기인 3, 5, 7에는 1, 2, 3의 zero-pad를 사용하면 기존 입력 이미지의 사이즈를 보존할 수 있습니다.
zero-padding을 사용하지 않으면 CONV RELU 레이어를 지날 때 마다 이미지의 사이즈가 빠르게 줄어들고 이는 정보 손실을 야기시킬 수 있으며 또한 코너나 엣지에 대한 정보들을 잃을 수 있습니다.
참고로 보통 필터의 개수는 2의 거듭제곱으로 설정함.
계산 예시



프레임워크들



이제 Convolutional Layer을 뇌의 뉴런 관점에서 살펴보겠습니다. Convolutional Layer에서는 이미지의 각 공간적 위치마다 필터와 해당 이미지 영역 간의 dot product를 수행하고 그 결과로 하나의 숫자를 출력하게 됩니다.
이는 입력값에 필터의 가중치를 곱해 결과를 얻는 방식으로 마치 필터의 가중치가 뉴런의 시냅스 역할을 하는 것과 유사합니다. 하지만 일반적인 뉴런과의 주요 차이점은 바로 Local Connectivity에 있습니다. 기존의 뉴런은 전체 입력에 연결되어 있는 반면 합성곱 계층의 뉴런은 입력 이미지의 일부분만을 참조합니다.
즉 뉴런은 이미지의 국소적인 영역만을 바라보고 반응하며 이 반응 정도를 각 위치마다 계산함으로써 뉴런의 활성화 정도를 공간적으로 유지한 출력, 즉 activation map을 얻게됩니다.
이를 통해 공간적 구조를 그대로 유지하면서, 이후 계층에서는 이러한 activation map을 기반으로 더 높은 수준의 추론을 수행할 수 있게 됩니다.
추가적으로 5 x 5 filter를 "5 x 5 receptive filed for each neuron" 이라고도 부릅니다.
Pooling Layer
풀링 레이어의 역할은 feature map의 공간적 크기를 줄여 연산량을 감소시키고 표현을 보다 간결하고 효율적으로 만들기 위한 목적으로 사용됩니다.

Pooling Layer는 그냥 공간적으로 downsample하는 겁니다. 중요한 건 depth는 전혀 안 건드리고 downsample 한다는 점입니다. 따라서 input depth와 output depth는 동일합니다.

흔한 방법 중 하나는 max pooling 입니다. 위의 예시에서 pooling layer 또한 filter size와 stride를 가집니다. convolution에서 했던 것과 동일하게 필터가 input volume을 돕니다. 하지만 convolution에서 dot product를 했던 것과 다르게 단순히 input volume의 해당 영역에서 최대값을 뽑습니다.
Q. 보통 stride를 설정할 때 overlap(겹침)이 없도록 설정하나요?
A. 그렇습니다. 일반적으로 겹치지 않도록 stride를 설정하는 경우가 더 흔합니다. 단순하게 쉽게 이해해보면, 기본적으로 풀링의 목적이 다운샘플링이기 때문에 특정 영역을 하나의 값으로 요약하고 그 다음 겹치지 않는 영역을 또 요약하는 식으로 처리하는 것이 자연스럽고 효율적이라고 생각할 수 있습니다.
Q. 왜 max pooling이 average pooling 같은 다른 방식보다 더 좋은가요?
A. Average pooling 또한 사용할 수 있는 방법 중 하나이지만 Max pooling이 갖는 직관적인 해석 덕분에 더 자주 사용됩니다. activation map의 각 값은 해당 뉴런 또는 필터가 해당 위치에서 얼마나 강하게 반응했는지를 나타냅니다 이러한 관점에서 max pooling은 이 필터가 해당 영역에서 가장 강하게 반응한 정도를 추출하는 방식으로 해석할 수 있습니다.
이런 방식은 recognition과 같은 작업에서 특히 직관적으로 이해될 수 있습니다. 즉, 어떤 특징(예: 밝은 점, 특정 형태 등)이 이미지의 특정 위치가 아니라 어디에서든 나타났다면, 그 전체 영역에서 강하게 반응하도록 하는 것이 의미가 있습니다. 따라서 Max pooling은 해당 특징이 존재하기만 하면 강한 신호를 전달하는 방식으로 기능하게 됩니다.
Q. pooling과 stride 둘 다 다운샘플링 효과를 가지는데 그렇다면 그냥 pooling 대신 stride를 사용하면 되는 거 아닌가요?
A. 실제로 최근의(*2017년 기준) 신경망 아키텍처들을 살펴보면, 풀링보다 스트라이드를 활용하여 다운샘플링을 수행하는 경우가 점점 더 많아지고 있습니다. 특히 스트라이드를 조절함으로써 더 유연한 구조 설계각 가능하고, fractional stride와 같은 다양한 변형도 사용할 수 있습니다. 실제로 이러한 방식이 더 나은 성능을 보이는 경우가 있으며, 따라서 스트라이드를 이용한 다운샘플링은 충분히 유효한 대안이고 실제로 많은 모델들이 이를 채택하고 있습니다.
https://stats.stackexchange.com/questions/387482/pooling-vs-stride-for-downsampling
Pooling vs. stride for downsampling
Pooling and stride both can be used to downsample the image. Let's say we have an image of 4x4, like below and a filter of 2x2. Then how do we decide whether to use (2x2 pooling) vs. (stride of 2)?
stats.stackexchange.com
위 질문에 대한 답변으로 이 글을 참조해보아도 좋을 듯합니다.

보통 pooling layer에서는 직접적인 downsample을 하길 원하기 때문에 zero-padding을 사용하지 않습니다.
pooling layer에서 흔히 설정하는 값은 필터 사이즈를 2 x 2로 하고 스트라이드를 2로 하는 것입니다.
필터 사이즈 3 x 3에 스트라이드를 2로 할 수도 있지만 2 x 2의 필터 사이즈가 더 흔히 사용됩니다.
FC Layer

FC layer는 지금까지 봐왔던 Fully Connected Layer와 동일하게 작동합니다. 이 단계에서는 CNN의 마지막 계층에서 출력된 볼륨을 처리하게 됩니다. 이 볼륨은 보통 가로 x 세로 x 채널 수의 형태를 가지며, 우리는 이 출력을 1차원 벡터 형태로 펼치는 과정을 수행합니다. 이 과정을 통해 얻어진 1차원 벡터는 일반적인 fully connected layer의 입력 형식과 동일해지며, 이후에는 이 벡터를 FC layer에 입력하여 각 뉴런이 모든 합성곱 출력에 연결되도록 합니다. Convolutional Layer에서는 이미지의 공간적 구조를 유지하며 처리했지만 마지막 단계에서는 이러한 정보를 하나로 집약하여 최종적인 판단 또는 예측을 내리는 구조로 전환됩니다. 이러한 과정을 통해 얻어지는 출력은 우리가 잉전에 봤던 것과 같은 최종 점수 또는 분류 결과입니다.
끝!
'인공지능 > cs231n' 카테고리의 다른 글
| [cs231n 정리노트] 6. Training Neural Network I (0) | 2025.04.13 |
|---|---|
| [cs231n 정리노트] 4. Back-Propagation & Neural Networks (0) | 2025.03.21 |
| [cs231n 정리노트] 3. Loss Functions and Optimization (3) Optimization (0) | 2025.03.16 |
| [cs231n 정리노트] 3. Loss Functions and Optimization (2) Regularization (0) | 2025.03.10 |
| [cs231n 정리노트] 3. Loss Functions and Optimization (1) (0) | 2025.03.10 |