gpt4 book ai didi

python - 来自tensorflow的AdamOptimizer和GradientDescentOptimizer无法适应简单数据

转载 作者:太空宇宙 更新时间:2023-11-03 10:59:00 25 4
gpt4 key购买 nike

类似问题: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

剧情如下:

enter image description here

然后我更改了代码以使用梯度下降:

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

剧情如下:

enter image description here

我的问题:

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()

最佳答案

TLDR;你的损失是错误的。在不降低准确性的情况下损失变为零。

问题是你的概率没有标准化。如果您查看损失,它会下降,但是 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com