文章目录

  • 1 优化方法
    • 梯度下降
      • SGD
      • SGD+Momentum (动量项)
      • SGD+Nesterov (前瞻动量)
      • AdaGrad (梯度平方累计)
      • AdaDelta (梯度平方平均值+自适应学习率)
      • RMSprop (梯度平方平均值)
      • Adam (梯度平方平均值 + 动量项)
      • Adamax (学习率设上界 + Adam)
      • Nadam (NAG + Adam)
      • 合适的优化方法
      • Adam (Adaptive Moment Estimation)
        • Adam 中使用的指数加权滑动平均法
          • 偏差修正
        • Adam的原理机制
        • Adam参数和默认参数
    • 二阶梯度方法
      • 牛顿法
      • 拟牛顿法
    • 共轭梯度法
      • 问题模型
      • 解法
      • 推导(优化方向和步长确定)
      • 三个推论
      • 使用推论简化计算
      • 伪代码
  • 2 网络参数初始化
    • 相关概率公式
    • Xavier 初始化 2010
      • 假设
      • 推导
    • He Kaiming 初始化 2016 (MSRA)
    • 网络参数不可以初始化为0
  • 3 损失函数
    • KL散度(相对熵)和交叉熵
    • Smooth L1
    • Focal Loss
      • 消除类别不平衡 & 挖掘难分类样本
      • 改进思路
    • DR loss
      • 优化问题
      • 补充 回归项的改进
      • DR loss 的 检测器优化目标函数
    • 平方误差和交叉熵误差损失
      • 误差项
      • 使用场景
    • 交叉熵为什么用softmax归一化
    • 训练的模型实际效果不错, 但是平方根误差一直很高
    • IoU系列
      • GIoU 2019
      • DIoU 2019
      • CIoU 2020
  • 4 激活函数
    • 清单
    • 为什么使用激活函数
      • 激活函数性质
    • 为什么Sigmoid和Tanh导致梯度消失
    • ReLU 系列相对于 Sigmoid 和 Tanh 的优势
    • ReLU 有哪些局限性, 如何改进
    • 各激活函数的优缺点和适用场景
    • Sigmoid 和 Softmax
    • Relu死亡问题
    • 如何解决 ReLU 神经元死亡问题
    • ReLU6
    • 激活函数的使用原则
    • 新的激活函数 Swich / Mish
      • Swich
      • Mish:
  • 5 正则化
    • L1和L2优缺点:
    • L1和L2区别:
    • L1正则化的原理是
    • 为什么权值矩阵稀疏可以防止过拟合
    • 为何权重参数 w 减小就可以防止过拟合
    • 为什么稀疏化不选用L0,而选择L1
    • 为什么说 L2 范式可以优化计算?
    • 正则项如何确定
  • 6 归一化
    • Batch Normalization
      • BN层常放的位置
      • BN解决的问题
      • BN的好处
      • BN中batch大小
      • BN层中使用的均值和方差如何计算
      • BN层和多卡
      • BN在Inference阶段加速
      • BN层前面的卷积网络不需要偏置
    • Group Normalization
      • GN 为什么效果好
      • BN, LN, IN, GN 的区别
    • 归一化方法中的线性偏移个数
    • Instance Normalization
    • Layer Normalization
    • Switchable Normalization
  • 7 感受野
    • 感受野计算公式
    • 理论感受野和有效感受野的区别
    • 不同因素对有效感受野的影响
    • 目标检测的Anchor和感受野大小之间的关系
  • 8 全连接层
    • 作用
    • 全连接转换为卷积层及好处
      • 全连接层转换为卷积层
      • 好处
    • 两层全连接层的BP公式
    • 全连接层失宠
  • 9 卷积层
    • 卷积层输出尺寸计算公式
    • 1x1卷积层作用
    • 卷积操作的特性
    • 卷积核大小如何确定
    • 卷积层的优化
      • Im2col 算法
      • 空间组合优化
      • 其他卷积计算加速方法
        • 矩阵乘法的加速
  • 10 池化层
    • 什么是池化
    • 池化层尺寸
    • 池化层的作用
    • 池化层的BP过程
    • 最大池化和平均池化的异同和适用场景
    • 全局平均池话(GAP)
    • Ps RoI Pooling
    • PrROI Pooling
    • SPP 2014
    • ASPP
  • 11 反卷积层
    • 矩阵乘法描述反卷积
    • 反卷积和双线性插值(上采样)
    • 反卷积尺寸计算公式
  • 12 空洞卷积
  • 13 训练问题
    • 图像分类问题,数据量不足的问题核缓解
      • 处理方法
    • 分类问题中的数据不均衡
    • 训练不收敛
    • Nan值原因
    • 过拟合是什么
    • 欠拟合
    • Dropout
      • 实现方法
  • 附录
    • 反向传播推导
      • 平方误差损失函数
        • 伪代码

1 优化方法

梯度下降 SGD, Momentum, Nesterov, Adagrad, Adadelta, RMSprop, Adam, Adamax
牛顿法
拟牛顿法
共轭梯度法

梯度下降

θt=θt−1+Δθt\theta_{t}=\theta_{t-1}+\Delta \theta_{t}θt​=θt−1​+Δθt​

SGD

  • 小批量随机梯度下降
    gt=∇θt−f(θt−1)Δθt=−η×gt\begin{array}{c} g_{t}=\nabla_{\theta_{t-}} f\left(\theta_{t-1}\right) \\ \Delta \theta_{t}=-\eta \times g_{t} \end{array}gt​=∇θt−​​f(θt−1​)Δθt​=−η×gt​​
  • 每一次都计算mini-batch的梯度, 然后对参数进行更新. 公式中η\etaη的是学习率, gtg_{t}gt​是当前 batch 的梯度
  • 优点 在合理的学习率和相应的衰减策略下, 通常能够优化到一个不错的点, 配合下面的 Momentum, 通常可以获得比自适应方法更优的点
  • 缺点 (1) 因为要兼顾整个神经网络中所有参数的训练效果, 因此学习率敏感. (2) SGD 容易收敛到局部最优, 并且在某些情况下容易被困在鞍点( 这句话是不对的, 只有在特定的 inital point 时才会被困在鞍点, 通常情况下, 我们使用 random inital point, 被困在鞍点的概率非常小, 当使用合适的初始化和步长时, 几乎不会出现鞍点问题 ); (3) 参数的更新仅仅依赖于当前 batch 中的数据, 当数据分布波动较大时, 更新不稳定.

SGD+Momentum (动量项)

gt=∇θt−f(θt−1)mt=μ×mt−1+gtΔθt=−η×mt\begin{array}{c} g_{t}=\nabla_{\theta_{t-}} f\left(\theta_{t-1}\right) \\ m_{t}=\mu \times m_{t-1}+g_{t} \\ \Delta \theta_{t}=-\eta \times m_{t} \end{array}gt​=∇θt−​​f(θt−1​)mt​=μ×mt−1​+gt​Δθt​=−η×mt​​

  • μ\muμ 为动量因子,通常取值0.9或0.99
  • 通过动量的积累来在相关方向上加速 SGD 优化速度, 抑制震荡, 同时有助于跳出局部最优, 进而加快收敛.
  • 优点 (1) 下降初期, 动量因子可以加速网络的训练速度; (2) 当遇到鞍点时, 梯度虽然为零, 但是动量不为零, 可以跳出鞍点(局部最优) ; (3) 在梯度改变方向时, 能够降低更新幅度, 减小震荡, 加速网络收敛;
  • 总之, momentum 项能够在相关方向加速 SGD, 抑制震荡, 从而加快收敛。
  • 缺点 需要人工设置学习率

SGD+Nesterov (前瞻动量)

  • Nesterov Accelerated Gradient
    gt=∇θt−f(θt−1−η×μ×mt−1)mt=μ×mt−1+gtΔθt=−η×mt\begin{array}{c} g_{t}=\nabla_{\theta_{t-}} f\left(\theta_{t-1}-\eta \times \mu \times m_{t-1}\right) \\ m_{t}=\mu \times m_{t-1}+g_{t} \\ \Delta \theta_{t}=-\eta \times m_{t} \end{array}gt​=∇θt−​​f(θt−1​−η×μ×mt−1​)mt​=μ×mt−1​+gt​Δθt​=−η×mt​​
  • Nesterov 与 Momentum 公式的区别在于, 前者不是在当前的位置上求梯度, 而是根据本来计划要走的那一步提前前进一步以后, 再在新的位置上求梯度, 然后对这个新求得的梯度进行 Momentum 梯度下降计算
  • 优点 (1) 先站在下一步的位置看看, 再进行更新, 使得梯度更新方向更具前瞻性; (2) 实际使用中, NAG 会比 Momentum 收敛的速度更快
  • 缺点 需要人工设置学习率

AdaGrad (梯度平方累计)

nt=nt−1+gt2Δθt=−ηnt+ε×gt\begin{array}{c} n_{t}=n_{t-1}+g_{t}^{2} \\ \Delta \theta_{t}=-\frac{\eta}{\sqrt{n_{t}+\varepsilon}} \times g_{t} \end{array}nt​=nt−1​+gt2​Δθt​=−nt​+ε​η​×gt​​

  • 学习率前面乘了一个约束项1nt+ϵ,\frac{1}{\sqrt{n_{t}+\epsilon}},nt​+ϵ​1​,
  • 该约束项会随着算法的不断选代而增大, 那么对应学习率就会越来越小, Adagrad 算法在开始时是大步前进的, 而在后面则会减小步伐, 缓慢收敛
  • 优点:(1) 更新期间学习率随着训练过程变化 (2) 适合面对稀疏梯度 (3) 对于每一个不同的参数, 其具有不同的学习率, 由梯度动态调节
  • 缺点 (1) 依赖人工全局学习率; (2) 中后期, 分母上的梯度累加和会越来越大, 使得更新停滞, 训练提前结束

AdaDelta (梯度平方平均值+自适应学习率)

Egt2=ρ×Egt−12+(1−ρ)×gt2Δθt=−ηEgt2+ϵgt=−ηRMS∣g∣tgt=−RMS∣Δθ∣t−1RMS∣g∣tgtRMS[Δθ]t=E[Δθ2]t+ϵE[Δθ2]t=γE[Δθ2]t−1+(1−γ)Δθt2\begin{array}{c} E g_{t}^{2}=\rho \times E g_{t-1}^{2}+(1-\rho) \times g_{t}^{2} \\ \Delta \theta_{t}=-\frac{\eta}{\sqrt{E g_{t}^{2}+\epsilon}} g_{t} \\ =-\frac{\eta}{R M S|g|_{t}} g_{t} \\ =-\frac{R M S|\Delta \theta|_{t-1}}{R M S|g|_{t}} g_{t} \\ R M S[\Delta \theta]_{t}=\sqrt{E\left[\Delta \theta^{2}\right]_{t}+\epsilon} \\ E\left[\Delta \theta^{2}\right]_{t}=\gamma E\left[\Delta \theta^{2}\right]_{t-1}+(1-\gamma) \Delta \theta_{t}^{2} \end{array}Egt2​=ρ×Egt−12​+(1−ρ)×gt2​Δθt​=−Egt2​+ϵ​η​gt​=−RMS∣g∣t​η​gt​=−RMS∣g∣t​RMS∣Δθ∣t−1​​gt​RMS[Δθ]t​=E[Δθ2]t​+ϵ​E[Δθ2]t​=γE[Δθ2]t−1​+(1−γ)Δθt2​​

  • ρ 类似于冲量项, 其值在 0.9 附近. Adadelta是对Adagrad的扩展, 和 Adagrad 相比, 其改进是将分母约束项换成了 过去的梯度平方的衰减平均值, 相当于梯度的均方根 (Root Mean Squared, RMS), 此外, 如果将学习率也换成RMS[Δθ]tR M S[\Delta \theta]_{t}RMS[Δθ]t​的话, 甚至可以不用设置学习率了
  • 优点 (1) 对 Adagrad 的扩展, 约束项只计算梯度平方一段时间内的平均值, 而不是累计值, 不容易产生太大值而使得更新提早结束; (2) 无需人工设置学习率, 可以动态改变学习率的大小;
  • 缺点 (1) 训练后期会反复在局部最小值附近抖动, 无法收敛到最优点, 这时候用 SGD+Momentum, 通常会有 2%~5% 的验证集正确率提升.

RMSprop (梯度平方平均值)

Egt2=ρ×Egt−12+(1−ρ)×gt2Δθt=−ηEg2+ϵgt\begin{array}{c} E g_{t}^{2}=\rho \times E g_{t-1}^{2}+(1-\rho) \times g_{t}^{2} \\ \Delta \theta_{t}=-\frac{\eta}{\sqrt{E g^{2}+\epsilon}} g_{t} \end{array}Egt2​=ρ×Egt−12​+(1−ρ)×gt2​Δθt​=−Eg2+ϵ​η​gt​​

  • AdaDelta的特例,
  • 优点 (1) Adadelta 的特例, 也是对学习率添加约束, 适合处理非平稳目标, 对 RNN 效果较好
  • 缺点 RMSprop可以算作是Adadelta的一个特例, 可以看出 RMSprop 仍然需要设置全局学习率

Adam (梯度平方平均值 + 动量项)

mt=β1×mt−1+(1−β1)×gtnt=β2×nt−1+(1−β2)×gt2m^t=mt1−β1tn^t=nt1−β2tΔθt=−m^tn^t+ϵ×ηm_{t}=\beta_{1} \times m_{t-1}+\left(1-\beta_{1}\right) \times g_{t} \\ n_{t}=\beta_{2} \times n_{t-1}+\left(1-\beta_{2}\right) \times g_{t}^{2} \\ \hat{m}_{t}=\frac{m_{t}}{1-\beta_{1}^{t}} \\ \hat{n}_{t}=\frac{n_{t}}{1-\beta_{2}^{t}} \\ \Delta \theta_{t}=-\frac{\hat{m} t}{\sqrt{\hat{n}_{t}+\epsilon}} \times \eta mt​=β1​×mt−1​+(1−β1​)×gt​nt​=β2​×nt−1​+(1−β2​)×gt2​m^t​=1−β1t​mt​​n^t​=1−β2t​nt​​Δθt​=−n^t​+ϵ​m^t​×η

  • 利用修正后的梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率. mt,ntm_{t}, n_{t}mt​,nt​ 分别是对梯度的一阶矩估计和二阶矩估计, 可以看做是对期望Egt,Egt2E g_{t}, E g_{t}^{2}Egt​,Egt2​ 的估计, m^t,n^t\hat{m}_{t}, \hat{n}_{t}m^t​,n^t​ 是对mt,ntm_{t}, n_{t}mt​,nt​ 的校正, 这样可以近似为对期望的无偏估计.
  • 优点 (1) 经过偏置校正后, 每一次迭代学习率都有一个确定的范围, 使得参数更新比较平稳; (2) 结合了动量 RMSprop 的优点; 既可以加速收敛, 又可以根据梯度的大小动态调节每个参数的学习步长 (3) 对内存需求 (偏置估计, 不用存储前几次梯度) 较小; (4) 适用于大多非凸优化, 适用于大数据集和高维空间; (5) 超参数可以比较直观的解释, 同时只需要极少量的调参
  • 缺点 最终的收敛点通常比经过精心调参后的 SGD+Momentum 的收敛点差一些. 常取参数值:(β1=0.9,β2=0.999,ϵ=10−8\beta_{1}=0.9, \beta_{2}=0.999, \epsilon=10^{-8}β1​=0.9,β2​=0.999,ϵ=10−8)

Adamax (学习率设上界 + Adam)

nt=max⁡(ν×nt−1,abs(gt))Δx=−m^tnt+ϵ×ηn_{t}=\max \left(\nu \times n_{t-1}, a b s\left(g_{t}\right)\right) \\ \Delta x=-\frac{\hat{m}_{t}}{n_{t}+\epsilon} \times \eta nt​=max(ν×nt−1​,abs(gt​))Δx=−nt​+ϵm^t​​×η

  • Adamax 是 Adam 的一种变体, 此方法对学习率的上限提供了一个更简单的范围, 可以看出, 学习率的边界范围更加简单

Nadam (NAG + Adam)

g^t=gt1−Πi=1tμimt=μt∗mt−1+(1−μt)∗gtm^t=mt1−∏i=1t+1μint=ν∗nt−1+(1−ν)∗gt2n^t=nt1−νtmˉt=(1−μt)∗g^t+μt+1∗m^tΔθt=−η∗mˉtn^t+ϵ\hat{g}_{t}=\frac{g_{t}}{1-\Pi_{i=1}^{t} \mu_{i}} \\ m_{t}=\mu_{t} * m_{t-1}+\left(1-\mu_{t}\right) * g_{t} \\ \hat{m}_{t}=\frac{m_{t}}{1-\prod_{i=1}^{t+1} \mu_{i}} \\ n_{t}=\nu * n_{t-1}+(1-\nu) * g_{t}^{2} \\ \hat{n}_{t}=\frac{n_{t}}{1-\nu^{t}} \\ \bar{m}_{t}=\left(1-\mu_{t}\right) * \hat{g}_{t}+\mu_{t+1} * \hat{m}_{t} \\ \Delta \theta_{t}=-\eta * \frac{\bar{m}_{t}}{\sqrt{\hat{n}_{t}}+\epsilon} g^​t​=1−Πi=1t​μi​gt​​mt​=μt​∗mt−1​+(1−μt​)∗gt​m^t​=1−∏i=1t+1​μi​mt​​nt​=ν∗nt−1​+(1−ν)∗gt2​n^t​=1−νtnt​​mˉt​=(1−μt​)∗g^​t​+μt+1​∗m^t​Δθt​=−η∗n^t​​+ϵmˉt​​

合适的优化方法

  • Adam, RMSprop 等算法, 使用的都是一阶原点矩和二阶原点矩. 并且是利用滑动平均法来对一阶矩和二阶矩进行估计.
  • SGD+Momentum 相比于自适应优化器通常训练时间长, 但在好的学习率和衰减方案的情况下结果更优
  • AdaGrad, RMSprop, Adam 等适合希望得到快速结果的情况下使用
    • 在使用 RMSprop 和 Adam 的地方, 大多可以使用 Nadam 取得更好的效果.
  • 在训练较深层的网络时, 也推荐先使用 Adam 方法进行正确性验证, 然后再使用SGD+Momentum 微调.
  • 在实际训练中比较好的方法是: 先用 Adam 预训练一段时间, 然后使用 SGD+Momentum, 以达到最佳性能. Adam vs SGD 的表现通常如下图所示, 由于鲁棒性和自适应的学习速率, Adam 在一开始表现更好, 而 SGD 最终更容易达到全局最优.

Adam (Adaptive Moment Estimation)

