0422 Fine Tuning_EfficientNet

wldnjswldnjs·2022년 5월 16일
0

딥러닝

목록 보기
10/10
post-custom-banner
!pip install efficientnet
!pip install tensorflow-addons
import os
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator

import efficientnet
import efficientnet.tfkeras as efn

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense, Dropout

from tensorflow.keras.layers import GlobalAveragePooling2D
import tensorflow_addons as tfkeras
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

from tensorflow.keras.optimizers import RMSprop, Adam
import matplotlib.pyplot as plt
import cv2 as cv                 # opecv (이미지 resize)
train_dir = '/content/drive/MyDrive/colab/cat_dog_small/train'
valid_dir = '/content/drive/MyDrive/colab/cat_dog_small/validation'

# 상수라서 대문자로 표현
IMAGE_SIZE = 256
BATCH_SIZE = 8
LEARNING_RATE = 5e-5

# ImageGenerator를 위한 전처리 함수
# 여러가지 전처리 작업이 포함될 수 있다.
# 여기서의 역할은 이미지 resize
def generate_preprocessing(img):
    img = cv.resize(img, (IMAGE_SIZE, IMAGE_SIZE)) # (256, 256)
    return img

# ImageDataGenerator 생성
# train_data : augmentation해서 생성
train_datagen = ImageDataGenerator(rescale=1/255, # 0과 1사이의 값으로 정규화
                                   rotation_range=40,
                                   width_shift_range=0.1,
                                   height_shift_range=0.1,
                                   zoom_range=0.2,
                                   horizontal_flip=True,
                                   vertical_flip=True,
                                   preprocessing_function=generate_preprocessing,
                                   fill_mode='nearest')

valid_datagen = ImageDataGenerator(rescale=1/255,
                                   preprocessing_function=generate_preprocessing)

# data 추출
# train_datagen의 generate_preprocessing에 이미지 size가 지정되어 있으므로
# target_size 설정해주지 않아도 된다.
train_generator = train_datagen.flow_from_directory(
    train_dir,
    classes=['cats', 'dogs'],  # [0, 1]으로 지정
    batch_size=BATCH_SIZE,
    class_mode='binary'
)

valid_generator = valid_datagen.flow_from_directory(
    valid_dir,
    classes=['cats', 'dogs'],  # [0, 1]으로 지정
    batch_size=BATCH_SIZE,
    class_mode='binary',
    shuffle=False              # valid 용도라서 섞지 않아도 됨
)
# Pretrained Network

pretrained_network = efn.EfficientNetB4(
    weights='imagenet',
    include_top=False,                     # classifier 버린다
    input_shape=(IMAGE_SIZE,IMAGE_SIZE,3)  # (256, 256, 3)
)

pretrained_network.trainable = False       # 동결

# model 생성
model = Sequential()

model.add(pretrained_network)

# FC Layer
model.add(GlobalAveragePooling2D()) # FC Layer 붙일 때 해주면 좋다.
                                    # input layer 역할
# Hidden layer 주지 않고 바로 학습
model.add(Dense(units=1,
                activation='sigmoid'))

# Early Stopping
es = EarlyStopping(monitor='val_loss',
                   mode='auto',
                   patience=5,      # 5번동안 loss값이 떨어지지 않으면 stop
                   verbose=1)

# Checkpoint
model_checkpoint = './{epoch:06d}-{val_acc:0.6f}-{acc:0.6f}.ckpt'

checkpointer = ModelCheckpoint(
    filepath = model_checkpoint,
    verbose=1,
    period=2,                       # 2epoch당 저장
    save_best_weights=True,
    mode='auto',
    monitor='val_acc'
)

model.compile(optimizer=Adam(learning_rate=LEARNING_RATE),
              loss='binary_crossentropy',
              metrics=['acc'])

history = model.fit(train_generator,
                    steps_per_epoch=(2000 // BATCH_SIZE),
                    epochs=30,
                    validation_data=valid_generator,
                    validation_steps=(1000 // BATCH_SIZE),
                    callbacks=[es, checkpointer],
                    verbose=1)

# print(pretrained_network.summary())

# pretrained_network의 구조도 변환할 수 있음 => 리스트 형태로 되어 있다.

# for idx, layer in enumerate(pretrained_network.layers):
#     print('{}번 : {}'.format(idx,layer.name))

Fine Tuning

Pretrained Network의 layer 몇 개를 학습이 가능한 형태로 동결 해제한 후 재학습

post-custom-banner

0개의 댓글