機械学習手法を用いて画像認識してみたいです。
このような要望にお応えします。
画像認識は、教師あり学習手法を用いて行います。
教師あり学習については、下記の記事を参照してみてください。
今回は、RandomForestを用いて動物画像の分類を行いたいと思います。
分類の対象は、以下になります。
・犬
・猫
・リス
RandomForestは、機械学習モデルのひとつです。複数の決定木を用いて各決定木の予測結果の多数決で結果を求める方法になります。
このように、複数のモデルを用いて性能を向上させる学習方法をアンサンブル学習と呼ばれたりします。RandomForestもアンサンブル学習ということになります。
RandomForestによる画像認識の準備をします。
RandomForestの準備
pythonライブラリsklearnを用いることで簡単にRandomForestを使用することができます。
1 |
pip install sklearn |
pythonプロンプトを起動し、下記のプログラムが実行できればインストール成功です。
1 |
import sklearn |
データは、スクレイピングを実施して、犬、猫、リスに関する画像データを収集しています。以下のようにcsvファイルに書き出しています。
このcsvファイルを読み込み、画像データをPythonライブラリcv2, numpyを用いて、各画像をRamdomForestの学習に使用できるように変換します。
1 2 3 4 5 6 7 8 9 10 11 12 |
df = pd.read_csv('train_data.csv') # データ設定 features = np.array([cv2.cvtColor(cv2.resize(cv2.imread(f), (64, 64), cv2.INTER_CUBIC), cv2.COLOR_BGR2RGB) for f in df['image_name']]) # 画像データをベクトルに変換 #print(features.shape) x_data = features.reshape(features.shape[0], features.shape[1]*features.shape[2]*features.shape[3]).astype('float32') / 255.0 y_data = np.array(df['image_label'].astype(int)) x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.2) |
データの準備は、これで完了です。
次に、RandomForestによる学習を行っていきます。
今回の問題は、犬、猫、リスのうち、どれに相当するのかを学習するマルチクラス分類の問題になります。
学習モデル定義
学習は、以下のように実施します。
1 2 3 4 5 6 7 8 9 10 |
param = {'n_estimators': np.arange(1, 150)} gs = GridSearchCV(RFC(), param, cv=3, verbose=True, n_jobs=-1) gs.fit(x_train,y_train) print("acc: ", gs.score(x_test, y_test)) |
学習モデルによる予測
学習したモデルを用いた予測は以下のように行っています。
画像下に出力したラベル色が青の場合、正解データと予測値が一致し、赤色の場合は、一致しないことを表現するように処理します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# 予測 predict_result = clf.predict(x_test) col = 5 row = int(len(x_test) / col) + 1 plt.figure(figsize=(20, 20)) plt.subplots_adjust(wspace=0.2, hspace=0.7) for index in range(len(x_test)): plt.subplot(row, col, index+1) plt.imshow(x_test[index].reshape(features.shape[1], features.shape[2], features.shape[3]), cmap=plt.get_cmap('gray')) # 正解の場合は青、不正解の場合は赤 predict_label = predict_result[index] teach_label = y_test[index] if predict_label == teach_label: color = 'blue' else: color = 'red' result = '' if predict_label == 0: result = 'dog' elif predict_label == 1: result = 'cat' elif predict_label == 2: result = 'Squirrel' plt.xlabel("{}".format(result), color=color, fontsize=20) |
出力結果は、以下になります。
結果を見ると、一部赤色になっており、誤分類していることが確認できます。
ソースコード全体を載せます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# coding: utf-8 from sklearn.ensemble import RandomForestClassifier as RFC from sklearn.model_selection import train_test_split, GridSearchCV import numpy as np import matplotlib.pyplot as plt import pandas as pd from PIL import Image import cv2 def fn_start_RandomForest(): df = pd.read_csv('train_data.csv') # データ設定 features = np.array([cv2.cvtColor(cv2.resize(cv2.imread(f), (64, 64), cv2.INTER_CUBIC), cv2.COLOR_BGR2RGB) for f in df['image_name']]) # 画像データをベクトルに変換 #print(features.shape) x_data = features.reshape(features.shape[0], features.shape[1]*features.shape[2]*features.shape[3]).astype('float32') / 255.0 y_data = np.array(df['image_label'].astype(int)) x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.2) # Randomforest学習 param = {'n_estimators': np.arange(1, 150)} gs = GridSearchCV(RFC(), param, cv=3, verbose=True, n_jobs=-1) gs.fit(x_train,y_train) print("acc: ", gs.score(x_test, y_test)) # 予測 predict_result = gs.predict(x_test) col = 5 row = int(len(x_test) / col) + 1 plt.figure(figsize=(32, 32)) plt.subplots_adjust(wspace=0.2, hspace=0.7) for index in range(len(x_test)): plt.subplot(row, col, index+1) plt.imshow(x_test[index].reshape(features.shape[1], features.shape[2], features.shape[3]), cmap=plt.get_cmap('gray')) # 正解の場合は青、不正解の場合は赤 predict_label = predict_result[index] teach_label = y_test[index] if predict_label == teach_label: color = 'blue' else: color = 'red' result = '' if predict_label == 0: result = 'dog' elif predict_label == 1: result = 'cat' elif predict_label == 2: result = 'Squirrel' plt.xlabel("{}".format(result), color=color, fontsize=20) if __name__ == '__main__': fn_start_RandomForest() |
どうでしょうか?このように、sklearnを用いることで、様々なデータに対して機械学習を適用できますし、精度を高めるために、パラメータの調整等、様々試すことができますので是非活用してみましょう。