Adam 中使用的指数加权滑动平均法

  • 在数学中一般会以 1/e 来作为一个临界值, 小于该值的加权系数对应的值不作考虑. 因此, 当 β=0.9 时, 0.9^10 约等于 1e, 认为此时是约 10 个数值的加权平均.
  • 偏差修正:由于初始化的值太小, 导致初期的滑动平均值偏小, 随着时间的增长, 初期的值影响减小, 滑动平均值才逐渐正常. 为了让初期的滑动平均值也相对正常,所以除以一个数进行修正!
偏差修正
  • 令其在梯度变得稀疏时要比 RMSprop 算法更快速和优秀。
    n0=0nt=β2×nt−1+(1−β2)×gt2=(1−β2)∑i=1tβ2t−i×gi2E[nt]=E[(1−β2)∑i=1tβ2t−i×gi2]=E[gt2]×(1−β2)∑i=1tβ2t−i+C=E[gt2]×(1−β2t)+C′n_0 = 0 \\ n_{t}=\beta_{2} \times n_{t-1}+\left(1-\beta_{2}\right) \times g_{t}^{2}=\left(1-\beta_{2}\right) \sum_{i=1}^{t} \beta_{2}^{t-i} \times g_{i}^{2} \\ E\left[n_{t}\right]=E\left[\left(1-\beta_{2}\right) \sum_{i=1}^{t} \beta_{2}^{t-i} \times g_{i}^{2}\right]=E\left[g_{t}^{2}\right] \times\left(1-\beta_{2}\right) \sum_{i=1}^{t} \beta_{2}^{t-i}+C= E\left[g_{t}^{2}\right] \times\left(1-\beta_{2}^{t}\right)+C^{\prime} n0​=0nt​=β2​×nt−1​+(1−β2​)×gt2​=(1−β2​)i=1∑t​β2t−i​×gi2​E[nt​]=E[(1−β2​)i=1∑t​β2t−i​×gi2​]=E[gt2​]×(1−β2​)i=1∑t​β2t−i​+C=E[gt2​]×(1−β2t​)+C′

Adam的原理机制

  • Adam 算法和传统的随机梯度下降不同。随机梯度下降保持单一的学习率更新所有的权重,学习率在训练过程中并不会改变。而 Adam 通过计算梯度的一阶矩估计和二阶矩估计而为不同的参数设计独立的自适应性学习率。
  • 本质上,Adam是AdaGrad和RMSprop的集合:适应性梯度算法(AdaGrad)为每一个参数保留一个学习率以提升在稀疏梯度(即自然语言和计算机视觉问题)上的性能;均方根传播(RMSprop)基于权重梯度最近量级的均值为每一个参数适应性地保留学习率。这意味着算法在非稳态和在线问题上有很有优秀的性能。

Adam参数和默认参数

  • α\alphaα:同样也称为学习率或步长因子,它控制了权重的更新比率(如 0.001)。较大的值(如 0.3)在学习率更新前会有更快的初始学习,而较小的值(如 1.0E-5)会令训练收敛到更好的性能。
  • β1\beta_1β1​:一阶矩估计的指数衰减率(如 0.9)。
  • β2\beta_2β2​:二阶矩估计的指数衰减率(如 0.999)。该超参数在稀疏梯度(如在 NLP 或计算机视觉任务中)中应该设置为接近 1 的数。
  • ϵ\epsilonϵ:该参数是非常小的数,其为了防止在实现中除以零(如 10E-8)

二阶梯度方法

  • DL中一般只使用一阶梯度方法!

牛顿法

f(x)=f(x(k))+∇f(x(k))T(x−x(k))+12(x−x(k))TH(x(k))(x−x(k))()∇f(x)=∇f(x(k))+H(x(k))(x−x(k))因为:∇f(x(k+1))=0则:∇f(xk))+H(x(k))(x(k+1)−x(k))=0x(k+1)=x(k)−H(x(k))−1∇f(x(k))即:x(k+1)=x(k)−Hk−1gkf(x)=f\left(x^{(k)}\right)+\nabla f\left(x^{(k)}\right)^{T}\left(x-x^{(k)}\right)+\frac{1}{2}\left(x-x^{(k)}\right)^{T} H\left(x^{(k)}\right)\left(x-x^{(k)}\right)(\text) \\ \nabla f(x)=\nabla f\left(x^{(k)}\right)+H\left(x^{(k)}\right)\left(x-x^{(k)}\right) \\ 因为: \nabla f\left(x^{(k+1)}\right)=0 \\ 则: \nabla f\left(x^{k)}\right)+H\left(x^{(k)}\right)\left(x^{(k+1)}-x^{(k)}\right)=0 \\ x^{(k+1)}=x^{(k)}-H\left(x^{(k)}\right)^{-1} \nabla f\left(x^{(k)}\right) \\ 即:x^{(k+1)}=x^{(k)}-H_{k}^{-1} g_{k} f(x)=f(x(k))+∇f(x(k))T(x−x(k))+21​(x−x(k))TH(x(k))(x−x(k))()∇f(x)=∇f(x(k))+H(x(k))(x−x(k))因为:∇f(x(k+1))=0则:∇f(xk))+H(x(k))(x(k+1)−x(k))=0x(k+1)=x(k)−H(x(k))−1∇f(x(k))即:x(k+1)=x(k)−Hk−1​gk​

拟牛顿法

  • 牛顿法中海赛矩阵的逆矩阵计算复杂度高
  • 拟牛顿的基本思路:考虑用一个正定矩阵替代海赛矩阵
    gk+1−gk=H(x(k))(x(k+1)−x(k))g_{k+1}-g_{k}=H\left(x^{(k)}\right)\left(x^{(k+1)}-x^{(k)}\right) gk+1​−gk​=H(x(k))(x(k+1)−x(k))
  • 得到拟牛顿条件:yk=Hkδky_{k}=H_{k} \delta_{k}yk​=Hk​δk​
  • 如果 HkH_{k}Hk​ 是正定的 Hk−1H_{k}^{-1}Hk−1​ 也是正定的, 那么可以保证牛顿法搜索方向 pkp_{k}pk​是下降方向。这是因为搜索方向是pk=−Hk−1gkp_{k}=-H_{k}^{-1} g_{k}pk​=−Hk−1​gk​
  • 如何找到和更新这个矩阵有DFP算法、BFGS算法和Broyden类算法 TODO … …
  • 高斯牛顿法 TODO … …

共轭梯度法

  • 共轭梯度法是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点
  • 共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。
  • 在各种优化算法中,共轭梯度法是非常重要的一种。其优点是所需存储量小,具有步收敛性,稳定性高,而且不需要任何外来参数。

问题模型

min⁡xf(x)=12xTAx−bTx\min _{x} f(x)=\frac{1}{2} x^{T} A x-b^{T} xxmin​f(x)=21​xTAx−bTx

  • A为半正定矩阵,x为优化变量,A和b为已知,负梯度如下:
    rk=−(Axk−b)r_{k}=-\left(A x_{k}-b\right)rk​=−(Axk​−b)
  • 其实 就是求 方程 4x∗=b4 x^{*}=b4x∗=b 的解(通过迭代避免了求逆的难度),定义每次迭代和最优解的误差如下:ek=x∗−xke_{k}=x^{*}-x_{k}ek​=x∗−xk​

解法

  • 虽然梯度下降法的每一步都是朝着局部最优的方向前进的,但是它在不同的迭代轮数中会选择非常近似的方向,说明这个方向的误差并没通过一次更新方向和步长更新完,在这个方向上还存在误差,因此参数更新的轨迹是锯齿状。共轭梯度法的思想是,选择一个优化方向后,本次选择的步长能够将这个方向的误差更新完,在以后的优化更新过程中不再需要朝这个方向更新了。由于每次将一个方向优化到了极小,后面的优化过程将不再影响之前优化方向上的极小值,所以理论上对N维问题求极小只用对N个方向都求出极小就行了。为了不影响之前优化方向上的更新量,需要每次优化方向共轭正交。假定每一步的优化方向用pkp_kpk​表示,可得共轭正交:
    piApj=0i≠jp_{i} A p_{j}=0 \quad i ≠ jpi​Apj​=0i​=j
  • 则据上式,误差和优化方向:
    pkAek+1=0p_{k} A e_{k+1}=0pk​Aek+1​=0
  • 若为N维空间优化问题, 则每次优化方向可以组成这个空间中的一组基底P={p1,p2,…,pN}P = \left\{p_{1}, p_{2}, \ldots, p_{N}\right\}P={p1​,p2​,…,pN​}

推导(优化方向和步长确定)

  • 第一次优化方向为初始负梯度方向:
    p1=r1=b−Ax1p_{1}=r_{1}=b-A x_{1}p1​=r1​=b−Ax1​
  • 使用施密特正交化,得到第k次优化方向为(对rkr_krk​进行正交化):
  • pk=rk−∑i<kpiTArkpiTApipip_{k}=r_{k}-\sum_{i<k} \frac{p_{i}^{T} A r_{k}}{p_{i}^{T} A p_{i}} p_{i}pk​=rk​−i<k∑​piT​Api​piT​Ark​​pi​
  • βi=piTArkpiTApi\beta_{i}=\frac{p_{i}^{T} A r_{k}}{p_{i}^{T} A p_{i}}βi​=piT​Api​piT​Ark​​
  • 优化步长计算如下:
  • pkTAek+1=pkTA(x∗−xk+1)=pkTA(x∗−xk+xk−xk+1)=pkTA(ek−αkpk)=pkTAek−αkpkTApk=0\begin{aligned} p_{k}^{T} A e_{k+1} &=p_{k}^{T} A\left(x^{*}-x_{k+1}\right) \\ &=p_{k}^{T} A\left(x^{*}-x_{k}+x_{k}-x_{k+1}\right) \\ &=p_{k}^{T} A\left(e_{k}-\alpha_{k} p_{k}\right) \\ &=p_{k}^{T} A e_{k}-\alpha_{k} p_{k}^{T} A p_{k}=0 \end{aligned}pkT​Aek+1​​=pkT​A(x∗−xk+1​)=pkT​A(x∗−xk​+xk​−xk+1​)=pkT​A(ek​−αk​pk​)=pkT​Aek​−αk​pkT​Apk​=0​
  • αk=pkTAekpkTApk=pkTA(x∗−xk)pkTApk=pkT(Ax∗−Axk)pkTApk=pkT(b−Axk)pkTApk=pkTrkpkTApk\begin{aligned} \alpha_{k} &=\frac{p_{k}^{T} A e_{k}}{p_{k}^{T} A p_{k}} \\ &=\frac{p_{k}^{T} A\left(x^{*}-x_{k}\right)}{p_{k}^{T} A p_{k}} \\ &=\frac{p_{k}^{T}\left(A x^{*}-A x_{k}\right)}{p_{k}^{T} A p_{k}} \\ &=\frac{p_{k}^{T}\left(b-A x_{k}\right)}{p_{k}^{T} A p_{k}} \\ &=\frac{p_{k}^{T} r_{k}}{p_{k}^{T} A p_{k}} \end{aligned}αk​​=pkT​Apk​pkT​Aek​​=pkT​Apk​pkT​A(x∗−xk​)​=pkT​Apk​pkT​(Ax∗−Axk​)​=pkT​Apk​pkT​(b−Axk​)​=pkT​Apk​pkT​rk​​​

三个推论

  • 第k步计算的梯度 rkr_{k}rk​ 和前k-1步的优化向量 {pi}i=1k−1\left\{p_{i}\right\}_{i=1}^{k-1}{pi​}i=1k−1​ 正交。

    • 证明: 当 i<ji<ji<j
      piTrj=piT(Axj−b)=piT(Axj−Ax∗)=piTAej=piTA(ei+1−∑k=1j−1βkpk)=0\begin{aligned} p_{i}^{T} r_{j} &=p_{i}^{T}\left(A x_{j}-b\right) \\ &=p_{i}^{T}\left(A x_{j}-A x^{*}\right) \\ &=p_{i}^{T} A e_{j} \\ &=p_{i}^{T} A\left(e_{i+1}-\sum_{k=1}^{j-1} \beta_{k} p_{k}\right) \\ &=0 \end{aligned} piT​rj​​=piT​(Axj​−b)=piT​(Axj​−Ax∗)=piT​Aej​=piT​A(ei+1​−k=1∑j−1​βk​pk​)=0​
  • 第k步计算的梯度 rkr_{k}rk​ 和前k-1步的梯度 {ri}i=1k−1\left\{r_{i}\right\}_{i=1}^{k-1}{ri​}i=1k−1​ 正交。
    • 证明: 当 i<ji<ji<j
      riTrj=(pi+∑k=1i−1βkpk)rj=0r_{i}^{T} r_{j}=\left(p_{i}+\sum_{k=1}^{i-1} \beta_{k} p_{k}\right) r_{j}=0 riT​rj​=(pi​+k=1∑i−1​βk​pk​)rj​=0
  • 第K步计算的梯度 rkr_{k}rk​ 和前k-2步的优化向量 {pi}i=1k−2\left\{p_{i}\right\}_{i=1}^{k-2}{pi​}i=1k−2​ 共轭正交。
    • 证明:
      rj+1Tri=(b−Axj+1)Tri=(b−A(xj+αjpj))Tri=(b−Axj−αjApj)Tri=(rj−αjApj)Tri=rjTri−αjpjTAri\begin{aligned} r_{j+1}^{T} r_{i} &=\left(b-A x_{j+1}\right)^{T} r_{i} \\ &=\left(b-A\left(x_{j}+\alpha_{j} p_{j}\right)\right)^{T} r_{i} \\ &=\left(b-A x_{j}-\alpha_{j} A p_{j}\right)^{T} r_{i} \\ &=\left(r_{j}-\alpha_{j} A p_{j}\right)^{T} r_{i} \\ &=r_{j}^{T} r_{i}-\alpha_{j} p_{j}^{T} A r_{i} \end{aligned} rj+1T​ri​​=(b−Axj+1​)Tri​=(b−A(xj​+αj​pj​))Tri​=(b−Axj​−αj​Apj​)Tri​=(rj​−αj​Apj​)Tri​=rjT​ri​−αj​pjT​Ari​​
    • 当 j+1=ij+1=ij+1=i 时, pjTAri≠0p_{j}^{T} A r_{i}≠0pjT​Ari​​=0
    • 当 j+1<ij+1<ij+1<i 时, pjTAri=0p_{j}^{T} A r_{i}=0pjT​Ari​=0

使用推论简化计算

  • 使用上述公式,每次迭代都要计算β\betaβ,现简化如下:
  • 优化方向:(推论三)
    pk+1=rk+1−pkTArk+1pkTAkkpk=rk+1−(Apk)Trk+1(Apk)Tpkpk=rk+1−(rk−rk+1α)Trk+1(rk−rk+1α)Tpkpk=rk+1−(rk−rk+1α)Trk+1(rk−rk+1α)T(rk−βk−1pk−1)pk=rt+1+rk+1Trk+1rkTrkpk\begin{aligned} p_{k+1} &=r_{k+1}-\frac{p_{k}^{T} A r_{k+1}}{p_{k}^{T} A k_{k}} p_{k} \\ &=r_{k+1}-\frac{\left(A p_{k}\right)^{T} r_{k+1}}{\left(A p_{k}\right)^{T} p_{k}} p_{k} \\ &=r_{k+1}-\frac{\left(\frac{r_{k}-r_{k+1}}{\alpha}\right)^{T} r_{k+1}}{\left(\frac{r_{k}-r_{k+1}}{\alpha}\right)^{T} p_{k}} p_{k} \\ &=r_{k+1}-\frac{\left(\frac{r_{k}-r_{k+1}}{\alpha}\right)^{T} r_{k+1}}{\left(\frac{r_{k}-r_{k+1}}{\alpha}\right)^{T}\left(r_{k}-\beta_{k-1} p_{k-1}\right)} p_{k} \\ &=r_{t+1}+\frac{r_{k+1}^{T} r_{k+1}}{r_{k}^{T} r_{k}} p_{k} \end{aligned}pk+1​​=rk+1​−pkT​Akk​pkT​Ark+1​​pk​=rk+1​−(Apk​)Tpk​(Apk​)Trk+1​​pk​=rk+1​−(αrk​−rk+1​​)Tpk​(αrk​−rk+1​​)Trk+1​​pk​=rk+1​−(αrk​−rk+1​​)T(rk​−βk−1​pk−1​)(αrk​−rk+1​​)Trk+1​​pk​=rt+1​+rkT​rk​rk+1T​rk+1​​pk​​
  • 优化步长:(推论一)
    αk=pkTrkpktApk=(rk−βk−1pk−1)TrkpktApk=rkTrkpkTApkT\begin{aligned} \alpha_{k} &=\frac{p_{k}^{T} r_{k}}{p_{k}^{t} A p_{k}} \\ &=\frac{\left(r_{k}-\beta_{k-1} p_{k-1}\right)^{T} r_{k}}{p_{k}^{t} A p_{k}} \\ &=\frac{r_{k}^{T} r_{k}}{p_{k}^{T} A p_{k}^{T}} \end{aligned}αk​​=pkt​Apk​pkT​rk​​=pkt​Apk​(rk​−βk−1​pk−1​)Trk​​=pkT​ApkT​rkT​rk​​​
  • 最终梯度计算公式:
    rk+1=b−Axk+1=b−A(xk+αkpk)=b−Axk−αkApk=rk−αkApk\begin{aligned} r_{k+1} &=b-A x_{k+1} \\ &=b-A\left(x_{k}+\alpha_{k} p_{k}\right) \\ &=b-A x_{k}-\alpha_{k} A p_{k} \\ &=r_{k}-\alpha_{k} A p_{k} \end{aligned}rk+1​​=b−Axk+1​=b−A(xk​+αk​pk​)=b−Axk​−αk​Apk​=rk​−αk​Apk​​

伪代码

r0=b−Ax0r_{0} = b-A x_{0}r0​=b−Ax0​
p0=r0p_{0} = r_{0}p0​=r0​
k=0k = 0k=0
whileαk=rkTrkpkTApkwhile \quad \alpha_{k}=\frac{r_{k}^{T} r_{k}}{p_{k}^{T} A p_{k}}whileαk​=pkT​Apk​rkT​rk​​
xk+1=xk+αkpk\qquad x_{k+1}=x_{k}+\alpha_{k} p_{k}xk+1​=xk​+αk​pk​
rk+1=rk−αkApk\qquad r_{k+1}=r_{k}-\alpha_{k} A p_{k}rk+1​=rk​−αk​Apk​
ifrk+1<ϵbreak\qquad if \quad r_{k+1}<\epsilon \quad breakifrk+1​<ϵbreak
βk+1=rk+1Trk+1rkTrk\qquad \beta_{k+1}=\frac{r_{k+1}^{T} r_{k+1}}{r_{k}^{T} r_{k}}βk+1​=rkT​rk​rk+1T​rk+1​​
pk+1=rk+1+βkpk\qquad p_{k+1}=r_{k+1}+\beta_{k} p_{k}pk+1​=rk+1​+βk​pk​
k=k+1\qquad k=k+1k=k+1
returnxk+1return \quad x_{k+1}returnxk+1​

