또 8강으로 돌아온 나..
홀수강을 시러하는 게 분명함
짱졸린 아침부터 시작하려는데
날씨가 인간적으로 너무춥다 그치
미틴것같애
목도리하고 귀도리하고 다녀라!
따숩게 하기
이번 시간은 씨엔엔 아키텍쳐!
ImageNet challenge는 대규모 이미지 데이터셋을 활용하여 객체 인식 알고리즘 성능을 평가하는 대회 중 하나이다.
2010년부터 시작된 대회인데 이 대회는 딥러닝 기술의 발전과 함께 컴퓨티비전 분야에서 중요한 역할을 했다.
이때 2012년에 등장한 AlexNet이라는 딥러닝 기반의 모델이 처음으로 우승을 하면서 혁명을 일으켰다.
AlexNet이 뭔데!
AlexNet은
- 227 x 227 픽셀의 이미지를 input으로 사용
- 5개의 Convolution layers와 3개의 Fully Connected layers로 구성됨
- Max poolingd을 사용하여 차원을 줄임
- ReLU 활성화 함수를 사용하여 nonlinerity를 부여함.
하지만 현재 사용되지 않는 특징들도 존재하는데
- LRN (local response normalization) : 각 뉴런의 출력을 그 주변 출력에 대해 정규화 하는 방식
- 하지만 현재는 Batch Noramalization과 같은 방식이 더 효과적이라 사용하지 않음
- AlexNet은 하드웨어 환경을 반영해 3GB 메모리를 가진 그래픽카드를 사용하여 두 개의 GPU로 분할, 병렬처리로 훈련됨
- 현재는 더 높은 용량의 그래픽카드가 있어, 더 큰 메모리 용량을 활용하여 사용하지 않음.
AlexNet 논문은 엄청 유명한데,
위와 같이 Darwin의 종의기원, Shannon의 대표적인 medical 논문 들의 인용수와 비교해보자면, AlexNet논문이 엄청난 인용수를 가지고 있음을 알 수 있다. (사실 논문을 인용횟수의 척도로 판단하는 것은 옳지않다. 서로 분야도 영역도 다르기 때문! 그냥 대략적인 경향성만 읽도록 하쟈)
AlexNet은 어떻게 생겼는데!
AlexNet은 위와 같은 구성을 가졌고, 실제 논문에서는 64가 아닌 96개의 filter와 padding은 0이다.
또한 output channel == number of filters 이었으므로 64(실제 논문에선 96)임을 알 수 있다.
사실 오른쪽 상단의 잘린 사진을 잘 보면 output size가 48로 두 개가 나뉜 걸 볼 수 있다. -> GPU를 2개 사용했으므로!
또한 output size는 지난 강의에서 배웠던 공식을 사용하여 구하면
56임을 알 수 있다.
이 맵이 KB단위로 소비하는 메모리는 다음과 같다.
다음은 학습해야하는 parmeter의 개수이다.
이 convolution layer를 다시 잘 계산하는데 얼마나 많은 부동소수점 연산이 필요한가!
그렇다고 한 다..
downsampling을 위해
다음과 같이 pooling을 적용하였다.
이렇게 AlexNet 모델을 볼 수 있는데,
이 아키텍쳐에서 파란색 layer에 대한 parameter들이 모두 hyperparameter이다.
어떻게 그것들을 결정한 것인지! 에 대한 대답(?)은 trial and error다.. 즉, 여러가지 시행착오를 거쳐서 이렇게도 저렇게도 해보고 실험적으로 고안된 최적의 값으로 결정해야한다. 라는 뜻이다.
hyperparameter에 의해 위 표 노란색 부분을 살펴보자면 (우리에게 중요한 것 들?)
- 227 x 227 크기의 input을 다루려고 하다보니 앞부분의 conv에서 메모리가 많이 필요하다. 점점 메모리는 감소!
- 반면, parameter개수는 뒷부분, fully-connected 부분에서 증가함. -> 전체가 다 하나로 연결되어야 하니까!
- 앞부분 convolution에서는 kenerl 하나를 share하는 방식으로 연산되므로 많은 수의 parameter를 학습할 필요 x
- 계산 연산 측면에서 본다면, convolution 연산을 진행해야 하는 앞부분에 연산량이 많음.
다음 2013년에 AlexNet보다 성능이 좋은 친구가 등장했다.
바로 ZFNet인데, 더 큰 AlexNet이라고 보면 된다.
위 사진을 보면 원래 input 이 11 x 11 이었는데, 7 x 7로, stride를 2로 줄인것이다.
그렇다면 layer1에 Image size가 훨씬 더 커질 것이다. -> 더 높은 공간 해상도! 를 갖겟징?
다음 conv3, 4, 5에서도 filter 개수를 늘렸다.
filter 개수를 늘린다는 것은 channel 수를 늘린다는 것과 같고 그러면 layer의 volum이 더 커질 것이다.
이는 새로운 아키텍쳐라 볼 수도 있지만 AlexNet에서 hyperparameter를 조정한 경우라고 생각할 수도 있겠다.
다음 새로 2014년에 VGG라는 친구가 등장했다.
보면 성능이 훨씬 더 좋아졌으며 8layers에서 19layers로 확 뛴 것을 볼 수 있다.
이 친구를 더 자세히 알아보면,
VGG를 어떻게 만들었냐! 하면 기본적인 규칙이 있었다.
- 모든 conv를 3x3크기로 쌓으며 stride는 1, padding도 1
- max pooling을 2x2, stirde 2로 적용시킴. -> (절반으로 줄겠다)
- pooling 후에는 이미지 사이즈가 줄지만 channel수를 두배로 증가시켜 volum을 그대로 유지하도록 함
- layer 늘리기!
위는 VGG16을 잘 설명해주는 그림이라 가져와보았다.
앞부분 conv만 살펴보자면, 224x224 input에서 filter를 64개를 적용시킨 후 max pool을 통해 사이즈를 줄였다.
대신 channel 개수를 2배(64 -> 128)증가시킨 것을 볼 수 있다.
VGG에서 주목해보아야 할 특징들이 있는데,
첫번째규칙인 모든 conv가 3x3 이라는 점이다.
사실 이는 Option2와 같이 3x3 conv를 두번 적용한 것과 Option 1에서 5x5 conv를 한번에 적용한 것과 동일한 결과를 도출한다.
하지만 밑에 prameter 개수나 FLOPs를 보면 3x3 conv를 두 번 적용한 것이 훨씬 더 작은 수치를 띠고있다.
이는 filter size를 더 작게 하는것이 더 적은 연산량을 필요로하는 형태로 VGG가 디자인 된다고 볼 수 있다.
다음은 세번째 규칙인 pooling 후 channels 수를 두 배로 늘리는 것이다.
위 사진에서 본 두가지 경우를 비교해보면
channels수를 2배로 늘린 두번째 경우에서 메모리도 더 작게 사용하며 learnable parameter가 더 많아져 다양한 경우에서의 학습이 가능해 성능이 좋아질 수 있을 것이다.
그렇다면 AlexNet과 VGG의 성능을 비교해보자.
VGG가 메모리가 훨씬 더 많이 사용되고 있으며 parameter와 계산량 또한 훨씬 더 많이 사용되고 있다.
-> 그러니까 성능이 훨씬 좋겟징 ..?
2014년에 VGG와 동시에 GoogLeNet이 등장했다.
성능은 좀 더 좋아졌으며 layer가 더 늘었는데, 이는 효율성에 초점을 맞춘 아키텍쳐이다.
GoogLeNet은 어떻게 만들어졌을까!
*위 사진의 오른쪽 하단 빨간색 상자는 stem을 가리킨다.
1) Aggressive Stem
input을 초반에 아주 빠르게 downsampling하는 방식인데,
VGG-16과 비교해보면 훨씬 적은 메모리와 연산량으로 size를 확 줄이는 것을 알 수 있다.
-> 다른 모델에서는 초반 layers에서 큰 conv computation을 하기 때문에 stem network를 사용하여 down sample
(사실 volum이 GoogLeNet은 192, VGG-16는 512로 정보량의 손실을 우려해볼 순 있다고 생각한다....)
2) Inception Module
-> 여러 크기의 필터와 pooling 연산을 동시에 사용하여 input data를 처리하는 아이디어를 기반으로 함.
네트워크가 서로 다른 크기의 특징을 동시에 학습하고 결합할 수 있음.
1x1 Bottleneck layer는 위 그림에서 빨간색 상자를 가리키는데, 1x1 conv를 통해서 channel수를 조정할 수 있었다.
따라서 1x1 conv의 개수에 따라 output의 channels의 개수가 결정이 난다. 이때 이미지의 특성은 그대로 유지하고
단지 channel을 줄이고 싶을때 사용하는 것이라고 보면 된다.
3) Global Average Pooling
VGG-16에서 보면 대부분의 parameter는 FC에 존재하는 것을 위에서 볼 수 있었다.
그래서 GoogLeNet에서는 flatten layer를 통하여 벡터로 만드는 것이 아닌, 각 feature vector의 평균만 남겨 벡터로 만들어 내었다.
즉 VGG-16를 보면 3개의 fc를 연산하였는데, GoogLeNet은 1x1 크기로 감소시켜 parameter의 개수가 현저히 작아진 것을 볼 수 있다.
4) Auxiliary Classifiers
하지만 문제점이 있다.
network의 끝 부분에 있는 loss를 사용하여 backpropagation을 진행하였을때, network가 너무 깊으면 gradient가 너무 작아져
더 이상 흐르지 않게되는 도중에 중단되는 현상이 발생할 수 있다.
그럼 어쨰!
-> 끝부분을 똑 떼다가 중간 중간에 넣어보자!
위 사진을 보면 끝 부분에 있는 network를 중간 지점에다가 넣어서 gradient가 잘 흐를 수 있도록 해주고 있다.
근데 이것은 batch normalization과 같은 효과일 수 있어(?)!
batch normalization은 항상 그 값의 범위가 특정 범위에 정규화 되도록 만들어준다. 이 때문에 gradient가 계속 살아서 뒷 부분까지 잘 흐를 수 있게 해준다.
-> 그래서 중간 중간 똑 떼다 넣는 trick을 사용하지 않아도 batch normalization을 활용하면 되겠따!
다음 등장한 친구는 2015년, ResNet이라는 친구이다.
전의 아키텍처에 비해 엄청난 layers수를 갖고 있는 것을 볼 수 있다.
ResNet : Residual Networks
우리가 Batch Noramlization을 사용하면 10개의 layer에 대해서도 쉽게 train이 가능한데, 더 deep하게 만들면 어떻게 될까?
-> shallow한 모델에 비해서 안 좋아! -> overfiting 되었다고 예측함
하지만 사실! underfitting 된 것.
여기서 deep model이 적어도 shallow model보다는 나아야 하지 않을까? 하는 생각에 마주한 것이다.
deep model이 shallow model을 흉내낼 수는 있어야 하니까 shallow model의 layers는 다 복사해서 오고 나머지 extra layers는 그냥 흘러주는 역할만 하게 두자! 그럼 최소 shallow 모델 보다는 같거나 더 좋겠지! 싶었던 것..
그래서 내린 결론.. 가설. ? 은 -> optimize가 제대로 이루어지지 않은 것.
shallow model보다 deep model이 optimize 하기 더 힘들 것이니까! 왜냐.. identity func은 학습할 수 없어!
그럼 해결은 어떻게 할까!
Network를 바꿔보자! extra layers를 identity function으로 학습되도록 바꿔보자는 것이다.
왼쪽은 기본 VGG의 conv layers이다. 오른쪽은 기존 방식에 추가로 input X를 더하는 구조인데,
만약 conv layers 값이 0이라면 그냥 바로 X를 더해주는 방식으로 진행된다.
기본적으로 ResNet은 residual block을 많이 쌓아 만든 구조라고 볼 수 있다. 그치만 VGG와 같이 각 residual block은 3x3 conv로 디자인 되어있다. 더하여 오른쪽 그림을 보면 색상별로 나누어져 있는 모습을 볼 수 있다.
이렇게 Network를 stage로 나누어 구분하고, 각 stage에서의 spatial resolution과 channel의 변화를 주고있다.
GoogLeNet에서 처럼 aggressive stem을 사용하여 초반 Input을 빠르게 downsample을 하는 방식으로 되어있다.
(224 -> 56으로 size를 확 줄인 것을 볼 수 있다.)
더하여 젤 윗 부분도 GoogLeNet과 같이 FC를 사용하지 않고 global average pooling + single layers를 사용하고 있다.
위 사진은 ResNet-18, ResNet-34을 나타내고 있는데, VGG-16과 비교해보면 ResNet-34가 성능도 좋고 계산량도 현저히 적은 것을 볼 수 있다.
또한 ResNet은 Bottleneck Block으로 이루어져 있는데, 앞서 봤던 1x1 conv를 떠올리면 좋겠다.
왼쪽 Basic block을 보면 C 로 들어가서 C로 나와 연산량이 대략 18(단위는 생략하겠어) 정도이고,
오른쪽 Botteneck block을 보면 4C로 들어가서 4C로 나오고 있다. 여기서 input의 size는 중요하지 않고, 같은 크기로 들어가 같은 크기로 나왔다는 점을 주목해야한다. Bottleneck의 경우 1x1 conv를 통해 size를 줄여주고 다시 3x3 conv를 거친 후 1x1 conv를 적용시켜
원래 input size를 유지하고 있다. 이 경우 연산량도 17로 왼쪽의 경우보다 낮으며 layer가 더 많아졌다는 특징이 있다.
사실 layers가 더 깊어졌다는 것은 nonlinearity가 훨씬 더 증가되었다는 뜻과 같으므로 좋은 것!
아래 사진을 보면 더 직관적으로 나타내고 있다.
block type에 따라 layers 깊이의 차이, 그리고 성능의 차이를 주목하면서 표를 해석하면 좋을 것 같다.
ResNet은 all five main tracks에서 1등을 차지한 것을 볼 수 있으며 다른 여러 대회에서도 우수한 성적(?)을 거두었다.
그리고! 오늘날에도 여전히 널리 쓰이고 있다고 한다.
더하여 성능을 좀 더 향상시키기 위해! (욕심쟁잉)
왼쪽을 보면 output이 nonnegative이 되었을 때 identity function이 제대로 학습이 되지 않는 문제점을 제기하고 있다.
그래서 batch norm과 relu의 순서를 바꾸면 성능이 개선되지만 그렇게 많이 쓰이진 않는답니당..
아래는 여러 모델을 비교한 그래프이다.
표를 잘 보면 여러가지 모델을 대략적으로 평가할 수 있는데,
- AlexNet : 적은 수의 연산이 필요만큼 성능도 낮아
- VGG : 많은 메모리와 연산이 드는 것에 비해 성능이 우월하진 않아.
- GoogLeNet : 효율적이지만 성능이 좋진 않아
- ResNet : 적절한 효율성에 적절한 성능을 가졌어!
가장 좋은 건 Inception-v4 인데, ResNet과 Inception을 합친 것이다.
다음 2016년에 등장한 친구는 더 좋은 성능을 가지고 등장했다. $
이는 앙상블! 이라고 여러가지 모델들을 다 합친 것을 말한다. 가장 err가 작은 것을 볼 수 있음!
ResNets을 더 향상시키려고 노력해서 나온 ResNeXt ... (진짜 욕심ㅁ쟁이)
왼쪽은 앞서 봤던 Botteneck 구조인데 이것을 병렬적으로 사용하는 ResNeXt가 등장했다.
1x1 conv를 사용해서 C가 아닌 c..! small c를 만들어서 다시 4C로 되돌려주는 연산을 여러개를 사용하자! 라는 방향으로 개선되었다.
여기서 9Gc^2 + 8GCc - 17C^2 = 0이라는 Flops 수를 구하는 방정식으로 통해 기존의 bottleneck residual block의 cost와 같게 둔 다음 방정식의 해의 값으로 c를 정한다고 한다.
이러한 개념을 Grouped Convolution 이라고 한다.
일반적인 normal convolution은 group이 1개인 것으로 볼 수 있으며,
오른쪽 그림을 보면 group을 2개로 나누어 Input Cin을 Cin / 2, Cin / 2로 분리하여 연산하고 다시 concat 하는 과정을 거친다.
이것을 확장? 일반화? 하여
G group으로 나누어 G개의 conv layers를 쌓고 C/G output 만큼을 도출하자!
그런데 특별한 경우, G == Cin 인 경우!
예를 들어 R, G, B 3개의 channels이 있을 때, 채널 각각 따로 convolution을 하고 싶을 때 depthwise conv를 사용한다고 한다.
결국 ResNeXt는!
Group Convolution으로 진행하자! -> G parallel pathways와 동일한 결과를 낼 수 있겟당
위 표를 보면 ResNeXt에서 group을 늘리니 Error가 약간씩 줄어드는 것을 볼 수 있다.
즉 그룹을 늘리는 것은 같은 computational complexity를 가지면서 성능은 증가시키는 것으로 볼 수 있다.
다음 2017년에 등장한 친구는 SENet이다.
이것은 residual block 안에 Squeeze-and-excite라는 branch를 추가한 것으로 볼 수 있다.
이 Squeeze-and-excite branch는 global pooling, FC을 진행한 다음 feature map에 집어넣은 것이다.
위 오른쪽 사진에 "Add global context to each residual block!" 라는 문장이 있는데, 이 뜻은 residual이 끝까지 연결되기 전에 옆에 branch를 파서(?) 위와 같은 과정을 거치는 것이다. 각 채널마다 pooling을 거치는 global pooling을 한 뒤 FC를 거쳐 채널을 줄이고 복귀한 뒤, sigmoid -> scaling 순으로 추가적으로 더해준 것이다.
결과적으로 성능은 더 좋아졌음!
2017년 이후에는 ImageNet Challenge가 진행되지 않았고 kaggle로 넘어갔다고 함니다.. (징해....)
그 중 우리가 많이 언급되고 있는 것 중 하나가 Densely Connected Neural Networks가 있다.
이 residual 이라는 개념이 block안에서만 적용(?)되는 것이 아니라 Input이 각 layer에 다 영향을 미치는 것이다.
그 input과 연결된 layer에서 나온 값도 다음 layers에 영향을 미쳐 모든 layers가 다른 layers에 다 영향을 미치는 구조이다.
이는 vanishing gradient의 문제를 완화시켜줄 수 있으며 더 중요한 feature를 왕성하게(?) 잘 흘려줄 수 있다.
더하여 feature를 재사용하는데 도움이 되도록 하고 있다.
또 이는 Mobile Devices 에서도 사용할 수 있도록 한다.
왼쪽과 같은 standard block을 그룹화하여 오른쪽과 같은 depthwise convolution을 진행한다. 더 cost가 작아짐!
또 다른 개념으로 .. Neural Architecture Search가 등장하는데
NN도 아키텍처를 설계하는데 어려움이 있다. 그래서 이를 자동화시켜보자! 는 것인데
- 하나의 네트워크가 하나의 네트워크 아키텍처를 출력한다
- 아키텍처들 중에서 child network를 샘플링 한 다음 그것을 trian 한다.
- train 후에 policy gradient를 사용한다
- policy gradient는 강화학습에서 사용되는 알고리즘으로 policy를 직접적으로 학습하여 agent가 어떤 행동을 취할 지를 결정하는 전략을 개선하는 것이다.
- 시간이 지나면 controller는 좋은 아키텍처가 되도록 학습이 될 것이다!
하지만 이것은!!!
- 기본적으로 매우 비용이 비싸! -> 각각의 gradient step은 child model 전체를 train 해야하니까!
- 헉 800개의 GPU를 가지고 28일동안 train 했대 ... 미첫다..
- 더 효과적인 연구에 중점을 둬야겠다..!
CNN architecture보다 Neural architecture가 더 성능이 좋네! 를 알 수 있답니다. ..
드 디 어 요약이다!
- AlexNet -> ZFNet -> VGG 로 발전해오면서 -> 더 큰 네트워크가 좋은 결과를 냈다!
- GoogLeNet은 efficiency에 중점을 두었었고 aggressive stem, 1x1 bottleneckconvolutions, global avg pool instead of FC layers 같은 것들을 사용했다!
- ResNet은 deep network를 train 하려니까 한계가 있었어 -> 그래서 차원을 줄였어!
- ResNet 이후에는 효과적인 network를 만들기 위해 여러가지 연구들이 등장하기도 했다.
그럼 우린 어떤 아키텍처를 사용해야 하나?
강의에서 말하길, 굳이 자신만의 것을 고집하지 않고 나와있는 것들을 활용하면 된다고 한다.
정확성을 필요로 한다면 ResNet-50, ResNet-101을 사용하는 것이 좋고, 효과적인 것이 필요하다면 MobileNets, ShuffleNetd을 사용해라! 라고 말하고 있다.
와 드디어 다 썼따..
뭐? 짱 졸린 아침부터 시작한다고?
지금 시각은 새벽 한 시를 바라보구있다고라..
그래도 하루만에 포스팅까지 끝낸 엄청난 날이다
(발전형 인간(?))
집에가야지 이제
각박한 세상 흐어어락아ㅓ루
좋은 밤 되세요들 ....
'EECS 498-007' 카테고리의 다른 글
[EECS 498-007] Lecture 10. Training Neural Networks I (2) | 2024.01.29 |
---|---|
[EECS 498-007] Lecture 09. Hardware and Software (2) | 2024.01.25 |
[EECS 498-007] Lecture 06. Backpropagation (1) | 2024.01.21 |
[EECS 498-007] Lecture 04강 Optimization (1) | 2024.01.11 |
[EECS 498-007] Lecture 03강 Linear Classifier (2) | 2024.01.08 |