機械学習による火成岩の判定②

#開発方針
###①	機械学習でプログラミング
機械学習でよく使われる、Pythonというプログラミング言語を使って作ってみる。
ちょっと難易度が上がるが、機械学習で分析する。機械学習のデータ画像を10枚ぐらいダウンロードして機械学習させる。

###②	完成したら、アプリにする。
もしできたらAndroidなどのスマホでも動かしてみたい。

###③	機械学習を使わないプログラムでも挑戦してみる
機械学習を使わない方法でも、岩石の色から種類を判別するプログラムを作る。色の特徴から、判別する方法で、画像を分別させてみる。
開発の過程
①	機械学習で判定するプログラム開発
開発日数――＞５日間
###（１）画像収集
Google 画像検索で1つの項目につき10枚の写真を集めた。その写真を明るさや大きさを調節してーごとに分別。googleのＡＰＩを使ってダウンロードしてみたしかし、制限がありなかなか難しかった。結局、手動でダウンロードすることにした。
	
（２）インポートエラー
機械学習の環境を構築してみたがなかなかうまくいかず。このようなエラーばかりで4時間ぐらい無駄にしました。
ImportError: DLL load failed: ダイナミック リンク ライブラリ (DLL) 初期化ルーチンの実行に失敗しました。
　このエラーは、ダイナミックリンクライブラリというアプリに使われる、アプリなどに使われているプログラムファイルで、よく読むと初期化に失敗したことが書かれていた。調べたら、tensoflow1.7からaｖｘ命令という特殊な命令が使われ、Intel celeron、 Intel　PentiumとIntel atomなどの低価格CPUはできないことが分かった。バージョンをTensorflow１.7にすることで、実行できることがインターネットのサイトに書かれてあり、Tensorflow1.7にダウングレードしてみた。しかし、kerasはTensorflowが１.7だとkeras側が対応していないことがわかった。仕方なく別のパソコンでテストした。

###（３）kerasによる開発
kerasというTensorflowの拡張機能を使い、機械学習を始めた。しかし、参考にしたサイトのプログラムがとてもバグが多く、バグ修復に時間がかかった。
いろんなサイトを使って修正方法を調べてみた
機械学習が終わって検証実験してみた。しかし、玄武岩としか答えを出さなくなくなり、岩石の画像をもう一回、ダウンロードし、画像をトリミングした。

###（４）もう一回作り直し
画像フォルダーを整理していたが、間違えて上書きしてしまい、機械学習のプログラムを紛失してしまった。結局、最初から作る羽目になってしまった。
前回と同じく機械学習のプログラムを作り直し、検証実験し、システムは完成した。

###（５）機械学習で判別できるのか、専門家に質問した
画像を整理しても、回答が玄武岩しか出てこなくたったため、やはり機械学習では正答率を上げるのはなかなか難しいのかもしれない。そこで、資料を見た専門家である、目代邦康先生にフェイスブックで質問した。

質問：「火成岩は、色や組織で正確に判別できず、二酸化ケイ素や採取場所で決まるのではないか、だからAIではなかなか難しいのではないか。」
回答：「予想の通り，火成岩は肉眼で判別はある程度できますが，基本的には化学的な性質（二酸化珪素の含有量）できまりますので，写真ベースの分類だと正答率3～5割というのは，妥当なところのようにも思います．」

つまり、火成岩は色や組織などでは判別不可能で、判別方法は二酸化ケイ素の量だった。色や組織よりも、二酸化ケイ素の含有量が火成岩の分類に関係していることが分かった。８０％～100%の正答率は、難しいことがわかったが、できるだけあげてゆけるように工夫することにした。

###（６）正答率をあげる
まず、正答率を上げるテストで２種類の火成岩を選んで（例えば、流紋岩と花崗岩、とか）、画像を判別したところ、９０％ぐらいの正答率にあがった。次に、6種類の火成岩に増やしてみたが、正答率は30％～60％に下がってしまった。
多分、学習不足という現象が発生していると思った。学習不足というのは、モデルがテストデータに対してまだ改善の余地がある場合に発生する。学習不足の原因は様々あり、モデルが十分強力でない、正則化のしすぎだとか、単に訓練時間が短すぎるといった理由などある。学習不足は、訓練用データの中の関連したパターンを学習しきっていないと思われる。
そこで、学習回数を30回ぐらいに増やした。９０％ぐらいまで精度が上がった。学習回数が重要だということが分かった。

###（７）過学習がおこる
しかし、検証時の正答率があまり上がっていなかった。原因は、画像枚数が少なくて学習回数が多い時に発生する「過学習」（過剰適合や過適合ともいう）というものだった。細かい画像固有の情報まで学習させる（例えば影や模様の形）現象がおきた。
過学習が起きると、学習データ固有の情報が入っているため、未知のデータではなかなか判別がなかなかうまくいかないらしい。
この対策として、まず、画像の枚数をもっと増やすことにした。
次に、正則化というものも使ってみた。正則化とは、モデルに保存される情報の量とタイプに制約を課すもので、重要なとこしか学習しない方法で過学習を抑制する。
あと1つ、早期打ち切りという方法も使ってみた。早期打ち切りというのは、過学習を始める兆候があったら、その時点で学習データを保存して学習を終了することである。
過学習は、あまり画像が似ていたり、特徴がない時にも発生することがあるらしく、もしかしたら、学習データにあまり特徴がないため過学習が発生しているのかもしれない。
やっぱり学習不足や過学習させないために、機械学習には調節が必要だと分かりました。

結果　学習データは完成した。


###②	Android化に挑戦
開発日数　6日

###（１）エラーが多い
Androidアプリ作成開始。Kerasの学習データｈｄｆ５という拡張子をTensorflowの学習データpbという拡張子に変換しようとしたが、バグが多く修正が難しい。

####（２）ネットで質問する
Terataiというサイトでバグを直す方法を質問した。しかし、なかなか回答が返ってこなくてできなかった。質問が難しかったからだと思う。					
https://teratail.com/questions/268059

###（３）tflileに形式変換
Pbファイルを変換するのではなくTensorflowのAndroidやiosなどでよく使われるtflileという形式変換することにした。そしたらうまくいった。
TensorflowのAndroidサンプル専用のサンプルを使って作ってみたが、参考にしているサイトの内容が1年前の内容だったので、どこをどうすればできるのかわからず結局できなかった。

結果　できなかった。

###③	レンタルサーバでウェブブラウザに変更
開発日数３日

方向転換してAndroidで動かすのではなくウェブブラウザなどで動くように改造した。

（１）ウェブカメラを使う
ウェブカメラを使ってウェブブラウザで動かすことに成功した。しかし、とても正答率は低かった。
理由は、ウェブカメラだと、岩石の周りの風景まで判定されるため、うまく分類できないと思った。




試作
https://miyadai.sakura.ne.jp/tensorflow1/ 


###（２）画像取り込みにする	
ウェブカメラを使うのではなく普通に画像で判定することにしたので、正答率が上がった。
画像取り込みは、ウェブカメラと違って写真の明るさを補正しているからだと思われる。
サーバーを借りてインターネットに公開した。

結果　完成した。

試作
https://miyadai.sakura.ne.jp/tensorflow2/