————————————————————————————
原文发表于夏木青 | JoselynZhao Blog,欢迎访问博文原文。
————————————————————————————

深度学习教程与实战案列系列文章


深度学习 | 绪论
深度学习 | 线性代数基础
深度学习 | 机器学习基础
深度学习 | 实践方法论
深度学习 | 应用
深度学习 | 安装conda、opencv、pycharm以及相关问题
深度学习 | 工具及实践(TensorFlow)
深度学习 | TensorFlow 命名机制和变量共享、变量赋值与模型封装
深度学习 | TFSlim介绍
深度学习 | TensorFlow可视化
深度学习 | 训练及优化方法
深度学习 | 模型评估与梯度下降优化
深度学习 | 物体检测
深度学习| 实战1-python基本操作
深度学习 | 实战2-TensorFlow基础
深度学习 | 实战3-设计变量共享网络进行MNIST分类
深度学习 | 实战4-将LENET封装为class,并进行分类
深度学习 | 实战5-用slim 定义Lenet网络,并训练测试
深度学习 | 实战6-利用tensorboard实现卷积可视化
深度学习 | 实战7- 连体网络MINIST优化
深度学习 | 实战8 - 梯度截断
深度学习 | 实战9- 参数正则化


训练及优化方法

    • 深度学习教程与实战案列系列文章
  • 深度网络优化方法
    • 优化及调试策略:实践流程
    • 梯度消失与梯度爆炸
    • Sigmoid 激活函数问题
    • ReLU
    • 参数初始化
    • 学习率
    • 迭代次数
    • batch size
      • Batch 方差与 learning rate 关系
      • Large-batch 魔咒
  • 正则化
    • 正则化技术概述
    • 数据增强技术
    • 数据集规范化
    • 目标函数及正则化
    • dropout
    • Batch Norm
      • moving_mean,moving_variance 为什么需要学习和更新?
      • μ, σ 是否需要在测试时更新?
      • TF Batch Norm 接口
      • TF Batch Norm 使用方式:
      • 训练参数保持
      • TF Batch Norm 使用方式:
      • 指数加权平均
      • Batch Norm 实现细节剖析
      • 应用举例:作业学号三次函数拟合 cos

深度网络优化方法

优化及调试策略:实践流程

  1. 确定目标:误差度量及期望目标
  2. 建立端到端流程:
    数据读取、预处理流程
    端到端模型构建:基准模型(传统方法、经典模型)vs 设计模型
    性能度量、评测脚本

三个脚本先写好:数据处理、模型训练、评测脚本

  1. 搭建系统,确定性能瓶颈:
    调通系统:是否出现正确结果
    预期判断:过拟合、欠拟合?
    调通系统:是否出现正确结果?

我们最关心的是泛化性能,所以评测脚本很重要,得出目前结果是过拟合还是欠拟合。

  1. 根据观察进行增量式改进:
    收集新数据、调参、改进算法

错误来源: 算法本身还是编程实现
难点: 1. 无法预测算法行为;2. 模型很多地方自适应
重要的调试检测手段:

  1. 可视化计算中模型的行为(看中间,最后输出结果)
  2. 可视化最严重的错误(看做错的例子)
  3. 训练、测试误差分析:
    训练低,测试高:过拟合、训练模型未正确加载
    训练高,测试高:欠拟合、程序错误
  4. 缩小问题规模,测试程序正确性
  5. 可视化网络参数、梯度等

梯度消失与梯度爆炸

梯度消失: 随着网络层数的增加,网络从后往前,传回的梯度越来越小,导致之前的网络层“训不动”

图中三张图表示网络层数分别为2、3、4的情况,
越靠近前面的层,变化越小

梯度爆炸:梯度下降训练过程中遇到损失突变的位置(墙、悬崖 等形态),梯度瞬间增大,指向某处不理想的位置。可能现象: 训练无法收敛; 损失函数、权重:变化非常大 or 出现 NaN 值; 梯 度:每层的每个节点训练时梯度一直大于 1.0

链式法则? 在RNN中更常见。

问题本质:梯度的乘积积累
期望效果:连续乘积都刚好平衡大约等于 1,但几率很小
梯度爆炸更多来源于不合理的参数初始化及过大的学习率
梯度消失在更深的网络中更具有普遍性
梯度的乘积积累路径变长
激活函数的问题:例如 Sigmoid 易饱和,考虑采用 ReLU 等

消失和爆炸都在于累乘。
sigmoid 对信息的保存更好,更平和(Relu小于0的部分全都丢掉了)

Sigmoid 激活函数问题

