TensorFlow GradientDescentOptimizer未按预期成本收敛

时间:2017-10-18 06:15:41

标签: python machine-learning tensorflow

我正在回顾我在Andrew Ng关于ML的课程中所做的材料,并尝试在TensorFlow中实现它。我能够使用scipy的optimize函数来获得0.213的成本,但是使用TensorFlow时,它会停留在0.622,距离0.693的最初损失不远。 1}}使用一组初始权重为零。

我查看了帖子here,并在我的丢失功能中添加了tf.maximum来阻止NaN's。我不相信这是正确的方法,我确信有更好的方法。我也尝试使用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时的成本。我期待它会在更少的迭代中收敛。

1 个答案:

答案 0 :(得分:1)

学会了很多,试图解决这个问题。到目前为止,我没有意识到损失功能的这一部分可能存在问题:

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

如果h(x),即sigmoid函数结果为1(并且如果z,即X * theta出现的话可能会发生)那么我们将评估log(1 - 1)= log (0),这是无限的。

为了解决这个问题,我不得不使用Feature Scaling来标准化我对X的值。这确保X * theta更小,类似z,sigmoid函数不会出现1.当z变大^ -z倾向于零。因此,使用特征缩放确保我们在z中的值相对较小,并且e ^ -z将具有可在分母计算中添加到1的实际值:

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

作为参考,特征缩放仅表示减去均值并除以范围。

(arr - mean) / (max - min)