バツイチとインケンのエンジニアブログ
プログラムやプログラムじゃないこと

分散TensorFlowでロジスティック回帰 -Distributed TensorFlow- その1

2016-08-17
書いた人 : バツイチ
カテゴリ : 機械学習 | タグ : TensorFlow, 分散

TensorFlow0.8から並列分散処理がサポートされるようになりました。
大量のデータに対して高コストな計算を行う機械学習でも、たくさんマシンを並べれば数分〜数時間で終わらせることができるのは魅力ですよね。

どうやって分散するのか気になったので、これからやってみます。
最初のパートでロジスティック回帰のアルゴリズムをおさらいし、「分散しないTensorFlow」でロジスティック回帰を実装します。
次のパートで分散TensorFlowでロジスティック回帰による分類を行います。

使うのはTensorFlowお馴染みの、MNISTの数字手書き画像です。

MNIST
MNIST

ロジスティック回帰とは

ロジスティック回帰モデルは目的変数が1となる確率を予測します。

ロジスティック回帰の活用例

  • キャンペーンの反応率
  • 土砂災害発生危険基準線の確率
  • 医療における症例の発生確率

ロジスティック回帰モデル(多クラス分類)

手書きの数字は0〜9の10個に分類する他クラス分類になるので、シュプリンガーのパターン認識と機械学習を参考に、ロジスティック回帰モデルによる多クラス分類を見ていきます。

多クラスの分布に対しては、事後確率が特徴変換のソフトマックス変換で与えられます。

事後確率

 p \big( C_{k} \mid \phi \big) = y_{k} \big( \phi \big) = \frac{exp(a_{k})}{\sum_{j}exp(a_{j})}

活性

 a_{k} = w_{k}^{T}\phi.

最尤法を用いてパラメータwを決定する

すべての活性化関数に関するyの微分が必要となります。

 \frac{\partial y_{k}}{\partial a{j}} = y_{k} \big( I_{kj} - y{j} \big)

I は単位行列の要素。
ここから尤度関数を出して式変形すると、多クラス分類問題に対する *交差エントロピー誤差関数* になります。

多クラス交差エントロピー誤差関数

 E\big( w_{1}, ... , w_{K} \big) = - \ln p \big( T \mid w_{1}, ... , w_{K} \big) = - \sum_{n=1}^{N} \sum_{k=1}^{K} t_{nk} \ln y_{nk}

勾配

ソフトマックス関数の微分に対する結果を使うと・・・

 \nabla E \big( w_{1}, ... , w_{K} \big) = \sum_{n=1}^{N} \big( y_{nj} - t{nj} \big)

これを使っています。

 \sum_{k} t_{nk} = 1

他クラス交差エントロピー誤差関数とソフトマックス活性化関数に対しても、「誤差」 (y_{n} - t_{n}) と特徴ベクトル  \Phi_{n} との積 という式が得られます。

シングル・ノード版ソースコード

上で得られた式をコードにすると下記のようになります。
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 へ

このエントリーをはてなブックマークに追加
Tweet

← Yogibo ヨギボーで快適ダラダラ開発環境を導入した
分散TensorFlowでロジスティック回帰 -Distributed TensorFlow- その2 →

 

最近書いた記事

  • Ryzen7 3800XT でmini ITXオープンフレームPCを作る
  • Pythonで機械学習入門 競馬予測
  • HP ENVY 15 クリエイターモデルレビューとRAID0解除
  • JRA-VAN データラボを使って、競馬データを収集する
  • Surface Pro 3 にubuntu18.04を入れる

カテゴリー

  • Android
  • Apache Flink
  • API
  • AWS
  • bazel
  • BigQuery
  • Cassandra
  • Docker
  • Druid
  • Elasticsearch
  • Git
  • Golang
  • gradle
  • HDFS
  • JavaScript
  • jvm
  • Linux
  • MongoDB
  • MySQL
  • Nginx
  • Nodejs
  • PaaS
  • PHP
  • Python
  • RabbitMQ
  • Raspberry Pi
  • React Native
  • Redis
  • Riak
  • rust
  • scala
  • Scheme
  • SEO
  • solr
  • Spark
  • spray
  • Sublime Text
  • Swift
  • Tableau
  • Unity
  • WebIDE
  • Wordpress
  • Youtube
  • ひとこと
  • カンファレンス
  • スケジューラ
  • マイクロマウス
  • 広告
  • 技術じゃないやつ
  • 株
  • 機械学習
  • 競馬
  • 自作キーボード
  • 自然言語処理

アーカイブ

  • 2021年4月
  • 2021年2月
  • 2021年1月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年9月
  • 2018年5月
  • 2018年3月
  • 2018年2月
  • 2017年9月
  • 2017年8月
  • 2017年6月
  • 2017年4月
  • 2017年3月
  • 2017年1月
  • 2016年10月
  • 2016年9月
  • 2016年8月
  • 2016年6月
  • 2016年5月
  • 2016年4月
  • 2016年3月
  • 2016年2月
  • 2016年1月
  • 2015年12月
  • 2015年11月
  • 2015年10月
  • 2015年9月
  • 2015年8月
  • 2015年6月
  • 2015年5月
  • 2015年2月
  • 2015年1月
  • 2014年12月
  • 2014年11月
  • 2014年9月
  • 2014年6月
  • 2014年5月
  • 2014年3月
  • 2014年2月
  • 2014年1月
  • 2013年12月
  • 2013年11月
  • 2013年10月
  • 2013年9月
  • 2013年8月

書いた人

  • バツイチちゃん
  • インケンくん

このブログについて

エンジニアとしての考え方が間逆な2人がしょーもないこと書いてます。

バツイチ

アイコン

IT業界で働くエンジニアです。名前の通りバツイチです。
理論や抽象的概念が好きだけど人に説明するのが下手。

インケン

アイコン

バツイチちゃんと同じ業界で働いています。
理論とか開発手法とかは正直どうでもよくて、
生活する上で役に立つことに使いたい

Copyright 2025 バツイチとインケンのエンジニアブログ