MNIST 分类:准确率低(10%),损失没有变化
Posted
技术标签:
【中文标题】MNIST 分类:准确率低(10%),损失没有变化【英文标题】:MNIST Classification: low accuracy (10%) and no change in loss 【发布时间】:2018-04-29 11:48:27 【问题描述】:我正在学习 TensorFlow,并且厌倦了申请 mnist 数据库。 我的问题是(见附图):
什么会导致这种输出的准确性(提高然后降低!)和损失(几乎恒定!) 准确度不是很好,只是徘徊在 10% 左右尽管:
5层网络(包括输出层),分别有200/10/60/30/10个神经元 网络不学习了吗?尽管学习率为 0.1(我相信这相当高)完整代码:https://github.com/vibhorj/tf> mnist-2.py
1) 下面是定义层的方式:
K,L,M,N=200,100,60,30
""" Layer 1 """
with tf.name_scope('L1'):
w1 = tf.Variable(initial_value = tf.truncated_normal([28*28,K],mean=0,stddev=0.1), name = 'w1')
b1 = tf.Variable(initial_value = tf.truncated_normal([K],mean=0,stddev=0.1), name = 'b1')
""" Layer 2 """
with tf.name_scope('L2'):
w2 = tf.Variable(initial_value =tf.truncated_normal([K,L],mean=0,stddev=0.1), name = 'w2')
b2 = tf.Variable(initial_value = tf.truncated_normal([L],mean=0,stddev=0.1), name = 'b2')
""" Layer 3 """
with tf.name_scope('L3'):
w3 = tf.Variable(initial_value = tf.truncated_normal([L,M],mean=0,stddev=0.1), name = 'w3')
b3 = tf.Variable(initial_value = tf.truncated_normal([M],mean=0,stddev=0.1), name = 'b3')
""" Layer 4 """
with tf.name_scope('L4'):
w4 = tf.Variable(initial_value = tf.truncated_normal([M,N],mean=0,stddev=0.1), name = 'w4')
b4 = tf.Variable(initial_value = tf.truncated_normal([N],mean=0,stddev=0.1), name = 'b4')
""" Layer output """
with tf.name_scope('L_out'):
w_out = tf.Variable(initial_value = tf.truncated_normal([N,10],mean=0,stddev=0.1), name = 'w_out')
b_out = tf.Variable(initial_value = tf.truncated_normal([10],mean=0,stddev=0.1), name = 'b_out')
2) 损失函数
Y1 = tf.nn.sigmoid(tf.add(tf.matmul(X,w1),b1), name='Y1')
Y2 = tf.nn.sigmoid(tf.add(tf.matmul(Y1,w2),b2), name='Y2')
Y3 = tf.nn.sigmoid(tf.add(tf.matmul(Y2,w3),b3), name='Y3')
Y4 = tf.nn.sigmoid(tf.add(tf.matmul(Y3,w4),b4), name='Y4')
Y_pred_logits = tf.add(tf.matmul(Y4, w_out),b_out,name='logits')
Y_pred_prob = tf.nn.softmax(Y_pred_logits, name='probs')
error = -tf.matmul(Y
, tf.reshape(tf.log(Y_pred_prob),[10,-1]), name ='err')
loss = tf.reduce_mean(error, name = 'loss')
3) 优化函数
opt = tf.train.GradientDescentOptimizer(0.1)
grads_and_vars = opt.compute_gradients(loss)
ctr = tf.Variable(0.0, name='ctr')
z = opt.apply_gradients(grads_and_vars, global_step=ctr)
4)张量板代码:
evt_file = tf.summary.FileWriter('/Users/vibhorj/python/-tf/g_mnist')
evt_file.add_graph(tf.get_default_graph())
s1 = tf.summary.scalar(name='accuracy', tensor=accuracy)
s2 = tf.summary.scalar(name='loss', tensor=loss)
m1 = tf.summary.merge([s1,s2])
5) 运行会话(测试数据为 mnist.test.images & mnist.test.labels
with tf.Session() as sess:
sess.run(tf.variables_initializer(tf.global_variables()))
for i in range(300):
""" calc. accuracy on test data - TENSORBOARD before iteration beings """
summary = sess.run(m1, feed_dict=test_data)
evt_file.add_summary(summary, sess.run(ctr))
evt_file.flush()
""" fetch train data """
a_train, b_train = mnist.train.next_batch(batch_size=100)
train_data = X: a_train , Y: b_train
""" train """
sess.run(z, feed_dict = train_data)
感谢您抽出宝贵时间提供有关它的任何见解。我完全不知道如何继续进行(甚至尝试使用 random_normal 初始化 w & b,使用学习率 [0.1,0.01, 0.001])
干杯!
【问题讨论】:
您是否有一个 Gist 或公共 repo,我们可以通过检查来找到问题?我进行了快速回顾,但在此页面上浏览此类代码非常耗时。到目前为止的评论:也许是名称范围的东西。 非常感谢您的关注! github.com/vibhorj/tf > mnist-2.py 基本问题:(1) 您的架构与经典的 MNIST 解决方案相比如何? (2) 是否有类似的、更广泛的拓扑结构可以很好地训练?例如,如果将第二层从 10 个神经元更改为 30 个神经元,会发生什么?这些检查将有助于缩小问题范围(消除拓扑问题)。 TF 和 MNiST 有公开的例子,请阅读文档 【参考方案1】:请考虑
-
将偏差初始化为零
使用 ReLU 单元代替 sigmoid - 避免饱和
使用 Adam 优化器 - 更快的学习
我觉得你的网络很大。您可以使用较小的网络。
K,L,M,N=200,100,60,30
""" Layer 1 """
with tf.name_scope('L1'):
w1 = tf.Variable(initial_value = tf.truncated_normal([28*28,K],mean=0,stddev=0.1), name = 'w1')
b1 = tf.zeros([K])#tf.Variable(initial_value = tf.truncated_normal([K],mean=0,stddev=0.01), name = 'b1')
""" Layer 2 """
with tf.name_scope('L2'):
w2 = tf.Variable(initial_value =tf.truncated_normal([K,L],mean=0,stddev=0.1), name = 'w2')
b2 = tf.zeros([L])#tf.Variable(initial_value = tf.truncated_normal([L],mean=0,stddev=0.01), name = 'b2')
""" Layer 3 """
with tf.name_scope('L3'):
w3 = tf.Variable(initial_value = tf.truncated_normal([L,M],mean=0,stddev=0.1), name = 'w3')
b3 = tf.zeros([M]) #tf.Variable(initial_value = tf.truncated_normal([M],mean=0,stddev=0.01), name = 'b3')
""" Layer 4 """
with tf.name_scope('L4'):
w4 = tf.Variable(initial_value = tf.truncated_normal([M,N],mean=0,stddev=0.1), name = 'w4')
b4 = tf.zeros([N])#tf.Variable(initial_value = tf.truncated_normal([N],mean=0,stddev=0.1), name = 'b4')
""" Layer output """
with tf.name_scope('L_out'):
w_out = tf.Variable(initial_value = tf.truncated_normal([N,10],mean=0,stddev=0.1), name = 'w_out')
b_out = tf.zeros([10])#tf.Variable(initial_value = tf.truncated_normal([10],mean=0,stddev=0.1), name = 'b_out')
Y1 = tf.nn.relu(tf.add(tf.matmul(X,w1),b1), name='Y1')
Y2 = tf.nn.relu(tf.add(tf.matmul(Y1,w2),b2), name='Y2')
Y3 = tf.nn.relu(tf.add(tf.matmul(Y2,w3),b3), name='Y3')
Y4 = tf.nn.relu(tf.add(tf.matmul(Y3,w4),b4), name='Y4')
Y_pred_logits = tf.add(tf.matmul(Y4, w_out),b_out,name='logits')
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y, logits=Y_pred_logits, name='xentropy'))
opt = tf.train.GradientDescentOptimizer(0.01)
grads_and_vars = opt.compute_gradients(loss)
ctr = tf.Variable(0.0, name='ctr', trainable=False)
train_op = opt.minimize(loss, global_step=ctr)
for v in tf.trainable_variables():
print v.op.name
with tf.Session() as sess:
sess.run(tf.variables_initializer(tf.global_variables()))
for i in range(3000):
""" calc. accuracy on test data - TENSORBOARD before iteration beings """
#summary = sess.run(m1, feed_dict=test_data)
#evt_file.add_summary(summary, sess.run(ctr))
#evt_file.flush()
""" fetch train data """
a_train, b_train = mnist.train.next_batch(batch_size=100)
train_data = X: a_train , Y: b_train
""" train """
l = sess.run(loss, feed_dict = train_data)
print l
sess.run(train_op, feed_dict = train_data)
【讨论】:
非常感谢分享小费。在 1) 将偏差初始化为 0 之后,2) 激活 RELU 除了输出层损失为 nan 并且准确度没有变化(9.79%)。甚至将学习率降低到 0.00001 你能分享你最新的代码吗?我可以看到我上面发布的代码的损失正在下降。 给你github.com/vibhorj/tf/blob/master/so-changes/mnist-2-so.py 非常感谢!有趣的是,代码看起来非常相似,但你并没有想到损失会下降。可能是因为我没有使用内置函数 tf.nn.softmax_cross_entropy_with_logits() 进行损失计算吗? 请问您为什么建议将偏差初始化为 0?它有什么含义..大多数人说使用随机值进行初始化.. 这是惯例。对于 relu 单元,一个小的正值可能是好的,因为它可以确保梯度最初流动。以上是关于MNIST 分类:准确率低(10%),损失没有变化的主要内容,如果未能解决你的问题,请参考以下文章
深度学习原理与框架-Tensorflow卷积神经网络-神经网络mnist分类
基于pytorch后量化(mnist分类)---浮点训练vs多bit后量化vs多bit量化感知训练效果对比
第四讲 网络八股拓展--用mnist数据集实现断点续训, 绘制准确图像和损失图像