キュウゾウ
・機械学習の画像認識を使って超サイヤ人を判別するプログラムを書いてみた
・CIFAR-10で使われているCNNや学習データの水増し、転移学習にも挑戦
・最高68%の確率で超サイヤ人を判定できるようになった!
前回の「AIは超サイヤ人の各形態を判別できるか?」では、自分でプログラムを1行も書くことなく超サイヤ人の判別を試みました。
プログラミングしないでも実行までできるという意味では確かにお手軽でしたが、その判別の精度は低く、機械学習だとどういう画像が判別しやすい(しにくい)などの傾向すらつかむことができませんでした。
キュウゾウ個人的にはこの「機械学習の得手不得手の傾向すらつかめなかったこと」がとても悔しくて、今回はもう少し高い精度が出るようにプログラミングにチャレンジしてみることにしたのです。
とは言え、私も機械学習初心者なので自力でプログラミングできるわけがありません。
ですが、Udemyの動画を参考書代わりに使ったらとても簡単にできてしまいました!
(1)CIFAR-10の画像分類で使われているCNNを使って超サイヤ人判別機をプログラミング
機械学習を勉強し始めると、まず「MNIST」という数字の画像データを使って実装方法を学ぶことが多いと思います。
そして、その次によく出てくるのが「CIFAR-10」ではないでしょうか。
MNISTが数字画像だったの対して、CIFAR-10は飛行機や自動車、猫や馬などのよりリアルな画像がメインとなります。
今回は「超サイヤ人の判別機」なので、画像的により近いのはMNISTよりこちらのCIFAR-10だと思います。
CIFAR-10も定番中の定番なので、この画像データセットを使った画像分類のプログラムは、既にKeras(cifar10_cnn.py)等で公開されていて誰でも真似することができるようになっています!
ですが、Kerasの該当ページを見てみると、初心者にはまだ実装が難しいレベルなのが現実です。
そこで「UdemyにCIFAR-10を使って画像判定アプリを開発している動画」があるので、今回はその動画をお手本にしつつ、少しだけ応用して「超サイヤ人判別機2」を作ってみました!
参考書代わりに使ったUdemyの動画
今回、お手本に使った動画はUdemyにある井上 博樹先生の
【画像判定AIアプリ開発・パート1】TensorFlow・Python・Flaskで作る画像判定AIアプリ開発入門
です。
私も井上先生のことはUdemyで知ったのですが、人気動画を何本も出している実績のある先生ということはすぐにわかりました。
確かに初心者でも何とか食らいついていける難易度の内容にしてくれていて、なのに内容がショボくない!
私が色々な教材で機械学習を勉強していて、現在進行系で最も役立っているのが井上先生の動画と言っても過言ではないです。
今回の動画の内容は、リンク先のUdemyのページからも確認できます。
必要な部分だけに絞ってまとめると、
- FlickrのAPIからサル、イノシシ、カラスの画像をPythonで取得
- cifar10_cnn.pyで使われているCNN(畳み込みニューラルネットワーク)を定義
- 学習したモデルに、例えば新たなサル画像を渡して、きちんとサルと判別できるか?を確認
初心者の私は、まずは動画の内容通りに画像判定プログラムを実装して、その後に超サイヤ人判別機版としてアレンジを行いました。
アレンジした内容と具体的なコード
サル、イノシシ、カラスの3分類から、超サイヤ人の各形態4分類に変更
動画では「サル、イノシシ、カラス」の3種類の画像データを学習させていますが、今回の超サイヤ人別機では、
- 超サイヤ人(first)
- 超サイヤ人3(third)
- 超サイヤ人ゴッド(god)
- 超サイヤ人ゴッド超サイヤ人(ssgss)
3分類から4分類への変更は、まず各pyファイルの最初に定義しているclassesを、
classes = ['monkey', 'boar', 'crow']
⇒
classes = ['first', 'third', 'god', 'ssgss']
firstやssgssは私が超サイヤ人を分類する為に作った要素なので、任意で変更してください!
続いて、animal_cnn.pyでCNNモデルを定義している箇所を、
model.add(Dense(3))
⇒
model.add(Dense(4))
変更はたったこれだけなので、いかに「超サイヤ人判別機」のような◎◎判別機が簡単につくれるかおわかり頂けるかと思います。
複数の画像を一気に判定する方法
ここは必須の変更ではありませんので参考までに。
動画内ではテスト用に準備した画像を1枚1枚手打ちで入力して、機械学習が「サル・イノシシ・カラス」のどれと判断するかを確認していました。
そのやり方だと、何十枚何百枚もの画像判定をしたい場合に大変になってきます。
私の場合、学習データとは別に用意した超サイヤ人の各形態ごとの画像を22枚用意して、どの超サイヤ人だと判定するかを確認したかったので手打ちだと少しだけ大変です。
そこで、動画内のpredict.pyを下記のように変更しました。
for i in range(len(X)):
result = model.predict([X])[i]
predicted = result.argmax()
percentage = int(result[predicted] * 100)
print('{0}⇒{1}({2} %)'.format(Y[i], classes[predicted], percentage))
こうすると、
のように画像を1枚ずつ手打ち入力必要がなく、フォルダに入っている画像を一気に判定できるのでとても楽です!
実行結果
テスト用の画像を機械学習に判別させてみると、上の画像に見える範囲だと、
- 1.jpg:超サイヤ人3(third)⇒不正解
- 2.jpg:超サイヤ人3(third)⇒不正解
- 3.jpg:超サイヤ人3(third)⇒正解
- 4.jpg:超サイヤ人3(third)⇒正解
- 15.jpg:超サイヤ人ゴッド超サイヤ人(ssgss)⇒正解
- 16.jpg:超サイヤ人ゴッド超サイヤ人(ssgss)⇒正解
- 17.jpg:超サイヤ人ゴッド(god)⇒正解
- 18.jpg:超サイヤ人ゴッド超サイヤ人(ssgss)⇒正解
と割と良く判定できていて、トータルでは「68%」の精度という結果になりました!
前回よりもだいぶまともな結果になったので、超サイヤ人判別機としてはひとまず合格点を与えられると思います!
キュウゾウ
ここからは応用編として「学習データの水増し」と「転移学習」にもチャレンジして、上の精度が上がるかどうかを試してみます。
(2)学習データの水増しをして判別精度が高まるか試してみる
続いて、学習データを水増しすることにチャレンジしていきます!
「AIにはデータが大量に必要」と聞くことが多いと思いますが、それはそのまま「機械学習にはデータが大量に必要」と読み替えることができます。
例えば、今回で言うと、超サイヤ人の各形態の画像を大量に機械学習することによって、テスト用に準備した画像がどの形態の画像か判断できるようになります。
この際、学習用の画像をたくさん用意できないことがあります。
今回で言うと、超サイヤ人の画像をネットで集めたのですが、各形態100枚ずつ集めることさえとても大変なことだとわかりました。
そういった時に試みるのが「学習データ(画像)の水増し」です。
1枚の画像を斜めにしたり反転させたりして、10枚くらいに増やすわけですね。
学習データを水増しする方法も、先ほどの井上先生の同じ動画で見ることができます。
【画像判定AIアプリ開発・パート1】TensorFlow・Python・Flaskで作る画像判定AIアプリ開発入門
データの水増しを行った結果
水増しする方法は動画の内容の通りで、アレンジした箇所はないのでここでの説明は省かせてもらいます。
それで水増しをした結果はどうだったかというと、「64%」と先ほどより少し精度が下がってしまいました。
使った画像は先ほどと全く同じもので、今回は水増しを行った分だけ「学習データ」的には大量に増えたにも関わらずです。
「なぜこういう結果になったのか?」は現時点ではわからないので、今後の課題にしたいと思います。
ひとまず学習データを水増しする為の一つの手法は覚えることができました!
(3)転移学習にもチャレンジ!
「超サイヤ人判別機2」の精度を上げる為に転移学習にもチャレンジしてみました。
転移学習を勉強する為に、井上先生の動画の続編である、
【画像判定AIアプリ開発・パート2】Django・TensorFlow・転移学習による高精度AI アプリ開発
を使わせてもらいました!
転移学習とは?については、ネットもしくは動画でご確認ください!
また超サイヤ人判別機にする為にカスタマイズした箇所は、これまで説明した内容と同じなので割愛します。
転移学習した結果は?
転移学習した結果は、最初の精度と同じ「68%」でした。
水増しと同じく「おーすげー」という結果にはならず、このあたりの原因がわかるように勉強を進めていきたいと思います!
画像認識を使った判別機作成はひとまず終了。今後は?
今回の実験で、ひとまず機械学習の画像認識の勉強はひとまず終了にしたいと思います。
前回の「AIは超サイヤ人の各形態を判別できるか?」では、機械学習の傾向すらつかめませんでしたが、今回は「このテスト画像なら正解できそうだな」という傾向をきちんとつかむことができたからです。
例えば、超サイヤ人と超サイヤ人3の区別は難しかったが、超サイヤ人ゴッド(赤髪)と超サイヤ人ゴッド超サイヤ人(青髪)は、色が明確に異なるので高い精度で判別できることがわかったなどです。
さらに、私としても今回の勉強を通して、機械学習の初歩である画像認識についてはだいぶ理解できるようになりました。
具体的には、VGG16やCIFAR-10の畳み込みニューラルネットワークのモデルを使って、「超サイヤ人判別機アプリ」のようなサービスを実装可能になりました。
おそらく、脱初心者はできたと思います!
今後は、興味の出てきたGANに移っていく予定です。