👀 코드 보기 , 🤷♀️
이 두개의 아이콘을 누르시면 코드, 개념 부가 설명을 보실 수 있습니다:)
CS231N: Lecture 9강의를 빠짐 없이 정리하였고, 어려운 개념에 대한 보충 설명까지 알기 쉽게 추가해 두었습니다.
OverView
오늘은 최신 CNN 아키텍쳐들에 대해서 배워보겠다.
사람들이 가장 많이 사용하는 아키텍쳐들을 아주 심도깊게 살펴볼 것이다.
이들은 모두 ImageNet 첼린지에서 우승한 모델들이다.
연대순으로,
- AlexNet
- VGGNet
- GoogLeNet
- ResNet
그리고 또한 엄청 잘 사용하지는 않지만 역사적인 관점에서 아주 흥미로운 모델들, 그리고 아주 최신의 모델들도 다룰 것이다.
LeNet
[특징]
- LeNet은 산업에 아주 성공적으로 적용된 최초의 ConvNet
- 엄청 간단한 모델이지만 숫자 인식에서 엄청난 성공
[모델 구성]
- LeNet은 이미지를 입력으로 받아서 stride = 1 인 5 x 5 필터를 거치고 몇 개의 Conv Layer와 pooling layer를 거침.
- 그리고 끝 단에 FC Layer가 붙음.
AlexNet
[특징]
- 2012년에 등장해서는 기존의 non-딥러닝 모델들을 능가하는 놀라운 성능을 보여줌
- 최초의 Large scale CNN
- ConvNet 연구의 부흥을 일으킨 장본
- 생긴 것만 봐서는 기존의 LeNet과 상당히 유사함 (레이어만 더 많아짐)
[구조]
- 기본적으로
conv - pool - normalization
구조가 두 번 반복됨 - AlexNet는 5개의
Conv Layer
와 2개의FC-Layer
로 구성됨 - CONV 3,4,5:
conv layer
가 조금 더 붙음 - Max POOL3: 그 뒤에
pooling layer
존재 - FC6, FC7, FC8: 마지막에는
FC-layer
가 몇 개 붙음
[모델 크기]
- 입력의 크기: 227 x 227 x 3 (AlexNet의 ImageNet으로 학습시키는 경우)
- 첫 레이어:
CONV
레이어로, 살펴보면 11 x 11 필터가 stride = 4 로 96개가 존재(출력 차원은 55)- 첫 레이어의 출력사이즈:
(전체 이미지 크기 - 필터 크기) / Stride + 1
이므로 55 x 55 x 96이다 - 첫 레이어의 파라미터 개수: 11 x 11 필터가 총 96개 있으므로 필터 하나가 11 x 11 x 3 을 통과 하여 필터의 크기 X 96, 즉 35K개 이다.
- 첫 레이어의 출력사이즈:
- 두번째 레이어:
Pooling Layer
로, stride = 2 인 3 x 3 필터 존재- 두번째 레이어의 출력사이즈:
(전체 이미지 크기 - 필터 크기) / Stride + 1
이므로 27 x 27 x 96이다 - 두번째 레이어의 파라미터 개수: Pooling layer에는 파라미터(우리가 학습시키는 가중치)가 없다. pooling의 경우에는 가중치가 없고 그저 특정 지역에서 큰 값을 뽑아내는 역할만 함.
- 두번째 레이어의 출력사이즈:
- 끝부분 레이어들: 끝에 몇 개의
FC-Layer
가 있다.- 4096개의 노드를 가진 레이어임
FC8
는 Softmax를 통과함 ➡ 1000 ImageNet 클래스로 이동
[더 자세히 알아보기]
- 활성화 함수: ReLU (딥러닝 모델에서 아주 보편화된 방법)
- local response normalization layer: 채널간의 normalization을 위한 것 (요즘은 잘 사용하지 않음)
- data augumentation을 엄청 했다. ➡ 논문이 더 자세하지만 flipping, jittering, color norm 등을 적용했다.
- Dropout을 사용
- 학습 시 Batch size는 128
- SGD momentum 사용
- 초기 Learning rate 는 1e-2 val accuracy가 올라가지 않는 지점에서는 학습이 종료되는 시점까지 Learning rate를 1e-10까지 줄임
- 그리고 wight decay를 사용
- 마지막에는 모델 앙상블로 성능을 향상킴
[AlexNet 다이어그램 분석]
AlexNet 다이어그램을 보면 대체로 다른 Conv Net의 다이어그램과 유사하긴 하지만 한 가지 차이점이 존재
그것은 바로 모델이 처번쨰 레이어에서 두개로 나눠져서 서로 교차하는 것임
- 이는 AlexNet을 학습할 당시에 GPU는 메모리가 3GB 뿐인 GTX850를 사용하여 전체 레이어를 GPU에 다 넣을 수 없었기 때문이다.
➡ 그래서 네트워크를 GPU에 분산시켜서 넣었다.
➡ 그래서 각 GPU가 모델의 뉴런과 Feature Map을 반반씩 나눠가짐 - 다이어그램을 유심히 살펴보면 각 GPU에서의 Depth가 48이다.
Conv 1,2,4,5
: 여기에서는 같은 GPU 내에 있는 Feature Map만 사용
- Conv 1,2,4,5는 전체 96 feature map을 볼 수 없음
- Conv 1,2,4,5는 48개의 Feature Map만 사용하는 셈임
conv 3
와 FC 6, 7, 8
: 이 레이어들은 이전 계층의 “전체 Feature map”과 연결되어 있음
- 이 레이어들에서는 GPU간의 통신을 하기 때문에 이전 입력 레이어의 전체 Depth를 전부 가져올 수 있는 것임
📜 학생 질문: AlexNet이 기존의 모델들보다 뛰어날 수 있었던 이유
이는 딥러닝와 Conv Net 때문입니다. 이들은 기존의 방법들과 완전히 다른 접근방법입니다.
AlexNet이 최초로 딥러닝과 Conv Net을 적용하였습니다.
ZFNet
[특징]
- 2013년의 ImageNet Challange의 승자
- ZF는 저자들의 이름을 딴 명칭
- AlexNet의 하이퍼파라미터를 개선한 모델
- AlexNet과 같은 레이어 수이고 기존적인 구조도 같지만 stride size, 필터 수 같은 하이퍼파라미터를 조절하여 AlexNet의 Error rate를 좀 더 개선시킴
VGGNet
이 시기 가장 큰 차이점이라면 우선 네트워크가 훨씬 더 깊어졌다는 것이다.
2012/2013년에는 8개의 레이어였지만 2014년에는 19레이어와 22 레이어로 늘어났다 ➡ 훨씬 더 깊어졌다.
[특징]
- 훨씬 더 깊어지고, 더 작은 필터를 사용
- AlexNet에서는 8개의 레이어였지만 VGGNet은 16에서 19개의 레이어임
- VGGNet은 아주 작은 필터만 사용 ➡ 항상 3 x 3 필터(이웃픽셀을 포함할 수 있는 가장 작은 필터)
- 이렇게 작은 필터를 유지해 주고 주기적으로 Pooling을 수행하면서 전체 네트워크를 구성
- VGGNet은 아주 심플하면서도 고급진 아키텍쳐이고 ImageNet에서 7.3%의 Top 5 Error를 기록함.
[작은 필터를 사용한 이유]
- 우선 필터의 크기가 작으면 파라미터의 수가 더 적으므로 큰 필터에 비해 레이어를 조금 더 많이 쌓을 수 있음.
➡ 작은 필터를 사용하면 Depth를 더 키울 수 있음 - 3 x 3 필터를 여러 개 쌓은 것은 결국 7 x 7 필터를 사용하는 것과 실질적으로 동일한 Receptive Filter를 가지는 것임
📜 stride = 1 인 3 x 3필터를 세 개의 Receptive Filed는 어떻게 될까
Stride가 1인 필터 세 개를 쌓게 되면 실질적인 Receptive Field가 어떻게 될까
- Receptive Field: filter가 한번에 볼 수 있는 입력의 “Sparical area” 이다.
정답:
15 픽셀
해설:
필터들이 서로 겹치기 때문
실제로 어떤 일이 발생하는지 한번 살펴보자.
우선 첫 번째 레이어의 Receptive Field는 3 x 3이다.
두 번째 레이어의 경우는 각 뉴런이 첫 번째 레이어 출력의 3 x 3 만큼을 보게 될 것이다.
그리고 3 x 3 중에 각 사이드는 한 픽셀씩 더 볼 수 있게 된다.
따라서 두번째 레이어의 경우는 실제로 5 x 5의 receptive filed를 가지게 되는 것이다.
세 번째 레이어의 경우 두 번째 레이어의 3 x 3 을 보게된다.
그리고 이 과정을 피라미드처럼 그려보면, 결국 입력 레이어의 7 x 7을 보게되는 것이다.
따라서 실질적인 Receptive Field는 여기에서 7 x 7 이 된다.
하나의 7 x 7 필터를 사용하는 것과 동일하다.
따라서 이는 7 x 7 필터와 실직적으로 동일한 receptive filed를 가지면서도 더 깊은 레이어를 쌓을 수 있게 된다.
[필터 적용]
- 더 깊게 쌓으므로써 Non-Linearity를 더 추가할 수 있고 파라미터 수도 더 적어지게 된다.
전체 파라미터의 갯수를 살펴보면 3 x 3 필터에는 9개의 파라미터가 있다. ➡ 3 x 3가 되고, Depth인 C가 있으니 3 x 3 x C 가 됟다. - 그리고 출력 Feature Map의 갯수를 곱해줘야 하는데 이 경우에는 입력 Depth(C)와 같늠.
➡ 따라서 각 레이터 당 3 x 3 x C x C 가 되고 레이어가 세개 이므로 3을 더 곱해줌 - 7 x 7 필터인 경우에는 7 x 7 x C x C임.
➡ 따라서 더 적은 파라미터를 가지게 됨 - 전체 네트워크에 적용(하나하나 읽어보면 많은 도움이 될 것)
[메모리 사용]
비슷한 패턴이 반복(Conv Layer
와 Pooling Layer
가 반복적으로 진행됨)
VGG16의 Layer의 수는 16개이다.
➡ VGG19의 경우 유사한 아키텍쳐이지만 Conv Layer
가 조금 더 추가됨
- Forward pass시 필요한 전체 메모리
- 각 노드가 4 bytes 의 메모리를 차지하므로 전체 약 100 MB의 메모리가 필요(100MB가 전체 메모리 사용량)
하지만 이 값은 Forward Pass 만 계산한 것 - Backward Pass를 고려한다면 더 많은 메모리가 필요(VGG16은 메모리사용량이 많은 편임)
- 전체 메모리가 5GB라면 이미지 하나당 100MB이므로 50장 밖에 처리할 수 없음
- 각 노드가 4 bytes 의 메모리를 차지하므로 전체 약 100 MB의 메모리가 필요(100MB가 전체 메모리 사용량)
📜 학생 질문: "네트워크가 더 깊다"는게 "필터의 갯수가 더 많은 것"을 의미하는 것인지 "레이어의 갯수가 더 많은 것"을 의미하는 것인지
이 경우에는 레이어의 갯수를 의미합니다.
Depth 라는 용어는 두 가지도 사용할 수 있습니다. 첫 째로는 채널의 Depth입니다. Width, Height, Depth 할때 Depth이죠
반면 일반적으로 “네트워크의 깊이(Depth)”라고 할 때는 네트워크의 전체 레이어의 갯수 를 의미합니다.
“학습 가능한 가중치를 가진 레이어의 갯수” 를 의미합니다. 가령 Conv Layer와 FC Layer 등 말입니다.
GoogLeNet
2014년 Classification Challenge에서 우승한 모델입니다.
248 00:28:37,612 –> 00:28:47,776 저GoogLeNet도 엄청 깊은 네트워크입니다. 22개의 레이어를 가지고있죠. 그런데 GoogLeNet에서 가장 중요한 것은
249 00:28:47,776 –> 00:28:57,866 효율적인 계산에 관한 그들의 특별한 관점이 있다는 것과 높은 계산량을 아주 효율적으로 수행하도록 네트워크를 디자인했다는 점입니다.
250 00:28:57,866 –> 00:29:05,023 GoogLeNet은 Inception module을 사용합니다. 앞으로 더 깊이 배울 내용입니다. 기본적으로 GoogLeNet은
251 00:29:05,023 –> 00:29:08,336 Inception module을 여러개 쌓아서 만듭니다.
252 00:29:08,336 –> 00:29:19,841 GoogLeNet에는 FC-Layer가 없습니다. 파라미터를 줄이기 위해서죠. 전체 파라미터 수가 5M 정도입니다. 60M인 AlexNet보다 적죠
253 00:29:19,841 –> 00:29:24,308 그럼에도 불구하고 훨씬 더 깊습니다.
254 00:29:24,308 –> 00:29:26,975 ILVRC 14에서 6.7%의 top-5 error로 우승을 거머쥡니다.
255 00:29:31,392 –> 00:29:35,363 그렇다면 inception module이 무엇일까요? inception module가 만들어지게된 배경을 살펴보면
256 00:29:35,363 –> 00:29:40,023 그들은 “a good local network typology”를 디자인하고 싶었습니다.
257 00:29:40,023 –> 00:29:52,341 그리고 “network within a network” 라는 개념으로 local topology를 구현했고 이를 쌓아올렸습니다.
258 00:29:52,341 –> 00:29:58,387 이 Local Network를 Inception Module이라고 합니다.
259 00:29:58,387 –> 00:30:07,138 Inception Module 내부에는 동일한 입력을 받는 서로 다른 다양한 필터들이 “병렬로” 존재합니다.
260 00:30:07,138 –> 00:30:11,896 이전 레이어의 입력을 받아서 다양한 Conv 연산을 수행하는 것이죠
261 00:30:11,896 –> 00:30:25,647 1x1 / 3x3 / 5x5 conv에 Pooling도 있습니다. 여기에서는 3x3 pooling이죠 각 레이어에서 각각의 출력 값들이 나오는데
262 00:30:25,647 –> 00:30:31,499 그 출력들을 모두 Depth 방향으로 합칩니다(concatenate).
263 00:30:31,499 –> 00:30:38,893 그렇게 합치면 하나의 tensor로 출력이 결정되고 이 하나의 출력을 다음 레이어로 전달하는 것입니다.
264 00:30:41,020 –> 00:30:50,015 지금까지는 다양한 연산을 수행하고 이를 하나로 합쳐준다는 아주 단순한 방식(naive way)을 살펴봤습니다.
265 00:30:50,015 –> 00:30:52,386 그렇다면 이 방법의 문제가 무엇일까요?
266 00:30:52,386 –> 00:30:57,717 문제는 바로 계산 비용에 있습니다.
267 00:30:58,982 –> 00:31:11,156 예제를 자세히 들여다봅시다. 우선 128개의 1x1 필터가 있습니다. 192개의 3x3 필터와 96개의 5x5 필터도 있습니다.
268 00:31:11,156 –> 00:31:19,398 그리고 stride를 조절하여 입/출력 간의 spatial dimention을 유지시켜줍니다.
269 00:31:21,341 –> 00:31:29,231 이 경우에 1 x 1 x 128 conv의 출력은 어떻게 될까요?
270 00:31:35,910 –> 00:31:39,910 네 맞습니다. 28 x 28 x 128이 되겠죠.
271 00:31:40,988 –> 00:31:53,159 1x1 conv의 경우 입력에 맞춰 depth는 256입니다.
272 00:31:53,159 –> 00:32:00,194 그리고 128개의 필터 하나 당 28 x 28 Feature map을 생성하게 될 것입니다.
273 00:32:00,194 –> 00:32:02,361 그렇다면 출력은 28 x 28 x 128 이 되겠죠
274 00:32:05,469 –> 00:32:14,939 이런 방식으로 각 필터의 출력 값을 계산해보면
275 00:32:14,939 –> 00:32:20,379 3 x 3 conv의 경우에 출력이 28 x 28 x 192이 될 것이고
276 00:32:20,379 –> 00:32:24,559 5 x 5 conv의 경우에 96개의 필터이므로 출력이 28 x 28 x 96 이 될 것입니다.
277 00:32:24,559 –> 00:32:34,712 Pooling Layer는 input에서 depth가 변하지 않습니다.
278 00:32:34,712 –> 00:32:40,192 그리고 Stride를 잘 조절해서 Spatial dimention를 유지하면 입력과 출력의 크기는 같습니다.
279 00:32:41,225 –> 00:32:51,498 그렇다면 모든 출력 값들을 합친(concat) 사이즈를 계산해봅시다. 28 x 28 은 동일하고 depth가 점점 쌓이게 됩니다.
280 00:32:51,498 –> 00:32:59,330 28 x 28 에 모든 depth를 더하면 최종적으로 28 x 28 x 672이 됩니다.
281 00:33:01,113 –> 00:33:10,208 Inception module의 입력은 28 x 28 x 256 이었으나 출력은 28 x 28 x 672 이 된 것입니다.
282 00:33:11,466 –> 00:33:17,254 spatial dimention은 변하지 않았지만 depth가 엄청나게 불어난 것이죠
283 00:33:17,254 –> 00:33:18,188 질문있나요?
284 00:33:18,188 –> 00:33:21,905 [학생이 질문]
285 00:33:21,905 –> 00:33:25,546 질문은 어떻게 출력의 spatial dimention이 28 x 28이 될 수 있는지 입니다.
286 00:33:25,546 –> 00:33:29,307 이 경우는 spatial dimention을 유지하기 위해서 zero padding을 한 경우입니다.
287 00:33:29,307 –> 00:33:33,403 그리고 depth-wise로 합쳤습니다(concat).
288 00:33:34,395 –> 00:33:36,233 질문있나요?
289 00:33:36,233 –> 00:33:39,650 [학생이 질문]
290 00:33:44,824 –> 00:33:47,805 질문은 입력의 depth가 256인 이유가 무엇인지 입니다.
291 00:33:47,805 –> 00:33:53,814 현재 입력은 네트워크의 입력이 아닙니다. 네트워크 중간에 있는 어떤 한 레이어의 입력인 것이죠
292 00:33:53,814 –> 00:34:00,506 256이라는 값은 바로 직전에 있던 inception module의 출력 depth라고 할 수 있습니다.
293 00:34:00,506 –> 00:34:08,438 현재 레이어의 출력이 28 x 28 x 672 이었습니다. 이 값이 다음 레이어로 넘어가는 것입니다 .
294 00:34:08,438 –> 00:34:09,915 질문있나요?
295 00:34:09,916 –> 00:34:13,333 [학생이 질문]
296 00:34:17,039 –> 00:34:23,181 질문은 어떻게 1 x 1 conv의 출력이 28 x 28 x 128이 되는지 입니다.
297 00:34:23,181 –> 00:34:34,058 이 필터는 1 x 1 conv 필터입니다. 이 필터가 입력 28 x 28 x 256 돌아다니면서 conv연산을 수행하겠죠
298 00:34:35,485 –> 00:34:41,956 1 x 1 conv는 입력의 depth인 256 만 가지고 내적을 한다고 보시면 됩니다.
299 00:34:41,956 –> 00:34:46,983 그렇게 되면 필터 하나 당 28 x 28 x 1 의 feature map을 얻게 될 것입니다.
300 00:34:46,983 –> 00:34:58,311 다시 말해 입력의 각 픽셀마다 값이 하나 씩 계산됩니다. 그러면 필터당 28 x 28 x 1이 되겠죠. 그리고 필터가 128개 입니다.
301 00:35:01,050 –> 00:35:04,800 따라서 28 x 28 x 128 이 되는 것입니다.
302 00:35:05,809 –> 00:35:10,403 그리고 이 레이어들의 계산량을 한번 살펴봅시다
303 00:35:10,403 –> 00:35:22,553 첫 번째 예시로 1 x 1 conv를 살펴봅시다. 1 x 1 conv는 각 픽셀마다 1 x 1 x 256 개의 내적연산을 수행합니다.
304 00:35:24,545 –> 00:35:28,358 따라서 픽셀 당 256번의 곱셈 연산이 수행되는 것이죠 (Conv Ops:맨 뒤의 256)
305 00:35:28,358 –> 00:35:37,865 그리고 픽셀이 총 28 x 28 이므로 처음 “28 x 28” 이 여기에 해당합니다.
306 00:35:37,865 –> 00:35:53,859 그리고 이런 연산을 수행하는 필터가 총 256개 있으므로
307 00:35:53,859 –> 00:36:01,221 1 x 1 conv에서의 전체 연산량은 28 x 28 x 128 x 256 입니다.
308 00:36:02,129 –> 00:36:10,349 이런 식으로 3x3/5x5 conv 의 연산량도 계산해 볼 수 있습니다.
309 00:36:10,349 –> 00:36:16,690 따라서 하나의 Inception Module에서의 전체 연산량은 854M 가 됩니다.
310 00:36:17,968 –> 00:36:21,191 [학생이 질문] 각 필터의 depth인 128, 192, 96이 의미가 있는지
311 00:36:22,131 –> 00:36:29,044 이 값들을 제가 임의로 정한 값들입니다.
312 00:36:29,044 –> 00:36:35,594 하지만 실제 Inception Net에서도 비슷한 값이긴 합니다.
313 00:36:35,594 –> 00:36:43,103 GoogLeNet의 각 Inception Module에는 파라미터 값이 다양하기 때문에 그 중 일부를 참고한 값들입니다.
314 00:36:45,089 –> 00:36:49,046 아무튼 이는 연산량이 아주 많습니다.
315 00:36:49,046 –> 00:36:55,507 그리고 Pooling layer 또한 문제를 악화시킵니다. 왜냐하면 입력의 Depth를 그대로 유지하기 때문입니다.
316 00:36:57,062 –> 00:37:03,519 레이어를 거칠때마다 Depth가 점점 늘어만 갑니다.
317 00:37:03,519 –> 00:37:10,513 Pooling의 출력은 이미 입력의 Depth와 동일하고 여기에 다른 레이어의 출력이 계속해서 더해지게 되는 것입니다.
318 00:37:10,513 –> 00:37:18,960 이 경우에는 입력의 Depth는 256이었지만 출력은 672이 됩니다. 그리고 레이어를 거칠수록 점점 더 늘어나게 되는 것이죠
319 00:37:21,920 –> 00:37:25,441 이 문제를 어떻게 해결할 수 있을까요?
320 00:37:25,441 –> 00:37:36,181 GoogLeNet에서 사용한 key insight는 “bottleneck layer” 를 이용하는 것입니다. Conv 연산을 수행하기에 앞서
321 00:37:36,181 –> 00:37:43,174 입력을 더 낮은 차원으로 보내는 것이죠
322 00:37:45,007 –> 00:37:46,642 낮은 차원으로 보낸다는 것이 어떤 의미일까요?
323 00:37:46,642 –> 00:37:58,080 1x1 conv를 다시 한번 살펴봅시다. 1x1 conv는 각 spatial location에서만 내적을 수행합니다.
324 00:38:00,141 –> 00:38:06,139 그러면서 depth만 줄일 수 있습니다. 입력의 depth를 더 낮은 차원으로 projection 하는 것입니다.
325 00:38:06,139 –> 00:38:10,515 Input feature map들 간의 선형결합(linear combination) 이라고 할 수 있습니다.
326 00:38:12,880 –> 00:38:18,199 주요 아이디어는 바로 입력의 depth를 줄이는 것입니다.
327 00:38:18,199 –> 00:38:29,085 각 레이어의 계산량은 1x1 conv를 통해 줄어듭니다.
328 00:38:29,085 –> 00:38:36,162 3x3/5x5 conv 이전에 1x2이 추가됩니다.
329 00:38:36,162 –> 00:38:42,315 그리고 polling layer 후에도 1x1 conv가 추가되죠
330 00:38:43,284 –> 00:38:47,609 1x1 conv가 bottleneck layers의 역할로 추가되는 것입니다.
331 00:38:48,562 –> 00:38:52,736 그렇다면 다시한번 계산량을 세어봅시다
332 00:38:52,736 –> 00:38:58,589 우선 이전과 입력은 동일합니다. 28 x 28 x 256 이죠
333 00:38:58,589 –> 00:39:12,856 1 x 1 conv가 depth 의 차원을 줄여줍니다. 3 x 3 conv 앞쪽의 1 x 1 conv의 출력은 28 x 28 x 64 이죠
334 00:39:14,184 –> 00:39:25,154 앞선 예시 처럼 28 x 28 x 256 을 입력인 대신에 28 x 28 x 64인 것입니다. .
335 00:39:25,154 –> 00:39:31,454 conv의 입력이 더 줄어든 셈입니다.
336 00:39:31,454 –> 00:39:40,499 3x3 뿐만 아니라 5x5 conv와 pooling layer에서도 동일한 작용을 하게됩니다.
337 00:39:41,562 –> 00:39:51,214 그렇다면 이제 전체 계산량을 계산해봅시다. 현재는 1x1 conv가 추가된 상태입니다.
338 00:39:51,214 –> 00:40:02,499 계산해보면 전체 358M번의 연산을 수행합니다. 기존의 854M보다 훨씬 줄어든 셈입니다.
339 00:40:02,499 –> 00:40:10,438 이를 통해 배울 수 있는 점은 1x1 conv를 이용하면 계산량을 조절할 수 있다는 사실입니다.
340 00:40:10,438 –> 00:40:12,118 질문있나요?
341 00:40:12,118 –> 00:40:15,535 [학생이 질문]
342 00:40:23,525 –> 00:40:30,979 질문은 “1 x 1 Conv를 수행하면 일부 정보손실이 발생하지 않는지” 입니다.
343 00:40:30,979 –> 00:40:35,112 정보 손실이 발생할 수는 있습니다.
344 00:40:35,112 –> 00:40:46,013 그러나 동시에 redundancy가 있는 input features를 선형결합 한다고 볼 수 있습니다. 1x1 conv로 선형결합을 하고
345 00:40:47,623 –> 00:40:59,422 non-linearity를 추가하면(ReLU같은) 네트워크가 더 깊어지는 효과도 있습니다. 이것이 엄밀한 해석은 아닙니다. 하지만
346 00:40:59,422 –> 00:41:07,314 일반적으로 1x1 conv를 추가하면 여러모로 도움이 되고 더 잘 동작합니다.
347 00:41:07,314 –> 00:41:15,627 Inception Module에서 1 x 1 convs를 사용하는 기본적인 이유는 계산복잡도를 조절하기 위해서입니다.
348 00:41:15,627 –> 00:41:20,450 GooleNet은 Inception module들을 쌓아올려 구성합니다.
349 00:41:20,450 –> 00:41:22,827 가운데 그림이 완전한 모습의 inception architecture 입니다.
350 00:41:22,827 –> 00:41:32,773 GoogLeNet을 더 깊게 알아봅시다. 우선 슬라이드에 안맞아서 그림을 돌려놨습니다.
351 00:41:32,773 –> 00:41:41,867 GoogLeNet의 앞단(stem) 에는 일반적인 네트워크구조 입니다. 초기 6개의 레이어는 지금까지 봤던 일반적인 레이어들이죠
352 00:41:43,256 –> 00:41:48,570 처음에는 conv pool을 몇 번 반복합니다.
353 00:41:48,570 –> 00:41:54,911 이 후에는 Inception module에 쌓이는데 모두 조금씩 다릅니다.
354 00:41:54,911 –> 00:41:58,433 그리고 마지막에는 classifier 결과를 출력합니다.
355 00:41:58,433 –> 00:42:08,982 GoogLeNet에서는 계산량이 많은 FC-layer를 대부분 걷어냈고 파라미터를가 줄어들어도 모델이 잘 동작함을 확인했습니다.
356 00:42:08,982 –> 00:42:17,098 그리고 여기 보시면 추가적인 줄기가 뻗어있는데 이들은 보조분류기(auxiliary classifier) 입니다.
357 00:42:18,866 –> 00:42:23,273 그리고 이것들은 또한 당신이 알고있는 단지 작은 미니 네트워크들입니다.
358 00:42:23,273 –> 00:42:29,217 Average pooling과 1x1 conv가 있고 FC-layey도 몇개 붙습니다.
359 00:42:29,217 –> 00:42:35,702 그리고 SoftMax로 1000개의 ImageNet class를 구분합니다.
360 00:42:35,702 –> 00:42:41,350 그리고 실제로 이 곳에서도 ImageNet trainset loss를 계산합니다.
361 00:42:41,350 –> 00:42:51,752 네트워크의 끝에서 뿐만 아니라 이 두 곳에서도 Loss를 계산하는 이유는 네트워크가 깊기 때문입니다.
362 00:42:51,752 –> 00:43:02,140 보조분류기를 중간 레이어에 달아주면 추가적엔 그레디언트를 얻을 수 있고
363 00:43:02,140 –> 00:43:13,484 따라서 중간 레이어의 학습을 도울 수 있습니다.
364 00:43:13,484 –> 00:43:20,711 전체 아키텍쳐의 모습입니다. 가중치를 가진 레이어는 총 22개입니다.
365 00:43:20,711 –> 00:43:29,474 각 Inception Module은 1x1/3x3/5x5 conv layer를 병렬적으로 가지고있습니다.
366 00:43:29,474 –> 00:43:44,128 GoogLeNet은 아주 신중하게 디자인된 모델입니다. 모델 디자인의 일부는 앞서 말씀드린 직관들에서 비롯된 것들이고,
367 00:43:44,128 –> 00:43:55,511 일부는 Google의 거대한 클러스터를 이용한 cross validation을 수행한 결과 나온 최적의 디자인이기도합니다.
368 00:43:55,511 –> 00:43:57,105 질문있나요?
369 00:43:57,105 –> 00:44:00,522 [학생이 질문]
370 00:44:24,442 –> 00:44:32,457 질문은 “보조분류기에서 나온 결과를 최종 분류결과에 이용할 수 있는지” 입니다.
371 00:44:32,457 –> 00:44:39,164 GoogLeNet 학습 시, 각 보조분류기의 Loss를 모두 합친 평균을 계산합니다. 아마도 도움일 될 것입니다.
372 00:44:39,164 –> 00:44:49,272 최종 아키텍쳐에서 보조분류기의 결과를 사용하는지 정확히 기억이 나지 않습니다만 충분히 가능성 있습니다. 한번 확인해 보시기 바랍니다.
373 00:44:49,272 –> 00:44:52,689 [학생이 질문]
374 00:44:58,352 –> 00:45:10,219 질문은 “bottleneck layer를 구성할 때 1x1 conv 말고 다른 방법으로 차원을 축소시켜도 되는지” 입니다.
375 00:45:10,219 –> 00:45:17,138 여기에서 1x1 conv를 쓴 이유는 차원 축소의 효과도 있고 다른 레이어들처럼 conv layer이기 때문입니다.
376 00:45:17,138 –> 00:45:26,180 차원 축소 과정에서 이전의 feature map와 연관이 있는지 학습하려면 전체 네트워크를 Backprop으로 학습시킬 수 있어야 합니다.
377 00:45:28,601 –> 00:45:30,730 질문있나요?
378 00:45:30,730 –> 00:45:34,147 [학생이 질문]
379 00:45:35,807 –> 00:45:42,549 질문은 “각 레이어가 가중치를 공유하는지 아닌지” 입니다.
380 00:45:42,549 –> 00:45:45,542 네 모든 레이어를 가중치를 공유하지 않습니다.
381 00:45:45,542 –> 00:45:46,690 질문있나요?
382 00:45:46,690 –> 00:45:50,107 [학생이 질문]
383 00:45:56,784 –> 00:46:00,143 질문은 “왜 앞선 레이어에서 그레디언트를 전달해야만 하는지” 입니다.
384 00:46:00,143 –> 00:46:07,785 네트워크의 맨 마지막에서부터 Chain rule을 이용해서 그레디언트가 전달된다고 생각해봅시다.
385 00:46:09,599 –> 00:46:21,178 네트워크가 엄청 깊은 경우에서는 그레디언트 신호가 점점 작아지게 되고 결국에는 0에 가깝게 될 수 있습니다.
386 00:46:21,178 –> 00:46:28,377 그렇기 때문에 보조 분류기를 이용해서 추가적인 그레디언트 신호를 흘려줍니다.
387 00:46:28,377 –> 00:46:32,667 [학생이 질문]
388 00:46:32,667 –> 00:46:35,853 질문은 “backprob을 각 보조분류기에서 별도로 여러번 수행하는지” 입니다.
389 00:46:35,853 –> 00:46:41,446 아닙니다. backprob은 한번만 합니다. 어떤 식으로 생각하시면 되냐면
390 00:46:41,446 –> 00:46:48,075 computational graph 상에 서로 다른 출력이 있는 것인데
391 00:46:48,075 –> 00:46:54,004 각 출력에서의 gradient를 모두 계산한 다음 한번에 Backprop을 합니다.
392 00:46:54,004 –> 00:46:58,970 마치 computational graph 상에 다 함께 있는 것 처럼 생각하고 계산한다고 보시면 됩니다.
393 00:46:58,970 –> 00:47:05,423 진도가 많이 남았으므로 질문은 수업종료 후 해주시기 바랍니다.
394 00:47:07,353 –> 00:47:10,520 GoogLeNet에는 기본적으로 22개의 레이어가 있습니다.
395 00:47:11,441 –> 00:47:15,983 아주 효율적인 Inception module이 있고 FC Layer를 들어냈습니다
396 00:47:15,983 –> 00:47:22,026 AlexNet보다 12배 작은 파라미터를 가지고있고 GoogLeNet은 ILSVRC 2014 clssification의 우승자이죠
397 00:47:25,228 –> 00:47:30,869 자 그럼 2015년도의 우승자를 살펴보겠습니다. ResNet이 바로 그 주인공입니다.
398 00:47:30,869 –> 00:47:38,339 ResNet은 혁명적으로 네트워크의 깊이가 깊어진 모델입니다. 2014년부터 네트워크가 깊어지긴 했지만
399 00:47:38,339 –> 00:47:45,616 ResNet 아키텍쳐는 152 레이어로 엄청나게 더 깊어졌죠
400 00:47:45,616 –> 00:47:48,846 지금부터는 ResNet에 대해서 조금 더 알아보겠습니다.
401 00:47:48,846 –> 00:47:54,286 ResNet 아키텍쳐는 엄청나게 깊은 네트워크입니다. 기존의 어떤 네트워크보다도 훨씬 더 깊습니다
402 00:47:54,286 –> 00:48:00,479 ResNet는 residual connections 라는 방법을 사용합니다. 지금부터 논의해볼 주제입니다.
403 00:48:00,479 –> 00:48:04,158 ImageNet데이터를 분류하기 위해 ResNet은 152개의 레이어를 가지고 있습니다.
404 00:48:04,158 –> 00:48:07,969 그리고 ILSVRC’15에서 3.57% top5 error를 기록했습니다.
405 00:48:07,969 –> 00:48:18,114 그리고 아주 놀랍게도 이들은 ResNet 하나로 ImageNet과 COCO classification/detection 대회를 모조리 휩쓸었습니다.
406 00:48:18,114 –> 00:48:23,546 그리고 다른 참가자들보다 월등히 우수했습니다.
407 00:48:25,055 –> 00:48:32,538 자 그럼 ResNet과 residual connection의 기본 Motivation에 대해서 알아봅시다
408 00:48:32,538 –> 00:48:41,939 그들이 처음 시작한 질문은 바로 일반 CNN을 깊고 더 깊게 쌓게되면 어떤 일이 발생할지였습니다.
409 00:48:41,939 –> 00:48:53,874 가령 VGG에 conv pool 레이어를 깊게만 쌓는다고 과연 성능이 더 좋아지는 것일까요?
410 00:48:55,601 –> 00:48:58,421 대답은 NO 입니다.
411 00:48:58,421 –> 00:49:06,599 네트워크가 깊어지면 어떤 일이 발생하는지 살펴보겠습니다. 20레이어/56레이어의 네트워크를 한번 비교해보죠
412 00:49:09,498 –> 00:49:16,817 두 모델 다 평범한(plain) CNN입니다. 오른쪽의 test error의 경우는 56 레이어가 20 레이어보다 안좋습니다.
413 00:49:16,817 –> 00:49:19,771 더 깊은 네트워크가 더 않좋을 수도 있겠구나 싶을 수 있습니다.
414 00:49:19,771 –> 00:49:29,680 하지만 Training Error가 조금 이상합니다. 다시한번 20/56 레이어를 한번 비교해보겠습니다
415 00:49:29,680 –> 00:49:40,271 여러분에게 56 레이어 네트워크가 있다면 당연히 엄청나게 많은 파라미터가 있으니 Orverfit하겠구나 를 예상하실 것입니다.
416 00:49:41,294 –> 00:49:48,985 그리고 overfit이 발생한다면 test error는 높더라도 training error는 아주 낮아야 정상일 것입니다.
417 00:49:48,985 –> 00:49:55,511 그런데 56 레이어 네트워크의 traing error을 보자하니 20 레이어보다 안좋습니다.
418 00:49:56,833 –> 00:50:01,545 따라서 더 깊은 모델임에도 test 성능이 낮은 이유가 over-fitting때문이 아니라는 것을 알 수 있습니다.
419 00:50:03,462 –> 00:50:10,253 ResNet 저자들이 내린 가설은 더 깊은 모델 학습 시 optimization에 문제가 생긴다는 것입니다.
420 00:50:10,253 –> 00:50:15,611 모델이 깊어질수록 최적화가 어렵다는 가설이죠
421 00:50:16,835 –> 00:50:23,263 그들은 “모델이 더 깊다면 적어도 더 얕은 모델만큼은 성능이 나와야 하지 않은지”라고 추론했습니다.
422 00:50:23,263 –> 00:50:32,330 가령 이런 해결책을 생각해 볼 수 있습니다. 우선 더 얕은 모델의 가중치를 깊은 모델의 일부 레이어에 복사합니다.
423 00:50:32,330 –> 00:50:35,192 그리고 나머지 레이어는 identity mapping을 하는 것이죠 (input을 output으로 그냥 내보냄)
424 00:50:35,192 –> 00:50:39,533 이렇게 구성하면 shallower layer 만큼의 성능을 나와야겠죠
425 00:50:39,533 –> 00:50:46,295 Deeper Model의 학습이 제대로 안되더라도 적어도 Shallow Model 만큼의 성능은 보장됩니다.
426 00:50:46,295 –> 00:51:00,594 그렇다면 이 motivation을 우리가 만들 모델에 녹이려면 어떻게 모델 아키첵쳐를 디자인해야할까요?
427 00:51:00,594 –> 00:51:11,794 그들의 아이디어는 레이어를 단순하게 쌓지 않는 것입니다.
428 00:51:11,794 –> 00:51:21,708 Direct mapping 대신에 Residual mapping을 하도록 이런 식으로 블럭을 쌓는 것이죠
429 00:51:21,708 –> 00:51:28,220 오른쪽 그림을 봅시다. 우선 입력은 그저 이전 레이어에서 흘러들어온 입력입니다.
430 00:51:29,818 –> 00:51:48,499 그리고 레이어가 직접 “H(x)”를 학습하기 보다 이런 식으로 “H(x) - x” 를 학습할 수 있도록 만들어줍니다.
431 00:51:49,450 –> 00:51:55,827 이를 위해서 Skip Connection을 도입하게 됩니다. 오른쪽의 고리모양 보이시죠
432 00:51:55,827 –> 00:52:07,241 오른쪽의 Skip Connection은 가중치가 없으며 입력을 identity mapping으로 그대로 출력단으로 내보냅니다.
433 00:52:07,241 –> 00:52:12,562 그러면 실제 레이어는 변화량(delta) 만 학습하면 됩니다. 입력 X에 대한 잔차(residual) 이라고 할 수 있죠
434 00:52:14,067 –> 00:52:24,502 최종 출력 값은 “input X + 변화량(Residual)” 입니다.
435 00:52:24,502 –> 00:52:31,428 이 방법을 사용하면 학습이 더 쉬워집니다. 가령 Input = output 이어야 하는 상황이라면
436 00:52:32,510 –> 00:52:39,249 레이어의 출력인 F(x)가 0 이어야 하므로(residual = 0) 모든 가중치를 0으로 만들어주면 그만입니다.
437 00:52:39,249 –> 00:52:48,578 손쉽게 출력을 Identity로 만들어 줄 수 있는 것이죠. 이 방법을 사용하면 앞서 제시한 방법을 손쉽게 구성할 수 있습니다.
438 00:52:48,578 –> 00:53:00,962 네트워크는 Residual만 학습하면 그만입니다. 출력 값도 결국엔 입력 입력 X에 가까운 값입니다.
439 00:53:00,962 –> 00:53:05,388 다만 X를 조금 수정한 값이죠. 레이어가 Full mapping을 학습하기 보다 이런 조금의 변화만 학습하는 것입니다.
440 00:53:05,388 –> 00:53:08,249 질문있나요?
441 00:53:08,249 –> 00:53:09,189 [학생이 질문]
442 00:53:09,189 –> 00:53:12,689 질문은 “레이어의 출력과 Skip Connection의 출력이 같은 차원인지” 입니다.
443 00:53:13,770 –> 00:53:17,603 그렇습니다. 두 경로의 출력 값 모두 같은 차원입니다.
444 00:53:18,752 –> 00:53:32,288 일반적으로는 같은 차원이 맞지만, 그렇지 않은 경우에는 Depth-wise padding으로 차원을 맞춰 줍니다.
445 00:53:32,288 –> 00:53:33,395 질문있나요?
446 00:53:33,395 –> 00:53:39,120 [학생이 질문]
447 00:53:45,857 –> 00:53:53,638 질문은 “레이어의 출력이 Residual 이라는 것이 뜻하는 바가 정확히 무엇인지” 입니다.
448 00:53:53,638 –> 00:54:01,899 여기 전체 출력 값인 “F(x) + X” 를 다시한번 살펴봅시다. F(x)는 레이어의 출력 값입니다.
449 00:54:01,899 –> 00:54:06,650 그리고 X는 그저 입력 값이죠.
450 00:54:06,650 –> 00:54:17,198 왼쪽의 평범한(Plain) 네트워크는 H(x)를 학습하고 있습니다. 하지만 앞서 보았듯 H(x)를 학습시키는 것은 너무 어렵습니다.
451 00:54:17,198 –> 00:54:20,671 아주 깊은 네트워크에서는 H(x)를 잘 학습시키기가 아주 어려운 것이죠.
452 00:54:20,671 –> 00:54:29,438 ResNet의 아이디어는 H(x) = F(x) + X 이니 F(x)를 학습시켜보면 어떨까? 하는 것입니다.
453 00:54:29,438 –> 00:54:39,741 H(x)를 직접 배우는 대신에 X에 얼마의 값을 더하고 빼야 할까?(Residual)를 배우는 것이 쉬울 것이라고 생각한 것이죠
454 00:54:39,741 –> 00:54:45,889 입력값을 어떻게 수정해야 하는지를 배운다고 보시면 됩니다.
455 00:54:45,889 –> 00:54:49,121 [학생이 질문]
456 00:54:49,121 –> 00:54:58,129 질문은 “F(x) 가 Residual 인지” 입니다. 맞습니다. F(x)가 Residual 입니다.
457 00:55:01,477 –> 00:55:03,941 질문있나요?
458 00:55:03,941 –> 00:55:07,441 [학생이 질문]
459 00:55:11,319 –> 00:55:20,145 질문은 “실제로 F(x)와 x를 단순히 더하는 것인지 별도의 방법이 있는지” 입니다. 그냥 더하시면 됩니다.
460 00:55:20,145 –> 00:55:28,809 F(x)는 단순히 X에 값을 얼마나 더거나 빼야 하는지를 나타내므로 단순하게 더하기만 하시면 됩니다.
461 00:55:30,652 –> 00:55:34,463 Main intuition을 어느정도 이해하셨나요?
462 00:55:34,463 –> 00:55:35,361 질문있나요?
463 00:55:35,361 –> 00:55:38,778 [학생이 질문]
464 00:55:40,721 –> 00:55:47,099 질문은 “왜 Direct mapping(H(x))을 학습하는 것 보다 Residual(F(x))을 학습하는 것이 쉬운지” 입니다.
465 00:55:47,099 –> 00:55:58,747 그것은 단지 그들이 제시한 “가설” 일 뿐입니다. Residual을 학습 시키는 것은 X에 대한 변화량(delda)을 학습시키는 것입니다.
466 00:55:58,747 –> 00:56:16,101 만약 가설이 참이라면, 내 모델의 일부는 학습된 shallow layers이고 나머지 레이어들은 Identity라면 잘 동작해야만 합니다.
467 00:56:16,101 –> 00:56:23,985 이는 대부분의 레이어가 잘 동작하려면 레이어의 출력이 Identity에 가까워야 할지 모른다는 것을 암시합니다.
468 00:56:23,985 –> 00:56:30,954 이 때문에 Identity(Input) + 변화량(delta) 만 학습시키면 됩니다.
469 00:56:30,954 –> 00:56:34,315 그리고 가령 Output = Input (identity) 이어야만 하는 상황이면
470 00:56:34,315 –> 00:56:40,363 F(x) = 0 이 되면 그만입니다. 이는 상대적으로 학습시키기 쉽다고 볼 수 있습니다.
471 00:56:40,363 –> 00:56:44,784 이런 방식으로 Identity Mapping에 가까운 값을 얻을 수 있습니다.
472 00:56:44,784 –> 00:56:50,966 하지만 그들의 직관과 가설이 입증된 바는 없습니다.
473 00:56:50,966 –> 00:56:58,708 그리고 나중에 보시겠지만, 일부 사람들은 residuals가 필요 없다고 주장하기도 합니다.
474 00:56:58,708 –> 00:57:07,507 적어도 ResNet에서 주장하고 있는 그 “가설”이 불필요하다고 말이죠 하지만 실제로는 ResNet을 쓰면 성능이 더 좋아집니다.
475 00:57:07,507 –> 00:57:08,810 질문있나요?
476 00:57:08,810 –> 00:57:12,227 [학생이 질문]
477 00:57:41,813 –> 00:57:49,128 질문은 “이전에도 ResNet처럼 레이어의 입/출력을 합치는 연구가 있었는지” 입니다.
478 00:57:49,128 –> 00:57:56,747 예 그렇습니다. 네트워크의 구성과 연결구조는 아주 활발하게 연구되고있는 분야입니다.
479 00:57:56,747 –> 00:58:04,695 아마도 나중에 다른 네트워크 아키텍쳐의 예시도 간단하게 살펴볼 예정입니다. 아주 활발히 연구되는 분야이죠
480 00:58:05,658 –> 00:58:12,093 좋습니다. 기본적으로 ResNet은 residual block들을 쌓아 올리는 구조입니다.
481 00:58:12,093 –> 00:58:14,788 여기 전체 ResNet 아키텍쳐를 보실 수 있습니다.
482 00:58:14,788 –> 00:58:27,299 하나의 Residual blocks는 두 개의 3x3 conv layers로 이루어져 있습니다. 이렇게 구성해야 잘 동작하는 것으로 알려져있습니다.
483 00:58:27,299 –> 00:58:29,828 이 Residual blocks를 아주 깊게 쌓아 올립니다.
484 00:58:29,828 –> 00:58:40,851 ResNet은 150 Layers까지 쌓아 올릴 수 있습니다.
485 00:58:46,582 –> 00:58:53,982 그리고 주기적으로 필터를 두배 씩 늘리고 stride 2를 이용하여 Downsampling을 수행합니다.
486 00:58:55,856 –> 00:59:03,867 그리고 네트워크의 초반에는 Conv Layer가 추가적으로 붙고 네트워크의 끝에는 FC-Layer가 없습니다.
487 00:59:03,867 –> 00:59:08,641 대신 Global Average Pooling Layer 를 사용합니다. GAP는 하나의 Map 전체를 Average Pooling 합니다.
488 00:59:08,641 –> 00:59:12,808 그리고 마지막에는 1000 개의 클래스분류를 위한 노드가 붙습니다.
489 00:59:14,694 –> 00:59:16,991 여기 까지가 전체 ResNet 아키텍쳐입니다.
490 00:59:16,991 –> 00:59:21,935 ResNet은 아주 심플하면서도 세련된 모델입니다. ResNet Block을 하나씩 쌓아 올리는 구조입니다.
491 00:59:21,935 –> 00:59:29,389 ResNet 모델의 Depth는 34, 50, 100 까지 늘어납니다. 논문에서는 ImageNet문제를 위해 152 까지 늘렸습니다.
492 00:59:34,230 –> 00:59:43,964 그리고 한가지 더 말씀드릴 점은 ResNet의 경우 모델 Depth가 50 이상일 때 Bottleneck Layers를 도입합니다.
493 00:59:43,964 –> 00:59:46,663 이는 GoogLeNet에서 사용한 방법과 유사합니다.
494 00:59:46,663 –> 00:59:57,195 Bottleneck Layer는 1x1 conv를 도입하여 초기 필터의 depth를 줄여줍니다.
495 00:59:57,195 –> 01:00:07,949 가령 입력이 28x28x256 일때 1x1 conv를 적용하면 depth가 줄어들어서 28x28x64 가 됩니다.
496 01:00:09,107 –> 01:00:18,486 이로인해 3 x 3 conv의 계산량이 줄어듭니다.
497 01:00:18,486 –> 01:00:29,870 그리고 뒤에 다시 1x1 conv를 추가해서 Depth를 다시 256으로 늘립니다. Deeper ResNet은 이런 구조를 취합니다.
498 01:00:33,021 –> 01:00:41,282 실제로 ResNet은 모든 Conv Layer 다음 Batch Norm 을 사용합니다. 그리고 초기화는 Xavier를 사용하는데
499 01:00:41,282 –> 01:00:50,578 추가적인 scaling factor를 추가합니다(2로 나눔). 이 방법은 SGD + Momentum에서 좋은 초기화 성능을 보입니다.
500 01:00:51,604 –> 01:00:59,470 learning rate는 learning rate 스케줄링을 통해서 validation error가 줄어들지 않는 시점에서 조금씩 줄여줍니다.
501 01:01:01,751 –> 01:01:05,874 Minibatch 사이즈는 256이고 weight dacay도 적용합니다. Dropout은 사용하지 않았습니다.
502 01:01:07,645 –> 01:01:13,581 실험결과를 보시면 그들은 성능의 열화 없이 Very deep network를 아주 잘 학습시킬 수 있었습니다.
503 01:01:13,581 –> 01:01:19,060 Backprob시 네트워크의 gradient flow를 아주 잘 가져갈 수 있었습니다.
504 01:01:19,060 –> 01:01:22,625 ImageNet 학습을 위해서 152 레이어 까지 시도해 보았으며
505 01:01:22,625 –> 01:01:26,632 Cifar-10 으로는 1200 Layer 까지 늘렸습니다.
506 01:01:26,632 –> 01:01:35,024 그리고 네트워크가 깊어질수록 Training Error는 더 줄어듦을 알 수 있었습니다.
507 01:01:36,303 –> 01:01:44,543 깊은 네트워크의 Train Error가 더 높아지는 경우는 없었습니다.
508 01:01:44,543 –> 01:01:54,843 ResNet은 ILSVRC와 COCO의 모든 대회종목을 휩쓸었습니다. 그것도 2등과의 엄청난 격차로 말이죠
509 01:01:56,152 –> 01:02:06,649 Total top-5 Error는 3.6% 였습니다. 이 수치는 ImageNet paper에서 제시한 “인간의 성능” 보다 뛰어났죠
510 01:02:08,902 –> 01:02:22,551 ImageNet Challenge의 “인간의 성능”은 우리 연구실에 있던 Andrej Kapathy가 일주일동안 공들여서 직접 수행했습니다.
511 01:02:24,730 –> 01:02:34,191 아마 5%대의 결과로 기억합니다. ResNet의 인간보다 더 잘했습니다.
512 01:02:36,175 –> 01:02:42,069 ResNet의 최근에 사람들이 아주 많이 사용하는 네트워크입니다.
513 01:02:42,069 –> 01:02:48,004 처음에 AlexNet부터 살펴보았습니다. VGGNet과 GooglLeNet은 지금도 여전히 아주 유명합니다.
514 01:02:48,004 –> 01:02:58,218 하지만 ResNet이 단연 가장 최신에 나왔고 성능이 제일 좋았습니다. 여러분이 성능좋은 네트워크를 찾는다면 ResNet은 아주 좋은 선택입니다.
515 01:03:00,154 –> 01:03:06,403 자 그럼 모델 별 complexity를 빠르게 한번 살펴보겠습니다.
516 01:03:06,403 –> 01:03:14,120 왼쪽 그래프는 모델의 성능 별로 정렬해 보았습니다 . Top-1 Accuracy가 기준이고 높을수록 좋은 모델입니다.
517 01:03:15,275 –> 01:03:21,540 거의 모두 우리가 지금까지 배운 모델이거나 조금 변형된 모델들 입니다. 가령 GoogLe-inception을 보시면
518 01:03:21,540 –> 01:03:31,389 이 모델은 버전별로 V2, V3 등이 있는데 가장 좋은 모델은 바로 여기 V4 입니다. ResNet + Inception 모델입니다.
519 01:03:31,389 –> 01:03:39,159 모델이 조금 조금씩 점점 바뀌었고 결국 가장 좋은 모델을 차지했습니다.
520 01:03:39,159 –> 01:03:45,446 자 이제는 오른쪽 그래프를 살펴봅시다. 계산 복잡성이 추가되었습니다.
521 01:03:47,686 –> 01:03:52,313 Y축은 top-1 Accuracy이고 높을수록 좋습니다.
522 01:03:52,313 –> 01:04:03,074 X축은 연산량을 나타냅니다. 오른쪽으로 갈수록 연산량이 많습니다. 원의 크기는 메모리 사용량입니다. 원이 클수록 덩치가 큰 모델이죠.
523 01:04:03,074 –> 01:04:07,251 오른쪽 아래 회색 원을 참고하시면 됩니다. 원이 점점 커질수록 메모리 사용량도 점점 커집니다.
524 01:04:07,251 –> 01:04:16,206 초록색 원이 VGGNet입니다. 가장 효율성이 작습니다. 메모리도 엄청 잡아먹고 계산량도 엄청 많죠
525 01:04:16,206 –> 01:04:18,623 하지만 어쨌든 성능은 나쁘지 않습니다.
526 01:04:19,838 –> 01:04:29,275 GoogLeNet이 가장 효율적인 네트워크입니다. x축에서 거의 왼쪽에 있죠 뿐만 아니라 메모리 사용도 적습니다.
527 01:04:29,275 –> 01:04:39,411 초기 모델인 AlexNet은 Accuracy가 낮습니다. 몸집이 작은지라 계산량도 작죠.하지만 메모리사용량은 아주 비효율적입니다.
528 01:04:41,309 –> 01:04:46,216 ResNet의 경우는 적당한 효율성을 가지고있습니다.
529 01:04:46,216 –> 01:04:52,500 메모리 사용량과 계산량을 중간정도이지만 Accuracy는 최상위입니다.
530 01:04:56,029 –> 01:04:58,028 다른 그래프를 몇가지 더 보여드리겠습니다.
531 01:04:58,028 –> 01:05:14,868 왼쪽 그래프는 forward pass 시간입니다. 단위는 ms 인데 VGG가 제일 오래걸립니다. 200ms으로 초당 5정도 처리할 수 있겠군요
532 01:05:14,868 –> 01:05:25,883 오른쪽은 전력소모량인데 더 자세한 내용은 아래 논문을 참고하시기 바랍니다. 더 다양한 분석 결과를 보실 수 있습니다.
533 01:05:30,604 –> 01:05:38,750 지금까지 보신 아키텍쳐이 아주 중요합니다. 반드시 깊게 잘 알아야 하고 익숙해져야 합니다.
534 01:05:38,750 –> 01:05:48,263 이제는 아키텍쳐 몇 가지를 더 소개시켜 드리겠습니다. 역사적으로 의미가 있거나, 최신 연구분야에 속하는 것들입니다.
535 01:05:50,716 –> 01:05:56,342 자 우선 Network in Network 입니다. 2014년에 나온 논문입니다.
536 01:06:00,529 –> 01:06:16,118 Network in Network의 기본 아이디어는 MLP conv layer 입니다. 네트워크 안에 작은 네트워크를 삽입하는 것이죠
537 01:06:16,118 –> 01:06:23,152 각 Conv layer 안에 MLP(Multi-Layer Perceptron) 를 쌓습니다. FC-Layer 몇 개를 쌓는 것이죠
538 01:06:23,152 –> 01:06:29,167 맨 처음에는 기존의 Conv Layer가 있고 FC-Layer를 통해 abstract features를 잘 뽑을수 있도록 합니다.
539 01:06:29,167 –> 01:06:41,975 단순히 conv filter만 사용하지 말고, 조금 더 복잡한 계층을 만들어서 activation map을 얻어보자는 아이디어입니다.
540 01:06:41,975 –> 01:06:47,941 NIN에서는 기본적으로는 FC-Layer를 사용합니다. 이를 1x1 conv layer 라고도 합니다.
541 01:06:47,941 –> 01:06:57,196 아래의 다이어그램이 바로 Network in Network 구조입니다.
542 01:06:57,196 –> 01:07:10,102 Network in Network는 GoogLeNet과 ResNet보다 먼저 Bottleneck 개념을 정립했기 때문에 아주 의미있는 아이디어입니다.
543 01:07:10,102 –> 01:07:22,070 또한 GoogLeNet은 NIN와 구조는 조금 다르지만 NIN의 “철학적인 영감” 을 받았습니다.
544 01:07:24,238 –> 01:07:36,759 자 다음은 ResNet과 관련된 일련의 연구들을 소개해 드리겠습니다. ResNet의 성능을 향상시킨 최근의 연구들입니다.
545 01:07:36,759 –> 01:07:39,911 이 쪽이 워낙 빠르게 변하고 있어서 저도 깊게 아는 내용은 아닙니다.
546 01:07:39,911 –> 01:07:44,754 자세한 내용은 여러분이 직접 논문을 찾아보시기 바랍니다.
547 01:07:45,755 –> 01:07:55,719 2016년 ResNet의 저자들은 ResNet의 블록 디자인을 향상시킨 논문을 발표했습니다.
548 01:07:56,742 –> 01:08:03,015 이 논문에서는 ResNet block path를 조절하였습니다.
549 01:08:03,015 –> 01:08:18,861 새로운 구조는 direct path를 늘려서 정보들이 앞으로 더욱 더 잘 전달되고 Backprob도 더 잘 될 수 있게 개선했습니다.
550 01:08:18,861 –> 01:08:25,319 이 새로운 Block 구조 덕분에 더 좋은 성능을 얻을 수 있었습니다.
551 01:08:25,319 –> 01:08:28,959 Wide Residual Network 라는 논문도 있습니다.
552 01:08:28,959 –> 01:08:40,228 그들이 기존의 ResNet 논문은 깊게 쌓는 것에 열중했지만 사실 중요한 것은 depth가 아닌 residual 이라고 주장했습니다.
553 01:08:40,228 –> 01:08:45,290 Residual Connection이 있다면 네트워크가 굳이 더 깊어질 필요가 없다고 주장했습니다.
554 01:08:45,290 –> 01:08:52,794 그래서 그들은 residual block 을 더 넓게 만들었습니다. 즉 conv layer의 필터를 더 많이 추가했습니다.
555 01:08:52,794 –> 01:09:02,661 가령 기존의 ResNet에는 Block 당 F개의 filter만 있었다면 대신에 F * K 개의 필터로 구성했습니다.
556 01:09:02,663 –> 01:09:11,502 각 레이어를 넓게 구성했더니 50 레이어만 있어도 152 레이어의 기존 ResNet보다 성능이 좋다는 것을 입증했습니다.
557 01:09:13,754 –> 01:09:23,035 그리고 네트워크의 Depth 대신에 filter의 Width를 늘리면 추가적인 이점이 있는데, 계산 효율이 증가합니다.
558 01:09:23,035 –> 01:09:26,922 왜냐하면 병렬화가 더 잘되기 때문입니다.
559 01:09:26,923 –> 01:09:39,546 네트워크의 Depth를 늘리는 것은 sequential한 증가이기 때문에 conv의 필터를 늘리는(width) 편이 더 효율적입니다.
560 01:09:39,546 –> 01:09:49,817 이들은 네트워크의 width/depth/residual connection 를 고찰하는 뜻깊은 연구를 하였습니다.
561 01:09:49,817 –> 01:09:58,125 그리고 비슷한 시점에 등장한 또 하나의 논문이 있습니다. 바로 ResNeXt 입니다.
562 01:09:58,125 –> 01:10:04,383 이 논문 또한 ResNet의 저자의 논문입니다. 계속해서 ResNet 구조를 밀고 있는 것이죠
563 01:10:04,383 –> 01:10:18,576 여기에서도 계속 residual block의 width를 파고듭니다. filter의 수를 늘리는 것이죠
564 01:10:18,576 –> 01:10:26,415 각 Residual block 내에 “다중 병렬 경로” 추가합니다. 이들은 pathways의 총 합을 cardinality라고 불렀습니다.
565 01:10:26,415 –> 01:10:36,317 하나의 bottleneck ResNet block은 비교적 작지만 이런 thinner blocks을 병렬로 여러개 묶었습니다.
566 01:10:38,395 –> 01:10:44,452 여기에서 ResNeXt과 Wide ResNet과의 연관성을 볼 수 있습니다.
567 01:10:44,452 –> 01:10:54,023 또한 여러 Layers를 병렬로 묶어준다는 점에서 Inception Module과도 연관있습니다.
568 01:10:54,023 –> 01:10:58,190 ResNeXt 라는 이름 자체가 이를 내포하고 있습니다. (ResNet + inEXeption)
569 01:11:00,838 –> 01:11:13,878 ResNet의 성능을 개선하고자 하는 방법은 계속됩니다. Stochastic Depth 이라는 논문이 있습니다. 주제는 Depth 이죠
570 01:11:13,878 –> 01:11:21,537 네트워크가 깊어지면 깊어질수록 Vanishing gradient 문제가 발생합니다.
571 01:11:21,537 –> 01:11:32,071 깊은 네트워크에서는 그레디언트를 뒤로 전달할수록 점점 그레디언트가 작아지는 문제가 있습니다.
572 01:11:32,071 –> 01:11:43,045 기본 아이디어는 Train time에 레이어의 일부를 제거합니다. short network면 트레이닝이 더 잘 될 수 있기 때문입니다.
573 01:11:43,045 –> 01:11:48,436 일부 네트워크를 골라서 identity connection으로 만들어버립니다.
574 01:11:48,436 –> 01:11:56,126 이렇게 shorter network를 만들어서 Train하면 그레디언트가 더 잘 전달될 수 있겠죠
575 01:11:56,126 –> 01:12:04,074 아주 효율적인 방법이 될 수 있습니다. Dropout과 유사합니다. Dropout은 앞선 강의에서 다룬 적 있었죠
576 01:12:04,074 –> 01:12:08,108 그리고 Test time에서는 full deep network를 사용합니다.
577 01:12:10,446 –> 01:12:19,038 지금까지 소개시켜 드린 방법들은 ResNet 아키텍쳐를 개선하고자 노력했습니다.
578 01:12:19,038 –> 01:12:32,253 “Beyond ResNet”을 지향하는 방법들도 있습니다. Non-ResNets 중에도 ResNet과 견줄만한 성능의 모델들이 있습니다.
579 01:12:32,253 –> 01:12:45,273 그 중 하나는 FractalNet 입니다. 아주 최근에 나왔습니다. 그들은 residual connection이 쓸모없다고 주장합니다.
580 01:12:45,273 –> 01:12:52,645 지금까지는 ResNet의 Motivation이 어느정도 납득할만 하다고 생각했지만, FractalNet은 그렇게 생각하지 않습니다.
581 01:12:52,645 –> 01:12:58,407 FractalNet 아키텍쳐에서는 residual connection이 전혀 없습니다.
582 01:12:58,407 –> 01:13:03,898 그들은 shallow/deep network의 정보 모두를 잘 전달하는 것이 중요하다고 생각했습니다.
583 01:13:03,898 –> 01:13:13,258 그래서 FractalNet은는 오른쪽 그림에서 보시는 바와 같이 fractal한 모습입니다.
584 01:13:14,769 –> 01:13:18,639 FractalNet에서는 shllow/deep 경로를 출력에 모두 연결합니다.
585 01:13:20,045 –> 01:13:29,568 FractalNet에는 다양한 경로가 존재하지만 Train time에는 Dropout처럼 일부 경로만을 이용해서 Train 합니다.
586 01:13:29,568 –> 01:13:37,203 그리고 Test time에는 full network를 사용합니다. 그들은 FractalNet의 좋은 성능을 입증했습니다.
587 01:13:39,047 –> 01:13:44,886 DenseNet 이라는 아키텍쳐도 있습니다. (DENSEly Connected Convolutional NETworks)
588 01:13:44,886 –> 01:13:48,567 DenseNet에는 Dense Block 이란 것이 있습니다.
589 01:13:48,567 –> 01:13:55,940 여기 보시면 한 레이어가 그 레이어 하위의 모든 레이어와 연결되어 있습니다.
590 01:13:55,940 –> 01:14:00,362 Network의 입력이미지가 모든 Layer의 입력으로 들어갑니다.
591 01:14:00,362 –> 01:14:08,779 그리고 모든 레이어의 출력이 각 레이어의 출력과 Concat 됩니다.
592 01:14:08,779 –> 01:14:18,643 그리고 이 값이 각 Conv layer의 입력으로 들어갑니다. 이 과정에서 dimention을 줄여주는 과정이 포함됩니다.
593 01:14:18,643 –> 01:14:30,863 그리고 이들은 Dense Connection이 Vanishing gradient 문제를 완화시킬 수 있다고 주장합니다.
594 01:14:30,863 –> 01:14:37,324 그리고 Dense connection은 Feature를 더 잘 전달하고 더 잘 사용할 수 있게 해줍니다.
595 01:14:37,324 –> 01:14:45,487 각 레이어의 출력이 다른 레이어에서도 여러번 사용될 수 있기 때문입니다.
596 01:14:47,906 –> 01:15:03,006 ResNet 스럽지 않지만 ResNets만큼 성능이 좋은 다양한 아키텍쳐들을 살펴보고 있습니다. 아주 활발하게 연구되고 있는 분야입니다.
597 01:15:03,006 –> 01:15:11,830 그런 네트워크들은 대게는, 레이어 간의 연결을 어떻게 구성할지, 그리고 depth를 어떻게 구성할지에 관한 연구가 많습니다.
598 01:15:13,528 –> 01:15:17,991 그리고 마지막으로 말씀드릴 네트워크는 “효율성” 게 치중한 네트워크입니다.
599 01:15:17,991 –> 01:15:33,994 GoogLeNet은 효율적인 모델에 대한 방향을 제시했습니다. practical usage 를 위해서는 아주 중요한 주제입니다.
600 01:15:33,994 –> 01:15:37,927 효율성을 강조하는 또 하나의 모델이 있습니다. 바로 SqueezeNet 입니다.
601 01:15:37,927 –> 01:15:41,618 아주 효율적인 네트워크입니다. 그들은 fire modules 이라는 것을 도입했습니다. fire modules 의-
602 01:15:41,618 –> 01:15:49,645 “squeeze layer”는 1x1 필터들로 구성되고, 이 출력 값이 1x1/3x3 필터들로 구성되는 “expand layer”의 입력이 됩니다.
603 01:15:49,645 –> 01:15:59,220 SqueezeNet는 ImageNet에서 AlexNet 만큼의 Accuracy를 보이지만 파라미터는 50배 더 적었습니다.
604 01:15:59,220 –> 01:16:06,093 그리고 SqueezeNet을 더 압축하면 AlexNet보다 500배 더 작아지게 됩니다.
605 01:16:06,093 –> 01:16:10,095 SqueezeNet의 용량은 0.5Mb 밖에 안되죠
606 01:16:10,095 –> 01:16:20,062 Model Compression과 관련해서는 나중에 더 다루도록 하겠습니다.
607 01:16:21,856 –> 01:16:26,809 오늘 배운 내용을 요약해보겠습니다. 오늘은 다양한 종류의 CNN 아키텍쳐를 배웠습니다.
608 01:16:26,809 –> 01:16:31,555 4가지 주요 아키텍쳐를 배웠습니다. 여러분들이 아주 많이 사용하게 될 모델들이죠
609 01:16:31,555 –> 01:16:35,553 AlexNet는 초창기에 아주 유명했던 네트워크입니다.
610 01:16:35,553 –> 01:16:38,832 VGG과 GoogleNet은 지금도 여전히 널리 사용됩니다.
611 01:16:38,832 –> 01:16:45,906 아마 ResNet 을 가장 많이 사용할 지 모르겠네요
612 01:16:45,906 –> 01:16:50,587 그리고 그 밖에 다른 네트워크들도 살펴보았습니다.
613 01:16:51,921 –> 01:16:58,228 Model zoo가 있으니 필요할 때 마다 언제든지 이런 모델들을 가져다 쓸 수 있습니다.
614 01:16:58,228 –> 01:17:06,827 그리고 네트워크가 점점 깊어지는 트렌드가 있긴 하나 어떻게 레이어를 디자인할지가 가장 큰 관심사였습니다.
615 01:17:06,827 –> 01:17:15,419 skip connections 등 말이죠. 그리고 Backprob이 잘 되도록 디자인하는 것도 중요했습니다.
616 01:17:15,419 –> 01:17:22,748 그리고 Depth vs Width, residual connection 등 다양한 이슈를 다뤄보았습니다.
617 01:17:22,748 –> 01:17:31,380 서로 어떤 Trade off가 존재하는지는 지금도 아주 활발하게 연구되는 분야입니다. 여러분도 계속 지켜보시기 바랍니다.
618 01:17:31,380 –> 01:17:33,597 다음 시간에는 Recurrent Neural Networks 에 대해서 배워보도록 하겠습니다.