1.exp() 计算复杂
2. 激活函数易饱和,梯度易消失:$z^(l−1) $偏大或偏小的地方 (-4>,>4) 接近 0,梯度传递接近 0 .


3.sigmoid 输出范围 (0 1), 非 0 中心,σ(zl−1) 总大于 0,由

权重更新呈现锯齿形

ReLU

不易出现激活函数饱和问题 (为什么), 计算高效
相比 sigmoid/tanh 收敛速度快 (为什么?)
问题: 依然是非 0 中心输出; 存在 dying ReLU 问题; 信息丢失

dead 节点连接的下面的 参数不再更新了。

激活函数输入 zn 小于 0,梯度也为 0,zn 之前权重 w 不能更新
权重未初始化好 (使得某些节点对所有样本输出都是负数),或训练过
程中,一股剧变梯度使得 w 分布突然改变在一定范围,使得 zn 输出一直小于0,w永远不更新。

参数初始化

  1. 优化结果优劣(不只是最小值问题,梯度学习行为)
  2. 训练是否可行(梯度消失、爆炸、训不动。。。)

参数设得大,容易炸。

破坏对称性:
随机初始化权重
不能 0 初始化(回顾之前可视化中的例子,为什么?)
随机初始化权重 0 初始化权重失败(回顾之前可视化中的例子)

权重大小:相对大的情况
大权重破坏对称性更强 +
有益于缓解梯度消失 +
梯度爆炸等不稳定问题-(权重累积存在反向传播链上)
激活函数易饱和-

不同层的缩放因子

一开始都是同样的01初始化,后面层的分布可能会更摘一点

偏置可以 0 初始化

偏置不会出现在链上,所以没有影响

随机、不能全0、不能太大也不能太小

LeNet 训练 MNIST
案例 1, 送分题:全 0 初始化 LeNet 导致参数不更新。为什么?

案例 2:错误的层间参数数值范围比例:初始化最后全连接层参数 均值 100,方差 10;其他层变量均值 0,方差 0.1。导致无法训练: 学习率太小,学不动;太大,爆炸,或不收敛。

权值大,则学习率应该大一点,才能匹配,不然学不懂。

训不动,但又没有炸,则可以抬高学习率。

参数随机初始化的问题:
10 层的神经网络,非线性变换为 tanh,每一层的参数都是随机正态分布,均值为 0,标准差为 0.01
训练后,每一层输出值分布的直方图

输出集中在 0 附近,对样本变化太敏感,网络表达能力差,且本层w 难以更新(反向传播公式)

均值仍然为 0,标准差现在变为 1

这样的网络近似为一个二值网络

输出集中在-1,1, 网络表达能力依然弱 (极端情况下,相当于 2 值网络),且 tanh 激活函数饱和,w 依然无法更新

无法更新的原因: 0值的地方穿不过来,1的地方饱和了。

问题出在哪里?
参数太大,饱和;太小,不激活:激活函数的特性(relu 也存在相 关问题)
如何配合激活函数特性初始化参数?
Xavier 或者 Glorot initialization 方案

基本思想: 保持输入和输出的方差一致,避免所有输出值都趋向于0

针对不同激活函数的 Xavier 初始化形式

不同激活函数对应的初始化区别主要是根号外的系数
Tensorflow 中可以根据公式手动缩放初始化值,也有类似的 xavier_initializer 初始化方法:

initializer = tf.contrib.layers.xavier_initializer()
W = tf.get_variable("W", shape=[784, 256], initializer= initializer)
w1 = tf.Variable(initializer(w1_shape))

大多数都是采用的这个初始化方法

ReLU 实验效果:xavier 初始化 (注意:下面写法是 node_in ≈ node_out 的近似)

另一种方差平衡初始化:He initialization
基本思想:ReLU 网络中,假定每层一半神经元被激活,另一半为 0 保持 variance 不变,需在 Xavier 的基础上再除以2


这样的效果更好一些。

node_in 和node_out 是什么?

学习率

学习率选择

  • 过大: 振动、不收敛;过小: 收敛速度慢
  • 理想的学习率设计是:前期较大学习率搜索,后期小学习率调优。
    以及对参数的个性化调整:优化频率高的参数小学习率调整,优化频率低的参数大学习率调整。
  • 初期选择 :指数级改变学习率观察 loss 变化
  • 其他手段:
    自适应学习率算法: Nesterov ,Adagrad , Adadelta , Adam… 热启动

有的网络会先以小学习率训练一段时间,再调大学习率,这个叫做热身。
蓝色,下坡缓慢,学习率太低了。
红色,是比较理想的情况
学习率不光影响学习的速率,还影响最后的收敛效果。
想调整成为红色,但可能会调整成为绿色。 收敛并不代表最优。

