[DSBA] CS231n - 7. Convolutional Neural Networks

2024. 11. 10. 19:06AI/CS231n

https://www.youtube.com/watch?v=vT1JzLTH4G4&list=PLC1qU-LWwrF64f4QKQT-Vg5Wr4qEE1Zxk&index=3

스탠포드 대학교의 유명한 컴퓨터 비전 강의를 보고 정리한 글입니다.

https://www.youtube.com/playlist?list=PLetSlH8YjIfXMONyPC1t3uuDlc1Mc5F1A

CS231n 강의와 서울대학교 DSBA 연구실의 강의를 참고하여 공부한 부분을 정리하였습니다.

이번 강의를 들으면서 처음 AI 공부를 시작했고, 그만큼 틀린 부분 해석이 모호한 부분이 있을 수 있습니다.


1. Overview

왜 이미지 네트워크를 Conv Neural Network로 다뤄야 할까?

기존의 신경망을 이미지에 적용하면 왜 안되는지 살펴보자.

height 112px, width 150px, RGB 3의 이미지를 파이썬에서 다루려면 (112, 115, 3) 이러한 형태의 tensor를 다루게 될텐데, artificial neural network에서는 다룰 수 없고 벡터의 형태로 펼쳐줘야 한다. 즉, 1차원 벡터로 펼쳐야 한다.

 

그런데 사진의 왼쪽 위를 보면 초록색 픽셀들이 모여 있다. 이런 픽셀들의 지역적인 특성이 분명 있는데, 이미지를 tensor로 다루지 않고 벡터로 다루게 되면, 사진을 왼쪽 위에서부터 차례대로 한 줄씩 다루게 된다. 그럼 지역적인 특성이 사라지게 되는 것이다.

또, artificial neural network는 fully connected model 이지만 이 예제에서는 hidden node 없이 output node의 한 node만 가지고 생각해보자. 벡터의 dimension은 (1, 112 x 150 x 3) 형태로 굉장히 긴 벡터가 된다. 그럼 weight의 개수는 입력 벡터의 수가 되므로 112 X 150 X 3으로 엄청나게 많아지게 된다. 그런데 output node의 수가 늘어난다면 output node의 수만큼 저 숫자에 곱해지게 된다.

 

결론적으로 이미지를 artificial neural network로 다루려면 파라미터의 수가 엄청나게 많아지게 되고, 모델이 복잡해진다. 복잡해진 모델은 overfitting 되기 쉽다.

Convolution Neural Network에서는 tensor 형태의 input을 받으면 벡터로 펼치지 않고 tensor 그대로 다루게 된다. 그리고 파라미터의 수가 엄청나게 많아지면 Local connectivity, Parameter sharing 특성으로 극복하게 된다. 하나씩 알아보자.

Local connectivity

기존 Fully-connected인 neural network를 생각해보면 어떤 노드 하나가 112 x 150 x 3 size 만큼 펼쳐진 벡터 전체와 연결되어 weight 개수가 굉장히 많았다.

Local connectivity 성질은 어떤 이미지가 주어지면, 그 이미지의 특정 구역을 노드 하나가 담당하게 된다. 아래와 같은 방식이다.

 

RGB 채널로 나눠 봤을 때, 특정 노드가 똑같은 구역을 담당하게 되고, 이런 필드를 receptive field라 한다.

receptive field의 size를 35라 했을 때, weight의 개수가 얼마나 줄어드는지 확인해보자.

fully-connected의 경우 하나의 노드가 112 x 150 x 3 = 50400개의 weight를 가진다.

local activity는 하나의 노드가 35 x 35 x 3 = 3675개의 weight를 가진다.

하지만, 노드의 개수가 늘어나면 그 개수만큼 3675와 곱해지게 되고 여전히 파라미터가 너무 많고 모델이 복잡하다.

Parameter Sharing

parameter sharing의 근거는 다음과 같다.

어떤 하나의 feature가 어떤 구역에서 의미가 있다면 다른 구역에서도 의미가 있다.

예를 들어, 전체 이미지에서 별이라는 특징을 찾는다고 생각해보자. 각 노드는 3765개의 weight가 연결되어 있다. 같은 별이라는 특징을 찾는데 파라미터가 다를 필요가 없다.

그래서 parameter sharing 개념을 이용해서 원래 3675 * node 개수 만큼 weight가 필요했는데, 어차피 구역별로 같은 특징을 찾고 있기에 parameter의 개수를 3675개로 줄일 수 있다.

이런 별이라는 특징을 찾을 때 결과를 feature map이라 한다.

 

