jiku log

データサイエンスの核心を掴む : 学びと発見の記録

「PythonでつくるWebアプリのつくり方」を読む ~Chap.5 機械学習を使ったWebアプリを作ろう ②画像判定AI ~

はじめに

クジラ飛行机、 杉山 陽一、遠藤 俊輔 著「PythonでつくるWebアプリのつくり方」を読み,Pythonを使ったWebアプリ開発の基礎を学ぶことにした。

本記事は,「chapter5 機械学習を使ったWebアプリを作ろう」における,ラーメン判定AIに関する読書メモである。

本記事を読むことで得られること

本記事を読むことで得られることは,主に以下の内容である。

  • 本書における画像判定アプリのコード実行時の注意点

03 深層学習でラーメン判定AIを作ってみよう

要点

データセット

本項で紹介している画像判定AIは,ラーメンの画像をクラス分類するものである。ラーメンの種類は,塩ラーメン・醤油ラーメン・担々麺・味噌ラーメン・冷やし中華である。

画像データのデータセットは画像共有サイトFlickr(https://www.flickr.com/)からダウンロードして使うが,アノテーションが必要である。アノテーション済みのデータセットは著者が準備している。
github.com

なおラーメン画像のデータセットには,電気通信大学・箭内研究室のデータベースも存在する(https://mm.cs.uec.ac.jp/UEC-Ramen555/index_jp.html)。

本節の気付き : データセットのフォルダ名変更

アノテーション済みのデータをダウンロードすると,ramen_db-1.0.0.zipというファイルが得られる。これを解凍すると,dataフォルダの下に,ラーメンの種類別にフォルダができる。

ramen_make_model.pyを動作させるためには,このフォルダ群を「src/ch5/data」フォルダ直下にコピーする必要がある。
ただ,よく見るとフォルダ名が「soya_source」になっているため,フォルダ名を「soy_sauce」に変更する必要がある。

本節の気付き : ラーメン判定モデル

ラーメン判定モデルである「ramen_make_model.py」について,機能ごとに内容を確認した。

画像の回転

画像の水増しをするために,画像を45度ずつ回転させている。なおこの際,画像のサイズを縦img_w(=32)ピクセル,横img_h(=32)ピクセルにリサイズもしている。こうすることで,画像の枚数を360(度)÷45(度)=8(倍) に増やしている。

img = Image.open(img_path)
img = img.resize((img_w, img_h))
for angle in range(0, 360, 45): # 45度ずつ回転
    ...
画像の反転

画像の回転に加えて,画像を反転させることによってさらに画像の水増しをしている。

img_flip = img_rot.transpose(Image.FLIP_LEFT_RIGHT)

回転・反転により,元の画像の枚数は,8×2=16倍になる。

CNNのモデル

画像判定モデルには,畳み込みニューラルネットワーク(CNN)を用いる。層の定義は以下の通りである。

model = Sequential([
    Conv2D(32, (3, 3), activation='relu', input_shape=(img_w, img_h, 3)),
    MaxPooling2D(2, 2),
    Conv2D(64, (3, 3), activation='relu'),
    MaxPooling2D(2, 2),
    Conv2D(128, (3, 3), activation='relu'),
    MaxPooling2D(2, 2),
    Flatten(),
    Dense(512, activation='relu'),
    Dropout(0.5),
    Dense(len(labels), activation='softmax')
])

畳み込み層→プーリング層→畳み込み層→プーリング層→畳み込み層→プーリング層→1次元ベクトル化→全結合層(活性化関数はReLU)→ドロップアウト

という構成になっている。

モデルの精度

手元の環境で確認したところ,正解率は0.69であった。

本節の気付き : Webアプリ

画像判定モデルの読み込み

アプリ起動時に,先ほど作成した画像判定アプリを読み込んでいる。

model = models.load_model(RAMEN_MODEL_FILE)

そして画像の判定の際には,通常のPythonコードと同様に,predict関数でラベルの予測を行なっている。

predictions = model.predict([X])
モデルの精度

ためしに,モデルの学習に使ったデータのうち,「醤油ラーメン」(soy_sauce)の画像を入力にして判定させてみた。

4つの「醤油ラーメン」画像に対する判別結果

判定精度はそこまで高くないのかもしれない。左下の写真は,スープの色が濃いので「味噌ラーメン」と見間違えたのかもしれないが,画像のどの部分を判定に用いているか示されておらず,根拠が分からない。

まとめと感想

今回は,「chapter5 機械学習を使ったWebアプリを作ろう」における,画像判定アプリについてまとめた。

前回試した肥満度判定アプリと同様に,FlaskのWebアプリにおいて学習済みのモデルを用いて予測を行なう部分は,通常の関数を扱うような方法で呼び出せたので結構便利だった。
学習にそれなり時間がかかったので,学習と推論を分けるアプリの設計が好ましいが,今回はそのようなつくりになっていたので,別のアプリを作成する際にも参考にしたい。

誰かに見せるアプリではなくても,たとえば実験をする際でも,このようなアプリを作って可視化しやすくしておけば考察がしやすくなるのではと感じた。考察をしやすくするためにも,手軽にアプリ開発ができるFlaskは有用であると言える。

本記事を最後まで読んでくださり,どうもありがとうございました。