python - 无法训练只有一个隐藏层的神经网络

标签 python tensorflow neural-network mnist

我试图通过使用 TensorFlow 识别 MNIST 手写数字来实现具有一个隐藏层的神经网络。我正在使用梯度下降法来训练神经网络。然而,我对 NN 的训练似乎根本不起作用,因为在训练过程中测试精度根本没有改变。

谁能帮我找出问题所在?

这是我的代码。

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data", one_hot=True)

batch_size = 100

n_batch = mnist.train.num_examples // batch_size

x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])

#First layer of the NN
W1 = tf.Variable(tf.zeros([784,10]))
b1 = tf.Variable(tf.zeros([10]))
out1 = tf.nn.softmax(tf.matmul(x, W1) + b1)

#Second layer of the NN
W2 = tf.Variable(tf.zeros([10,10]))
b2 = tf.Variable(tf.zeros([10]))
prediction = tf.nn.softmax(tf.matmul(out1, W2) + b2)

loss = tf.reduce_mean(tf.square(y - prediction))

train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

init = tf.global_variables_initializer()

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(prediction, 1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

with tf.Session() as sess:
    sess.run(init)
    for epoch in range(101):
        for batch in range(n_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            sess.run(train_step, feed_dict={x:batch_xs, y:batch_ys})

        acc = sess.run(accuracy, feed_dict={x:mnist.test.images, y:mnist.test.labels})
        print("Iter " + str(epoch) + ", Testing Accuracy " + str(acc))

最佳答案

不要用全零初始化您的模型。如果这样做,该点(在参数空间中)的梯度很可能也为零。这导致梯度更新不存在,因此您的参数将不会改变。为避免这种情况使用随机初始化

改变

#First layer of the NN
W1 = tf.Variable(tf.zeros([784,10]))
b1 = tf.Variable(tf.zeros([10]))
out1 = tf.nn.softmax(tf.matmul(x, W1) + b1)

#Second layer of the NN
W2 = tf.Variable(tf.zeros([10,10]))
b2 = tf.Variable(tf.zeros([10]))

#First layer of the NN
W1 = tf.Variable(tf.truncated_normal([784,10], stddev=0.1))
b1 = tf.Variable(tf.truncated_normal([10], stddev=0.1))
out1 = tf.nn.sigmoid(tf.matmul(x, W1) + b1)
# out1 = tf.nn.softmax(tf.matmul(x, W1) + b1)

#Second layer of the NN
W2 = tf.Variable(tf.truncated_normal([10,10], stddev=0.1))
b2 = tf.Variable(tf.truncated_normal([10],stddev=0.1))

现在模型可以训练了。您还会看到我从第一层中删除了 softmax 非线性,并将其替换为 sigmoid。我这样做是因为 softmax 层对输出施加了限制:它强制该层的输出加起来为 1(这是它经常用于最后一层的原因之一:实现最终输出的概率解释)。此限制导致模型在快速测试中以 30% 的准确度停止学习。通过使用 sigmoid,准确率达到了 89%,性能要好得多。

您可以在中间层中使用的非线性的其他示例可能是:

  • 双曲正切
  • ReLU

关于python - 无法训练只有一个隐藏层的神经网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50663446/

相关文章:

python - 安装包(Python PIL/Pillow)但我无法导入它

tensorflow - 如何提高 LSTM、GRU 循环神经网络的分类精度

python - 类型错误 : "NoneType" object is not callable in Google Colab

algorithm - matlab中时滞神经网络的反向传播算法

python - 如何聚合热点(探查器)结果并在 kcachegrind 中查看

python - 使用 Visual Studio Code 时出现 ModuleNotFoundError

python - Python是如何将一个函数变成一个方法的?

python - Tensorflow 数据集 API 评估输出形状需要 10 多分钟

java - 如何正确将反向传播神经网络的权重和偏差值导出到另一种编程语言(Java)

java - 创建入侵检测系统输入的算法或 API