深层神经网络
线性模型的局限性:
因为线性模型的组合任然是线性模型,所以任意的全连接层网络和单层的神经网络在表达能力上没有任何区别。
激活函数:
如果将线性模型中每一个神经元通过非线性函数,那么整个神经网络模型就不再是非线性的了。这个非线性函数就是激活函数。
tensorflow中有其中激活函数,常见的激活函数:参考:https://www.cnblogs.com/lliuye/p/9486500.html
1. sigmoid函数:
在逻辑回归中我们介绍过sigmoid函数,该函数是将取值为 (−∞,+∞)(−∞,+∞) 的数映射到 (0,1)(0,1) 之间。sigmoid函数的公式以及图形如下:
sigmoid函数不常用,主要是它存在以下缺点:
a. 当 zz值非常大或者非常小时,通过上图我们可以看到,sigmoid函数的导数 g′(z) 将接近 0 。这会导致权重 W 的梯度将接近 0 ,使得梯度更新十分缓慢,即梯度消失。
b. 函数输出的均值不为0,不便于下层的计算。
c. sigmoid函数可以用在最后一层,作为输出层进行二分类,不适合用在隐藏层。
2.tanh函数
tanh函数相较于sigmoid函数要常见一些,该函数是将取值为 (−∞,+∞)(−∞,+∞) 的数映射到 (−1,1)(−1,1) 之间,其公式与图形为:
tanh函数和sigmoid函数一样,在z很大时,到数接近0,会导致梯度消失。
3. ReLu函数
ReLU函数又称为修正线性单元(Rectified Linear Unit),是一种分段线性函数,其弥补了sigmoid函数以及tanh函数的梯度消失问题。ReLU函数的公式以及图形如下:
ReLu函数求导的结果为:
ReLu函数优点:
a. 在输入为正数的时候(对于大多数输入 z 空间来说),不存在梯度消失问题。
b. 计算速度要快很多。ReLU函数只有线性关系,不管是前向传播还是反向传播,都比sigmod和tanh要快很多。(sigmod和 tanh要计算指数,计算速度会比较慢)
ReLU函数的缺点:
a, 当输入为负时,梯度为0,会产生梯度消失问题。
4. Leaky ReLu函数
Leaky ReLu函数是对ReLu函数的改进,图像和表达式如下所示:
其中,a的取值为【0,1】
Leaky ReLu函数求导的结果为:
偏置项
对于神经网络中的偏置项,可以看作一个输出始终为1的节点。偏置值允许将激活函数向左或向右移位,这可能是成功学习的关键。sigmoid(x)和sigmoid(x+a)的区别。
损失函数的定义:
神经网络模型的效果和优化目标是通过损失函数(loss function)来定义的。分别针对分类和回归进行描述:
分类:
神经网络解决n分类问题通常设置n个输出点, 即n维向量。例如对于mnist手写字体识别问题:
例如,如何评价实际输出向量与期望向量之间的接近程度,交叉熵(cross entropy)是一种常用的方法。
交叉熵是信息论中的一个概念,用来刻画两个概率分布之间的距离:
假设p,q为两个概率分布,则他们之间的交叉熵为:
当事件总数一定的情况下,概率分布函数p(X=x)满足:
所以在多分类问题中,一个样本的正确答案,例如[0,1,0,0,...0]就属于一个概率分布,因为一个样本属于正确类别的概率是1,属于其他类别的概率为0.
但是,神经网络的输出不一定是概率分布,所以需要将输出转化为概率分布,softmax回归就是一种常用的方法:
假设神经网络的输出为:
经过softmax回归处理之后为:
其中:
这样就可以用cross entropy衡量这两个概率分布之间的距离了。
交叉熵函数是不对称的,即H(p,q)与H(q,p)不相等,H(p,q)刻画的是通过概率分布q来表达概率分布p的困难程度。所以p应该是正确答案,q是神经网络的输出。交叉熵越小,两个概率分布之间的距离越小。
tensorflow对softmax和corss_entropy做了封装:
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)
其中: labels表示正确答案, logits为网络实际输出
回归:
与分类不同的是回归问题解决的是对具体数值的预测,这类问题需要预测的是一个任意的实数,而不是具体的类别,求解回归问题的网络只有一个输出点,节点的输出值就是预测值,回归最常用的损失函数是均方误差。
n表示一个batch中的数据量。
神经网络优化算法:
梯度下降算法主要用于优化单个参数的值,反向传播算法是在所有参数上使用梯度下降算法。是神经网络在训练数据上的损失函数降到最小。反向传播算法可以根据定义好的损失函数优化神经网络中的参数取值。
是损失函数,是参数。
梯度下降法不断沿着损失函数梯度的反方向,迭代更新参数:
其中:为学习率
神经网络通过反向传播算法,计算出损失函数对每一个参数的梯度,再根据梯度和学习率更新每一个参数。
梯度下降法存在的问题:
1.不一定能达到全局最优
2. 计算时间长,应为每次都要计算在所有数据上的损失和。
为了加速计算,使用随机梯度下降算法:只随机优化某一条数据上的损失函数,计算速度加快,但是存在问题:
1. 在一条数据上损失函数最小,不代表在所有数据上损失函数最小。所以可能无法达到全局最优点。
学习率设置:
上述的梯度下降法中有个参数叫“学习率”,用于控制参数更新的速度。学习率设置即不能过大,也不能过小:
1. 过大: 参数在极优值附近摆动
2..过小:收敛速度变慢
Tensorflow提供了指数衰减法来设置学习率:
decay_step为衰减速度,decay_rate为衰减系数。
当global_step/decay_step被转换为整数时, 指数衰减曲线就变成staircase(阶梯)类型了。
tensorflow设置指数衰减学习率:
global_step = tf.Variable(0)
learning_rate = tf.train.exponential_decay(learning_rate=0.1, global_step=global_step, decay_rate=0.96,
decay_steps=100, staircase=True)
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy, global_step=global_step) # 定义损失函数
过拟合问题:
避免过拟合的常用方法是正则化。正则化的思想就是在模型的损失函数中加入刻画模型复杂度的指标,采用正则化后,模型的损失函数为:
表示模型复杂度损失在损失函数中所占的比例。是网络中所有的参数,一般来说模型复杂度只由权重w决定,正则化分为两种:
1. L1正则化
2. L2正则化
正则化的基本思想是通过限制权重的大小,使得模型不能够任意拟合训练数据中的随机噪音。(使得模型在测试集上鲁棒性更强)。
a. L1会使得模型的参数变得稀疏,L2不会。(如果w_i=0.01, L2的计算结果会更加接近于0,所以就不会再去优化w_i)
b. L1不可导,L2可导,所以含有L2的损失函数优化更加简单
c. L1,L2可以同时使用:
tensorflow总实现正则化的方法:
在复杂的网络中,权重的定义比较多,可以借助Collection将所有参数的正则化保存在集合中:
def get_weight(shape, lamb, name):
"""
定义一层网络边上的权重
:param shape:
:param lamb: lambda参数
:param name: 权重名字
:return:
"""
var = tf.Variable(initial_value=tf.random_normal(shape=shape, dtype=tf.float32, mean=0, stddev=1), name=name)
# 将权重正则化的值加入loss中
tf.add_to_collection(name='losses', value=tf.contrib.layers.l2_regularizer(lamb)(var))
return var
滑动平均模型:
增强模型在测试数据集上的鲁棒性:
滑动平均模型对每一个变量维护一个影子变量,影子变量的初始值就是相应变量的初始值。每次更新时,影子变量的值会更新为:
shadow_variable = decay*shadow_variabl + (1-decay)*variable
decay: 衰减率
variable: 待更新的变量