본문 바로가기

대학원 준비2

CNN 아키텍처 정리4 - ResNet

4.1 ResNet 소개

ResNet2015년도 ILSVRC에서 1위한 아키텍처입니다. 스탠포드 대학의 Andrej karpathy 가 알아낸 인간의 이미지 인식 오류율인 5%보다 낮은 오류율인 3.57%를 가집니다. 또한 그 전에는 깊다고 해봐야 22층 정도의 신경망인데, ResNet은 무려 152층을 가집니다

 

 

4.2 계층을 깊게 할수록 신경망의 성능이 오르는 이유

다음의 그림은 AlexNet의 각 layer에서의 특징맵들

학습이 완료된 신경망은 앞쪽 Conv Layer를 통과시, Input의 단순한 특징을 추출

추출된 특징맵은 Layer들을 지날수록, 단순한 특징들이 조합된 복잡한 특징들에 반응하다가 Layer의 끝부분에서는 사물의 일부분이 추출되게 되고, FC Layer를 통과하면, 특징맵들을 조합하여 객체의 클래스를 판별

, 계층을 깊게 할수록 객체를 단계적으로 이해할 수 있게 된다

 

 

4.3 일반 CNN을 엄청 깊게 한 심층 신경망이면 정확도가 무조건 증가할까?

ResNet의 저자는 일반 CNN을 엄청 깊게하면 어떤 일이 일어날까에 대해 생각했습니다. 그리하여 일반 20CNN 모델과 일반 56CNN 모델에 대해서 성능 평가를 했습니다. 그 결과

Test error를 보면, 일반적으로 심층 신경망이면 성능이 더 좋다고 알고 있으나이걸 보면, 56층의 error가 더 높습니다. 그러면 56층이면 parameter가 엄청나게 많으니, 훈련 데이터에만 Overfitting 되어서 Test 데이터에 제대로 반응을 못한건가 싶어서 Train error를 알아보았습니다.

 

Train error를 보면, 56층 신경망 모델에 Overfitting이 일어났다면, 훈련 데이터에 대해선 성능이 더 좋아야 할텐데, 오히려 20층 신경망 모델보다 성능이 더 안좋음을 알 수 있습니다

 

그 이유는, 심층 신경망을 학습 시킬때는 gradient( ∂y/∂x )가 점점 작아져서, 기울기 소실 문제가 발생한다. 즉 최적화 문제가 발생하며, 또한 앞쪽의 특징맵과 뒤쪽에서 추출한 특징맵간에 의미 있는 논리 결합이 안되기 때문입니다

 

그리하여 ResNet 저자들은 심층 신경망은 절대 구현할 수 없는건가? 에 대해 생각하다가 하나의 가설을 세우게 됩니다.

 

가설 : 학습이 완료된 얉은 신경망모델에 일부러 layer들을 추가시켜서 만든 깊은 신경망 모델은, 얉은 신경망모델의 성능을 보장할 수 있어야 한다

 

위 가설을 구현하기 위해 ResNet 저자들은, 학습된 얉은 신경망 모델의 가중치를 깊은 신경망 모델의 일부 layer에 복사시키고, 나머지 layer는 입력 = 출력 으로 하게 하면 얉은 신경망의 깊은 신경망화 가능할 것. 이를 구현하기 위한 아키텍처로 Residual Block을 고안해냅니다.

 

 

4.4 Residual block

앞에서 말한 얉은 신경망을 깊은 신경망으로 바꿀 때 경우를 생각해보겠습니다

 

4.5 Residual block의 의의

 

이때, 기울기 소실에 대해 조금 더 자세히 알아보면, 기울기 소실이 일어난다는 말은, 학습이 잘 안된다는 점 뿐만 아니라, 앞쪽 layer의 가중치가 사라져서, 입력이미지가 신경망에 입력되어도 이미지가 사라진다는 의미입니다. 그러므로 기존의 심층 신경망이면, 입력이미지에 대해 어떤 처리를 하려고 해도 할 수 없게됩니다만, Residual Block처럼 입력이미지 자체를 다음 layer로 전송시켜주면 기울기 소실 문제를 해결할 수 있습니다.

 

 

4.6 Residual block 효과 비유

이번에는 resnet의 효과를 직관적으로 알아보겠습니다

 

이 그림을 보면, 자동차도 있고, 테이블도 있고 전등도 있습니다. 이때 질문을 하나 하겠습니다.

 

이 질문을 해결하려면 위 그림을 다시 보면 됩니다. 그림을 보면 검은 테이블은 5개 정도가 있는 것을 알 수 있습니다.

 

 

, ResNet, 입력 이미지에 대해 어떠한 처리를 할 때, 중간 중간에 살짝식 입력 이미지를 보여주어서 학습을 더 잘하게 하는 방법입니다. resnet은 수학적으로 증명이 되지 않았지만 이 방식대로 신경망 모델을 쓰니 실제로 학습이 정말 잘됬습니다

 