2 网络参数初始化

  • constant, uniform, gaussian, xavier, msra(kaiming), bilinear
均匀分布 将权值与偏置进行均匀分布的初始化
高斯分布 初始化为服从N(μ,σ2)N\left(\mu, \sigma^{2}\right)N(μ,σ2)的高斯分布
Xavier W∼U[−6nj+nj+1,6nj+nj+1]W \sim U\left[-\frac{\sqrt{6}}{\sqrt{n_{j}+n_{j+1}}}, \frac{\sqrt{6}}{\sqrt{n_{j}+n_{j+1}}}\right]W∼U[−nj​+nj+1​​6​​,nj​+nj+1​​6​​] 服从均值为 0, 方差为2ni+ni+1\frac{2}{n_{i}+n_{i+1}}ni​+ni+1​2​ 的均匀分布 公式中, nin_ini​ 为本层输入的神经元个数, ni+1n_{i+1}ni+1​ 为本层输出的神经元个数, 适合于线性激活函数(原文公式推导的假设)
MSRA(Kaiming) 基于均值为0, 方差为 2(1+a2)×fanin\sqrt{\frac{2}{\left(1+a^{2}\right) \times fan_{in}}}(1+a2)×fanin​2​​ 的高斯分布 它特别适合 ReLU 激活函数(非线性)
双线性初始化 常用在反卷积网络里的权值初始化

相关概率公式

推导时使用的現率公式:
D(x)=E(x2)−E2(x)D(xy)=E(x2y2)−E2(xy)=E(x2)E(y2)−E2(x)E2(y)D(x)=E\left(x^{2}\right)-E^{2}(x) \\ D(x y)=E\left(x^{2} y^{2}\right)-E^{2}(x y) =E\left(x^{2}\right) E\left(y^{2}\right)-E^{2}(x) E^{2}(y) D(x)=E(x2)−E2(x)D(xy)=E(x2y2)−E2(xy)=E(x2)E(y2)−E2(x)E2(y)
如果 E(y)=0,E(y)=0,E(y)=0, 则有:
D(xy)=D(y)E(x2)D(x y)=D(y) E\left(x^{2}\right) D(xy)=D(y)E(x2)
如果(x,y)是相互独立的,则有
E(xy)=E(x)E(y)E(x y)=E(x) E(y) E(xy)=E(x)E(y)

Xavier 初始化 2010

  • 核心理念是: 优秀的初始化方法应该使得各层的激活值和状态梯度在传播过程中的方差保持一致
  • 它为了保证前向传播和反向传播时每一层的方差一致:
    • 在正向传播时,每层的激活值的方差保持不变;
    • 在反向传播时,每层的梯度值的方差保持不变。
    • 根据每层的输入个数和输出个数来决定参数随机初始化的分布范围,是一个通过该层的输入和输出参数个数得到的分布范围内的均匀分布。

假设

  • 首先,输入数据来说,其均值和方差应满足: E(x)=0,Var(x)=1 (通过BN,较容易满足)
  • 权重矩阵 WWW 和 网络输入 xxx 互相独立
  • 每层输入的每个特征方差一样
  • 激活函数对称: 这主要是为了满足均值为0的假设
  • 激活函数是线性的, 也就是说其导数为1
  • 初始时, 状态值落在激活函数的线性区域, 即此时导数为1

推导

  • 正向传播的推导过程
    Y=W1X1+W2X2+…+WnXnY=W_{1} X_{1}+W_{2} X_{2}+\ldots+W_{n} X_{n} Y=W1​X1​+W2​X2​+…+Wn​Xn​
  • 方差
    Var⁡(WiXi)=E(Xi)2Var⁡(Wi)+E(Wi)2Var⁡(Xi)+Var⁡(Xi)Var⁡(Wi)\operatorname{Var}\left(W_{i} X_{i}\right)=E\left(X_{i}\right)^{2} \operatorname{Var}\left(W_{i}\right)+E\left(W_{i}\right)^{2} \operatorname{Var}\left(X_{i}\right)+\operatorname{Var}\left(X_{i}\right) \operatorname{Var}\left(W_{i}\right) Var(Wi​Xi​)=E(Xi​)2Var(Wi​)+E(Wi​)2Var(Xi​)+Var(Xi​)Var(Wi​)
  • 当输入的 X 均值为 0 时(通过 BN, 较容易满足), 输出的方差就是:
    Var⁡(WiXi)=Var⁡(Wi)Var⁡(Xi)\operatorname{Var}\left(W_{i} X_{i}\right)=\operatorname{Var}\left(W_{i}\right) \ \operatorname{Var}\left(X_{i}\right) Var(Wi​Xi​)=Var(Wi​) Var(Xi​)
  • 独立同分布
    Var⁡(Y)=n×Var⁡(Wi)Var⁡(Xi)\operatorname{Var}(Y)=n \times \operatorname{Var}\left(W_{i}\right) \operatorname{Var}\left(X_{i}\right) Var(Y)=n×Var(Wi​)Var(Xi​)
  • 也就是说输出的方差跟输入的方差只是相差了一个倍数 nVar(Wi),n V a r\left(W_{i}\right),nVar(Wi​), 因此, 为了保证前向传播和反向传播时每一层的方差一致, 则有下面的公式成立:
    ∀i,ni×Var⁡[Wi]=1\forall i, n_{i} \times \operatorname{Var}\left[W^{i}\right]=1 ∀i,ni​×Var[Wi]=1
  • 同时考虑反向传播时输入输出刚好相反, 于是就有:
    ∀i,ni+1×Var⁡[Wi]=1\forall i, n_{i+1} \times \operatorname{Var}\left[W^{i}\right]=1 ∀i,ni+1​×Var[Wi]=1
  • 权衡上述两个公式,可得方差为:
    ∀,Var⁡[Wi]=2ni+ni+1\forall, \operatorname{Var}\left[W^{i}\right]=\frac{2}{n_{i}+n_{i+1}}\\ ∀,Var[Wi]=ni​+ni+1​2​
  • 取均匀分布U(a,b)U(a,b)U(a,b)的方差为 (b−a)212\frac{(b - a) ^ 2}{12}12(b−a)2​,反推得到Xavier最终的初始化分布如下:
    W∼U[−6nj+nj+1,6nj+nj+1]W \sim U\left[-\frac{\sqrt{6}}{\sqrt{n_{j}+n_{j+1}}}, \frac{\sqrt{6}}{\sqrt{n_{j}+n_{j+1}}}\right] W∼U[−nj​+nj+1​​6​​,nj​+nj+1​​6​​]
  • 而取正态分布,则有:
    W∼N(0.0,2nin+nout)W \sim N(0.0, \sqrt{\frac{2}{n_{i n}+n_{\text {out}}}})W∼N(0.0,nin​+nout​2​​)
  • 对于权值的初始化,Glorot提出两个准则:
    • 各个层激活值的方差保持不变(正向传播)
    • 各个层的梯度值的方差保持不变(反向传播)
  • 通常初始的权值矩阵的均值为0. 这这些条件的基础上,Glorot 使用(tanh)作为激活函数,并假设输入值的均值为0,提出了Xavier初始化的方法。

He Kaiming 初始化 2016 (MSRA)

链接

  • 而Kaiming使用ReLU作为激活函数,就无法满足数值的均值为0的条件,因此使用Xavier来初始化ReLU作为激活函数的网络,效果也就不是那么理想。其提出了MSRA的初始化方法,来解决该问题
  • 由于Xavier的假设条件是激活函数是关于0对称的,而常用的ReLU激活函数并不能满足该条件
  • 正向传播:
    yl=Wlxl+bl\mathbf{y}_{l}=\mathbf{W}_{l} \mathbf{x}_{l}+\mathbf{b}_{l}yl​=Wl​xl​+bl​
  • 独立同分布
    Var⁡[yl]=nlVar⁡[wlxl]\operatorname{Var}\left[y_{l}\right]=n_{l} \operatorname{Var}\left[w_{l} x_{l}\right]Var[yl​]=nl​Var[wl​xl​]
  • 设w_的均值为0,即 E(wl)=0,E\left(w_{l}\right)=0,E(wl​)=0, 则有:
    Var⁡(yl)=nlVar⁡(wl)⋅E(xl2)\begin{aligned} \operatorname{Var}\left(y_{l}\right) =n_{l} \operatorname{Var}\left(w_{l}\right) \cdot E\left(x_{l}^{2}\right) \end{aligned}Var(yl​)=nl​Var(wl​)⋅E(xl2​)​
  • 这里有和Xavier一个很大的不同是,这里没有假设输入的值的均值为0。这是由于,使用ReLU的激活函数, xl=max⁡(0,yl−1)x_{l}=\max \left(0, y_{l-1}\right)xl​=max(0,yl−1​),每层输出的值不可能均值为0
  • 初始化时通常设, w的均值为0,偏置 b=0,b=0,b=0, 以及w和x是相互独立的,则有:
    E(yl)=E(wlxl)=E(xl)⋅E(wl)=0\begin{aligned} \mathrm{E}\left(y_{l}\right) &=\mathrm{E}\left(w_{l} x_{l}\right) \\ &=\mathrm{E}\left(x_{l}\right) \cdot \mathrm{E}\left(w_{l}\right) \\ &=0 \end{aligned}E(yl​)​=E(wl​xl​)=E(xl​)⋅E(wl​)=0​
  • 再假设w是关于0对称分布的 (均匀分布,高斯分布都符合) ,则可以得到 yly_{l}yl​ 在0附近也是对称分布的。这样,使用ReLU作为激活函数,则有:xl=max⁡(0,yl−1)x_{l}=\max \left(0, y_{l-1}\right)xl​=max(0,yl−1​)
  • 由于只有当 yl−1>0y_{l}-1>0yl​−1>0 的部分, xlx_{l}xl​ 才有值, 且 yly_{l}yl​ 在0附近也是对称分布的, 则可以得到:
    E(xl2)=12E(yl−12)=12(E(yl−12)−E(yl−1)),(由于 E(yl−1)=0)=12Var⁡(yl−1)\begin{aligned} \mathrm{E}\left(x_{l}^{2}\right) &=\frac{1}{2} \mathrm{E}\left(y_{l-1}^{2}\right) \\ &=\frac{1}{2}\left(E\left(y_{l-1}^{2}\right)-E\left(y_{l-1}\right)\right),\left(\text { 由于 } E\left(y_{l-1}\right)=0\right) \\ &=\frac{1}{2} \operatorname{Var}\left(y_{l-1}\right) \end{aligned}E(xl2​)​=21​E(yl−12​)=21​(E(yl−12​)−E(yl−1​)),( 由于 E(yl−1​)=0)=21​Var(yl−1​)​
  • 带入到:Var⁡(yl)=nlVar⁡(wl)⋅E(xl2)\operatorname{Var}\left(y_{l}\right)=n_{l} \operatorname{Var}\left(w_{l}\right) \cdot E\left(x_{l}^{2}\right)Var(yl​)=nl​Var(wl​)⋅E(xl2​)
  • 得到:
    Var⁡[yl]=12nlVar⁡[wl]Var⁡[yl−1]\operatorname{Var}\left[y_{l}\right]=\frac{1}{2} n_{l} \operatorname{Var}\left[w_{l}\right] \operatorname{Var}\left[y_{l-1}\right]Var[yl​]=21​nl​Var[wl​]Var[yl−1​]
  • 即:
    Var⁡[yL]=Var⁡[y1](∏l=2L12nlVar⁡[wl])\operatorname{Var}\left[y_{L}\right]=\operatorname{Var}\left[y_{1}\right]\left(\prod_{l=2}^{L} \frac{1}{2} n_{l} \operatorname{Var}\left[w_{l}\right]\right)Var[yL​]=Var[y1​](l=2∏L​21​nl​Var[wl​])
  • 为了方差一致:
    12nlVar⁡[wl]=1,∀l\frac{1}{2} n_{l} \operatorname{Var}\left[w_{l}\right]=1, \quad \forall l21​nl​Var[wl​]=1,∀l
  • 即权值得方差应该是:2/nl\sqrt{2 / n_{l}}2/nl​​
  • 取均匀分布,则有:
    W∼U[−6nl,6nl]W \sim U[-\sqrt{\frac{6}{n_{l}}}, \sqrt{\frac{6}{n_{l}}}]W∼U[−nl​6​​,nl​6​​]
  • 取正态分布,则有:
    W∼N(0.,2nl)W \sim N(0., \sqrt{\frac{2}{n_{l}}})W∼N(0.,nl​2​​)

网络参数不可以初始化为0

  • 首先, 在神经网络中, 每一层中的任意神经元都是同构的, 它们拥有相同的输入, 如果再将参数全部初始化为同样的值(如0), 那么输出也就是相同的, 反过来它们的梯度也都是相同的. 那么无论是前向传播还是反向传播的取值都是完全相同的, 那么每一个神经元都是基于input做相同的事情, 这样一来, 不同的神经元根本无法学到不同的特征, 这样就失去网络学习特征的意义了

3 损失函数

  • 01损失;L1损失;L2损失;
  • Softmax函数(用于分类),常用类似于逻辑回归的对数似然函数E(t,y)=−∑jtjlog⁡yjE(t, y)=-\sum_{j} t_{j} \log y_{j}E(t,y)=−∑j​tj​logyj​
  • Softmax容易上溢下溢(指数容易数据溢出),采用f(x−max(x))f(x - max(x))f(x−max(x)) 替代 f(x)f(x)f(x) (科大讯飞问到我了, 我竟然忘了)

KL散度(相对熵)和交叉熵

  • KL散度,值越小表示两个分布越接近:
  • p(x)常用于描述样本的真实分布且q(x)则常常用于表示预测的分布
    DKL(p∥q)=∑i=1np(xi)log⁡p(xi)q(xi)D_{K L}(p \| q)=\sum_{i=1}^{n} p\left(x_{i}\right) \log \frac{p\left(x_{i}\right)}{q\left(x_{i}\right)} DKL​(p∥q)=i=1∑n​p(xi​)logq(xi​)p(xi​)​
  • KL散度和交叉熵只差一个常数项(数据样本的熵):
    DKL(p∥q)=∑i=1np(xi)log⁡(p(xi))−∑i=1np(xi)log⁡(q(xi))=−H(p(x))+[−∑i=1np(xi)log⁡(q(xi))]D_{K L}(p \| q)=\sum_{i=1}^{n} p\left(x_{i}\right) \log \left(p\left(x_{i}\right)\right)-\sum_{i=1}^{n} p\left(x_{i}\right) \log \left(q\left(x_{i}\right)\right) \\ =-H(p(x))+\left[-\sum_{i=1}^{n} p\left(x_{i}\right) \log \left(q\left(x_{i}\right)\right)\right] DKL​(p∥q)=i=1∑n​p(xi​)log(p(xi​))−i=1∑n​p(xi​)log(q(xi​))=−H(p(x))+[−i=1∑n​p(xi​)log(q(xi​))]
  • 交叉熵公式:
    J(W,b)=−[1m∑i=1m(y(i)log⁡f(i)+(1−y(i))log⁡(1−f(i)))]J(W, b)=-\left[\frac{1}{m} \sum_{i=1}^{m}\left(y^{(i)} \log f^{(i)}+\left(1-y^{(i)}\right) \log \left(1-f^{(i)}\right)\right)\right] \\ J(W,b)=−[m1​i=1∑m​(y(i)logf(i)+(1−y(i))log(1−f(i)))]
  • 多分类
    J(W,b)=−[1m∑i=1m∑k=1nyk(i)log⁡fk(i)]J(W, b)=-\left[\frac{1}{m} \sum_{i=1}^{m} \sum_{k=1}^{n} y_{k}^{(i)} \log f_{k}^{(i)}\right] J(W,b)=−[m1​i=1∑m​k=1∑n​yk(i)​logfk(i)​]
  • 交叉熵和softmax的关系:crossentropy和softmax关系

Smooth L1

