텐서플로 VGG16모델을 이용한 파인 튜닝

1
2
3
4
5
6
7
8
9
10
11
# 이미지넷 대회 : 120만개 이미지 -> 분류기 -> 1000클래스 분류
# VGG16이라는 pretrained model을 사용해서 -> 전이학습


# VGG16 불러오기 + 우리의 네트워크를 연결 -> fine-tuning
# 학습 유형이 2가지 존재.
# 첫 번째 유형은 우리가 가지고 있는 데이터로 추가 학습(기존 모델은 그대로 사용) - 대부분 첫 번째 방법 사용
# 두 번째 유형은 전체 네트워크를 학습(시간이 엄청나게 소요) - 거의 안함

# 전체적인 과정은 다음과 같습니다
# 데이터 정제(VGG에서 학습한 사이즈대로) -> VGG호출 -> VGG 포함된 모델 생성 -> 학습
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout, Flatten, Conv2D, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras import optimizers, Input, models, layers, optimizers, metrics
from tensorflow.keras.applications import VGG16, EfficientNetB7
import numpy as np
import matplotlib.pyplot as plt

#train,test 데이터셋 정제
train_datagen = ImageDataGenerator(rescale=1./255,
horizontal_flip=True,
width_shift_range=0.1,
height_shift_range=0.1)
train_generator = train_datagen.flow_from_directory('./train',target_size =(150,150),batch_size=5, class_mode='binary')

test_datagen = ImageDataGenerator(rescale=1/255.)
test_generator = test_datagen.flow_from_directory('./test',target_size =(150,150),batch_size=5, class_mode='binary')

# VGG16이라는 이미지넷에서 사용된 pre_trained 모델 호출
#include_top을 True로 할 경우 softmax 1000으로 클래스 분류 그대로 사용한다는 의미 (대부분 추가 학습의 경우 False 사용)
transfer_model = VGG16(include_top= False, input_shape=(150,150,3), weights='imagenet')

#새롭게 학습하지 않고 이어서 학습하기에 False로 설정
transfer_model.trainable=False
# transfer_model.summary()

#새로운 모델을 설정
finetune_model = Sequential()
finetune_model.add(transfer_model) #파인튜닝이기때문에 이미 학습된 모델을 추가
finetune_model.add(Flatten()) #1차원으로 통일
finetune_model.add(Dense(64)) #(None, 64)
finetune_model.add(Activation('relu'))
finetune_model.add(Dropout(0.5))
finetune_model.add(Dense(1)) # (None, 1)
finetune_model.add(Activation('sigmoid'))
# finetune_model.summary()

#컴파일 및 콜백옵션
finetune_model.compile(loss='binary_crossentropy', optimizer=optimizers.Adam(learning_rate=0.0002), metrics=['accuracy'])
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=5)

#학습
history = finetune_model.fit(train_generator, epochs=20, validation_steps=10, validation_data=test_generator,callbacks=[early_stopping_callback])

## epochs당 변화를 시각화 하기
y_vloss = history.history['val_loss']
y_loss = history.history['loss']

x_len = np.arange(len(y_loss))
plt.plot(x_len, y_vloss,marker='.', c='red', label='testsetloss')
plt.plot(x_len, y_loss,marker='.', c='blue', label='trainsetloss')

plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

만약 파인튜닝이 아니고 그냥 학습 없이 pre_trained_data로 평가를 하고 싶은 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from tensorflow.keras.preprocessing import image
from keras.applications import vgg16

#평가할 사진을 불러옴
img = image.load_img('flower.jpg', target_size=(224,224))

# 평가할 사진을 (x,224,224,3) 차원으로 바꿔줌
input_img = np.expand_dims(img, axis = 0)
print(np.shape(img)) #(224,224,3)
print(np.shape(input_img)) # (1,224,224,3)

#VGG16모델을 불러옴
model_1 = vgg16.VGG16()

# 평가(예측)
pred = model_1.predict(input_img)
np.argmax(pred) #daisy
top_ten = vgg16.decode_predictions(pred, top=10)
top_ten # 예측값 상위 10개를 보여줌
Author

InhwanCho

Posted on

2022-12-22

Updated on

2022-12-22

Licensed under

Comments