替换激活函数

当正确率一直很低,无法上升时,可以考虑使用修正线性单元relu来替换sigmoid,目的是得到更快的初始收敛。

tf.nn.relu 替换 tf.nn.sigmoid。

替换优化器

使用更好的优化器,来越过鞍点。

用 tf.train.AdamOptimizer 替换 tf.train.GradientDescentOptimiser。

随机初始化

准确性一直很小,在0.1左右?这时需要把参数随机初始化,对于偏置值,如果用 ReLU 的话,最好的办法就是把它们都初始化成小的正值,这样神经元一开始就会工作在 ReLU 的非零区域内。

W = tf.Variable(tf.truncated_normal([K, L] ,stddev=0.1))

B = tf.Variable(tf.ones([L])/10)

使用softmax_cross_entropy_with_logits

如果你看到你的精确曲线陡然下滑并且调试口输出的交叉熵是 NaN,不用感到头疼,你其实是正在尝试计算 log(0),而这肯定是个不定值(NaN)。还记得吗,交叉熵的计算涉及到对 softmax 层的输出取对数。鉴于 softmax 基本上是一个指数,它肯定不是 0,我们如果用 32 位精度的浮点运算就还好,exp(-100) 基本上可以算作是 0 了。

很幸运,TensorFlow 有一个非常方便的函数可以在单步内计算 softmax 和交叉熵,它是以一种数值上较为稳定的方式实现的。如果要使用它,你需要在应用 softmax 之前将原始的权重和加上你最后一层的偏置隔离开来(在神经网络的术语里叫「logits」)。

如果你模型的最后一行是这样的:

Y = tf.nn.softmax(tf.matmul(Y4, W5) + B5)

你需要把它替换成:

Ylogits = tf.matmul(Y4, W5) + B5Y = tf.nn.softmax(Ylogits)

并且你现在能以一种安全的方式计算交叉熵了:

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(Ylogits, Y_)

同样加上下面这行代码使得测试和训练的交叉熵能够同框显示:

cross_entropy = tf.reduce_mean(cross_entropy)*100

升级 4/4:请把 tf.nn.softmax_cross_entropy_with_logits 加到你的代码里。你也可以跳过这一步,等你真在你的输出里看到 NaN 以后再来做这步。现在,你已经准备好实现「深度」了。

学习率衰减

当学习率一直上下跳动时,表明学习率还是太快了,可以设置一个随迭代衰减的学习率。

指数级衰减的方程:lr = lrmin+(lrmax-lrmin)*exp(-i/2000) 

为了把一个不同的学习率在每次迭代时传给 AdamOptimizer,你需要定义一个新的占位符(placeholder)并在每次迭代时通过 feed_dict 赋给它一个新的参数。

设置dropout

当训练集交叉熵不断下降,测试集交叉熵下降后又上升时,一般是因为过拟合。

为了防止过拟合,我们可以设置dropout=0.5~0.75,从网络中随机放弃一些神经元。



参考:

http://www.sohu.com/a/125061373_465975