スポンサーリンク

【Python】Kerasでひらがな画像を文字分類。〜 データ準備・転移学習でモデル作成・文字分類 〜

Python
スポンサーリンク

今回の記事ではKerasを用いてひらがな画像の「あ」「い」文字分類する流れをご紹介します。データ作成から、転移学習でモデル作成、文字分類まで流れをコードを使って紹介します。初学者の方でもすぐに動かすことができ、わかりすいと思いますので是非参考にしてみてください。

スポンサーリンク

Kerasの実行環境

dockerコンテナ上に環境を構築する方法を別記事でご紹介しています。環境構築ができていない方は是非そちらを参考にしてみてください。

DockerでのPython環境構築

データ準備

ひらがなの「あ」「い」の画像を下記のように準備します。

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に変更して、再度学習させたモデルが最も精度がよかったです。

みなさんも調整してみてください。

本記事を読んでいただき感謝です。サイトを訪れていただいた方はプログラミング勉強中かと思いますのでプログラミング勉強のコツを合わせてご紹介。

スポンサーリンク
スポンサーリンク
スポンサーリンク

ブログに関しては500円程度かかりますが、それ以外は無料です。知識の吸収と並行してアウトプットは非常に効率が良いです。テックアカデミーに関しては講座レベルが高いにも関わらず、無料体験や人気口座も大幅値下げがあるので、重点的に学びたいものを無料体験してみてください。

転職時にも、エンジニアからテックアカデミー・Paizaは認知度が高いので、未経験入社採用を行う際履歴書で目に留まります。特にPaizaのスキルレベルA・SなどはIT業界でも評価されます。

テックアカデミー・Paizaの無料登録ができる期間中にぜひご利用してみてください。私も活用経験ありです。

Python
スポンサーリンク
スポンサーリンク

コメント

  1. […] 【Keras】Kerasで転移学習を行い「ひらがな」を分類する方法。 […]

  2. […] 【Keras】Kerasで転移学習を行い「ひらがな」を分類する方法。 […]

タイトルとURLをコピーしました