Skip to content

神经网络

神经元

神经网络由神经元(单元, 节点)组成, 这些神经元通过有向链接互相连接, 每个连接都有一个相关的数值权重. 神经元会组成层状结构, 包括输入层, 输出层或多个隐藏层. 在训练的过程中, 权重会被调整, 以学习执行一个特定的任务.

在生物神经网络中, 每个神经元与其他神经元相连, 当它兴奋的时候, 就会向相连的神经元发送化学物质, 从而改变这些神经元内的电位, 如果某神经元的电位超过一个阈值, 那么它就会被激活, 即兴奋起来, 向其他神经元发送化学物质. 机器学习中的神经元也类似, 神经元接受到其他\(n\)个神经元传递过来的输入信号, 这些输入信号通过带权重的连接进行传递, 神经元接收到总输入将与神经元的阈值进行比较, 然后通过"激活函数"处理以产生神经元的输出.

1943年, McMulloch和Pittes将上述情景抽象, 这就是一直沿用至今的"M-P"神经元模型:

每一个神经元包含:

  • 输入向量\(\bm{x}\), 表示输入数据, 其中每个元素\(x_1, x_2, ..., x_n\), 对应\(n\)个特征
  • 权重向量\(\bm{w}\): 每个输入都有一个对应的权重\(w_1, w_2, ..., w_n\), 对应\(n\)个参数
  • 偏置\(b\): 是一个常数, 在将输入加权求和后添加, 用于平移激活曲线
  • 求和\(\sum\): 输入\(x_1, x_2, ..., x_n\)和权重\(w_1, w_2, ..., w_n\)相乘相加, 加上偏置值, 结果表达式为\(\bm{w}\bm{x}+b\)
  • 传递函数\(f\): 又叫激活函数, 是将求和结果进行映射并生成输出, 其中\(a=f(\bm{w}\bm{x}+b)\)
  • 输出\(a\): 对加权和及偏置应用激活函数后产生的最终结果

理想的激活函数应该是阶跃函数(如上左图所示), 它将输入值映射为输出值为\(0\)\(1\), \(1\)对应于神经元兴奋, \(0\)对应于神经元抑制. 但是阶跃函数具有不连续, 不光滑等不太好的特性, 因此实际常用sigmoid函数作为激活函数(如上右图所示).

轮, 批, 迭代

轮, 批, 迭代是神经网络中最基础的三个概念.

  • 轮, epoch, 是指使用训练集的全部数据对模型进行一次完整训练, 称之为"一代训练"
  • 批, batch, 使用训练集中的一小部分样本对模型权重进行一次反向传播的参数更新, 这一小部分样本被称为"一批数据"
  • 迭代, iteration, 使用一个批batch数据对模型尽心关一次参数更新的过程, 被称之为"一次训练"
  • 批大小, 在训练集中选择的一组用来更新权值的样本的数量, 通常设为\(2\)\(n\)次幂
  • 迭代次数, 迭代次数等于总的样本数量除以批大小
例子

假设有一个数据集, 已经被分为5个批次, batch1, batch2, batch3, batch4, batch5. 接下来要使用这些批次来训练模型.

  1. 批次1, 使用批次1进行一次正向传播, 进行一次反向传播, 更新权重, 完成了一次迭代
  2. 批次2, 使用批次2进行一次正向传播, 进行一次反向传播, 更新权重, 完成了一次迭代
  3. 批次3, 使用批次3进行一次正向传播, 进行一次反向传播, 更新权重, 完成了一次迭代
  4. 批次4, 使用批次4进行一次正向传播, 进行一次反向传播, 更新权重, 完成了一次迭代
  5. 批次5, 使用批次5进行一次正向传播, 进行一次反向传播, 更新权重, 完成了一次迭代

批次5结束后, 就完成了1个轮次, 如果要继续进行训练, 你可以再进行下一轮, 即再遍历所有5个轮次

感知机

