Ubuntu18.04でtensorflow動作させてみる(tf.kerasで入門)

2019年8月16日

最近はどこもAIがはやってますので、私も落ちこぼれないように深層学習の代表オープンソースのtensorflowを自分で動かしてみたいと思います。kerasはtensorflowのラッパーとのことですが、実際はtensorflowの中に組み込まれてますので、別途インストールする必要は無いかと思います。実際に使うPythonライブラリは 

 ft.keras

になります。

tensorflowを直接いじるのは初心者ではまず無理ですので、まずはkerasからですね。

インストール

オフィシャルサイトを参考にしてます。

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

python 仮想環境つかっているよね、と説明書きがあって環境構築されていますので、私の場合はvenvで構築してみます。

$ mkdir venv
$ cd venv
$ python3 -m venv testenv
$ source ./testenv/bin/activate

で仮想環境作成です。tensorflowは2.0betaを使ってみます。

(testenv)$ pip install tensorflow==2.0.0-beta1

これだけです。

サンプルコード実行

こちらを参考にしてみます。

https://www.tensorflow.org/tutorials/

サンプルコードはこちらですね。kera.pyとでもしておきます。上記サイトからコピペしたものです。

import tensorflow as tf
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(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.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)

これを仮想環境で実行するといろいろ警告がでますが、一応なんだかわかりませんが一応無事結果とともに終了します。

1s 88us/sample - loss: 0.0707 - accuracy: 0.9800

このモデルで学習した結果をテストしたところ正確度は98%でした、ということですね。

一応自分なりに理解したことをコードごとにまとめて見たいと思います。

1.データセット作成

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 = tf.keras.datasets.mnist

は有名なMNISTの数字の手書きデータオブジェクト作ってくれていることろですね。

2行目

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

は何やら4つ変数ができていますが、それぞれのshape など見てみますとわかりますが、

・ x_train は学習用データで、28x28の画像ファイル60000個をデータ化したものですね。shapeでの出力は(60000,28,28)で画像数が60000個あって、一つの画像の画素をグレースケール値で表現したものが28x28あることがわかります。1画像分データですね。

#先頭のデータサンプル
[
[  0   0   0   0     〜ゼロが20個〜 0   0   0   0] #1行目
[  0   0   0   0     〜ゼロが20個〜 0   0   0   0]  #2行目
〜
[  0   0   0   0     〜ゼロ以外数字と0が20個〜 0   0   0   0] #途中行
〜
[  0   0   0   0     〜ゼロが20個〜 0   0   0   0] #28行目
]

グレースケール値では真っ黒は0ですね。ゼロ以外の部分には何か黒以外で数字が書かれているということですね。

・ y_train はラベルといいますが、x_train画像が実際にどの数字なのかの単純な1次元配列ですね。0から9までの数字60000個が詰まっています。

・x_test, y_testはデータ構造はx_train, y_trainと同じで検証用のデータになりますね。ここでは10000 個分データです。学習用と検証用のデータは同じものは使わない、ということかと思います。まずモデルを学習用データで学習させて、検証用データでそのモデル学習の正しさを検証する、という流れですね。

x_train, x_test = x_train / 255.0, x_test / 255.0

はグレースケール値が0から255まで取りますので、それを255で割って1以下の値に変換しているのですが、ちょっと私にはわかりませんね。何か理由があるんだと思います。

2.モデルの作成

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

これもサラッとmodel オブジェクトできてますが、難しいですね。Sequentialモデルを使ってその中に4つレイヤーがあるってことですね。ここで利用されているレイヤーを調べてみると、

Flatten(input_shape=(28, 28))  で入力を平滑化して28x28のデータが入るよ、ということみたいですね。平滑化がよくわかりません。Flattenまんまですね。。

Dense(512, activation=tf.nn.relu) は全結合ニューラルネットワークレイヤーで512次元の出力があってアクティベーション関数はreluを使う、ということですね。

Dropout(0.2) は「過学習の防止に役立ちます」とのことですがついていけません。

Dense(10, activation=tf.nn.softmax)は最終出力で10次元でアクティベーション関数はsoftmaxを使うよ、ということですね。

reluとかsoftmaxとか聞き慣れない単語が出てきますが、要勉強ですね。。

活性化関数 – Wikipedia

正規化線形関数 – Wikipedia

3.complieメソドでTrainingプロセスを設定する

モデルにレイヤだけではなくその他の情報もセットしていますね。

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

・optimizer 最適化アルゴリズム。いろいろある。

・loss 損失関数。誤差関数とも。いろいろある。

・metric 評価関数。学習の段階では使われないみたいですね。

4.fitメソドでエポック数を渡してTraining(学習)実行する。

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

 fit で学習の実行ですね。 epochsは学習回数で回数が多いほどよい?そうですが謎ですね。

5.evaluateメソドでモデルの学習を評価する(損失値を計算する)

model.evaluate(x_test, y_test)

最後はevaluateメソドで学習した結果を検証用データを利用して正確性を評価する、ですね。コピペしただけですので、98%とかになりますね。

6.predictで予想する

チュートリアルにはありませんが、 最後は predictメソドで予測です。

使い方はこちらのコード追加ですね。検証用データ画像ファイル一つ(x_test[0])を拝借です。

import numpy as np
c=np.array([x_test[0]])
result=model.predict(c)
print(c)

#結果は
[[0.0.0.0.0.0.0.1.0.0.]]
#で「7」が予測されたものと思います。

実際に読み込まれた画像を見てみますと、たしかに7ですね。

MNISTデータ数字の7

参考までに画像ファイルへの落とし込みはOpenCVでやってみましたが簡単にできました。OpenCVをpipで仮想環境に追加します。追加分コードだけ記載しておきます。

import cv2
cv2.imwrite('test.jpg',x_test[0])

まとめ

とりあえずkerasを使えばそれなりに初心者でも内部的な処理は抜きにしてtensorflowが手に届きそうなことまでは理解できました。使いこなすにはプログラミングというよりは数学や統計をしっかり理解する必要があることもようやく理解できましたね。。