목요일!
오늘은 Fine Tuning을 배우고 CNN을 마무리 짓는다.
DNN - 가진 이미지들의 픽셀을 학습
CNN - 가진 이미지들의 특성을 추출하여 학습
충분한 양의 데이터가 없는 경우 이미지 증식(Augmentation) 기법을 사용
학습 시간을 줄이고 더 좋은 filter를 이용하기 위해 전이학습(Transfer Learning)을 사용

이미지 데이터셋 학습 시 Feature Extraction(CNN) 이후 Classification(분류기)로 DNN이 적합하여 사용하고 있지만,
다른 분류기들이 많이 있음(SVM, Decision Tree, KNN, Naive Bayes, 앙상블 기법)
* 전이학습의 Pretrained Network 중 EfficientNet과 ResNet 성능이 좋음

1. 이미지 증식을 이용한 전이학습 (filter가 바뀌지 않도록 고정시켜 주어야 함)
import os
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import VGG16
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense, Dropout
from tensorflow.keras.optimizers import Adam
import matplotlib.pyplot as plt
train_dir = './data/cat_dog_small/train'
valid_dir = './data/cat_dog_small/validation'
train_datagen = ImageDataGenerator(rescale=1/255,
rotation_range=30,
width_shift_range=0.1,
height_shift_range=0.1,
zoom_range=0.2,
horizontal_flip=True,
vertical_flip=True,
fill_mode='nearest')
valid_datagen = ImageDataGenerator(rescale=1/255)
train_generator = train_datagen.flow_from_directory(train_dir,
classes=['cats', 'dogs'],
target_size=(150,150),
batch_size=20,
class_mode='binary') # 다중분류 시에는 categorical
valid_generator = valid_datagen.flow_from_directory(valid_dir,
classes=['cats', 'dogs'],
target_size=(150,150),
batch_size=20,
class_mode='binary') # 다중분류 시에는 categorical
# Pretrained Network
model_base = VGG16(weights='imagenet',
include_top=False,
input_shape=(150,150,3))
# VGG16(Conv layer) 안에 있는 모든 prams를 동결. Non-trainable params: 0 -> 14,714,688
model_base.trainable = False
# print(model_base.summary())
# model 생성
model = Sequential()
model.add(model_base)
model.add(Flatten(input_shape=(4*4*512,))) # 4차원인 activation map을 2차원으로 펴줌(이미지 3차원을 1차원으로)
model.add(Dense(units=256, activation='relu'))
model.add(Dropout(rate=0.5))
model.add(Dense(units=1, activation='sigmoid'))
print(model.summary())
model.compile(optimizer=Adam(learning_rate=1e-4),
loss='binary_crossentropy',
metrics=['accuracy'])
history = model.fit(train_generator, # val_accuracy: 0.8830
steps_per_epoch=100, # 2000 / 20
epochs=30,
validation_data=valid_generator,
validation_steps=50,
verbose=2) # verbose=0(Print None), 1(연산 전체), 2(loss만), 3(epochs만)
model.save('./data/cat_dog_small/transfer_learning_cnn_cat_dog_small.h5')
# history 객체로 그래프 그려보기
import matplotlib.pyplot as plt
train_acc = history.history['accuracy']
valid_acc = history.history['val_accuracy']
train_loss = history.history['loss']
valid_loss = history.history['val_loss']
figure = plt.figure(figsize=(20,5))
ax1 = figure.add_subplot(1,2,1)
ax2 = figure.add_subplot(1,2,2)
ax1.plot(train_acc, color='r', label='train accuracy')
ax1.plot(valid_acc, color='b', label='valid accuracy')
ax1.legend()
ax1.grid()
ax2.plot(train_loss, color='r', label='train loss')
ax2.plot(valid_loss, color='b', label='valid loss')
ax2.legend()
ax2.grid()
plt.tight_layout()
plt.show()


Fine Tuning(미세조정)
VGG16(CNN) 전체를 동결해서 사용하면, 우리가 학습해야 할 데이터셋과 맞지 않으므로 정확도가 떨어짐
→ FC layer 전의 마지막 2~3개 Conv layers의 동결을 풀고, 데이터셋에 맞게 학습이 가능한 형태로 만듦. fine tuning을 하려면, Classifier(분류기)가 전체를 동결한 CNN에 대해 학습이 되어 있어야 하므로 총 2번 학습해야 함!



2. Image Augmentation + Transfer Learning + Fine Tuning

