微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – tensorflow的AdamOptimizer和GradientDescentOptimizer无法适应简单的数据

类似的问题: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:你能分享你用来制作上图的代码吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