深度学习第五课-训练注意事项与框架使用

说明:本文是七月算法5月深度学习班第五次课听课笔记。黄色标注的部分为自己不太确定的部分。

训练


mini-batch SGD

神经网络使用mini-batch SGD训练得到最优权重。训练过程如下:(以下参考了andrew ng的机器学习课程)

例如训练样本量m=3200,mini-batch 每次取32张

for  i = 1,33,65,...
从i 开始取32个图片样本
前向计算得到中间变量a  z 和 损失函数值
后向计算得到梯度
用这部分梯度更新权重


问:为什么使用batch而不使用一张图片呢?
答:一张图片样本量不够,容易发生振荡。 如果是一张图片,就是随机梯度下降了。 

两种去均值方法

第一种:减去图片每个像素的均值。在图片的每个像素位求均值。例如样本图片是[32,32,3],将会得到[32,32,3]数组的平均值。每个样本的不同像素减去对应位置的均值。AlexNet使用该方法。
第二种:减去每个通道(channel)的均值。例如样本图片是[32,32,3],会得到3个平均值,分别表示R、G、B的均值。每个样本不同通道的值减去对应的均值。VGGNet使用该方法。
再次强调:CNN训练不需要做标准化、PCA和白化

权重初始化


SGD参数学习第一步就是权重初始化。权重初始化有多种方法。
al表示每层神经单元值。W1表示从第一层到第二层的权重
         
方法1  w=0。不可以。所有权重初始化为0,这会发生对称现象。例如a2=g(a1*W1)。所有W1=0,a2所有神经单元的值就都相同了。而神经网络的不同神经元是用来学习不同的知识点。这样就引起了对称性。不能好好工作了。

方法2 w=0.01*np.random.rand(D,H).  初始化权重为一些小的随机数。在python实现中,实现了权重正负数各一半。效果:该方法在包含1-2个隐藏层的网络中是有效的。网络层数加深, 带来整个网络激活传递的不对称性(会引起数据在很小或者特别大的范围内变动,也就是说方差趋于0,或者无穷)
实现:使用10层网络(500)神经元,观察 每一层 神经单元的 平均值 和方差。可以看到从第三层开始均值与方差几乎不发生变化,接近0。

方法3 w=np.random.rand(fan_in,fan_out). 说明:fan_in = 这一层输入元素的个数,fan_out=这一层输出元素的个数。效果:会出现梯度为0的情况,类似sigmoid函数出现的情况。
 
方法4 w=np.random.rand(fan_in,fan_out)/np.sqr(fan_in) 效果:效果还不错可以使用。但是在使用ReLU激活函数的时候,同样 带来整个网络激活传递的不对称性
方法5 w=np.random.rand(fan_in,fan_out)/np.sqr(fan_in/2)这是一篇在2015年的论文中提到的方法。可以解决ReLU时发生的问题。

Batch Normalization


        对于权重可能引起网络激活的不对称性问题,谷歌提出了一种解决方法Batch Normalization。思想是期望激励过后的神经元的值仍然能够保持高斯分布。
        问:为什么是高斯分布呢?
        答:高斯分布简单,方差可控。而且还满足了同一层神经元要有一定的差异性。
        问题:BN放在什么问题?
         Batch Normalization通常接在全连接之后,激励层之前。全连接层是产生波动最大可能性的地方,也是学习能力最强的地方。
        问题:BN的具体操作
        求均值;求方差;xi=(xi-均值)/np.sqr(方差+e);最后一步做伸缩和平移且输出:yi=gama * xi+beta     。gama和beta是训练过程中可以获得的。 之所以有最后一步,是因为BN过程中对原始数据做了修改,表达的信息会有部分丢失。通过伸缩平移尽量将信息还原
        BN的优点是:学习率设置高一点也可以;对初始化数据依赖少了。


开始训练

首先先用小数据集训练(10个分类,每个分类下10个样本)测试训练模型是否OK。接着可以改变正则化,从无到有。
需要监控的参数 1const function的值是不是振荡下降;2 训练集上的准确率是否能到100%。
几个现象:准确率低(0.6),cost function值不变=>有问题,学习率太大了?
训练集准确率>>交叉验证集准确率   =>过拟合,试试调大正则化项?
训练集准确率 约等于 交叉验证集准确率   如果都很高,那模型不错,可以使用。如果都很低(0.6),数据问题?模型问题?样本倾斜了?

Dropout ---神经网络正则化

        L2 正则化    l = ... + lamda*(权重和)    用于神经网络,参数个数多,计算量大。所以不是最好的选择。
        Dropout 语言描述:1 别一次打开所有学习单元;别让神经元记住那么多东西;每次关掉一部分感知器,得到新的模型,最后融合。
        设置一个概率p=允许通过的概率。在dropout层,会有n*(1-p)个节点关闭,神经单元的值为0。注意:不是权重为0。由于训练的时候有一个概率,在预测的时候同样需要概率。所以工业上一般是在训练过程中,将输入数据x=x*p。预测的时候就不需要再乘以p了。


Caffe使用


主要模块

                Blob 存储数据和梯度值
                Layer 传递层与层的输入输出
                Net   网络,利用前向后向计算梯度
                 Solver 用梯度更新权重

                                                        

使用过程

               网上有很多资料讲使用过程,这里不详细记录。
                1 Resize图片,转存为LMDB/LevelDB格式。注意分类下表从0开始。
                2 定义网络结构
                3 定义solver,训练参数
                4 训练

模型库选择  model zoo

               1 如果层次不变,改变输入输出
                  输入是 data层 data_param 和transform_param 参数段。输出是layer {  name: "fc8"  , name 需要修改

               2 如果添加/删除层次,注意顺序。一般把前面层学习率调低,从修改层开始调高学习率。一般fine-tuning的前期loss下降非常快,中间有个瓶颈期,要有耐心。
               3 在solver调整学习率(1/10,1/100)。利用snapshot 存储中间结果。如果发生宕机,可以接着继续训练。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值