# 이미지 증식을 이용한 전이학습(Fine Tuning)
import os
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import VGG16
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense, Dropout
from tensorflow.keras.optimizers import Adam
import matplotlib.pyplot as plt
train_dir = '/content/drive/MyDrive/Colab 멀캠 이지연/cat_dog_small/train'
valid_dir = '/content/drive/MyDrive/Colab 멀캠 이지연/cat_dog_small/validation'
train_datagen = ImageDataGenerator(rescale=1/255,
rotation_range=30,
width_shift_range=0.1,
height_shift_range=0.1,
zoom_range=0.2,
horizontal_flip=True,
vertical_flip=True,
fill_mode='nearest')
valid_datagen = ImageDataGenerator(rescale=1/255)
train_generator = train_datagen.flow_from_directory(train_dir,
classes=['cats', 'dogs'],
target_size=(150,150),
batch_size=20,
class_mode='binary') # 다중분류 시에는 categorical
valid_generator = valid_datagen.flow_from_directory(valid_dir,
classes=['cats', 'dogs'],
target_size=(150,150),
batch_size=20,
class_mode='binary') # 다중분류 시에는 categorical
# Pretrained Network
model_base = VGG16(weights='imagenet',
include_top=False,
input_shape=(150,150,3))
# VGG16(Conv layer) 안에 있는 모든 prams를 동결. Non-trainable params: 0 -> 14,714,688
model_base.trainable = False
# print(model_base.summary())
# model 생성
model = Sequential()
model.add(model_base)
model.add(Flatten(input_shape=(4*4*512,))) # 4차원인 activation map을 2차원으로 펴줌(이미지 3차원을 1차원으로)
model.add(Dense(units=256, activation='relu'))
model.add(Dropout(rate=0.5))
model.add(Dense(units=1, activation='sigmoid'))
# print(model.summary())
model.compile(optimizer=Adam(learning_rate=1e-4),
loss='binary_crossentropy',
metrics=['accuracy'])
history = model.fit(train_generator,
steps_per_epoch=100, # 2000 / 20
epochs=30,
validation_data=valid_generator,
validation_steps=50,
verbose=1) # verbose=0(Print None), 1(연산 전체), 2(loss만), 3(epochs만)
########### 여기까지 수행하면 classifier가 학습됨 ###########
model_base.trainable = True # VGG16(Conv layer) 동결 해체
for layer in model_base.layers:
if layer.name in ['block5_conv1', 'block5_conv2', 'block5_conv3']:
layer.trainable = True # 동결 해제
else:
layer.trainable = False # 동결
model.compile(optimizer=Adam(learning_rate=1e-5),
loss='binary_crossentropy',
metrics=['accuracy'])
history = model.fit(train_generator,
steps_per_epoch=100, # 2000 / 20
epochs=30,
validation_data=valid_generator,
validation_steps=50,
verbose=1) # val_accuracy: 0.9390
# history 객체로 그래프 그려보기
import matplotlib.pyplot as plt
train_acc = history.history['accuracy']
valid_acc = history.history['val_accuracy']
train_loss = history.history['loss']
valid_loss = history.history['val_loss']
figure = plt.figure(figsize=(20,5))
ax1 = figure.add_subplot(1,2,1)
ax2 = figure.add_subplot(1,2,2)
ax1.plot(train_acc, color='r', label='train accuracy')
ax1.plot(valid_acc, color='b', label='valid accuracy')
ax1.legend()
ax1.grid()
ax2.plot(train_loss, color='r', label='train loss')
ax2.plot(valid_loss, color='b', label='valid loss')
ax2.legend()
ax2.grid()
plt.tight_layout()
plt.show()

이미지 증식 + 전이학습 + Fine Tuning 여기서 모델의 성능을 더 높이려면, VGG16 대신에 EfficientNet를 이용하면 됨!
ImageDataGenerator를 사용하면 I/O Latency(Input/Output 지연. 이미지 → 픽셀 데이터)가 발생함
→ 이를 방지하기 위해 TFRecord를 이용해서, 이미지를 마치 CSV처럼 특별한 file을 만들어서 사용. 학습 속도가 빨라짐!
Object Dection에서 주로 사용
1. 4/11 월 | 2. 4/12 화 | 3. 4/13 수 | 4. 4/14 목 | 5. 4/15 금 |
Deep Learning Perceptron, Nueral Network |
Deep Learning Initialization, ReLU, Drop-out, Early-Stopping |
Deep Learning Image, CNN, Convolution Layer, Channel, Filter, Stride, Padding, Feature Map, Activation Map |
Deep Learning CNN, Feature Extraction, Pooling |
Deep Learning CNN |
6. 4/18 월 | 7. 4/19 화 | 8. 4/20 수 | 9. 4/21 목 | 10. 4/22 금 |
Deep Learning Generator |
Deep Learning AWS, Generator |
Deep Learning Image Augmentation, Transfer Learning |