画像分類タスクの精度があまり良くないかもしれません。
何かできることありませんか?
このような疑問にお答えします。
次元圧縮をしてみましょう。次元圧縮とは、データの次元数を圧縮することです。
機械学習において、データを扱うことを考えたとき、多くの場合、そのデータは高次元となります。
このとき、次元圧縮をすることで、そのデータが持つ特徴を保持したまま、それより少ない次元の特徴へ落とし込むことができます。
下記のページを参考にさせていただきました。
- https://blog.albert2005.co.jp/2015/12/02/tsne/
- https://qiita.com/stfate/items/8988d01aad9596f9d586
- https://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html
t-SNEについて
次元圧縮の方法は、様々提案されていますが、今回はt-SNE(t-distributed Stochastic Neighbor Embedding)を使用します。
t-SNEとは、高次元データの可視化のため2次元または3次元の低次元空間へ埋め込みに最適な非線形次元削減手法である。具体的には、高次元のデータ集合を2次元または3次元へ配置する際に、高い確率で類似した集合が近傍に、異なる集合が遠方となるように対応付ける。 (wikipediaより抜粋)
t-SNEによる次元圧縮方法については、以下のページがわかりやすいように思います。
- https://blog.albert2005.co.jp/2015/12/02/tsne/
- https://qiita.com/stfate/items/8988d01aad9596f9d586
Pythonライブラリsklearnのt-SNEを使用します。
ライブラリの仕様は、下記になります。
- https://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html
画像データの分類手法、およびデータについては下記の記事を参照ください。
ソースコードは、以下になります。
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 |
# 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.manifold import TSNE def fn_compress_dimension(feature): tsne = TSNE(n_components=2) return tsne.fit_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) # RGB形式の64*64形式の画像を変換 row=画像数, col=縦pixel数 * 横pixel数 * RGBチャネル(=3) 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='k-means++', max_iter=200, 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を用いることで、様々なデータに対して機械学習を適用できますし、精度を高めるために、分類手法を変更することやパラメータの調整、圧縮数、学習回数等を簡単に試すことができます。是非試してみてはいかがでしょうか。