DNN¶
1. 机器学习与深度学习¶
机器学习 就是从历史数据中探索和训练出数据的普遍规律, 将其归纳为相应的数学模型, 并对未知的数据进行预测的过程; 在这个过程中会碰到各种各样的问题, 比如如下等一系列关乎机器学习模型生死的问题:
- 数据质量
- 模型评价标准
- 训练优化方法
- 过拟合
在机器学习中, 有很多已经相当成熟的模型, 在这些机器学习模型中, 人工神经网络 就是一种比较厉害的模型; 人工神经网络从早期的感知机发展而来, 对任何函数都有较好的拟合性.
但自上个世纪 90 年代一直到 2012 年深度学习集中爆发前夕, 神经网络受制于计算资源的限制和较差的可解释性, 一直处于发展的低谷阶段. 之后大数据兴起,计算资源也迅速跟上, 加之 2012 年 ImageNet 竞赛冠军采用的 AlexNet 卷积神经网络一举将图片预测的 top5 错误率降至 16.4%, 震惊了当时的学界和业界. 从此之后, 原本处于研究边缘状态的神经网络又迅速热了起来, 深度学习也逐渐占据了计算机视觉的主导地位.
以神经网络为核心的深度学习理论是机器学习的一个领域分支, 所以深度学习其本质上也必须遵循一些机器学习的基本要以和法则.
2.感知机¶
2.1 感知机模型介绍¶
2.1.1 感知机模型¶
感知机, perceptron 是由美国学者 Frank Rosenblatt 在 1957 年提出来的, 感知机是神经网络(深度学习)的起源算法. 因此, 学习感知机的构造也就是学习通向神经网络和深度学习的一种重要思想, 感知机是神经网络的理论基础.
感知机就是一个通过建立一个线性超平面, 对线性可分的数据集进行分类的线性模型. 感知机接收多个输入信号, 输出一个信号.
假设 \(x_1, x_2, \cdots, x_p\) 是输入信号, \(\hat{y}\) 是输出信号, \(w_1,w_2,\cdots, w_p\) 是权重, \(b\) 是偏置.输入信号被送往神经元时, 会被分别乘以固定的权重 \((w_1x_1,w_2x_2,\cdots,w_px_p)\). 神经元会计算传送过来的信号的总和, 只有当这个总和超过了某个界限值时, 才会输出 1. 这也被称为”神经元被激活”. 这里将这个界限值称为阈值, 用符号 \(\theta\) 表示.
感知机的多个输入信号都有各自固定的权重, 这些权重发挥着重要控制各个信号的重要性的作用. 也就是说,权重越大, 对应该权重的信号的重要性就越高:
2.1.2 感知机训练¶
- 首先, 模型接受输入 \(x_{i}\),将输入 \(x_{i}\) 与权重(weights) \(\omega_i\) 和偏置(bias) \(b\) 进行加权求和 \(\sum_{i=1}^{p} \omega_i x_i + b\), 并经过 \(\sigma(\cdot)\) 函数进行激活,将激活结果作为 \(\hat{y}\) 进行输出. 这便是感知机执行前向传播计算的基本过程;
- 其次, 当执行完前向传播计算得到输出 \(\hat{y}\) 之后, 模型需要根据输出 \(\hat{y}\) 和实际的样本标签(sample label) \(y\) 按照损失函数 \(L(y, \hat{y})\) 计算当前损失;
- 最后, 通过计算损失函数 \(L(y, \hat{y})\) 关于权重(weights) \(\omega_i\) 和偏置(bias) \(b\) 的梯度, 根据梯度下降算法更新权重和偏置. 经过不断的迭代调整权重和偏置使得损失最小, 这便是完整的 单层感知机 的训练过程.
2.2 单层感知机的局限性¶
单层感知机无法分离非线性空间
- 单层感知机只能表示由一条直线(超平面)分割的空间
感知机无法实现异或门(XOR gate)
- XOR 函数(“异或”逻辑)是两个二进制值的运算, 当这些二进制值中恰好有一个为 1 时, XOR 函数返回值为 1, 其余情况下为 0.
2.3 多层感知机可以实现异或门¶
感知机可以通过叠加层可以表示异或门, 实现非线性空间的分割:
- 异或门 可以通过组合 与非门、或门, 再将前两个逻辑门的组合和 与门 组合得到
叠加了多层的感知机也称为 多层感知机(MLP, Multi-Layered Perceptron)
2.4 从感知机到神经网络¶
单层感知机 包含两层神经元,即输入与输出神经元,可以非常容易的实现逻辑与、或和非等线性可分情形, 但终归而言,这样的一层感知机的学习能力是非常有限的, 对于像异或这样的非线性情形, 单层感知机就搞不定了. 其学习过程会呈现一定程度的振荡,权值参数 \(\omega_i\) 难以稳定下来,最终不能求得合适的解;
对于 非线性可分 的情况, 在感知机的基础上一般有了两个解决方向:
- 支持向量机模型
- 支持向量机旨在通过 核函数 映射来处理非线性的情况;
- 神经网络模型
- 神经网络模型也叫 多层感知机, 与单层的感知机 在结构上的区别主要在于 MLP 多了若干 隐藏层, 这使得神经网络对非线性的情况拟合能力大大增强.
3.深度前馈网络¶
3.1 深度前馈网络概念¶
深度学习模型:
- 前馈神经网络 (Feedforward Neural Network)
- 深度前馈网络 (Deep Feedforward Network)
- 多层感知机 (Multilayer Perceptron, MLP)
- 反馈神经网络 (FeedBack Neural Network)
- 循环神经网络 (Recurrent Neural Network)
神经网络结构:
- 深度
- 宽度
- 第一层,第二层,…
- 隐藏层
- 输出层
深度前馈网络介绍:
深度前馈网络的目标是: 近似某个函数 \(f^{*}\).
- 深度前馈网络定义了一个映射 \(y = f(x; \theta)\), 并且学习参数 \(\theta\) 的值, 使它能够得到最佳的函数近似 \(f^{*}\).
深度前馈网络之所以被称为 前馈(feedforward) 的, 是因为信息流过 \(x\) 的函数, 流经用于定义 \(f\) 的中间计算过程, 最终到达输出 \(y\). 在模型的输出和模型本身之间没有 反馈(feedback) 连接. 当深度前馈网络被扩展成包含反馈连接时, 被称为 循环神经网络(Recurrent Reural Network, RNN).
深度前馈网络之所以被称为 网络(network), 是因为它们通常用许多不同函数复合在一起来表示, 该模型与一个有向无环图相关联, 而图描述了函数是如何复合在一起的. 网络链的全长称为模型的 深度(depth)。
\[f(x) = f^{(3)}(f^{(2)}(f^{(1)}(x)))\]
其中:
\(f^{(1)}\): 网络的第一层(first layer)
\(f^{(2)}\): 网络的第二层(second layer)
- 隐藏层(hidden layer)
…
\(f^{(3)}\): 网络的输出层(output layer)
深度前馈网络之所以被称为 神经网路, 是因为他们或多或少地受到神经科学的启发.
- 网络中每个隐藏层通常都是向量值的. 这些隐藏层的维数决定了模型的 宽度(width). 向量的每个元素都可以被视为起到类似一个神经元的作用. 除了将层想象成向量到向量的单个函数, 也可以把层想象成由许多并行操作 单元(unit) 组成, 每个单元表示一个向量到标量的函数. 每个单元在某种意义上类似一个神经元, 它接收的输入来源于许多其他的单元, 并计算自己的激活值.
深度前馈网络设计:
选择优化模型
选择代价函数
选择输出单元形式
选择用于计算隐藏层值激活函数(activation function)
设计网络的结构, 包括
- 网络应该包含多少层
- 层与层之间应该如何连接
- 每一层包含多少单元
反向传播(back propagation)算法和推广
3.2 线性模型的局限性及克服¶
线性模型的局限性:
- 线性模型,如逻辑回归和线性回归, 是非常吸引人的, 因为无论是通过闭解形式还是使用凸优化, 它们都能高效且可靠地拟合. 线性模型也有明显的缺陷: 模型的能力被局限在线性函数里, 所以无法理解任何两个输入变量之间的相互作用.
克服线性模型的局限性:
- 为了扩展线性模型来表示 \(x\) 的非线性函数,可以不把线性模型用于 \(x\) 本身,而是用在一个变换后的输入 \(\phi(x)\) 上,这里 \(\phi\) 是一个非线性学习算法,可以认为 \(\phi\) 提供了一组描述 \(x\) 的特征,或者认为它提供了 \(x\) 的一个新的表示.
如何选择映射 \(\phi\)?
其中一种选择是使用一个通用的 \(\phi\), 例如无限维的 \(\phi\), 它隐含地用在基于 RBF 核的核机器上.
另一种选择是手动设计 \(\phi\), 传统的机器学习模型.
深度学习的策略是去学习 \(\phi\). 在这种方法中, 有一个模型 \(y=f(x;\theta,\omega)= \phi(x;\theta)^{T}\omega\), 现在有两种参数:
用于从一大类函数中学习 \(\phi\) 的参数 \(\theta\)
用于将 \(\phi(x)\) 映射到所需的输出的参数 \(\omega\).
- \(\phi\) 定义了一个隐藏层, 即: 通过学习特征来改善模型.
4.基于梯度的学习¶
线性模型和神经网络的最大区别, 在于神经网络的非线性导致大多数感兴趣的代价函数都变得非凸, 这意味着神经网络的训练通常使用迭代的、 基于梯度的优化, 仅仅使得代价函数达到一个非常小的值;而不是像用于训练线性回归模型的线性方程求解器, 或者用于训练逻辑回归或 SVM 的 凸优化算法那样保证全局收敛。
凸优化从任何一种初始参数出发都会收敛(理论上如此, 在实践中也很鲁棒但可能会遇到数值问题)。用于非凸损失函数的随机梯度下降没有这种收敛性保证, 并且对参数的初始值很敏感。
对于前馈神经网络, 将所有的权重值初始化为小随机数是很重要的。偏置可以初始化为 0 或者小的正值。
Note
- 当然可以用梯度下降来训练诸如线性回归和 SVM 之类的模型, 但是事实上, 当训练集相当大时这是很常用的。从这点来看, 训练神经网络和训练其他任何模型并没有太大的区别。只是, 计算梯度对于神经网络会略微复杂一些, 但仍然可以很高效而精确地实现。
4.1 代价函数/损失函数¶
为了使用基于梯度的学习方法, 必须选择一个代价函数, 并且必须选择如何表示模型的输出。
- 大多数情况下, 参数模型定义了一个分布 \(p(y|x;\theta)\) 并且简单地使用最大似然原理。这意味着使用训练数据和模型预测间的交叉熵作为代价函数。
- 有时, 使用一个更加简单的方法, 不是预测 \(y\) 的完整概率分布, 而是仅仅预测在给定 \(x\) 的条件下 \(y\) 的某种统计量。 某些专门的损失函数允许我们来训练这些估计量的预测器。
Note
- 用于训练神经网络的完整的代价函数, 通常在基本代价函数的基础上集合一个正则项。
4.2 输出层的设计¶
- 神经网络可以用在分类和回归问题上, 不过需要根据情况改变输出层的激活函数
- 一般而言,回归问题用
恒等函数
, 分类问题用softmax
函数
4.2.1 输出层激活函数¶
4.2.1.1 恒等函数¶
恒等函数的形式
\[\sigma(x) = x\]
4.2.1.2 Softmax 函数¶
softmax函数的形式
\[y_k = \frac{e^{a_{k}}}{\sum_{i=1}^{n}e^{a_i}}\]
其中:
- \(n\): 是输出层神经元的个数
- \(k\): 是指第 \(k\) 个神经元
- \(a\): 是输入信号
softmax函数针对
溢出
问题的改进\[y_k = \frac{e^{a_k+C}}{\sum_{n}^{i=1}e^{a_i+C}}\]
4.2.2 输出层的神经元数量¶
- 输出层的神经元数量需要根据待解决的问题决定
- 对于分类问题, 输出层的神经元数量一般设定为类别的数量
5.隐藏单元¶
5.1 隐藏单元设计介绍¶
隐藏单元的设计方法
- 隐藏单元的设计是一个非常活跃的研究领域, 并且还没有许多明确的指导性理论原则。
- 整流线性单元(ReLU)是隐藏单元极好的默认选择。许多其他类型的隐藏单元也是可用的, 决定何时使用哪种类型的隐藏单元是困难的事, 通常不可能预先预测出哪种隐藏单元工作得最好。
- 隐藏单元的设计过程充满了试验和错误, 先直觉认为某种隐藏单元可能表现良好, 然后用它组成神经网络进行训练, 最后用验证集来评估它的性能。
隐藏层函数可微性分析
一些隐藏单元可能并不是在所有的输入点上都是可微的。
- 在实践中, 梯度下降对这些机器学习模型仍然表现得足够好, 部分原因是神经网络训练算法通常不会达到代价函数的局部最小值, 而是仅仅显著地减小它的值
不可微的隐藏单元通常只在少数点上不可微。
- 一般来说, 函数 \(g(x)\) 具有左导数和右导数, 左导数定义为紧邻在 \(z\) 左边的函数的斜率, 右导数定义为紧邻在 \(z\) 右边的函数的斜率。只有当函数在 \(z\) 处的左导数和右导数都有定义并且相等时, 函数在 \(z\) 点处才是可微的。
在实践中, 可以放心地忽略隐藏单元激活函数的不可微性
- 除非另有说明, 大多数的隐藏单元都可以描述为接受输入向量 \(x\) , 计算仿射变换 \(z=W^{T}x+b\) , 然后使用一个逐元素的非线性函数 \(g(z)\)。 大多数隐藏单元的区别仅仅在于激活函数 \(g(z)\) 的形式。
Note
神经网络中用到的函数通常对左导数和右导数都有定义, 软件实现通常返回左导数或右导数的其中一个, 而不是报告导数未定义或产生一个错误。
5.2 隐藏层激活函数¶
5.1.1 ReLU¶
在神经网络发展的历史上, Sigmoid 激活函数很早就开始使用了, 而在现代神经网络中, 默认推荐的是使用 ReLU(Rectified Linear Unitm 整流线性单元) 函数(Jarrett et al., 2009b; Nair and Hinton, 2010a;Glorot et al., 2011a).
\[\begin{split}h(x)=max\{0, x\} = \left \{ \begin{array}{rcl} x & & {x > 0} \\ 0 & & {x \leq 0} \\ \end{array} \right.\end{split}\]Note
- 整流线性激活函数 (ReLU) 是被推荐用于大多数前馈神经网络的默认激活函数。将此函数用于线性变换的输出将产生非线性变换。 然而, 函数仍然非常接近线性, 在这种意义上它是具有两个线性部分的分段线性函数。
- 由于 ReLU 几乎是线性的, 因此他们保留了许多使得线性模型易于使用基于梯度的方法进行优化的属性。 它们还保留了许多使得线性模型能够泛化良好的属性。
- 计算机科学的一个公共原则是, 可以从最小的组件构建最复杂的系统, 就像图灵机的内存只需要能够存储 0 或 1 的状态, 可以从整流线性函数构建一万个函数近似器
5.1.2 Sigmoid¶
神经网络中用 Sigmoid 函数作为激活函数, 进行信号的转换, 转换后的信号被传送给下一个神经元.
\[h(x) = \frac{1}{1+e^{-x}}, 其中: e是纳皮尔常数 2.7182...\]
5.1.3 双曲正切函数¶
\[h(x) = tanh(x) =\]