类似问题:Here
我在试TensorFlow。我生成了简单的数据,这些数据是线性可分的,并试图将线性方程拟合到其中。这是密码。
np.random.seed(2010)
n = 300
x_data = np.random.random([n, 2]).tolist()
y_data = [[1., 0.] if v[0]> 0.5 else [0., 1.] for v in x_data]
x = tf.placeholder(tf.float32, [None, 2])
W = tf.Variable(tf.zeros([2, 2]))
b = tf.Variable(tf.zeros([2]))
y = tf.sigmoid(tf.matmul(x , W) + b)
y_ = tf.placeholder(tf.float32, [None, 2])
cross_entropy = -tf.reduce_sum(y_ * tf.log(tf.clip_by_value(y, 1e-9, 1)))
train_step = tf.train.AdamOptimizer(0.01).minimize(cross_entropy)
correct_predict = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_predict, tf.float32))
s = tf.Session()
s.run(tf.initialize_all_variables())
for i in range(10):
s.run(train_step, feed_dict = {x: x_data, y_: y_data})
print(s.run(accuracy, feed_dict = {x: x_data, y_: y_data}))
print(s.run(accuracy, feed_dict = {x: x_data, y_: y_data}), end=",")
我得到以下输出:
0.536667、0.46、0.46、0.46、0.46、0.46、0.46、0.46、0.46、0.46、0.46、0.46
在第一次迭代之后,它在
0.46
处被击中。情节如下:
然后我把代码改成梯度下降:
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
现在我得到了以下结果:0.54,0.54,0.63,0.70,0.75,0.8,0.84,0.89,0.92,0.94,0.94
情节如下:
我的问题:
1)为什么AdamopTimizer失败?
2)如果问题是学习速度或其他需要调整的参数,我通常如何调试它们?
3)我运行梯度下降50次(我运行10次以上),每5次打印一次精度,这是输出:
0.54、0.8、0.95、0.96、0.92、0.89、0.87、0.84、0.81、0.79、0.77。
很明显,它开始发散,看起来问题在于固定的学习率(在一个点之后是超调的)我说得对吗?
4)在这个玩具示例中,可以做些什么来获得更好的适合性。理想情况下,它应该有1.0的精度,因为数据是线性可分的。
[编辑]
根据@yaroslav的请求,下面是用于绘图的代码
xx = [v[0] for v in x_data]
yy = [v[1] for v in x_data]
x_min, x_max = min(xx) - 0.5, max(xx) + 0.5
y_min, y_max = min(yy) - 0.5, max(yy) + 0.5
xxx, yyy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))
pts = np.c_[xxx.ravel(), yyy.ravel()].tolist()
# ---> Important
z = s.run(tf.argmax(y, 1), feed_dict = {x: pts})
z = np.array(z).reshape(xxx.shape)
plt.pcolormesh(xxx, yyy, z)
plt.scatter(xx, yy, c=['r' if v[0] == 1 else 'b' for v in y_data], edgecolor='k', s=50)
plt.show()
最佳答案
你的损失是错的在不降低精度的情况下,损耗归零。
问题是你的概率没有标准化如果你看一下你的损失,它会下降,但是y[:0]
和y[:1]
的概率都是1,所以argmax是没有意义的。
传统的解决方案是只使用1个自由度而不是2个自由度,所以第一类的概率是sigmoid(y)
,第二类的概率是1-sigmoid(y)
,所以交叉熵类似于-y[0]log(sigmoid(y0)) - y[1]log(1-sigmoid(y0))
或者,您可以更改代码,使用tf.nn.softmax
而不是tf.sigmoid
。这除以概率之和,这样优化器就不能通过同时将两个概率都驱动到1来减少损失。
以下是0.99666673
的准确度。
tf.reset_default_graph()
np.random.seed(2010)
n = 300
x_data = np.random.random([n, 2]).tolist()
y_data = [[1., 0.] if v[0]> 0.5 else [0., 1.] for v in x_data]
x = tf.placeholder(tf.float32, [None, 2])
W = tf.Variable(tf.zeros([2, 2]))
b = tf.Variable(tf.zeros([2]))
y = tf.nn.softmax(tf.matmul(x , W) + b)
y_ = tf.placeholder(tf.float32, [None, 2])
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
regularizer = tf.reduce_sum(tf.square(y))
train_step = tf.train.AdamOptimizer(1.0).minimize(cross_entropy+regularizer)
correct_predict = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_predict, tf.float32))
s = tf.Session()
s.run(tf.initialize_all_variables())
for i in range(30):
s.run(train_step, feed_dict = {x: x_data, y_: y_data})
cost1,cost2=s.run([cross_entropy,accuracy], feed_dict = {x: x_data, y_: y_data})
print(cost1, cost2)
PS:你能分享一下你用来绘制上面这些图的代码吗?
关于python - tensorflow 的AdamOptimizer和GradientDescentOptimizer无法拟合简单数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36468701/