3.1 CNN의 문제
3.2 Naive Inception Module
3.3 Naive Inception Module의 문제점
즉, Naive Inception Module을 쓰니 연산량이 854M으로 엄청나게 증가합니다. 이를 해결하기 위해 Bottleneck layer라는 것을 추가해주게 됩니다.
3.4 Bottleneck Layer
- Convolution 연산을 할 때의 출력의 크기를 구하는 공식을 보겠습니다. 이 식을 보면 (1x1)크기로 필터링을 하면 입력데이터의 높이와 너비는 그대로 유지한 채, 채널을 감소시킬 수 있을 것입니다.
- 입력데이터의 채널이 엄청나게 많다고 가정할 경우, 입력데이터에 (1x1)필터를 64개 쓴다고 하면, 입력데이터의 높이와 너비를 유지한채로 채널이 64인 데이터가 생깁니다
- 즉, 1x1 Conv layer를 넣으면, 입력데이터의 채널수를 줄일수 있으므로, 연산량도 감소 가능할 것.
3.5 Inception module with dimension reduction (Inception Module v1)
다음은 Inception module with dimension reduction입니다. 이건 Naive Inception Module에 Bottleneck Layer를 넣어서 입력 데이터의 채널수를 줄인 모듈입니다. 앞과 같은 예시에서 필터 결합시 출력맵을 구해보면 다음과 같이 (28 x 28 x 480)이 나오고, 각 Conv layer에서의 연산량을 합해보면, 다음과 같이 358M번으로, 연산량이 절반이상 줄어듭니다
즉, (1x1) Conv인 bottleneck layer를 사용하면, 연산량을 조절 할 수 있습니다.
3.5 GoogLeNet 전체 구조
GoogLeNet은 크게 세부분으로 나눌 수 있습니다. 초반 6개의 layer는 Stem 영역이라 부르는데, 이 영역은 그저 Conv, Pool layer를 쌓았습니다 (왜냐면 이 영역에 Inception Module을 넣어도 성능에 변화가 없었음). 그리고 중간에는 Inception Module을 9층 쌓았고 끝부분에는 Softmax로 클래스를 분류하는 output classifier 영역으로 쌓았습니다. 중요한 점은, 이 output classifier 영역에 FC layer를 사용하지 않았습니다. 대신 Global Average Pooing을 씀으로써, 학습할 parameter 양을 줄였습니다.
GoogLeNet은 중간의 Inception Module들에 보조분류기가 달려 있습니다. 보조분류기가 있는 이유는, 신경망이 22층으로 깊기에 gradient가 역전파 되는 도중 소실이 될 수 있으므로, 신경망 중간에 예측 결과 Loss를 삽입해줌으로써, 기울기 소실 문제를 해결합니다. 이때 최종 Loss는, 중간에 전파되는 손실함수값과 output classifier에 전파되는 손실함수의 값의 평균으로 구합니다
3.6 GoogLeNet 구현 - 가정
이제 GoogLeNet을 구현해보겠습니다. 먼저 GoogLeNet를 만들 때 가정한 점은 다음과 같습니다
첫 번째로, ImageNet 대신 Fashion-MNIST 데이터셋을 사용했습니다.
두 번째로, 제 컴퓨터의 성능이 안좋아서인지, googlenet 모델대로 inception모듈을 9개쓰니, 채널이 너무나도 증가하여 계속 에러가 발생했습니다. 그래서 인셉션 모듈의 수를 5개로 줄여봤더니 제가 만든 googlenet이 동작은 하였으나 1에폭에 대해 약 10분이 걸렸기에 (필터의 개수는 출력맵의 채널이 되므로) 인셉션 모듈에 입력할 필터의 개수를 크게 감소시켰습니다.
세 번째로, 인셉션모듈을 5개밖에 안쓰니, 얉은신경망 모델이므로 보조 분류기는 달지 않았습니다
네 번째로, 가중치 최적화는 Adam을 사용하였습니다.
다섯 번째로, Overfitting을 방지하기 위해 Data Augmentation을 사용하였습니다.
3.7 GoogLeNet 구현 - GoogLeNet_Class 파일
우선 Inception block 클래스를 만들어 줍니다. 이 클래스는 말그대로 인셉션블럭을 그대로 구현한 클래스입니다.
아래의 InceptionNet클래스는 _layers 리스트변수에 Stem영역을 구현한 뒤, 앞에서의 Inception Block을 사용하여 Inception block을 5번 사용하고, Global Average Pooling과 FC layer를 사용하여 GoogLeNet의 결과를 구하는 클래스입니다. 이때 학습 속도를 위해서 필터의 개수를 16개로 적게했습니다. 또한 앞에서 말했듯, 인셉션 모듈을 9개쓰니 에러가 떠서 한계치인 5개를 사용하였습니다.
3.8 GoogLeNet 구현 - GoogLeNet_eval 파일
하이퍼파라미터를 다음과 같이 정의하였고, 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에 추가해주고 각 파라미터들에 대해 출력을 합니다
3.9 GoogLeNet구현 - 실행 결과
신경망을 100에폭 동안 훈련과 시험을했을 때 loss와 accuaracy가 나오게 됩니다. 이 때 googlenet 모델의 성능은 91.24%가 됩니다. 이 결과는 vgg보다 성능이 떨어지게 되는데, 그 이유는
첫 번째로 인셉션 블록의 필터갯수를 적게하였기 때문입니다. 필터의 개수가 적으면 그만큼 이미지에서 추출할 특징이 적어집니다. 그리하여 신경망 모델 제일 끝부분에서 추출한 특징맵들을 합쳐서 추론을 해봐도 정확도가 높지 않게 됩니다.
두 번째로 인셉션 모듈 자체를 적게썼기에 vgg보다 더 얉은 신경망이기 때문입니다. 신경망은 이미지의 특징을 단계적으로 이해하는데 얉은 신경망이면 한번에 학습해야할 양이 많아지므로 정확도가 떨어지게 됩니다.
'대학원 준비2' 카테고리의 다른 글
CNN 아키텍처 정리5 - 그 외 아키텍처(MobileNet, U-Net, DenseNet, ResNext) (0) | 2020.09.09 |
---|---|
CNN 아키텍처 정리4 - ResNet (0) | 2020.09.09 |
CNN 아키텍처 정리2 - VGG (0) | 2020.09.09 |
CNN 아키텍처 정리1 - AlexNet (0) | 2020.09.09 |