DeepLearning 已经持续火了一段时间,很多领域的 state-of-the-art 都被刷了一刷。这里整理一下前段时间关于DeepLearning的学习笔记,主要是CNN以及Neural Networds方面的理解,如果有理解错误之处,还请不吝指出。
首先从最简单的神经网络说起,单独一个神经元可以表示一个逻辑回归模型,表示公式为: hW,b(X)=f(WTX+b) ,图示如下:
其表达的意思也就是权值向量 W 与输入向量 X 相乘后加上偏置 b 经过激活函数输出,网络的输出我们称之为 激活值 。由于激活函数的非线性变换从而使得神经元具备表达非线性模型的能力。
如果我们将输入 X 增加1维,值为1,那么就可以将偏置 b 并入 W 中,表达式变为 hW(X)=f(WTX)
所谓神经网络就是将许多个单一“神经元”联结在一起,这样,一个“神经元”的输出就可以是另一个“神经元”的输入。例如,下图就是一个简单的神经网络:
由上图的网络模型,我们可以简单用公式表达一些前向传播的过程:
第一层:令 z(2)=W(1)x+b(1) , 则激活值为: a(2)=f(z(2))
第二层:将第一层的输出,也就是激活值作为第二层的输入。令 z(3)=W(2)a(2)+b(2) ,则可以得到输出层:
hW,b(x)=a(3)=f(z(3))
以此类推,便是神经网络模型的前向传播的过程。
先举个栗子,假设我们有一个固定样本集 { (x(1),y(1)),...(x(m),y(m)) } 包含&m& 个样例,我们可以用批量梯度下降算法求解神经网络,定义整体代价函数为:
其中第一项 J(W,b) 是一个均方差项,第二项是一个规则化项(也叫权重衰减项),其目的是减小权重的幅度,防止过度拟合.
BP是后向传播的英文缩写,那么传播对象是什么?传播的目的是什么?传播的方式是后向,可这又是什么意思呢
传播的对象是误差,传播的目的是得到所有层的估计误差,后向是说由后层的估计误差推导前层估计误差:
即BP的思想可以总结为:
利用输出后的误差来估计输出层的直接前导层的误差,再用这个误差估计更前一层的误差,如此一层一层的反传下去,就获得了所有其他各层的误差估计。
BP神经网络模型拓扑结构包括输入层(input)、隐层(hide layer)和输出层(output layer)
神经网络的学习目的:
希望能够学习到一个模型,能够对输入输出一个我们期望的输出。
学习的方式:
在外界输入样本的刺激下不断改变网络的连接权值
学习的本质:
对各连接权值的动态调整
学习的核心:
权值调整规则,即在学习过程中网络中各神经元的连接权变化所依据的一定的调整规则。
BP的核心思想就是:
将输出误差以某种形式通过隐层向输入层逐层反传
BP算法的具体推导可以参考UFLDL
用梯度的原始定义来逼近BP误差传递算法以达到检验BP算法的实现是否正确,在UFLDL中经常会做这样的检验。
用法:
- 定义 h 为一个很小的值,然后将输入 θ 替换为 θ+h 进行前向传播,得到 J(θ+h)
- 将输入 θ 替换为 θ−h 进行前向传播,得到 J(θ−h)
- 计算 (J(θ+h)−J(θ−h))/2h 的值,与BP算法反馈回来的值进行比较,两者相差是 10−9 或更小则可以认为BP算法正确实现
像大多数分类器,神经网络也会出现过拟合的现象,这将会导致神经网络的交叉验证以及测试准确率下降。这时我们依旧可以使用 L2 范数进行正则化。此时的 loss Function 如下:
添加这个约束项可以惩罚那些会造成 JR 过大的 W ,也可以减轻网络的复杂性。
惩罚那些会造成 JR 过大的 W 很容易理解,就是在减小 JR 的同时也减小那些比较大的 W 。
减轻网络的复杂性可以用 先验贝叶斯信念( prior Bayesian belief ) 来解释:先验贝叶斯信念认为,优化后的权重 W 应该是非常接近0的。那么要多接近呢?这就要根据 λ 的值来确定, λ 的值越大,就有越多的 W 被优化为 0,此时网络中有效的 w 就变少了,相当于去掉了这部分 w 为 0 的网络,此时的网络就变得比较轻盈了。
然而需要注意的是,我们只对权重 W 进行正则化而不对 bias b 进行正则化,因为 b 对网络的复杂性以及过拟合都没有影响。
加入权重惩罚项之后,就可以减少网络过拟合的概率。
波形图如下:将输入 x 映射到 [0-1] 之间
sigmoid 函数的梯度如下:
Tanh 是 sigmoid 函数的替代品,通常来说,它的收敛速度比sigmoid 函数更快一点,它跟 sigmoid 函数的区别在于,它将输入映射到 [-1,1] 之间,波形图如下:
公式如下:
导数为:
Relu 函数是一个比较流行的激活函数,已经逐渐取代sigmoid函数。它不会随着输入 z 的逐渐增加而趋于饱和。波形图如下:
多层的神经网络如果用sigmoid或tanh激活函数也不做pre-training的话会因为 gradient vanishing problem 而会无法收敛。使用ReLU则这没有这个问题。
预训练的用处:规则化,防止过拟合;压缩数据,去除冗余;强化特征,减小误差;加快收敛速度。
标准的sigmoid输出不具备稀疏性,需要用一些惩罚因子来训练出一大堆接近0的冗余数据来,从而产生稀疏数据,例如L1、L2作惩罚因子。因此需要进行无监督的预训练。
而ReLU是线性修正,公式为:g(x) = max(0, x),是purelin的折线版。它的作用是如果计算出的值小于0,就让它等于0,否则保持原来的值不变。
这是一种简单粗暴地强制某些数据为0的方法,然而经实践证明,训练后的网络完全具备适度的稀疏性。而且训练后的可视化效果和传统方式预训练出的效果很相似,这也说明了ReLU具备引导适度稀疏的能力。
而后续又出现了relu的修改版prelu,这里不做介绍。
前面说的神经网络都是属于监督模型,因为训练样本是有类别标签的,也就是每一个训练样本 x ,我们都知道它的类别 y ,以此进行监督学习。
自编码神经网络是一种无监督学习算法,它使用了反向传播算法,并让目标值等于输入值,比如: y(i)=x(i) ,如下图:
自编码神经网络尝试学习一个 hW,b(x)≈x 的函数,它尝试逼近一个恒等函数,从而使得输出尽可能等于输入。这看上去好像并不现实,因为我们在信息论中学过,信息经过每一层传递处理都会发生损耗,因此自编码神经网络的输入和输出是不可能相等的。
确实,自编码神经网络的输入和输出是不可能相等的,但是我们就是要强迫它相等,或者说尽可能地相等。当我们限制隐藏层的神经元数量时,神经元学出来的特征就变得非常有价值。
如上图,加入我们的输入 x 是100维,但我们限制隐藏层的神经元个数为50个,此时上图的映射关系为:100 - 50 - 100。也就是从隐藏层的50维特征要能够还原出类似于100维的原始输入,这将逼迫50维的隐藏层去学习输入数据的聚类特征,或者说高阶特征。
其实单层的自编码算法或者是卷积神经网络的第一层学习到的特征跟聚类算法,比如 K-means 或者是 GMM 算法聚类得到的特征是一样的。具体可以看下图:
图一:自编码提取的卷积核可视化
图二:Kmeans提取的卷积核可视化
这里的卷积核比较小,所以放大后有点模糊
图一是自编码算法在手写数字图上学习得到的特征,也就是手写数字的边缘特征,图二是我用K-means算法在480x640 的彩色图像上用 K-means 算法聚类得到的特征,也就是K-means的聚类中心。某种程度上来说,他们是一样的,50维的隐藏层神经元去学习描述100维的数据,这50维的隐藏层神经元就可以看做是100维数据的聚类。同样的,GMM算法也可以进行聚类学习得到聚类特征。
另一种情况,就是隐藏层神经元的个数比输入数据个数还多,此时的做法是加入稀疏性限制。稀疏性可以被简单地解释如下。如果当神经元的输出接近于1的时候我们认为它被激活,而输出接近于0的时候认为它被抑制,那么使得神经元大部分的时间都是被抑制的限制则被称作稀疏性限制。
稀疏性限制跟权重衰减是一个道理,比如: fW(x)=w1x1+w2x2+...+wixi ,我们在其cost function 上加入惩罚项 λ∑Li=1||W(i)||2 , 这就限制了权重 W 的值,在不断减小 cost function 的过程中,权重 W 中的某些值会被限制为 0 ,从而使得网络轻盈化。
令 a(2)j(x) 表示给定输入 x 的情况下,自编码神经网络隐藏神经元 j 的激活度,令 p′j=1m∑mi=1[a(2)j(x(i))] , 表示隐藏神经元 j 在训练数据集上的平均值。为了实现稀疏性限制,我们加入一个条件:
其中, p 为稀疏性参数,是一个比较接近于0的值,比如0.05.为了满足这个条件,我们得让大多数隐藏神经元的活跃度接近0.
为了实现这一限制,我们将会在我们的优化目标函数中加入一个额外的惩罚因子,而这一惩罚因子将惩罚那些 p′j 和 p 显著不同的情况,惩罚因子如下:
其中, s2 表示隐藏神经元的数量。
基于相对熵的话,上述惩罚因子也可以表示为:
假设 p=0.2 ,则 ∑s2j=1KL(p||p′j) 随着 p′j 的变化如下图:
由上图可以看到,当 p′j=p 的时候, ∑s2j=1KL(p||p′j) 的值为0,而当 p′j 远离 p 的时候, ∑s2j=1KL(p||p′j) 的值快速增大。因此,很明显,这个惩罚因子的作用就是让 p′j 尽可能靠近 p ,从而达到我们的稀疏性限制。更加具体的计算,请参考ULFDL。
这里只描述一些点的理解,而不做更详细的介绍。
首先,为什么是卷积?卷积运算一个重要的特点就是,通过卷积运算,可以使原信号特征增强,并且降低噪音。
什么是局部感知?神经元并非链接整个输入image,而只是连接局部区域,这个区域叫作局部感受野,它的大小可以理解为 kernel size的大小。
一个feature map是由同一个卷积核卷积得到的,从另一个角度来看,就是同时有 n 个卷积核对一个输入img 进行卷积提取特征,然而这 n 个卷积核的每一条连接 wij ( j 表示第 j 个卷积核, i 表示第 j 个卷积核的第 i 条连接的权重)都是相同的,也就是 wi1=wi2=...win ,效果也就相当于一个卷积核用一定的卷积步长一步一步对输入img进行卷积。然后不同的卷积核就得到不同的feature map。
下图展示了在四个通道上的卷积操作,有两个卷积核,生成两个通道。其中需要注意的是,四个通道上每个通道对应一个卷积核,先将w2忽略,只看w1,那么**在w1的某位置(i,j)处的值,是由四个通道上(i,j)处的卷积结果相加然后再取激活函数值得到的。
所以,在上图由4个通道卷积得到2个通道的过程中,参数的数目为4×2×2×2个,其中4表示4个通道,第一个2表示生成2个通道,最后的2×2表示卷积核大小
output = (input - kernel_size) / stride + 1
由于pooling 也是滑动窗口模式,因此计算公式一样
如果选择图像中的连续范围作为池化区域,并且只是池化相同(重复)的隐藏单元产生的特征,那么,这些池化单元就具有平移不变性 (translation invariant)
注意这两点:1、连续范围 2、池化相同隐藏单元产生的特征
这意思是指,在池化单元内部能够具有平移的不变性,它的平移范围也是有一定范围的,因为每个池化单元都是连续的,所以能够保证图像整体上发生了平移一样能提取特征进行匹配。
举个交单的栗子:假如三个元素(1,5,3),取max就取到5,如果三个元素向右平移一下变成(0,1,5),那取max之后还是5,具备了平移不变性,大概可以这么理解。
Dropout : 使得部分权重被随机设置为0,使得网络稀疏化,能够避免过拟合
weight- decay:权重衰减,也能够避免训练过拟合
实际应用中,我们一般不会设定学习率一层不变,而是使其随着迭代次数的增加逐渐减小:
AdaGrad 也是 SGD的一种,不同的是,它对于每一个参数都有一个特定的学习率,这个学习率跟该参数被更新的次数有关,更新次数多的参数的学习率小,更新次数少的参数的学习率大。公式如下:
# 假设gradient 为 dw ,参数向量为 w
cache += dw **2
w+= -learning_rate * dw /np.sqrt(cache + 1e-8)
可以在caffe中装一个 DIGITS接口 进行可视化查看其变化趋势:
1、UFLDL
2、一文读懂卷积神经网络
3、其他比较零碎就不一一指出了