smooth⁡L1(x)={0.5x2∣x∣<1∣x∣−0.5otherwise \operatorname{smooth}_{L_{1}}(x)=\left\{\begin{array}{ll}0.5 x^{2} & |x|<1 \\ |x|-0.5 & \text { otherwise }\end{array}\right. smoothL1​​(x)={0.5x2∣x∣−0.5​∣x∣<1 otherwise ​

  • 优点:① smooth L1 损失是一种鲁棒性较强的 L1 损失, 相比于 R-CNN 和 SPPNet 中使用的 L2损失, 它对离异点的敏感度更低. 当回归目标趋于无限时, L2 损失需要很小心的处理学习率的设置以避免发生梯度爆炸, 而 smooth L1 损失则会消除这种敏感情况. ② 相比于 L2 损失, L1 损失对于离异值更加鲁棒, 当预测值与目标值相差很大时, 梯度很容易爆炸, 因为梯度里面包含了 (tiu−vi)\left(t_{i}^{u}-v_{i}\right)(tiu​−vi​)这一项, 而smooth L1 在值相差很大是, 其梯度为 ±1 ( L1 在 x 绝对值较大时, 是线性的, 而 L2 是指数的, 很容易爆炸).

Focal Loss

  • Focal Loss for Dense Object Detection
  • 论文论点:1stage不如2stage效果好一个重要原因就是类别不平衡导致:① Two-Stage算法,在经过RPN,再通过score筛选和nms筛选过滤掉了大量的负样本,然后在分类、回归阶段又固定了正负样本比例(1:3),或者通过OHEM技巧使得前景和背景相对平衡。类别不平衡的问题并不明显,算法精度得以保证。② One-Stage算法需要产生超大量的预选框,训练被大量负样本所主导,Focal Loss对此种情况卓有成效。
  • 即:① 无用的易分反例样本会使得模型的整体学习方向跑偏,导致无效学习,即只能分辨出没有物体的背景,而无法分辨具体的物体。② 负样本数量太大,占总的loss函数输入参数的大部分,而且多是容易分类的,因此使得模型的优化方向(即loss函数的梯度下降方向)并不是我们所希望的那样

消除类别不平衡 & 挖掘难分类样本

  • 先前也有一些算法,如OHEM(online hard example mining)为解决类别不平衡(In OHEM each example is scored by its loss, non-maximum suppression (nms) is then applied, and a minibatch is constructed with the highest-loss examples)但是过分关注于错分类的正负样本,而忽视了容易分的正样本
  • 提出Focal Loss:
  • 在交叉熵损失函数基础上改的

改进思路

  • 二分类交叉熵函数
    L=−ylog⁡y′−(1−y)log⁡(1−y′)={−log⁡y′y=1−log⁡(1−y′),y=0\mathrm{L}=-\mathrm{y} \log y^{\prime}-(1-y) \log \left(1-y^{\prime}\right)=\left\{\begin{array}{ll}-\log y^{\prime} & y=1 \\ -\log \left(1-y^{\prime}\right), & y=0\end{array}\right. L=−ylogy′−(1−y)log(1−y′)={−logy′−log(1−y′),​y=1y=0​
  • 缺点:此时的损失函数在大量简单样本的迭代过程中比较缓慢且可能无法优化至最优。
  • Focal Loss
    Lfl={−α(1−y′)γlog⁡y′y=1−(1−α)y′γlog⁡(1−y′),y=0\mathrm{L}_{f l}=\left\{\begin{array}{ll}-\alpha\left(1-y^{\prime}\right)^{\gamma} \log y^{\prime} & y=1 \\ -(1-\alpha) y^{\prime \gamma} \log \left(1-y^{\prime}\right), & y=0\end{array}\right. Lfl​={−α(1−y′)γlogy′−(1−α)y′γlog(1−y′),​y=1y=0​
  • ① γ>0\gamma>0γ>0 用途:挖掘难分类样本。使得减少易分类样本的损失,使得模型更关注于困难的、错分的样本。 2最好
  • ② α>0\alpha>0α>0 用途:平衡正负样本本身的数量比例不均(即类别不均衡) 0.25最好
  • 多分类Focal Loss:
    FL(yt)=−αt∗(1−y^t)γ∗log⁡(y^t)F L\left(y_{t}\right)=- \alpha_{t} *\left(1-\hat{y}_{t}\right)^{\gamma} * \log \left(\hat{y}_{t}\right) FL(yt​)=−αt​∗(1−y^​t​)γ∗log(y^​t​)
  • 进一步提出 RetinaNet TODO

DR loss

  • DR Loss: Improving Object Detection by Distributional Ranking
  • 也是类似于Focal Loss,解决One-Stage中的类别不平衡问题。将分类问题转换为排序问题,从而避免了正负样本不平衡的问题。同时针对排序,提出了排序的损失函数DR loss,并给出了可求导的解。
  • 公式变形
  • 原分类优化函数为,其中:Pi,j,kP_{i,j,k}Pi,j,k​表示第i个图像中第j个候选对象第k类的估计概率!
    min⁡θ∑iN∑j,kℓ(pi,j,k)=>min⁡θ∑iN(∑j+n+ℓ(pi,j+)+∑j−n−ℓ(pi,j−))\min _{\theta} \sum_{i}^{N} \sum_{j, k} \ell\left(p_{i, j, k}\right) => \\ \min _{\theta} \sum_{i}^{N}\left(\sum_{j_{+}}^{n_{+}} \ell\left(p_{i, j_{+}}\right)+\sum_{j_{-}}^{n_{-}} \ell\left(p_{i, j_{-}}\right)\right) θmin​i∑N​j,k∑​ℓ(pi,j,k​)=>θmin​i∑N​⎝⎛​j+​∑n+​​ℓ(pi,j+​​)+j−​∑n−​​ℓ(pi,j−​​)⎠⎞​
  • 将其转换为排序配对问题(γ\gammaγ表示margin):
    min⁡θ∑iN∑j+n+∑j−n−ℓ(pi,j−−pi,j++γ)\min _{\theta} \sum_{i}^{N} \sum_{j_{+}}^{n_{+}} \sum_{j_{-}}^{n_{-}} \ell\left(p_{i, j_{-}}-p_{i, j_{+}}+\gamma\right) θmin​i∑N​j+​∑n+​​j−​∑n−​​ℓ(pi,j−​​−pi,j+​​+γ)
  • 每一幅图像可以写成:
    1n+n−∑j+n+∑j−n−ℓ(pi,j−−pi,j++γ)=Ej+,j−[ℓ(pi,j−−pi,j++γ)]\frac{1}{n_{+} n_{-}} \sum_{j_{+}}^{n_{+}} \sum_{j_{-}}^{n_{-}} \ell\left(p_{i, j_{-}}-p_{i, j_{+}}+\gamma\right) \\ =E_{j_{+}, j_{-}}\left[\ell\left(p_{i, j_{-}}-p_{i, j_{+}}+\gamma\right)\right] n+​n−​1​j+​∑n+​​j−​∑n−​​ℓ(pi,j−​​−pi,j+​​+γ)=Ej+​,j−​​[ℓ(pi,j−​​−pi,j+​​+γ)]
  • 进一步:(Distributional Ranking)
    min⁡θ∑iNℓ(max⁡j−pi,j−−min⁡j+pi,j++γ)\min _{\theta} \sum_{i}^{N} \ell\left(\max _{j_{-}} p_{i, j_{-}}-\min _{j_{+}} p_{i, j_{+}}+\gamma\right) θmin​i∑N​ℓ(j−​max​pi,j−​​−j+​min​pi,j+​​+γ)
  • 将O(n+n_+n+​n−n_-n−​)复杂度转换到O(1),但是max min 对Outier过于敏感!
  • 进一步改进,选取正负样本中最具代表性的样本来排序!其中,sum(q) = 1,是概率分布
    Pi,+=∑j+n+qi,j+pi,j+;Pi,−=∑j=n−qi,j−pi,j−P_{i,+}=\sum_{j_{+}}^{n_{+}} q_{i, j_{+}} p_{i, j_{+}} ; \quad P_{i,-}=\sum_{j=}^{n_{-}} q_{i, j_{-}} p_{i, j_{-}} Pi,+​=j+​∑n+​​qi,j+​​pi,j+​​;Pi,−​=j=∑n−​​qi,j−​​pi,j−​​
  • 当q为均匀分布,则上述的公式就是求期望!
  • 求解q的公式:
    Pi,+=min⁡qi,+∈Δ∑j+n+qi,j+pi,j+;Pi,−=max⁡qi,−∈Δ∑j−n−qi,j−pi,j−P_{i,+}=\min _{\mathbf{q} i,+\in \Delta} \sum_{j_{+}}^{n_{+}} q_{i, j_{+}} p_{i, j_{+}} ; \\ \quad P_{i,-}=\max _{\mathbf{q} i,-\in \Delta} \sum_{j_{-}}^{n_{-}} q_{i, j_{-}} p_{i, j_{-}} Pi,+​=qi,+∈Δmin​j+​∑n+​​qi,j+​​pi,j+​​;Pi,−​=qi,−∈Δmax​j−​∑n−​​qi,j−​​pi,j−​​
  • 但是如果不加约束,那么问题就重新退化到求解max-min的问题
  • 加约束,如下:.其中,Ω(∙)\Omega(\bullet)Ω(∙) 是分布多样性的一个正则化器, 可以防止分布到平凡one-hot解决方案。它可以是不同形式的嫡, 如仁义嫡、值农嫡等。 ε−\varepsilon_{-}ε−​ 和 ε−\varepsilon_-ε−​,是控制分布自由度的常量(注:变量的不确定性越大, 嫡也就越大, 把它搞清楚所需要的信息量也就越大)
    Pi,−=max⁡qi,−∈Δ,Ω(qi,−)≥ϵ−∑j=n−qi,j−pi,j−−Pi,+=max⁡qi,+∈Δ,Ω(qi,+)≥ϵ+∑j+n+qi,j+(−pi,j+)P_{i,-}=\max _{\mathbf{q}_{i,-} \in \Delta, \Omega\left(\mathbf{q}_{i,-}\right) \geq \epsilon_{-}} \sum_{j=}^{n_{-}} q_{i, j_{-}} p_{i, j_{-}} \\ -P_{i,+}=\max _{\mathbf{q}_{i,+} \in \Delta, \Omega\left(\mathbf{q}_{i,+}\right) \geq \epsilon_{+}} \sum_{j_{+}}^{n_{+}} q_{i, j_{+}}\left(-p_{i, j_{+}}\right) Pi,−​=qi,−​∈Δ,Ω(qi,−​)≥ϵ−​max​j=∑n−​​qi,j−​​pi,j−​​−Pi,+​=qi,+​∈Δ,Ω(qi,+​)≥ϵ+​max​j+​∑n+​​qi,j+​​(−pi,j+​​)

优化问题

max⁡qi,−∈Δ∑j−qi,j−pi,j−s.t.Ω(qi−)≥ϵ−\max _{\mathbf{q}_{i,-\in \Delta}} \sum_{j_{-}} q_{i, j_{-}} p_{i, j_{-}} \\ s.t. \quad \Omega\left(\mathbf{q}_{i_{-}}\right) \geq \epsilon_{-} qi,−∈Δ​max​j−​∑​qi,j−​​pi,j−​​s.t.Ω(qi−​​)≥ϵ−​

  • 拉格朗日乘子法
    max⁡qi,−∈Δ∑j−qi,j−pi,j−+λ−Ω(qi,−)\max _{\mathbf{q}_{i,-} \in \Delta} \sum_{j_{-}} q_{i, j_{-}} p_{i, j_{-}}+\lambda_{-} \Omega\left(\mathbf{q}_{i,-}\right) qi,−​∈Δmax​j−​∑​qi,j−​​pi,j−​​+λ−​Ω(qi,−​)
  • 其中正则项 Ω(qi,−)\Omega\left(\mathbf{q}_{i,-}\right)Ω(qi,−​) 使用熵 H(qi,−)H\left(\mathbf{q}_{i,-}\right)H(qi,−​)
  • 得到闭合解:
    qi,j−=1Z−exp⁡(pi,j−λ−);Z−=∑j−exp⁡(pi,j−λ−)q_{i, j_{-}}=\frac{1}{Z_{-}} \exp \left(\frac{p_{i, j_{-}}}{\lambda_{-}}\right) ; \quad Z_{-}=\sum_{j_{-}} \exp \left(\frac{p_{i, j_{-}}}{\lambda_{-}}\right) qi,j−​​=Z−​1​exp(λ−​pi,j−​​​);Z−​=j−​∑​exp(λ−​pi,j−​​​)
  • 同理,正样本:
    qi,j+=1Z+exp⁡(−pi,j+λ+);Z+=∑j+exp⁡(−pi,j+λ+)q_{i, j_{+}}=\frac{1}{Z_{+}} \exp \left(\frac{-p_{i, j_{+}}}{\lambda_{+}}\right) ; \quad Z_{+}=\sum_{j_{+}} \exp \left(\frac{-p_{i, j_{+}}}{\lambda_{+}}\right) qi,j+​​=Z+​1​exp(λ+​−pi,j+​​​);Z+​=j+​∑​exp(λ+​−pi,j+​​​)
  • 上述公式表示,当样本越难(p越小)有越高的权值,受数据分布的影响
  • 则:
    P^i,−=∑j=n−qi,j−pi,j−=∑j=n−1Z−exp⁡(pi,j−λ−)pi,j−P^i,+=∑j−n−qi,j+pi,j+=∑j+n+1Z+exp⁡(−pi,j+λ片平 )pi,j+\begin{aligned} \hat{P}_{i,-} &=\sum_{j=}^{n_{-}} q_{i, j_{-}} p_{i, j_{-}}=\sum_{j=}^{n_{-}} \frac{1}{Z_{-}} \exp \left(\frac{p_{i, j_{-}}}{\lambda_{-}}\right) p_{i, j_{-}} \\ \hat{P}_{i,+} &=\sum_{j-}^{n_{-}} q_{i, j_{+}} p_{i, j_{+}}=\sum_{j_{+}}^{n_{+}} \frac{1}{Z_{+}} \exp \left(\frac{-p_{i, j_{+}}}{\lambda_{\text {片平 }}}\right) p_{i, j_{+}} \end{aligned} P^i,−​P^i,+​​=j=∑n−​​qi,j−​​pi,j−​​=j=∑n−​​Z−​1​exp(λ−​pi,j−​​​)pi,j−​​=j−∑n−​​qi,j+​​pi,j+​​=j+​∑n+​​Z+​1​exp(λ片平 ​−pi,j+​​​)pi,j+​​​
  • 进一步,光滑性对非凸优化的收敛至关重要。因此,我们使用平滑近似代替原来的铰链损耗作为损耗函数,设定γ=0.5\gamma = 0.5γ=0.5, 其中:∀i,j+pi,j+>0.5;∀i,j−pi,j−≤0.5\forall i, j_{+} \quad p_{i, j_{+}}>0.5 ; \quad \forall i, j_{-} \quad p_{i, j_{-}} \leq 0.5∀i,j+​pi,j+​​>0.5;∀i,j−​pi,j−​​≤0.5
    ℓsmooth (z)=1Llog⁡(1+exp⁡(Lz))\ell_{\text {smooth }}(z)=\frac{1}{L} \log (1+\exp (L z)) ℓsmooth ​(z)=L1​log(1+exp(Lz))
  • 最终 DR loss定义为:
    min⁡θLDR(θ)=∑iNℓsmooth(P^i,−−P^i,++γ)\min _{\theta} \mathcal{L}_{\mathrm{DR}}(\theta)=\sum_{i}^{N} \ell_{\mathrm{smooth}}\left(\hat{P}_{i,-}-\hat{P}_{i,+}+\gamma\right) θmin​LDR​(θ)=i∑N​ℓsmooth​(P^i,−​−P^i,+​+γ)
  • 那么这个函数就可以进行梯度下降优化!

补充 回归项的改进

  • 使用平滑L1损失来优化bounding box
    ℓreg(x)={0.5x2/βx≤β∣x∣−0.5βx≥β\ell_{\mathrm{reg}}(x)=\left\{\begin{array}{cc}0.5 x^{2} / \beta & x \leq \beta \\ |x|-0.5 \beta & x \geq \beta\end{array}\right. ℓreg​(x)={0.5x2/β∣x∣−0.5β​x≤βx≥β​
  • 对β\betaβ进行训练期间的衰减,t次迭代时:
    βt=β0−α(t%K)\beta_{t}=\beta_{0}-\alpha(t \% K) βt​=β0​−α(t%K)

DR loss 的 检测器优化目标函数

min⁡∑iNτℓsmooth (P^i,−−P^i,++γ)+ℓreg (vi;βt)\min \sum_{i}^{N} \tau \ell_{\text {smooth }}\left(\hat{P}_{i,-}-\hat{P}_{i,+}+\gamma\right)+\ell_{\text {reg }}\left(v_{i} ; \beta_{t}\right) mini∑N​τℓsmooth ​(P^i,−​−P^i,+​+γ)+ℓreg ​(vi​;βt​)

平方误差和交叉熵误差损失

误差项

  • 平方损失函数:J(θ)=12∥y−f(x)∥2J(\theta)=\frac{1}{2}\|y-f(x)\|^{2}J(θ)=21​∥y−f(x)∥2
  • 交叉熵损失函数:J(W,b)=−[∑k=1nyklog⁡fk]J(W, b)=-\left[\sum_{k=1}^{n} y_{k} \log f_{k}\right]J(W,b)=−[∑k=1n​yk​logfk​]
  • 详细看 反向传播推导
  • 相对于临时输出值(上一层输出值的线性加权值)的梯度
  • 误差项的通项
    δL=∂C∂aL⊙∂aL∂zL=−∣y−f(x)∣σ′(zL)δL=∂C∂aL⊙∂aL∂zL=−∑k=1nykσ′(zkL)fk\delta^{L}=\frac{\partial C}{\partial a^{L}} \odot \frac{\partial a^{L}}{\partial z^{L}}=-|y-f(x)| \sigma^{\prime}\left(z^{L}\right) \\ \delta^{L}=\frac{\partial C}{\partial a^{L}} \odot \frac{\partial a^{L}}{\partial z^{L}}=-\sum_{k=1}^{n} y_{k} \frac{\sigma^{\prime}\left(z_{k}^{L}\right)}{f_{k}} δL=∂aL∂C​⊙∂zL∂aL​=−∣y−f(x)∣σ′(zL)δL=∂aL∂C​⊙∂zL∂aL​=−k=1∑n​yk​fk​σ′(zkL​)​

使用场景

  • 平方损失: 适用于输出值为连续的回归任务;交叉熵损失: 适用于分类任务.
  • 平方损失不适合分类任务:平方损失函数的误差损失函数中含有激活函数对临时输出值的导数,而一般的分类使用sigmoid激活函数,当临时输出量绝对值过大会导致值饱和,进而有可能导致梯度消失,导致参数更新过慢无法更新。
  • 交叉熵损失不适合回归:平方损失(最小二乘法)有好处:1唯一确定, 只有x=y;d(x,y)=0x = y;d(x,y)=0x=y;d(x,y)=0;2对称性 d(x,y)=d(y,x)d(x,y)=d(y,x)d(x,y)=d(y,x) 3物理性质明确

交叉熵为什么用softmax归一化

  • 物理意义更明确,0~1概率值
  • 交叉熵本身含义是分布之间的差异,使用softmax输入,看作概率分布,符合交叉熵意义
  • 数值稳定性,如果不进行归一化,模型会对值的大小很敏感,鲁棒性差!

训练的模型实际效果不错, 但是平方根误差一直很高

  • 这可能是因为存在若干个偏离真实样本程度很大的异常点(Outlier), 这样一来, 即使离群点的数量非常少, 也会让 RMSE 指标变的很差.
  • 解决:
  • 1 这些异常点判定为 “噪声”, 在数据预处理的阶段将这些噪声点过滤掉;
  • 2 如果不认为这些异常点为 “噪声”, 那么就需要进一步的提高模型的预测能力, 使其能够将这些异常点考虑在模型内.
  • 3 可以换用比 RMSE 鲁棒性更好的评估指标, 比如平均绝对百分比误差(Mean Absolute Precent Error, MAPE), 其定义为:
    MAPE=∑i=1n∣yi−y^iyi∣×100nM A P E=\sum_{i=1}^{n}\left|\frac{y_{i}-\hat{y}_{i}}{y_{i}}\right| \times \frac{100}{n} MAPE=i=1∑n​∣∣∣∣​yi​yi​−y^​i​​∣∣∣∣​×n100​
import numpy as np
def Iou(box1, box2, wh=False):if wh == False:xmin1, ymin1, xmax1, ymax1 = box1xmin2, ymin2, xmax2, ymax2 = box2else:xmin1, ymin1 = int(box1[0]-box1[2]/2.0), int(box1[1]-box1[3]/2.0)xmax1, ymax1 = int(box1[0]+box1[2]/2.0), int(box1[1]+box1[3]/2.0)xmin2, ymin2 = int(box2[0]-box2[2]/2.0), int(box2[1]-box2[3]/2.0)xmax2, ymax2 = int(box2[0]+box2[2]/2.0), int(box2[1]+box2[3]/2.0)# 获取矩形框交集对应的左上角和右下角的坐标(intersection)xx1 = np.max([xmin1, xmin2])yy1 = np.max([ymin1, ymin2])xx2 = np.min([xmax1, xmax2])yy2 = np.min([ymax1, ymax2]) # 计算两个矩形框面积area1 = (xmax1-xmin1) * (ymax1-ymin1) area2 = (xmax2-xmin2) * (ymax2-ymin2)inter_area = (np.max([0, xx2-xx1])) * (np.max([0, yy2-yy1])) #计算交集面积iou = inter_area / (area1+area2-inter_area+1e-6)  #计算交并比return iou

IoU系列

  • IoU(交并比)
  • 优点:① 可以反映预测检测框与真实检测框的检测效果 ② 尺度不变性 ③ regression任务中,判断predict box和gt的距离最直接的指标就是IoU (满足非负性;同一性;对称性;三角不等性)
  • 不能直接作为损失函数:① 当两个物体没有相交,IoU=0,不能反映重合程度,且梯度为0不能回传 ② IoU不能反映重合程度

GIoU 2019

  • Generalized Intersection over Union
  • GIoU也是距离度量,使用1-GIoU即可作为损失函数
  • GIoU也是尺度不变
  • GIoU是IoU的下界
  • IoU取值范围是[0,1],而GIoU取值范围[-1,1](对称区间)
  • 无限重合取1,无限远离取-1
  • 与IoU只关注重叠区域不同,GIoU不仅关注重叠区域,还关注其他的非重合区域,能更好的反映两者的重合度
def Giou(rec1,rec2):#分别是第一个矩形左右上下的坐标x1,x2,y1,y2 = rec1 x3,x4,y3,y4 = rec2iou = Iou(rec1,rec2)area_C = (max(x1,x2,x3,x4)-min(x1,x2,x3,x4))*(max(y1,y2,y3,y4)-min(y1,y2,y3,y4))area_1 = (x2-x1)*(y1-y2)area_2 = (x4-x3)*(y3-y4)sum_area = area_1 + area_2w1 = x2 - x1   #第一个矩形的宽w2 = x4 - x3   #第二个矩形的宽h1 = y1 - y2h2 = y3 - y4W = min(x1,x2,x3,x4)+w1+w2-max(x1,x2,x3,x4)    #交叉部分的宽H = min(y1,y2,y3,y4)+h1+h2-max(y1,y2,y3,y4)    #交叉部分的高Area = W*H    #交叉的面积add_area = sum_area - Area    #两矩形并集的面积end_area = (area_C - add_area)/area_C    #闭包区域中不属于两个框的区域占闭包区域的比重giou = iou - end_areareturn giou

DIoU 2019

  • Distance-IoU
  • DIoU要比GIou更加符合目标框回归的机制,将目标与anchor之间的距离,重叠率以及尺度都考虑进去,使得目标框回归变得更加稳定,不会像IoU和GIoU一样出现训练过程中发散等问题。
    DIoU=IoU−d2(b,bgt)c2D I o U=I o U-\frac{d^{2}\left(b, b^{g t}\right)}{c^{2}}DIoU=IoU−c2d2(b,bgt)​
  • GIoU loss 类似,DIoU loss 与目标框不重叠时,仍然可以为边界框提供移动方向
  • DIoU loss可以直接最小化两个目标框的距离,因此比GIoU loss收敛快得多
  • 在两类特殊情况下更好:对于包含两个框在水平方向和垂直方向上这种情况,DIoU损失可以使回归非常快,而GIoU损失几乎退化为IoU损失
  • DIoU还可以替换普通的IoU评价策略,应用于NMS中,使得NMS得到的结果更加合理和有效
def Diou(bboxes1, bboxes2):rows = bboxes1.shape[0]cols = bboxes2.shape[0]dious = torch.zeros((rows, cols))if rows * cols == 0:#return diousexchange = Falseif bboxes1.shape[0] > bboxes2.shape[0]:bboxes1, bboxes2 = bboxes2, bboxes1dious = torch.zeros((cols, rows))exchange = True# #xmin,ymin,xmax,ymax->[:,0],[:,1],[:,2],[:,3]w1 = bboxes1[:, 2] - bboxes1[:, 0]h1 = bboxes1[:, 3] - bboxes1[:, 1] w2 = bboxes2[:, 2] - bboxes2[:, 0]h2 = bboxes2[:, 3] - bboxes2[:, 1]area1 = w1 * h1area2 = w2 * h2center_x1 = (bboxes1[:, 2] + bboxes1[:, 0]) / 2 center_y1 = (bboxes1[:, 3] + bboxes1[:, 1]) / 2 center_x2 = (bboxes2[:, 2] + bboxes2[:, 0]) / 2center_y2 = (bboxes2[:, 3] + bboxes2[:, 1]) / 2inter_max_xy = torch.min(bboxes1[:, 2:],bboxes2[:, 2:]) inter_min_xy = torch.max(bboxes1[:, :2],bboxes2[:, :2]) out_max_xy = torch.max(bboxes1[:, 2:],bboxes2[:, 2:]) out_min_xy = torch.min(bboxes1[:, :2],bboxes2[:, :2])inter = torch.clamp((inter_max_xy - inter_min_xy), min=0)inter_area = inter[:, 0] * inter[:, 1]inter_diag = (center_x2 - center_x1)**2 + (center_y2 - center_y1)**2outer = torch.clamp((out_max_xy - out_min_xy), min=0)outer_diag = (outer[:, 0] ** 2) + (outer[:, 1] ** 2)union = area1+area2-inter_areadious = inter_area / union - (inter_diag) / outer_diagdious = torch.clamp(dious,min=-1.0,max = 1.0)if exchange:dious = dious.Treturn dious

CIoU 2020

  • Complete-IoU
    LCIoU=1−IoU+ρ2(b,bgt)c2+αv\mathcal{L}_{C I o U}=1-I o U+\frac{\rho^{2}\left(\mathbf{b}, \mathbf{b}^{g t}\right)}{c^{2}}+\alpha vLCIoU​=1−IoU+c2ρ2(b,bgt)​+αv
  • 在DIoU基础上,加了一项:
  • ν\nuν 而用来度量长宽比的相似性
    • v=4π2(arctan⁡wgthgt−arctan⁡wh)2v=\frac{4}{\pi^{2}}\left(\arctan \frac{w^{g t}}{h^{g t}}-\arctan \frac{w}{h}\right)^{2}v=π24​(arctanhgtwgt​−arctanhw​)2
  • 其中:
    α=v(1−IoU)+v∂v∂w=8π2(arctan⁡wgthgt−arctan⁡wh)×hw2+h2∂v∂h=−8π2(arctan⁡wgthgt−arctan⁡wh)×ww2+h2\alpha=\frac{v}{(1-I o U)+v} \\ \frac{\partial v}{\partial w}=\frac{8}{\pi^{2}}\left(\arctan \frac{w^{g t}}{h^{g t}}-\arctan \frac{w}{h}\right) \times \frac{h}{w^{2}+h^{2}} \\ \frac{\partial v}{\partial h}=-\frac{8}{\pi^{2}}\left(\arctan \frac{w^{g t}}{h^{g t}}-\arctan \frac{w}{h}\right) \times \frac{w}{w^{2}+h^{2}} α=(1−IoU)+vv​∂w∂v​=π28​(arctanhgtwgt​−arctanhw​)×w2+h2h​∂h∂v​=−π28​(arctanhgtwgt​−arctanhw​)×w2+h2w​
  • 在长宽在[0,1]的情况下, w2+h2w^{2}+h^{2}w2+h2 的值通常很小,会导致梯度爆炸,因此在实现时将 1w2+h2\frac{1}{w^{2}+h^{2}}w2+h21​ 替换成1
  • Non-Maximum Suppression using DIoU:在原始的NMS中,IoU指标用于抑制多余的检测框,但由于仅考虑了重叠区域,经常会造成错误的抑制,特别是在bbox包含的情况下。因此,可以使用DIoU作为NMS的标准,不仅考虑重叠区域,还考虑了中心点距离
    si={si,IoU⁡−RDIoU(M,Bi)<ε0,IoU−RDIoU(M,Bi)≥εs_{i}=\left\{\begin{array}{l} s_{i}, \operatorname{IoU}-\mathcal{R}_{D I o U}\left(\mathcal{M}, B_{i}\right)<\varepsilon \\ 0, \quad I o U-\mathcal{R}_{D I o U}\left(\mathcal{M}, B_{i}\right) \geq \varepsilon \end{array}\right.si​={si​,IoU−RDIoU​(M,Bi​)<ε0,IoU−RDIoU​(M,Bi​)≥ε​
  • 其中:sis_{i}si​ 是分类置信度, ϵ\epsilonϵ 为NMS阅值, M\mathcal{M}M 为最高置信度的框。
def bbox_overlaps_ciou(bboxes1, bboxes2):rows = bboxes1.shape[0]cols = bboxes2.shape[0]cious = torch.zeros((rows, cols))if rows * cols == 0:return ciousexchange = Falseif bboxes1.shape[0] > bboxes2.shape[0]:bboxes1, bboxes2 = bboxes2, bboxes1cious = torch.zeros((cols, rows))exchange = Truew1 = bboxes1[:, 2] - bboxes1[:, 0]h1 = bboxes1[:, 3] - bboxes1[:, 1]w2 = bboxes2[:, 2] - bboxes2[:, 0]h2 = bboxes2[:, 3] - bboxes2[:, 1]area1 = w1 * h1area2 = w2 * h2center_x1 = (bboxes1[:, 2] + bboxes1[:, 0]) / 2center_y1 = (bboxes1[:, 3] + bboxes1[:, 1]) / 2center_x2 = (bboxes2[:, 2] + bboxes2[:, 0]) / 2center_y2 = (bboxes2[:, 3] + bboxes2[:, 1]) / 2inter_max_xy = torch.min(bboxes1[:, 2:],bboxes2[:, 2:])inter_min_xy = torch.max(bboxes1[:, :2],bboxes2[:, :2])out_max_xy = torch.max(bboxes1[:, 2:],bboxes2[:, 2:])out_min_xy = torch.min(bboxes1[:, :2],bboxes2[:, :2])inter = torch.clamp((inter_max_xy - inter_min_xy), min=0)inter_area = inter[:, 0] * inter[:, 1]inter_diag = (center_x2 - center_x1)**2 + (center_y2 - center_y1)**2outer = torch.clamp((out_max_xy - out_min_xy), min=0)outer_diag = (outer[:, 0] ** 2) + (outer[:, 1] ** 2)union = area1+area2-inter_areau = (inter_diag) / outer_diagiou = inter_area / unionwith torch.no_grad():arctan = torch.atan(w2 / h2) - torch.atan(w1 / h1)v = (4 / (math.pi ** 2)) * torch.pow((torch.atan(w2 / h2) - torch.atan(w1 / h1)), 2)S = 1 - ioualpha = v / (S + v)w_temp = 2 * w1ar = (8 / (math.pi ** 2)) * arctan * ((w1 - w_temp) * h1)cious = iou - (u + alpha * ar)cious = torch.clamp(cious,min=-1.0,max = 1.0)if exchange:cious = cious.Treturn cious

4 激活函数

清单

激活函数 形式 导数
Sigmoid f(x)=11+e−xf(x)=\frac{1}{1+e^{-x}}f(x)=1+e−x1​ f′(x)=f(x)(1−f(x))f^{\prime}(x)=f(x)(1-f(x))f′(x)=f(x)(1−f(x))
Tanh f(x)=tanh⁡(x)=ex−e−xex+e−xf(x)=\tanh (x)=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}}f(x)=tanh(x)=ex+e−xex−e−x​ 或 2Sigmoid(2x)−12Sigmoid(2x) - 12Sigmoid(2x)−1 f′(x)=1−(f(x))2f^{\prime}(x)=1-(f(x))^{2}f′(x)=1−(f(x))2
Relu f(x)=max⁡(0,x)={0x≤0xx>0f(x)=\max (0, x)=\left\{\begin{array}{ll}0 & x \leq 0 \\ x \quad x>0\end{array}\right.f(x)=max(0,x)={0xx>0​x≤0 f′(x)={0x≤01x>0f^{\prime}(x)=\left\{\begin{array}{ll}0 & x \leq 0 \\ 1 & x>0\end{array}\right.f′(x)={01​x≤0x>0​
Leaky Relu f(x)=max⁡(0.001x,x)={0.001xx≤0xx>0f(x)=\max (0.001 x, x)=\left\{\begin{array}{ll}0.001 x & x \leq 0 \\ x & x>0\end{array}\right.f(x)=max(0.001x,x)={0.001xx​x≤0x>0​ f(x)=max⁡(0.001x,x)={0.001x≤01x>0f(x)=\max (0.001 x, x)=\left\{\begin{array}{ll}0.001 & x \leq 0 \\ 1 & x>0\end{array}\right.f(x)=max(0.001x,x)={0.0011​x≤0x>0​
PRelu f(x)=max⁡(αx,x)={αxx≤0xx>0f(x)=\max (\alpha x, x)=\left\{\begin{array}{ll}\alpha x & x \leq 0 \\ x & x>0\end{array}\right.f(x)=max(αx,x)={αxx​x≤0x>0​ f(x)=max⁡(αx,x)={αx≤01x>0f(x)=\max (\alpha x, x)=\left\{\begin{array}{ll}\alpha & x \leq 0 \\ 1 & x>0\end{array}\right.f(x)=max(αx,x)={α1​x≤0x>0​
RRelu PReLU中的 α\alphaα 随机取值 f(x)=max⁡(αx,x)={αx≤01x>0f(x)=\max (\alpha x, x)=\left\{\begin{array}{ll}\alpha & x \leq 0 \\ 1 & x>0\end{array}\right.f(x)=max(αx,x)={α1​x≤0x>0​
ELU f(x)={xx≥0α(ex−1)x<0f(x)=\left\{\begin{array}{ll}x & x \geq 0 \\ \alpha\left(e^{x}-1\right) & x<0\end{array}\right.f(x)={xα(ex−1)​x≥0x<0​ f(x)={1x≥0αexx<0f(x)=\left\{\begin{array}{ll}1 & x \geq 0 \\ \alpha e^{x} & x<0\end{array}\right.f(x)={1αex​x≥0x<0​
MaxOut f(x)=max⁡(w1Tx+b1,w2Tx+b2)f(x)=\max \left(w_{1}^{T} x+b_{1}, w_{2}^{T} x+b_{2}\right)f(x)=max(w1T​x+b1​,w2T​x+b2​) f(x)=max⁡(w1,w2)f(x)=\max \left(w_{1}, w_{2}\right)f(x)=max(w1​,w2​)

为什么使用激活函数

激活函数性质

  • 非线性:需要激活函数的非线性对非线性数据进行重新映射,以获得强大的拟合能力
  • 可微性:有助于BP梯度求导
  • 单调性:使得单层网络保证网络是凸的
  • 约恒等性:f(x)≈xf(x)≈xf(x)≈x,这个性质可以使得参数初始值很小时,网络训练很高效,类似于ResNet,这一条有待商榷
  • 如果不使用激活函数,多层网络退化成单层网络

为什么Sigmoid和Tanh导致梯度消失

ReLU 系列相对于 Sigmoid 和 Tanh 的优势

ReLU 有哪些局限性, 如何改进

各激活函数的优缺点和适用场景

  • 神经元饱和问题: 当输入值很大或者很小时, 其梯度值接近于0, 此时, 不管从深层网络中传来何种梯度值, 它向浅层网络中传过去的, 都是趋近于0的数, 进而引发梯度消失问题
  • zero-centered: 如果数据分布不是zero-centered的话就会导致后一层的神经元接受的输入永远为正或者永远为负, 因为 ∂f∂w=x , 所以如果x的符号固定,那么 ∂f/∂w∂f/∂w∂f/∂w 的符号也就固定了, 这样在训练时, weight的更新只会沿着一个方向更新, 但是我们希望的是类似于zig-zag形式的更新路径 (关于非0均值问题, 由于通常训练时是按batch训练的, 所以每个batch会得到不同的信号, 这在一定程度上可以缓解非0均值问题带来的影响, 这也是ReLU虽然不是非0 均值, 但是却称为主流激活函数的原因之一)
激活函数 优势 劣势 适用场景
Sigmoid 可以将数据值压缩到[0,1]区间内 1. 神经元饱和问题 2.sigmoid的输出值域不是zero-centered的 3. 指数计算在计算机中相对来说比较复杂 在logistic回归中有重要地位
Tanh 1. zero-centered: 可以将 (−∞,+∞) 的数据压缩到 [−1,1] 区间内 2.完全可微分的,反对称,对称中心在原点 1. 神经元饱和问题 2. 计算复杂 在分类任务中,双曲正切函数(Tanh)逐渐取代 Sigmoid 函数作为标准的激活函数
ReLU 1. 在 (0,+∞) ,梯度始终为1, 没有神经元饱和问题 2. 不论是函数形式本身,还是其导数, 计算起来都十分高效 3. 可以让训练过程更快收敛(实验结果表明比sigmoid收敛速度快6倍) 4. 从生物神经理论角度来看, 比sigmoid更加合理 1. 非zero-centered 2. 如果输入值为负值, ReLU由于导数为0, 权重无法更新, 其学习速度可能会变的很慢,很容易就会”死”掉(为了克服这个问题, 在实际中, 人们常常在初始化ReLU神经元时, 会倾向于给它附加一个正数偏好,如0.01) 在卷积神经网络中比较主流
LeakyReLU 1. 没有神经元饱和问题 2. 计算高效 3. 收敛迅速(继承了ReLU的优点) 4. 神经元不会”死”掉(因为在负值时, 输出不为0, 而是x的系数0.001)
PReLU 1. 没有神经元饱和问题 2. 计算高效 3. 收敛迅速(继承了ReLU的优点) 4. 神经元不会”死”掉(因为在负值时, 输出不为0, 而是x的系数 α ) 5. 相对于Leaky ReLU需要通过先验知识人工赋值, PReLU通过迭代优化来自动找到一个较好的值, 更加科学合理, 同时省去人工调参的麻烦
ELU 1. 拥有ReLU所有的优点 2. 形式上更接近于zero-centered 3. 在面对负值输入时,更加健壮 1. 引入了指数计算, 使计算变的复杂
Maxout 1. 跳出了点乘的基本形式 2. 可以看作是ReLU和Leaky ReLU 的一般化形式 3. linear Regime(啥意思?) 4. 在所有输入范围上都没有神经元饱和问题 5. 神经元永远不会”死”掉 6. 拟合能力非常强,它可以拟合任意的的凸函数。作者从数学的角度上也证明了这个结论,即只需2个maxout节点就可以拟合任意的凸函数了(相减),前提是”隐含层”节点的个数可以任意多 1. 使得神经元个数和参数个数加倍, 导致优化困难

Sigmoid 和 Softmax

  • Softmax是Sigmoid的扩展,前者倾向多类别中单标签分类问题,后者倾向(多类别中)多标签分类问题

Relu死亡问题

  • 如果某次更新过程中, 梯度值过大, 同时学习率又不小心设置的过大, 就会导致权重一下走更新过多, 那么就有一定概率出现这种情况: 对于任意的训练样本 xix_ixi​, 当前神经元的输出都是小于 0
  • 复活问题: 如果是 ReLU 的话, 几乎就无法复活了, 因为由于此时大部分的输入都是小于 0 的, 这样导致反向传播回来的梯度一直为 0, 那么就无法一点点的更新权重, 使之回归正常值, 也就无法复活神经元了. 由此也可以看出, LeakyReLU 可以在负半区一点点的更新权重, 使之有可能复活.
  • 为什么实际使用中不使用 LeakyReLU?(死亡的神经元也可以起到一定的正则作用, 实际使用效果较好)

如何解决 ReLU 神经元死亡问题

  • 把 ReLU 换成 LReLU 或者 PReLU,保证让激活函数在输入小于零的情况下也有非零的输出。
  • 采用较小的学习率
  • 采用自适应的优化算法,动态调整学习率

ReLU6

  • Mobile v2中,ReLU6 就是普通的ReLU但是限制最大输出值为6
  • 建议最后输出的ReLU6去掉,直接线性输出,理由是:ReLU变换后保留非0区域对应于一个线性变换,仅当输入低维时ReLU能保留所有完整信息。

激活函数的使用原则

  • 优先使用ReLU, 同时要谨慎设置初值和学习率 ( 实际操作中,如果你的learning rate 很大,那么很有可能你网络中的40%的神经元都 “dead” 了。 当然,如果你设置了一个合适的较小的learning rate,这个问题发生的情况其实也不会太频繁 )
  • 尝试使用LeakyReLU/PReLU/Maxout/ELU等激活函数
  • 可以试下tanh, 但是一般不会有太好的结果
  • 不要使用sigmoid

新的激活函数 Swich / Mish

TODO 参考 - 链接

Swich

  • SEARCHING FOR ACTIVATION FUNCTIONS
  • Swich(x)=x⋅σ(βx)Swich(x) = x \cdot \sigma(\beta x)Swich(x)=x⋅σ(βx)

Mish:

  • Mish: A Self Regularized Non-Monotonic Neural Activation Function
    f(x)=x⋅tanh⁡(softplus⁡(x))=x⋅tanh⁡(ln⁡(1+ex))f(x)=x \cdot \tanh (\operatorname{softplus}(x))=x \cdot \tanh \left(\ln \left(1+e^{x}\right)\right)f(x)=x⋅tanh(softplus(x))=x⋅tanh(ln(1+ex))
  • Tensorflow:x=x∗tf.math.tanh(F.softplus(x))x = x *tf.math.tanh(F.softplus(x))x=x∗tf.math.tanh(F.softplus(x))

5 正则化

  • L0正则化可以使用∥x∥0,δ=∑i=1Nxi2xi2+δ\|x\|_{0, \delta}=\sum_{i=1}^{N} \frac{x_{i}^{2}}{x_{i}^{2}+\delta}∥x∥0,δ​=∑i=1N​xi2​+δxi2​​ 近似
  • L1正则:∂L∂w=∂L0∂w+λsign⁡(w)\frac{\partial L}{\partial w}=\frac{\partial L_{0}}{\partial w}+\lambda \operatorname{sign}(w)∂w∂L​=∂w∂L0​​+λsign(w) 令sign(0) = 0
  • L2 正则化:∂L∂w=∂L0∂w+2λw\frac{\partial L}{\partial w}=\frac{\partial L_{0}}{\partial w}+2 \lambda w∂w∂L​=∂w∂L0​​+2λw

L1和L2优缺点:

  • 二者共同的特点都是能够防止过拟合问题.
  • L1 的优点: 能够获得更加稀疏的模型, 权重参数最终大部分会变成 0
  • L1 的缺点: 加入 L1 后会使得目标函数在原点不可导, 需要做特殊处理
  • L2 的优点: 在任意位置都可导, 优化求解过程比较方便, 而且更加稳定
  • L2 的缺点: 无法获得真正的稀疏模型, 参数值只是缓慢趋近于0, 不是直接变成 0
  • 在实际应用过程中, 大部分情况下都是 L2 正则的效果更好, 因此推荐优先使用 L2 正则

L1和L2区别:

  • L1 相对于 L2 能够产生更加稀疏的模型
  • L2 相比于 L1 对于离异值更敏感(因为平方的原因, L2 对于大数的乘法比对小数的惩罚大)
  • L1 和 L2 梯度下降速度不同: 前者梯度恒定, 并且接接近于 0 的时候会很快将参数更新成0, 后者在接近于0 时, 权重的更新速度放缓, 使得不那么容易更新为0 (这也解释了为什么 L1 具有稀疏性)
  • 二者解空间性状不同

L1正则化的原理是

  • 角度一: 函数图像
    L1 在 0 处迅速下降到 0, L2 在 0 处会变得缓慢, 并不会直接更新为 0.
  • 角度二: 函数叠加(梯度下降更新公式)
    w→w′=w−η∂L0∂w−ηλsign⁡(w)w→w′=w−η∂L0∂w−η2λww \rightarrow w^{\prime}=w-\eta \frac{\partial L_{0}}{\partial w}-\eta \lambda \operatorname{sign}(w) \\ w \rightarrow w^{\prime}=w-\eta \frac{\partial L_{0}}{\partial w}-\eta 2 \lambda w w→w′=w−η∂w∂L0​​−ηλsign(w)w→w′=w−η∂w∂L0​​−η2λw
    从以上的更新表达式我们可以看出, 当 w 为正时, L1正则化会将更新后的 w 变的再小一点, 而当 w 为负时, L1正则化会将其变的更大一点—-因此L1的正则化效果就是让 w 尽可能的向 0 靠近, 即最终的 w 参数矩阵会变的更加稀疏
  • 角度三: 贝叶斯先验, “百面机器学习” TODO 为什么 L1 和 L2 分别对应拉普拉斯先验和高斯先验?
  • 角度四: 解空间性状, “百面机器学习” TODO

为什么权值矩阵稀疏可以防止过拟合

  • 1)特征选择(Feature Selection):稀疏性可以实现特征的自动选择, 可以在进行预测时减少无用信息的干扰
  • 2)可解释性(Interpretability):较稀疏的模型表示最终的预测结果只与个别关键特征有关, 这符合实际生活中的历史经验

为何权重参数 w 减小就可以防止过拟合

  • 直观理解:奥卡姆剃刀
  • 过拟合的函数为了完美拟合训练数据,对于一些剧烈变大或者变小的数据也要花时间拟合,只有系数足够大,才能保证在剧烈变化的小区间也能拟合好

为什么稀疏化不选用L0,而选择L1

  • L0范数是指向量中非零元素的个数
  • 一是因为L0范数很难优化求解(NP难问题
  • 二是L1范数是L0范数的最优凸近似,而且它比L0范数要容易优化求解

为什么说 L2 范式可以优化计算?

  • 防止过拟合: 最基本的好处是可以提高模型泛化能力, 防止过拟合
  • 优化计算: 从优化或者数值计算的角度来说, L2正则化有利于提高模型训练速度, 加快计算。提高了数据稳定性,加了正则项系数,改善了减小了X^t * X的条件数,使得数值稳定性提高,方便求逆!

正则项如何确定

  • 通常做法是一开始将正则项系数 λ 设置为 0, 然后先确定出一个比较好的 learning rate, 接着固定该 learning rate, 给 lambda 一个初始值, 如 1e-4.
  • 然后根据验证集上的准确率, 将 λ 增大或者缩小 10 倍, 这里增减 10 倍是粗调节, 当确定了 λ 合适的数量级以后, 再进一步的细调节.

6 归一化

链接

  • 归一化:线性归一化0~1;白化(0均值1方差)
  • 归一化原因:激活函数的饱和阶段(数据不敏感)通过Normalization让数据的分布始终处在激活函数敏感的区域

Batch Normalization

  • ① 进行归一化(对当前 batch 中的所有元素减去均值再除以标准差), 用于统一不同网络层的数据分布; ② 变换重构, 用于恢复原始数据的特征信息(引入了用于变换重构的线性偏移参数γγγ和βββ, 它们分别对简单归一化后的数据执行 scale 和 shift 操作)

BN层常放的位置

  • Conv-BN-ReLU: 常见的使用方式, ① 直接的好处就是可以在网络做前向 inference 的时候, 将 BN 融合到 Conv 中进行加速. ② 还有另一种好处是个人理解, BN 在 ReLU 的激活之前, 可以防止某一层的激活值全部被抑制(及某一层的值均小于0), 从而防止从这一层传播的梯度全是 0, 进而可以防止梯度消失现象. (BN 的减均值处理会使得相当一部分响应值变为正, 进而解决了零梯度问题) 小模型
  • Conv-ReLU-BN: 通常 BN 放在最后面效果最好. 个人见解: BN 实际上就是一种归一化, 而归一化通常是对于输入层使用的, 因此, 把 BN 放在最后, 实际上就是对下一个卷积段的输入进行归一化, 从这个角度看, 将 BN 放在激活层之后, 是比较自然的一种做法. 另外, BN 的原文使用的是 sigmoid 和 tanh 激活函数, 但是对于 ReLU 激活来说, 其曲线图像有较大区别, 而 BN 层会起到一定的平滑隐藏层输入分布的作用, 因此, 对于不同的激活函数, BN 的最佳位置或许有些许不同. 大模型

BN解决的问题

  • Internal Covariate Shift:深层网络中不同网络的数据分布不断发生变化的问题
  • ① 上层网络需要不停调整来适应输入数据分布的变化,导致网络学习速度的降低 ② 网络的训练过程容易陷入梯度饱和区,减缓网络收敛速度

BN的好处

  • BN 通过将每一层网络的输入进行归一化, 保证输入分布的均值与方差固定在一定范围内, 减少了网络中的 Internal Covariate Shift问题, 加速模型收敛; 一定程度上实现了层间的解耦,使得后一层不必去适应输入变化,有利于优化进行;
  • BN 可以使得网络对参数的设置如学习率, 初始权重等不那么敏感, 简化了调参过程, 使得网络学习更加稳定; 常用的权值初始化Xavier,学习率设置高容易更新步伐过大,容易震荡不收敛;
  • BN 使得网络可以使用饱和性激活函数如 Sigmoid, tahh 等, 从而缓解梯度消失问题; 网络的深度和复杂度会累积,导致训练进入激活函数的梯度饱和区;
  • BN mini-batch 的均值和方差每次都不同,因此引入了随机噪声,在一定程度上对模型起到了正则化的效果, 也就是说, BN 可以起到和 Dropout 类似的作用, 因此在使用 BN 时可以去掉 Dropout 层而不会降级模型精度. 但是这一点是存疑的,1 BN 没有防止过拟合的作用 它最多可以使 Overfitting 来的晚一些 《UNDERSTANDING DEEP LEARNING REQUIRES RETHINKING GENERALIZATION 》 2 BN 可以看做是对参数搜索空间做的一种约束, 和Dropout相互冲突,不能同时获益,所以可以去除一个

BN中batch大小

  • 当 batch 较小时, 求出来的均值和方差就会有较大的随机性, 从而导致效果下降, 具体来说, 当 batch 的大小低于 16 时, 就不建议使用 BN, 当 batch 低于 8 时, 网络的性能就会有非常明显的下降.

BN层中使用的均值和方差如何计算

  • 在训练阶段, 就是利用当前 batch 中的均值和方差进行计算;在最后的几个 epoch, 我们通常会固定住 BN 层的参数多训练一会, 这样可以确保 training 和 inference 之间的一致性
  • 在测试阶段, 采用的是网络中维护的滑动平均值进行计算的, 滑动平均值的维护方式是用当前的滑动平均值乘以一个 decay 系数, 然后再加上 (1−decay) 倍的当前 batch 的统计值. decay 决定了数值的更新速度, 通常 decay 会设成一个非常接近于 1 的数, 比如, 0.99 或 0.999.
    shadowvariable=decay×shadowvariable+(1−decay)×variableshadowvariable=decay×shadowvariable+(1−decay)×variableshadowvariable=decay×shadowvariable+(1−decay)×variable

BN层和多卡

  • 多卡通信问题,BN 使用的均值和标准差是单个 GPU 计算的, 这相当于缩小了 mini-batch size.
  • 为什么不支持多卡通信: 至于为什么这样实现: (1) 因为没有 sync 的需求, 因为对于大多数 vision 问题, 单 GPU 上的 mini-batch 已经够大了, 完全不会影响结果. (2) 影响训练速度, BN layer 通常是在网络结构里面广泛使用的, 这样每次都同步一下 GPUs, 十分影响训练速度.

BN在Inference阶段加速

  • 可以将Conv+BN这种情况可以融合,相当于将卷积层乘一个数,加一个数
  • BN+Conv不能融合;Conv和BN之间有激活层不能融合

BN层前面的卷积网络不需要偏置

  • 无论加偏置还是不加偏置, 效果都是一样的, 对均值和方差都不影响
  • 另外, 在 BN 中的βββ参数也可以起到一定的偏置作用.

Group Normalization

  • 在使用 BN 时, 如果数据集改变了, 则均值和方差就会有较大改变, 这就造成了训练阶段和测试阶段的不一致性, 由此也会带来一些问题. 因此, GN 为了解决 BN 对 batch 大小的依赖问题, 转而从另一个角度来进行归一化, GN 更像是介于 LN 和 IN 中间的一种归一化方法, 它会将通道分成不同的组, 同时在固定下标 N 的同时, 求取当前组内的均值和方差来进行归一化.

GN 为什么效果好

  • 组同分布假设:GN 是从 LN 和 IN 中变化来的, 组的划分实际上可以看做是一种对数据分布的假设, 以 LN 为例, 它实际上假设了每张图片所有通道的特征都是同分布的, 而 GN 则是假设每个组的分布不同, 条件没有那么苛刻, 因此 GN 的表现力和包容性会更强, 而 IN 只依赖与独立的某一维, 没有探究不同通道之间特征的关联性.
  • 历史渊源:传统的图像处理中,提取特征通常是使用SIFT,HOG和GIST特征,这些特征有一个共性,都具有按group表示的特性,每一个group由相同种类直方图的构建而成,这些特征通常是对在每个直方图(histogram)或每个方向(orientation)上进行组归一化(group-wise norm)而得到。而更高维的特征比如VLAD和Fisher Vectors(FV)也可以看作是group-wise feature,此处的group可以被认为是每个聚类(cluster)下的子向量sub-vector。
  • 按照个人理解,每个滤波器提取的是前层的非结构特征到一个通道中,认为同一个通道中的是一种特征,所以同一个特征应该是同一种分布,所以GN就是有道理的!

BN, LN, IN, GN 的区别

  • 就是计算均值和方差的集合不同,设shape:(N,C,H,W)(N,C,H,W)(N,C,H,W)
  • BN 是固定 CCC 不变, 求固定 C 时所有(N,H,W)(N,H,W)(N,H,W)像素点的均值和方差, 这个均值和方差会用来归一化所有处于当前通道CCC上的像素.
  • LN 是固定 NNN 不变, 求固定 N 时所有 (C,H,W)(C,H,W)(C,H,W) 像素点的均值和方差, 这个均值和方差会用来归一化所有处于当前 NNN 上的像素. 可以看出, 这里 LN 在求取均值和方差时, 由于固定了NNN, 所以与 batch 的大小无关.
  • IN 是同时固定 NNN和 CCC 不变, 求固定 N 和 C 时所示 (H,W)(H,W)(H,W) 像素点的均值和方差.
  • GN 是介于 LN 和 IN 中的一种 Norm 方法, 它首先也是固定 N 不变, 然后会将 C 分成若干个 Group, 然后分别求取每个 Group 的均值和方差, 并对 Group 中的像素进行归一化

归一化方法中的线性偏移个数

  • shape :(N,C,H,W)(N, C, H, W)(N,C,H,W) 不变. 所有归一化方法线性偏移参数 γγγ 和 βββ 的个数都与输入shape 的通道数相同, 均为 CCC.
  • 不同归一化方法, 使用的mean和var划分方法不同, 但偏移参数γ\gammaγ和β\betaβ仍与channel数量保持一致

Instance Normalization

  • 风格迁移常用

Layer Normalization

Switchable Normalization

  • SN是LN,BN以及IN的加权和
  • 算法核心在于提出了一个可微的归一化层,可以让模型根据数据来学习到每一层该选择的归一化方法,亦或是三个归一化方法的加权和

7 感受野

  • 感受野的定义是 卷积神经网络每一层输出的特征图(feature map)上的像素点在原始图像上映射的区域大小

感受野计算公式

  • 没有空洞卷积:RFl+1=RFl+(kernelSizel−1)×stridelRF_{l+1}=RF_l+(kernelSize_l−1)×stride_lRFl+1​=RFl​+(kernelSizel​−1)×stridel​
  • 有空洞卷积(Dilated Conv):RFl+1=RFl+(kernelSizel−1)×stridel×(dilationRatel+1−1)RF_{l+1}=RF_l+(kernelSize_l−1)×stride_l×(dilationRate_{l+1}-1)RFl+1​=RFl​+(kernelSizel​−1)×stridel​×(dilationRatel+1​−1)
  • PS:空洞率是当前卷积核的卷积过程中,一个元素对应原图上的区域,图示(空洞卷积率分别是1;2;4)

理论感受野和有效感受野的区别

  • 特征有效感受野远小于理论公式推出的感受野
  • 越靠近中心位置,实际有效感受野也越大
  • 如图,x1,1x_{1,1}x1,1​只对o1,1o_{1,1}o1,1​有效,而x3,3x_{3,3}x3,3​对o的全部都有影响!
    • Understanding the Effective Receptive Field in Deep Convolutional Neural Networks
  • 影响某个神经元输出的输入区域就是理论感受野,也就是我们平时说的感受野,但该输入区域的每个像素点对输出的重要性不同,越靠近中心的像素点影响越大,呈高斯分布,也就是说只有中间的一小部分区域对最后的输出有重要的影响,这个中间的一小部分区域就是有效感受野
  • 有效感受野在训练过程中是会发生变化的,影响有效感受野的因素:
    • 数据集
    • 层的类型(下采样,扩张卷积,跳层连接,非线性激活函数)
    • 卷积层参数初始化方式(Uniform(参数全部设置为1), Random)
    • 卷积层的个数

不同因素对有效感受野的影响

  • 卷积层层数,权值初始化方式以及非线性激活对ERF的影响
  • 下采样和扩张卷积可以增大感受野
  • 不同数据集对感受野的影响

目标检测的Anchor和感受野大小之间的关系

  • 基于anchor的,比如SSD系列,v2以后的yolo,还有faster rcnn系列。
  • 通过anchor设置每一层实际响应的区域,使得某一层对特定大小的目标响应。
  • 不同大小的anchor应该放在哪几层?
  • 放置anchor层的特征感受野应该跟anchor大小相匹配,感受野比anchor大太多不好,小太多也不好。如果感受野比anchor小很多,就好比只给你一只脚,让你说出这是什么鸟一样。如果感受野比anchor大很多,则好比给你一张世界地图,让你指出故宫在哪儿一样。

8 全连接层

作用

  • 直观的作用, 起到 “分类器” 的作用. 通常在网络的最后, 会利用全连接层将网络学习到的 “分布式特征表示” 映射到 样本标记空间.
  • 特征融合, 全连接的任意一个神经元, 都能够 “看到” 前一层网络层输出的所有特征信息(FC 认为下一层的输出与上一层所有输入都有关, 实际上这样很容易 overfitting), 全连接层会根据这些信息, 决定它当前某一个神经元的输出. 这样也就弥补了卷积层只能 “看到” 局部信息的缺点.
  • 存在大量的参数冗余, 所有大多数时候我们会用全局平均池化来代替 FC. 但是我之前有看过一篇论文说 FC 的参数冗余也并不是一无是处, 它可以在一定程度上保证模型的迁移能力, 当原模型和目标数据集相差较大的时候, 使用 FC 的模型比不使用 FC 的模型迁移效果好. 原因可能是冗余的参数对于特征的表示可能更加丰富.

全连接转换为卷积层及好处

全连接层转换为卷积层

  • ① 如果前一层是全连接层, 那么可以把前一层的全连接层当做是 h=1,w=1,c=len(FC)h=1,w=1,c=len(FC)h=1,w=1,c=len(FC) 的特征图谱, 然后卷积核化:核大小为 1×1, 通道数ccc为前一层神经元个数, 卷积核的个数nnn根据当前层的神经元个数决定. ② 如果前一层是卷积层, 则只需核的大小设置为前一层的特征图谱的大小, 进行全局卷积, 核的通道数由前一层的卷积结果决定, 核的个数由当前层的神经元个数决定.

好处

  • 1 可以接受更多尺寸的图片输入, 我们只需要固定网络的通道数符合要求, 然后利用卷积层即可完全最终的分类.
  • 2 高效, 当我们需要在一张图片上以一定大小的滑动窗口进行多次计算时, 由于这些窗口之间有大量的重合区域, 因此直接使用全连接层会造成会多的计算浪费, 而卷积操作在大多数框架中都得到了性能优化, 十分擅长处理这种操作, 因此在时间上更占优势.

两层全连接层的BP公式

全连接层失宠

  • 目前大多数的任务,如目标检测,或是分割,并不要求提取全图特征,只需要提取能够覆盖目标物体的大小的感受野内特征即可。尤其是小物体检测问题,感受野很小即可,如果还去接全连接提取全图特征,我们待检测的目标会被淹没在和其它背景的平均特征之中变得不可识别。

9 卷积层

卷积层输出尺寸计算公式

  • 不带空洞卷积
    Hout=⌊Hin+2×padding[0]−kernelsize[0]stride[0]+1Wout=⌊Win+2×padding[1]−kernelsize[1]stride[1]+1H_{o u t}=\left\lfloor\frac{H_{i n}+2 \times padding[0]-kernel size[0]}{stride[0]}+1\right. \\ W_{o u t}=\left \lfloor\frac{W_{in}+2 \times padding[1]-kernel size[1]}{stride[1]}+1 \right. Hout​=⌊stride[0]Hin​+2×padding[0]−kernelsize[0]​+1Wout​=⌊stride[1]Win​+2×padding[1]−kernelsize[1]​+1

  • 带空洞卷积
    Hout=⌊Hin+2×padding[0]−dilation[0]×(kernel size [0]−1)−1stride [0]+1Wout=⌊Win+2×padding⁡[1]−dilation[1]×(kernel size [1]−1)−1stride[1]+1H_{o u t}=\left\lfloor\frac{H_{i n}+2 \times p a ddin g[0]-d i l a t i o n[0] \times(\text { kernel size }[0]-1)-1}{\text { stride }[0]}+1\right. \\ W_{\text {out}}=\left\lfloor\frac{W_{i n}+2 \times \operatorname{padding}[1]-\text {dilation}[1] \times(\text { kernel size }[1]-1)-1}{\text {stride}[1]}+1\right. Hout​=⌊ stride [0]Hin​+2×padding[0]−dilation[0]×( kernel size [0]−1)−1​+1Wout​=⌊stride[1]Win​+2×padding[1]−dilation[1]×( kernel size [1]−1)−1​+1

1x1卷积层作用

  • 改变特征图谱的深度: 通常用作降维
  • xception 和 mobilenet 系列将其用作解耦: 将 cross-channel correlation 和 spatial correlation 的学习进行解耦. 大大降低计算量 HOW?
  • 实现了跨通道的信息组合: 使用 1x1 卷积核,实现降维和升维的操作其实就是channel间信息的线性组合变化, 3x3 ,64channels的卷积核前面添加一个 1x1 ,28channels的卷积核,就变成了 3x3 ,28channels的卷积核,原来的64个channels就可以理解为跨通道线性组合变成了28channels,这就是通道间的信息交互。因为 1x1 卷积核,可以在保持feature map尺度不变的(即不损失分辨率)的前提下大幅增加非线性特性(利用后接的非线性激活函数),把网络做的很deep,增加非线性特性。

卷积操作的特性

  • 稀疏连接(稀疏交互):相对于全连接网络来说的,每个神经元只对前一层的局部区域交互。好处:使得参数更少减少过拟合;提高模型的统计效率,每个像素区域都可以提供一部分特征
  • 参数共享:卷积核的每个元素将作用于每一次局部输入的特定位置上。
    只需要学习一个参数集合,而不是对于每一个位置都学习一个单独的参数集合。

卷积核大小如何确定

  • 在网络的起始层,选用较大的卷积核(7×7),这样可以使得卷积核“看到”更多的原图特征;
  • 在网络中中间层,可以用两个3×3大小的卷积层来代替一个5×5大小的卷积层,这样做可以在保持感受野大小不变的情况下降低参数个数,减少模型复杂度;
  • 通常使用奇数大小的卷积核,原因有二,一是可以更加方便的进行padding,二是奇数核相对于偶数核,具有天然的中心点,并且对边沿、对线条更加敏感,可以更有效的提取边沿信息

卷积层的优化

Im2col 算法

  • 将三维张量转换为二维矩阵,将卷积转换为矩阵乘法,使用GEMM(通用矩阵乘法)库(cuBLAS和OpenBLAS)进行加速优化,再使用Col2im转换为三维矩阵。
  • 具体就是:根据卷积核的大小在特征图谱上获得一个 patch, 将这个 patch 里面的元素拿出来变成矩阵的一列, 按照卷积操作, 取出所有的 path 组成一个新的矩阵. 然后将卷积核展开成一个矩阵, 矩阵的每一行都是卷积核中的元素, 总共的行数和输出图谱的通道数相关. 这样, 卷积的计算操作就变成了普通的矩阵乘法.
  • 缺点:存储大量的冗余元素, 使得内存消耗比较大.

空间组合优化

  • 分治递归,基于空间特性将卷积计算划分为若干份, 分别处理, 虽然划分后的计算总量保持不变, 但是计算小矩阵时的访问内存的局部性更好, 可以借由计算机存储层次结果获得性能提升.
  • 对于不同规模的卷积, 寻找合适的划分方法不是一件容易的事情. 该划分也可以通过 AutoTVM 自动化来完成.

其他卷积计算加速方法

  • FFT: 大卷积核时使用, 时域卷积等于频域相乘, 因此可以将问题转化成简单的乘法问题. cuFFT
  • Winograd: 据说在 GPU 上效率更高, 貌似是针对 2×2 和 3×3 的卷积核专门使用的? 是用更多的加法计算来减少乘法计算。因此,一个前提就是,在处理器中,乘法计算的时钟周期数要大于加法计算的时钟周期数. Winograd 将矩阵乘法的复杂度降到了 O(n2.376), 目前最优!
  • NNPACK: FFT 和 Winograd 方法的结合
  • MEC(17年): 一种内存利用率高且速度较快的卷积计算方法, 添加链接描述 主要改进了 im2col+GEMM 的策略, 目的主要是减少内存消耗的同时顺便提升速度. 由于同样可以利用现有的矩阵运算库, 因此算法的实现难度并不大.

矩阵乘法的加速

  • 传统的就是3for循环
  • Strassen算法:递归进行2x2划分,求解矩阵乘法;一个局限是其要求矩阵乘的规模为 2n,这在现实情况中不容易满足。一种解决方法是将规模分解为 2nX 其中 X 无法被 2 整除,那么可以应用 Strassen 算法不断递归拆分计算直到小矩阵规模。
  • 还有很多内容,先不弄了!

10 池化层

什么是池化

  • 考虑卷积神经网络的局部稀疏链接和滤波器全局权值共享,也就意味着在一个图像区域的特征极有可能在另一个区域同样适用。当我们描述一个大的图像的时候就可以对不同位置的特征进行聚合统计(例如:可以计算图像一个区域上的某个特定特征的平均值 or 最大值)这种统计方式不仅可以降低纬度,还不容易过拟合,提高了网络的非线性表达能力!

池化层尺寸

(inputwidth+2×pad−poolsize)/stride+1(input_{width}+2×pad-pool_{size}) / stride+1(inputwidth​+2×pad−poolsize​)/stride+1

池化层的作用

  • 降低优化难度和参数个数: 池化层可以降低特征图谱的维度,从而降低网络整体的复杂度,不仅可以加速计算,也能起到 一定的防止过拟合的作用(只保留最大值, 相于不保留非关键信息).
  • 增大感受野: 当没有池化层时,一个3×3,步长为1的卷积,它输出的一个像素的感受野就是3×3的区域,再加一个stride=1的3×3卷积,则感受野为5×5。当使用pooling后,很明显感受野迅速增大,感受野的增加对于模型的能力的提升是必要的, 当然还有其他更有效的提升感受野的方法, 只不过池化对于感受野的提升也有一定作用.
  • 增加网络平移, 伸缩, 旋转不变性: 池化层只会关注核内的值,而不会关注该值的位置,因此,当目标位置发生移动时,池化层也可以得到相同的结果,所以池化层在一定程度上可以增加CNN网络的平移不变性. 同时一定程度上也具有旋转不变性(旋转可以看做是特殊的平移)和尺度不变性(与具体的缩放插值方式有关, 但通常也能保持池化输出值不变)

池化层的BP过程

  • 无论是最大池化还是均值池化, 都没有需要学习的参数。因此,在卷积神经网络的训练中,Pooling层需要做的仅仅是将误差项传递到上一层,而没有梯度的计算。
  • 对于 mean pooling,backward的时候,把一个值分成四等分放到前面2x2的格子里面就好了
  • 对于 max pooling,backward的时候把当前的值放到之前那个最大的位置,其他的三个位置都设置成0。

最大池化和平均池化的异同和适用场景

  • 最大池化多用于提取特征, 因为我们需要提取出物体中最显著的若干特征来帮助我们感知和识别物体, 而最大池化的计算规则将是保留特征相应最大的值, 在使用中, 由于网络内部的大部分时候都是在进行特征提取, 因此 maxpooling 更常用.
  • 平均池化的作用是可以聚合核内的所有特征信息, 因此通常在整个网络的最后, 我们会使用全局平均池化来整合整体的特征;因为特征图谱已经是经过高度提取抽象后的, 所以, 我们不能只关注那些最大的值, 图谱上的每一个值所对应的特征我们都需要综合考虑, 这一点和全连接层本身的计算规则相符合, 因为全连接中的每一个神经元都能够 “看到” 全一层所有的输出, 使得全连接可以通过整合所有的特征信息来决定最终的分类结果, GAP 也能够起到相类似的作用.

全局平均池话(GAP)

  • 替代全连接层,将池化核的个数设置为全连接的神经元个数, 就可以获得相同维度的计算结果.
  • 全连接层参数多, 因此容易产生过拟合现象, 从而影响整个模型的泛化能力. 而 GAP 本身不包含任何参数, 它直接在 feature map 和样本标签空间内建立了联系, 使得每一个 feature map 本身具有的含义更加清晰, 也就是一个 feature map 对应一个 label. 明确学习目标, 简化学习过程.
  • 通常认为如果选取区域均值(mean pooling),往往能保留整体数据的特征,较好的突出背景信息;如果选取区域最大值(max pooling),则能更好保留纹理特征。

Ps RoI Pooling

  • Position-sensitive RoI Pooling
  • 来自于 R-FCN 2016
  • 见博客 目标检测

PrROI Pooling

  • Precise RoI Pooling
  • 从 ROI Align 进化而来

    IC(x,y,i,j)=max⁡(0,1−∣x−i∣)×max⁡(0,1−∣y−j∣)f(x,y)=∑i,jIC(x,y,i,j)×wi,jPrPool⁡(bin⁡,F)=∫y1y2∫x1x2f(x,y)dxdy(x2−x1)×(y2−y1)\begin{array}{c} I C(x, y, i, j)=\max (0,1-|x-i|) \times \max (0,1-|y-j|) \\ f(x, y)=\sum_{i, j} I C(x, y, i, j) \times w_{i, j} \\ \operatorname{PrPool}(\operatorname{bin}, \mathcal{F})=\frac{\int_{y 1}^{y 2} \int_{x 1}^{x 2} f(x, y) d x d y}{\left(x_{2}-x_{1}\right) \times\left(y_{2}-y_{1}\right)} \end{array} IC(x,y,i,j)=max(0,1−∣x−i∣)×max(0,1−∣y−j∣)f(x,y)=∑i,j​IC(x,y,i,j)×wi,j​PrPool(bin,F)=(x2​−x1​)×(y2​−y1​)∫y1y2​∫x1x2​f(x,y)dxdy​​
  • IC函数计算每一个连续的x,yx,yx,y方向的偏移的乘积,在1个像素以内的偏移,使用该像素(i,j)(i,j)(i,j)计算,即该像素上下左右1个像素以内的区域都会被计算到
  • 特点:
    • 不涉及任何量化取整操作
    • 解决了ROI Align中插值像素点数目N的问题,这里不再有该参数,整个feature map是一个连续的整体。
    • 整个区域的像素值通过求积分得到,所以所有的像素值都有梯度的传递。

SPP 2014

  • Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition
  • Spatial Pyramid Pooling
  • ① 直接对整个特征图池化,每一维得到一个池化后的值,构成一个1x256的向量
  • ② 将特征图分成2x2共4份,每份单独进行池化,得到一个1x256的向量,最终得到2x2=4个1x256的向量
  • ③ 将特征图分成4x4共16份,每份单独进行池化,得到一个1x256的向量,,最终得到4x4=16个1x256的向量
  • 将三种划分方式池化得到的结果进行拼接,得到(1+4+16)256=21256的特征
  • 由图中可以看出,整个过程对于输入的尺寸大小完全无关,因此可以处理任意尺寸的候选框。
  • 空间池化层实际就是一种自适应的层,这样无论你的输入是什么尺寸,输出都是固定的(21xchannel)

ASPP

  • Atrous Convolution(空洞卷积),它是一种增加感受野的方法。空洞卷积是是为了解决基于FCN思想的语义分割中,输出图像的size要求和输入图像的size一致而需要upsample,但由于FCN中使用pooling操作来增大感受野同时降低分辨率,导致upsample无法还原由于pooling导致的一些细节信息的损失的问题而提出的。
  • AConv有很多问题:The Gridding Effect + Long-ranged information might be not relevant
    • GE:kernel 并不连续,也就是并不是所有的 pixel 都用来计算了,因此这里将信息看做 checker-board 的方式会损失信息的连续性。这对 pixel-level dense prediction 的任务来说是致命的。
    • LI:光采用大 dilation rate 的信息或许只对一些大物体分割有效果,而对小物体来说可能则有弊无利了。如何同时处理不同大小的物体的关系,则是设计好 dilated convolution 网络的关键
  • Hybrid Dilated Convolution (HDC)
  • Atrous Spatial Pyramid Pooling
    • 设计了几种不同采样率的空洞卷积来捕捉多尺度信息,但我们要明白采样率(dilation rate)并不是越大越好,因为采样率太大,会导致滤波器有的会跑到padding上,产生无意义的权重,因此要选择合适的采样率。

11 反卷积层

  • Transposed Convolution / Deconvolution / Fractionally-strided convolution.

矩阵乘法描述反卷积

  • 将卷积转换为 Y=CXY = CXY=CX
  • 只需要保证反卷积的输出尺寸和正卷积相对应即可, 也就是说反卷积只恢复了矩阵 XXX 的尺寸的大小, 并不能回复 XXX 的每个元素值.
  • X=CTYX = C^T YX=CTY

反卷积和双线性插值(上采样)

  • 双线性插值, 计算速度快, 实现简单;反卷积, 具有学习参数, 可以学习相应特征
  • Deconv名字其实不太适合,其使用转置卷积核的方式应该叫转置卷积 Transposed Conv;但是其本质思想还是旨在消除卷积

反卷积尺寸计算公式

Hout=(Hin−1)×stride[0]−2×padding[0]+kernelsize[0]+outputpadding[0]H_{o u t}=\left(H_{i n}-1\right) \times stride [0]-2 \times padding[0]+kernel size[0]+output padding [0]Hout​=(Hin​−1)×stride[0]−2×padding[0]+kernelsize[0]+outputpadding[0]

Hout=(Hin−1)×stride[0]−2×padding[0]+dilation[0]×(kernel size⁡[0]−1)+outputpadding[0]+1H_{o u t}=\left(H_{i n}-1\right) \times stride [0]-2 \times padding[0]+ dilation[0] \times(\text { kernel } \operatorname{size}[0]-1)+output padding[0]+1Hout​=(Hin​−1)×stride[0]−2×padding[0]+dilation[0]×( kernel size[0]−1)+outputpadding[0]+1

12 空洞卷积

  • 可以在不引入额外计算量的前提下, 可以扩大感受野

13 训练问题

图像分类问题,数据量不足的问题核缓解

  • 白面的问题
  • 带来的问题: 过拟合

处理方法

  • 基于模型的方法: 采用降低过拟合风险的措施,包括简化模型(如将非线性简化成线性), 添加约束项以缩小假设空间(如L1和L2正则化), 集成学习, Dropout超参数等.
  • 基于数据的方法, 主要通过数据扩充(Data Augmentation), 即根据一些先验知识, 在保持特定信息的前提下, 对原始数据进行适合变换以达到扩充数据集的效果.
  • 在图像分类任务中,在保持图像类别不变的前提下,可以对训练集中的每幅图像进行以下变换:
    • 观察角度:一定程度内的随机旋转、平移、缩放、裁剪、填充、左右翻转等
    • 噪声扰动:椒盐噪声、高斯白噪声
    • 颜色变换:在RGB颜色空间上进行主成分分析
    • 其他:亮度、清晰度、对比度、锐度
    • 其他扩充数据方法:特征提取, 在图像的特征空间内进行变换:数据扩充or上采样技术,如SMOTE(Synthetic Minority Over-sampling Technique)。
  • 最后,迁移学习或者用GAN合成一些新样本也可帮助解决数据不足问题。

分类问题中的数据不均衡

  • 上采样:上采样是把小种类复制多份;上采样反复出现数据,容易过拟合,所以每次生成新数据,加一点扰动。减少信息损失的方法:采用bagging或boosting思路,前者叫EasyEnsemble,随机有放回抽样,训练多个不同分类器,再组合;后者叫BalanceCascade,增量训练,分类正确的样本不放回,对样本集再下采样进行第二个分类器的分类。也可以采用KNN挑选最具代表性的样本 NearMiss
  • 数据合成:SMOTE为每个小众样本合成相同数量的新样本;Borderline-SMOTE的解决思路是寻找那些应该为之合成新样本的小众样本;ADASYN的解决思路是根据数据分布情况为不同小众样本生成不同数量的新样本。
  • 加权:难点在于设置合理的权重
  • 问题转换为一分类问题或异常检测问题 One-class SVM

训练不收敛

我们主要通过观察 loss 曲线来判断是否收敛, 根据不同的 loss 曲线, 有以下三种不收敛的情形:

  • 从训练开始曲线就一直震荡或者发散
    可能原因: (1) 学习率设置的过大; (2) 向网络中输入的数据是错误数据, 如标签对应错误, 读取图片时将宽高弄反, 图片本身质量极差等;
    解决方法: 调节学习率; 检查数据读取代码
  • 在训练过程中曲线突然发散
    可能原因: (1) 学习率设置过大, 或者没有采用衰减策略; (2) 读取到了个别的脏数据, 如标签对应错误, 或者标签为空等
    解决方法: 调整学习率及相应的衰减策略; 将 batch size 设为 1, shuffle 置为 false, 检查发散时对应的数据是否正确;
  • 在训练过程中曲线突然震荡
    可能原因: (1) 损失函数中的正则化系数设置有问题, 或者损失函数本身存在 Bug; (2)数据存在问题
    解决方法: 检查损失函数; 检查数据

Nan值原因

  • 一种是梯度爆炸, 使得某一层计算出来的值超过了浮点数的表示范围
  • 另一种是由于损失函数中 logloglog 项的值出现的负值或者 0 导致的, 因为 logxlogxlogx 只在 x 大于 0 的时候才有意义.
  • 梯度爆炸:数据归一化,减小学习率,加入Gradient Clipping,参数初始化方法?
  • logloglog项出现负值或者0,参数是否初始化为0?数据是否有问题,比如含有Nan值等脏数据?
  • 损失函数计算问题,对于batch_size大的情况,损失函数相加可能会出现数据溢出,要么将float转换为double,或者避免加操作?预先预计loss大小?

过拟合是什么

  • 使用正则项(Regularization): L1, L2 正则
  • 数据增广(Data Augmentation): 水平或垂直翻转图像、裁剪、色彩变换、扩展和旋转等等, 也可利用GAN辅助生成(不常用)
  • Dropout: Dropout是指在深度网络的训练中, 以一定的概率随机的”临时丢弃”一部分神经元节点. 具体来讲, Dropout作用于每份小批量训练数据, 由于其随机丢弃部分神经元的机制, 相当于每次迭代都在训练不同结构的神经网络, 可以被认为是一种实用的大规模深度神经网络的模型继承算法.
  • Drop Connect: Drop Connect 是另一种减少算法过拟合的正则化策略,是 Dropout 的一般化。
  • 早停: 早停法可以限制模型最小化代价函数所需的训练迭代次数。早停法通常用于防止训练中过度表达的模型泛化性能差。如果迭代次数太少,算法容易欠拟合(方差较小,偏差较大),而迭代次数太多,算法容易过拟合(方差较大,偏差较小)。早停法通过确定迭代次数解决这个问题,不需要对特定值进行手动设置。

欠拟合

  • 当模型在训练数据和测试数据上都无法很好的拟合数据时, 说明出现了欠拟合
  • 首先看看是否是神经网络本身的拟合能力不足导致的,具体方法是让神经网络在每次训练时, 只迭代 同样的数据, 甚至每一个 batch 里面也是完全相同一模一样的数据, 再来看看 loss 值和 accurancy 值的变化. 如果这时候 loss 开始下降, accurancy 也开始上升了, 并且在训练了一段时间后神经网络能够正确地计算出所训练样本的输出值, 那么这种情况属于神经网络拟合能力不足. 因为对于大量的数据样本, 神经网络由于自身能力的原因无法去拟合全部数据, 只能拟合大量样本的整体特征, 或者少数样本的具体特征. 对于拟合能力不足问题, 通常可以增加网络层数, 增加神经元个数, 增大卷积核通道数等方法.
  • 如果不是拟合能力不足导致的欠拟合, 就需要尝试其他方法, 更改网络初始化方法(Xavier, MSRA), 更改优化器, 降低学习率

Dropout

  • 对于包含 N 个神经元节点的网络, 在Dropout的作用下可以看作为2N2^N2N个模型的集成, 这2N2^N2N个模型可认为是原始网络的子网络, 它们共享部分权值, 并且拥有相同的网络层数, 而模型整个的参数数目不变, 大大简化了运算.

实现方法

  • 直接 Dropout: 使用较少, AlexNet 使用的是这种Dropout. 该方法在训练阶段会按照保留概率来决定是否将神经元的激活值置为0. 同时, 为了保持训练阶段和测试阶段数值的一致性, 会在测试阶段对所有的计算结果乘以保留概率.
  • Inverted Dropout: 这是目前常用的方法. 该方法在训练阶段会按照保留概率来决定是否将神经元的激活值置为0, 并且, 在训练阶段会令输出值都会乘以1αdropout \frac{1}{\alpha_{\text {dropout }}}αdropout ​1​, 这样一来, 在训练阶段可以随时更改 dropout 的参数值, 而对于测试阶段来说, 无需对神经元进行任何额外处理, 所有的神经元都相当于适配了训练过程中 dropout 对参数数值大小带来的影响. 更优

附录

反向传播推导

  • 变量定义
  • wjklw_{j k}^{l}wjkl​ 表示第 (l−1)(l-1)(l−1) 层的第 kkk 个神经元连接到第 lll 层的第 jjj 个神经元的权重;
  • bjlb_{j}^{l}bjl​ 表示第 lll 层的第 jjj 个神经元的偏置
  • zjlz_{j}^{l}zjl​ 表示第 lll 层的第 jjj 个神经元的 临时输出值(未经过激活的), 即 zjl=∑kwjklakl−1+bjlz_{j}^{l}=\sum_{k} w_{j k}^{l} a_{k}^{l-1}+b_{j}^{l}zjl​=∑k​wjkl​akl−1​+bjl​
  • ajla_{j}^{l}ajl​ 表示第 lll 层的第 jjj 个神经元的输出, 即 ajl=σ(∑kwjklakl−1+bjl)a_{j}^{l}=\sigma\left(\sum_{k} w_{j k}^{l} a_{k}^{l-1}+b_{j}^{l}\right)ajl​=σ(∑k​wjkl​akl−1​+bjl​) 其中, σ\sigmaσ 表示激活函数.

平方误差损失函数

  • 推导
    C=12n∑x∥y(x)−aL(x)∥2∂C∂wjkl=∂C∂zjl⋅∂zjl∂wjkl=δjl⋅∂(wjklakl−1+bjl)∂wjkl=akl−1δjlC=\frac{1}{2 n} \sum_{x}\left\|y(x)-a^{L}(x)\right\|^{2} \\ \frac{\partial C}{\partial w_{j k}^{l}}=\frac{\partial C}{\partial z_{j}^{l}} \cdot \frac{\partial z_{j}^{l}}{\partial w_{j k}^{l}}=\delta_{j}^{l} \cdot \frac{\partial\left(w_{j k}^{l} a_{k}^{l-1}+b_{j}^{l}\right)}{\partial w_{j k}^{l}}=a_{k}^{l-1} \delta_{j}^{l} C=2n1​x∑​∥∥​y(x)−aL(x)∥∥​2∂wjkl​∂C​=∂zjl​∂C​⋅∂wjkl​∂zjl​​=δjl​⋅∂wjkl​∂(wjkl​akl−1​+bjl​)​=akl−1​δjl​
  • 解释: 前一层对应神经元的输出值乘以当前层对应节点的 “误差项”(损失函数对神经网络每一层临时输出值的梯度(注意是临时, 指未经激活的输出值))
    ∂C∂bjl=∂C∂zjl⋅∂zjl∂bjl=δjl⋅∂(wjklakl−1+bjl)∂bjl=δjl\frac{\partial C}{\partial b_{j}^{l}}=\frac{\partial C}{\partial z_{j}^{l}} \cdot \frac{\partial z_{j}^{l}}{\partial b_{j}^{l}}=\delta_{j}^{l} \cdot \frac{\partial\left(w_{j k}^{l} a_{k}^{l-1}+b_{j}^{l}\right)}{\partial b_{j}^{l}}=\delta_{j}^{l} ∂bjl​∂C​=∂zjl​∂C​⋅∂bjl​∂zjl​​=δjl​⋅∂bjl​∂(wjkl​akl−1​+bjl​)​=δjl​
  • 某一层某个神经元的偏置梯度, 等于 当前层对应节点的 “误差项”.
  • 误差项的推导:
    δjL=∂C∂zjL=∂C∂ajL⋅∂ajL∂zjL\delta_{j}^{L}=\frac{\partial C}{\partial z_{j}^{L}}=\frac{\partial C}{\partial a_{j}^{L}} \cdot \frac{\partial a_{j}^{L}}{\partial z_{j}^{L}} δjL​=∂zjL​∂C​=∂ajL​∂C​⋅∂zjL​∂ajL​​
  • 反向传播
    δjl=∂C∂zjl=∑k∂C∂zkl+1⋅∂zkl+1∂ajl⋅∂ajl∂zjl=∑kδkl+1⋅∂(wkjl+1ajl+bkl+1)∂ajl⋅σ′(zjl)=∑kδkl+1⋅wkjl+1⋅σ′(zjl)\delta_{j}^{l}=\frac{\partial C}{\partial z_{j}^{l}}=\sum_{k} \frac{\partial C}{\partial z_{k}^{l+1}} \cdot \frac{\partial z_{k}^{l+1}}{\partial a_{j}^{l}} \cdot \frac{\partial a_{j}^{l}}{\partial z_{j}^{l}} \\ =\sum_{k} \delta_{k}^{l+1} \cdot \frac{\partial\left(w_{k j}^{l+1} a_{j}^{l}+b_{k}^{l+1}\right)}{\partial a_{j}^{l}} \cdot \sigma^{\prime}\left(z_{j}^{l}\right) \\ \quad=\sum_{k} \delta_{k}^{l+1} \cdot w_{k j}^{l+1} \cdot \sigma^{\prime}\left(z_{j}^{l}\right) δjl​=∂zjl​∂C​=k∑​∂zkl+1​∂C​⋅∂ajl​∂zkl+1​​⋅∂zjl​∂ajl​​=k∑​δkl+1​⋅∂ajl​∂(wkjl+1​ajl​+bkl+1​)​⋅σ′(zjl​)=k∑​δkl+1​⋅wkjl+1​⋅σ′(zjl​)
  • 则:δl=((wl+1)Tδl+1)⊙σ′(zl)\delta^{l}=\left(\left(w^{l+1}\right)^{T} \delta^{l+1}\right) \odot \sigma^{\prime}\left(z^{l}\right)δl=((wl+1)Tδl+1)⊙σ′(zl)

伪代码

  • 1 输入训练集
    对于训练集中的每个样本 xxx ,设置输入层对应的激活值 a1a^{1}a1
  • 2 计算前向传播过程
    zl=wlal−1+bl,al=σ(zl)z^{l}=w^{l} a^{l-1}+b^{l}, a^{l}=\sigma\left(z^{l}\right) zl=wlal−1+bl,al=σ(zl)
  • 3 计算输出层误差项
    δL=ΔaC⊙σ′(zL)\delta^{L}=\Delta_{a} C \odot \sigma^{\prime}\left(z^{L}\right) δL=Δa​C⊙σ′(zL)
  • 4 计算每一层的误差项
    δl=((wl+1)Tδl+1)⊙σ′(zl)\delta^{l}=\left(\left(w^{l+1}\right)^{T} \delta^{l+1}\right) \odot \sigma^{\prime}\left(z^{l}\right) δl=((wl+1)Tδl+1)⊙σ′(zl)
  • 5 使用梯度下降, 更新参数:
    wl=wl−ηm∑xδx,l(ax,l−1)Tbl=bl−ηm∑xδx,lw^{l}=w^{l}-\frac{\eta}{m} \sum_{x} \delta^{x, l}\left(a^{x, l-1}\right)^{T} \\ b^{l}=b^{l}-\frac{\eta}{m} \sum_{x} \delta^{x, l} wl=wl−mη​x∑​δx,l(ax,l−1)Tbl=bl−mη​x∑​δx,l

黄金时代 —— 深度学习 (基础)相关推荐

  1. 资源 | Intel发布AI免费系列课程3部曲:机器学习基础、深度学习基础以及TensorFlow基础

    翻译 | AI科技大本营(公众号ID:rgznai100) 校对 | 成龙 编辑 | 明明 Intel于近期发布了三门AI系列的免费课程,分别是关于机器学习基础.深度学习基础.TensorFlow基础 ...

  2. 深度估计相关原理(计算机视觉和深度学习基础)

    今天来和大家介绍一下深度估计涉及到的理论知识点,包括计算机视觉基础和深度学习基础. 一.计算机视觉基础 1.1. 针孔相机模型 相机模型,是指采用一个几何模型来描述三维世界中的坐标点映射到二维图像平面 ...

  3. 深度学习基础(基本概念、优化算法、初始化、正则化等)

    2020-04-25 16:29:09 引言 深度学习目前已成为发展最快.最令人兴奋的机器学习领域之一,许多卓有建树的论文已经发表,而且已有很多高质量的开源深度学习框架可供使用.然而,论文通常非常简明 ...

  4. 【完结】有三AI阿里云的深度学习基础课程暂时完结,欢迎扩散学习

    2021年3月份有三AI与阿里天池联合推出了深度学习系列课程, 课程内容包括人工智能与深度学习发展背景,深度学习典型应用,卷积神经网络,循环神经网络,生成对抗网络,深度学习开源框架等内容,目前已经基本 ...

  5. [深度学习基础] 深度学习基础及数学原理

    图像分类 (image classification) 问题是指, 假设给定一系列离散的类别(categories)(如猫, 狗, 飞机, 货车, ...), 对于给定的图像, 从这些类别中赋予一个作 ...

  6. 人工智能 - paddlepaddle飞桨 - 深度学习基础教程 - 编程指南

    编程指南 目前飞桨(PaddlePaddle,以下简称Paddle)已经同时支持动态图和静态图两种编程方式, 本文主要侧重于介绍静态图的编程方法,关于动态图编程方法,请参考动态图机制-DyGraph. ...

  7. 人工智能 - paddlepaddle飞桨 - 深度学习基础教程 - 个性化推荐

    人工智能 - paddlepaddle飞桨 - 深度学习基础教程 - 个性化推荐 本教程源代码目录在book/recommender_system,初次使用请您参考Book文档使用说明. 说明: 硬件 ...

  8. Deep learning with python notebooks 笔记 第一章 深度学习基础

    第一章 深度学习基础 好的图表比文字传达的信息量多 图1-1帮助理清了人工智能.机器学习和深度学习之间的关系. 图1-2 清晰的阐述了经典程序设计范式和机器学习一种新的编程范式的不同.两种范式引出了两 ...

  9. 深度学习基础 | NLP大魔王 · BERT

    ‍作者 | Chilia 整理 | NewBeeNLP‍ 首先,请阅读先修知识: 深度学习基础 | 从Language Model到RNN 深度学习基础 | RNN家族全面解析 深度学习基础 | Se ...

最新文章

  1. 二叉树的路径(根节点到叶节点)Binary Tree Paths
  2. python+mysql:实现一千万条数据插入数据库
  3. 什么是透传通道?(透明传输通道,就是当中继使)
  4. 重庆大学光电工程学院 贾旭滨 对 “句柄” “指针” 有下面的描述(AfxGetMainWnd GetSafeHwnd() AfxGetAppName() AfxGetThread)...
  5. 大道至简读书笔记02
  6. dojo中的dojoConfig配置
  7. 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序。
  8. 照相机的成像原理,镜头和单反相机的认识
  9. Vue学习---插槽篇
  10. 网络原理——基础知识
  11. 十门峡旅游攻略:临安十门峡的春天
  12. java生成迷宫_java怎么生成迷宫地图
  13. unityshader 晶格化消散
  14. JAVA系列 IO流 知识结构整理 建立合理的知识框架逻辑 输入输出流 理顺你的思维架构Fileoutput inputStream FileWriter FIleReader结构整理
  15. 使用fate框架训练流程
  16. python学习------面向对象的程序设计
  17. 简易四则运算计算器(C51单片机实现)
  18. OpenCPN安装与海图下载探索
  19. IT 专业人士的必备远程工具——radmin
  20. Ajax局部刷新后,重新加载百度分享

热门文章

  1. c语言中求字节的运算符是,初学者单片机C语言运算符
  2. python网络编程/套接字和DNS(验证加进一步应用)
  3. python compiler.ast_ast --- 抽象语法树 — Python 3.7.9 文档
  4. 天下游安装方式和充值卡激活方式‘’
  5. 写一个python脚本控制微信企业版的群聊机器人完成番茄工作法的闹钟通知
  6. 2015华为实习生招聘机试、面试记录
  7. like 和 = 的区别
  8. 一天的时间戳是多少?
  9. 微商引流可以用哪些渠道?微商有哪些渠道可以精准引流
  10. 【银行测试】必看的四类题型:这可是最经典的一套题目了