CNN Case Study(LeNet-5, AlexNet, ZFNet, VGGNet, GoogLeNet)

2020-05-03

.

Deep_Learning_TIL(20190720)

study program : https://www.fastcampus.co.kr/data_camp_deeplearning

[학습노트]

  • CNN의 아버지 ‘LeNet-5’

image

CNN이 등장한 것은 오래되었지만 쓸만한 모델로서 등장한 때가 1998년에 ‘LeNet-5’다.

아래 그림과 같이 fully connected layer가 3개가 있는 형태이고, 레이어가 5개로 된 모델이다.(풀링레이어는 레이어로 치지 않는다.)

단점은 일단 연산량이 너무 많고, 그 당시 컴퓨팅 파워도 별로 좋지 않았다. 학습하는데도 시간이 많이 걸렸다. 물론 성능도 별로 안좋았다.

  • Image classification 대회의 등장

image

Image classification 대회가 2010년부터 시작이 되었다. ImageNet이라는 라지스케일 데이터셋을 구축해놓고, 1500만개 이상의 high-resolution 이미지들이 있었다. 클래스는 2만2천개정도 였다. 대회를 할때는 데이터가 너무 크기 때문에 1000개의 클래스를 뽑고, 1000개에 대해서 1.2milion개 트레이닝 데이터를 제공하고 대회를 했다. 이게 classification 대회만 한 것이 아니고, ImageNet Large-Scale Visual Recognition Challenge(ILSVRC)라는 이름으로 세가지 competition 파트가 있었다. 하나는 이미지 분류, 다른 하나는 이미지 localization, 다른 하나는 object detection가 있었다. classification과 localization은 같은 데이터 셋으로 진행하고 순위를 분류한번 로컬라이제이션 한번 따로따로 매겨서 발표했다.

로컬라이제이션은 정답클래스의 이미지가 어디에 있는지 박스를 치는 것을 말한다. object detection도 똑같이 어떤 이미지 안에 사물에 대해서 박스를 치는 것이다. 로컬라이제이션과 디텍션의 차이는 로컬라이제이션은 클래스 하나에 대해서만 수행을 하는 것이고, 디텍션은 그 안에 클래스가 여러개가 있는 것이다. 개도 있고 고양이도 있고 사람도 있고 이것들을 모두 탐지해서 따로따로 박스를 치고, 따로따로 분류도 잘 해줘야 한다. 로컬라이제이션은 이미지에 여러 물체가 있을수 있지만, 일단 가장 핵심적인 클래스의 물체가 하나만 있다라고 생각하고 걔가 어디에 있는지만 박스를 치는 것이다.

classification은 top-1 애러와 top-5 애러 두가지를 레포트 한다고 되어있는데 실제 순위를 매길때는 top-5 애러율 또는 top-5 accuracy로 순위를 매긴다. top-5 애러가 뭐냐면 정답을 다섯개를 내는 것이다. 클래스가 1000개인 경우 1000지선다형 문제를 푸는것인데 그중에 답을 5개를 내서 그 5개중에 답이 있으면 정답이라고 하고 다섯개중에 답이 없으면 틀리다고 하는 것이다. top-1 애러는 답을 하나만 내서 그게 맞으면 정답, 아니면 오답으로 처리하는 방식이다.

위에 그림이 2010년 ~ 2017년까지 대회결과인데 2012년에 처음 이 대회에서 CNN이 사용되었다. 2012년에 알렉스넷이 등장하면서 2013년부터 CNN을 안쓰는 팀이 거의 없었다. 그 이후로 2017년 대회가 없어질때까지 CNN이 대회를 휩쓸었다. 컴퓨터비전 딥러닝 붐이 일어났던 것이 이 대회덕이라고 말하는 것이 과언이 아닐정도였다.

  • AlexNet

image

