2017-10-18 71 views
0

我正在评论我在Andrew Ng的ML课上做过的材料,并试图在TensorFlow中实现它。我能够使用scipy的optimize函数来获得0.213的成本,但是对于TensorFlow,它被卡在0.622,离初始损失0.693不太远,使用初始权重为零的初始损失。TensorFlow GradientDescentOptimizer没有收敛于预期成本

我审查后here,并添加了tf.maximum调用我的损失功能,防止NaN的。我不相信这是正确的方法,我相信有更好的方法。我也尝试使用tf.clip_by_value来代替,但它给出了相同的非优化成本。

iterations = 1500 

with tf.Session() as sess: 
    X = tf.placeholder(tf.float32) 
    y = tf.placeholder(tf.float32) 
    theta = tf.Variable(tf.zeros([3,1]), dtype=tf.float32) 
    training_rows = tf.placeholder(tf.float32) 
    z = tf.matmul(X, theta) 
    h_x = 1.0/(1.0 + tf.exp(-z)) 
    lhs = tf.matmul(tf.transpose(-y), tf.log(tf.maximum(1e-5, h_x))) 
    rhs = tf.matmul(tf.transpose((1 - y)), tf.log(tf.maximum(1e-5, 1 - h_x))) 
    loss = tf.reduce_sum(lhs - rhs)/training_rows 
    alpha = 0.001 
    optimizer = tf.train.GradientDescentOptimizer(alpha) 
    train = optimizer.minimize(loss) 

    # Run the session 
    X_val, y_val = get_data() 
    rows = X_val.shape[0] 
    kwargs = {X: X_val, y: y_val, training_rows: rows} 
    sess.run(tf.global_variables_initializer()) 
    sess.run(tf.assign(theta, np.array([0,0,0]).reshape(3,1))) 
    print("Original cost before optimization is: {}".format(sess.run(loss, kwargs))) 
    print("Optimizing loss function") 
    costs = [] 
    for i in range(iterations): 
     optimal_theta, result = sess.run([theta, train], {X: X_val, y: y_val, training_rows: rows}) 
     cost = sess.run(loss, kwargs) 
     costs.append(cost) 
    optimal_theta,loss = sess.run([theta, loss], {X: X_val, y: y_val, training_rows: rows}) 
    print("Optimal value for theta is: {} with a loss of: {}".format(optimal_theta, loss)) 
    plt.plot(costs) 
    plt.show() 

我也注意到,任何学习速度比0.001更大会导致优化跳舞似地来回的损失。这是正常的吗?最后,当我尝试将迭代次数增加到25,000时,我意识到成本降低到0.53。我期待它会以更少的迭代收敛。

回答

0

学习了很多,试图找出这一点。到目前为止首先,我并没有意识到,损失这部分功能可能是有问题的:

loss = -y log(h(x)) + (1 - y) (log(1 - h(x))) 

如果H(X),这是双曲线函数原来是1(它可以发生,如果z,即X * theta变大),那么我们将评估log(1 - 1)= log(0),这是无限的。

为了解决这个问题,我不得不使用Feature Scaling来规范X的值。这确保了X * theta更小,并且同样z,sigmoid函数不会出现1.当z变大e^-z倾向于零。因此,在使用缩放功能保证了我们在z值相对较小和e^-z将有可能在分母计算被添加到1的实际值:

z = 1/(1 + e^-(X*theta)) 

以供参考,特征缩放刚意味着减去均值并除以范围。

(arr - mean)/(max - min)