引言
神经网络可以说是这几年最火的机器学习算法了。今天的大数据茶馆,咱们就一起聊聊神经网络那些事儿。
一、神经网络的概念
所谓神经网络就是一个个神经元组成的网络。下面我们看看神经元,大脑神经元和算法神经元有什么相通的地方。
1.1 大脑神经元
大脑神经元结构如图所示,有多个树突和一个轴突,树突用来接收信号,轴突用来输出信号。

神经元从多个树突接收信号,然后综合这些信号**产生一个输出信号,通过轴突传递给下一个神经元。
1.2 算法神经元
和大脑神经元类似,机器学习中的神经元结构如图所示。

从图中可以看出,算法神经元也有多个输入,输入按权重加和后通过**函数**生成输出。大家有没有注意到,图中画的不就是逻辑回归吗?是的,其实逻辑回归就可以看成是一个神经元,只不过神经元的**函数除了逻辑回归的 sigmoid, 还可以是别的比如 relu,softmax 等。
所以大脑神经元和算法神经元都是把多个输入**成一个输出,结构是相似的。但除此之外,算法神经网络和人体神经系统的生物科学并没有什么关系。
二、神经网络的结构

如图所示,神经网络由输入层、隐含层(可能有多个)和输出层构成,一般我们说几层神经网络是不包含输入层的,只包含隐含层和输出层,比如图中的网络是两层神经网络。
图中隐含层和输出层的每个节点都是一个神经元,接收多个输入按权重加和,然后用**函数生成一个输出。
三、关于**函数
3.1 为什么要有**函数
我们说每个神经元都是多个输入按权重加和,然后再用**函数**来生成输出,为什么要有**函数呢?
**函数主要是为了给神经元加入非线性因素。假设没有**函数,在上图中:
- a1 和 a2 是输入(x1,x2,x3,x4) 的线性组合
-
y^ 是输入(a1,a2) 的线性组合
- 所以 y^ 也是输入(x1,x2,x3,x4) 的线性组合,就和没有隐含层的逻辑回归一样了
而实际中我们的输出与输入可不一定是线性关系,而是任意复杂的函数关系,所以我们在每个神经元处都加上非线性的**函数,这样多层次多节点的传输下来,多个非线性函数的组合就使得 y^ 可以表示 (x1,x2,x3,x4) 的任意复杂的函数关系。然后再经过梯度下降一次次调节每个神经元的权重,就可以让 y^ 逼近真实的 y。
3.2 有哪些常用的**函数
常用的**函数有 sigmoid、tanh、relu、leaky relu 以及 softmax。
3.2.1 sigmoid
sigmoid 主要用于二分类神经网络的输出层。

sigmoid:asigmoid′:a′=1+e−z1=a(1−a)
3.2.2 tanh
tanh 将 sigmoid 平移到中心为0上,效果比 sigmoid 好,更容易收敛。

tanh:atanh′:a′=ez+e−zez−e−z=1−a2
sigmoid 和 tanh 都有一个缺点: 当变量很大的时候斜率衰减的厉害,减缓了神经网络的优化速度。
3.2.3 relu
relu 的变量为负值时结果为0,变量为正值时结果为 linear,当 Z 很大时斜率仍然没有衰减。

relu:arelu′:a′=max(0,z)={0,z<0z,z≥0
缺点:当变量为负数时,结果都为0,相当于负数不起作用。
3.2.4 leaky relu
leaky relu 的变量为负值时 A 不至于是0,但并不常用。

leakyrelu:aleakyrelu′:a′=max(0.01z,z)={0.01,z<0z,z≥0
3.2.5 softmax
softmax 主要用于多分类神经网络的输出层。

softmax(Zi)=∑j=1neZjeZi
在实际应用中,通常隐含层使用 relu 作为**函数,输出层二分类时采用 sigmoid、多分类时采用 softmax 作为**函数。
四、神经网络的矩阵化表示

图中样本有四个维度:(x1,x2,x3,x4), 隐含层有两个节点。
先考虑一个样本的情况
z1=[w11w12w13w14]⎣⎢⎢⎡x1x2x3x4⎦⎥⎥⎤+b1
z2=[w21w22w23w24]⎣⎢⎢⎡x1x2x3x4⎦⎥⎥⎤+b2
将两个公式合为矩阵:
[z1z2]=[w11w12w13w14w21w22w23w24]⎣⎢⎢⎡x1x2x3x4⎦⎥⎥⎤+[b1b2]
再考虑 m 个样本的情况:
[z11…z1mz21…z2m]=[w11w12w13w14w21w22w23w24]⎣⎢⎢⎡x11…x1mx21…x2mx31…x3mx41…x4m⎦⎥⎥⎤+[b1b2]
矩阵简化为
Z2∗m=W2∗4∗X4∗m+b2∗1
最后一般化,把输入层的维度由 4 改成 in,隐含层的维度由 2 改成 out, 矩阵为
Zout∗m=Wout∗in∗Xin∗m+bout∗1
总结一下:
-
输入矩阵 Xin∗m: in 行表示维度,m 列表示样本个数
-
参数矩阵 Wout∗in: out 行表示输出的维度,in 列表示输入的维度
-
参数向量 bout∗1: out 行表示输出的维度,1 列表示列向量,计算时维度自适应
-
输出矩阵 Zout∗m: out 行表示输出的维度,m 列表示样本个数
-
**矩阵 Aout∗m: 维度与 Z 一致。既是上一层的输出,同时也是下一层的输入
五、求解神经网络
神经网络的求解仍然采用梯度下降的方法。

5.1 正向传播
- 隐含层
Z[1]A[1]=W[1]∗X+b[1]=relu(Z[1])
- 输出层
Z[2]Y^=W[2]∗A[1]+b[2]=A[2]=sigmoid(Z[2])
- 损失函数
Loss=−(YlogY^+(1−Y)log(1−Y^))
这里隐含层的**函数为 relu, 输出层的**函数为 sigmoid。
5.2 反向传播
反向传播中主要利用链式求导法则,即 ∂x∂z=∂y∂z∂x∂y
dA[2]dZ[2]dW[2]db[2]dA[1]dZ[1]dW[1]db[1]=−A[2]Y+1−A[2]1−Y=A[2]−Y=m1dZ[2]XT=m1sum(dZ[2])=W[2]TdZ[2]=dA[1]dRelu(Z[1])=m1dZ[1]XT=m1sum(dZ[1])
在 dW 和 db 中都有一个 m1, 这是因为正向计算时有 m 个样本,所以这里需要除以 m
5.3 更新参数
W[1]:b[1]:W[2]:b[2]:=W[1]−αdW[1]=b[1]−αdb[1]=W[2]−αdW[2]=b[2]−αdb[2]
其中 α 为学习率
经过多轮迭代即可得到最优的(W,b)。
后记
神经网络先聊到这里,下次 我们将探索多隐含层多节点的深度神经网络(DNN)及其一般推导过程。
欢迎关注本人公众号《大数据茶馆》,用大白话畅聊大数据。
来的都是客,欢迎您常来坐坐~