学习率对模型训练的影响

学习率大了之后,毛刺比较多。在lr=0.003的时候,收敛速度慢了一些,但较为平稳了。
lr = 0.00001的时候,训练效果是最好。 为了得到更好的效果,慢也得等。

学习率分析举例:LeNet 训练 MNIST
案例 1:lr(ε 步长)=0.0001;0.001;1 各是哪个loss?

橙色线对应着 0.0001 ,因为收敛得最为缓慢。

lr(ε 步长)=0.0001;0.001;1 各是哪个 w?

学习率越小,波动越大。

学习率衰减策略:learning rate decay 学习过程中,学习率并不是一成不变,而是根据学习的情况进行调整 开始大,快速收敛,后期小,优化收敛位置

学习率衰减策略很多,主要包括持续衰减和周期学习率两种,其代表: Exponential decay: 学习率随一定步长阶段指数减少,最常用
Cycle learning rate: 防止网络后期 lr 十分小导致一直在某个局部最小值 中振荡,突然调大 lr 可以跳出注定不会继续增长的区域探索其他区域

另外,很多时候,由于网络或模型中一些部件的特性,需要先用比较 小的学习率优化其参数 (例 BatchNorm 种的 moving avg),之后再开始 训练,对此类网络常先用一个较小学习率进行“Warm up”, 再用一般 学习率衰减策略

迭代次数

由于泛化界限的存在,数据在迭代训练时,会逐渐产生过拟合现象
变化趋势表现为:

  1. test loss 与 train loss 均缓慢下降并趋于平稳
  2. train loss 虽然下降,但 test loss 已经开始上升
  3. train loss 与 test loss 一直上升 (呈现 U 形)

提前终止(early stop)

  • 一种常用的正则化形式
  • 当验证集上的误差在事先指定循环次数内没有进一步改善时,停止训练算法
  • 一般可取一个窗口的误差均值,当验证集上误差均值开始上升时,停止

将训练步数视作超一个超参数,提前终止通过控制拟合训练集的步数来控制模型的有效容量

LeNet 训练 MNIST
案例 1:总共只随机取 1000 个训练样本,缩小训练集的规模,人为制 造过拟合


问题:

  1. 为什么说现在的训练过拟合了?
  2. 为什么没有发生 U 型 test 上升?

训练收敛,训练 loss 没有进一步往下降, 过拟合就不再有进展。否则 loss 继续降,过拟合继续进展,呈现 U 型上升。

batch size

(batch size 和学习率的关系)

Batch 方差与 learning rate 关系

  • Batch size 变大的效果:
    梯度的均值越接近期望,方向更准
    梯度的方差期望越小,估计更稳
    学习率增大会增大梯度估计方差
  • 另一方面,如果 batch size 比较大,可 以用比较大的 lr 而同时可以保持一定 的方差(保持证明见右公式),这样加 快学习。

Large-batch 魔咒

  • Large batch 会有更准的梯度,方差越小,应该有更高的准确性
  • Batch size 不见得越大越好**:large batch 可能会降低准确率!**
  • ICLR 2017: ON LARGE-BATCH TRAINING FOR DEEP LEARNING: GENERALIZATION GAP AND SHARP MINIMA
    (i) LB methods over-fit the model;
    (ii) LB methods are attracted to saddle points;
    (iii) LB methods lack the explorative properties of SB methods and tend to zoom-in on the minimizer closest to the initial point;
    (iv) SB and LB methods converge to qualitatively different minimizers with differing generalization properties.
  • LB 陷入的是比较 sharp 的极值点,SB 陷入的是比较 flat 的极值点, 泛化性能更好

  • 另一种声音:Facebook: Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour
  • LB 之所以不 work,不是泛化能力的问题,而是优化的问题
  • 学习过程要维护好学习率和 batch size 的关系
  • Linear Scaling Learning Rate:简单点:batch size 翻多少倍, learning rate 就翻多少倍
  • LB 方法,开始用大的 learning rate,效果差;只要开始把 LR 设小, 之后逐步提高 LR 到正常大小,LB 能到跟 SB 几乎一样的 training curve、基本相同的准确度

