自分のための備忘録的なブログです。

Ubuntu14.04LTS および Win10 を使って、ディープラーニングの勉強をしています。記載されているコードは、他の OS には互換性がない可能性があります。


DNN:
マシン性能別 学習速度の比較, TFチュートリアルをmodifyする

python3:
オブジェクト指向プログラミングとは, モジュールとインポート、パスを通す, システムコマンド(os), ファイル・フォルダ名取得, 画像の前処理,

Ubuntu14 の初期設定:
Ubuntu14初期設定, 初期設定-2, cudaなども, 初期設定-3

TensorFlow "高度な" MNISTチュートリアル1

原文:Deep MNIST for Experts  |  TensorFlow

 

ディープラーニング・ディープニューラルネットワークの勉強のために、MNIST のチュートリアルの日本語訳(意訳・直訳のちゃんぽん+自分のコメントも時々まじる)を作成。今回前半部分のみ。

 

初心者なので誤りがあるかもしれません。

気づかれたら教えてください。

当方 Windows 10 + Python 3.5 (Anaconda) という環境です。

クリエイティブ・コモンズなので、著作権的に大丈夫と思いますが、問題あれば教えてください) 

 

コード全体は、最下段にまとめています。

対話型環境へのコピペだけで、走るようにしてあります。

 

 

MNISTデータを読み込みましょう。

 

まず、TensorFlow をインストールしていること、"簡単な" MNIST チュートリアルを終えているなど、Deep Learning の理解が必要と始める前に念押しされます。

 

まず、MNISTのデータをダウンロードします。

 

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

 

 

インターアクティブセッションを初めましょう

 

通常は グラフを作ってからセッションを始めるのだが、今回はもっと便利で柔軟な、インターアクティブセッションという方法でやってみるとのこと。この方法では、計算グラフ(computation graph)を作るのと、グラフを走らせる(launch graph)ことを交互に行えると。これを使わないなら、"launch graph" の前に、計算グラフを完成させないといけないそうです。

IPython (現 Jupyter Notebook?)で使う時に便利なんだそうです。

 

 

セッション(Session)というのは、C++で実装されたバックエンドとの連絡(connection)のこと(原文:*1)。

どうやら「セッション」のなかで作業が行われるようです*2

 

import tensorflow as tf
sess = tf.InteractiveSession()

 

 

計算グラフ (Computation Graph)

 

Python を使って計算をする時、NumPy のようなライブラリを使うわけですが、処理をしてから Python に戻ってくる(switching back)時に大きな負荷(a lot of overhead)がかかると。特に GPU に分散させて (distributed manner) 処理する時に負荷が大きいそう。

TensorFlow ではこの負荷を避けるために、処理の表(graph)を作るのだと(Theano や Torch など、他の DNN*3  ライブラリと同様とのこと)。

Python コードの役割は、外部で行う作業の表(external computation graph)を作成し、その表のどの部分を実行するかを指示すること。詳しくは、Basic Usage の Computation Graph Computation Graph  |  Basic Usage  |  TensorFlow を参照のこと。

 

 

Softmax 回帰モデル

 

このセクションで、一層の線形の層を持った(with a single linear layer) Softmax 回帰モデルを作成し、次のセクションでこれを、convolutionan deep neural network に拡張するとのことです(原文:multilayer convolutional network)。わくわくしますね!

 

 

Placeholders について*4

 

まず、画像データやアウトプットを挿入するためのノードを作成。

 

x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])

 

ここで、"x" と "y_" は特定の値ではなく、placeholder であり、あとで数字を代入して使うことができます。

 

解析する画像を表す "x" は浮動小数点を含んだ二次元のテンソルで、784 という数字は、MNIST 画像が 28 x 28 ピクセルで作成されていることから来ています。

 

最初に代入した None はバッチサイズで、None にすることで、後からどんな数字でも挿入することができます。

 

アウトプットを示す "y_" もまた二次元のテンソル。各々の列(row)は one-hot 表現*5 の十次元のベクトル。0-9 の、どれかの数字を表す。*6

 

tf.placeholder 関数で [shape] はオプションなので書かなくても良いが、指定することでバグを回避することができる。

 

 

変数(Variables)

 

重み W とバイアス b を設定します(原文を読むと、他のやり方もありそうですが、今回はこの方法を使う、というニュアンスを受けます)。

 

W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

 

W と b の初期値にゼロを入れ、初期化します。
セッションで Variable を使う前に、初期化する必要があります。初期化作業では、最初の値を設定します(今回はゼロ)。

 

なお、次のコードを実行すると、全ての Variable を一度に初期化することができます。

 

sess.run(tf.global_variables_initializer())

 

 

クラスの予測と損失関数

 

では、回帰モデル(regression model)を設定しましょう。たった一行で設定できます。ベクトルの情報 x と 重み W を掛け合わせ、バイアス b を加えます。

 

y = tf.matmul(x,W) + b

 

# tf.matmul はベクトル内積の計算です*7

 

