![](/img/trans.png)
[英]What is the best way to create a deep neural network (with 100+ layers) using custom layers in tensorflow?
[英]How to create 2-layers neural network using TensorFlow and python on MNIST data
我是机器学习的新手,我正在按照tensorflow的教程创建一些简单的神经网络,以学习MNIST数据。
我已经建立了一个单层网络(遵循tutotial),精度约为0.92,对我来说还可以。 但是后来我又增加了一层,精度降低到0.113,这是非常糟糕的。
以下是两层之间的关系:
import tensorflow as tf
x = tf.placeholder(tf.float32, [None, 784])
#layer 1
W1 = tf.Variable(tf.zeros([784, 100]))
b1 = tf.Variable(tf.zeros([100]))
y1 = tf.nn.softmax(tf.matmul(x, W1) + b1)
#layer 2
W2 = tf.Variable(tf.zeros([100, 10]))
b2 = tf.Variable(tf.zeros([10]))
y2 = tf.nn.softmax(tf.matmul(y1, W2) + b2)
#output
y = y2
y_ = tf.placeholder(tf.float32, [None, 10])
我的结构还好吗? 是什么原因使其性能如此差? 我应该如何修改我的网络?
第二层的输入是第一层输出的softmax
。 你不想那样做。
您将这些值的总和强制为1。如果tf.matmul(x, W1) + b1
某些值约为0(并且某些值肯定是),softmax操作会将其降低为0。结果:您正在消除梯度,没有任何东西可以通过这些神经元。
如果您删除了各层之间的softmax(但如果您想将这些值视为概率,则将其保留在输出层上),则网络将正常工作。
Tl; dr:
import tensorflow as tf
x = tf.placeholder(tf.float32, [None, 784])
#layer 1
W1 = tf.Variable(tf.zeros([784, 100]))
b1 = tf.Variable(tf.zeros([100]))
y1 = tf.matmul(x, W1) + b1 #remove softmax
#layer 2
W2 = tf.Variable(tf.zeros([100, 10]))
b2 = tf.Variable(tf.zeros([10]))
y2 = tf.nn.softmax(tf.matmul(y1, W2) + b2)
#output
y = y2
y_ = tf.placeholder(tf.float32, [None, 10])
遇到了完全相同的问题,梯度发散并为预测y
得到了一堆nan
。 不幸的是,按照nessuno的建议实施,发散的梯度仍然不固定。
相反,我尝试将sigmoid
用作第1层的激活功能,它起作用了! 但是因为如果将W1
和W2
初始化为零矩阵,则relu
无法正常工作,因此精度仅为0.1135。 为了使relu
和sigmoid
都能工作,最好随机化W1
和W2
的初始化。 这是修改后的代码
import tensorflow as tf
x = tf.placeholder(tf.float32, [None, 784])
# layer 1
with tf.variable_scope('layer1'):
W1 = tf.get_variable('w1',[784,200],
initializer=tf.random_normal_initializer())
b1 = tf.get_variable('b1',[1,],
initializer=tf.constant_initializer(0.0))
y1 = tf.nn.sigmoid(tf.matmul(x, W1) + b1)
# y1 = tf.nn.relu(tf.matmul(x, W1) + b1) # alternative choice for activation
# layer 2
with tf.variable_scope('layer2'):
W2 = tf.get_variable('w2',[200,10],
initializer= tf.random_normal_nitializer())
b2 = tf.get_variable('b2',[1,],
initializer=tf.constant_initializer(0.0))
y2 = tf.nn.softmax(tf.matmul(y1, W2) + b2)
# output
y = y2
y_ = tf.placeholder(tf.float32, [None, 10])
我发现此链接很有用,请参阅问题2(c),其中提供了基本2层神经网络的反向传播导数。 在我看来,当用户未指定任何接受函数时,只需在第1层中应用线性流,最终将对(sth)*W2^T*W1^T
的梯度进行反向传播,并同时初始化W1
如果W2
为零,则它们的乘积可能非常小,接近于零,从而导致梯度消失。
更新
这是Ofir Ofir在Quora上发表的关于神经网络中良好初始权重的答案。
最常见的初始化是随机初始化和Xavier初始化。 随机初始化仅从标准分布(通常为正态分布)中以低偏差对每个权重进行采样。 低偏差使您可以将网络偏向“简单” 0解决方案,而不会产生将权重实际初始化为0的不良影响。
我试图运行上面的代码段。 低于90%的结果被丢弃,我从来没有真正确定自己做了上面的评论。 这是我的完整代码。
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
x = tf.placeholder(tf.float32, [None, 784])
#layer 1
W1 = tf.get_variable('w1', [784, 100], initializer=tf.random_normal_initializer())
b1 = tf.get_variable('b1', [1,], initializer=tf.random_normal_initializer())
y1 = tf.nn.sigmoid(tf.matmul(x, W1) + b1)
#layer 2
W2 = tf.get_variable('w2',[100,10], initializer=
tf.random_normal_initializer())
b2 = tf.get_variable('b2',[1,], initializer=tf.random_normal_initializer())
y2 = tf.nn.softmax(tf.matmul(y1, W2) + b2)
#output
y = y2
y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y),
reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(cross_entropy)
sess = tf.InteractiveSession()
tf.global_variables_initializer().run()
for _ in range(10000):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_:
mnist.test.labels}))
通过更改10000-> 200000,我达到了95.5%。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.