모델 첫번째 레이어에서 스트라이드 4로 주고 11x11 필터로 컨볼루션 연산을 한다는 것이다. 첫번째 레이어의 입력값은 224x224라고 되어 있지만 이거는 잘못된 것이고, 아래 그림상 227x227이 맞는 것이다. 참고로 224x224가 매직넘버처럼 이 이후의 이미지넷의 네트워크들은 대부분 224x224를 쓰게 된다.

아무튼 11x11x3짜리 컨볼루션 필터를 96개(48개, 48개)를 쓴 것이다. 그래서 output feature map이 96인데 반을 짤라서 한쪽에 48, 다른한쪽에 48을 두었다. 왜 이렇게 했냐면 이 당시 GPU성능이 안좋아서 어쩔 수 없이 GPU를 2개로 나누어서 학습을 시키고자 하는 의도였다.

재미있는 사실은 추후에 GPU성능이 좋아지면서 GPU 하나로 돌려봤는데 두개로 돌렸던 것보다 성능이 떨어졌다는 것이다. 그래서 나중에는 이런식으로 두개로 쪼개는 것이 하나의 테크닉이 되었다. 이런 방식을 Group convolution이라고 한다. 원래 컨볼루션 할때는 채널을 전체 채널을 다 봐야하는데 전체를 다 안보고 몇개의 그룹으로 나누어서 일부만 가지고 연산을 하는 것이다.

그 다음에는 풀링이 있고, 5x5x128 컨볼루션 필터를 썼고, 마지막에 fully connected layer를 4096, 4096, 1000개(클래스가 1000개니까)를 배치했다. 중간중간에는 맥스풀링이 들어가 있는 형태다.

이 네트워크는 또한 렐루를 처음 사용했다. 또한 중간에 노멀라이즈(배치노멀라이제이션과 비슷한 기능)하는 레이어를 썼는데 이 방법은 요즘에는 아예 쓰이지 않는다. 또한 데이터 augmentation과 드랍아웃도 썼다.

7개 CNN 모델을 앙상블한 것보다 성능이 3%정도 더 잘나왔다. 이렇게 학습할때 디테일한 정보를 대부분의 CNN논문에서 제공을 하는데 그래야지 똑같이 재현을 할 수 있기 때문이다.

파라미터 사이즈는 11x11x3이 필터한개의 사이즈이고, 96개를 썼으니까 96을 추가로 곱해줬다. 따라서 첫번째 레이어 하나에만 35000개의 파라미터가 있다.

Conv1 Conv2 이런식으로 숫자가 올라가는 것이 보이는데 이는 레이어가 증가할때마다 숫자를 증가시켜주는 식으로 표기해준다.

컨볼루션 레이어 5개, fully connected layer 3개로 구성된 네트워크이다. 파라미터가 6000만개가 있는 네트워크다.

image

위에 그림에서 위에 있는 4개가 top-1, top-5에서 다 맞춘것이고, 밑에서는 top-1에서는 다 틀린거고, top-5는 맞춘것이다. 우측하단에 채리와 마다가스카캣은 전부 틀린것이다.

  • ZFNet

image

2013년에는 ZFNet이라는 네트워크가 1등을 했다. 네트워크 구조 자체는 알렉스넷과 똑같지만 알렉스넷을 조금 더 좋게 튜닝을 했다는 것이다. 무슨말이냐면 네트워크 구조를 컨볼루션 필터사이즈를 조금 조절하고, 필터의 갯수도 조절했다.

ZFNet의 논문을 보면 CNN으로 대표되는 알렉스 넷의 내부구조에서 도대체 무슨일이 일어났길래 성능이 잘나왔는지 시각화하는데 많은 노력을 했다. 모델자체의 성능을 발전시키기 위한 노력보다는.

  • VGGNet

image

2014년에는 VGGNet이라는 네트워크가 image classification에서는 2등을하고, localization에서는 1등을 했다.