linear scale rule

  • baeline(batch size B) 走 k 步 (3), large batch(batch size kB) 走 1 步 (4) 更新公式比较 (#B = n):

(4):过一步相当于(3):过 k 步
为使更新效果一致,(4)的学习率应该再乘以 k 倍
在 weight 变化较快的时候,W(t+j) W(t) 不满足
故在开始变化很快的时候,一般不是 k 倍,后面逐渐放大
lr 也不能无限放大,batchsize 变大后,合适的 lr 范围在变小

large batch 问题一般在分布式训练中非常 large 的情景一般情况下,batch size 选取有以下建议

  • 小 batch 训练,受噪音影响大,不容易收敛,学习慢;泛化误差较小;
  • 大 batch 训练,梯度估计更准确,训练震荡越小,收敛速度快,但 是容易陷入局部最小(非凸函数优化);容易过拟合,过大的 large batch 准确率会低;
  • 在实践过程中,在 GPU 显存容许的情况下,一般采用较大的 batch size。注意和 learning rate 的配合

解决毛刺大的方法: batch_size 调大,或者学习率调小

正则化

正则化技术概述

  • 机器学习核心问题:如何提高泛化能力?

    • 泛化:一个假设模型应用到新样本上的能力
    • 欠拟合可直接从训练情况中观察到,并设法改进
    • 如何有效防止过拟合行为:模型过度拟合了训练数据的噪音,导致 测试集性能不佳,泛化能力差
  • 正则化:减少测试误差(可能以增加训练误差为代价),提高模型 泛化能力

  • 广义讲,提高算法测试性能的一切手段都可以视为正则化技术

  • 主要目标:减少泛化误差而不是训练误差

  • 正则化技术在深度学习中的必要性:

    • 小规模神经网络模型可以降低对数据量的需求并缓解过拟合,但是性能短板明显
    • 收集数据集尚无法满足复杂模型避免过拟合的要求 - - 关键还是模型能力与问题复杂度、数据量的匹配方式 (regularization)
  • 必须引入正则化以提升泛化能力

  • 正则化主要手段:

    • 数据处理:数据规范化技术/数据集扩充技术
    • 目标牵引:目标函数正则化项
    • 模型技巧:dropout 技术/batch normalization 技术
    • 策略选择与具体任务相关

数据增强技术

主要包括两方面:

  • 数据集扩充:问题是否被数据有效覆盖?

  • 数据集规范化:数据形态是否可被现有模型有效学习?

  • 数据集扩充与模型过拟合:

    • 过拟合本质是模型相对问题复杂,但数据的不充分,会加剧这种不 匹配
    • 完善数据,可以有效约束 (regularization) 过拟合的行为
  1. 几何变换:丰富数据集中目标的变化,更多适应卷积网的特性
    刚性几何变换:目标内部的相对空间关系不变

    旋转变换:当需要分类或被识别的目标可能存在多种不同角度时
    尺度变换:当任务可能面对不同的尺度
    水平/垂直翻转:任务没有更多旋转条件时,翻转更为常见
    平移变换:未限制学习目标在视

    非刚性几何变换:未来检测目标可能展示柔性的变化
    例:薄样板条插值法 Thin Plate Spline(TPS)
    TPS 是一种插值算法,常用于图像变形,以达到数据增广的作用。
    TPS 功能强大,即可涵盖之前的刚性变换,放射变换,也可以产生 更多的柔性变换。

TPS 应用举例:人脸关键点预测
人脸、动物等可有一定柔性空间的关键点相关算法,可用 TPS 增强算法鲁棒性

  1. 截取:从输入裁剪出更多保持尺寸比例样本,或突出学习重点 应对网络输入的限制 (224x224),截取采样保持目标比例

    方法:采样 (保持目标尺寸比例)、遮挡 (突出重点)
    方法:随机截取、监督式截取
    在细分类、关键点标注等任务中,遮挡对于提升局部敏感度有帮助

随机截取:难以控制截取内容
一些样本质量有限,有一定冗余,也存在一定错误样本

监督式截取:训练如何截取

  • 随机初始化训练较为粗糙的类别激活模型
  • 生成的特征图反映了图像内部各区域与标签的相关性
  • 基于特征图截取样本训练高性能分类网络

  1. 加噪和色彩变换:

    • 对颜色进行轻微的变化(如对每个像素点的 RGB 值乘以 0.95-1.05
      间的随机系数)
    • 目标具有多样颜色的情况,但要控制色彩范围
    • 对存在曝光过度或过暗的任务,增加亮度变换
  • 添加噪声可有效提升识别的鲁

    相关工具 DeepAugment 等:pip install deepaugment

数据集规范化

从模型学习的角度,规范数据集数据的分布范围

规范的是数值,常有:零均值化,归一化,去相关 (白化)

减去均值之后,做归一化

零均值化:对数据集内所有样本,减去数据的均值

  • 利用训练集得到图像均值
  • 每个样本均减去图像均值
  • 移除图像共同部分,凸显个体差异
  • 从数据分布来说,使数据的中心点移到了原点

归一化:零均值化的数据除以归一化值 (例如标准差), 使数据分布范围 限制在固定范围,例如 (-1,1) 例如标准差规范化:

  • 利用训练集得到图像的标准差
  • 每个零均值化的样本均除以图像标准差
  • 从数据分布来说,只是限制了分布的范围,并未改变分布形态,

例如不一定归一化后的就服从正太分布!
归一化减少模型偏置学习压力,零均值化使权值学习范围无明显偏向 零均值化和归一化后的数据和模型参数初始化范围已经接近,是比较 好的训练输入

但数据如果不做零均值化和归一化,模型训练将非常困难

去相关 (白化):去除数据相关性、降低冗余

  • 数据中,不同维度之间存在一定的相关性,例如图像中目标局部 的一定相关性
  • 训练时相关数据带来冗余,使得模型对区分特性不敏感
  • 从数据分布来说,去相关改变了数据维度上的分布形态:1. 使数 据的不同维度去相关;2. 使数据每个维度的方差为 1;
  • 常用:PCA 白化,ZCA 白化

维度去相关,并且维度上的方差为1 ,则为白化

PCA 白化: 应用 PCA 主成分分析,将数据在主成分特征向量上进行投 影,并用主成分特征代替原特征

ZCA 白化:PCA 白化后,数据原来的维度转换成了主成分维度,为了使 白化后的数据尽可能接近原数据,可以把处理过的数据再变换回原空 间,也就是 ZCA 白化。

白化效果举例:可见 ZCA 相比 PCA 更接近原数据 (相同的维度定义)

目标函数及正则化

目标函数:模型的学习引导

  1. 想让模型表达什么?分类、特征分布、流形提取、对抗。。
  2. 想让模型的表达有什么特点?稀疏、降低结构风险。。

目标函数的设计直接影响了学习效果

Siamense Net Loss 思路:正样本对的 Ew 要尽量小,负样本对的尽量大 也就是,Loss 要鼓励正样本对的 Ew 减小,鼓励负样本对的 Ew 增大

按此 loss 引导,网络学习的 Ew 最终会根据正负样本对两个阵营,形成 两个峰的分布。分类问题就变为对这两个聚集分布的划分:

Triplets Loss

区别:多类型的时候

  1. 假设不一样:CL 考察距离: 正例要求往一起集中 yd2,TL 考察
    距离的差: 不要求集中,只要正例距离与负例距离差小就可以
  2. CL 限制了类间距 D 的范围,(d 比 a 大的时候反而会反向惩罚), 实际上会将不同类团进行聚集,实际对各个类型的分布有了潜在 的假设,同时拉动整个类型也会增加网络学习难度;
  3. TL 只要求正例与正例的距离小于正例与负例的距离 (考察的是 距离的差) 即可,更灵活适应多类分布。

Hard negative mining

  • Hard negative mining: 难例!
  • 难例:错误分类样本,而且预测的置信度很高
  • 网络训好需要难例,尤其后期,简单样本已难以提升了:(回忆我 们正负例数据不平衡的时候的 Siamese 作业)
  • 简单方案:找到难例,训一波。或者适当时候找难例,训一波
  • CL:可以很快收敛;TL:会有坍塌现象(TL 梯度 han := f(xa) − f(xp),对于难例,很近,往哪个方向推?可能同时推了 f(xa), 原来 训好的也搞坏了)
  • 问题:怎么定义难例?尤其后期训不动的时候找难例?

难例不仅是数据集未充分采集的结果: 样本缺乏、样本不平衡 更多时候,在训练过程中,模型会对大多数样本损失很小

  1. 不平衡的类型效果;
  2. 类中比较困难的样本

此时 gradient 被 easy example 支配,长期不改变
OHEM: online hard example mining
目标函数引导:根据不同样本的 loss 大小,增多 loss 比较大的样本的 学习机会

  • class 比例加权重:最常用处理类别不平衡问题的方式
  • OHEM: 只保留 loss 最高的那些样本,完全忽略掉简单样本 (梯度置为 0)
  • OHEM+ 按 class 比例 sample:在前者基础上,再保证正负样本的比例

Focal Loss:
OHEM 需要根据 loss 选样本,再去对选择的样本进行训练
另一个角度,直接在 loss 上将难例的惩罚增大, 简单例的惩罚减小
在交叉熵上根据样本难度加权,(正样本难例 Pi 小,负样本难例 Pi 大)

参数正则化:
过拟合:模型相对问题复杂
增加数据可以减轻过拟合现象,但并不是解决根本问题
如何在不改变网络结构的情况下降低复杂度?
正则化:在目标函数中增加约束项损失函数:L(θ) → L(θ) + λ ∗ R(w) R(w): 正则化项, 常用 L1 范数:R(w) = ∥w∥21 = Σ|wi| 和 L2 范数: R(w) = ∥w∥2 = Σw2i
参数正则化目标:网络在降低样本损失的同时,偏好较小的权值
实际上牺牲了一些作对的样本,以换取泛化性能
L1 更易产生稀疏解 (解容易发生在轴上);L2 的解较平滑,较 L1 好解

L1、L2 正则化实例:手写数字分类(MNIST 数据集)
网络结构:全连接神经网络(3 隐层,节点数为 1500、1000、500)
目标函数:交叉熵目标函数
正则化方法:无正则化 (1.25%),L1(1.16%),L2(1.11%)
L1、L2 正则化技术的使用可以带来一定的性能改善 L1 正则化得到更加稀疏的权值矩阵


参数正则化技术 tensorflow 实现示例

#例 如, 对 所 有 参 数 进 行 正 则 化 #首先选定所有训练参数tv作为正则化对象
tv = tf.trainable_variables()
Regularization_term = lambda*tf.reduce_sum( [ tf.nn.l2_loss(v)
for v in tv ])
New_loss = original_loss + Regularization_term
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(
New_loss)
#也 可 将 参 数 加 入 指 定 正 则 化 损 失 函 数 集 合, 加 入 的 同 时, 指 定 其 正 则 化 方 式 regularizer
regularizer = tf.contrib.layers.l2_regularizer(0.001) ...
tf.add_to_collection('reg_loss', regularizer(W_fc1)))) ...
#最终loss是原loss和l2正则项列表相加
loss = original_loss + tf.add_n(tf.get_collection('losses'))

