Recurrent Neural Network

RNN是深度学习领域对序列进行建模的一个非常强大的工具, 它可以实现翻译/手写识别/图片转文本/语音识别等等众多任务, 并且都获得了不菲的成绩. 同时也正是由于它的强大, 学习起来也相对比较费劲, 很难去直观地理解它. 这里有两个推荐资料值得阅读:
推荐资料1: http://www.deeplearningbook.org/contents/rnn.html
推荐资料2: http://colah.github.io/posts/2015-08-Understanding-LSTMs/

===== 什么是RNN =====

看图说话, 假如我们有一段序列, 譬如文本: <x_1,x_2,...,x_n>, 人们在阅读这句话的时候一般是从左向右依次去阅读理解它, 读到某个字x_i的时候, 它可能有多种含义, 那它在这句话中的意思就是由上下文来决定的. RNN序列模型就类似于人类的这个行为, 它以时间为序, 依次获取一个元素, 当前输出不仅受当前元素影响, 还受前面序列输出的影响, 即h^{(t)}是由h^{(t-1)}x^{(t)}.
但是普通的RNN有个毛病, 就是它的记忆力不好, 只能记得最近出现的若干个单词, 稍微远一点的就忘了.

===== RNN痛点 =====
先看一个普通的RNN实现(WUV是共享参数, 共享参数的优点在CNN那一篇文章中有讲述):

    \[a^{(t)}=b+Wh^{(t-1)}+Ux^{(t)}\\ h^{(t)}=tanh(a^{(t)})\\ o^{(t)}=c+Vh^{(t)}\\ \hat{y}^{(t)}=softmax(o^{(t)})\\\]

h^{(t)}依赖于h^{(t-1)}, 进一步简化h^{(t)}

    \[h^{(t)}=Wh^{(t-1)}=W^th^{(0)}\]

进一步简化, 假设W可以进行正交分解, 那么有

    \[h^{(t)}=Q{\Lambda}^tQ^Th^{(0)}\]

假如W某些特征值大于1, 在t次方以后会变得非常大, 对应的梯度值也会非常大, 导致梯度爆发(exploding), 系统的状态会极不稳定; 假如W某些特征值小于1, 那么在t次方以后对应的h^{(0)}的输出就会趋向于0, 对应的梯度值也会非常小, 就是所谓的梯度消失(vanishing).

===== 解决方法 =====
对于梯度爆发和消失, 有很多方法来缓解, 具体见推荐资料1. 但是对于机器学习领域来说, 设计一个简单的易于优化的模型远远比设计一个强大的优化算法简单, LSTM/GRU就是这样的一个模型. LSTM模型见下图:

图截取自推荐资料1, 推荐资料1和推荐资料2对LSTM都有非常透彻的讲解, 这里主要说说怎么从直观上理解LSTM是怎样支持long term的信息传播的以及其他的一些优点.
– LSTM的核心创新点在于引入了一个self-loop, 前一时刻的状态可以通过完全打开forget gate来完全传播给下一时刻.
– 如果想要完全传递初始时刻的状态, 只需要在以后的时刻中input gate全部关闭, forget get和output gate全部打开就可以达到目的.
– 即使当input gate是打开的, LSTM也不是像RNN一样完全替换前一时刻的状态, 而是加权合并这些状态.
– 这些gates可以自主决定是否丢弃一些比较老的信息, 传递比较重要的信息.

===== 结束语 =====
RNN个人感觉比CNN要难, 但是各有各的优点, 各有各的应用擅长领域. 在实际应用过程中活学活用选一个适用的就可以了, 不必拘泥于哪一个模型更好.

— 2016/07/31 15:07

浅析Jacobian和Hessian矩阵

Jacobian和Hessian矩阵是深度学习基于梯度优化算法中两个非常重要的概念, 分别对应一阶偏导和二阶偏导, Jacobian矩阵可以帮你找到所有的critical points, 而Hessian矩阵帮你定位发现的临界点(critical points)是什么类型的, 譬如局部最小值, 局部最大值还是鞍点(saddle point). 下面列举一些Jacobian和Hessian矩阵的一些非常重要的性质, 帮助深度学习优化算法的学习.
注: 参考http://www.deeplearningbook.org第四章, 作者Ian Goodfellow, Yoshua Bengio and Aaron Courville

**性质1:** 如果二阶偏导是连续的, 那么Hessian矩阵是对称的
这是个非常好的性质, 因为深度学习领域里面大部分的函数的二阶偏导都是连续的, 所以它们的Hessian矩阵都是对称的. 由于是实对称矩阵, 我们可以把它分解成一些实特征值集合以及一些互相垂直的实特征向量的集合.