알렉스넷에서는 11x11을 처음에 썼고, ZFNet은 7x7을 쓰고 그 다음에 5x5, 3x3 다양하게 쓰였다. 뒤에 구글넷이라는 것도 5x5도 쓰고 3x3도 쓰고 1x1도 썼다. 이당시만 해도 컨볼루션 필터사이즈를 어떻게 조절을 하면 좋을지에 대해서 사람들이 감이 없었고, 기준도 없었다.

VGGNet를 만든 사람들은 상당히 단순한 구조의 네트워크를 들고와서 단순한 구조도 상당히 성능을 잘 낼 수 있다는 것을 보여줬다. 3x3 컨볼루션에 스트라이드 1, 그리고 패딩을 해주는 딱 이 컨볼루션 필터만 계속 쌓는 구조다. 그리고 풀링도 2x2에 스트라이드 2로하는 풀링 딱 이거 하나만 쓴다. 이것들만 잘 쌓아올려도 성능이 잘 나온다라는 것을 보여줬다. 컨볼루션 필터사이즈 고민하지말고 3x3만 써도 된다는 것을 보여줬다. 유명한게 VGG16과 VGG19인데 VGG 뒤에 붙은 숫자는 레이어 수를 의미한다. 3x3 컨볼루션에 64라는 것은 컨볼루션 필터를 64개를 썼다는 것이다. 즉 output feature map의 채널수를 의미한다.

풀링을 한번할때마다 채널수를 두배로 늘려준것이 또 특징이다. 이 특징은 최근 나오는 거의 모든네트워크에서도 그대로 쓰는 특징이다.

3x3 필터만 써도 성능이 잘나오는 이유는 이 모델을 만든 사람들은 3x3 필터를 두개 레이어에 쓰면 5x5 컨볼루션 필터 1개를 쓴거와 같은 효과가 있다는 것이다. 똑같은 효과라는 것은 receptive field라고 한다.

위에 그림과 같이 파란색박스 점 하나에 도달하기 위해 계산하기 위해서 입력에 얼마만큼의 영역이 필요한지. 이게 실제로 사람의 시신경에 receptive field라는 개념이 있다. 시신경에 있는 뉴런들이 실제로 이런식으로 동작을 한다.

그래서 5x5 컨볼루션 필터 한개쓴거랑 receptive field가 동일하지만 수학적으로 다른 과정을 거친것이다. 그러나 파라미터수는 receptive field가 더 적다. 아래 그림을 예로들자면 첫번째 레이어에서 3x3xC 만큼의 컨볼루션 필터가 있을것이고, 이게 두번 있으니까 2x3x3xc가 될 것이다. 반면에 5x5 컨볼루션 필터는 5x5xc가 될것이다. 컨볼루션 필터 하나씩만 썼을때 파라미터수를 비교해보면 당연히 2x3x3xc가 적을 것이다. 오버피팅에 더 유리할 수 밖에 없다.

모델사이즈는 내가 갖고 있는 문제를 풀수 있으면서 가장 단순한 사이즈의 네트워크가 제네럴라이즈 성능이 잘 나온다.

또하나의 장점은 레이어를 두개 쌓기 때문에 중간에 렐루 같은것도 쓸 수 있다는 것이다. 활성화 함수(non linear function)가 여러번 쓰일 수록 표현력이 좋아진다.

3x3 필터를 두번쌓으면 5x5 , 세개쌓으면 7x7, 4개 쌓으면 9x9의 receptive field가 생기기 때문에 3x3만 잘쌓아도 되더라 라는 것이다.

위에 중간에 표를 보면 알 수 있듯이 6가지 형태의 VGGNet의 구조가 있다. 한때 VGGNet은 단순하지만 성능이 잘 나왔기 때문에 대중적으로 많이 쓰였다.