感知机, Perceptron, 它是最简单的神经网络, 由两层神经元组成, 输入层接受外界输入的信号后传递给输出层, 输出层是M-P神经元, 也被称为"阈值逻辑单元", 激活函数为阶跃函数.

它由Frank Rosenblatt在1957年提出. 同时它的局限性由Marvin Minsky和Seymour Papert在书中提出. Rosenblatt和他的同事意识到这个局限可以通过使用更复杂的NNs, 即multi-layer perceptrons解决, 但是他们没有将感知机使用于神经网络的训练.

学习算法

那么, 感知机是如何进行学习的呢?

之前我们说过, 神经元会在训练过程中调整权重\(w_1, w_2\), 这个其实就是感知机学习的过程. 权重的更新公式为\(\bm{w}^{new}=\bm{w}^{old}+e\bm{x}^T\), \(e=t-a\), \(t\)为目标输出(\(0\)\(1\)), \(a\)为实际输出(\(0\)\(1\)), \(\bm{x}\)为输入向量; 同时还要调整截距, \(b^{new}=b^{old}+e\)

  • \(e=1\)的时候, \(\bm{w}^{new}=\bm{w}^{old}+\bm{x}^T\), \(b^{new}=b^{old}+1\)
  • \(e=-1\)的时候, \(\bm{w}^{new}=\bm{w}^{old}-\bm{x}^T\), \(b^{new}=b^{old}-1\)
  • \(e=0\)的时候, \(\bm{w}^{new}=\bm{w}^{old}\), \(b^{new}=b^{old}\)

具体算法如下:

  1. 初始化权重和截距\(\bm{w}\), \(b\)为小的随机数, 设置当前轮次为\(1\)
  2. 对于每一个训练样本\(\{\bm{x}, t\}\)
    1. 计算\(a\), 这一步又叫作网络激活
    2. 计算误差\(e=t-a\)
    3. 更新权重和截距: \(\bm{w}^{new}=\bm{w}^{old}+e\bm{x}^T\), \(b^{new}=b^{old}+e\)
  3. 在每论结束时(即循环一遍所有的训练样本)检查是否满足停止条件, 如果所有的样本都被正确分类, 或者训练次数达到最大轮次数, 则停止训练, 否则继续, 执行第2步
Tip

感知机学习算法中批大小通常等于全部的样本数量, 所以在感知机学习算法中, 一轮=一次迭代.

例子

给出下列的训练样本:

序号 特征(输入) 标签(输出)
1 1 0 0 0
2 1 0 1 1
3 1 1 0 0

初始权重为\(\bm{w}=[0.3\ 0.2\ 0.4]\), 初始截距为\(b=0.1\). 最大轮次数为\(5\).

  • \(a=sign([0.3\ 0.2\ 0.4][1\ 0\ 0]+0.1)=sign(0.4)=1\), 错误, \(e=0-1=-1\)
  • \(\bm{w}^{new}=[0.3\ 0.2\ 0.4] + (-1)[1\ 0\ 0]=[-0.7\ 0.2\ 0.4]\)
  • \(b^{new}=0.1+(-1)=-0.9\)
  • \(a=sign([-0.7\ 0.2\ 0.4][1\ 0\ 1]-0.9)=sign(-1.2)=0\), 错误, \(e=1-0=1\)
  • \(\bm{w}^{new}=[-0.7\ 0.2\ 0.4] + (1)[1\ 0\ 1]=[0.3\ 0.2\ 1.4]\)
  • \(b^{new}=-0.9+1=0.1\)
  • \(a=sign([0.3\ 0.2\ 1.4][1\ 1\ 1]+0.1)=sign(0.6)=1\), 错误, \(e=0-1=-1\)
  • \(\bm{w}^{new}=[0.3\ 0.2\ 1.4] + (-1)[1\ 1\ 1]=[-0.7\ -0.8\ 1.4]\)
  • \(b^{new}=0.1-1=-0.9\)