**插入语:** 特征值和特征向量
矩阵是一种向量到向量的映射, 矩阵A的特征值\lambda和特征向量\vec{x}具有性质A\vec{x}=\lambda\vec{x}, 也就是说矩阵A对特征向量\vec{x}的映射只是在\vec{x}方向上进行扩展, 不会改变把\vec{x}映射到其他方向.
实对称阵的不同特征值对应的特征向量是相互垂直的.

    \[A\vec{x}=\lambda\vec{x}\\ (A-\lambda{I})\vec{x}=\vec{0}\\\]

由于\vec{x}\neq\vec{0}存在, 那么A-\lambda{I}必然不可逆, 所以|A-\lambda{I}|=0
如果A正定, 那么A所有的特征值都为正, 并且任意\vec{x}\vec{x}^TA\vec{x}>0
如果A半正定, 那么A所有的特征值都非负, 并且任意\vec{x}\vec{x}^TA\vec{x}\geq0

**性质2:** f(\vec{x})在方向单位向量\vec{u}上的导数为\vec{u}^T\nabla_\vec{x}f(\vec{x}), 在方向\vec{d}(单位向量)上的二阶导数为\vec{d}^TH\vec{d}.
如果\vec{d}H的一个特征向量, 那么对应方向的二阶导数为相应的特征值; 如果是其他方向的, 那么二阶偏导为是所有特征值的加权(权值0到1)平均(可以理解为什么所有特征值为正就能断定这是个最小值, 因为所有方向上的二阶偏导都是正), 并且如果\vec{d}与某个特征值的夹角较小, 那么相应的权值会较大; 最大的特征值对应最大的方向导数, 最小的特征值决定最小的方向导数.

**性质3:** 二阶导数可以决定临界点是一个局部最小值, 局部最大值还是鞍点.
临界点的一阶导数为0, 当二阶导数大于0, 临界点为局部最小值; 当二阶导数小于0, 临界点为局部最大值; 当临界点为0时, 临界点可以为鞍点或者在一个平坦区域里.
推广到多维空间里, 如果临界点的Hessian矩阵是正定的, 那么它是个局部最小值; 如果临界点的Hessian矩阵是负定的, 那么它是个局部最大值; 当临界点的Hessian的特征值有正有负, 那么它可能是个鞍点.

Jacobian和Hessian细细品味起来其实很有意思, 当然他们还有很多很多其他的很好的性质, 这里不再一一列举:)

— 2016/07/09 18:10

卷积神经网络

读书笔记又来了, 源于注中书第9章Convolutional Networks.

**1. 卷积神经网络名称的由来: 卷积公式**
连续变量的卷积公式:

    \[s(t)=(x*w)(t)=\int{x(a)w(t-a)}da\]

离散变量的卷积公式:

    \[s(t)=(x*w)(t)=\sum_{a=-\infty}^{\infty}x(a)w(t-a)\]

其中x一般称为卷积的输入(input), w一般称为卷积核(kernel). 下图是卷积神经网络的图示:

**2. 卷积神经网络三大推动力**
* sparse interactions: 以文本举例, 一个句子中当前的字只跟左右的字具有很强的关联性.
* parameter sharing: deep feedforward nn对于输入的每一个维度都会有一个权值, 而卷积神经网络共用卷积核, 好处就是降低参数量级, 减少计算量, 并且用相同的卷积核处理每个区块会提取出相同的特征, 对于图像来说可能就是边缘特征.
* equivariant representations: f(g(x))=g(f(x)), 以图像举例, 先右移一个像素再做卷积和先做卷积在右移一个像素效果相同, 使得我们不必关心位置, 只关心有没有就行了.

**3. 一般结构**
* 阶段1卷积, 对输入进行卷积操作.
* 阶段2非线性映射, 常用relu激活函数.
* 阶段3Pooling, 常用max pooling, 也有average pooling, L^2 norm pooling等.
Pooling使得对输入进行的小变换不敏感. 有时为了进一步降低计算量, pooling会加上stride, 如下图:

**4. Zero padding**
Zero padding可以帮助卷积神经网络自由设置卷积核的大小, 达到任意层的目的; 否则每加一层都会使得输出减少一些, 极大限制了卷积核的大小.

**5. Locally connected layers, tiled convolution, and standard convolution**