좀 더 자세히 보자.

위의 사진은 CNN의 첫 번째 convolution layer의 필터를 시각화 한 것이다. 필터를 보면 어떤 특징들이 나타난다. 어떤 특징이 한 곳에서 의미가 있다면 다른 필드에서도 의미가 있을 수 있기에 똑같은 파라미터를 공유하는 것이다.

Artificial Neural Network와 CNN의 차이점을 보자.

  1. CNN은 이미지를 그대로 받아서 벡터로 변환하지 않고 바로 결과로 내어준다.
  2. local connectivity
  3. parameter share를 적용하여 파라미터의 개수를 확 줄였다.

LeNet-5 모델을 보자.

사진에서 convolutions 부분이 입력 이미지를 sliding window 방식으로 움직이며 특징을 추출하는 부분이다.

CNN이 데이터로부터 task에 기여하는 필터들을 학습하고, 컨볼루션 층은 입력 이미지에서 다양한 level의 특징을 추출한다. 같은 필터가 이미지의 모든 부분에 적용되어 parameter sharing을 한다.


2. Convolution Layer

32x32x3 image를 주어진 필터가 convolve를 하게 된다.

앞에서 local connectivity, parameter sharing을 통해 parameter의 수를 줄인다고 했는데, 필터가 parameter를 의미한다고 생각하면 된다. 즉, weight를 뜻한다.

convolve 한다는 뜻은 sliding window 방식으로 필터가 이미지 위에서 움직이면서 연산하게 되는데, 이 과정을 convolve 한다고 한다.

여기서 주의할 부분이 있는데, 이미지와 필터 모두 width, height, depth를 가지고 필터는 이미지와 같은 depth를 가져야 convolve 할 수 있다.

convolve 한다는 의미를 좀 더 자세히 살펴보자.

32x32x3 image를 5x5x3 filter로 convolve한 결과는 스칼라 값이 된다.

연산의 과정은 필터를 이미지에 겹치면, 큰 이미지에 필터와 상응하는 값이 있을 것이다. 그 값과 필터의 값을 element wise로 곱해서 단순히 더한 것이다. 선형 연산이 되고 그래서 스칼라 값이 결과로 나오게 되는 것이다.

이 그림으로 보면, 5x5x3 필터가 이미지를 window sliding 하면서 이동하게 될텐데, 그럼 convolve 값이 매핑되게 된다. 그럼 convoleve 한 값이 tensor 형태로 나오게 된다.

원래의 artificial neural network에서는 input과 weight를 내적하고 bias를 더하고, activation function에 통과시킨다.

마찬가지로 필터가 이미지를 convolve 해서 나온 tensor를 element마다 activation function을 통과하게 된다. 결국 기존의 artificial neural network와 동일한 것이다.

feature map 1이 *이라는 feature를 찾는다면 feature map 1과 대응되는 filter가 * object를 찾는 filter이다. filter가 image를 convolve하면, feature map(activation map)이 생기게 된다.

이 feature map은 뉴런의 관점에서 노드 뭉치에 해당하게 된다.

feature map 2가 #이라는 feature를 찾는다면 #이라는 object에 대응하는 filter가 주어지게 되고, 이 filter를 image에 convolve를 시켰을 때 activation map이 또 나오게 되고, 그게 노드 뭉치와 대응되게 되는 것이다.

 

activation map을 tensor 형태로 표현하면 (28, 28, 2) 가 된다. depth가 2인 이유는 feature map 2 까지를 생각했기 때문이다.

중요한건 filter가 feature map과 대응된다는 것이다.

위의 사진을 보면 5x5x3 filter 6개를 사용했을 때 결과로 28x28x6의 activation maps을 얻을 수 있다.

결과가 또 tensor로 나오기에 또 filter로 convolve를 해줄 수 있다.

input image에 6개의 5x5x3 filter로 convolve를 하고, 각각의 스칼라값에 ReLU를 통과시켜서 새로운 tensor를 만들어내고, 계속 필터를 통과시켜 쌓으면 Deep Convolution Neural Network가 된다.

Convolution Layer의 hyperparameter를 알아보자.

spatial extent

  • receptive filed, 즉 필터의 크기를 의미한다.
  • 여기서 잠깐 짚어보고 넘어가자. 필터는 모든 receptive field와 convolve를 수행하고 이 부분이 parameter share이다. receptive field는 노드와 따로 연결되어있고 이 부분이 local connectivity이다.

depth

  • filter의 개수

stride

  • filter가 image 내에서 움직이는 보폭