第一轮结束后的权重\(\bm{w}=[-0.7\ -0.8\ -1.4]\), 截距\(b=-0.9\), 检查:

  1. 所有的样本都被正确分类?
    1. 第一个样本: \(a=sign([-0.7\ -0.8\ 1.4][1\ 0\ 0]-0.9)=sign(-1.6)=0\), 正确✅
    2. 第二个样本: \(a=sign([-0.7\ -0.8\ 1.4][1\ 0\ 1]-0.9)=sign(-0.2)=0\), 错误❎
    3. 第三个样本: 无需检查第三个样本, 因为第二个样本已经错误
  2. 达到最大轮次数? 🈚️

进入第二轮...

限制条件

如果训练样本是线性可分的, 即样本可以用一条直线在超平面(1)中分开, 感知机学习算法保证能够在有限步骤内找到一组权重和截距, 这组权重和截距能正确地将所有的训练样本分类. 这时候, 感知机将会找到一个线性的决策边界, 但不一定是"最优"的边界, 而是找到一个可行的边界后就会停止. 在现实世界中, 大多数的问题都是线性不可分的, 这意味着训练样本无法用一个超平面正确分开, 这也是感知机的最大局限之一.

  1. 什么是超平面, 可以在这里找到.

逻辑门

感知机能够实现与门, 这是一个线性可分的问题, 如图所示.

感知机能够找到一个线性的决策边界, 如\(w_1=1=w_2=1, b=2\), 即\(y=sign(x_1+x_2-2)\).

感知机能够实现或门, 这是一个线性可分的问题, 如图所示.

感知机能够找到一个线性的决策边界, 如\(w_1=w_2=1, b=0.5\), 即\(y=sign(x_1+x_2-0.5).\)

感知机能够实现与非门, 这是一个线性可分的问题, 如图所示.

感知机无法实现异或门, 这不是一个线性可分的问题, 如图所示.

然而, 异或门可以通过与门, 非门和与非门的组合实现, 如图所示.

所以, 只要使用一个两层的感知机就能解决异或问题.


从上面的实验中, 我们得出结论, 如果增加更多的层, 可以得到更加复杂的决策边界, 如图所示.

深度学习

深度学习和一般的神经网络的主要区别在于层数的深度以及能力的提升, 具体可以解释:

  • 层数的区别: 一般的神经网络通常指那些只有一层或者几层隐藏层的神经网络, 也叫做浅层神经网络. 虽然他们可以处理简单的任务, 但是其表现收到限制, 尤其在处理复杂的非线性问题时效果不佳. 深度学习则使用多层隐藏层, 这些隐藏层构成了一个深层神经网络(DNN), 通过多个隐藏层, 网络可以捕捉到更加复杂的特征和模式, 解决如图像识别, 语音识别等复杂的任务
  • 特征学习能力: 在浅层神经网络中, 特征的提取能力有限, 通常需要手工提取特征, 然后将特征输入神经网络进行分类或回归. 深度神经网络可以自动学习特征, 尤其在深度网络的层次结构中, 每一层可以逐渐学习到更高的特征, 例如, 卷积神经网络(CNN)可以自动从低级别的边缘, 纹理特征逐步学习到高级别的对象形状, 语义信息.
  • 训练方式和算法: 浅层神经网络的训练相对简单, 常用的训练方法包括梯度下降和反向传播. 深度学习网络由于层数较多, 训练起来较复杂, 需要更加强大的硬件, 如GPU, 并且依赖于改进的训练方法, 如权重初始化(使用autoencoders), 正则化技术(如dropout), 优化算法等来避免梯度消失(vanishing gradient problem)和爆炸问题
  • 数据需求: 浅层神经网络可以在中小规模的数据集上进行有效的训练, 深度神经网络通常需要大量数据来避免过拟合问题, 大型数据集是深度学习成功的重要因素之一

梯度消失

