Python 3.6.6 でTensorFlowのライブラリを使って、手書き数字の認識を学習させてみる

少し前の記事で、Python 3.7 にTensorFlowが対応できていなかったので、急遽、Python 3.6.6 を導入しました。 

ts0818.hatenablog.com

⇧  TensorFlowを使って、Hello World を表示するところまで実施しました。機械学習のライブラリを使って、Hello World っていうところで、パンチが飛んできそうですが...

 

というわけで、今回は若干、機械学習っぽく、手書き数字を認識するよう学習させてみたいと思います。

レッツ、トライ~。 

 

手書き数字を学習する用のプログラムをインストール

今回も、

www.sejuku.net

⇧  上記サイト様を参考にさせていただきます。

で、手書き数字を学習する用のプログラムが、GitHub上で公開されているようです。

https://github.com/tensorflow/tensorflow/blob/r1.11/tensorflow/examples/tutorials/layers/cnn_mnist.py

github.com

⇧  上記は、TensorFlowのバージョンが、1.11 のものですかね。

リンク先で、バージョンは、選べるようです。

f:id:ts0818:20181007200304j:plain

そしたらば、右の方に「Row」ってボタンがあるのでクリック。

f:id:ts0818:20181007223004j:plain

遷移先のURLをコピーして、適当なテキストエディターに貼り付けときます。

f:id:ts0818:20181007223314j:plain

 

で、Visula Studio Code を起動し、前に作ったTensorFlow用のプロジェクトディレクトリを開きます。ない場合は、新しく適当なディレクトリを作成し、Pythonの仮想環境にログインできる環境を準備しましょう。

手前味噌になりますが、 

ts0818.hatenablog.com

⇧  こちらの記事で、Pyhton 3.6.6 でTensorFlowが動くところまでの構築手順を掲載してますので是非是非。

で、環境が整ったディレクトリを開きます。「ファイル(F)」>「フォルダーを開く(F)...」を選択。

f:id:ts0818:20181007201416p:plain

TensorFlowの動くPython環境の用意されたプロジェクトディレクトリを選択し、「フォルダーの選択」を選択。 

f:id:ts0818:20181007201607p:plain

で、もし、「ターミナル」が開いてない場合は、「表示(V)」>「ターミナル(T)」を選択。

f:id:ts0818:20181007201817p:plain

そしたらば、curlコマンドで、ファイルをインストールしちゃいましょう。

forest.watch.impress.co.jp

⇧  とりあえず、最近のWindows 10 は、デフォルトでcurl コマンドがいるはず。 

f:id:ts0818:20181007202655p:plain

⇧  コマンドプロンプトとかで、バージョン情報が確認できれば、インストール済みです。

もし、インストールできてない場合は、

shigeo-t.hatenablog.com

⇧  上記サイト様が参考になると思われます。 

で、PowerShellだと、何か分からないけどcurlコマンドがエラーになってしまうので、普通にコマンドプロンプトで。

プロジェクトのPythonの仮想環境である「.venv」まで移動しておきます。

cd [プロジェクト用のディレクトリ]\.venv  

そしたらば、github上のcnn_mnist.pyをインストールしちゃいましょう。tensorflowのバージョンは、1.11を使ってます。

curl -kLO https://raw.githubusercontent.com/tensorflow/tensorflow/r1.11/tensorflow/examples/tutorials/layers/cnn_mnist.py 

f:id:ts0818:20181007223638p:plain

無事に、インストールできたようです。

f:id:ts0818:20181007224119p:plain

そしたらば、Visual Studio Codeの「ターミナル」で、Pythonの仮想環境にログイン。 

.\.venv\Scripts\activate.ps1

そしたらば、Visual Studio Codeの「ターミナル」で、cnn_mnist.pyを実行。 

python ./.venv/cnn_mnist.py

f:id:ts0818:20181007225008p:plain

⇧  この「step = 1801」って部分が、20000になるまで待つそうです...かなり時間がかかります。 今回はCUIのTensorFlowを使ってるけど、GUIのほうが早いのかな?

っていうか、日またいじゃうよ、これ...1時間以上かかるから、開始タイミングには、ご注意を。

f:id:ts0818:20181008000740p:plain

⇧  結局、終わったの、0:06って...「MNIST-data」っていう手書き数字の認識に必要なデータがダウンロードされるので、2回目は多少、処理が早まるんだとか。

とりあえず、明日に持ち越しで。

で、翌日。

二回目を実行。

f:id:ts0818:20181008175101p:plain

20001回目からスタート。

f:id:ts0818:20181008175156p:plain

結局、1時間ぐらいかかってますが...

f:id:ts0818:20181008191321p:plain

んで、Cドライブでプロジェクトを作っていた場合は、Cドライブ直下に、「C:¥tmp¥mnist_convnet_model」みたいなディレクトリが作成されてるという、いや~、怖い...