zero-padding

  • input image의 테두리를 0으로 채우는 것이다.
  • zero-padding을 하는 이유는 convolution layer를 계속 통과하다 보면 이미지가 점점 작아지게 되는데, 이미지의 크기를 보존하기 위해 사용한다.

spatial extent & stride

spatial extent는 필터의 크기, stride는 filter가 slide하는 보폭의 크기이다.

한 번 계산해보자.

gray scale의 NxN의 image에 FxF의 spatial extent를 사용하면 output size는 (N-F) / stride + 1이 된다.

stride 3을 사용한다고 생각했을 때 7x7 image, 3x3 filter로는 이미지 전체를 convolve 할 수 없다. 이런 경우 zero padding을 사용하기도 한다.

 

Zero-padding

이미지의 테두리를 0으로 채우는 것이다. 이미지가 필터를 통과하다보면 이미지의 크기가 계속 작아지기에 zero-padding을 사용해서 이미지의 크기를 유지하려고 사용한다.

즉, zero-padding은 convolution layer를 통과할 때 input, output size를 같게끔 유지하려고 사용하는 것이다.

공식이 존재하긴 하지만 공식보다는 왜 zero-padding을 사용하는지가 더 중요하다.

아까 전의 예시를 다시 생각해보면 32x32x3 image에 5x5 filter를 계속 통과시키면 size가 32 → 28 → 24 이렇게 tensor가 계속 줄어든다.

zero pad를 임의로 추가한다면 input, outut tensor 크기가 유지된다.

계산 과정을 보면, 각 필터와 이미지를 채널별로 곱한다. 나온 결과를 모두 더하고 bias를 더하면 Output Volume이 나온다.

여기서 잠깐 짚고 넘어가자.

학습의 의미를 잘 알고 넘어가야 하는데 여기서는 필터, 기존 neural net에서는 weight는 처음에는 어떤 특징이 중요한지 모르는, 랜덤 상태에서 시작했다가 점차 순전파, 역전파, parameter update 과정을 거치며 주어진 정답과의 차이, loss 값이 가장 적어지게끔 조절된다. 이 조절되는 과정이 task에 맞는 특징을 뽑아내게끔 필터 혹은 weight를 update하는 과정이고 이게 학습이다.


3. Pooling Layer

Convolution Layer에서 zero padding을 거쳐 input의 size를 유지했다. 이렇게 유지된 이미지는 pooling layer를 거치면서 size가 줄어들게 된다.

pooling layer를 거치면 width, height가 줄어드게 되는데, 공간적인 정보를 줄이기 때문에 왜 pooling layer를 거쳐야 하는가에 대한 의문이 든다.

왜 width, height를 줄여야 할까?

기존 artificial neural network의 bottleneck 구조를 생각해보자.

입력층에서 시작하여 hidden layer를 거치면서 노드의 수가 점점 줄어드는 구조를 bottleneck 구조라 하는데, 노드 수 감소는 데이터 차원을 축소시키는 것을 의미한다.

병목 지점에서 데이터 차원이 점차 축소되며 핵심적인 특징만 남게 되고 좋은 representation이 생성되게 되는 것이다.

Neural Net에서 좋은 representation이 생성되는 원리

좋은 representation이 생성되는 원리가 좀 모호하다. 알아보자.

  • 노드를 거치면서 활성화 함수를 통과하게 된다.
  • 활성화 함수는 비선형 변환을 수행하고, 좀 더 복잡한 패턴을 표현 가능하게 한다.
  • 여러 층의 비선형 변환을 통해 더욱 복잡한 함수를 만들 수 있고 이는 더 복잡한 패턴을 학습할 수 있게 한다.
  • 예를 들어, 이미지 분류라면 1층에서는 엣지나 색상 변화만을 감지하고, 3층에서는 더 복잡한 눈, 코, 입 등을 감지할 수 있는 것이다.
    • 위의 예시가 비선형 변환과 무슨 상관이냐면, 선형 변환에서는 y = ax + b 형태로, 직선만 표현이 가능하지만 비선형 변환에서는 곡선, 굴곡 등 복잡한 형태를 만들 수 있다.
  • 자연어 처리의 경우 단어를 백터로 표현하게 된다. 단어 벡터의 시퀀스로 문장을 표현하는데 비선형 변환을 통해 문맥에 따른 의미 변화를 학습한다.
  • 예를 들어 “The movie was not bad at all” 이라는 문장이 있다.
    • 1층에서는 not bad 조합 인식, 2층에서는 부정어와 형용사의 관계 학습, 3층에서는 전체 문장의 긍정적 뉘앙스를 포착하여 비선형 변환을 통해 주변 단어와의 관계를 고려해 의미를 결정할 수 있는 것이다.

