神经网络基础
(预警:本节开始涉及数学符号及必要的微积分、线性代数运算)
本节概要
在上一讲中已经提到,“学习”就是要让计算机自动去实现一个复杂函数,完成从输入X到输出Y的映射。机器学习的基本框架如下图所示。
本节将从神经网络的角度,应用这个框架。
首先要定义假设函数集合(function hypothesis set),又称模型(model),然后根据输入数据做训练,去找到一个“最好”的函数 f∗ 。最后用它对测试数据做测试。
要解决的三个问题:
1. What is the model?(这个模型是什么样子的)
2. What is the “best” function?(如何定义“最好”)
3. How to pick the “best” function?(如何找到这个目标函数)
本节应用的任务的是分类(classification)问题,即预测输入是已知类别中的哪一类,对应的是离散的输出变量。
- 二分类问题(Binary Classification)
- 垃圾邮件过滤(是不是垃圾邮件)
- 推荐系统(该商品需不需要推荐给该用户)
- 恶意软件检测(该软件是否存在恶意操作)
- 股票预测(股票是涨还是跌)
- 多分类问题(Multi-class Classification)
- 手写数字识别(图片写的是哪一个数字)
- 图像识别(图片里的物体是什么)
一. What is the model(function hypothesis set)?
换句话说,网络结构长什么样?
对于分类问题,我们要找到这样的 y=f(x) ,其中x是待分类的对象,y是该对象所属类别,并假设x和y各自都是固定长度的向量(fixed-size vector),即 x⊆RN,y⊆RM .
以手写数字识别为例,二值图像可以统一调整成16*16的大小。输入向量的每一维表示每个像素是0还是1;输出向量用one-hot 表示,即对应类别的那一维标记为1,其余类别标记为0。
回到我们要解决的问题,如果只用单层神经元,那么连异或这种简单的逻辑操作都很难完成,此处省略证明过程,所以引入多个隐藏层的神经网络。
神经网络作为模型
全连接前馈网络
最常用的神经网络架构——全连接前馈网络(Fully Connected feedforward network)如上图所示,通常又称深度神经网络(Deep Neural Network,因其隐层数目多而冠上“Deep”)。
每一层的每一个节点都用前一层所有节点的输出做权重和(weighted sum)后作为输入,经自身的激励函数加工后,产生输出给下一层。
神经网络的数学标记
规定以下标记用于描述DNN(非常重要!):
- 第
l
层神经元的数目
Nl ,除权重外,上标 l 代表该神经元所在的层次,下标i 代表是该层的第几个神经元。 - 两个神经元之间的权重
wlij
,下标
ij
代表从第
l−1
层的第
j
个神经元通向第
l 层的第 i 个神经元,上标l 代表后者所在层次。
- 这样定义看上去很奇怪,但其实是为了赋予权重矩阵 Wl 和向量 x 所做的乘法的意义,很巧妙。
-
- 神经元的偏置bias
bli
,第
l
层神经元的所有bias构成向量
bl - 神经元的输入
zli
。第
l
层神经元的所有输入构成向量
zl 。定义zli=∑j=1Ni−1wlijal−1j+bli -
- 神经元的输出
ali
,第
l
层神经元的所有输出构成向量
al 。定义 ali=σ(zli) ,其中σ(·)为激励函数。
- 神经元的输出
ali
,第
l
层神经元的所有输出构成向量
- 神经元的偏置bias
bli
,第
l
层神经元的所有bias构成向量
注意仔细观察下面几张图!
单个神经元涉及的标记。
相邻层次涉及的标记(前)。
相邻层次涉及的标记(后)。
函数总览
至此,我们就定义好了我们的model的样子,即DNN式的网络结构。
但是大量参数就意味着无穷大的假设函数空间,那么我们怎么从假设函数空间里找到我们所需要的那个函数呢?接下来就要解决这个问题。
二. What is the “best” function?
由于不同的参数 W 和 b 决定了我们最终不同的函数,因此要找最好的函数<=>找最优的参数集合。
定义函数 f(x;θ) , 其中x是函数的输入,θ是函数中涉及的所有参数 W 和 b 的集合,随着参数值的变化,这样的函数构成了我们的假设函数空间,因此学习 f∗ <=>学习 θ∗ 。
代价函数
定义代价函数(Cost Function) 为C(θ) ,它以参数集合θ作为输入,输出的实数值衡量这组参数“不好”的程度,值越大意味着参数越糟糕。又称为损失函数(loss function)、误差函数(error function)。
那么我们的问题就转化为搜索所有的参数θ,找到一组 θ∗ ,满足
实际上,代价函数的真正数学定义与我们的任务高度相关(task-dependant),不同的任务应当采取对应的代价函数。
多分类问题中常用的代价函数形式如下图所示。
在这里,代价函数衡量的就是对于所有样本,模型的输出 f(xr;θ) 和真实的标记 y^r 的距离之和。
三. How to pick the “best” function?
梯度下降
定义完衡量参数的指标,接下来就是对参数调整来寻找最佳参数,那要如何进行调整呢?
如果用暴力搜索,那么需要穷举所有可能的θ,但是这样做要计算到猴年马月,所以显然是不可能完成的任务。
实际的解决方法就是著名的梯度下降(Gradient Descend)。
先以单变量为例来看梯度下降的概念。
直观地理解:将一枚小球放在曲线的初始位置,那么小球收到重力的影响就会沿着当前最陡峭的下降方向往下滚,直到稳定在一个“坑”里。其中曲线相当于受自变量θ影响的函数值C(θ),最陡峭的下降方向就称为梯度(gradient),稳定的“坑”就称为局部最小值(local minima)。高等数学里的知识告诉我们,让函数曲线对该单变量求导,就可以算出斜率,就是我们要找的梯度。
对于参数优化问题,首先随机选择一组 θ0 ,找到 (θ0,C(θ0)) ,然后计算 dC(θ0)dθ 。第一次更新时,让 θ0−η∗dC(θ0)dθ 成为新的 θ1 。重复上述迭代的步骤,直到 θ 不再发生变化。
对于多变量的情况,只是把求导换成了对各个变量依次求偏导,再同时更新参数。
上面提到的 η 叫做学习率(learning rate),即用梯度更新参数时的幅度, η 越大则更新时迈出的步伐越大。(非常重要的参数!!!)
接着是用泰勒展开来证明梯度下降的严格推导,这里就不再展开。
总之,在我们搭建的神经网络里,我们要更新的θ就是所有参数
W
和
b
的集合。
由于涉及大量的参数,要实现高效的计算梯度并更新,就要使用反向传播算法(backpropagation,BP)。(在之后会详细解释)
这里留下了一个问题,当C(θ)的值卡在极小值点处,或者鞍点(saddle point)时,该点的导数值为0,不对参数进行更新,但实际上并没有达到我们的目标。关于这个问题的讨论留到后面的几节里。
训练时的实战技巧
参数初始化
参数的初始化(parameter initialization)确实会影响梯度下降的性能,但目前入门阶段,我们只要随机赋值即可,但不要把全部参数都初始化成一模一样的值。
学习率的调整
上面提到,学习率是决定模型能否正常收敛,以及最终模型好坏的非常重要的因素。
比较理想的情况是,学习率能随着迭代次数的递进而变化。但是对于入门阶段,李老师的建议是,用尝试的方法仔细调整这个超参数。
从左边这张图上我们看到,随着迭代的进行:
- 当 η 过大时,更新太剧烈,代价函数的值直接越过我们期望的最小值(error surface上的谷底),代价只会越来越大;
- 当 η 偏大时,代价函数的值虽然会很接近最小值,但是依然在“谷底”两侧震荡,进入不了谷底。
- 当 η 偏小时,更新太缓慢,代价函数呈递减趋势,虽然会不断逼近且成功到达最小值,但是需要大量的迭代计算,收敛速度较慢。
- 当 η 合适时,更新幅度比较理想,既保证了能顺利收敛,而且收敛速度也比较快。
举例:双变量代价函数在不同学习率下的梯度下降图示:
随机梯度下降和mini-batch
优化的万能药
未完待续。。。