損失関数は簡単に設定できます。

損失関数は、モデルの予測がいかに悪いかを表すもので、この値を小さくすることを目標に学習を行います。

今回、損失関数として交差エントロピー誤差*8 を利用し、活性化関数(activation function)として Softmax 関数*9 を利用します。

 

cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))

 

 計算結果に対して、 "tf.nn.softmax_cross_entropy_with_logits" の部分でソフトマックスの計算と各々の予測の結果を加算し、tf.reduce_mean の部分でその平均を取ります。

 

 

モデルの学習 (Train the Model)

 

以上でモデルと学習方法を定義しました。この例では、 TensorFlow の自動微分を使用して損失の勾配を検出し、steepest gradient descent アルゴリズムを使い、ステップ長さ 0.5 で学習していきます。


TensorFlow には、他にも多数の最適化アルゴリズムがビルトイン*10されています。

 

train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

 

この一行で、新しい処理を計算グラフに追加します。この処理には、こで勾配を計算し、パラメータ更新ステップを計算し、パラメータを更新する操作が含まれています。

上記の train_step を実行すると、勾配降下法を用いてパラメータを更新します。これを繰り返すことでモデルを訓練(training)することができます。

 

for i in range(1000):
    batch = mnist.train.next_batch(100)
    train_step.run(feed_dict={x: batch[0], y_: batch[1]})

 

 

100例からなるサンプルを使って、繰り返し学習します。次にトレーニング例(training example)を使って feed_dict で placeholder テンソルである x と y_ を置き換えて train_step を実行します(分かりにくくてすみません。まず100例でトレーニングを行い、次にその次の100例を使ってトレーニングする、という作業を繰り返す ようです)。

なお、feed_dict を使えば計算グラフにあるどんなテンソルでも置き換えることができます。Placeholder だけではありません。

 

 

モデルの評価

 

最初にどれだけ正しく判断できたか確認します。
tf.argmax はとても便利な関数で、複数の軸を持つテンソルの中で、最も高い数字が入力されたラベルを示すことができます。例えば、tf.argmax(y,1) は最も可能性が高いラベルを返し、tf.argmax(y_,1)は回答を示します。tf.equalを使って、回答が合っていたを確認します。

 

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

 

この計算式は、ブール値(booleans)を返します。
どの程度正確だったのかを示すため、結果を浮動小数点数で表し、その平均を計算します。例えば、[True, False, True, True] は [1, 0, 1, 1] として表すことができ、0.75 となります。

 

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))


最終的に、精度(accuracy)を計算します。今回の方法では 92% 程度でしょう。

 

print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

 

------------------------------------------------------------------- 

 

 コードのまとめ

上記コードをまとめたもの、さらに、経過時間を計測できるようにしています。

python の interactive session にコピペするだけで動きます。

 

 # コードのまとめ、時間計測付き

 

import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

 

## 時間経過の測定

import time

start = time.time()
time.ctimes(start)

 

sess = tf.InteractiveSession()

 

x = tf.placeholder(tf.float32, shape=[None, 784])

y_ = tf.placeholder(tf.float32, shape=[None, 10])

 

W = tf.Variable(tf.zeros([784,10]))

b = tf.Variable(tf.zeros([10]))

 

sess.run(tf.global_variables_initializer())

y = tf.matmul(x,W) + b

cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))

 

train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

 

for i in range(1000):

    batch = mnist.train.next_batch(100)

    train_step.run(feed_dict={x: batch[0], y_: batch[1]})

 


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(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

 

 

## 時間経過の表示

print("start time = " + (time.ctime(start)))
print("fin time = " + (time.ctime(time.time())))
elapsed_time = time.time() - start
print ("elapsed_time:{0} sec".format(elapsed_time))

 

 

 

 

続いて

pmonty.hatenablog.com

多層のCNN作成へと続きます。

 

 

------------------------------------------------------------------- 

今回は前半部分のみで以上です。

ここまで、隠れ層なしのネットワークである "簡単な" MNIST チュートリアル

 MNIST For ML Beginners  |  TensorFlow の詳しい解説になっていました。

これだけでも 92% の精度が出るのはすごいと思いますが、次回はいよいよ Deep Neural Network を作成し、より高い診断能を目指すものと思います。

*1:TensorFlow relies on a highly efficient C++ backend to do its computation. The connection to this backend is called a session.

*2:The common usage for TensorFlow programs is to first create a graph and then launch it in a session.

*3:Deep Neural Network

*4:プレースホルダー。代理人・代用語。後で文字や数字を代入する場所を示す。

*5:一つのデータだけが True で、他のデータは False を示す表現法 

*6:

 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0] が 0

 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0] が 3

 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0] が 7

 といった表記法

*7:https://www.tensorflow.org/api_docs/python/math_ops/matrix_math_functions#matmul

*8:結果の自然対数計算し、それを加算したもの

*9:結果の和が 1 になるように正規化を行う

*10:Training  |  TensorFlow