Pooling Layer의 장점 및 설명

Conv Net에서는 Pooling layer를 거치면서 공간적인 정보를 없애는 대신에 내가 탐지하고 싶은 object를 좀 더 잘 찾아내는 representation을 만들어 낼 수 있다.

Pooling Layer는 항상 activation map에 독립적으로 적용된다. 다른 activation map의 값에 영향을 받지 않고 별도로 pooling 연산이 수행된다는 뜻이다.

pooling 연산은 보통 모든 activation map에 똑같이 적용된다. pooling의 역할은 각 activation map 내에서 가장 강한 반응 또는 평균적인 반응을 선택하기에 각 특징의 존재나 강도를 압축하여 표현하는 것이다.

주의할 점이 pooling 연산이 object 특징을 추출하는 것이 아니라 이미 추출된 특징의 공간적 정보를 압축한다는 것이다!

pooling layer의 hyper parameter는 보통 두 가지가 있다.

  • spatial extent F, pooling이 적용되는 크기이다.
  • stride S

예제로 보자.

224x224x62의 tensor에 pooling을 적용하면 depth는 유지가 되면서 width, height가 줄어든다. 예제에 나온 pooling은 max pooling으로, spatial extent F 중 가장 큰 값만 남기고, stride 만큼 움직인다.


4. Normalization layer & Fully-connected layer

Normalization layer

Normalization layer는 학습 속도를 높이기 위해 정규화하는 것이고 요즘에는 batch 정규화 기법을 사용한다.

기존 사용했던 정규화 기법은 Internal covariate shift problem을 가지고 있었다.

예를 들어 처음 neural network를 학습하면 batch 단위로 학습하게 되고, weight 값은 임의로 정해지게 된다.

처음 순전파, 역전파를 거치면 weight가 업데이트 될것이다. 그럼 비슷한 batch가 들어왔음에도 weight가 다르게 다음 iteration의 같은 노드에서 다른 값이 나오게 된다.

그래서 노드 값들의 분포가 점점 바뀌고, 이런 문제를 Internal covariate shift problem이라한다. 분포가 바뀌는 것의 문제는 다음과 같다.

  • 학습 속도 저하
  • 안정성 감소 : 상위 층의 계속 변화하는 하위 층의 출력에 대응해야 해서 학습이 불안정해진다.
  • 포화 문제 : 특히 sigmoid, tanh activation function 사용 시, 입력 값이 극단적으로 치우치면 gradient가 매우 작아진다.

batch 정규화 기법은 미니배치 내의 데이터를 사용하여 전체 데이터셋을 정규화하여 해당 문제를 해결하였다.

Fully-connected layer

Fully-connected layer는 한 층의 뉴런이 이전 층의 모든 뉴런과 연결된 신경망 층이다. CNN의 convolution 층들이 추출한 지역적 특징을 전체적으로 통합하는 역할을 한다.

  • 예를 들어, convolution 층에서 귀 모양, 털 텍스처, 눈 형태 등 특징을 추출했다면 Fully-connected layer에서 특징을 종합하여 이 특징들의 조합이 고양이에 가까운지, 개에 가까운지를 결정하게 된다.

Fully-connected layer는 convolution layer로 바꿔서 구조를 만들 수도 있다. 왜냐하면 Fully-connected layer와 convolution layer 모두 weight와 input의 내적으로 볼 수 있기 때문이다.

어떻게 Fully-Conencted Layer를 Convolution Layer로 대체하는지 보자.

예제는 10-class classification task이다.

32x32x3 input이 CONV ReLu를 거친 다음, 원래 Fully-Connected Layer라면 24 * 24 * 10 size의 벡터로 펼친 다음,   output에 10개가 되도록 이어 붙이게 된다.

그런데 이 과정을 filter가 convolve하는 연산으로 대체할 수 있다.

어쨌든 우리의 목표는 output이 길이가 10인 벡터가 되면 된다.

그렇다면 24x24x10 filter를 마지막에 나온 tensor에 적용시키면 스칼라 값이 하나가 나오게 된다. 이런 필터 10개를 사용하면 결과는 1x1x10 tensor 10개가 된다. 1x1이므로 사실상 길이 10의 vector가 되는 것이다.

이렇게 결과로 나온 vector에 대해 Softmax layer를 거치면 각각의 값에 확률이 나오게 된다.