f:id:ts0818:20181008194009p:plain

⇧  このディレクトリのパスを後半で使うようです。 

 

Pillow(Python Imaging Library)のインストール

pythonのライブラリが必要なようなので、インストールします。

pip install pillow   

f:id:ts0818:20181008192240p:plain

f:id:ts0818:20181008192304p:plain

「pillow-5.3.0」ってライブラリがインストールされたようです。 

 

手書き数字の画像を用意

我らが救世主の「ペイント」で、手書き数字の画像を作成しちゃいましょう。 

f:id:ts0818:20181007231550p:plain

⇧  検索で日本語が入力できないときは、

www.coyapuyo.com

⇧  上記サイト様によりますと、「Google日本語入力」を再インストールする必要があるようです。

ペイントが起動できたら、「ブラシ」の中から、「クレヨン」を選択。

f:id:ts0818:20181007232129p:plain

「サイズ変更」で、キャンバスサイズを変更しときます。「縦横比を維持する(M)」のチェックを外し、「ピクセル」にチェックし、「水平方向(H):」「垂直方向(V):」ともに「280」とします。

f:id:ts0818:20181007232658p:plain

「線の幅」とかを好きに選んで、数字を各々のありったけの思いを載せて描く!

f:id:ts0818:20181007233005p:plain

そして、保存する際は、サイズを「28 × 28」にしないといけないらしい。

「サイズ変更」を選択し、「縦横比を維持する(M)」のチェックを外し、「ピクセル」にチェックし、「水平方向(H):」「垂直方向(V):」ともに「28」とします。

f:id:ts0818:20181007232408p:plain

そしたら、「ファイル」>「名前を付けて保存(A)」>「PNG 画像(P)」を選択。 

f:id:ts0818:20181007233125p:plain

で、どこに画像を保存するかが説明ないんですよね...途中までペイントのめっちゃ丁寧な説明をしてるのに、なぜ肝心の画像の保存先の説明を端折るのかが疑問ですが... 

とりあえず、 「MNIST-data」と同じ階層に「image」ディレクトリを作成し、その中に画像を保存ということで。

f:id:ts0818:20181008182526p:plain

f:id:ts0818:20181008182647p:plain

とりあえず、ペイントで、0 ~ 9 まで作成し保存します。

f:id:ts0818:20181008183442p:plain

f:id:ts0818:20181008183508p:plain

 

cnn_mnist.pyの書き換え

一応、「cnn_mnist.py」のbackupとして、「cnn_mnist_bk.py」を作成しときましょう。「cnn_mnist.py」上で右クリックし、「コピー」を選択。

f:id:ts0818:20181008192537p:plain

「.venv」上で右クリックし、「貼り付け」を選択。

f:id:ts0818:20181008192650p:plain

ファイルが複製されるので、

f:id:ts0818:20181008192736p:plain

「名前変更」で。

f:id:ts0818:20181008192904p:plain

f:id:ts0818:20181008193002p:plain

というわけで、「cnn_mnist.py」の内容を編集します。下記の部分を、

if __name__ == "__main__":
  tf.app.run()    

⇩ のように書き換えます。model_dirの部分は、cnn_mnist.pyを実行した時にできるディレクトリを指定。

def checkImage(arg):
  new_img = Image.open(arg)
  new_img = new_img.convert('L')
  new_img = 1.0 - np.asarray(new_img, dtype="float32") / 255
  predict_data = new_img.reshape((1,784))
 
  # Create the Estimator
  mnist_classifier = tf.estimator.Estimator(
      model_fn=cnn_model_fn, model_dir="C:/tmp/mnist_convnet_model")
 
  predict_input_fn = tf.estimator.inputs.numpy_input_fn(
      x={"x": predict_data},
      num_epochs=1,
      shuffle=False)
  predict = mnist_classifier.predict(
      input_fn=predict_input_fn
  )
  predictions = list(predict)
  print("CLASS:")
  print(predictions[0]["classes"])
 
if __name__ == "__main__":
  import sys
  if len(sys.argv) == 1:
      tf.app.run()
  else:
      import os
      from PIL import Image
      for arg in sys.argv[1:]:
          if os.path.isfile(arg):
              checkImage(arg)    

で、保存したらば、ターミナルで、引数に用意した手書き画像のパスを指定し、実行。「1」を認識できるか試してみる。

python ./.venv/cnn_mnist.py ./image/01.png    

f:id:ts0818:20181008201732p:plain

f:id:ts0818:20181008201758p:plain

⇧  結果は、「6」って...

そのほかも試してみました。

手書き数字の画像 認識結果 結果
1 6
2 2
3 3
4 4
5 5
6 3
7 8
8 8
9 4
0 0

結果は、五分五分ですかね。武富士のCMを思い出しますな。

というわけで、機械学習っぽいことをようやくできましたかね。なんか書籍とかでキッチリ勉強してみたいですね。

今回はこのへんで。