48901


『[機械学習 はじめよう 第20回](http://gihyo.jp/dev/serial/01/machine-
learning/0020)』を参考にして、ロジスティック回帰をTensorflowを用いて実装しようと考えていますが、重み・バイアスがすぐにnanになってしまいます。

調べたところ、対数尤度関数のlogが怪しい、ということでlogの中身に小さい数（1e-5など）を足してみたりしましたが変わりませんでした。

Tensorflowにも不慣れですので他の部分にも不具合があるかもしれません。  
何が原因と考えられますでしょうか。  
ご教授いただければ幸いです。

list: logistic_tf.py

[code]

    import numpy as np
    import tensorflow as tf
    
    def sigmoid(z):
        return 1.0 / (1.0 + tf.exp(-z))
    
    x_d = tf.placeholder(tf.float32, shape=(None, 2), name='x_d')
    t_d = tf.placeholder(tf.float32, shape=(None, ), name='t_d')
    
    W = tf.Variable(tf.zeros([2, 1]))
    b = tf.Variable(tf.zeros([1]))
    t = sigmoid(tf.matmul(x_d, W) + b)
    
    loss = - tf.reduce_sum(t_d * tf.log(t) + (1 - t_d) * tf.log(1 - t))
    optimizer = tf.train.GradientDescentOptimizer(0.1)
    train = optimizer.minimize(loss)
    
    init = tf.global_variables_initializer()
    
    sess = tf.Session()
    sess.run(init)
    
    # create data set
    def h(x, y):
        return 5 * x + 3 * y - 1
    x_data = np.random.randn(100, 2).astype('float32')
    t_data = np.array([1 if h(x, y) > 0 else 0 for x, y in x_data])
    
    for step in range(200):
        sess.run(train, feed_dict={x_d: x_data, t_d: t_data})
        if step % 10 == 0:
            print(step, sess.run(W), sess.run(b))
            # W = [[5], [3]], b = [-1], expected
    
    sess.close() 
    
[/code]

9/27追記  
学習率を0.1から0.01,
0.001と下げたところ、0.01ではnanになりました。0.001ではnanは回避できましたが、期待される値とは別のところで振動してしまいました。損失関数が間違っているということでしょうか。どのように修正すべきでしょうか。

学習率0.001のときの出力

[code]

    0 [[ 0.33279842]
     [-0.0880626 ]] [-1.4000001]
    1000 [[ 1.2017732 ]
     [-0.18360852]] [-2.0046742]
    2000 [[ 1.2017722 ] 
     [-0.18360843]] [-2.0046737]
    3000 [[ 1.2017732 ]
     [-0.18360852]] [-2.0046742]
    4000 [[ 1.2017722 ]
     [-0.18360843]] [-2.0046737]
    5000 [[ 1.2017732 ]
     [-0.18360852]] [-2.0046742]
    6000 [[ 1.2017722 ]
     [-0.18360843]] [-2.0046737]
    7000 [[ 1.2017732 ]
     [-0.18360852]] [-2.0046742]
    8000 [[ 1.2017722 ]
     [-0.18360843]] [-2.0046737]
    9000 [[ 1.2017732 ]
     [-0.18360852]] [-2.0046742]
    
[/code]


CC BY-SA 4.0
2018-09-13T13:52:32.657
48368
2018-10-02T10:05:47.707
2018-09-27T01:58:14.160
3060
30100
question
python tensorflow
Tensorflowを用いたロジスティック回帰で重みがnanになる


2点問題がありそうです  
1\. 学習データの作成がループの外で1回のみ行われ1回の学習でそのデータを全て使っており  
毎回同じ学習となっている。  
2\. ラベルの形が[None]となっており、教師データ正解全体で評価がなされている

上記修正したところ2000回の学習で  
W:[[13.174871],[ 7.863011]] b:[-2.5919526]となり  
元の式に対してスカラ倍した形の式(2.6*(5x+3y-1))に近い形になっており正解と言えそうです。

[code]

    import numpy as np
    import tensorflow as tf
    
    def sigmoid(z):
        return 1.0 / (1.0 + tf.exp(-z))
    
    x_d = tf.placeholder(tf.float32, shape=(None, 2), name='x_d')
    t_d = tf.placeholder(tf.float32, shape=(None, 1), name='t_d') # [1]をラベルとする
    
    W = tf.Variable(tf.zeros([2, 1]))
    b = tf.Variable(tf.zeros([1]))
    t = sigmoid(tf.matmul(x_d, W) + b)
    
    #loss = - tf.reduce_sum(t_d * tf.log(t) + (1 - t_d) * tf.log(1 - t))
    loss = -tf.reduce_sum(t_d * tf.log(tf.clip_by_value(t,1e-10,1.0)) + (1 - t_d) * tf.log(tf.clip_by_value(1-t,1e-10,1.0))) #log(0)対策
    optimizer = tf.train.GradientDescentOptimizer(0.01)
    train = optimizer.minimize(loss)
    
    init = tf.global_variables_initializer()
    
    sess = tf.Session()
    sess.run(init)
    
    # create data set
    def h(x, y):
        return 5 * x + 3 * y - 1
    
    
    for step in range(2000):
        x_data = np.random.randn(100, 2).astype('float32')
        t_data = np.array([[1] if h(x, y) > 0 else [0] for x, y in x_data]) #[None,1]の形で返す
        sess.run(train, feed_dict={x_d: x_data, t_d: t_data})
        if step % 10 == 0:
            print(step, sess.run(W), sess.run(b))
            print(step,sess.run(loss,feed_dict={x_d: x_data, t_d: t_data}))
            # W = [[5], [3]], b = [-1], expected
    
    sess.close() 
    
[/code]

なお、今回はログに学習進捗を出力していますが  
学習進捗はtensorboardを使用した方が便利かと思います。  
<https://www.tensorflow.org/guide/summaries_and_tensorboard>

また、sigmoid関数やcrossentroy関数も自前で定義せずともAPIとして用意されているのでそちらもご確認ください。  
<https://www.tensorflow.org/api_docs/python/tf/losses/sigmoid_cross_entropy>


CC BY-SA 4.0
2018-10-02T10:05:47.707
48901
2018-10-02T10:05:47.707
19716
48368
answer