TensorFlow and deep learning,without a PHD 第7章 中文

实验:深度网络的特殊调整

随着层数的增加,神经网络的训练越来越难收敛。

但我们今天就会知道如何使训练能收敛。

如果您看到像下面这张图的准确度变化的曲线:

其实只需要做1行代码的修改,就能解决不收敛的问题。

1.改用Relu激活函数

sigmoid激活函数在深网络中实际上是有很大问题的。

sigmoid函数会把输入压缩0到1之间的所有值,如果当你重复使用sigmoid函数,神经元的输出及其梯度可以完全消失。

(类似于一个常数A不断地乘一个0-1之间的数,会导致A渐渐趋近于0)

之前用sigmoid激活函数只是因为历史的原因才用到它。

而现代的网络使用Relu激活函数,它看起来是这样的:

代码修改:

现在只要用Relu激活函数替换所有的sigmoid函数,您将得到更快的初始收敛速度,并在以后添加层数的时后避免网络无法训练的问题。

只需在代码中用tf.nn.sigmoid与tf.nn.relu交换即可。

2.换一个更好的优化器

在我们手写数字识别的这个高维空间中,我们有大约1万个的权重w和偏置b参数,这意味着“马鞍点”会很常见。这些点其实不是局部最小值,但是梯度却为零,而梯度下降优化器就会停留在那里。

TensorFlow有很多可用的优化器,包括一些带有惯性的优化器,这种优化器能安全地通过马鞍点。

代码修改:

把 tf.train.GradientDescentOptimiser 这个优化器换成tf.train.AdamOptimizer。

(关于优化器,可以看我的另一篇:https://blog.csdn.net/qq_39683748/article/details/83932077

 

3.随机初始化

如果你1和2都尝试过了,但是准确度却仍然停留在0.1的话。你可以用随机值初始化你的权重。

对于偏置b,当你使用Relu激活函数时,最好将偏置b初始化为小的正值,以便神经元最初能在Relu激活函数的非零范围内操作。

代码修改:

W = tf.Variable(tf.truncated_normal([K, L] ,stddev=0.1))
B = tf.Variable(tf.ones([L])/10)

检查您的所有权重W和偏置B是否已经适当的初始化。

如上图所示,偏置B的每个值都为0.1。

 

4.准确率炸了?

如果您看到准确率的变化曲线一下子暴跌,并且控制台输出的交叉熵值为NaN,不要慌,电脑正在尝试计算log(0),

这个值实际上不存在(log 0 没有定义)。

记住,交叉熵涉及一个log函数,它是根据softmax层的输出计算的。

因为softmax本质上是指数型的,它的输出尽管很接近于0,但却不是零,我们人可以知道这个数不为0,但是对于机器来说,经过32位精度的浮点运算后,exp(-100)已经是真正的零了。

幸运的是,TensorFlow有一个方便的函数,它可以在单个步骤中计算softmax和交叉熵,并以一个数值比较稳定的方式实现。

如果要使用它,应该在应用softmax之前,您需要在最后一层隔离原始的权重W和偏置B。(神经网络术语中的“logits”)

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

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

你需要用下面这些代码代替:

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

现在你可以用一种安全的方式计算你的交叉熵:

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

顺便添加这行代码以将测试集和训练集交叉熵变换到相同的尺度以供显示:

cross_entropy = tf.reduce_mean(cross_entropy)*100

请在代码中添加tf.nn.softmax_cross_entropy_with_logits。

如果准确率的表现正常,您可以跳过此步不作处理。

在实际看到输出中中有NaN时,用这个方法处理。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值