今回の記事ではKerasを用いてひらがな画像の「あ」「い」文字分類する流れをご紹介します。データ作成から、転移学習でモデル作成、文字分類まで流れをコードを使って紹介します。初学者の方でもすぐに動かすことができ、わかりすいと思いますので是非参考にしてみてください。
Kerasの実行環境
dockerコンテナ上に環境を構築する方法を別記事でご紹介しています。環境構築ができていない方は是非そちらを参考にしてみてください。
データ準備
ひらがなの「あ」「い」の画像を下記のように準備します。
photo
├── a
│ ├── a.jpg
│ ├── a0.jpg
│ ├── a1.jpg
│ ├── a10.jpg
│ ├── a11.jpg
│ ├── a12.jpg
│ ├── a2.jpg
│ ├── a3.jpg
│ ├── a4.jpg
│ ├── a5.jpg
│ ├── a6.jpg
│ ├── a7.jpg
│ ├── a8.jpg
│ └── a9.jpg
└── i
├── i.jpg
├── i0.jpg
├── i1.jpg
├── i10.jpg
├── i11.jpg
├── i12.jpg
├── i2.jpg
├── i3.jpg
├── i4.jpg
├── i5.jpg
├── i6.jpg
├── i7.jpg
├── i8.jpg
└── i9.jpg
各画像14枚ごとの少数ですが、枚数が増えても変わらないです。
上記のモデルデータを読み込むための関数を先に実行します。
import os
import cv2
import numpy
import keras
import tensorflow
import re
from keras.callbacks import EarlyStopping
from keras.applications.inception_v3 import InceptionV3
from keras.callbacks import ModelCheckpoint
# モジュールのimport関連です。今回の転移学習の元学習データはInceptionV3です。
# データ読み込み関数
def create_image_list():
main_path = "/photo/"
files = os.listdir(main_path)
files_dirs = [f for f in files if os.path.isdir(os.path.join(main_path, f))]
description_value = None
objective_value = []
now_index_number = 0
for dir_item in files_dirs:
if dir_item == ".ipynb_checkpoints":
pass
else:
print(dir_item + "読み込み中")
sub_path = main_path + "/" + dir_item
sub_files = os.listdir(sub_path)
sub_files_dirs = [f for f in sub_files if os.path.isdir(os.path.join(sub_path, f))]
sub_files = [f for f in sub_files if re.search('jpg', f, re.IGNORECASE)]
image_list = []
loop_count = 0
if len(sub_files) != 0:
for image_path_item in sub_files:
image_path = sub_path + "/" + image_path_item
img = cv2.imread(image_path ,cv2.COLOR_BGR2RGB)
#一時措置
img = cv2.resize(img, (150,150))
image_list.append(img.tolist())
index_number = now_index_number
objective_value.append(index_number)
loop_count += 1
if loop_count >= 1500:
break
if description_value is None:
description_value = numpy.array(image_list)
else:
now_array = numpy.array(image_list)
description_value = numpy.concatenate([description_value,now_array], axis=0)
image_list = None
now_index_number += 1
return[description_value,objective_value]
転移学習でモデル学習
モデル学習を行うコードは下記です。
# モデル学習コード
def main():
description_value,objective_value = create_image_list()
description_value = description_value.astype('float32') / 255#
objective_value = numpy.array(objective_value)
objective_value = keras.utils.to_categorical(objective_value, 2)
print(description_value.shape[1:])
model = InceptionV3(include_top=True,weights=None, input_shape=description_value.shape[1:], classes=2)
print(model.summary())
model.compile(loss='categorical_crossentropy', optimizer="sgd", metrics=['accuracy'])
MODEL_DIR = "/test_model/"
if not os.path.exists(MODEL_DIR): # ディレクトリが存在しない場合、作成する。
os.makedirs(MODEL_DIR)
checkpoint = ModelCheckpoint(
filepath=os.path.join(MODEL_DIR, "test.hdf5"), save_best_only=True) # 精度が向上した場合のみ保存する。
es_cb = EarlyStopping(monitor='val_loss', patience=2, verbose=1, mode='auto')
history = model.fit(description_value, objective_value, batch_size=64, epochs=150, verbose=1, validation_data=(description_value, objective_value), shuffle=True, callbacks=[checkpoint])
open(os.path.join("/test_model/",'keras_model.json'), 'w').write(model.to_json())
if __name__ == "__main__":
main()
今回はInceptionという既存モデルに転移学習させていきます。学習はmodel.fitで行なっています。エポック回数等を指定できますので調整してみてください。
結果から言うと、今回生成したモデルの精度は悪かったです。
サンプルデータをモデルにインプット
実際に学習で使用していないひらがなの画像「あ」「い」を転移学習させたモデルにインプットしてみました。
from keras.models import load_model
import numpy as np
from keras.preprocessing.image import img_to_array, load_img
model = load_model(r"/test_model/test.hdf5")
print(model.input,model.output)
import glab
img_dir = glob.glob(r"/test_image/*.jpg")
print(img_dir)
#今回は['/test_image/test_img.jpg']test_imageフォルダのtest_img.jpg(あの画像)の一枚をテスト
img1 = load_img(img_dir[0], target_size=(150,150))
img_nad = img_to_array(img1)/255
img_nad = img_nad[None, ...]
pred = model.predict(img_nad, batch_size=1, verbose=0)
print(pred)
上記のコードではひらがな画像の「あ」をインプットしました。出力結果は下記のようになっています。
[[0.49381995 0.50618005]]
「あ」である確率が約49%、「い」である確率が約50%と「い」である確率の方が高いとなっています。
「あ」でも「い」でもない全く関係ない画像でも、同じような確率が出力されたので、特徴量が多くモデル学習に失敗していると思われます。これは学習データが少ないことが原因と考えられます。
画像の枚数を水増しし、60枚程度の画像データをそれぞれ作成しました。
何度か学習をやり直し、batchを64→32、epochを150→100に変更して、再度学習させたモデルが最も精度がよかったです。
みなさんも調整してみてください。
コメント
[…] 【Keras】Kerasで転移学習を行い「ひらがな」を分類する方法。 […]
[…] 【Keras】Kerasで転移学習を行い「ひらがな」を分類する方法。 […]