前回でTensorFlowのプログラム環境が整ったので、さっそくディープラーニングっちゃおうと思います。
・前回
学習する内容
0 ~ 9 までの手書き文字の判定器を作成します。
いわゆる MNIST データセットを使う初歩的なやつです。
どんなにヘタクソな手書き数字も分類できるようになるでしょう。
今回使用するコード
さっそくですが以下、学習用データのダウンロードから機械学習、モデルの評価までやっちゃってるコードです。
Python3.6 + Tensorflow 1.11.0
import tensorflow as tf # データセットのダウンロード、変数展開 (x_train, y_train),(x_test, y_test) = tf.keras.datasets.mnist.load_data() # 0 ~ 1 の少数値にする x_train, x_test = x_train / 255.0, x_test / 255.0 # モデルの定義 model = tf.keras.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(128, activation=tf.nn.relu), tf.keras.layers.Dense(10, activation=tf.nn.softmax) ]) # モデルのコンパイル model.compile(optimizer=tf.train.AdamOptimizer(), loss='sparse_categorical_crossentropy', metrics=['accuracy']) # 学習実行 model.fit(x_train, y_train, epochs=5) # モデルの評価 loss, acc = model.evaluate(x_test, y_test) print('accuracy:', acc)
前回インストールした Notebook を起動し、上のコードをコピペして実行すれば動きます。
Keras について
今回はTensorFlowに実装されている Keras というAPI群を使っています。
コード的にはより抽象度が高いのですが、バックで動いているのは TensorFlow です。
コードの解説
データセットの準備
「機械学習やろう!」と前のめりに手をつけてみた場合、環境準備の後に当たる壁が
データどうしよう...
ですね。
機械学習を行うには 大量のデータ が必要になります。
今は無償でビッグデータを公開しているサイトもたくさんありますが、 TensorFlowにはデフォルトで使えるデータセットが用意してある ので、機械学習学習用(ややこしい)にはまずこれを使いましょう。
コード中の下の行で、データのダウンロードから変数への展開までをやっています。
(x_train, y_train),(x_test, y_test) = tf.keras.datasets.mnist.load_data()
今回のデータは MNIST という有名なデータセットで、0 ~ 9 までの数字の手書き文字をデータ化したものです。
変数の内訳
ダウンロードしたデータを変数に展開していますが、それぞれ次のような内容になっています
(x_train, y_train)
こちらのカッコで囲まれているのは、モデルの学習に使うためのデータです。
x_train は画像のデータ本体で、手書き数字画像の平面データを2次元配列にしたものです。
y_train には、x_train のデータが 0 ~ 9 のどれなのか、正解が入っています。
(x_test, y_test)
こちらはモデルを学習した後、モデルの正確性を評価するため に使うデータです。
内訳としては (x_train, y_train) と同じですが、学習には使いません。理由は後述。
モデルの定義
肝心の学習モデルは以下のように定義しています。
model = tf.keras.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(128, activation=tf.nn.relu), tf.keras.layers.Dense(10, activation=tf.nn.softmax) ])
学習実行時は、Sequential に渡しているものが順番に実行されていきます。
入力層の定義(データの次元変換)
入力の画像データは平面なので2次元配列になっているわけですが、これをまず 1次元配列に変換 します。
tf.keras.layers.Flatten(input_shape=(28, 28))
入力が 28 × 28 ピクセルなので、そのサイズを引数に指定しています。
中間層の定義
自分の中でトップレベルのブラックボックス。理解したら詳細書く。
tf.keras.layers.Dense(128, activation=tf.nn.relu)
ここらへんの調節が判定器のメインなんだと思います。
出力層の定義
最終的には 0 ~ 9 の10種類の判定 になるので、それを定義。
tf.keras.layers.Dense(10, activation=tf.nn.softmax)
softmax というのは、入力が 0 ~ 9 のどれかであるかを確率で出力してもらう ための関数のようです。
モデルのコンパイル
モデルの定義が終わったら、学習プロセスを指定してコンパイルを実行。
# モデルのコンパイル model.compile(optimizer=tf.train.AdamOptimizer(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])
- optimizer
モデルの最適化(?)を行う方法で、AdamOptimizer が早いっぽい。 - loss
値の近似値を得るための方法の定義とかそんなかんじ 損失関数 - Keras Documentation - metrics
調査不足
学習の実行
fit メソッドで学習を実行します。
# 学習実行 model.fit(x_train, y_train, epochs=5)
epochs を指定するとその回数だけ学習を反復します。
Modelクラス (functional API) - Keras Documentation
モデルの評価
学習したモデルの正確性を評価します。
ここで登場するのが冒頭でダウンロードした (x_test, y_test) です。
というのも、「学習に使ったデータを判定器に入れたらそりゃ正解でますよね」ということで、 評価用に使うデータは 学習に使っていない新規データ である必要があるのです。
# モデルの評価
loss, acc = model.evaluate(x_test, y_test)
acc が正確性なので、この数字を高めていくようにパラメータを調整していくのが腕の見せ所なんじゃねいですかね知らないけど。
以上、なんとなくでもできてしまうものですね。
・参考 今回のコードは TensorFlow公式のサンプルを参考にして書いています。