Raspberry Pi 3 & Python 開発ブログ☆彡

Raspberry Pi 3の使い方、設定をわかりやすく解説。Raspberry Pi3 Model B(Element14版)、Raspbian 8.0(NOOBS Ver1.9.2)を使用して開発中。

【スポンサーリンク】

TensorFlowの使い方

【スポンサーリンク】

今回はTensorFlowの使い方を紹介したいと思います。TensorFlowの公式ページにトライアルとして記載されている、MNISTデータを使用した機械学習について解説したいと思います。今回はRaspberry Piではなく、WindowsPythonとTensorFlowを入れて動作させます。

MNISTデータを使用した機械学習の概要

大まかに内容、流れを説明します。
① 0~9までの文字が手書きで書かれた画像データを大量に用意します(MNISTデータ)。
② TensorFlowで機械学習モデルを作成します。このモデルに①のデータを大量に与え、
学習をさせ、パラメータの最適値を探します。
③ この学習済みモデルに、何か数字が書かれたデータを与えると、自動的に0~9のどの文字が書かれているか判別します。
例えば"3"と手書きで書かれた画像データをこの学習済みモデルに与えると、
最適化されたパラメータとTensorFlowのアルゴリズムにより推測された、
"3"という結果が出力されます(推測結果が正しい場合)。
100%正しい推測結果が出るわけではありませんが、訓練の度合いや
仕様したアルゴリズムによって正解率の高くなっていきます。

それでは、WindowsPythonとTensorFlowを入れて実際に動かしてみます。

WindowsPython、TensorFlowで使用するモジュールのインストール

pythonのインストール

下記のサイトからpythonインストーラをダウンロードしてください。

https://www.python.org/downloads/release/python-353/

インストールウィザードで"Add Python to environment variables" にチェックを入れてインストールしてください。

〇TensorFlowのインストール
管理者権限でWindowsコマンドプロンプトを起動します。以下のコマンドでインストールを行います。

pip3 install --upgrade tensorflow

・インストール手順の参考ホームページ

https://www.tensorflow.org/install/install_windows

※上記のコマンドを使用するとTensorFlowの最新版がインストールされるのですが、最新版を使うと実行時にワーニングが出てしまいました(ワーニングはでますが、普通に動作します)。下記のコマンドで少し古いモジュールをインストールするとワーニングはなくなりました。

pip install --upgrade https://storage.googleapis.com/tensorflow/windows/cpu/tensorflow-0.12.1-cp35-cp35m-win_amd64.whl

 

〇MINSTデータを使用するためのモジュールをダウンロード
下記のinput_data.pyをダウンロードし、インポートできるように本pythonコードと同フォルダもしくは
Pythonパスが通っているフォルダに保存します。
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/input_data.py

MNISTデータを使用した機械学習のコード解説

それでは実際のコードの説明をしていきます。機能単位で説明していきます。
ページの最後に全コードを記載していますので、まずはそちらにざっと目を通して
頂いてもいいかもしれません。

〇TensorFlowデータ型について

コードの解説の前に、Tensorflowのデータ型について説明します。
今回、以下のデータ型を使用しています。
プレースホルダー(tf.placeholderで) :プレースホルダーは中身は空で、領域だけを確保するイメージです。具体的な値は実行時に与えます。x = tf.placeholder(...)という形で、プレースホルダー:xを生成します。xに値を代入するときは、feed_dict={x:XXX}という構文を使用します(feed_dictは省略しても大丈夫そう)
 
・変数 : b = tf.Variable(...)という形で、変数;bを生成します。bに値を代入するときは、tf.assignメゾットを使用します。


プレースホルダーと変数の違いが判りにくいですが、モデルの入力として一番初めに与えるデータ⇒プレースホルダー、その後の処理で使用する値⇒変数と理解しましょう。

 

# モジュールのインポート
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf

MNISTデータを読み込むモジュールとTensorFlowモジュールをインポートします。MNISTデータには、"0~9までの文字が手書きで書かれた画像データ"と"それが0~9までのどの数字なのかが示されている正解値データ"が入っています。


#MNISTデータの読み込み
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)

