목차
- History of CNN
- Convolutional Neural NetworK
- CNN
- CNN의 수행 개요
- Spatial dimension
- The brain/neuron view of CONV Layer
- Pooling Layer
- Fully Connected Layer (FC layer)
👀 코드 보기 , 🤷♀️
이 두개의 아이콘을 누르시면 코드, 개념 부가 설명을 보실 수 있습니다:)
CS231N: Lecture 5강의를 빠짐 없이 정리하였고, 어려운 개념에 대한 보충 설명까지 알기 쉽게 추가해 두었습니다.
History of CNN
전체 개요를 정리해보자면 아래와 같다.
신경망의 역사
1957년: Mark I Perceptron machine 개발
- 개발자: Frank Rosenblatt
- 의의
- 이 기계는 “perceptron”을 구현한 최초의 기계
- “Perceptron”은 우리가 배운 Wx + b 와 유사한 함수를 사용
- 다른점: 여기에서는 출력 값이 1 또는 0
- 같은점: 가중치 W를 Update 하는 Update Rule이 존재합니다.
- 이 Update Rule은 Backprop과 유사
- 하지만 당시에는 backprob이라는 개념이 없어서, 단지 W를 이리저리 조절하면서 맞추는 식이었음
1960년: Adaline and Madaline을 개발
- 개발자: Widrow와 Hoff
- 의의
- 최초의 Multilayer Perceptron Network
- 이 시점에서야 비로소 Neural network와 비슷한 모양을 하기 시작하긴 했지만 아직 Backprob같은 학습 알고리즘은 없음
1986: 최초의 Backporp
- 개발자: Rumelhart
- 의의
- 우리에게 익숙한 Chain rule과 Update rule
- 이때 최초로 network를 학습시키는 것에 관한 개념이 정립되기 시작함
- 하지만 그 이후로 NN을 더 크게 만들지는 못함.
암흑기
- 그리고 한동안은 새로운 이론이 나오지 못했고 널리 쓰이지도 못함
- 2000년대가 되서야 다시 활기를 찾기 시작함
2006: DNN의 학습가능성
- 개발자: Geoff Hinton 과 Ruslan Salakhutdinov
- 의의
- DNN의 학습가능성을 선보임
- 그것이 실제로 아주 효과적이라는 것을 보여줌
- 하지만 그 때 까지도 아직 모던한 NN는 아니었음
- backprop이 가능하려면 아주 세심한 초기화가 필요하기 때문
- 그래서 여기에서는 전처리 과정이 필요했고, 초기화를 위해 RBM을 이용해서 각 히든레이어 가중치를 학습시켜야 했음
- 이렇게 초기화된 히든 레이어를 이용해서 전체 신경망을 backprop하거나 fine tune하는 것이었음
2012: NN의 광풍
- 개발자: Hintin lab
- 의의
- NN이 음성 인식에서 아주 좋은 성능을 보임
- acoustic modeling과 speech recognition에 관한 것
2012: AlexNet
- 개발자: Hintin lab
- 의의
- 영상인식에 관한 landmark paper
- 이 논문에서는 ImageNet Classification에서 최초로 NN을 사용했고, 결과는 정말 놀라웠음
- AlexNet은 ImageNet benchmark의 Error를 극적으로 감소시킴
- 그 이후로 ConNets은 아주 널리 쓰이고 있음
CNN의 역사
다시 돌아가서 구체적으로 “CNN이 어떻게 유명해졌는지” 에 대해 한 번 알아보도록 하겠다.
1950: 일차시각피질의 뉴런에 관한 연구
- 개발자: Hubel과 Wiesel
- 의의
- 고양이의 뇌에 전극을 꽂아 고양이에게 다양한 자극을 주며 실험
- 이 실험에서 뉴런이 oriented edges와 shapes같은 것에 반응한다는 것을 알아냄
- **결론 **
- 피질 내부에 지형적인 매핑(topographical mapping)이 있다
- 피질 내 서로 인접해 있는 세포들은 visual field내에 어떤 지역성을 띄고 있음.
- 밑의 그림은 보면 해당하는 spatial mapping을 볼 수 있음
- 중심에서 더 벗어난 파란색 지역도 볼 수 있습니다.
- 뉴런들이 계층구조를 지닌다는 것도 발견
- 다양한 종류의 시각자극을 관찰하면서 시각 신호가 가장 먼저 도달하는 곳이 바로 Retinal ganglion 이라는 것을 발견함
- Retinal ganglion cell은 원형으로 생긴 지역임
- 가장 상위에는 Simple cells이 있는데, 이 세포들은 다양한 edges의 방향과 빛의 방향에 반응함
- 그리고 더 나아가, 그런 Simple Cells 이 Complex cells과 연결되어 있다는 것을 발견함.
- Complex cells는 빛의 방향 뿐만 아니라 움직임에서 반응함
- 복잡도가 증가함게 따라, 가령 hypercomplex cells은 끝 점(end point) 과 같은것에 반응하게 되는 것입니다.
- 이런 결과로부터 “corner” 나 “blob”에 대한 아이디어를 얻기 시작한 것임
- 피질 내부에 지형적인 매핑(topographical mapping)이 있다
1980: neocognitron
- 개발자: Hubel과 Wiesel
- 의의
- simple/complex cells의 아이디어를 사용한 최초의 NN
- Fukishima는 simple/complex cells을 교차시킴 (SCSCSC..)
- Simple cells은 학습가능한 parameters를 가지고 있고 Complex cells은 pooling과 같은 것으로 구현했는데 작은 변화에 Simple cells보다 좀 더 강인함.
1998: Backprob과 gradient-based learning을 적용
- 개발자: Yann LeCun
- 의의
* 1998년 Yann LeCun이 최초로 NN을 학습시키기 위해 Backprob과 gradient-based learning을 적용함.
* 실제로 그 방법은 문서인식에 아주 잘 동작함
* 그리고 우편번호의 숫자를 인식하는데도 아주 잘 동작함
* 그리고 실제 우편 서비스에서 우편번호 인식에 널리 쓰임
* 하지만 아직 이 Network를 더 크게만들 수는 없었습니다.
* 그리고 숫자 라는 데이터는 단순했습니다.
2012: CNN의 현대화 바람
- 개발자: Alex Krizhevsky
- 의의
- 이 Network는 AlexNet이라고도 불림
- Yann LeCun의 CNN과 크게 달라보이진 않지만 더 크고 깊어짐.
- 여기서 가장 중요한 점은 지금은 ImageNet dataset과 같이 대규모의 데이터를 활용할 수 있다는 것임.
- 또한 GPU의 힘도 있었음
현재
- ConvNets은 모든 곳에 쓰임
- AlexNet의 ImageNet 데이터 분류 결과를 살펴보자면 이미지 검색에 정말 좋은 성능을 보이고 있음
- 가령 꽃을 검색하는 것을 보면 학습된 특징이 유사한 것을 매칭시키는데 아주 강력하다는 것을 볼 수 있음
- Detection에서도 ConvNet을 사용 ➡ 영상 내에 객체가 어디에 있는지를 아주 잘 찾아냄
- segmentation 가능: 단지 네모박스만 치는 것이 아니라 나무나 사람 등을 구별하는데 픽셀 하나 하나에 모두 레이블링하는 것임 ➡ 이런 알고리즘은 자율주행 자동차에 사용 가능
- 대부분의 작업은 GPU가 수행할 수 있으며, 병렬처리를 통해 ConvNet을 아주 효과적으로 훈련하고 실행시키기 가능
- 이와 같이 많은 분야에서 사용되고 있음
Convolutional Neural NetworK
Convolutional Neural Network의 작동 원리에 대해 알아 볼 것이다.
이번에 CNN의 첫 시간이니, CNN이 어떻게 동작하는지에 대해서만 간단하게 이야기해 볼 것이다.
Fully Connected Layer(FC Layer)
본격적인 CNN을 들어가기 전, 그 보다 하위 모델인 FC Layer를 면저 보고 가겠다.
[역할]
어떤 벡터를 가지고 연산 함
[과정]
- 1) 우선 입력으로 32 x 32 x 3 의 이미지가 가 있다고 가정하자
- 2) 이 이미지를 길게 펴서 3072차원의 벡터로 만든다.
- 3) 가중치 W와 벡터를 곱한다. (Wx)
- 이 예시에서는 W가 10x3072 행렬이다
- 4) 그리고 activation 을 얻는다
- 이 Layer의 출력이다.
- 출력: 10개의 행으로 되어있는데 3072 차원의 입력와 내적을 한 결과라고 할 수 있음
- 내적 결과, 어떤 숫자 하나를 얻게 되는데 이는 그 Neuron의 한 값이라고 할 수 있음
- 이 예시의 경우 10개의 출력이 있게 됨
[단점]
2) 의 과정에서 이미지를 이미지 자체로 못보고 길게펴서 보기 떄문에 이미지 자체의 픽셀의 위치 정보가 무시되게 됨
그런데 Convolution Layer은 기존의 FC레이어와 달리 Convolution Layer는 기존의 구조를 보존시켜 위의 단점을 보완함.
➡ 기존의 FC Layer가 입력 이미지를 길게 쭉 펴서 이미지 위치 정보를 잃었다면,
➡ CNN은 기존의 이미지 구조를 그대로 유지하여 입력값으로 받아 위치 정보를 유지하게됨.
CNN
이 강의를 보기 전에 이 포스트를 보고오면 훨씬 이해가 잘 될 것이다.
- input image
- FC Layer와 달리 input 이미지가 한줄로 펴진것이 아닌 이미지가 보존 된 상태로 들어옴
- FC Layer와 달리 input 이미지가 한줄로 펴진것이 아닌 이미지가 보존 된 상태로 들어옴
- filter
- 가중치다.
- input image에 맞춰 가중치도 이와 같은 필터이다.
- 이 예시에서는 5x5x3 필터가, 이 필터를 가지고 이미지를 슬라이딩하면서 공간적으로 내적을 수행하게 된다.
필터의 연산
이제 이것을 어떻게 수행하는지 자세하게 알아보자
[필터 연산]
- 1) 필터의 깉이 확장
- 우선 필터는 입력의 깊이(Depth)만큼 확장된다.
- CNN의 하나의 필터는 아주 작은 부분만 취할 수 있다 ➡ 전체 32x32 이미지의 5x5 만 취하는 것
- 하지만 깊이는 전체 깊이를 전부 취함 ➡ 여기에서는 5 x 5 x 3 가 됨(image: 32 x 32 x 3)
- 이 깊이는 주로 이미지의 색(RGB)를 의미한다.
- 2) 내적
- 이 필터를 가지고 전체 이미지에 내적을 시킬 것이다.
- 이 필터를 이미지의 어떤 공간에 겹쳐놓고 내적을 수행한다.
- 그리고 필터의 각 w와, 이에 해당하는 이미지의 픽셀을 곱해준다
- 여기에 필터가 5 x 5 x 3 라는건 그만큼 곱셈연산을 한다는 것이다.
- bias term인 b도 보인다(얜 곱셈이 아니다!)
- 여기에서는 기본적으로 \(W^{t}x + b\)를 수행한다.
- 3) 슬라이딩
- 그럼 필터 전체의 연산을 보겠다.
- 실제는 슬라이딩을 하며 각 슬라이딩 구역에 앞에서 살펴본 내적을 하는 것이다.
- Convolution은 이미지의 좌상단부터 시작한다
- 그리고 필터의 중앙을 값들을 모은다.
- 필터의 모든 요소를 가지고 내적을 수행하게 되면 하나의 값을 얻게된다
- 그리고 슬라이딩한다.
- Conv연산을 수행하는 값들을 다시 Output activation map의 해당하는 위치에 저장한다.
[출력크기가 입력크기와 다른 이유]
- 여기 보면 입력 이미지와 출력 activation map의 차원이 다르다는 것을 알 수 있다.
- ➡ 입력은 32 x 32 이고 출력은 28 x 28 이다
- 그래서 우리는 나중에 수학에 대해 설명 할 것이다.
- 수학적 설명 후엔 이 방법이 차원 적으로 어떻게 작동하는지 정확히 알 수 있다.
- 기본적으로는 어떻게 슬라이딩을 할 것인지를 선택할 수 있다.
- 출력 형을 위와 같이 맞추기 위해선 슬라이딩여부와 관계없이 입력 값을 두 개씩 뽑아서 연산을 수행할 수도 있을 것이다.(하지만 이렇게 하지는 않을 것이다.)
- 출력 행렬의 크기는 슬라이드를 어떻게 하느냐에 따라 다르다.
- 하지만 보편적으로 사용하는 슬라이딩 방법이 있다
[여러개의 필터 사용]
- 하나의 필터를 가지고 전체 이미지에 Convolution 연산을 수행한다.
- 그러면 하나의 activation map이라는 출력값을 얻게 된다.
- 즉 이는 여러개의 필터를 사용하면 여러개의 activation map이라는 출력값을 갖을 수 있다는 것을 의미한다.
- 보통 Convolution Layer에서는 여러개의 필터를 사용한다.
- 왜냐하면 필터마다 다른 특징을 추출하고 싶기 때문이다.
- ex) 초록색의 5 x 5 x 3 형태의 두번째 필터
- 이 녹색 필터를 연산하고 나면, 앞서 계산했던 activate map과 같은 크기의 새로운 map이 만들어집니다.
- 우리는 한 Layer에서 원하는 만큼 여러개의 필터를 사용할 수 있다.
- 가령 5 x 5 필터가 6개가 있다면 총 6개의 activation map을 얻게 될 것이다.
- 이 경우, 출력 map의 크기는 28 x 28이 되겠다.
- 여러개의 필터 활용
- 위의 필터들을 담은 CNN을 다시 그려보면 아래 그림과 같이 Cov Layer들의 연속된 형태가 될 것이다.
- 그리고 각각을 쌓아 올리게 되면 아래 그림과 같이 간단한 Linear Layer로 된 Neural Network가 된다.
- 이제는 그 사이 사이에 activation function을 넣을 것이다(ReLU 같은 것들을 사용 가능)
- 그렇게 되면 Conv-ReLU 가 반복되겠죠 그리고 가끔은 pooling layer도 들어갑니다.
- 그리고 각 Layer의 출력은 다음 Layer의 입력이 됩니다.
- 그리고 말씀드렸듯 각 Layer는 여러개의 필터를 가지고 있다.
- 그리고 각 필터마다 각각의 출력 map을 만든다. ➡ 그러므로 여러개의 Layer들을 쌓고나서 보면 결국 각 필터들이 계층적으로 학습을 하는것을 보게된다.
[필터의 계층적 학습]
- 1) low-level feature
- 앞쪽에 있는 필터들은 low-level feature를 학습하게 된다.
- 여기선 Edge와 같은것들이 보입니다.
- 2) Mid-level
- 여기선 좀 더 복잡한 특징을 가지게 된다.
- 코너나 blobs 등과 같이 보입니다.
- 3) high-level features
- 그리고 high-level features를 보면 좀 더 객체와 닮은 것들이 출력으로 나오는 것을 볼 수 있다.
- +) 나중 수업에서 객 특징을 어떻게 시각화하는지, 그리고 특징들이 어떻게 학습되는지를 살펴볼 것이다.
➡ 위에서 이해하고 넘어가야 하는 것은 특징이 어떻게 생겼고, Layer의 계층에 따라 단순/복잡한 특징을이 존재한다는 것을 아는 것이다.
📜 학생 질문: 우리가 전체 이미지를 슬라이딩 하면서 필터링을 하는데 이미지의 가장자리는 필터가 덜 적용되지 않냐
A: 아주 좋은 질문 입니다.
그리고 어떻게 그것을 다시 보완해야 하는지가 앞으로 할 내용이다. (ex zero-padding)
지금까지는 Conv Layer를 계층적으로 쌓아서 단순한 특징을을 뽑고 그것을 또 조합해서 더 복잡한 특징으로 활용했습니다.
그리고 이는 Hubel과 Wiesel의 이론과도 잘 맞습니다.
네트워크에 앞쪽에서는 단순한 것들일 처리하고 뒤로 갈수록 점점 더 복잡해 지는 식이죠
우리는 그것을 강제로 학습시킨 것이 아니라 계층적 구조를 설계하고 역전파로 학습시킨 것 뿐이지만 필터는 이렇게 학습되는 것입니다.
📜 학생 질문: 여기에서 시각화 한 것이 무엇인지
A:
가령 Cov1을 보면 각 그리드의 요소가 하나의 뉴런(필터) 라고 보시면 됩니다.
그리고 시각화 시킨 이 뉴런의 모습은 바로 이미지가 어떻게 생겨야 해당 뉴런의 활성을 최대화시킬 수 있는지는 나타내는 것입니다.
이미지가 뉴런과 비슷하게 생겼으면 출력 값을 큰 값을 가지게 됩니다.
시각화는 Backpopagation을 통해 해볼 수 있는데. 이를 시각화하는 방법은 나중에 더 자세하게 배울 것입니다.
그러나 기본적으로 여기 그리드의 각 요소는 각 뉴런의 활성을최대화시키는 입력의 모양을 나타내게 됩니다.
그런 의미에서 뉴런이 어떻게 생겼는지를 의미합니다.
Activation map의 예제: Convolution
아래는 각 필터가 만든 출력값이다.
[필터 Conv 연산]
- 슬라이드 위쪽엔 5 x 5 필터들을 시각화 한 것을 볼 수 있다.
- 이는 실제 ConvNet을 학습시킨 결과이다.
- 이제 이 각각의 필터를 아래 input image(자동차의 한 부분(모서리와 조명쪽))에 곱해줄 것이다.
➡ 그럼 이미지와 필터간 Conv 결과, 한 필터당 하나의 activation map이 나올 것이다.
[activation map]
- 위의 연산 결과가 activation map으로 한 필터당 하나의 activation map이 있다는 것을 확인 할 수 있다.
- 그럼 결과를 해석해보자.
- 이 필터는 edge를 찾고 있는 것이다
- 그리고 이 필터를 input image에 슬라이딩 시키면 이 필터와 비슷한 값들은 값이 더 커지게 된다
- 따라서 각 actavation은 이미지가 필터를 통과한 결과가 되며 이미지 중 어느 위치에서 이 필터가 크게 반응하지는지를 보여준다
(즉 무슨 필터와 더 잘 맞는지를 보여주는 것이다)
(인풋과 필터가 비슷하면 슬리이딩 시 각 반응이 커지니까)
[Convolution]
- 위와 같이 필터에서 activation map을 도출하는 연산을 Convolution이라고 칭한다.
- 우리가 이걸 Convolution이러고 칭하는 이유는 바로 위에 언급한 것이 바로 두 신호 사이에 cov를 하는것과 유사하기 때문이다.
- Conv 식
- 예전에 신호처리에서 Conv를 본 적이 있는 학생이라면 이 식이 correlation 같아 보일 것이다.
- 우리는 사실 Conv의 뒤집힌 버전을 쓰고 있는 것이다. 하지만 이 수업에서는 이를 더 자세히 다루지는 않겠다.
- 하지만 손으로 직접 계산해보면 conv에 정확한 정의와 크게 다르지 않을 것이다.
- 하지만 기본적으로는 필터를 가지고 이미지에 슬라이딩하면서 모든 위치에서 내적을 수행하게 되는 것이다.
CNN의 수행 개요
이전에도 언급했듯이 CNN이 어떻게 수행되는지를 살펴보면, 입력 이미지는 여러 레이어를 통과하게 됩니다.
한번 간단한 예를 들어보겠다.
- 1) 첫 번째 Conv Layer 후에는 non-linear layer를 통과합니다.
- 나중에 배우겠지만, non-linear layer로는 ReLU를 가장 많이 사용한다
- 2) Conv, ReLU, Conv, ReLU를 하고나면 pooling layer를 거치게 된다.
- 다시 배우겠지만 pooling 은 activation maps의 사이즈를 줄이는 역할을 한다.
- 3) 그리고 CNN의 끝단에는 FC-Layer가 있다.
- FC-Layer는 우에서 배운 완전 연결 레이어이다.
FC-Layer는 마지막 Conv 출력 모두와 연결되어 있으며 최종 스코어를 계산하기위해 사용한다.
Spatial dimension
그럼 이제 “Spatial dimension”에 대해 알아보겠다.
자 여기 32 x 32 x 3 이미지가 있다.
그리고 이 이미지를 5 x 5 x 3 필터를 가지고 연산을 수행할 것이다.
이제 어떻게 이 둘을 가지고 28 x 28 activation map이 생기는지를 알아보겠다.
간단한 예시로 7 x 7 입력에 3 x 3 필터가 있다고 해보자.
이제 이 필터를 이미지의 왼상단부터 씌운다
그리고 이제 해당 값들의 내적을 수행할 것이다.
이 값들은 activation map의 좌 상단에 위치하게 된다
그리고 다음 단계로 필터를 오른쪽으로 한칸 움직인다.
그러면 값 하나를 또 얻을 수 있을 것이다.
📜 gif 자세히보기
이렇게 계속 반복하게 되면 결국 5 x 5의 출력을 얻게 된다
이 슬라이드 필터는 좌우 방향으로는 5번만 수행가능하고 상하 방향으로도 5번만 수행가능하다.
stride
그리고 여기에는 다양한 방법을 이용해 볼 수 있다.
[stride란?]
지금까지는 슬라이딩을 한칸씩만 진행했었다.
이때 한번 슬라이드시 움직이는 칸의 개수를 “stride” 라고 한다.
지금까지는 stide = 1을 사용했다. 그럼 stride = 2 일때를 보자
[stride = 2]
다시 왼쪽 위부터 시작해서 움직인다.
다만 여기에서는 1칸은 건너뛰고 그 다음칸으로 이동해서 계산을 한다.
이렇게 tride가 2 이면, 3칸을 최대로 못움직이고 결국 출력은 3 x 3 이 된다.
📜 gif 자세히보기
[stride = 3]
stride가 3인 경우에는 이미지를 슬라이딩해도 필터가 모든 이미지를 커버할 수 없다.
이 예시에서 stride 가 3이면 이미지에 잘 맞아떨어지지 않는다.
실제로 이렇게 되면 잘 동작하지 않으므로 이렇게 하면 안된다.
➡ 이로 인해 불균형한 결과를 볼 수도 있기 때문이다.
[stride 수식]
그래서 상황에 따라 출력의 사이즈가 어떻게 될 것인지를 계산할 수 있는 아주 유용한 수식이 있다.
Output size: \({(N - F) / stride} + 1\),
- 입력의 차원: N
- 필터 사이즈: F
- 스트라이드: stride
➡ 이를 이용해서 어떤 필터 크기를 사용해야 하는지를 알 수 있다
➡ 어떤 stride를 사용했을때 이미지에 꼭 맞는지(주로 정수값이 나와야한다), 그리고 몇 개의 출력값을 낼 수 있는지도 알 수 있다.
📜 앞의 예 수식 적용
앞서 보신바와 같이 N = 7 이고 F = 3 일때,
stride가 1이면
➡ 이걸 그대로 수식에 적용해보면 5 x 5 출력이 나올 것이라는 것을 알 수 있다.
반면, stride가 3이면
➡ 잘 동작하지 않겠죠. (2.33)
📜 학생질문: stride를 선택하는데 있어 가질 수 있는 직관
우선 한가지는 stride를 크게 가져갈수록 출력은 점점 작아짐.
이미지를 다운샘플링하는 것은 Pooling을 하는것과 비슷합니다. 하지만 그 둘은 확실이 다르고, pooling보다 더 좋은 성능을 보이기도 함.
Pooling 처럼 다운 샘플링하는 동일한 효과를 얻으면서도 더 좋은 성능을 낼 수도 있습니다.
그리고 activation map의 사이즈를 줄이는 것은 추후 모델의 전체 파라미터의 갯수에도 영향을 미칩니다. ➡ 가령 Conv Layer의 마지막에는 FC Layer가 있을 수 있겠죠. ➡ FC Layer는 Conv의 출력 모두와 연결되어 있습니다. ➡ Conv Layer의 출력이 작을수록 FC Layer에서 필요한 파라미터의 수가 더 작겠죠
파라미터의 수, 모델의 사이즈 그리고 Overfitting 과 같은 것들에는 다양한 trade-off 가 있습니다.
이 trade-off는 stride를 몇 으로 할지를 결정할때 고려해야 하는 문제입니다.
zero-pad
역할: 출력의 사이즈 의도대로 만들어 줌.
이는 이전 학생의 질문이었던 “코너는 어떻게 처리하나요” 와도 연결되는 문제다.
작동: 이미지의 가장자리에 0을 채워 넣음
➡ 이렇게 되면 좌 상단의 자리에서도 필터 연산을 수행할 수 있게 된다.
[예시]
그럼 위의 예시에 zero-padding을 해보자
- 7 x 7 입력
- 3 x 3 필터 연산을 수행할 때
- stride를 1
- Output size: \({(N - F) / stride} + 1\),
- zero-padding 전: \({(7 - 3) / 1} + 1 = 5\),
- zero-padding 후: \({(7+2 - 3) / 1} + 1 = 7\),
- 즉 이를 통해 출력의 사이즈를 조정할 수 있다.
📜 학생질문: 0 을 padding 하게되면 모서리에 필요없는 특징을 추가하게 되는게 아닌지?
우리가 지금 하고싶은 일은 영상 내에 어떤 모서리 부분에서 값을 얻고싶은 것이고
zero-padding은 이를 할 수 있는 하나의 방법일 뿐입니다.
우리는 지금 필터가 닿지 않는 모서리 부분에서도 값을 뽑을 수 있게 됩니다.
물론 zero-padding 말고 다른 방법을 사용할 수도 있습니다.
zero가 아닌 mirror나 extend하는 방법도 있습니다.
꼭 zero-padding을 써야 하는 것은 아닙니다.
하지만 zero-padding도 제법 잘 동작하는 방법 중 하나입니다.
물론 모서리 부분에 약간의 artifact이 생긴 순 있습니다. 당연히 고려해야 하 부분이죠. 하지만 대부분의 경우 제법 잘 동작합니다.
예시적용
자 그럼 몇가지 예를 더 살펴보자.
- 입력 이미지: 32 x 32 x 3
- 10개의 5 x 5 필터
- stride: 1
- padding: 2
[Q2: 이 조건에서 출력사이즈는 몇이 될까?]
이전 공식을 생각해보면,
- 입력 사이즈 F: 32 ➡ padding으로 이 값을 2씩 증가시킴
- 32+{2* 2} ➡ 즉 2를 양쪽(\(* 2\))에 추가한다.
- 필터사이즈 = 5
➡ Output size: \({(32+2* 2 - 5) / 1} + 1 = 32\),
➡ 32x32
그런데,이러한 결과가 필터 10개에 의해 10번 연산되므로,
즉 전체 필터의 갯수는 10개이니 10개의 activation map이 나올 것이다.
최종 출력사이즈는
➡ 32x32x10이다.
[Q1: 이 레이어의 파라미터는 총 몇개일까?]
우리에게 10개의 5 x 5 필터가 있다는 것이 힌트이다.
- ✨ 필터가 입력의 Depth만큼도 통과한다 ➡ 필터가 입력의 전체 depth를 통과하게 된다.
- bias term도 있다 ➡ 5 x 5 x 3 가중치에는 하나의 bias term이 들어있다.
- 즉, 필터당 파라미터 개수
- \(5* 5* 3 + 1 = 76\),
- \(5* 5\) ➡ filters의 크기
- \(* 3\) ➡ 필터가 입력의 Depth만큼 통과
- \(+ 1\) ➡ for bias
- \(5* 5* 3 + 1 = 76\),
- 그러므로 전체 파라미터 개수는,
- \(76* 10 = 760\),
- \(* 10\) ➡ 필터의 개수
- \(76* 10 = 760\),
📜 Conv layer 요약정리
나중에 주의깊게 읽어보시기 바랍니다.
어떤 n차원의 입력이 있습니다.
그리고 어떤 필터를 쓸지 선택해야 합니다.
몇개의 필터를 쓸건지, 필터 크기는 몇인지, stride는 몇으로 할지 zero-padding은 몇 으로 할지를 다 정해줘야합니다.
그리고 앞서 말한 수식을 이용해서 출력의 사이즈가 어떻게 될 것인지를 계산해 봅니다.
그리고 전체 파라미터가 몇개가 될 것인지도 확인해 봐야 합니다.
[Common settings]
- 여기에는 일반적으로 사용하는 값들이 있습니다.
- 필터 사이즈는 3x3, 5x5 를 씁니다.
- Stride는 보통 1이나 2가 가장 흔합니다.
- 그리고 padding은 그 설정에 따라 조금씩 다르겠죠
- 그리고 보통 필터의 갯수는 2의 제곱수로 합니다.
- 32, 64, 128, 512 와 같이 말이죠
- 위의 숫자들은 아주 자주 보게될 것입니다.
1 x 1 Convolution
이제 1 x 1 Convolution에 대해 말해봅시다.
1 x 1 Convolution도 의미가 있다.
똑같이 슬라이딩 하면서 값을 구하기 때문이다.
하지만 여기에서는 5x5 처럼 공간적인 정보를 이용하지 않지만, 이 필터는 여전히 Depth만큼 연산을 수행한다.
그러니 1 x 1 Conv는 입력의 전체 Depth에 대한 내적을 수행하는 것과 같다.
- 입력: 56x56x64
- Conv: 32개의 1x1 필터로 연산 수행
- 출력: 56x56x32
프레임워크
[TORCH]
- Torch에서는 다양한 레이어가 정의되어 있음
- 그리고 그 레이어의 forward/backward pass가 구현되어 있음
- spatial convolution이 바로 그 중 하나
- 이로 구현된 Conv Layer 예제
- 여기에 arguments를 가지고 여러 디자인을 선택할 수 있음
- 입/출력 사이즈를 정할수도 있음
- 커널 사이즈, Padding 와 같은 것들을 전부 정해줄 수 있음
[Caffe]
- 또한 다른 프레임워크
- 위와 비슷비슷 함
- 아래 그림을 보면, 네트워크가 정의되어있음
- Caffe에서는 proto text라는 파일을 이용함 ➡ 여기에 디자인을 명시
- 여기 conv layer의 예시가 있는데 출력의 사이즈나 필터의 갯수, 커널 사이즈 stride 등등을 여기에 명시하는 것임
The brain/neuron view of CONV Layer
자 그럼 Conv Layer을 Brain Neuron의 관점에서 살펴보겠다
뉴런에 대해서는 지난 시간에 조금 배웠었댜.
[공통점]
Conv Layer를 보면, 전체 이미지의 특정 위치에 필터를 가지고 내적을 수행했다.
그러면 하나의 값을 얻게된다
이는 여기 오른쪽 그림의 내적과 같은 아이디어이다. ➡ 입력이 들어오면 Ws(필터 값)와 곱하고, 하나의 값을 출력
[차이점]
- 가장 큰 차이점은 우리의 뉴런은 Local connectivity 를 가지고 있다는 것임
- Conv Layer처럼
슬라이딩을 하는게 아니라 특정 부분에만 연결되어 있음- 하나의 뉴런은 한 부분만 처리하고, 그런 뉴런들이 모여서 전체 이미지를 처리하는 것임
- 이런 식으로 spatial structure를 유지한 채로 Layer의 출력인 activation map을 만드는 것임
[중요 용어 정리]
- Receptive field
- 한 뉴런이 한 번에 수용할 수 있는 영역을 의미
- 즉, 5 x 5 필터 ➡ 한 뉴런의 “Receptive field” 가 5 x 5 다
[필터의 의미]
그 필터가 슬라이딩하면서 계산을 하는데 중요한 것은 필터 값이 항상 같다는 것이다.
그럼 이제 출력 값에 대해 알아보면 출력 값은 여기 보이는 파란색 Volume 처럼 생길 것이다.
크기는 28 x 28 x (필터의 갯수) 가 될 것이다.
- 필터가 총 5종류가 있는 경우라면 출력은 28 x 28 x 5 인 3D Grid가 된다.
➡ 그러면 이제 어떤 한 점을 찍어서 depth방향으로 바라보면(파란색 Map 안에 5개 점) 이 5개의 점은 정확하게 같은 지역에서 추출된 서로 다른 특징이라고 할 수 있다.
➡ 하지만 각 필터는 서로 다른 특징을 추출한다.
➡ 그러므로 각 필터는 이미지에서 같은 지역을 돌더라도 서로 다른 특징을 뽑아낸다고 볼 수 있다
📜 학생 질문: Layer 내에서 filter가 하는 일이 Symmetric하냐
어떤 점에서 Symmetric하다는 것을 질문하는것인가요?
필터들이 같은 차원을 가지고 같은 계산을 한다는 것을 의미하는 것 같은데요.
필터 연산을 할때 다른 특수한 경우가 있냐는 질문입니다. 답은 없습니다.
가령 우리가 5 x 5 필터가 있다면
슬라이딩 할때마다 같은 연산을 수행하고, 그렇게 나온 값이 activation map입니다.
Pooling Layer
지금까지 Conv Layer 꽤 심도깊게 살펴봤다.
CNN에는 Conv Layer와 Pooling Layer, 그리고 다른 비선형연산(ex.ReLU)이 있었다.
이 중 설명 안한 Pooling Layer를 살펴보겠다.
[Pooling Layer]
- Representation들을 더 작고 관리하게 쉽게 해줌
- Representation을 작게 만드는 이유: 작아지면 파라미터의 수가 줄게되고, 일종의 공간적인 불변성(invaiance)을 얻을 수도 있음
- Downsample 을 수행함.
- 가령 224 x 224 x 64 인 입력이 있다면, 이를 112 x 112 x 64 로 “공간적”으로 줄여줌.
- ✨”Depth”에는 아무 짓도 하지 않음
- 따라서 Depth에는 영향을 주지 않음
- Max Pooling이 일반적으로 쓰임
- Pooling에도 필터 크기를 정할 수 있음
- 얼마만큼의 영역을 한 번에 묶을지를 정하는 것임
MAX POOLING
그럼 풀링의 한 종류인 MAX POOLING의 방법을 보겠다.
[조건]
- 2 x 2 필터
- Stride: 2
[방법]
Conv Layer가 했던 것 처럼 슬라이딩하면서 연산을 수행
대신 내적을 하는 것이 아니라, 필터 안에 가장 큰 값 중에 하나를 고르는 것임.
- 빨간색 영역을 보면 6이 제일 큼
- 녹색을 보면 8이 제일 큼
- 나머지도 마찬가지
Pooling Layer의 Design Choice
Pooling Layer는 몇가지 Design Choice가 존재함.
입력이 W(width), H(Height), D(Depth) 면,
이를 통해 Filter Size를 정해줄 수 있음
여기에 Stride까지 정해주면, 앞서 Conv Layer에서 사용했던 수식을 그대로 이용해서 Design Choice를 할 수 있음
즉, \((W - Filter Size) / Stride + 1\)로 구하면 됨
[특징]
pooling layer에서는 보통 padding을 하지 않음
➡ 우리는 downsampling하고 싶고, 또한 Conv 때처럼 코너의 값을 계산하지 못하는 경우도 없기 때문
➡ Pooling 할때는 padding을 고려하지 않아도 되고 그냥 downsample만 하면 됨
[common choice]
가장 널리 쓰이는 것은,
- 필터사이즈: 2 x 2, 3 x 3
- stride: 2
- 필터가 3 x 3 일때도 보통 stride는 2 x 2 로 함
➡ 앞서 언급했듯, 2 x 2 가 좀더 자주 쓰임
📜 학생 질문: Max pooling이 average pooling보다 더 좋은 이유
좋은 질문입니다. Average Pooling도 물론 사용할 수 있습니다.
왜 max pooling을 주로 사용하지는지에 대한 직관을 설명드리자면,
우리가 다루는 값들은, 얼마나 이 뉴런이 활성되었는지를 나타내는 값 들입니다.
즉, 이 필터가 각 위치에서 얼마나 활성되었는지 입니다.
Max pooling은 그 지역이 어디든, 어떤 신호에 대해 “얼마나” 그 필터가 활성화 되었는지를 알려준다고 알 수 있습니다.
우리가 “인식” 에 대해 생각해보면 어느정도의 직관을 얻을 수 있는데,
그 값이 어디에 있었다는 것 보다는 그 값이 얼마나 큰지가 중요한 것입니다.
📜 학생 질문: "Pooling" 이나 Conv Layer의 "Stride"나 같지않나요?
네 맞습니다. 요즘들어 사람들이 Downsample할때 pooling을 하기보단 stride를 많이 사용하고 있는 추세입니다.
제 생각에는 Pooling 도 일종의 Stride 기법이라고 볼 수 있다고 봅니다.
실제로 요즘은 stride가 더 좋은 성능을 보이는 것 같습니다.
그러니 당연히 Conv Layer의 stride를 사용해도 무방합니다. 그리고 사람들도 그렇게 하고 있습니다.
📜 학생 질문: Pooling 할 때 겹치지 않는 것이 일반적입니까?
네 맞습니다. 보통은 겹치지 않는 것이 일반적입니다.
기본적으로 Downsample을 하고싶은 것이기 때문에
한 지역을 선택하고 값 하나 뽑고, 또 다른 지역 선택하고 값 하나 뽑고 이런식으로 진행합니다.
Fully Connected Layer (FC layer)
우리는 지금 Conv Layer를 배우고 있다 ReLU Layer는 지난 강의에 했던것과 같다.
그리고 downsampling을 하고싶을때는 Pooling을 섞어준다.
그리고 여기 마지막에는 FC Layer가 있다.
➡ 우리가 이전에 살펴본 FC와 똑같다.
[CNN에서의 FC layer 역할]
위 그림의 마지막 Conv Layer의 출력은 3차원 volume으로 이루어진다.
1) 이 값들을 전부 펴서(stretch) 1차원 벡터로 만든다.
2) 그리고 이를 가지고 FC Layer의 입력으로 사용한다. ➡ Conv Net의 모든 출력을 서로 연결
3) 이 마지막 Layer부터는 공간적 구조(spatial structure)를 신경쓰지 않게 됨
4) 전부 다 하나로 통합시키고는 최종적인 추론을 함
5) 그렇게 되면 Score가 출력으로 나오게 됨
📜 학생 질문: 여기 열(col)들을 각각 어떻게 해석해야 하는지?
각 열들의 위에는 POOL같은 것들이 써있죠
우선 여기 보이는 것들은 출력 Activation map입니다.
각 출력들은 하나의 Layer의 결과 값입니다.
처음부터 한 번 살펴보겠습니다. 처음에 Conv Layer를 거치면 activation map이 나옵니다.
그리고 ReLU를 거칩니다. 그리고 Pooling Layer는 그 ReLU의 출력을 입력으로 받아서 Downsampling 하는 것입니다.
Pooling 을 통해 Downsample합니다.
Pool Layer의 출력을 한 번 보면 RELU의 출력과 비슷하게 생겨 보입니다.
하지만 ReLU의 출력을 Downsample한 것이죠. 눈으로 보기에는 비슷하게 생겼을 수 있습니다.
📜 학생 질문: 결과만 보면 정보 자체는 엄청 적을 것 같은데 저 정보만 가지고 어떻게 분류를 할 수 있는지?
우선 저기 오른쪽 맨 끝에있는 Pool Layer의 출력 값은 전체 네트워크를 통과한 집약체라고 할 수 있습니다.
그러므로 우리가 만든 계층구조의 최상위라고 할 수 있습니다. 실제로 Higher level concept을 표현하고 있는 것들입니다.
예전에 Hubel and Wiesel의 예를 보았고, 이를 기반으로 우리는 필터를 계층적으로 쌓아 올렸습니다.
최하위 계층에서는 edges 와 같은 단순한 구조를 찾아냅니다.
그러니 여기 첫번째 열(col)의 map들이 의미하는 것은 각 자리에서 edges같은 것들이 얼마나 존재하는지를 의미합니다.
그리고 지나면 지날수록 더 복잡한 것들을 찾아냅니다.
두 번째 레이어에서는 (edge보다 복잡한) corner 같은 것이 얼마나 있는지를 보여주는 것입니다.
각 Conv의 입력이 원본 이미지(자동차)가 아닙니다. 이전 레이어에서 나온 edge maps과 같은 것들이죠
이런 edge map을 가지고 더 복잡한 것들을 추론을 하는 것입니다.
마지막 pooling layer를 거치기 전까지의 각 값들은 각 필터가 가진 templete이 얼마나 활성되었는지를 표현합니다.
그리고 이런 정보를 가지고 FC Layer를 거치게 되면, 그 정보들을 한데 모아 클래스 스코어를 계산하는 것입니다.
요약하자면, 각 값들이 의미하는 것은 필터의 Templete이 얼마나 활성화 되었는가를 의미하는 것입니다.
📜 학생 질문: Classification 문제를 푸는데 pooling을 얼마나 해야하는지를 어떻게 아는지?
제 대답은, 그저 여러분이 시도해 봐야 한다는 것입니다.
실제로 여러분이 어떤 Design choices를 할때 조금의 직관은 가질 수 있습니다.
Pool을 너무 많이하면 값이 너무 작아질 것이고 전체 이미지를 잘 표현하지 못하겠죠
때로는 조금의 직관이 있을수도 있겠지만, 일반적으로는 다양한 옵션을 시도해 봅니다.
다양한 pooling 사이즈, 필터 크기, 레이어 수 등을 시도해 보는 등의 Crossvalidation을 해야 할 것입니다
그리고 가장 좋은 것을 찾는 것이지요. 어떤 하이퍼파라미터가 좋은지는 어떤 문제이냐에 따라 달라질 수 있습니다.
➕ demo
- 데모 보러가기
- 이 Demo는 CIFAR-10을 학습시킴.
- 이 Demo가 좋은점은 실제로 Filter가 어떻게 생겼고 Activation Map이 어떻게 생겼는지를 볼 수 있다는 점임
- 첫 레이어가 무슨 그림인 지 비교적 알기 쉬움
- 하지만 더 높은 Layer로 가면 갈수록 해당 Layer가 무슨 일을 하는지 해석하기가 점점 힘들어짐
- Demo를 보며 흐름이 어떻게되고 출력이 어떻게 되는지를 전체적으로 살펴보는 것 만으로도 좋음