본문 바로가기
AI, 빅데이터/AI

[AI] 전이학습 | Cifar10 | MobileNetV2

by Foxy현 2022. 11. 23.
728x90
반응형

안녕하세요! Foxy현입니다

오늘은 내가 직접 모델을 작성하는 것이 아닌, 공개된 모델을 가져와 사용하는 전이 학습(Transfer Learning)에 대해 알아보겠습니다


먼저 Transfer Learning(전이학습)이란 나의 데이터를 학습시키기 위해 공개된 모델을 가져와 일부만 수정하여 학습시키는 것을 말합니다.

그런다고 모든 데이터를 내가 원하는 모델을 사용하여 학습시킬 수 있는 것은 아니고,

최대한 나의 데이터와 공개된 모델에 사용된 데이터와 유사한 데이터를 사용하는 것이 좋습니다

 

즉, 이미 학습된 모델에서 일부 Layer(weight)만 가져와 학습하는 것을 말합니다.

 

일반적으로 다음과 같은 과정을 거칩니다

  1. 학습된 기존 모델의 layers를 가져오기
  2. Transfer learning 과정에서 기존 weight 정보가 손실되지 않도록 trainable 속성을 false로 지정
  3.  layers에 학습 가능한 새로운 layers를 추가
  4. 새로운 데이터로 모델을 다시 training 

또한 Fine-tuning이라는 것도 있는데

성능을 향상하기 위해 전체 layers trainable 속성을 true로 지정하고, 낮은 learning rate으로 다시 학습 시키는 것을 말합니다

이제 실습을 해보겠습니다!


from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Flatten, Dense 
import cv2
from google.colab.patches import cv2_imshow 
import matplotlib.pyplot as plt
import numpy as np
from keras.applications import MobileNetV2 
from keras.optimizers import Adam
from keras.datasets import cifar10 as data

필요한 라이브러를 불러옵니다.

여기서 Dataset은 cifar10을 사용하며, 사전 작성된 모델은 MobileNetV2를 사용합니다.

(train_X,train_Y),(test_X,test_Y) = data.load_data()

학습 데이터와 테스트 데이터로 나눠줍니다.

 

train_X=np.array(train_X) 
train_Y=np.array(train_Y)

test_X=np.array(test_X) 
test_Y=np.array(test_Y)

데이터는 리스트 형식으로 저장되어있기 때문에, 계산을 위해 행렬로 바꿔줍니다.

 

train_X = train_X.astype('float32')/255.0
test_X = test_X.astype('float32')/255.0

train_Y = np_utils.to_categorical(train_Y)
test_Y = np_utils.to_categorical(test_Y)

입력 데이터는 정규화해주고, 타깃 데이터는  원핫인코딩을 해주겠습니다.

 

pretrained_model = MobileNetV2(input_shape=(32,32, 3), include_top=False)
pretrained_model.trainable = False

이미지 데이터의 크기가 (32,32,3)이므로 모델의 input shape 또한 동일하게 지정합니다

include_top은 Output Layers를 포함하지 않기 위해 지정합니다

 

trainable 속성을 false로 해줌으로써 기존 모델학습하지 않겠습니다

 

 

model = Sequential([
    pretrained_model,
    Flatten(),
    Dense(10,activation='softmax')
])

기존 모델인 pretrained_model과 새롭게 추가한 Flatten과 Dense Layer입니다.

여기서 주의할점은 Dense의 크기를 입력 Y의 수와 동일하게 만들어줘야 합니다.

 

위의 Y라는 데이터의 인풋은 10입니다. 따라서 10을 지정합니다

 

 

pretrained_model.trainable = True
model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=1e-5), metrics=['accuracy']) 
history=model.fit(train_X, train_Y, batch_size=8, epochs=10)

학습 시간을 고려하여 epoch를 10으로 지정하였지만 더 높여 좋은 성능을 낼 수 있습니다. 물론 한계가 있지만요.

trainable 속성을 True로 하여 성능을 향상하는 fine-tuning 과정입니다

 

학습률 또한 낮게 지정합니다

 

 

_, accuracy = model.evaluate(test_X, test_Y) 
print('Accuracy: ', accuracy)

 모델을 평가합니다

 

plt.plot(history.history['loss'], label='loss') 
model.evaluate(test_X,test_Y)
trial=0
cv2_imshow(test_X[trial]*255); 
pred=model.predict(test_X)
print("Prediction: " + str(pred[trial])) 
print("Real: " + str(test_Y[trial]))

마지막으로 predict하여 정답을 확인해보는 코드입니다.

 


요약하자면, 전이학습은 이미 학습된 모델에서 일부 Layer(weight)만 가져와 학습하는 것이였습니다.

 

감사합니다!!

728x90
반응형