weight_decay = tf.constant(0.0005, dtype=tf.float32) # your
weight decay rate, must be a scalar tensor.
W = tf.get_variable(name='weight', shape=[4, 4, 256, 512],
regularizer=tf.contrib.layers.l2_regularizer(weight_decay))

Weight decay 效果举例:

dropout

深度神经网络学习过程中的依赖现象:

学习过程中,如果隐含层节点较多,可能出现相互依赖的现象

  • 隐含节点之间出现固定关系
  • 若测试数据无法激活具有固定关系的隐含节点,则分类性能可能大大降低
  • 实际是一种过拟合的表现
  • 同一类型只有有限种组合的节点激活方式

可以采用模型平均的方式
缺点:需要训练多个模型,效率较低

Dropout:一种随机丢弃模型节点的方法,消除节点相互依赖

  • 不修改损失函数, 直接修改神经网络的结构
  • 训练过程中以概率 p 随机“丢弃”一部分节点:消除依赖
  • 未被丢弃的节点需以 1/p 为权重进行缩放
  • 每个迭代实际上使用了不同的网络结构
  • 测试时使用完整网络 (p=1),事实上起到了多个模型合并的作用, 可看做一种集成学习

测试的时候设成1,为什么要设成1啊?

从集成学习角度理解 Dropout

  • 假设网络中每个节点都有 50% 的概率被丢弃,网络共有 N 个节点,则一共可能有 2N 种不同的网络
  • 当 dropout 不同的神经元时,相当于训练的不同的神经网络
  • 测试时使用所有的网络节点,可以近似视为模型平均 (每个模型训 练时权值乘以 50%,节点规模测试时为训练 2 倍,相当于平均两 个训练时只有一半的节点网络)

