画像分類タスクの精度があまり良くないかもしれません。
何かできることありませんか?
このような疑問にお答えします。
次元圧縮をしてみましょう。
次元圧縮とは、データの次元数を圧縮することです。
機械学習において、データを扱うことを考えたとき、多くの場合、そのデータは高次元となります。
このとき、次元圧縮をすることで、そのデータが持つ特徴を保持したまま、それより少ない次元の特徴へ落とし込むことができます。
次元圧縮の方法は、様々提案されていますが、
今回はPCA(Principal Component Analysis)を使用します。
PCAでは、データの分散に基づき次元の重要度を算出し、データの分散が最大になるように特徴量を抽出しつつ次元圧縮を行うことができます。
分散が最大になるように特徴抽出することから、データ間の差(ばらつき)を最大にした特徴量が利用できるため、分類タスク等の学習時に有効に作用すると考えられます。
下記の記事に引き続き、Pythonライブラリsklearnを用います。
画像データの分類手法、およびデータについても下記の記事を参照ください。
ソースコードは、以下になります。
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 |
# coding: utf-8 from PIL import Image import cv2 import glob import matplotlib.pyplot as plt import numpy as np from sklearn.cluster import KMeans from sklearn.decomposition import PCA def fn_compress_dimension(feature): pca = PCA(n_components=int(2)) pca.fit(feature) return pca.transform(feature) def fn_image_convert(dir_name): files = glob.glob(dir_name + '/*') # print(files) col = 10 row = int(len(files) / col) + 1 cols = 64 rows = 64 dpis = 100 fig = plt.figure(figsize=(cols, rows)) index = 1 for f in files: try: img = Image.open(f) img_resize = img.resize((64, 64)) plt.subplot(row, col, index) plt.imshow(img_resize, cmap='gray') index += 1 except OSError as e: return features = np.array([cv2.cvtColor(cv2.resize(cv2.imread(f), (64, 64), cv2.INTER_CUBIC), cv2.COLOR_BGR2RGB) for f in files]) print(features.shape) train_data = features.reshape(features.shape[0], features.shape[1]*features.shape[2]*features.shape[3]).astype('float32') / 255.0 #print(train_data) train_data = fn_compress_dimension(train_data) print(train_data.shape) # モデル定義 model = KMeans(n_clusters=9, init='random', max_iter=100, random_state=0) y_res = model.fit_predict(train_data) # 結果出力 fig = plt.figure(figsize=(cols, rows)) index = 1 for label, p in zip(y_res, features): plt.subplot(row, col, index) plt.imshow(p, cmap='gray') plt.xlabel("cluster={}".format(label), fontsize=30) index += 1 if __name__ == '__main__': dir_name = input('input dir->') fn_image_convert(dir_name) |
各画像の次元数が2となるように次元を圧縮してみます。
出力結果は、以下になります。
前回の記事で得られた次元圧縮なしでの結果よりも、次元圧縮後のほうが画像の誤分類は少ないように思います。それでも、誤分類はありますので、分類手法を変更することやパラメータの調整、
圧縮数、学習回数等を工夫するといいのかもしれません。
このように、sklearnを用いることで、様々なデータに対して機械学習を適用できますし、
精度を高めるために様々試すことができますので是非活用してみましょう。