Fine Tuning (미세조정) , EarlyStopping, ModelCheckpoint

2021. 10. 5. 00:38ai/Deep Learning

728x90

tf.reset_default_graph()

 

기본 CNN구조 (architecture)

1. Traning Data Set

2. Input Layer

3. convolution Layer [특성 (4차원) ]

     (1) conv

     (2) relu

     (3) pooling Layer

4.     3번 x a

5. Flatten Layer ( 2차원 )

6. hidden Layer

7. output Layer

8. T, Y 비교  ( update는 당연히 미분이 아닌 back propagation )

 

 

많은 양의 Data가 있어야지 학습이 잘되요 ! → 현실적으로 그렇게 많은 data를 수직하기 쉽지 않아요!!

그러면 어떻게 하나요?

Data Augmentation (데이터 증식) → overfiting을 많이 줄일수 있이요

                                                하지만 accuracy 자체는 많이 높아지지 않아요 !! + 학습시간이 오래걸려요 

 

Pretrained Network : VGG16, VGG19, MS (ResNet), google (Inception), EfficiectNet, MobileNet ..

 

1. Training Dataset

2. Pretrained Network
      [1]inputlayer
      [2]convolution
      [3]pooling
      [4]x2   / [2][3]x a
 (2)Classfier [제거] 해서 우리의 Model (DNN) 이용

 

Pretrained Network 의 filter로 Traning Data Set이 적절한가요?

정확도 ↑ overfitting ↓  

조금더 확장시킬수 있는데 밑에 내용참조

 

Pretrained Network을 이용해서 (Feature Extraction)학습할때 증식을 이용하려면 ??

 

전체가 Model
1.Training Data Set [X, T] (Augmentation) 
2.Pretrained Network
 (1)Feature Extraction
      [1]inputlayer
      [2]convolution
      [3]pooling
      [4]x2   / [2][3]x a
 (2)Classfier [제거]
3.DNN (classifeier) [Pretrend Network에서 제거한 classifier에 넣는다]
      [1]inputlayer
      [2]hidden
      [3]output
4. Y 값 loss

여기서 문제는 Pretrained Network은 filter 들을 update할때

1.Layer도 크고

2.이미 완성된 filter 

3.너무 많은 양의 filter

그래서 update 할때 시간이 너무걸린다


그래서 완성된 filter는 update할 필요가 x 즉 parameter를 동결 !!  = 증식ok(overfitting↓), accuracy↑

 

 

조금 더 좋아지려면 어떻게 해야 하나요? 

Fine Tuning (미세조정) 

- Pretrained Network filter 에서 우리의 data filter를 합쳐 더 나은 filter를 만들기 위해

  이렇게 되면 accuracy ↑

- 상위 level Layer의 필터를 동결에서 해제

상위 level Layer : classifier 에 가까울수록 상위

- 일반적으로 1~3개 해제

- Fine Tuning 작업을 하려면 우리의 classifier가 훈련이 되어있어야 한다 (W, B가 완성)
  그래서 동결시켜서 1번 돌고 layer를 풀고 1번 더해야 한다

  왜냐하면 classifier 가 학습이 안된 상태로 되면 너무 큰 오차가 network에 전파되서 fine tuning이 안된다

 


1.Training Data Set [X, T] (Augmentation) 
2.Pretrained Network
 (1)Feature Extraction
      [1]inputlayer
      [2]convolution
      [3]pooling
      [4] / [2][3]x a
 (2)Classfier [제거]

3.DNN (classifeier) [Pretrend Network에서 제거한 classifier에 넣는다]
      [1]inputlayer
      [2]hidden
      [3]output
4. Y 값 loss

 

Fine Tuning을 하는 절차

1. Pretrained Network에 우리의 classifier(Network)를 추가
2. Pretrained Network을 동결
3. 우리의 Classifier를 학습
4. Pretrained Network의 상위 Layer의 일부를 동결에서 해제..
5. 우리의 classifier를 다시 학습해요

 


epochs 가 너무 많으면 overfitting / 똑같은 책을 계속 보는거라고 보면 된다

epochs 가 너무 적으면 학습 x     /  책을 1  , 2권 본다고 생각하면 된다

 

ex ) epochs 1000을 잡으면 좋았다가 안좋아 진다

좋았을때 시점의 model을 써야되는데 현재는 다 끝났을때 사용

 

callback function

 early stopping : epoch을 돌리다가 어느 시점에 최상의 model일때 stop

 Checkpoint    : 중간중간 model file을 check하면서 만들어주겠다


 