그러나 VGGNet은 치명적인 단점이 있다. 네트워크가 너무 크다. 위에 가장 아래 그림을 보면 빨간색이 메모리 사용량, 파란색이 파라미터 수인데 메모리 사용량은 피쳐맵을 저장하기 위한 메모리 사용량만을 나타낸것이다. 웨이트 파라미터도 메모리에 저장을 해야하는데 그건 뺀것이다. 이미지 한장을 트레이닝도 아니고 인퍼런스만 처리하기 위해서 600메가 이상의 공간이 필요하다. 그러면 트레이닝한다 그러면 인퍼런스의 두배의 메모리가 필요하다. 그러면 내 GPU의 메모리가 3기가다 그러면 배치를 2정도 밖에 못돌릴것이다.

이 이후 사람들은 네트워크가 작으면서도 성능이 잘나오는 네트워크를 찾게된다.

  • GoogLeNet

image

구글넷은 22개의 레이어로 이루어져 있다. (VGG는 보통 16 아니면 19) inception module이라는게 있다. 인셉션은 영화 인셉션의 아이디어를 가져온 것이라고 한다. 네트워크 안에 네트워크가 있는 것이라고 생각하면 된다. (network in network).

사실 network in network라는 논문이 따로 있다. 구글넷 나오기 전에 있는 개념이었고 성능도 잘 나오는 편이었다. 구글넷은 이 논문에서 모티베이션을 많이 받았다고 한다. 이 모델의 특징은 global average polling이라는 것을 썼다. 이 이후에 나오는 모든 네트워크에서 global average polling을 거의 다 쓴다고 보면 된다.

그리고 파타미터 수가 5milion(500만개) 밖에 안된다. (반면에 vgg는 138milion, 알렉스넷은 60milion) 그래서 2014년에 1등을 한 모델이다.

인셉션 모듈은 위에 그림과 같이 사용자가 컨볼루션 필터를 어떤것을 쓸지 모를때 1x1, 3x3, 5x5, 심지어 맥스풀링도 쓴다. 그래서 각각 연산을 한다음에 그 결과를 합칠때는 채널방향으로 합친다. 예를 들어서 점수표가 10장, 10장, 10장, 10장이 나오면 합쳐서 40장을 만드는 것이다. 근데 이렇게하면 한번 지나갈때마다 너무 채널수가 많아진다. 예를 들어서 input feature map이 100이었는데 인셉션 모듈에서도 필터를 100개씩 썼다고 하면 400이 될 것이다.

image

그래서 나온게 위에 그림과 같이 1x1 컨볼루션을 이용해서 바틀넥 레이어라는 것을 만들어주게 된다. 컨볼루션 필터를 개수를 조절하면 아웃풋으로 나가는 채널수를 조절할 수 있기 때문에 그 기법을 쓴것이다. 입력이 가로세로 56x56이고 채널이 64가 들어왔을때 1x1 컨볼루션을 해서 필터를 32개를 쓰면 output(채널)이 32개로 줄어들 것이다. 그래서 이렇게 줄여놓고 그 다음에 뭔가 연산을 하는 식으로 작동한다. 이걸 바틀넷 레이어라고 하고 의미적으로는 1x1을 썼다는 것은 가로세로는 한점만보고 채널방향으로만 전체 다보겠다는 것이다. 그래서 채널간에 상관관계를 계산해서 강아지 코에 대한 점수와 눈에 대한 점수를 합쳐서 그냥 하나의 점수표로 만드는 것이라고 이해하면 된다. 조금 더 압축을 하겠다는 개념이다.

image

위에 그림과 같이 빨간색 박스부분과 같이 그런 바틀넷 레이어 아키텍처가 들어간 것이다. 3x3 컨볼루션을 하기전에 채널을 줄여놓고 하겠다는 것이다. 이렇게 하면 채널수가 커지는 것을 막을 수 있다.

image

그래서 위와 같은 인셉션 모듈이 구글넷에 9개가 들어가있다. 앞부분에 stem network가 있다.

참고로 어떤 네트워크던지 각자 자기만의 특이한 네트워크 구조가 있는데 이런 특이한 네트워크 구조들은 첫번째 레이어에는 적용하지 않는다.

