본문 바로가기

멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차/DL

4/21 목

728x90

목요일!

 

오늘은 Fine Tuning을 배우고 CNN을 마무리 짓는다.

 

DNN - 가진 이미지들의 픽셀을 학습

CNN - 가진 이미지들의 특성을 추출하여 학습

 

충분한 양의 데이터가 없는 경우 이미지 증식(Augmentation) 기법을 사용

학습 시간을 줄이고 더 좋은 filter를 이용하기 위해 전이학습(Transfer Learning)을 사용

이미지 데이터셋 학습 시 Feature Extraction(CNN) 이후 Classification(분류기)로 DNN이 적합하여 사용하고 있지만,

다른 분류기들이 많이 있음(SVM, Decision Tree, KNN, Naive Bayes, 앙상블 기법)

 

* 전이학습의 Pretrained Network 중 EfficientNet과 ResNet 성능이 좋음

 

작은 양의 데이터를 VGG16을 이용해서 전이학습 -> Overfitting 발생!

 

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()​

Image Augmentation + Transfer Learning

 

Fine Tuning(미세조정)

VGG16(CNN) 전체를 동결해서 사용하면, 우리가 학습해야 할 데이터셋과 맞지 않으므로 정확도가 떨어짐

→ FC layer 전의 마지막 2~3개 Conv layers의 동결을 풀고, 데이터셋에 맞게 학습이 가능한 형태로 만듦. fine tuning을 하려면, Classifier(분류기)가 전체를 동결한 CNN에 대해 학습이 되어 있어야 하므로 총 2번 학습해야 함!

Transfer Learning_Fine Tuning

 

2. Image Augmentation + Transfer Learning + Fine Tuning

끝에 3개의 Conv layers만 동결 해제

# 이미지 증식을 이용한 전이학습(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()

Image Augmentation + Transfer Learning + Fine Tuning

 

이미지 증식 + 전이학습 + 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
Deep Learning
Transfer Learning,
Fine Tuning
Deep Learning
TFRecord,
EfficientNet
11. 4/25 월 4/26 화 ~ 5/19 목
Deep Learning

AI 프로젝트

* 실습!

728x90

'멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차 > DL' 카테고리의 다른 글

4/22 금  (0) 2022.04.23
4/20 수  (0) 2022.04.20
4/19 화  (0) 2022.04.19
4/18 월  (0) 2022.04.18
4/15 금  (0) 2022.04.15