本記事では、作成した学習器(CNN:畳み込みニューラルネットワーク)を用いて、画像を分類する雛形コードを載せました。
自前の画像ファイル(jpg, png)で分類学習器を作成する雛形コードは、次のリンク先です。hk29.hatenablog.jp
本記事のプログラムを実行すると下図のように画像の判定確率を取得できます。そして、例えば判定確率90%以上を正解として分類することが出来ます。
下図は、0~9の手書き数字を分類した結果です。label_nullと記載したフォルダには、0~9のいずれの判定確率も90%未満であったものを分類しています。
■本プログラム
# -*- coding: utf-8 -*- import os, glob, re import json, pprint import shutil import numpy as np import pandas as pd import tensorflow as tf #print("Num GPUs:", len(tf.config.list_physical_devices('GPU'))) from tensorflow import keras from tensorflow.keras.models import model_from_json from tensorflow.keras.preprocessing.image import array_to_img, img_to_array, load_img # CNN分類学習器を読み込んで実行する関数 def load_cnn_func(modelFile, model_weight): model = model_from_json(open(modelFile).read()) model.load_weights(os.path.join(os.path.dirname(modelFile), model_weight)) img_data_list = [] for file_path in file_list: img = img_to_array(load_img(file_path, target_size=(img_width, img_height, img_ch))) img_data_list.append(img) # numpyアレイ型へ変換 img_data_np = np.asarray(img_data_list) img_data_np = img_data_np.astype('float32') img_data_np = img_data_np / 255.0 # 予測結果を返す return model.predict(img_data_np) # メイン関数 def main(): # CNN実行して予測結果を取得 predict_y = load_cnn_func(modelFile, model_weight) print(predict_y) # 予測結果をひとつのcsvファイルに保存する df = pd.DataFrame(predict_y, columns = label_name_list) df.insert(0, 'file_name', file_list) print(df) df.to_csv('predict_y.csv', sep=',', header=True, index=False) # 画像を分類する。 if os.path.isdir('class_picture'): shutil.rmtree('class_picture') os.makedirs('class_picture', exist_ok=False) for i in range(df.shape[1]-1): label_name = 'label_' + str(i) # ラベル名 df_buf = df[df[label_name] >= target_value] # 指定条件の値のある行を抽出 df_buf.to_csv('class_picture/predict_y_label_' + str(i) + '.csv') # csvに保存 os.mkdir('class_picture/' + label_name) # ラベル名のフォルダを作成 for file_path in df_buf['file_name']: new_file_path = '/'.join(['class_picture', label_name, os.path.basename(file_path)]) shutil.copy2(file_path, new_file_path) # 指定した判定確率未満の画像をnullとして分類する index_list = [] for file_path in glob.glob('class_picture/*.csv'): df_buf = pd.read_csv(file_path, index_col=0) index_list.extend(df_buf.index.values.tolist()) df_drop = df.drop(index=index_list) df_drop.to_csv('class_picture/predict_y_label_null.csv') # csvに保存 os.mkdir('class_picture/label_null') # ラベル名のフォルダを作成 for file_path in df_drop['file_name']: new_file_path = '/'.join(['class_picture/label_null', os.path.basename(file_path)]) shutil.copy2(file_path, new_file_path) if __name__ == '__main__': print(tf.__version__) file_list = glob.glob('testSet/*.jpg') file_list = sorted(file_list, key=lambda x:int((re.search(r"[0-9]+", x)).group(0))) modelFile = 'model.json' model_weight = 'model_weight.hdf5' # 判定確率90%以上を正解として分類する target_value = 0.90 # 分類クラス数をモデルから取得する json_open = open(modelFile, 'r') json_load = json.load(json_open) pprint.pprint(json_load) myclasses = json_load['config']['layers'][-1]['config']['units'] print('myclasses -> ', myclasses) label_name_list = [] for i in range(myclasses): label_name_list.append('label_' + str(i)) print(label_name_list) # 画像の読み込み設定 img_width = 28 # 横 img_height = 28 # 縦 img_ch = 3 # 3ch(RGB) main()
以上
<広告>
リンク
リンク
リンク