1. タスクの説明と画像分類プログラムの概要
このセクションでは機械学習技術を用いて下のような画像を「文章」「図表」「風景画像」の3カテゴリに分類します。
今回用いる機械学習アルゴリズムは以下の2つです。どちらも実装にはScikit-learnというPython用のシンプルなデータ分析ライブラリを用いています。
-
-
- ・PCA(主成分分析)
- ・K-means clustering
-
環境構築にはAnacondaというディストリビューションを用い、実際に画像分類のプログラムをAnacondaに含まれているJupyter notebookという環境の上で解説とともにStep by stepで実行していきます。
2.Anacondaのインストール
まずはセットアップとしてAnacondaという科学計算(データサイエンス含む)でよく用いられるディストリビューションをインストールします。Python本体とPythonでよく用いられるライブラリがほぼ全てセットになっていて、面倒な環境構築を簡略化できるので多くの人に利用されています。
2.1: インストーラのダウンロード
以下のリンクからLinux用のAnacondaインストーラ(Python 3版)をダウンロードしてください。
Downloadを押した後にメールアドレスを聞かれるかと思いますが、スターターガイドが欲しい場合以外はNo Thanksでスキップして構いません。
2.2: インストーラの実行
ターミナル(端末)を起動し、ダウンロードしたファイルを実行します。
1 |
$ bash ~/Downloads/Anaconda3-4.4.0-Linux-x86_64.sh |
*ファイル名中の数字はAnacondaのバージョンによって異なります。
インストーラが起動するので、ライセンスを表示するためにまずEnterキーを押します。
ラインスが表示されるかと思いますのでSpaceキーでスクロールしていきます。
ライセンスに同意するか尋ねられるのでyesと入力しライセンスに同意します。
インストール場所を聞かれるかと思いますが、基本はデフォルトで大丈夫なのでEnterキーを押します。
最後に.bashrc の環境変数(PATH)にAnacondaの位置を追加するか聞かれるので、yesと入力します。
2.3: 正しくインストールされているかの確認
以下のコマンドを実行し、バージョンが表示されることを確認してみてください。
1 |
$ conda -V |
バージョンが正しく表示されればAnacondaのインストールは完了です。
3. 画像分類プログラムの実行
ここではJupyter Notebook内でどのようなコードを書いているかの中身を先に紹介します。実際のコードの実行は画像とnotebookのダウンロード後にJupyter notebook環境上で行なってください。
実際にプログラミング体験を行っていただくにはセクション4で用意しているJupyterNotebookをダウンロードしてください。
今回の画像分類のプログラムでは
- 1. 画像データを機械学習アルゴリズムが適用できる形式のデータセットに変換する
- 2. PCAを用いてそのデータセットの次元を削減して扱いやすくする
- 3. K-means clusteringでクラスタリング(グループ分け)をする
という流れを3回繰り返して画像を分類していきます。
理想は1回のクラスタリングで上の3グループに分けることですが、今回のような教師なしの分類でそれを行うのは至難の業です。ですので、ここでは3回に分けて分類(ラベル付け)をすることで精度を上げていきます。なお今回用いる2つの機械学習アルゴリズムの説明はプログラム中の実際に使用するところで行います。
プログラムのOutline
3.1: 必要なライブラリ、モジュールのインポート
また、再現性のための乱数のseed等も適宜設定していきます。
1 2 3 4 5 6 7 8 9 10 11 |
import os import glob from PIL import Image import numpy as np import matplotlib.pyplot as plt %matplotlib inline from sklearn.decomposition import IncrementalPCA from sklearn.cluster import KMeans np.random.seed(5) |
3.2: 何枚かの画像とそのサイズの表示
3.2-1: 画像へのパスのリスト(img_paths)をつくる
ここでは、今回分類する画像のパスを取得し、リストimg_
画像は全部で868枚あります。
1 2 3 4 5 6 |
img_paths = [] for file in glob.glob("./1*/*.jpg"): img_paths.append(file) print("Image number:", len(img_paths)) print("Image list make done.") |
3.2-2: 画像とそのサイズを表示する
下のコードを実行すると、画像とそのサイズ(1232, 1754)が確認できると思います。
1 2 3 4 5 |
for i in img_paths[::124]: img = Image.open(i) print(img.size) plt.figure() plt.imshow(np.asarray(img)) |
3.3: 1回目の分類(データセットづくり → PCA → K-means clustering)
それでは1回目の分類をしていきます。
3.3-1: 画像データを機械学習用データセットへ変換する
ここではそれぞれの画像データをnumpy(
なお画像の枚数868枚はlaptop + Jupyter notebookという環境には少し多すぎるので、
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 |
plt.close("all") img_paths = img_paths[:600] print(len(img_paths)) def img_to_matrix(img): img_array = np.asarray(img) return img_array def flatten_img(img_array): s = img_array.shape[0] * img_array.shape[1] * img_array.shape[2] img_width = img_array.reshape(1, s) return img_width[0] dataset = [] for i in img_paths: img = Image.open(i) img = img.resize((int(1232/6), int(1754/6)), Image.BICUBIC) img = img_to_matrix(img) img = flatten_img(img) dataset.append(img) dataset = np.array(dataset) print(dataset.shape) print("Dataset make done.") |
3.3-2: データセットにPCA(主成分分析)を適用して次元を削減する
PCA(主成分分析)とはデータの重要な次元を見つけだし、
それでは3.3-1で作成したデータセットにPCAを適用してい
今回はデータを179580次元から100次元まで次元削減しま
なおここではbatch処理というものを行い全体のPCAの計算
1 2 3 4 5 6 7 8 9 10 |
n = dataset.shape[0] batch_size = 180 ipca = IncrementalPCA(n_components=100) for i in range(n//batch_size): r_dataset = ipca.partial_fit(dataset[i*batch_size:(i+1)*batch_size]) r_dataset = ipca.transform(dataset) print(r_dataset.shape) print("PCA done.") |
3.3-3: K-means clustering でクラスタリング
K-means clusteringとは似たデータ同士を少しずつ集めてクラス
それでは最後のステップとして、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# K-means clustering n_clusters = 4 kmeans = KMeans(n_clusters=n_clusters, random_state=5).fit(r_dataset) labels = kmeans.labels_ print("K-means clustering done.") for i in range(n_clusters): label = np.where(labels==i)[0] # Image placing if not os.path.exists("label"+str(i)): os.makedirs("label"+str(i)) for j in label: img = Image.open(img_paths[j]) fname = img_paths[j].split('/')[-1] img.save("label"+str(i)+"/" + fname) print("Image placing done.") |
グループ分けが終わると、label0に割り当てられた画像は~
label1、
ファイル

files
文章と図表と風景画像とが混ざったままのグループ

label0
風景画像グループ

label1
文章グループ

label2
図表グループ

label3
データの構造から、
教師なしの分類なので、自動的にどのグループがどの画像カテゴリかまでを決定することはできませんが、複数のカテゴリの画像がまだ混じってしまっているlabel0を除けば、label1は風景画像グループ、label2は文章グループ、label3は図表グループと分類結果から目で見てすぐにラベル付けをすることができます。
3.4: 2回目の分類(データセットづくり → PCA → K-means clustering)
1回目の分類では、
そこで、再度このグループの画像のみ分類にかけます。
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 |
# このダブルクオーテーションの間にまだ分類の不十分なグループのlabel名を入れてください # 例 unclassified_label = "label0" unclassified_label = "label0" # Image path list make img_paths = [] for root, dirs, files in os.walk("./" + unclassified_label + "/"): for file in files: if file.endswith(".jpg"): img_paths.append(os.path.join(root, file)) print(len(img_paths)) print("Image list make done.") # Dataset make dataset = [] for i in img_paths: img = Image.open(i) img = img.resize((int(1232/6), int(1754/6)), Image.BICUBIC) img = img_to_matrix(img) img = flatten_img(img) dataset.append(img) dataset = np.array(dataset) print(dataset.shape) print("Dataset make done.") # PCA n = dataset.shape[0] batch_size = 180 ipca = IncrementalPCA(n_components=100) for i in range(n//batch_size): r_dataset = ipca.partial_fit(dataset[i*batch_size:(i+1)*batch_size]) r_dataset = ipca.transform(dataset) print(r_dataset.shape) print("PCA done.") # K-means clustering n_clusters = 6 kmeans = KMeans(n_clusters=n_clusters, random_state=3).fit(r_dataset) labels = kmeans.labels_ print("K-means clustering done.") for i in range(n_clusters): label = np.where(labels==i)[0] # Image placing if not os.path.exists(unclassified_label+"/label"+str(i)): os.makedirs(unclassified_label+"/label"+str(i)) for j in label: img = Image.open(img_paths[j]) fname = img_paths[j].split('/')[-1] img.save(unclassified_label+"/label"+str(i)+"/" + fname) print("Image placing done.") |
終わったら1回目と同様に結果を確認してみましょう。~/
3.5: 3回目の分類(データセットづくり → PCA → K-means clustering)
2回目の分類の結果はいかがだったでしょうか。まだ文章と図表が混じったままのlabel2のグループ以外は先
ここでも多少の誤分類はありますが) そこで2回目と同様に最終的な分類結果の精度を上げるために再度このグループに分類をかけます。 今回は4グループに分類していきます。
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 |
# このダブルクオーテーションの間にまだ分類の不十分なグループのlabel名を入れてください # 例 unclassified_label2 = "label0" unclassified_label2 = "label4" # Image path list make img_paths = [] for root, dirs, files in os.walk("./"+unclassified_label+"/"+unclassified_label2+"/"): for file in files: if file.endswith(".jpg"): img_paths.append(os.path.join(root, file)) print(len(img_paths)) print("Image list make done.") # Dataset make dataset = [] for i in img_paths: img = Image.open(i) img = img.resize((int(1232/6), int(1754/6)), Image.BICUBIC) img = img_to_matrix(img) img = flatten_img(img) dataset.append(img) dataset = np.array(dataset) print(dataset.shape) print("Dataset make done.") # PCA n = dataset.shape[0] batch_size = n ipca = IncrementalPCA(n_components=100) for i in range(n//batch_size): r_dataset = ipca.partial_fit(dataset[i*batch_size:(i+1)*batch_size]) r_dataset = ipca.transform(dataset) print(r_dataset.shape) print("PCA done.") # K-means clustering n_clusters = 6 kmeans = KMeans(n_clusters=n_clusters, random_state=0).fit(r_dataset) labels = kmeans.labels_ print("K-means clustering done.") for i in range(n_clusters): label = np.where(labels==i)[0] # Image placing if not os.path.exists(unclassified_label+"/"+unclassified_label2+"/label"+str(i)): os.makedirs(unclassified_label+"/"+unclassified_label2+"/label"+str(i)) for j in label: img = Image.open(img_paths[j]) fname = img_paths[j].split('/')[-1] img.save(unclassified_label+"/"+unclassified_label2+"/label"+str(i)+"/" + fname) print("Image placing done.") |
同じくFilesで結果を見てみましょう。
まだ分類されきっていないと思うグループにさらに分類をかけてい
以上で本チュートリアルを終わります。
4. 画像とJupyter Notebook(Image_classifier.ipynb)のダウンロード
実際にプログラムを動かす際は、画像とnotebookをダウンロードして、Jupyter notebook環境上で実行を行なってください。
以下のリンクからダウンロードできます。
ダウンロードしたら、ZIPファイルをダブルクリックして解凍してください。
ダウンロードが終わったら、そのフォルダをDocumentsディレクトリ以下に置きましょう。
1 |
$ mv ~/Downloads/MLImageClassifier ~/Documents/ |
そしてその場所まで移動します。
1 |
$ cd ~/Documents/MLImageClassifier |
ダウンロードしたjupyter notebookを開いてみましょう。
1 |
$ jupyter notebook Image_classifier.ipynb |
なおJupyter notebookの使い方は以下を見ると良いかと思います。
Notebook内のセルの実行の仕方やJupyter notebook自体の終了の仕方など、実際に画像分類をJupyter notebook上で進める前に確認しておきましょう。
先ほどのコマンドを実行すると、ブラウザが開いて以下のような画面が出てくるかと思います。
後はこのnotebook内のコードを少しずつ実行していき、画像の分類を進めていってください。
あなたも、Avintonでこのような最先端技術を習得し活用してみませんか?
社員の成長を導きながら、AIやビッグデータなどの最先端技術をプロジェクトに活用していくことが私たちのビジョンです。Avintonの充実した技術研修でスキルアップを図り、あなたのキャリア目標を一緒に達成しませんか?