DeepLearning 已经持续火了一段时间,很多领域的 state-of-the-art 都被刷了一刷。这里整理一下前段时间关于DeepLearning的学习笔记,主要是CNN以及Neural Networds方面的理解,如果有理解错误之处,还请不吝指出。
首先从最简单的神经网络说起,单独一个神经元可以表示一个逻辑回归模型,表示公式为:
其表达的意思也就是权值向量
如果我们将输入
所谓神经网络就是将许多个单一“神经元”联结在一起,这样,一个“神经元”的输出就可以是另一个“神经元”的输入。例如,下图就是一个简单的神经网络:
由上图的网络模型,我们可以简单用公式表达一些前向传播的过程:
第一层:令
第二层:将第一层的输出,也就是激活值作为第二层的输入。令
以此类推,便是神经网络模型的前向传播的过程。
先举个栗子,假设我们有一个固定样本集 {
其中第一项
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算法正确实现
像大多数分类器,神经网络也会出现过拟合的现象,这将会导致神经网络的交叉验证以及测试准确率下降。这时我们依旧可以使用
添加这个约束项可以惩罚那些会造成
惩罚那些会造成
减轻网络的复杂性可以用 先验贝叶斯信念( prior Bayesian belief ) 来解释:先验贝叶斯信念认为,优化后的权重
然而需要注意的是,我们只对权重
加入权重惩罚项之后,就可以减少网络过拟合的概率。
波形图如下:将输入 x 映射到 [0-1] 之间
sigmoid 函数的梯度如下:
Tanh 是 sigmoid 函数的替代品,通常来说,它的收敛速度比sigmoid 函数更快一点,它跟 sigmoid 函数的区别在于,它将输入映射到 [-1,1] 之间,波形图如下:
公式如下:
导数为:
Relu 函数是一个比较流行的激活函数,已经逐渐取代sigmoid函数。它不会随着输入
多层的神经网络如果用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,这里不做介绍。
前面说的神经网络都是属于监督模型,因为训练样本是有类别标签的,也就是每一个训练样本
自编码神经网络是一种无监督学习算法,它使用了反向传播算法,并让目标值等于输入值,比如:
自编码神经网络尝试学习一个
确实,自编码神经网络的输入和输出是不可能相等的,但是我们就是要强迫它相等,或者说尽可能地相等。当我们限制隐藏层的神经元数量时,神经元学出来的特征就变得非常有价值。
如上图,加入我们的输入
其实单层的自编码算法或者是卷积神经网络的第一层学习到的特征跟聚类算法,比如 K-means 或者是 GMM 算法聚类得到的特征是一样的。具体可以看下图:
图一:自编码提取的卷积核可视化
图二:Kmeans提取的卷积核可视化
这里的卷积核比较小,所以放大后有点模糊
图一是自编码算法在手写数字图上学习得到的特征,也就是手写数字的边缘特征,图二是我用K-means算法在480x640 的彩色图像上用 K-means 算法聚类得到的特征,也就是K-means的聚类中心。某种程度上来说,他们是一样的,50维的隐藏层神经元去学习描述100维的数据,这50维的隐藏层神经元就可以看做是100维数据的聚类。同样的,GMM算法也可以进行聚类学习得到聚类特征。
另一种情况,就是隐藏层神经元的个数比输入数据个数还多,此时的做法是加入稀疏性限制。稀疏性可以被简单地解释如下。如果当神经元的输出接近于1的时候我们认为它被激活,而输出接近于0的时候认为它被抑制,那么使得神经元大部分的时间都是被抑制的限制则被称作稀疏性限制。
稀疏性限制跟权重衰减是一个道理,比如:
令
其中,
为了实现这一限制,我们将会在我们的优化目标函数中加入一个额外的惩罚因子,而这一惩罚因子将惩罚那些
其中,
基于相对熵的话,上述惩罚因子也可以表示为:
假设
由上图可以看到,当
这里只描述一些点的理解,而不做更详细的介绍。
首先,为什么是卷积?卷积运算一个重要的特点就是,通过卷积运算,可以使原信号特征增强,并且降低噪音。
什么是局部感知?神经元并非链接整个输入image,而只是连接局部区域,这个区域叫作局部感受野,它的大小可以理解为 kernel size的大小。
一个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、其他比较零碎就不一一指出了
版权声明:本文为博主原创文章,未经博主允许不得转载。
DeepLearning (六) 学习笔记整理:神经网络以及卷积神经网络
原文地址:http://blog.csdn.net/llp1992/article/details/49685537