为什么我的 GradientDescentOptimizer 产生 NaN?
Why does my GradientDescentOptimizer produce NaN?
我目前正在修改 Andrew Ng 教授在 Coursera 上的 "Machine Learning" 课程作业,但我陷入了逻辑回归部分。
filename = 'data/ex2data1.txt'
data = np.loadtxt(filename, delimiter = ",", unpack = True)
# Data matrices
xtr = np.transpose(np.array(data[:-1]))
ytr = np.transpose(np.array(data[-1:]))
# Initial weights
W = tf.Variable(tf.zeros([2,1], dtype = tf.float64))
# Bias
b = tf.Variable(tf.zeros([1], dtype = tf.float64))
# Cost function
y_ = tf.nn.sigmoid(tf.matmul(xtr,W) + b)
cost = -tf.reduce_mean(ytr*tf.log(y_) + (1-ytr)*tf.log(1-y_))
optimize = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
corr = tf.equal(tf.argmax(ytr,1), tf.argmax(y_,1))
acc = tf.reduce_mean(tf.cast(corr, tf.float64))
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
print(sess.run(cost))
for _ in range(3):
sess.run(optimize)
print(sess.run(cost))
这产生了答案:
0.69314718056
nan
nan
nan
成本函数的第一个结果是正确的,但接下来的结果应该是:
3.0133
1.5207
0.7336
相反,我得到了一堆 NaN。我试过降低学习率,但都无济于事。我究竟做错了什么?是否可以在 TensorFlow 中重现此作业?
PS:其他 python 解决方案似乎正在使用 scipy.optimize 但我不知道如何将其与 TensorFlow 值一起使用,如果完全有可能。
编辑:我也试过将偏差设为 tf.ones 而不是 tf.zeros,但它也没有用。
您的对数未对输入进行清理。很可能您有负输入值,可以快速 NaN 任何浮点数运算。
What I did in Java code that makes heavy use of logs in similar domain:
- 检查 NaN 或 Infinity 并假定输出为零
- 如果输入为负数,则将输出裁剪为某个静态数字,例如。日志 (1e-5) ~= -11.51
- 否则只拿日志
在 Java 中,代码看起来像这样,应该不难翻译成 tf:
public static double guardedLogarithm(double input) {
if (Double.isNaN(input) || Double.isInfinite(input)) {
return 0d;
} else if (input <= 0d || input <= -0d) {
// assume a quite low value of log(1e-5) ~= -11.51
return -10d;
} else {
return FastMath.log(input);
}
}
我目前正在修改 Andrew Ng 教授在 Coursera 上的 "Machine Learning" 课程作业,但我陷入了逻辑回归部分。
filename = 'data/ex2data1.txt'
data = np.loadtxt(filename, delimiter = ",", unpack = True)
# Data matrices
xtr = np.transpose(np.array(data[:-1]))
ytr = np.transpose(np.array(data[-1:]))
# Initial weights
W = tf.Variable(tf.zeros([2,1], dtype = tf.float64))
# Bias
b = tf.Variable(tf.zeros([1], dtype = tf.float64))
# Cost function
y_ = tf.nn.sigmoid(tf.matmul(xtr,W) + b)
cost = -tf.reduce_mean(ytr*tf.log(y_) + (1-ytr)*tf.log(1-y_))
optimize = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
corr = tf.equal(tf.argmax(ytr,1), tf.argmax(y_,1))
acc = tf.reduce_mean(tf.cast(corr, tf.float64))
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
print(sess.run(cost))
for _ in range(3):
sess.run(optimize)
print(sess.run(cost))
这产生了答案:
0.69314718056
nan
nan
nan
成本函数的第一个结果是正确的,但接下来的结果应该是:
3.0133
1.5207
0.7336
相反,我得到了一堆 NaN。我试过降低学习率,但都无济于事。我究竟做错了什么?是否可以在 TensorFlow 中重现此作业?
PS:其他 python 解决方案似乎正在使用 scipy.optimize 但我不知道如何将其与 TensorFlow 值一起使用,如果完全有可能。
编辑:我也试过将偏差设为 tf.ones 而不是 tf.zeros,但它也没有用。
您的对数未对输入进行清理。很可能您有负输入值,可以快速 NaN 任何浮点数运算。
What I did in Java code that makes heavy use of logs in similar domain:
- 检查 NaN 或 Infinity 并假定输出为零
- 如果输入为负数,则将输出裁剪为某个静态数字,例如。日志 (1e-5) ~= -11.51
- 否则只拿日志
在 Java 中,代码看起来像这样,应该不难翻译成 tf:
public static double guardedLogarithm(double input) {
if (Double.isNaN(input) || Double.isInfinite(input)) {
return 0d;
} else if (input <= 0d || input <= -0d) {
// assume a quite low value of log(1e-5) ~= -11.51
return -10d;
} else {
return FastMath.log(input);
}
}