**6. 减少CNN训练时的计算量**
* 随机得到卷积核(有时效果出奇的好)
* 手工设置卷积核
* 无监督学习卷积核(详见神经网络优化中的挑战插入语6)
* 当前大多数的卷积神经网络使用纯监督学习的方式训练

注: 参考http://www.deeplearningbook.org第九章, 作者Ian Goodfellow, Yoshua Bengio and Aaron Courville

— 2016/07/17 12:12

Neural Network实战经验

* L2 norm基于这样一个事实, 当样本数不足以体现整体分布时, 训练集上获得的最优点泛化能力不是最优. L2 norm将得到的最优点往原点拉, 大小通过调节lambda控制, 方向由样本属性控制.
* L1 norm主要作用是特征选择, 效果一般低于L2 norm; max norm或其他norm方式一般也低于L2 norm.
* Norm Penalties as Constrained Optimization, 将正则化部分从损失函数中拉出来, 直接定义成限制条件, 可以通过clip技术实现, 还能和norm共同使用.Dataset Augmentation, 图像处理领域应用较多, 通过拉伸剪切生成新图像作为训练集, 提高泛化能力.
* 直接在权值上添加高斯噪声, 效果是将局部最小值所在的位置放置在比较平坦的位置, 周围的点也近似最小值, 提高泛化能力.
* 一般训练集不是100%准确, 假设每个样本的准确率是95%, 那么y向量可以设置成[0.95, 0.025, 0.025], 而不是[1, 0, 0].
* Early Stopping, 简单而实用的避免过拟合技术, 对训练过程影响很小, 但最终对结果的影响类似L2 norm.
* Parameter Tying and Parameter Sharing, CNN用的比较多, 公用一些参数, 因为一个物体在图像中不同位置并不会改变这个物体的性质.Sparse Representations, L1让W变得稀疏, 这个不仅让W变稀疏, 同时让h变稀疏.
* Bagging and Other Ensemble Methods, 通过交换训练集训练多个分类器进行投票.
* Dropout, 一般输入保留80%, W保留50%, 提升泛化能力非常好的方法.
* Adversarial Training, 类似Dataset Augmentation, 给数据加噪声.
* 正负样本不均衡会导致每次训练准确率波动很大, 通过确定每次每个类别样本的大小来选取样本可以避免波动, 并且会更快收敛. 每个类别样本的比例最好与原分布相同.
* 为了获取最好模型, 需要随机初始化参数并多跑几次.
* 增加弱相关维度对结果没什么影响, 反而增加计算量.
* relu激活函数需要用正随机数来初始化权值.
* 一般选取relu类型的激活函数, 避免gradient vanishing, 并且计算量小, 但要警惕小于零那一部分.
* Test集合足够大时可以反映最终效果.
* 单隐层足够的NN(特征间关系不是很复杂), 多隐层一般不会优于单隐层.
* Regularization一般应用在W上, 不在b上.
* RMSprop算法一般比其他梯度下降算法好.
* 小数据集用batch gradient descent.
* 当relu作为激活函数, 交叉熵作为loss函数时, 记得clip数据.
* Random_uniform一般比random_normal效果好.
* Regularization可以加快收敛速度.精心设计维度值, 会提升不少准确率.
* 对于categorical数据, 1 of C-1 effects coding比较有效, 譬如Red/Green/Blue向量分别为(1,0),(0,1),(-1,-1), 均值已经为0了. (直接1,2,3表示也能拟合, 但是需要更多神经单元, 更难训练)
* 如果每个类别的预测准确率都比较低, 那么尽量不要用softmax, 用多分类.
* Regularization可以调整准确率召回率之间的权衡.
* 单隐层的神经网络可以以任意精度拟合出任意单值函数, 研究领域主要要做的事是用数据和算法(包括神经网络结构的改变)最好地拟合出来这个函数.
注: 一些调优经验条目不一定适用于所有情况, 具体问题具体分析.

— 2016/06/18 09:13

神经网络优化中的挑战

已经有好几篇都类似于注中提到的那本书的读书笔记, 这篇也不例外:)读书笔记是个很好的习惯, 可以帮你巩固记忆, 记下纲领, 即使以后忘了, 也可以通过笔记很快记忆起来. Deep Learning是本好书, 推荐阅读~

**挑战1:** Ill-Conditioning
Condition的定义见于第四章, 对于矩阵A, 它的condition number是\max_{i,j}|\cfrac{\lambda{i}}{\lambda{j}}|. Ill-Conditioning会导致NN的学习过程被卡主, 甚至一个很小的步长会导致loss function增大. 第四章在讲解Jacobian和Hessian矩阵的时候有个例子, 可以帮助理解.

