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 へ
