HIROBIRO

HIROBIRO

金銭的・精神的自由を目指すブログ。

【6章後半・応用編】PythonによるAI・機械学習・深層学習アプリのつくり方


「PythonによるAI・機械学習・深層学習アプリのつくり方」の第6章の後半についてまとめます。
6章は本の最終章なのですが、応用編として機械学習をWebアプリや業務システムに組み込む方法について紹介されています。
6-3までは前回の記事で書いたため、この記事は6-4からです。

はじめに

この本に載っているコードは全てGitHubで公開されているため、この記事では具体的なコードは書きません。以下を参照してください。
https://github.com/kujirahand/book-mlearn-gyomu


前回の記事はこちらです。
www.hirobiro-life.com


6-4 Webで使える文章ジャンル判定アプリを作ろう

前回の6-3で作ったジャンル判定ツールをWebシステムに組み込みます。
本来はWebサーバーと機械学習サーバーの二つに分け、機械学習サーバーを起動しておき、Webアプリ側から機械学習サーバーに問い合わせる形を取るのが時間がかからず効率が良いです。
ただ今回は簡易な方法を取ってWebサーバーに機械学習システムを持たせる方法を取ります。


ジャンル判定を行うAPIを含めたWebサーバー側のプログラムがtm_server.pyになります。
このプログラムではWebサーバーの作成にフレームワークのFlaskを利用します。


tm_server.pyではサーバーを起動し、前節の6-3で作ったmy_text.pyのジャンル判定プログラムをモジュールとして利用します。
ルート「/」にアクセスしたときはindex.htmlを呼び出して以下の画面になります。


f:id:hirokun1735:20181126212256j:plain



テキストボックスにジャンル判定したい文章を書いてボタンを押すと、APIサーバーに送信して結果を表示します。


f:id:hirokun1735:20181126212951j:plain


6-5 機械学習にデータベース(RDBMS)を利用しよう

ここではすでにデータベースに入っている業務データが存在していると想定し、そのデータを取得して機械学習を行うシステムを構築します。
身長と体重のデータをデータベースに保存し、その値を元に機械学習して健康状態を診断するシステムです。


今回用いるデータベースはPythonの標準ライブラリであるSQLiteを使用します。
SQLを用いてデータベースの操作が可能で、init_db.pyでデータベースを作成、insert_db.pyでデータを追加します。
このデータベースには顧客ID、身長、体重、体型(BMIを元に0~5の値で表記)のデータが入ります。


f:id:hirokun1735:20181126215737j:plain


上図はデータベース内のデータを確認したもので、左から顧客ID、身長、体重、体型となっています。
機械学習によって身長、体重の値を元に体型を導きます。
BMIは身長と体重から計算できる値ですが、ここでは機械学習のMLP(多層パーセプトロン)モデルから求めます。


100件程度の学習データでは答えを間違えることが多く、3割程度の正解率ですが、1万件以上のデータを使って学習すると99%の精度で正解します。
ちなみに以下は身長160cm、体重50kgの普通体重のデータで健康診断した結果です。
当然正解です。


f:id:hirokun1735:20181126220949j:plain


6-6 料理の写真からカロリーを調べるツールを作ろう

画像分析を利用し、料理の写真からカロリーを計算するプログラムです。
写真共有サイトのFlickrから料理写真をダウンロードし、さらに画像の水増しも行います。
ただし、判定する料理は寿司、サラダ、麻婆豆腐の3種類のみです。

画像データの取得

Flickr APIを使用するにはYahoo.comのアカウントを作成したうえでFlickr APIのページにアクセスし、「Key」と「Secret」という2つの文字列を取得します。
下記のリンク先はFlickrの開発者向けページです。画面左上にある「Create an App」をクリックするとキー取得の画面に進みます。

Flickr Services


以下のコマンドを実行してFlickr APIに必要なモジュールをインストールします。

$ pip install flickrapi


download.pyを実行するとFlickrで写真を検索してダウンロードします。
コード内にAPIキーとシークレットを設定する箇所があるため、そこは自分で取得したキーに書き換えます。
「マグロ寿司」、「サラダ」、「麻婆豆腐」のキーワードで検索した画像が300枚ずつダウンロードされます。

画像データのスクリーニング

download.pyを実行する前にあらかじめimageという名前のフォルダを作っておきましょう。
このプログラムではimageというフォルダの中にsushi, salad, tofuというサブフォルダを作ってその中に画像を保存します。
imageフォルダがないと下記のエラーが出ます。

FileNotFoundError: [Errno 2] No such file or directory: './image/sushi'


ダウンロードしたマグロ寿司の画像の一部です。
全体的に赤っぽいですが、一部マグロ寿司と関係の無い写真が混ざっています。


f:id:hirokun1735:20181127224605j:plain


関係ない写真は自分で削除します。
300枚ダウンロードした中から100枚を選び出します。
サラダや麻婆豆腐の画像も同様に100枚選びます。


f:id:hirokun1735:20181127225041j:plain


read_image.pyによって画像データをNumPy形式に変換します。
各画像を32ピクセルにリサイズし、imageディレクトリにphotos.npzというNumPy形式のファイルが出力されます。

データの学習

それではCNNで画像データを学習させてみます。
使用するプログラムはcnn.pyです。
GitHubのコードをそのまま実行するとsegmentation faultというエラーが発生しました。
原因を調べたところ、以下のように修正するとエラーが消えました。

# 下記のコードでエラー発生
x = x.astype('float32') / 255

# 修正後
x = x.astype('float32')
x = x / 255


結果は以下のようになりました。


f:id:hirokun1735:20181127231124j:plain


正解率36.6%というなんとも悪い結果です。
この結果は画像のクリーニングの結果で大きく値が変わるそうです。

データの水増し

次に精度向上のためにデータの水増しを行います。
写真の回転・反転を行うのですが、人間の目には同じでもコンピュータにはまったく異なる画像として認識されます。


cnn2.pyを実行するとデータを240枚から5760枚に水増しをしてからCNNで学習させます。
cnn.pyと同様に以下の文は修正しました。

# 下記のコードでエラー発生
x = x.astype('float32') / 255

# 修正後
x = x.astype('float32')
x = x / 255


その結果は以下です。


f:id:hirokun1735:20181130232428j:plain


正解率38.3%となり、先ほどの結果とあまり変わりませんでした。
本書では正解率が低い大きな原因は画像データにあると書かれています。
画像データのスクリーニングで手抜きしたつもりはないのですが、なかなか難しいですね。
時間のあるときに再度スクリーニングからトライしたいと思います。

まとめ

6-4では機械学習プログラムのWebアプリへの反映方法、6-5ではデータベースとの連携方法、6-6ではFlickrによる画像データの取得や画像データ水増し方法について学びました。


全体を振り返ると、機械学習や深層学習を実際のアプリケーションにどのように組み込めばよいか理解が得られたことが良かったです。
ただ実際の業務で役立つレベルかと言われると少々疑問で、さらなる改良は考えるべきでしょう。


また本書では深層学習を用いたアプリケーションを作成するところに重点を当てています。
そのため実際にWebアプリを利用可能にするところまで持っていく方法(デプロイ)に関する説明が無いことや、、深層学習の理論的な説明や各ツールの細かい説明はありません。


しかしこういう勉強は実際に自分で動くものが作れることが一番のモチベーションになると思いますし、手っ取り早く何か作りたいという人にはお勧めできると思います。


すぐに使える! 業務で実践できる! Pythonによる AI・機械学習・深層学習アプリのつくり方