C:\tmp\dataフォルダにMNISTデータがダウンロードされます。MNISTデータは

#セッションの作成
sess = tf.InteractiveSession()

Tensorflowでは主に"機械学習モデル作成"と"作成したモデルを実行"するふたつに分かれます。モデルを実行する際にはセッションを生成する必要があるので、ここで生成しています。
モデルはデータフローグラフという呼び方が正式のようです。データフローグラフは機械学習する際の処理のフローのようなイメージで、折れ線グラフのようなグラフではいので勘違いしないようにしましょう。
 
# モデルの作成
x = tf.placeholder(tf.float32, [None, 784])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x, W) + b)

基本的なモデルのフローは、データを入力する ⇒ 何か処理をする ⇒ 答えが出力される、です。
・データを入力する
 上記の "x" がデータになります。プレースホルダーですので、まだ中身は空です。実行時に値を代入していきます。
・何か処理をする ⇒ 答えが出力される
 まず、重みWとバイアスbという値を変数を作成します。重みWとバイアスbは学習により最適値を求めていきます。それらとソフトマックス関数を使用して、答えを導いていきます。答えが"y"になります。

 

# 学習モデルを作成(損失とオプティマイザーを定義)
y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

機械学習するためのモデルを作成します。ダウンロードしたMNISTデータの中にある学習用の訓練データとその正解値データを使用して学習をします。
入力:訓練データ ⇒ 出力:正解値データ、と同じ答えになるように重みWとバイアスbの最適値を勾配降下アルゴリズムを使って求める処理(モデル)になります。

# イニシャライズ
tf.global_variables_initializer().run()

実行前に初期化処理を行います。

# 学習
for i in range(1000):
  batch_xs, batch_ys = mnist.train.next_batch(100)
  train_step.run({x: batch_xs, y_: batch_ys})

先ほど作成した訓練用のモデルを使用して、学習を実行します。
MNISTデータの訓練用データと正解値データを取り出し、学習します。
 
# 学習済みモデルにテストデータを入れてテスト
print(sess.run(tf.argmax(y, 1), feed_dict={x: [mnist.test.images[0]]}))
print(mnist.test.labels[0])

sess.runメゾットに入力(プレースホルダー)と実行したい関数を引数として与えます。feed_dictでxのプレースホルダーにテスト用データを入れると、tf.argmax(y, 1)関数で処理した結果を表示してくれます。argmaxはy関数の結果、配列の中の数値が1に1番近いものを取り出してくれるメゾット(1に1番近い配列の添え字を戻値りとして返す)です。

上記では、プレースホルダーにmnist.test.images[0]のデータを与えいます。配列[0]の正解値は4です。4と出力されれば、正しく学習できていると言えます。

 

# 学習済みモデルの正解率表示
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels}))

tf.argmax(y, 1)は今回作成したモデルでの結果、tf.argmax(y_, 1)は正解値データです。
作成したモデルの結果と実際の正解値をを比較して、正解率を表示してくれます。だいたい90%くらいの結果が表示されます。

何となくですが、TensorFlowのイメージはつかめましたでしょうか?ソフトマックス関数や勾配降下アルゴリズム等はさっぱり私も理解していませんが、モジュールになっていますので、使うことができます。Pythonでは機械学習のコードは書きやすくなっていますので、実際にコードを書いてみて理解を深めていくといいと思います。

全コードの紹介

# モジュールのインポート
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
 

#MNISTデータの読み込み
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)

 

#セッションの作成
sess = tf.InteractiveSession()
 
# モデルの作成
x = tf.placeholder(tf.float32, [None, 784])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x, W) + b)

# 学習モデルを作成(損失とオプティマイザーを定義)
y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

 

# イニシャライズ
tf.global_variables_initializer().run()

 
# 学習
for i in range(1000):
  batch_xs, batch_ys = mnist.train.next_batch(100)
  train_step.run({x: batch_xs, y_: batch_ys})

 

# 学習済みモデルにテストデータを入れてテスト
print(sess.run(tf.argmax(y, 1), feed_dict={x: [mnist.test.images[0]]}))
print(mnist.test.labels[0])

 

#学習済みモデルの正解率表示
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels}))