4.7 Residual block 전체 구조

다음은 ResNet 전체 구조를 나타낸 그림입니다. ResNet (3 x 3) Conv Layer 2개씩묶은 Residual Block들을 쌓아만들었습니다. GoogLeNet과 마찬가지로, Global Average Pooing으로 FC Layer를 대신합니다. 또한 주기적으로 Conv Layer의 필터개수를 2배씩 증가해주고 MaxPooling layer를 사용하는 대신, Stride = 2인 Conv Layer를 써서 크기를 줄입니다.

 

4.8 Residual block 세부 사항

 

4.9 Residual block - 가정

이제 ResNet을 구현해보겠습니다. 먼저ResNet을 만들 때 가정한 점은 다음과 같습니다

첫 번째로, ImageNet 대신 Fashion-MNIST 데이터셋을 사용했습니다. 

 

두 번째로, ResNet50을 기준으로 하였고

 

세 번째로, Residual 모듈에 Bottleneck layer를 추가해줘서 연산의 효율을 증가시켰습니다.

 

네 번째로, Overfitting을 방지하기 위해 Data Augmentation을 사용하였습니다

 

 

4.10 ResNet 구현 - ResNet_Class 파일

가져올 라이브러리들은 다음과 같습니다

우선 Residual block 클래스를 만들어 줍니다. 이 클래스는 말그대로 Residual block을 그대로 구현한 클래스입니다. 이때 Residual block의 입력과 출력의 차원이 같아야 하므로 channel_inchannel_out / 4의 결과를 같게 설정해줍니다. 그리고 일반 Conv을 진행하는 경로와, shortcut 해주는 경로를 Add()함수를 써서 합쳐줍니다.

 

이 ResNet50 클래스는 옆의 Residual block을 사용하여 Resnet50을 구현한 클래스입니다. 이때, Conv을 사용한 뒤, Pool layer 대신, stride = 2를 사용한 Conv으로 크기를 줄여줍니다.

 

4.11 ResNet 구현 - ResNet_eval 파일

가져올 라이브러리들은 다음과 같습니다. 이 때 앞에서 만든 ResNet50 클래스를 가져옵니다

하이퍼파라미터를 다음과 같이 정의하였고, dataset_test, dataset_train 변수에 Fashion-MNIST 데이터셋을 저장해줍니다 그 후, 이 데이터셋에 대해 정규화 + 셔플 + 배치를 해줍니다. 또한 Data augmetation을 위해 datagen 이라는 변수를 선언해줍니다. 그 후, VGG객체를 생성해주고 이 모델에 대해 요약한 정보를 출력하게 합니다

 

입력값에 대해 원핫라벨한 뒤, 교차엔트로피를 통과시키는 loss_object 변수를 선언하고, optimizer에는 Adam을 저장합니다. 그리고 훈련시와 시험시의 loss accuracy를 저장할 변수를 선언해줍니다.

train_step은 모델의 결과값과 레이블을 체크하고 역전파를 구하고, 훈련 데이터에 대한 loss와 accuracy를 구하는  함수이고 

test_step은 시험 데이터에 대한 loss와 accuracy를 구하는 함수 입니다

이제 훈련과 시험을 해줍니다. 우선 100에폭에 대해 반복문을 실행하는데, 먼저 훈련데이터에 대해 실행합니다. 이때 data augmetation된 훈련데이터셋을 만들어 주고, 훈련을 해줍니다, 그 후 시험데이터셋에도 같은 과정을 해줍니다.

그 결과값인 loss accurtacy를 리스트변수인 train_accuracies test_accuracties에 추가해주고 각 파라미터들에 대해 출력을 합니다

 

4.12 ResNet 구현 - 실행 결과

ResNet50모델에 대한 요약본이 나옵니다. 사용한 residual block의 수가 적으므로 ResNet50 모델에 대한 요약본도 작게 나옵니다

신경망을 100에폭 동안 훈련과 시험을했을 때 loss accuaracy가 나오게 됩니다. 이때 ResNet의 성능은 이론으로 배웠

던 것과 달리 크게 안좋아지게 됩니다. 그 이유는

 

첫 번째로, ResNet50은 Residual block을 적게 썼기에, 아주 얉은신경망의 성능만 보장할 수 있기 때문입니다

 

두 번째로, ResNet50 클래스의 필터 수를 증가시키니 성능이 증가하는걸 확인할 수 있었으나, 그만큼 특징맵의 채널도 증가하게 되므로 제 컴퓨터 GPU 성능으로는 앞에서 구현한 VGG 성능인 92%를 넘게 할 수 없었습니다.

ResNet_class.py
0.00MB
ResNet_eval.py
0.01MB