Dropout tensorflow 应用示例:训练时:keep_prob 设为 p(0.5,0.3…); 测试 时:keep_prob=1

net = tf.nn.relu(tf.matmul(net, W2) + b2)
net = tf.nn.dropout(net, keep_prob=keep_prob)

Dropout 主要用于全连接网络,一般设为 0.5 或者 0.3
卷积网层中由于卷积自身的稀疏化以及稀疏化的 ReLu 函数的大量使 用,Dropout 使用较少

Batch Norm

moving_mean,moving_variance 为什么需要学习和更新?

BN 对数据进行归一化,需要的是整个样本空间的 mean,var BN 实际上一次迭代只能估计一个 batch 中的 mean 和 var

  • batch 中的 mean 和 var 是局部的,是相对全局的有噪 (还很大) 估计
  • 故用 moving_mean 和 moving_variance 通过多次 batch 的局部统计
    来累积对全局的统计

μ, σ 是否需要在测试时更新?

理想情况下,train_data 和 test_data 数据分布应该一致

也就是,测试时,应该用训练得到的全局 μ, σ
但实际上,测试数据与训练数据分布可能存在一定鸿沟:1. 训练与测 试数据分布由于采样引起的不完全对应;2. 不同的 batch size:这些都 会使训练得到的 μ, σ 成为有偏估计