from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint

 

# Early Stopping

es = EarlyStopping(monitor='val_loss',            # 어떤 값을 지켜보면서 그만할지 더할지 ' .history '에서 나온값이다

                   mode='auto',                         # 자동으로 early stopping

                   verbose=1,                           # 출력을 할거냐

                   patience=5)                          #  epoch을 진행하다가 loss가 떨어져야되는데 5번 안떨어지면 stop

 

# Checkpoint

model_filename = './{epoch:06d}-{val_acc:0.6f}-{acc:0.6f}.hdf5'                      

              

 

checkpointer = ModelCheckpoint(

    filepath=model_filename, 

    verbose=1

    period=1,                

    save_best_only=True,

    mode='max',

    monitor='val_acc')

# val_acc 가 증가할때마다 저장

 

 

history = model.fit(train_generator,

                    steps_per_epoch=100,

                    epochs=30,

                    validation_data=valid_generator,

                    validation_steps=50,

                    callbacks=[es, checkpointer]

                    verbose=1)

# 사용하려면 model fit 할때 설정 , 위에 es 와 checkpointer는 변수

 


 

import numpy as np

import tensorflow as tf

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/융복합 프로젝트형 AI 서비스 개발(2021.06)/09월/30일(목요일)/cat_dog_small/train'

valid_dir = '/content/drive/MyDrive/융복합 프로젝트형 AI 서비스 개발(2021.06)/09월/30일(목요일)/cat_dog_small/validation'

 

# 학습용 데이터에 대한 ImageDataGenerator를 만들어요!

train_datagen = ImageDataGenerator(rescale=1/255,

                                   rotation_range=30,                 # 회전비율 0 ~ 30도

                                   width_shift_range=0.1,            # 왼쪽 오른쪽 움직이는 비율

                                   height_shift_range=0.1,           # 위 아래 움직이는 비율

                                   zoom_range=0.2,                   

                                   horizontal_flip=True,              # 좌우 반전 

                                   fill_mode='nearest')

 

# validation 데이터는 증식을 사용하지 않아요!

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'

)

 

valid_generator = valid_datagen.flow_from_directory(

    valid_dir,

    classes=['cats','dogs'],

    target_size=(150,150),

    batch_size=20,

    class_mode='binary'

)

 

# Pretrained Network

 

model_base = VGG16(weights='imagenet',

                   include_top=False,

                   input_shape=(150,150,3))

 

model_base.trainable = False   # 모든 convolution layer를 동결.

 

# print(model_base.summary())   # (4, 4, 512)

 

model = Sequential()

 

model.add(model_base)

model.add(Flatten(input_shape=(4*4*512,)))

 

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-5),

              loss='binary_crossentropy',

              metrics=['accuracy'])

 

history = model.fit(train_generator,

                    steps_per_epoch=100,

                    epochs=30,

                    validation_data=valid_generator,

                    validation_steps=50,

                    verbose=1)


model_base.trainable = True

 

# print(model_base.summary())  # block5_conv1 , 2, 3         # 상위 Layer 알아보기

 

# 상의 layer 3개만 동결에서 해제!

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,

                    epochs=30,

                    validation_data=valid_generator,

                    validation_steps=50,

                    verbose=1)


# accuracy와 loss 비교

 

train_acc = history.history['accuracy']

valid_acc = history.history['val_accuracy']

 

train_loss = history.history['loss']

valid_loss = history.history['val_loss']

 

fig = plt.figure()

fig_1 = fig.add_subplot(1,2,1)

fig_2 = fig.add_subplot(1,2,2)

 

fig_1.plot(train_acc, color='b', label='training_accuracy')

fig_1.plot(valid_acc, color='r', label='validation_accuracy')

fig_1.legend()

 

fig_2.plot(train_loss, color='b', label='training_loss')

fig_2.plot(valid_loss, color='r', label='validation_loss')

fig_2.legend()

 

plt.tight_layout()

plt.show()

# 그림이 이쁘진 않지만 처음에 비해 많이 좋아졌다





'ai > Deep Learning' 카테고리의 다른 글

pretrained network, Transfer Learning (전이학습)  (0) 2021.10.05
Data Augmentation (데이터 증식)  (0) 2021.10.01
Image Data Generator (cat & dog ver)  (1) 2021.10.01
cat & dog tf2.0 ver  (0) 2021.09.30
Dog & Cat img → csv  (0) 2021.09.30