구글넷도 마찬가지다. 앞쪽의 몇개 레이어는 다른네트워크 하나~두개정도 노멀한 연산을하고 뭔가를 적용하는 경우가 대부분이다. 그래서 앞쪽에는 스탬네트워크라고 부른다.

그 다음에 인셉션 모듈이 9번 스텍이 되어있고, 마지막에 classification하는 아웃풋이 있다. 그리고 또 하나의 특징은 중간에 가지가 있어서 auxilary classification을 할 수 있다. 이게 왜 있냐면 네트워크가 너무 깊게 쌓이면 렐루를 써도 베니싱 그레디언트가 생긴다. 왜냐하면 인풋도 상당히 작은값이고, 가중치도 상당히 작은값이기 때문에 애러가 백프로퍼게이션되면 딥한구조에서는 베니싱 그레디언트가 생길수 밖에 없다. 그래서 그거를 방지하기 위해서 중간에 브랜치를 땄다. 그 중간에 가지가 있는 곳까지 네트워크가 있다고 가정하고 classification branch를 만들어서 그 부분마다 로스를 계산하고 백프로퍼게이션을 그 브랜치 갯수만큼 해주게 된다. 그래서 이 브랜치는 트레이닝할때 쓰고 트레이닝이 끝나면 짤라버린다. 그레디언트의 원활한 흐름을 위해서 붙여놓은것이라고 생각하면 된다.

그리고 그림 중간에 보라색으로 글로벌 에버리지 풀링이라는게 있는데 이거는 말그대로 애버리지 풀링을 하는것이다. 근데 글로벌이라는 말이 붙었다는 것은 input feature map 전체에 대해서 에버리지 풀링을 하겠다는 것이다.

image

위에 그림은 각 레이어가 쭉 있고 output size가 나와있다. 그래서 그 레이어를 통과하고나면 피쳐맵이 가로세로와 채널이 어떻게 되는지 표시를 한 것이다. 예를들어서 위에 표에서 inception(5b)라는 것을 통과하고 나면 7x7x1024라는 피쳐맵 사이즈가 나오게 된다. 그런 다음에 글로벌 에버리지 풀링을 한다는 것은 풀링하는 필터안에 숫자를 그냥 다 더해서 평균을 내는(풀링은 채널별로 따로함) 에버리지 풀링과 같이 가로세로가 7x7이면 7x7 애러비리 풀링을 하는 것이다.

inception(5b) 밑에 avg pool을 보면 애버리지 풀링을 하는데 7x7풀링을 하고 스트라이드 1로 하라는 것이다. 만약에 100x100이었는데 글로벌 에버리지 풀링을 한다 그러면 풀링을 100x100을 하면 된다. 그러면 결과는 1x1에 채널이 그대로 살아있는 1x1x1024가 될 것이다.

그리고 fully connected layer 부분에 파라미터가 많은것이 이전 네트워크들에서는 문제였는데 글로벌 에버리지 풀링을 통해 파라미터 수를 줄일 수 있다. 애버리지 풀링은 파라미터가 0이다. 그러면 이런식으로 해도 문제가 없을까라는 얘기가 나올 수 밖에 없는데 결과적으로 해보니까 잘되었다는 것이다. 그래서 fully connected layer가 파라미터 수에 비해서 리던던트하게 영향력이 별로 없었다는 것이다.

그래서 글로벌 에버리지 풀링을 이용해서 파라미터수를 획기적으로 줄일 수 있었다는 것이 중요한 특징이다.

위에 표에서 인풋사이즈는 안나와 있지만 최초에 224x224이다. 최초 레이어는 스트라이드를 2로 줬기 때문에 사이즈가 절반으로 줄어드는 것을 알 수 있다.(112x112x64). 다음 레이어부터는 최초 레이어에 max pool이라는 두번째 레이어의 입력으로 들어가게 된다.