解决方案:1. 使用当前 batch 统计;2. 使用指数加权平均来逐步得到测 试阶段 μ, σ 估计

TF Batch Norm 接口

TF 主要调用关系:

  • tf.nn.batch_normalization: low-level API, 用户负责管理 mean,variance
  • tf.layers.batch_normalization: high-level 封装. 自动创建、管理 mean,variance. 一般常用
  • tf.contrib.layers.batch_norm: BN 早期实现,contrib 的一般都不推荐 使用,在未来版本中都有可能被放弃
  • slim.batch_norm:slim 实现,实际使用 tf.contrib.layers.batch_norm
  • keras.layers.BatchNormalization: 实际后端调用
    tf.nn.batch_normalization.

TF Batch Norm 使用方式:

TF BN 使用分为训练、测试两个阶段: 测试阶段:

  1. 参数 training=True, 以训练 gamma(γ),beta(β) 两个参数
  2. moving_mean 和 moving_variance 默认只是” 需更新的”(更新操 作集合 tf.GraphKeys.UPDATE_OPS),却不是” 需学习的” 而实际上滑动平均是需要更新学习的,为此,需手动添加更新操 作集合作为 train_op 依赖项,即在 minimize 优化前,要先做 update_ops 操作
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops): train_op = optimizer.minimize(loss)

训练参数保持

moving_mean,moving_variance 因为不是 trainable variable,所以是不在 tf.trainable_variables() 中的,或者将其填入保存变量列表 var_list 后,建 立 saver(var_list) 保存;或用 saver() 保存 global_variable()

TF Batch Norm 使用方式:

TF BN 使用分为训练、测试两个阶段: 测试阶段:

  1. 参数 training=False, 不训练 gamma(γ),beta(β) 两个参数
  2. 如果要用训练得到的全局 moving_mean 和 moving_variance,建 议用指数加权平均来逐步得到测试阶段 μ, σ 估计 也有用以下来恢复保存的指数加权平均影子参数来实现,此时需 要训练阶段将影子参数也同样保存。
ema = tf.train.ExponentialMovingAverage(0.999) vars = ema.variables_to_restore()

保存形式:
{’xxx/varibleExponentialMovingAverage’: <tf.Variable ’xxx/varible:0’ shape=(136,) dtype=float32_ref>,…}
或不用 ema.variables_to_restore() 而将全局 moving_mean 和 moving_variance 赋予新建的影子参数

指数加权平均

tf.train.ExponentialMovingAverage 采用滑动平均的方法更新参数 需衰减速率(decay),用于控制模型的更新速度 维护一个影子变量(也就是更新参数后的参数值),这个影子变量的初 始值就是这个变量的初始值,影子变量值的更新方式如下: shadow_variable = decay * shadow_variable + (1-decay) * variable shadow_variable 是影子变量,variable 表示待更新的变量,也就是变量 被赋予的值,decay 为衰减速率。decay 一般设为接近于 1 的数
(0.99,0.999)
decay 越大模型越稳定,因为 decay 越大,参数更新的速度就越慢,趋 于稳定
tf.train.ExponentialMovingAverage 这个函数还提供了自己动更新 decay 的计算方式:
decay= min(decay,(1+steps)/(10+steps))
steps 是迭代的次数,可以自己设定,可在前期加速迭代

Batch Norm 实现细节剖析

def bacthnorm(inputs, scope, epsilon=1e-05, momentum=0.99, is_training=True): inputs_shape = inputs.get_shape().as_list()
params_shape = inputs_shape[-1:]
axis = list(range(len(inputs_shape) - 1))
with tf.variable_scope(scope):
beta = create_variable("beta", params_shape, initializer=tf.zeros_initializer())
gamma = create_variable("gamma", params_shape, initializer=tf.ones_initializer())
# for inference
moving_mean = create_variable("moving_mean", params_shape, initializer=tf.zeros_initializer(), trainable=False) moving_variance = create_variable("moving_variance", params_shape, initializer=tf.ones_initializer(), trainable=False)
if is_training:
mean, variance = tf.nn.moments(inputs, axes=axis)
update_move_mean = moving_averages.assign_moving_average(moving_mean,
mean, decay=momentum)
update_move_variance = moving_averages.assign_moving_average(moving_variance, variance, decay=momentum)
tf.add_to_collection(UPDATE_OPS_COLLECTION, update_move_mean) tf.add_to_collection(UPDATE_OPS_COLLECTION, update_move_variance)
else:
mean, variance = moving_mean, moving_variance
return tf.nn.batch_normalization(inputs, mean, variance, beta, gamma, epsilon)

应用举例:作业学号三次函数拟合 cos

