今回は, 昨年の10月~12月に開催された「チームで学ぼう! TensorFlow(機械学習)実践編第2期」において, 私の参加した「チーム仲鶴後吉(仮)」の取り組んだ内容の番外編である.
関連記事
ペットボトルを認識してみよう! (1)
ペットボトルを認識してみよう! (2)
ペットボトルを認識してみよう! (3)
ペットボトルを認識してみよう! (4)
ペットボトルを認識してみよう! (5)
最近, AWSのGPUを使うようになり, 大規模なモデルの学習ができるようになったので,
Deep Learningの画像応用において代表的なモデルであるVGG16[1]をFine-tuningすることで, ペットボトルのカテゴリ識別の精度向上にトライした.
番外編
1. VGG16ベースシステム
1.1 VGG16+Fine-tuning[2]
VGG16は, 2014年のILSVRC(ImageNet Large Scale Visual Recognition Challenge)で提案された畳み込み13層とフル結合3層の計16層から成る畳み込みニューラルネットワークである.
KerasではこのVGG16を容易に利用できるので, 今回はKerasのバックエンドにTensorFlowを使い, ペットボトルのカテゴリ識別を試してみた.
[コード]
# coding: utf-8 # Petbottle classifier using VGG16 import os import sys import numpy as np import pandas as pd # Keras from keras.preprocessing.image import ImageDataGenerator from keras.layers import Input, Activation, Dropout, Flatten, Dense from keras.models import Sequential, Model from keras.applications.vgg16 import VGG16 from keras import optimizers # パラメータ # データ TRAIN_DIR = './data/train_images' VAL_DIR = './data/val_images' MODEL_DIR = './model' MODEL_FILE = 'petbottle_vgg16.h5' # 画像データ IMG_WIDTH = 80 IMG_HEIGHT = 160 IMG_CHANNELS = 3 BATCH_SIZE = 100 TRAIN_SAMPLES = 32208 VAL_SAMPLES = 84 # 2Epoch毎にモデル保存. 10(=2*15)Epoch学習 EPOCH = 2 LOOP = 5 # カテゴリ情報 category = pd.read_csv('category_master.tsv', sep='\t') classes = [] for name in category['category_dir']: classes.append(name) print(classes) # 学習データ準備 train_data_generator = ImageDataGenerator( rescale = 1.0 / 255, horizontal_flip = True) train_data = train_data_generator.flow_from_directory( TRAIN_DIR, target_size = (IMG_HEIGHT, IMG_WIDTH), color_mode = 'rgb', classes = classes, class_mode = 'categorical', batch_size = BATCH_SIZE, seed = 1, shuffle = True) # 評価データ準備 val_data_generator = ImageDataGenerator( rescale = 1.0 / 255) val_data = val_data_generator.flow_from_directory( VAL_DIR, target_size = (IMG_HEIGHT, IMG_WIDTH), color_mode = 'rgb', classes = classes, class_mode = 'categorical', shuffle = False) # VGG16モデル準備 # 注) FC層は使用しない(1000カテゴリ→11カテゴリのため) input_tensor = Input(shape=(IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS)) vgg16_model = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor) vgg16_model.summary() # カスタムFC層 # 11カテゴリ top_model = Sequential() top_model.add(Flatten(input_shape=vgg16_model.output_shape[1:])) top_model.add(Dense(128, activation='relu')) top_model.add(Dense(128, activation='relu')) top_model.add(Dropout(0.5)) top_model.add(Dense(11, activation='softmax')) # VGG16(nonFC) + カスタムFC層 model = Model(input=vgg16_model.input, output=top_model(vgg16_model.output)) if os.path.exists(os.path.join(MODEL_DIR, MODEL_FILE)): model.load_weights(os.path.join(MODEL_DIR, MODEL_FILE)) model.summary() for layer in model.layers[:15]: layer.trainable = False model.compile(loss='categorical_crossentropy', optimizer=optimizers.Adam(lr=3e-6, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.), metrics=['accuracy']) # ファインチューニング for i in range(LOOP): log = model.fit_generator( train_data, samples_per_epoch = TRAIN_SAMPLES, nb_epoch = EPOCH, validation_data = val_data, nb_val_samples = VAL_SAMPLES) mname = ('Epoch%d-%s' % ((i+1)*EPOCH, MODEL_FILE)) model.save_weights(os.path.join(MODEL_DIR, mname))
1.2 モデル構造
VGG16をベースとした今回のモデル構造は, 以下の通り.
1.3 学習と評価
学習履歴は, 以下の通り.
学習条件:
・カテゴリ数:11
・入力画像:80x160dot (注:32x64dotを拡大)
・学習データ:32,208
・エポック数:10
識別条件:
・カテゴリ数:11
・評価データ:84
10Epochで識別率80.95%となり, 以前の66.67%[3]を大きく上回るとともに, 初期の目標であった75.0%をも超える性能が得られた.
さすが, ImageNetと呼ばれる大規模な画像データセットを使って訓練したモデルだけのことはある.
現状, 各カテゴリーの学習データ数に結構バラツキがあるので, この辺りをバランスよくするなどすれば更に性能改善が見込めそうだ.
---
参照URL:
[1] VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION
[2] VGG16のFine-tuningによる犬猫認識 (2)
[3] ペットボトルを認識してみよう! (3)
詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~
|
TensorFlowで学ぶディープラーニング入門?畳み込みニューラルネットワーク徹底解説
|
|
初めてのディープラーニング --オープンソース"Caffe"による演習付き
|