Keras(TensorFlow)에서 학습된 모델을 전용하여 적은 데이터에서도 이미지 분류를 실현한다 [전이 학습: Fine tuning]

이전 블로그의 데이터를 사용하여 학습된 모델을 활용하여 Convolutional Neural Network (CNN) 컨벌루션 뉴럴넷의 실험을 해보세요!

1. 소개 「전이 학습(Fine tuning)」이란



이미 학습된 모델의 레이어 간의 결합 가중치를 최적화하여 새로운 모델을 생성하는 방법입니다.

많은 양의 이미지를 학습한 네트워크는 어느 정도 유사한 필터가 됩니다.
따라서 다른 이미지 데이터를 사용하여 학습된 모델을 사용함으로써 새롭게 만드는 모델은 적은 데이터/학습량으로 모델을 만들 수 있습니다.

1-1. 학습된 모델에 대하여



이번 학습이 끝난 모델은 VGG16을 사용해, 6개의 꽃의 화상 데이터(각 500장)를 학습해 꽃을 분류해 보겠습니다.

아래 그림의 모든 결합 부분을 재학습합니다.


※ VGG 모델이란, 2014에 ImageNet에서 우승한 옥스포드의 VGG팀이 사용한 모델이 됩니다.

2. 구현



이번 프로그램은 여기 Git에 넣어 둡니다.

2-1. 개발 환경(머신 스펙)




CPU
인텔® 코어™ i7-7700 프로세서


MEMORY
16GB

GPU
GeForce GTX 980 Ti

OS
우분투 16.04


2-2. 환경 준비 (Docker에 Jupyter 구축)



Docker 파일의 build.
GPU 환경이 아닌 경우는 우분투 이미지 등을 사용하십시오.

※build에는 조금 시간이 걸립니다.
$ git clone https://github.com/tsunaki00/fine_tuning.git
$ cd fine_tuning
$ cd docker
$ docker build . -t keras

# Dockerを起動(GPU環境ではnvidia-docker)
$ docker run -d --name keras-container \
             -v $PWD/notebooks:/notebooks  \
             -p 8888:8888  \
             keras

2-3. 학습 데이터 준비



마지막으로 모은 꽃 이미지를 사용하여 실험합니다.
Git

2-4.Jupyter에서 학습 프로그램 작성



개발 실행에 Jupyter에 액세스하여 다음 프로그램을 실행.
http://[서버]:8888

학습에는 약간의 시간이 걸립니다.

train.ipynb
import pandas as pd
import random, math

import numpy as np

from keras.preprocessing.image import load_img, img_to_array
from keras.applications.vgg16 import VGG16
from keras.models import Sequential, Model
from keras.layers import Input, Dense, Dropout, Activation, Flatten
from keras.optimizers import SGD
from keras.utils import np_utils
from keras.preprocessing.image import ImageDataGenerator


# 分類クラス
classes = ['chrysanthemum', 'cosmos', 'ginkgo', 'lotus' , 'margaret', 'rose']
nb_classes = len(classes)
batch_size = 32
nb_epoch = 10
current_dir = "/notebooks"

# image pixel
img_rows, img_cols = 224, 224

def build_model() :

    input_tensor = Input(shape=(img_rows, img_cols, 3))
    vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
    #vgg16.summary()

    _model = Sequential()

    _model.add(Flatten(input_shape=vgg16.output_shape[1:]))
    _model.add(Dense(256, activation='relu'))
    _model.add(Dropout(0.5))
    _model.add(Dense(nb_classes, activation='softmax'))

    model = Model(inputs=vgg16.input, outputs=_model(vgg16.output))
    # modelの14層目までのモデル重み
    for layer in model.layers[:15]:
        layer.trainable = False

    model.compile(loss='categorical_crossentropy',
                  optimizer=SGD(lr=1e-4, momentum=0.9), metrics=['accuracy'])
    return model

if __name__ == "__main__":
    train_datagen = ImageDataGenerator(
        rescale=1.0 / 255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

    train_generator = train_datagen.flow_from_directory(
        directory=current_dir + '/images',
        target_size=(img_rows, img_cols),
        color_mode='rgb',
        classes=classes,
        class_mode='categorical',
        batch_size=batch_size,
        shuffle=True)

    test_datagen = ImageDataGenerator(rescale=1.0 / 255)

    test_generator = test_datagen.flow_from_directory(
        directory=current_dir + '/test_images',
        target_size=(img_rows, img_cols),
        color_mode='rgb',
        classes=classes,
        class_mode='categorical',
        batch_size=batch_size,
        shuffle=True)
    model = build_model()
    model.fit_generator(
        train_generator,
        steps_per_epoch=3000,
        epochs=nb_epoch,
        validation_data=test_generator,
        validation_steps=600
    )

    hdf5_file = current_dir + "/model/flower-model.hdf5"
    model.save_weights(hdf5_file)


2-5. 모델 실험



학습된 모델을 실험합니다.

model_check.ipynb
import pandas as pd
import random, math
import numpy as np

from keras.preprocessing.image import load_img, img_to_array
from keras.applications.vgg16 import VGG16, preprocess_input
from keras.models import Sequential, Model
from keras.layers import Input, Dense, Dropout, Activation, Flatten
from keras.optimizers import SGD

classes = ['chrysanthemum', 'cosmos', 'ginkgo', 'lotus' , 'margaret', 'rose']
nb_classes = len(classes)
current_dir = "/notebooks"
img_rows, img_cols = 224, 224

def build_model() :
    input_tensor = Input(shape=(img_rows, img_cols, 3))
    vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

    _model = Sequential()

    _model.add(Flatten(input_shape=vgg16.output_shape[1:]))
    _model.add(Dense(256, activation='relu'))
    _model.add(Dropout(0.5))
    _model.add(Dense(nb_classes, activation='softmax'))

    model = Model(inputs=vgg16.input, outputs=_model(vgg16.output))
    # modelの14層目までのモデル重み
    for layer in model.layers[:15]:
        layer.trainable = False

    model.compile(loss='categorical_crossentropy',
                  optimizer=SGD(lr=1e-4, momentum=0.9), metrics=['accuracy'])
    return model

if __name__ == "__main__":
    model = build_model()
    model.load_weights(current_dir + "/model/flower-model.hdf5")

    filename = current_dir + "/check_images/rose.jpg"

    img = load_img(filename, target_size=(img_rows, img_cols))
    x = img_to_array(img)
    x = np.expand_dims(x, axis=0)

    filename = current_dir + "/check_images/rose.jpg"
    predict = model.predict(preprocess_input(x))

    for pre in predict:
        y = pre.argmax()
        print("花の名前 : ", classes[y])


다음 꽃으로 실험


결과는 Rose에서 정답했습니다.


3.사이고에게



학습이 끝난 모델을 최적화함으로써 여러가지 퍼질 것 같네요! !
평상시는 경마 예상 시바 이나 패션 관련 AI를 개발하고 있습니다.

또한 다양한 딥 러닝 실험을 tweet하고 있습니다.
트위터
따라주세요.

좋은 웹페이지 즐겨찾기