Colab使って、画像の真偽をDNNに学習させてみるまで


はじめに

Colaboratoryで、画像の真偽を学習してみようと思ったが、いろんなところに情報があって集めるのが大変だった。そこで、もう完成したものをそのまま貼り付けようと思った。
Pythonなんとなくわかる人向けです。

ドンッ
https://colab.research.google.com/drive/1ETjxVKCA3zv391tEAY5RHM_cyipIA9D-?hl=ja

そのまま使える人はいないと思いますが、誰かの参考になれば。
Jupyter-notebookとかPythonとか詳しくない状態で作ったので、なんか指摘も来るといいな。

やりたかったこと

私がやりたかったことはこれ。

  • Colaboratoryを使う
  • 画像の真偽を学習させたい
    • ディープラーニング
  • 訓練データ(画像)はGoogleDriveにある
    • 画像は横100px縦150pxのPNGファイル
    • 画像はZIPで圧縮してあって、フォルダ構成は下記の通り
  • 学習の履歴をグラフで見たいし、そのグラフやモデル情報をGoogleDriveに保存したい

ZIPファイルフォルダ構成

  • images.zip
    • 0(フォルダ)
      • 偽判定の画像
    • 1(フォルダ)
      • 真判定の画像

やっていること

簡単にやっていることの説明を書く。Colaboratoryにアクセスして、コードを参照のこと。

1つ目のセル(GoogleDriveのマウント)

GoogleDriveをマウントする。見ての通り。
世の中的には、GitHub使うのが多そうですね。GoogleDriveだと、毎回認証がめんどくさい。

2つ目のセル(訓練データの展開)

GoogleDriveにある訓練データのZIPファイルを、ディスクに展開する。
訓練データの画像1枚1枚をGoogleDriveから読み込むこともできるが、遅い。ZIPファイルにしておいて、全部ディスクに展開した後、ディスクから読み込んだ方がはるかに速いのでこうしている。

3つ目のセル(訓練データの読み込み)

訓練データとテストデータ、真偽同数にしたかったので、シャッフルしつつ真偽交互に画像パスを返すジェネレータgenerate_pathsを作った。
すなわち、
偽として 0-1, 0-2, 0-3, 0-4, 0-5
真として 1-1, 1-2, 1-3, 1-4, 1-5
の10枚の画像があったとして、
0-3, 1-5, 0-1, 1-1, 0-2, 1-3, 0-4, 1-4, 0-5, 1-2
のように返す。

ジェネレータなんか使わず、普通にリストをシャッフルした方がわかりやすかったかも?

load_dataメソッドでは、実際に画像を読み込んで配列にしている。今回扱った画像は、背景が白のものが多いので、1 - X / 255として、白黒反転させて0~1の浮動小数点にしている。大体が0で、時々1がある状態となる。
カラーの画像もあるので、inputのチャネル数は3で。

4つ目のセル(学習)

頑張って学習する。
いつ学習が終わったかわかるように、終わった時間を保存するのも忘れない。

import datetime
tz_jst = datetime.timezone(datetime.timedelta(hours=9), name="JST")
now = datetime.datetime.now(tz_jst)
str_now = now.strftime("%Y/%m/%d %H:%M:%S")
print(f"訓練が終了 {str_now}")

モデル全体と、そのアーキテクチャを保存しておく。

5つ目のセル(グラフを描画)

%matplotlib inlineを付けて画面上に表示するとともに、GoogleDriveにも保存する。

結論

Colaboratory、GPUとか無料で使えてとても便利。どこでも、iPhoneからでもアクセスできていいですね。ただ、昼間とかに、GPUとTPU使えなくなることがあって悲しい。

学習結果に関しては、accuracy、0.7強…ですって。いろいろ試行錯誤してみたけど、ちょっと微妙…
訓練データがなんなのかはちょっと言えないのだけど、この結果に関しては訓練データが悪い(というか問題が悪い)と信じている。