이전 포스트에서 transfer learning에 대한 간략한 개념을 알아봤으니 직접 코드로 실습해보자.
MobileNetV2 로 transfer learning해서 개와 고양이 이미지를 분류하려 한다.
이전 포스트가 궁금하면?
https://donghyeok90.tistory.com/170
MobileNetV2
모바일이나, 임베디드에서도 실시간으로 작동할 수 있게 모델이 경량화 되면서도,
정확도 또한 많이 떨어지지 않게하여, 속도와 정확도 사이의 트레이드 오프 문제를 어느정도 해결한 네트워크
1. 이미지 다운로드
!wget --no-check-certificate \
https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip \
-O ./cats_and_dogs_filtered.zip
# 압축풀기
import zipfile
file = zipfile.ZipFile('/content/cats_and_dogs_filtered.zip')
file.extractall('./') # './' : 현재경로
train_dir = '/content/cats_and_dogs_filtered/train'
test_dir = '/content/cats_and_dogs_filtered/validation'
2. MobileNetV2 가져오기
import tensorflow as tf
# 만들려는 모델의 인풋 이미지
IMG_SHAPE = (128, 128, 3)
base_model = tf.keras.applications.MobileNetV2(input_shape= IMG_SHAPE,
include_top= False)
- include_top= False : 헤드모델을 빼고 가져온다.
- include_top= True : 헤드모델을 포함해서 가져온다.
base_model.summary()
모델의 summary()를 확인해보면 layer가 아주 많이 나온다.
학습불가능한 34,112 개의 파라미터와 학습가능한 2,223,872개의 파라미터가 있다.
3. base model freezing하기
가져온 MobileNetV2는 이미 1400만장 이상의 이미지로 학습이 잘 되어서,
이미지의 특징을 뽑아내는 역할을 하므로, 나의 데이터로는 학습이 되지 않도록 한다.
base_model.trainable = False
summary()를 다시 확인해보면 모든 파라미터가 학습불가능하게 바뀐걸 확인할 수 있다.
4. 분류 작업을 할 head model 만들기
from keras.layers import Flatten, Dense
head_model = base_model.output
head_model = Flatten()(head_model)
head_model = Dense(128, 'relu')(head_model)
head_model = Dense(1, 'sigmoid')(head_model)
Sequential API를 썼을 때와는 다르게 model.add를 사용할 수 없고
뒤에 (head_model)을 붙이는 것처럼 Funtional API를 사용해야 한다.
5. base model 과 head model 이어붙이기
from keras.models import Model
model = Model(inputs= base_model.input, outputs= head_model)
model.summary()
모델이 이어졌다.
컴파일도 해준다.
from keras.optimizers import RMSprop
model.compile(optimizer= RMSprop(learning_rate=0.0001),
loss= 'binary_crossentropy',
metrics= ['accuracy'])
6. ImageDataGenerator를 이용해 이미지 증강과 전처리를 해준다.
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale= 1/255.0,
width_shift_range= 0.2)
test_datagen = ImageDataGenerator(rescale= 1/255.0)
train_generator = train_datagen.flow_from_directory(train_dir,
target_size= (128, 128),
class_mode= 'binary',
batch_size= 128)
test_generator = test_datagen.flow_from_directory(test_dir,
target_size= (128, 128),
class_mode= 'binary',
batch_size= 128)
7. 모델 학습 및 평가
# 데이터가 없어서 연습용이므로 test셋으로 validation과 test를 모두 수행함
epoch_history = model.fit(train_generator, epochs=5,
validation_data= (test_generator) )
model.evaluate(test_generator)
8. Fine tuning
base 모델의 일부분을 학습가능하도록 변경한 후에 추가학습 시켜서,
조금 더 개선이 가능한지 확인해본다.
# 파인튜닝은 head model을 학습하는 트랜스퍼 러닝을 마친 후에 수행해야 한다.
# 1. 일단은, 베이스모델의 전체 레이어를 다시 학습 가능하도록 먼저 바꿔준다.
base_model.trainable = True
# 2. 베이스 모델의 전체 레이어 수를 확인한다.
len(base_model.layers)
# 3. 몇번째 레이어까지 학습이 안 되도록 할 것인지, 결정해 준다.
end_layer = 100
for layer in base_model.layers[ 0 : end_layer+1 ]:
layer.trainable = False
base_model.summary()
model.summary()
from keras.optimizers import Adam
model.compile(Adam(0.0001), 'binary_crossentropy', ['accuracy'])
epoch_history2 = model.fit(train_generator, epochs=5,
validation_data= (test_generator))
model.evaluate(test_generator)
이 경우에는 성능 향상이 없었다.
'Machine Learning > Deep Learning' 카테고리의 다른 글
Tensorflow - 콜백을 이용해 로그와 모델 저장하기 (0) | 2023.01.08 |
---|---|
Transfer Learning(전이 학습) 과 Fine Tuning(미세 조정) (0) | 2023.01.03 |
파일을 Train/Test 디렉토리로 나눠서 저장하는 방법 (0) | 2023.01.02 |
Tensorflow - ImageDataGenerator를 이용한 이미지 전처리와 이미지 증강 (0) | 2023.01.01 |
Tensorflow - CNN 모델 예제 (0) | 2022.12.31 |