回顾在上面小节中讲到的误差计算公式:

  1. \(q\)为输出层神经元, 则\(\delta_q=(t_q-o_q)o_q(1-o_q)\)
  2. \(q\)为隐藏层神经元, 则\(\delta_q=o_q(1-o_q)\sum_i w_{qi}\delta_i\)

注意\(o_q\)是经过sigmoid函数激活后的输出, sigmoid函数的取值范围是\((0, 1)\), 若\(o_1\)非常贴近\(0\)\(1\), 可能导致\(\delta_q\)特别小, 接近于\(0\), 而\(\delta_q\)是会被反向传播的, 到前一层计算误差的时候也会特别小, 前面所有的层权重变化都特别小.

这种现象在隐藏层较多的时候较明显. 会导致梯度消失, 收敛地特别慢. 就算输出层没有饱和, 重复的乘以一个小于\(1\)的值, 梯度会变得非常小, 当传播到接近输出层的时候, 梯度可能会消失. 由于较低层的梯度非常小, 这些层的学习速度就会很慢.

解决方法是使用其他的激活函数, 如ReLU和LReLu. 它们没有上限, 因此输出不会饱和, 对于\(x>0\), ReLU的梯度为\(1\).

Dropout

Dropout是一种防止过拟合的方法.

核心思想是在每一次反向迭代的时候, 网络的每一层都会随机选择部分神经元, 并将其输出设为\(0\), 即"丢弃"这些神经元. 这些"丢弃"的神经元不会参与当前轮次的权重更新, 相当于暂时禁用它们. 真正有用的特征更能抵抗神经元的随机移除, 因为它们在不同的神经元的组合下仍然表现良好.

由于Dropout在训练的时候随机丢弃一部分神经元, 这实际上是在每次迭代的时候训练一个较小的子网络.

  • 在训练的过程中, 我们会用反向传播算法更新子网中的权重和截距, 然后将这些更新的权重值加回到原始的网络中
  • 在测试的过程中, 我们不会丢弃任何的神经元, 由于在训练过程中, Dropout会随机"丢弃"一部分神经元, 因此, 对于每一次训练迭代, 模型的激活和权重更新都是基于部分神经元计算, 例如, 如果Dropout率是\(0.5\), 那么在训练过程中, 激活函数的输入会是原始网络中大约\(50\%\)的信号, 这意味着, 在每一次前向传播的过程中, 神经元的输出实际值比全网络的预期值大约低\(50\%\). 在测试阶段, 我们需要对权重进行缩放, 乘以\(0.5\)

Softmax函数

神经网络输出的结果能够被继续处理成为概率. 神经网络的输出为\((o_1, ..., o_n)\), softmax函数为\(p_i=\frac{e^{o_i}}{\sum_j e^{o_i}}\).

例子

如三个输出神经元的输出为\(o_1=0.3, o_2=0.8, o_3=0.2\). 使用softmax函数之后\(p_1=0.28, p_2=0.46, p_3=0.26\).

其他的损失函数

可以使用交叉熵损失而不是MSE. 它衡量的是模型预测的概率分布和真实类别分布之间的差异, 例如通过softmax函数得到的输出 交叉熵损失用于反映模型对于正确类别的预测有多大的不确定性.

对于单个样本的交叉熵损失公式为\(CCE_i=-\sum_{j=1}^C y_{ij}\cdot \log(\hat{y_{ij}})\). 其中, \(y_{ij}\)是样本\(i\)的真实one-hot编码向量的第\(j\)个元素, 真实类别上为\(1\), 其他为\(0\). \(\hat{y_{ij}}\)为模型预测的概率分布中对应第\(j\)个类别的概率.

对于\(N\)个样本, 总的交叉熵损失是每个样本的交叉熵损失的总和: \(CCE=\sum_{i=1}^N CCE_i\).


  1. 神经元模型和感知机 | Machine Learning. (2018, August 12). https://zhjunqin.gitbook.io/machine-learning/ji-qi-xue-xi/shen-jing-wang-luo/shen-jing-yuan-mo-xing