人工神经网络相比传统的线性回归和逻辑回归,在模拟非线性模型上会有更好的效果,用于分类和回归均可。
一、神经元(感知器)
图片来自吴恩达机器学习入门
一个神经元包括几个输入结点(图中的,
,
等)和一个输出结点,每个输入结点连接到输出结点都要有一个权重(
,很多材料也用
来表示),用来模拟输入结点和输出结点之间的连接强度。训练一个神经元模型,就是持续调整连接强度,直到能拟合模型。
神经元模型里会在输出结点对这几个输入结点进行加权求和(一般会有一个偏置因子,这个原因后面写),然后得到一个结果
,用
的值来判断所处的分类。
一般来说,为了拟合非线性模型,除了简单的用加权求和以外,还应该套用一个函数在加权求和上,这个函数叫做激活函数。如果把输入特征和权重都看作向量,那么求和就是两个向量的内积,在这个外面再套用一个激活函数,输出结果。
展开来看就是
就是激活函数。
常见的激活函数种类
以下内容摘自https://zhuanlan.zhihu.com/p/29633019
sigmoid
优点:有较好的解释性
缺点:
1.Sigmoid函数饱和使梯度消失。sigmoid神经元有一个不好的特性,就是当神经元的激活在接近0或1处时会饱和:在这些区域,梯度几乎为0。
2.输出不是零中心的,这一情况将影响梯度下降的运作,因为如果输入神经元的数据总是正数,那么关于w的梯度在反向传播的过程中,将会要么全部是正数,要么全部是负数,这样梯度下降权重更新时出现z字型的下降。这样收敛会变得异常的慢。(这也是为什么要一直保持为数据的0中心化)—–但这个问题比较小。
3.exp()在深度神经网络时候相比其他运算就比较慢
Tanh非线性函数
优点:
1.它的输出是零中心的。因此,在实际操作中,tanh非线性函数比sigmoid非线性函数更受欢迎。
缺点:
1.和Sigmoid函数一样,饱和使梯度消失。计算慢.
ReLU
优点:
1.ReLU对于随机梯度下降的收敛有巨大的加速作用( Krizhevsky 等的论文alexnet指出有6倍之多)。据称这是由它的线性,非饱和的公式导致的;
2.注意:现在大部分的DNN用的激活函数就是ReLu
缺点:
1.当x是小于0的时候,那么从此所以流过这个神经元的梯度将都变成0;这个时候这个ReLU单元在训练中将死亡(也就是参数无法更新),这也导致了数据多样化的丢失(因为数据一旦使得梯度为0,也就说明这些数据已不起作用)。
Leaky ReLU
优点:
1.非饱和的公式;
2.Leaky ReLU是为解决“ReLU死亡”问题的尝试
缺点:
1.有些研究者的论文指出这个激活函数表现很不错,但是其效果并不是很稳定
Kaiming He等人在2015年发布的论文Delving Deep into Rectifiers中介绍了一种新方法PReLU,把负区间上的斜率当做每个神经元中的一个参数。然而该激活函数在在不同任务中均有益处的一致性并没有特别清晰。
Maxout
Maxout是对ReLU和leaky ReLU的一般化归纳
优点:
1.拥有ReLU单元的所有优点(线性操作和不饱和),而没有它的缺点(死亡的ReLU单元)
缺点 :
1.每个神经元的参数数量增加了一倍,这就导致整体参数的数量激增。难训练,容易过拟合
二、人工神经网络
一些神经元组合在一起就是神经网络(我是这么理解的),实际上人工神经网络可以分为三层,输入层,输出层和隐藏层。
输入层:最开始的一层,用来输入样本特征值。
输出层:最后一层,用来输出结果,判断分类。
隐藏层:其他的层次都叫隐藏层,可以有多个层级。
以这幅图为例,输入层就是(偏置因子),,,,隐藏层是。输出层则是最终得到的。计算方式如下图(图里可能没有,但是公式里有):
其中把看成矩阵,则下标按照线性代数定义,是行和列的坐标,而上标则代表了从第j层到第j+1层的权重值。(这里面的实际上和是一个意思,因为输入层输入的就是特征值,而代表的是第2层的第1个结点值)
不管是在输入层-隐藏层,还是隐藏层-输出层,只要是结点相连的地方都有一个权重。
每一层的结点仅和下一层的结点相连,叫做前馈神经网络,同一层结点可以相连或某层结点可以连接到前面如何一层的结点的叫做递归神经网络。
权重调整原理
通常来说,有监督学习都是试图让误差最小,来衡量参数的变化,这里可以采用MSE来作为代价函数:
把2替换为n就是MSE的式子,代表实际标签值,
代表根据给定权重算出来的y。
当是线性函数的时候,该函数表示为一个凸函数,如果有两个变量的话,就是一个三维碗状函数,用梯度下降法可以求解最小值,梯度下降法的求解为:
其中是学习率,式子的意思就是对
对每一个参数
求偏导数,乘以学习率之后,用
减掉这个值,得到这一次迭代的参数,轮番迭代之后得到局部最小值(凸优化中,局部最小就是全局最小),按照这个方法计算,权值会沿着使总体误差项减小的方向增加。
但是实际上神经网络大部分函数都不是线性的,因此也就不是凸函数,这样的话使用梯度下降法就会出现局部最优的问题,从而得不到最优解,并且对于隐藏节点来说,
因此有一种反向传播算法(back-propagation,BP)可以用来调整权重,从而得到最优解。
三、BP神经网络
从名字就可以看出,BP神经网络就是用了反向传播算法得出参数的神经网络,这个算法的每一次迭代包括两个阶段,前向阶段和后向阶段:
前向阶段就是用前一次迭代的权值计算网络中每一个结点的输出值,先计算j层输出,然后用j层计算j+1层。
后向阶段则是从相反的方向更新权重,先更新j+1层,再更新j层。这种方法可以用j+1层的结点误差来估算j层的结点误差。
还是吴恩达老师的图,图中代表第l层,j结点的误差,则
其中代表的是第3层到第4层的权重矩阵,
代表第四层的误差矩阵,
代表激活函数,
,也就是该层的结点值。图中蓝笔代表当激活函数是sigmoid的时候的计算公式。
上述式子的推导过程,看到一个笔记记的非常明白:https://zhuanlan.zhihu.com/p/58068618
反向传播的计算方式如下:
首先明确这个步骤中的代价函数(图中的
即为通常来说的
)。
1.设,其中
代表层数,
训练集中的第i个样本,
代表第i个样本的第j个特征。
2.计算完前向传播之后,会得到输出层的值,用这个值和标签值比较,得到输出层的误差。
3.用刚才提到的公式,依次求出
4.用公式累加得到
的值
5.计算梯度函数:
6.得到的就是代价函数关于的偏导数。 有了偏导数,根据权重的更新方式可以得到
可以得到迭代的Θ值。
事实上式子中的代表的是权重需要改变的程度大小。反向传播,实际上就是用 上一层节点的误差值 * 权重,得到下一层的误差值。和正向传播是类似的。
在第一次进行计算的时候,对于权重要进行随机初始化,不要设置为都是0,会导致逻辑单元不发生变化。(不存在隐藏层时,可以初始化为0)。最好初始化为一个较小的数,可以考虑采用np.random.randn(1,1)生成正态分布。
梯度检验
为了保证实施反向传播的过程是正确的,需要引入梯度检验。
梯度检验的原理就是在函数上有一点θ,可以取θ-ε和θ+ε这两个点的值,他们两点之间的斜率就接近于这一点的导数(二维的情况,推广到向量的道理是类似的)。
实际计算过程中,用反向传播计算导数,然后用梯度检验验证,如果非常接近(只有几位小数不同)那么证明反向传播的计算是正确的,然后用计算出来的导数进行下一次迭代。
多分类
上面说到的都是二元分类的情况,如果是多分类的情况,可以把输出结果向量化:
如果有k个分类,则分为k个输出结点,对应不同的输出结点用向量不同位置上的1来表示,其他的均为0。
这样的话,保证了每一个输出结点实际上还是二元的,但是可以根据4个输出结点的不同结果组成来判断分类。
简单了解了一下神经网络,看的还是不太明白,先写在这里。有机会再调整。在Python中通常用Keras来实现,但是sklearn中也是有这个类的,只不过因为不支持GPU性能有些问题,小规模数据也可以采用。