얼굴인식, Fine-Tunning, 커스텀 모델, 커스텀 데이터
얼굴인식. 해봤으면 이제 더 잘 해볼 수 있어야 한다.
어떻게 해야 할까?
모델을 수정해보고, 파라미터들을 좀 변경해 보면서
최적의 모델과 파라미터 값들을 찾아가는 긴~~~~~~ 여정을 떠나야한다.
전이학습을 선행해야 이해 할 수 있다.
이미 잘 학습된 모델에서 가중치를 가져와 나의 모델에 적용 할 때,
적은 시간과 적은 데이터로 최대의 효과를 가져 올 수 있다.
이게 전이학습의 효과이자 목표이다.
그럼 이전에 설명한 모델을 튜닝하는 작업을 해야한다.
우선 모델의 Summary 를 함께 보자.
_________________________________________________________________
Layer (type) Output Shape Param # ================================================================= zero_padding2d_79_input (Inp (None, 224, 224, 3) 0 _________________________________________________________________ zero_padding2d_79 (ZeroPaddi (None, 226, 226, 3) 0 _________________________________________________________________
conv2d_97 (Conv2D) (None, 224, 224, 64) 1792 _________________________________________________________________ zero_padding2d_80 (ZeroPaddi (None, 226, 226, 64) 0 _________________________________________________________________
conv2d_98 (Conv2D) (None, 224, 224, 64) 36928 _________________________________________________________________ max_pooling2d_31 (MaxPooling (None, 112, 112, 64) 0 _________________________________________________________________ zero_padding2d_81 (ZeroPaddi (None, 114, 114, 64) 0 _________________________________________________________________
conv2d_99 (Conv2D) (None, 112, 112, 128) 73856 _________________________________________________________________
dropout_31 (Dropout) (None, 112, 112, 128) 0 _________________________________________________________________ zero_padding2d_82 (ZeroPaddi (None, 114, 114, 128) 0 _________________________________________________________________ conv2d_100 (Conv2D) (None, 112, 112, 128) 147584 _________________________________________________________________
dropout_32 (Dropout) (None, 112, 112, 128) 0 _________________________________________________________________ max_pooling2d_32 (MaxPooling (None, 56, 56, 128) 0 _________________________________________________________________ zero_padding2d_83 (ZeroPaddi (None, 58, 58, 128) 0 _________________________________________________________________ conv2d_101 (Conv2D) (None, 56, 56, 256) 295168 _________________________________________________________________ zero_padding2d_84 (ZeroPaddi (None, 58, 58, 256) 0 _________________________________________________________________ conv2d_102 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ zero_padding2d_85 (ZeroPaddi (None, 58, 58, 256) 0 _________________________________________________________________ conv2d_103 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ max_pooling2d_33 (MaxPooling (None, 28, 28, 256) 0 _________________________________________________________________ zero_padding2d_86 (ZeroPaddi (None, 30, 30, 256) 0 _________________________________________________________________ conv2d_104 (Conv2D) (None, 28, 28, 512) 1180160 _________________________________________________________________ zero_padding2d_87 (ZeroPaddi (None, 30, 30, 512) 0 _________________________________________________________________ conv2d_105 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ zero_padding2d_88 (ZeroPaddi (None, 30, 30, 512) 0 _________________________________________________________________ conv2d_106 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ max_pooling2d_34 (MaxPooling (None, 14, 14, 512) 0 _________________________________________________________________ zero_padding2d_89 (ZeroPaddi (None, 16, 16, 512) 0 _________________________________________________________________ conv2d_107 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ zero_padding2d_90 (ZeroPaddi (None, 16, 16, 512) 0 _________________________________________________________________ conv2d_108 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________
dropout_33 (Dropout) (None, 14, 14, 512) 0 _________________________________________________________________ zero_padding2d_91 (ZeroPaddi (None, 16, 16, 512) 0 _________________________________________________________________ conv2d_109 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________
dropout_34 (Dropout) (None, 14, 14, 512) 0 _________________________________________________________________ max_pooling2d_35 (MaxPooling (None, 7, 7, 512) 0 _________________________________________________________________ conv2d_110 (Conv2D) (None, 1, 1, 4096) 102764544 _________________________________________________________________
dropout_35 (Dropout) (None, 1, 1, 4096) 0 _________________________________________________________________ conv2d_111 (Conv2D) (None, 1, 1, 4096) 16781312 _________________________________________________________________
dropout_36 (Dropout) (None, 1, 1, 4096) 0 _________________________________________________________________ conv2d_112 (Conv2D) (None, 1, 1, 2622) 10742334 _________________________________________________________________
flatten (Flatten) (None, 2622) 0 _________________________________________________________________
fc6 (Dense) (None, 256) 671488 _________________________________________________________________
dropout_37 (Dropout) (None, 256) 0 _________________________________________________________________
fc7 (Dense) (None, 256) 65792 _________________________________________________________________
dropout_38 (Dropout) (None, 256) 0 _________________________________________________________________
fc8 (Dense) (None, 4) 1028 _________________________________________________________________ activation_15 (Activation) (None, 4) 0 =================================================================
Total params: 145,741,186
Trainable params: 145,741,186
Non-trainable params: 0 _________________________________________________________________
모델 구조는 각자 입맛에 맛게 만들어야 하는데...
입맛이 좀 까다로울 수 있다.
데이터의 성격, 특징, 크기 등에 따라서 기본 모델을 잘 만들어야 한다.
그냥 잘 만들어진 모델을 따오는 것을 추천한다.
예로는 VGG, RES, INCEP, 등등 많이 있다.
여기서 키 포인트~! 는 바로 Trainable Params 를 바꾸는 작업인데!
위에서 이미 잘 훈련된 레이어의 파라미터들은 재학습에서 제외하는 것을 뜻한다.
어렵나?
어렵지 않게 느껴진다면, 어느정도 이미지 딥러닝에 많이 노출 되었다고 본다.
간단하게 내가 추가한 마지막 Output 레이어를 제외한 나머지를 재학습에서 제외 한다.
for l in custom_vgg_model.layers[:-6]:
l.trainable = False
쉽다.
이제 이 모델로 나만의 데이터를 이용한 Custom_model 을 만들어야 한다.
우선! Compile을 통한 학습 개요를 꾸린다.
"your_custom_model_name".compile(
loss='categorical_crossentropy',
optimizer='adadelta',
metrics=['accuracy'])
데이터 가공은 하도 언급을 많이 해서 이젠 그냥 자동이다. 각자 알아서.
나는 이전 글에서 진행한 부분의 연장선에 있기 때문에
바로 학습을 진행한다.
...
...
...
GPU를 사용하고 있어서 시간이 좀 단축되었다.
거의 뭐... 완벽에 가깝다고 할 수 있다.
테스트 데이터가 아닌 새로운 사진을 가지고 해보아도 거의 완벽하게 누구인지를 찾아낸다.
끝!