TensorFlow0.8から並列分散処理がサポートされるようになりました。
大量のデータに対して高コストな計算を行う機械学習でも、たくさんマシンを並べれば数分〜数時間で終わらせることができるのは魅力ですよね。
どうやって分散するのか気になったので、これからやってみます。
最初のパートでロジスティック回帰のアルゴリズムをおさらいし、「分散しないTensorFlow」でロジスティック回帰を実装します。
次のパートで分散TensorFlowでロジスティック回帰による分類を行います。
使うのはTensorFlowお馴染みの、MNISTの数字手書き画像です。
ロジスティック回帰とは
ロジスティック回帰モデルは目的変数が1となる確率を予測します。
ロジスティック回帰の活用例
- キャンペーンの反応率
- 土砂災害発生危険基準線の確率
- 医療における症例の発生確率
ロジスティック回帰モデル(多クラス分類)
手書きの数字は0〜9の10個に分類する他クラス分類になるので、シュプリンガーのパターン認識と機械学習を参考に、ロジスティック回帰モデルによる多クラス分類を見ていきます。
多クラスの分布に対しては、事後確率が特徴変換のソフトマックス変換で与えられます。
事後確率
活性
最尤法を用いてパラメータwを決定する
すべての活性化関数に関するyの微分が必要となります。
I は単位行列の要素。
ここから尤度関数を出して式変形すると、多クラス分類問題に対する *交差エントロピー誤差関数* になります。
多クラス交差エントロピー誤差関数
勾配
ソフトマックス関数の微分に対する結果を使うと・・・
これを使っています。
他クラス交差エントロピー誤差関数とソフトマックス活性化関数に対しても、「誤差」 と特徴ベクトル との積 という式が得られます。
シングル・ノード版ソースコード
上で得られた式をコードにすると下記のようになります。
TensorFlowは数式とコードの対応が非常にわかりやすいです。
LogisticRegression.py
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data ### パラメータの定義 # Parameters learning_rate = 0.01 training_epochs = 25 batch_size = 100 display_step = 1 ### 手書きの数字画像を訓練データに使う mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) x = tf.placeholder(tf.float32, [None, 784], name="x-input") # mnist の画像サイズ 28*28=784 W = tf.Variable(tf.zeros([784, 10]), name="weights") b = tf.Variable(tf.zeros([10]), name="bias") ### 活性化関数の定義 with tf.name_scope("Wx_b") as scope: y = tf.nn.softmax(tf.matmul(x, W) + b) # matmulは行列積を計算する。↑は内積を計算。 y_ = tf.placeholder(tf.float32, [None,10], name="y-input") # 0〜9 10 classes ### 損失関数の定義 交差エントロピー誤差関数のエラーを最小化する with tf.name_scope("xentropy") as scope: cross_entropy = -tf.reduce_sum(y_*tf.log(y)) ce_summ = tf.scalar_summary("cross entropy", cross_entropy) ### オプティマイザの定義 with tf.name_scope("train") as scope: optimizer = tf.train.GradientDescentOptimizer( learning_rate ).minimize( cross_entropy ) init = tf.initialize_all_variables() ### モデルの訓練 # Launch the graph with tf.Session() as sess: sess.run( init ) # Training cycle for epoch in range(training_epochs): avg_cost = 0. total_batch = int( mnist.train.num_examples / batch_size ) for i in range( total_batch ): batch_xs, batch_ys = mnist.train.next_batch(batch_size) # 訓練フェーズ _, c = sess.run( [optimizer, cross_entropy], feed_dict={x: batch_xs, y_: batch_ys} ) # 損失の平均 avg_cost += c / total_batch if (epoch+1) % display_step == 0: print "Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(avg_cost) print "Optimization Finished!" with tf.name_scope("test") as scope: correct_prediction = tf.equal( tf.argmax(y, 1), tf.argmax(y_, 1) ) accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) accuracy_summary = tf.scalar_summary("accuracy", accuracy) print "Accuracy:", accuracy.eval({x: mnist.test.images[:3000], y_: mnist.test.labels[:3000]}) # 全ての要約をマージしてそれらを /tmp/mnist_logs に書き出します。 merged = tf.merge_all_summaries() writer = tf.train.SummaryWriter("/tmp/mnist_logs", sess.graph_def)
Epoch:0025 cost= 26.540901189 Accuracy: 0.896
精度:0.896。結構良いです。
さて、これを分散するように書き換えたいのですが、長くなってきたので次回にします。
今回のソースコードはこちらです。
LearningLogisticRegression.ipynb
余談ですが・・・
TensorFlow0.9から導入されたLinearClassifierを使った、「バイナリ・データのベクトル化→訓練→推定」のチュートリアルが TensorFlow Linear Model Tutorial に掲載されているのでこちらも今度やってみたいです。
→ 分散TensorFlowでロジスティック回帰 -Distributed TensorFlow- その2 へ