Raspberry Pi & Python 開発ブログ ☆彡

Raspberry PiとPythonの基本的な使い方をわかりやすく解説。初心者、入門者必見!!

TensorFlow 2.0の使い方:MINISTデータで数字を識別

tensorflow 2.0

ブログ管理者のP.Hです!

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

それでは、TensorFlow 2.0の使い方を説明していきます。

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

大まかに内容、流れを説明します。

  1. 0~9までの文字が手書きで書かれた画像データを大量に用意します(MNISTデータ)。
  2. TensorFlowで機械学習モデルを作成します。このモデルにデータ(MINISTデータ)を大量に与え、学習をさせ、パラメータの最適値を探します。
  3. この学習済みモデルに、何か数字が書かれたデータを与えると、自動的に0~9のどの文字が書かれているか判別します。例えば"3"と手書きで書かれた画像データをこの学習済みモデルに与えると、最適化されたパラメータとTensorFlowのアルゴリズムにより推測された、"3"という結果が出力されます(推測結果が正しい場合)。

100%正しい推測結果が出るわけではありませんが、訓練の度合いや仕様したアルゴリズムによって正解率の高くなっていきます。 それでは、WindowsにTensorFlow2.0を入れて実際に動かしてみます。

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

pythonのインストール

下記のサイトからpythonのインストーラをダウンロードしてインストールを行います。
※現在、Windows版のTensorflow2.0はpython3.6用までしかリリースされていません。python3.7以上をインストールすると動作しない可能性があります。

www.python.org

pythonバージョン:3.6.8
Windows用インストーラ:Windows x86-64 executable installer

インストールウィザードの一番初めの画面で"Add Python to environment variables" にチェックを入れてインストールしてください。pythonの環境変数が設定されます。

また、pipのバージョンを最新版に更新しておきます。

> pip install --upgrade pip
> pip install setuptools --upgrade

Tensorflow2.0のインストール

下記コマンドでインストールを行います。NVIDIAのグラフィックカードを持っていないので、CPU版でインストールしています。

> pip install tensorflow

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

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

モジュールのインポート

from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
import numpy as np

tensorflowモジュールをインポートします。

MNISTデータの読み込み

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

MNISTデータには、"0~9までの文字が手書きで書かれた画像データ"と"それが0~9までのどの数字なのかが示されている正解値データ"が入っています。print文で確認すると以下のように表示されます。

  • x_train, x_test ⇒ 縦28 x 横28 = 28個のlistが28個(2次元)
  • y_train, y_test ⇒ 正解の数字
print(x_train[0]) # 画像データ
[[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
...
 [  0   0   0   0   0   0  18 171 219 253 253 253 253 195  80   9   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0  55 172 226 253 253 253 253 244 133  11   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0 136 253 253 253 212 135 132  16   0   0   0   0   0   0
...
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]]

print(y_train[0]) # 正解値データ この場合は5が正解
5

255.0で割ることにより、整数値から浮動小数点(255を1とする、1=100%のイメージ)に変換します。

モデルの作成

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation='softmax')
])

層を積み重ねてtf.keras.Sequentialモデルを構築します。簡単に説明すると、以下のようになります。

  • Flatten: 入力データを平坦化する(多次元を1次元に変換)
  • Dense: 通常のューラルネットワークレイヤー (作りたい出力空間の数、活性化関数を指定)
  • Dropout: ドロップアウト層(入力ユニットをドロップする割合を指定)。過学習を防止する

kerasはたくさん参考になるページがあるのですが、下記がわかりやすいと思いましたので紹介しておきます。
https://qiita.com/kakiuchis/items/3e727228dd770c240c5d

学習モデルを作成(損失関数とオプティマイザーを定義)

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

訓練のためにオプティマイザ(最適化アルゴリズム)と損失関数を選びます。精度が上がるようにオプティマイザと損失関数を選んでいきます。全て紹介することは不可能ですので、下記のページを参考にして、いろいろと試してみてください。

学習

model.fit(x_train, y_train, epochs=5)

上記でモデルを作成したので、fit関数で訓練(学習)を行います。引数には訓練データと反復回数(epochs)を指定します。

学習済みモデルの正解率表示

model.evaluate(x_test,  y_test, verbose=2)

evaluate関数を使うと、モデルの損失値と評価値を返してくれます。

学習済みモデルにテストデータを入れてテスト

predictions = model.predict(x_test[:10])
for i in range(10):
  print('正解値データ :{}'.format(y_test[i]))
  print('機械学習結果 :{}'.format(np.argmax(predictions[i])))

predict関数を使って、x_testの先頭から10個の画像データにどの数字が書かれているかを予測してみます。np.argmax関数で配列の要素の値が最大のものを見つけてくれます(最大 = 正解の確率が一番高いもの)。

正解値データと機械学習結果の値が同じになっていれば、精度が高いモデルになっていることがわかります。試しに、上記のfit関数でepochs=2に変えて実行してみてください。正解値データと機械学習結果が1つ間違っていると思います。訓練が足りず、モデルの精度が低いことがわかります。

わたしもまだまだ知識不足ですが、モジュール化されていますので、機械学習を体感することができます。Pythonでは機械学習のコードは書きやすくなっていますので、実際にコードを書いてみて理解を深めていくといいと思います。

全コードの紹介

# モジュールのインポート
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
import numpy as np

# MNISTデータの読み込み
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

# モデルの作成
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation='softmax')
])

# 学習モデルを作成(損失とオプティマイザーを定義)
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# 学習(訓練)
model.fit(x_train, y_train, epochs=5)

# 学習済みモデルの正解率表示
model.evaluate(x_test,  y_test, verbose=2)

# 学習済みモデルにテストデータを入れてテスト
predictions = model.predict(x_test[:10])
for i in range(10):
  print('正解値データ :{}'.format(y_test[i]))
  print('機械学習結果 :{}'.format(np.argmax(predictions[i])))

以上でTensorFlow 2.0の使い方の説明を終わります。