참고로 depth는 레이어 갯수를 말한다. 그래서 두번째 convolution에서 아웃풋이 56x56x192인데 이는 컨볼루션 필터를 192개를 썼다는 것이다. 그런데 레이어 2개짜리 인것을 알 수 있다. 연산이 하나인데 레이어가 두개짜리냐 라고 물어볼 수 있는데 연산이 하나만 써있는데 댑스가 2라는 것은 거기에 바틀넥 레이어가 들어가 있다는 뜻이다. 그래서 옆에보니까 3x3 reduce라고 써있는데 그게 바로 바틀넥 레이어다. 이 reduce라고 쓰여져 있는 칸이 3x3 컨볼루션, 5x5 컨볼루션 이게 아니다라는 것이다. 이름은 이렇게 되어있어도 1x1 컨볼루션(바틀넥 레이어)이다. 그래서 채널을 줄이지 않고 1x1으로 컨볼루션 하고, 그 다음에 3x3 192 2개를 써서 채널을 192로 했다는 것이다. 그다음에 풀링 한번 하면 28x28로 줄어든다. 인셉션이라고 쓰여져 있는 것은 인셉션 구조라고 이해하면 된다.

위에 인셉션 모듈 그림을 보면 알 수 있듯이 1x1, 3x3, 5x5, 그 다음에 3x3 맥스풀링 여기는 스트라이드 1짜리 풀링이다. 그래야 가로세로 사이즈가 같고 뒤에서 concatenate를 할 수 있다. 그 다음에 3x3하기전에 5x5하기전에 1x1 컨볼루션이 있다.

그래서 보면 인셉션하는 얘는 레이어가 2개짜리라는 것을 알 수 있다. 인셉션 브랜치를 딴거에서 레이어 갯수는 가장 레이어가 많은 것으로 친다. 1x1은 하나였고, 풀링쪽도 풀링은 레이어로 안치니까 한개였고, 나머지는 두개씩 있었다. 그래서 얘는 레이어 두개짜리다.

그래서 첫번째 브랜치 1x1 컨볼루션만 하는 곳에서는 필터를 64개를 썼다라는 것을 알 수 있다. inception(3a)부분을 보면 그 다음에 3x3 컨볼루션을 할때 3x3 컨볼루션을 하기전에 1x1 컨볼루션 (바틀넥)을 쓴다. 입력채널이 192개였는데 1x1 컨볼루션(바틀넥)을 64개를 썼기 때문에 64개로 채널이 줄었다가 그 다음에 192가 3x3 reduce에서 96으로 줄어들게 된다. 그 다음에 3x3 컨볼루션을 통해서 128이 된다. 그 다음에 192를 받아서 5x5 reduce에서 1x1 컨볼루션(버틀넥)을 해서 필터를 16개를 썼기 때문에 16까지 채널이 줄게 된다. 그 다음에 32 그 다음에 그대로 192로 갈 것이고 풀링해도 192가 유지될 것이다. 그 다음에 1x1 컨볼루션이 pool projection이라고 본 것이 32다. 그래서 192에서 32로 줄어들게 된다. 그래서 32(pool proj)+32(#5x5)+64(#1x1)+128(#3x3) = 256 채널이 된다. inception(3a) 말고 다른레이어도 마찬가지 방식으로 동작한다.

그래서 결론적으로 쭉 전부 파라미터를 더하면 600만개 정도 나온다. 알렉스넷보다 12분의 1수준으로 적어진다.

image

인셉션 모듈은 버전이 올라가면서 그해에 나온 좋은 특징을 흡수했다. 인셉션 모듈 v2, v3 이후에는 위에 그림과 같이 형태로 변화하게 된다. receptive field개념이 반영되고 3x3필터도 반드시 정사각형 필터만 쓰라는 법이 없으니 1x3과 3x1로 나누었다. 이렇게 다양한 구조들이 반영되기 시작한다.