深度学习 | 训练及优化方法相关推荐

  1. 基于NVIDIA GPUs的深度学习训练新优化

    基于NVIDIA GPUs的深度学习训练新优化 New Optimizations To Accelerate Deep Learning Training on NVIDIA GPUs 不同行业采用 ...

  2. 深度学习笔记:优化方法总结(BGD,SGD,Momentum,AdaGrad,RMSProp,Adam)

    深度学习笔记(一):logistic分类  深度学习笔记(二):简单神经网络,后向传播算法及实现  深度学习笔记(三):激活函数和损失函数  深度学习笔记:优化方法总结  深度学习笔记(四):循环神经 ...

  3. 【显存优化】深度学习显存优化方法

    深度学习gpu的显存至关重要,显存过小的话,模型根本无法跑起来,本文介绍几种显存不足时的优化方法,能够降低深度学习模型的显存要求. 目录 一.梯度累加 二.混合精度 1.权重备份 2.损失缩放 3.精 ...

  4. 深入云原生 AI:基于 Alluxio 数据缓存的大规模深度学习训练性能优化

    作者 | 车漾(阿里云高级技术专家).顾荣(南京大学 副研究员) 导读:Alluxio 项目诞生于 UC Berkeley AMP 实验室,自开源以来经过 7 年的不断开发迭代,支撑大数据处理场景的数 ...

  5. 阿里云原生实践:基于 Alluxio 数据缓存的大规模深度学习训练性能优化

    导读:Alluxio 项目诞生于 UC Berkeley AMP 实验室,自开源以来经过 7年的不断开发迭代,支撑大数据处理场景的数据统一管理和高效缓存功能日趋成熟.然而,随着云原生人工智能(Clou ...

  6. 深度学习中的优化方法总结

    转载自:https://blog.csdn.net/u012151283/article/details/78154917 梯度下降沿着整个训练集的梯度方向下降.可以使用随机梯度下降很大程度地加速,沿 ...

  7. introduction to deep learning--week1简单线性回归、梯度下降、模型正则化、和深度学习中的优化方法

    进阶课程需要一些基础知识: 1.机器学习基础知识 2.概率论知识 3.线性代数和微积分 4.python编程 我们需要知道的机器学习基础知识: 1.线性回归:均方误差(MSE).解析解 2.逻辑回归: ...

  8. 深度学习之optimizer 优化方法

    BGD batch gradient descent,batch梯度下降.在训练中,每一步迭代都使用训练集的所有内容.用全量数据集去计算梯度,迭代参数. 优点:  由于每一步都利用了训练集中的所有数据 ...

  9. 深度学习常见的优化方法(Optimizer)总结:Adam,SGD,Momentum,AdaGard等

    机器学习的常见优化方法在最近的学习中经常遇到,但是还是不够精通.将自己的学习记录下来,以备不时之需 https://www.cnblogs.com/GeekDanny/p/9655597.html

最新文章

  1. conflicts with existing, non-compatible bean definition of same name and class
  2. Devexpress报表开发(二):创建数据报表
  3. NTLDR is missing 的解决方法
  4. 六大场景下,模型分数如何应用?
  5. input标签中使输入文本向右偏移像素解决方案(亲测有效)
  6. 是否有“他们的”版本的“git merge -s ours”?
  7. 王道训练营3月10日
  8. 一款比PowerDesigner好用的uml建模工具chiner
  9. python 手写m3u8多线程下载器
  10. Python批量合并处理B站视频
  11. 原生JavaScript实现五子棋(直接上代码干货点赞收藏拿走)
  12. Apache Pulsar PMC 成员翟佳:开源和 Apache 社区是个带有魔法的宝库
  13. elasticsearch 分片(Shards)的理解
  14. vue设置网页title
  15. 基于单片机的测温风扇控制系统设计(#0420)
  16. Win10 启动模拟器
  17. Android 5.0 CardView 应用
  18. java 编译期常量
  19. 一步步学习微软InfoPath2010和SP2010--第一章节--介绍InfoPath2010(2)--InfoPath2010的新功能
  20. Java Web快速开发框架 ---- JSPX

热门文章

  1. 基于人脸识别的考勤记录项目
  2. 毕业了,等待我们的是什么?
  3. 品诺——浪漫的意大利之夜
  4. ESP32配置mqtt arduino
  5. java注解和反射详解
  6. linux连接wifi的方法
  7. java吸血鬼数字_吸血鬼数字的简单实现
  8. 云计算和大数据时代网络技术揭秘(十三)VXLAN
  9. Hibernate第五篇【inverse、cascade属性详解】
  10. ctypes调用海康威视人脸抓拍机并将抓拍的人脸上传到指定地址