**挑战2:** 局部最小值
凸优化理论中可以认为局部最小值就是全局最小值, 但是神经网络的函数不是凸函数, 它会存在相当多的一些局部最小值, 如果相当大一部分局部最小值与全局最小值的cost相差很大, 那么我们就很难通过梯度下降得到一个比较令人满意的结果.

**挑战3:** 平坦区域, 鞍点, 局部最大值
在低维空间中, 局部最小值比较常见; 而在高维空间中, 鞍点非常多, 并且局部最小值比较稀少. 直观上我们可以认为鞍点个数比上局部最小值个数的比例与输入维度成指数倍增长. 还有局部最大值, 虽然一阶梯度下降算法可以避免进入局部最大值, 但是未经修饰过的牛顿算法就不行.

**挑战4:** 梯度爆发
当NN的层数比较多的时候, 损失函数就会出现很多类似悬崖一样的梯度非常大的区域, 就会导致梯度算法移动相当大的一步, 这不管是往下移还是往上移都是非常危险的. 庆幸的是一些启发式算法可以避免此问题.

**挑战5:** 长期依赖
举例来说, 假如一个计算会不停重复乘以矩阵W, t步之后, 就相当于乘了W^t. 假设W可以进行特征分解W=Vdiag(\lambda)V^{-1}, 那么

    \[W^t=Vdiag(\lambda)^tV^{-1}\]

如果\lambda不是跟1很相近, 假设大于1, 那么就会引起梯度爆发; 假设小于1, 就会引起梯度消失.
RNN对每个时间步长来说都会用相同的一个Matrix, 但是前向神经网络不会, 这个会极大避免梯度消失和梯度爆发.

**挑战6:** 不精准的梯度
实际上, 收集的训练集都是有噪声的, 或者由于批梯度算法得到的非整体分布, 得到的梯度和Hessian都是有偏的.

**挑战7:** 局部和全局的弱关联性

如上图所示, 假设初始化时点在左边, 由于局部和全局的弱关联性, 根据梯度下降算法我们就很难得到曲线右边的较优值.

**插入语1:** 优化算法纲要
* Momentum: 通过历史梯度方向改变现有梯度方向优化收敛过程
* RMSprop/Adagrad等: 通过改变步长优化算法
* Adagrad: 所有以往步长作为参考信息
* RMSprop: 历史步长影响力乘以一个指数下降
* Adam: RMSprop加上momentum并且加上bias校正
**插入语2:** Newton Method缺点:
* 只适用于Hessian矩阵正定的情况, 深度学习的loss表面比较复杂.
* 计算Hessian矩阵以及它的逆计算量超大.
**插入语3:** Conjugate gradients和BFGS算法是为了克服Newton’s Method计算量上的缺点进行的优化.
**插入语4:** Batch Normalization是一项重大的创新, 通过normalize每一隐层单元的输出来达到normalization的目的(类似激活函数外再加一层激活函数, batch_norm), 并且效果好于常规的加penalties(L1, L2, etc.)的normalization方法.

    \[H'=\cfrac{H-\mu}{\sigma}\]

**插入语5:** 坐标下降算法通过依次最优化每个坐标方向来达到最优化的目的; block coordinate descent一次处理多个维度, 不适用于维度间相互影响比较严重的情况.
**插入语6:** Surprised Pretraining简单来说就是通过一层一层训练来简化深层网络难以训练的问题.(层次比较少的比较宽的网络比层次比较深的网络更容易训练, 但是神经元个数往往更多, 更浪费时间) GoogLeNet通过在深层网络中间添加输出的方式来使得网络初始层获得较高的梯度, 类似于pretraining.
**插入语7:** Polyak Averaging在计算t次迭代的时候也将之前的迭代出的参数考虑进来.
**插入语8:** 实际上, 选择或者设计一个好的模型远远比选择一个强大的优化算法更重要.
**插入语9:** Continuation methods大致思想是构造一些相同参数空间的loss函数, 优化难度从小到大排列(优化难度越低表示越大的参数空间会落入相对较小值), 当初始化的参数在低优化难度的loss函数上获得较好的效果时, 那么它放到难优化的loss函数中时经过调整(梯度算法等)就会在更难优化的loss函数上达到较优的效果, 直到最终的loss函数. Curriculum learning是Continuation methods的一种, 类似教学, 总是从简单的学起. (extremely successful in recent years)

注: 参考http://www.deeplearningbook.org第八章, 作者Ian Goodfellow, Yoshua Bengio and Aaron Courville

— 2016/07/10 11:21