2024年大数据最全算法工程师面试八股(搜广推方向)_算法岗八股(1),2024年最新大数据开发最新面试题

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

XGBoost对缺失数据有特定的处理方法, 因此,对于有缺失值的数据在经过缺失处理后:

  • 当数据量很小时,优先用朴素贝叶斯
  • 数据量适中或者较大,用树模型,优先XGBoost
  • 数据量较大,也可以用神经网络
  • 避免使用距离度量相关的模型,如KNN和SVM

XGBoost和RF单棵树哪个更深?

RF单颗树更深。Boosting主要关注降低偏差,因此Boosting能基于泛化性能相当弱的学习器构建出很强的集成;Bagging主要关注降低方差,因此它在不剪枝的决策树、神经网络等学习器上效用更为明显。
Bagging算法会并行地训练很多不同的分类器来降低方差variance:

E

[

h

E

(

h

)

]

E[h−E(h)]

E[h−E(h)],因为采用了相互独立的基分类器多了以后,h的值自然就会靠近E(h)。所以对于每个基分类器来说,目标就是降低偏差bias,所以会采用深度很深甚至不剪枝的决策树。对于Boosting来说,每一步会在上一轮的基础上更加拟合原数据,所以可以保证偏差bias,所以对于每个基分类器来说,问题就在于如何选择variance更小的分类器,即更简单的分类器,所以我们选择了深度很浅的决策树。

XGBoost和GBDT

  • 梯度提升决策树:都属于梯度提升决策树算法。集成学习方法,组合多个决策树逐步减小预测误差,提高模型性能。
  • 目标函数:使用相同的目标函数,通过最小化残差的平方和优化模型。每一轮迭代中,都会构建一个新的决策树来拟合前面模型的残差,以纠正之前模型的预测误差。
  • 特征工程:都支持类别型特征和缺失值的处理。在构建决策树时能自动处理类别型特征,不需要独热编码等转换。

区别:

  • 基分类器:XGBoost基分类器不仅支持CART决策树,还支持线性分类器,此时XGBoost相当于带L1和L2正则化项的Logistic回归(分类问题)或者线性回归(回归问题)。
  • 正则化策略:XGBoost引入正则化防止过拟合,包括L1和L2正则化控制模型的复杂度。
  • 算法优化:XGBoost使用近似贪心算法选择最佳分裂点,使用二阶导数信息更精准逼近真实的损失函数,来提高模型的拟合能力。支持自定义损失函数,只要损失函数一阶、二阶可导,可扩展性好。
  • 样本权重:XGBoost引入样本权重概念,对不同样本赋予不同权重,从而对模型训练产生不同影响。在处理不平衡数据集或处理样本噪声时非常有用。
  • 并行计算:XGBoost在多个线程上同时进行模型训练,使用并行计算和缓存优化加速训练过程。不是tree维度的并行,而是特征维度的并行。XGBoost预先将每个特征按特征值排好序,存储为块结构,分裂结点时可以采用多线程并行查找每个特征的最佳分割点,极大提升训练速度。GBDT通常是顺序训练的,无法直接进行并行化。
  • 列抽样:XGBoost支持列采样,与随机森林类似,用于防止过拟合。

XGBoost和LightGBM

  • 梯度提升决策树:都属于梯度提升决策树算法。集成学习方法,组合多个决策树逐步减小预测误差,提高模型性能。
  • 特征工程:都支持类别型特征和缺失值的处理。在构建决策树时能自动处理类别型特征,不需要独热编码等转换。还能处理带缺失值的数据。
  • 分布式训练:都支持分布式训练,可在分布式计算框架(如Spark)上运行。

区别:

  • 算法速度:LightGBM在训练和预测速度上更快。LightGBM采用基于梯度的直方图决策树算法来加速训练过程,减少内存使用和计算复杂度。
  • 内存占用:LightGBM具有更低的内存占用,适用于处理大规模数据集。使用了互斥特征捆绑算法和直方图算法来减少内存使用,提高了算法的扩展性。
  • 正则化策略:都支持正则化策略来防止过拟合。XGBoost采用基于树的正则化(如最大深度、最小子样本权重等),LightGBM采用基于叶子节点的正则化(如叶子数、最小叶子权重等)。
  • 数据并行和特征并行:XGBoost使用数据并行化,将数据划分为多个子集,每个子集在不同的计算节点上进行训练。LightGBM使用特征并行化,将特征划分为多个子集,每个子集在不同的计算节点上进行训练。
  1. 树生长策略:XGB采用level-wise(按层生长)的分裂策略,LGB采用leaf-wise的分裂策略。XGB对每一层所有节点做无差别分裂,但是可能有些节点增益非常小,对结果影响不大,带来不必要的开销。Leaf-wise是在所有叶子节点中选取分裂收益最大的节点进行的,但是很容易出现过拟合问题,所以需要对最大深度做限制 。
  2. 分割点查找算法:XGB使用特征预排序算法,LGB使用基于直方图的切分点算法,优势如下:
    • 减少内存占用,比如离散为256个bin时,只需要用8位整形就可以保存一个样本被映射为哪个bin(这个bin可以说就是转换后的特征),对比预排序的exact greedy算法来说(用int_32来存储索引+ 用float_32保存特征值),可以节省7/8的空间。
    • 计算效率提高,预排序的Exact greedy对每个特征都需要遍历一遍数据,并计算增益,复杂度为𝑂(#𝑓𝑒𝑎𝑡𝑢𝑟𝑒×#𝑑𝑎𝑡𝑎)。而直方图算法在建立完直方图后,只需要对每个特征遍历直方图即可,复杂度为𝑂(#𝑓𝑒𝑎𝑡𝑢𝑟𝑒×#𝑏𝑖𝑛𝑠)。
    • LGB还可以使用直方图做差加速,一个节点的直方图可以通过父节点的直方图减去兄弟节点的直方图得到,从而加速计算。实际上xgboost的近似直方图算法也类似于LGB这里的直方图算法,但xgboost的近似算法比LGB慢很多。XGB在每一层都动态构建直方图,XGB的直方图算法不是针对某个特定的feature,而是所有feature共享一个直方图(每个样本的权重是二阶导),所以每一层都要重新构建直方图,而LGB中对每个特征都有一个直方图,所以构建一次直方图就够
  3. 支持离散变量:XGB无法直接输入类别型变量,需要事先对类别型变量进行编码(如独热编码),而LightGBM可以直接处理类别型变量。
  4. 缓存命中率:XGB使用Block结构的缺点是取梯度时,是通过索引来获取的,而这些梯度的获取顺序是按照特征的大小顺序,导致非连续的内存访问,使得CPU cache缓存命中率低,影响算法效率。而LGB是基于直方图分裂特征的,梯度信息都存储在一个个bin中,所以访问梯度是连续的,缓存命中率高。
  5. 并行策略不同:
    • 特征并行 :LGB特征并行的前提是每个worker留有一份完整的数据集,但是每个worker仅在特征子集上进行最佳切分点的寻找;worker之间需要相互通信,通过比对损失来确定最佳切分点;然后将这个最佳切分点的位置进行全局广播,每个worker进行切分即可。XGB的特征并行与LGB的最大不同在于XGB每个worker节点中仅有部分的列数据,也就是垂直切分,每个worker寻找局部最佳切分点,worker之间相互通信,然后在具有最佳切分点的worker上进行节点分裂,再由这个节点广播一下被切分到左右节点的样本索引号,其他worker才能开始分裂。二者的区别就导致了LGB中worker间通信成本明显降低,只需通信一个特征分裂点即可,而XGB中要广播样本索引。
    • 数据并行 :当数据量很大,特征相对较少时,可采用数据并行策略。LGB中先对数据水平切分,每个worker上的数据先建立起局部的直方图,然后合并成全局的直方图,采用直方图相减的方式,先计算样本量少的节点的样本索引,然后直接相减得到另一子节点的样本索引,这个直方图算法使得worker间的通信成本降低一倍,因为只用通信以此样本量少的节点。XGB中的数据并行也是水平切分,然后单个worker建立局部直方图,再合并为全局,不同在于根据全局直方图进行各个worker上的节点分裂时会单独计算子节点的样本索引,因此效率贼慢,每个worker间的通信量也就变得很大。
    • 投票并行(LGB):当数据量和维度都很大时,选用投票并行,该方法是数据并行的一个改进。数据并行中的合并直方图的代价相对较大,尤其是当特征维度很大时。大致思想是:每个worker首先会找到本地的一些优秀的特征,然后进行全局投票,根据投票结果,选择top的特征进行直方图的合并,再寻求全局的最优分割点。

XGBoost面试题整理

AUC

  • 定义:ROC曲线下的面积(横坐标为假阳性率FPR,纵坐标为真阳性率TPR/召回),ROC曲线对于模型预估的一个正例,如果真实标签是正例,就往上走,如果是负例,就往左走,遍历完所有样本形成的曲线就是ROC曲线。

  • 含义:随机抽出一对样本(一个正样本,一个负样本),然后用训练得到的分类器来对这两个样本进行预测,预测得到正样本的概率大于负样本概率的概率。

  • 计算方法:

    1. KaTeX parse error: Undefined control sequence: \* at position 38: …本}, P_{负样本})}{M\̲*̲N}。在KaTeX parse error: Undefined control sequence: \* at position 2: M\̲*̲N对样本里(

    M

    M

    M和

    N

    N

    N分别表示正负样本的数量),统计正样本的预测概率大于负样本的预测概率的个数。
    2. A

    U

    C

    =

    i

    正样本

    r

    a

    n

    k

    (

    i

    )

    M

    (

    M

    1

    )

    2

    M

    N

    AUC=\frac{\sum_{i\in 正样本}rank(i)-\frac{M(M+1)}{2}}{M*N}

    AUC=M∗N∑i∈正样本​rank(i)−2M(M+1)​​。

    r

    a

    n

    k

    (

    i

    )

    rank(i)

    rank(i)表示按照预估概率升序排序后正样本

    i

    i

    i的排序编号。对预估概率得分相同,将其排序编号取平均作为新的排序编号。

  • 参考:

深度学习

激活函数

激活函数的主要作用是引入非线性变换,没有激活函数,神经网络层数再多,也只是简单的线性变换,无法处理复杂任务。

  1. 阶跃函数:用于二分类,但导数始终为0,不能用于反向传播,理论意义大于实际意义。
  2. sigmoid函数:

f

(

x

)

=

1

1

e

x

f(x)=\frac{1}{1+e^{-x}}

f(x)=1+e−x1​,用于二分类,X靠近0的时候,一点小小的值变化也能引起Y很大变化,说明函数区域将数值推向极值,很适合二分类。X远离0时,X值变化对Y起作用很小,函数的导数变化也很小,在反向传播中几乎起不到更新梯度的作用;且sigmoid函数只能得到正值,在很多情况下不适用。
3. tanh函数:

f

(

x

)

=

e

x

e

x

e

x

e

x

f(x)=\frac{e{x}-e{-x}}{e{x}+e{-x}}

f(x)=ex+e−xex−e−x​,对sigmoid函数的改进,函数值在(-1, 1)之间,改善了sigmoid函数只能得到正值的缺点,其他特点与sigmoid函数一模一样。
4. ReLU函数:近年使用广泛,优点是当输入值是负值时,输出值为0,意味着一段时间内只有部分神经元被激活,神经网络的这种稀疏性使其变得高效且易于计算。但X小于0时函数梯度为0,意味着反向传播时权重得不到更新,那么正向传播过程中输出值为0的神经元永远得不到激活,变成了死神经元。
5. Leaky ReLU函数:解决了死神经元的问题。
6. Softmax函数:可以看作是用作多分类的激活函数,将神经网络的输出值变成概率。
7. 线性激活函数:效果等同于未激活,在Keras中不激活时就是用f(x)=x这一激活函数。二分类时用sigmoid函数和tanh函数,但存在梯度消失问题时应避免使用这两种函数。ReLU函数适用于绝大多数情况,如果存在梯度不更新的问题时可以用Leaky ReLU函数替代。

Softmax函数及求导

Softmax函数通常用于多分类问题中,它将一个包含任意实数的 K 维向量(K 是类别数量)映射为一个概率分布,每个类别的预测概率值都在 0 到 1 之间,所有类别的概率总和为 1。Softmax函数的作用是将原始得分转换为概率值,使得模型的输出更符合实际的概率分布。函数公式:

S

i

=

e

a

i

k

=

1

K

e

a

k

S_i=\frac{e^{a_i}}{\sum ^K_{k=1} e^{a_k}}

Si​=∑k=1K​eak​eai​​
其中,

a

a

a 是输入向量,上述公式表示第

i

i

i 个类别的输出概率。函数求导分类讨论:

i

=

j

i=j

i=j时:

S

i

a

j

=

e

a

i

e

a

j

e

a

i

2

=

S

i

S

i

S

j

\frac{\partial S_i}{\partial a_j}=\frac{e{a_i}\sum-e{a_j}e^{a_i}}{\sum ^2}=S_i-S_iS_j

∂aj​∂Si​​=∑2eai​∑−eaj​eai​​=Si​−Si​Sj​

i

j

i\not =j

i=j时:

S

i

a

j

=

0

e

a

j

e

a

i

2

=

S

i

S

j

\frac{\partial S_i}{\partial a_j}=\frac{0-e{a_j}e{a_i}}{\sum ^2}=-S_iS_j

∂aj​∂Si​​=∑20−eaj​eai​​=−Si​Sj​

Softmax函数及其导数

优化器

  • 梯度下降法(Gradient Descent):最基本最常用的优化算法。通过计算损失函数关于参数的梯度,以负梯度方向更新参数,使损失函数最小化。梯度下降法有多个变种,如批量梯度下降、随机梯度下降和小批量梯度下降。

    • g

    t

    =

    f

    (

    θ

    t

    1

    )

    ,

    θ

    t

    =

    η

    g

    t

    g_t=▽f(θ_{t−1}), △θ_t=−η∗g_t

    gt​=▽f(θt−1​),△θt​=−η∗gt​

    • 批梯度下降:每次使用所有数据用于更新梯度,使得梯度总是朝着最小的方向更新,但数据量很大的时候更新速度太慢,容易陷入局部最优。
    • 随机梯度下降:每次使用一条数据来更新梯度,在梯度更新过程中梯度可能上升也可能下降,但总的来说梯度还是朝着最低的方向前进;最后梯度会在极小值附近徘徊。随机梯度下降的梯度更新速度快于批梯度下降,且由于每次梯度的更新方向不确定,陷入局部最优的时候有可能能跳出该局部极小值。
    • mini-batch梯度下降:介于批梯度下降和随机梯度下降之间,每次用若干条数据更新梯度。mini-batch梯度下降可以使用矩阵的方式来计算梯度,因此速度快于随机梯度下降,且同样具有跳出局部最优的特点。
  • 动量优化器(Momentum):引入动量项加速收敛过程。在参数更新时考虑之前的更新方向,在梯度方向上积累速度。如果本次梯度衰减方向与上一次相同,则可以加速梯度下降;如果不一致,则抑制梯度的改变。有助于在平坦区域中加快学习速度并减少震荡。

    • m

    t

    =

    μ

    m

    t

    1

    (

    1

    μ

    )

    g

    t

    m_t=μ∗m_{t−1}+(1−μ)g_t

    mt​=μ∗mt−1​+(1−μ)gt​

    θ

    t

    =

    η

    m

    t

    △θ_t=−η∗m_t

    △θt​=−η∗mt​

  • 自适应动量估计(Adaptive Moment Estimation,Adam):基于一阶矩估计和二阶矩估计的自适应优化器。结合了动量和学习率衰减机制,并具有自适应学习率调整。在很多情况下能快速收敛。

  • 自适应学习率优化器(Adagrad、RMSProp):Adagrad和RMSProp是常用的自适应学习率优化器。Adagrad适应性地调整参数的学习率,对于稀疏梯度的问题表现较好。RMSProp通过指数加权平均的方式动态调整学习率,适用于非平稳或具有较大梯度变化的问题。用初始学习率除以通过衰减系数控制的梯度平方和的平方根,相当于给每个参数赋予了各自的学习率。梯度相对平缓的地方,累积梯度小,学习率会增大;梯度相对陡峭的地方,累积梯度大,学习率会减小。从而加速训练。

    • RMSprop:

    n

    t

    =

    ν

    n

    t

    1

    (

    1

    ν

    )

    g

    t

    2

    n_t=νn_{t−1}+(1−ν)g_t^2

    nt​=νnt−1​+(1−ν)gt2​

    θ

    t

    =

    η

    n

    t

    ϵ

    g

    t

    △θ_t=−\frac{η}{\sqrt{n_t+ϵ}}*g_t

    △θt​=−nt​+ϵ

    ​η​∗gt​

  • Adam:本质上是带有动量项的RMSprop,结合了两者的优点,可以为不同的参数计算不同的自适应学习率,实践中常用。

    • m

    t

    =

    μ

    m

    t

    1

    (

    1

    μ

    )

    g

    t

    m_t=μm_{t−1}+(1−μ)g_t

    mt​=μmt−1​+(1−μ)gt​

    • n

    t

    =

    ν

    n

    t

    1

    (

    1

    ν

    )

    g

    t

    2

    n_t=νn_{t−1}+(1−ν)g_t^2

    nt​=νnt−1​+(1−ν)gt2​

    • m

    ^

    t

    =

    m

    t

    1

    μ

    t

    \hat m_t=\frac{m_t}{1−μ^t}

    m^t​=1−μtmt​​

    • n

    ^

    t

    =

    n

    t

    1

    ν

    t

    \hat n_t=\frac{n_t}{1−ν^t}

    n^t​=1−νtnt​​

    θ

    t

    =

    η

    n

    ^

    t

    ϵ

    △θ_t=-\frac{η}{\sqrt{\hat n_t+ϵ}}

    △θt​=−n^t​+ϵ

    ​η​

  • AdamW:Adam的变种,主要用于解决权重衰减(weight decay)在Adam中的问题。在计算梯度更新时,将权重衰减的计算从梯度中分离出来,并将其应用于参数更新之前。使得权重衰减仅影响参数的更新方向,而不会降低参数的更新速度。优势在于更好地控制权重衰减的影响,减轻过度正则化的问题,使模型更易优化和训练。

残差连接

Residual Connection跳跃连接技术,在模型中将输入信号与输出信号进行直接连接。作用:

  • 促进信息传递:使模型更容易传递信息和梯度,避免梯度消失或梯度爆炸,特别是在处理深层网络时。
  • 简化优化问题:可以简化优化问题,使模型更易于优化和训练。
  • 提高模型表达能力:允许模型保留更多的低层特征信息,使模型更好地捕捉输入序列中的细节和上下文信息。

DNN,CNN,RNN对比

请添加图片描述

池化层反向传播

反向传播在经过池化层的时候梯度的数量发生了变化。如2*2的池化操作,第L+1层梯度数量是L层的1/4,所以每个梯度要对应回4个梯度。

  • mean_pooling:正向传播时取周围4个像素的均值,所以反向传播将梯度平均分成4分,再分给上一层。
  • max_pooling:正向传播时取周围4个像素的最大值保留,其余的值丢弃,所以反向传播时将梯度对应回最大值的位置,其他位置取0。一般来说,为了知道最大值的位置,深度学习框架在正向传播时就用max_id来记录4个像素中最大值的位置。

浅层、深层神经网络差别

神经网络中,权重参数是给数据做线性变换,而激活函数给数据带来的非线性变换。增加某一层神经元数量是在增加线性变换的复杂性,而增加网络层数是在增加非线性变换的复杂性。理论上,浅层神经网络就能模拟任何函数,但需要巨大的数据量,而深层神经网络可以用更少的数据量来学习到更好的拟合。

防止过拟合

过拟合是模型学习能力太强大,把部分数据的不太一般的特性都学到了,并当成了整个样本空间的特性。防过拟合方法:

  • L2正则化。原loss是

L

0

L_0

L0​,加入L2正则化后loss是

L

0

λ

2

n

W

2

L_0+\frac{\lambda}{2n}||W||^2

L0​+2nλ​∣∣W∣∣2,L的梯度是

L

W

=

L

0

W

λ

n

W

\frac{\partial{L}}{\partial{W}}=\frac{\partial{L_0}}{\partial{W}}+\frac{\lambda}{n}{W}

∂W∂L​=∂W∂L0​​+nλ​W,

L

b

=

L

0

b

\frac{\partial{L}}{\partial{b}}=\frac{\partial{L_0}}{\partial{b}}

∂b∂L​=∂b∂L0​​,可以看出,L2正则化只对W有影响,对b没有影响。而加入L2正则化后的梯度更新:

W

=

W

α

(

L

0

W

λ

n

W

)

=

(

1

α

λ

n

)

W

α

L

0

W

W=W-\alpha(\frac{\partial{L_0}}{\partial{W}}+\frac{\lambda}{n}{W})=(1-\frac{\alpha\lambda}{n})W-\alpha\frac{\partial{L_0}}{\partial{W}}

W=W−α(∂W∂L0​​+nλ​W)=(1−nαλ​)W−α∂W∂L0​​,相比于原梯度更新公式,改变的是

(

1

2

α

λ

)

W

(1-2\alpha\lambda)W

(1−2αλ)W这里,而由于

α

λ

n

\alpha、\lambda、n

α、λ、n都是正数,所以

(

1

α

λ

n

)

<

1

(1-\frac{\alpha\lambda}{n})<1

(1−nαλ​)<1。因此,L2正则化使得反向传播更新参数时W参数比不添加正则项更小。在过拟合中,由于对每个数据都拟合得很好,所以函数的变化在小范围内往往很剧烈,而要使函数在小范围内剧烈变化,就是要W参数值很大。L2正则化抑制了这种小范围剧烈变化,使得拟合程度“刚刚好”。

  • L1正则化。原loss是

L

0

L_0

L0​,加入L1正则化后loss是

L

=

L

0

λ

n

W

L=L_0+\frac{\lambda}{n}|W|

L=L0​+nλ​∣W∣, L的梯度是

L

W

=

L

0

W

λ

n

W

\frac{\partial{L}}{\partial{W}}=\frac{\partial{L_0}}{\partial{W}}+\frac{\lambda}{n}|W|

∂W∂L​=∂W∂L0​​+nλ​∣W∣,

L

b

=

L

0

b

\frac{\partial{L}}{\partial{b}}=\frac{\partial{L_0}}{\partial{b}}

∂b∂L​=∂b∂L0​​, 可以看出,L1正则化只对W有影响,对b没有影响。而加入L1正则化后的梯度更新:

W

=

W

α

(

L

0

W

λ

n

W

)

=

W

λ

n

W

α

L

0

W

W=W-\alpha(\frac{\partial{L_0}}{\partial{W}}+\frac{\lambda}{n}{|W|})=W-\frac{\lambda}{n}|W|-\alpha\frac{\partial{L_0}}{\partial{W}}

W=W−α(∂W∂L0​​+nλ​∣W∣)=W−nλ​∣W∣−α∂W∂L0​​, 如果W为正,相对于原梯度就减小;如W为负,相对于原梯度就增大。所以,L1正则化使得参数W在更新时向0靠近使得参数W具有稀疏性。而权重趋近0,也就相当于减小了网络复杂度,防止过拟合。

  • Dropout。每次训练时,有一部分神经元不参与更新,而且每次不参与更新的神经元是随机的。随着训练的进行,每次用神经元就能拟合出较好的效果,少数拟合效果不好的也不会对结果造成太大的影响。
  • 增大数据量。过拟合是学习到了部分数据集的特有特征,那么增大数据集就能有效的防止这种情况出现。
  • Early stop。数据分为训练集、验证集和测试集,每个epoch后都用验证集验证一下,如果随着训练的进行训练集loss持续下降,而验证集loss先下降后上升,说明出现了过拟合,应该立即停止训练。
  • Batch Normalization。每次都用一个mini_batch的数据来计算均值和反差,这与整体的均值和方差存在一定偏差,从而带来了随机噪声,起到了与Dropout类似的效果,从而减轻过拟合。
  • L1 / L2对比:
    • L1(拉格朗日Lasso)正则假设参数先验分布是Laplace分布,可以使权重稀疏,保证模型的稀疏性,某些参数等于0,产生稀疏权值矩阵,用于特征选择;
    • L2(岭回归Ridge)正则假设参数先验分布是Gaussian分布,可以使权重平滑,保证模型的稳定性,也就是参数的值不会太大或太小。
    • 在实际使用中,如果特征是高维稀疏的,则使用L1正则;如果特征是低维稠密的,则使用L2正则

BN层的计算

神经网络反向传播后每一层的参数都会发生变化,在下一轮正向传播时第

l

l

l 层的输出值

Z

l

=

W

A

l

1

b

Zl=W\cdot{A}{l-1}+b

Zl=W⋅Al−1+b 也会发生变化,导致第

l

l

l 层的

A

l

=

r

e

l

u

(

Z

l

)

Al=relu(Zl)

Al=relu(Zl) 发生变化。而

A

l

A^l

Al 作为第

l

1

l+1

l+1 层的输入,

l

1

l+1

l+1 就需要去适应适应这种数据分布的变化,这就是神经网络难以训练的原因之一。
为此,Batch Normalization的做法是调整数据的分布来改变这一现象,具体做法如下:

  • 训练: 一般每次训练数据都是一个batch,假设

m

=

b

a

t

c

h

_

s

i

z

e

m=batch\_size

m=batch_size,则:
1. 计算各个特征均值

 μ 
 
 
 = 
 
 
 
 1 
 
 
 m 
 
 
 
 
 ∑ 
 
 
 
 i 
 
 
 = 
 
 
 1 
 
 
 
 m 
 
 
 
 
 z 
 
 
 i 
 
 
 
 
 \mu=\frac{1}{m}\sum\_{i=1}^{m}z^i 
 
 
 μ=m1​∑i=1m​zi,其中  
 
 
 
 
 
 z 
 
 
 i 
 
 
 
 
 z^i 
 
 
 zi 表示第  
 
 
 
 
 i 
 
 
 
 i 
 
 
 i 条数据
2. 计算方差  
 
 
 
 
 
 σ 
 
 
 2 
 
 
 
 = 
 
 
 
 1 
 
 
 m 
 
 
 
 
 ∑ 
 
 
 
 i 
 
 
 = 
 
 
 1 
 
 
 
 m 
 
 
 
 ( 
 
 
 
 z 
 
 
 i 
 
 
 
 − 
 
 
 μ 
 
 
 
 ) 
 
 
 2 
 
 
 
 
 \sigma^2=\frac{1}{m}\sum\_{i=1}^{m}(z^i-\mu)^2 
 
 
 σ2=m1​∑i=1m​(zi−μ)2
3. 归一化后的  
 
 
 
 
 
 Z 
 
 
 
 n 
 
 
 o 
 
 
 r 
 
 
 m 
 
 
 
 i 
 
 
 
 = 
 
 
 
 
 
 z 
 
 
 i 
 
 
 
 − 
 
 
 μ 
 
 
 
 
 
 
 σ 
 
 
 2 
 
 
 
 + 
 
 
 ϵ 
 
 
 
 
 
 
 Z\_{norm}^i=\frac{z^i-\mu}{\sqrt{\sigma^2+\epsilon}} 
 
 
 Znormi​=σ2+ϵ


​zi−μ​, 
 
 
 
 
 ϵ 
 
 
 
 \epsilon 
 
 
 ϵ 表示一个极小值,防止计算出现Nan
4. 这样调整分布后能加速训练,但之前层学习到的参数信息可能会丢失,所以加入参数  
 
 
 
 
 γ 
 
 
 
 \gamma 
 
 
 γ、 
 
 
 
 
 β 
 
 
 
 \beta 
 
 
 β 调整:  
 
 
 
 
 
 
 Z 
 
 
 ~ 
 
 
 
 i 
 
 
 
 = 
 
 
 γ 
 
 
 
 Z 
 
 
 
 n 
 
 
 o 
 
 
 r 
 
 
 m 
 
 
 
 i 
 
 
 
 + 
 
 
 β 
 
 
 
 \widetilde{Z}^i=\gamma{Z\_{norm}^i}+\beta 
 
 
 Z


i=γZnormi​+β
  • 反向传播:

L

Z

n

o

r

m

i

=

L

Z

~

i

λ

\frac{\partial{L}}{\partial{Z_{norm}i}}=\frac{\partial{L}}{\partial{\widetilde{Z}i}}\lambda

∂Znormi​∂L​=∂Z

i∂L​λ

L

λ

=

L

Z

~

i

Z

n

o

r

m

i

\frac{\partial{L}}{\partial\lambda}=\frac{\partial{L}}{\partial{\widetilde{Z}i}}Z_{norm}i

∂λ∂L​=∂Z

i∂L​Znormi​

L

β

=

L

Z

~

i

\frac{\partial{L}}{\partial\beta}=\frac{\partial{L}}{\partial{\widetilde{Z}^i}}

∂β∂L​=∂Z

i∂L​

L

σ

2

=

L

Z

n

o

r

m

i

Z

n

o

r

m

i

σ

2

=

L

Z

n

o

r

m

i

(

1

2

)

(

σ

2

ϵ

)

3

2

\frac{\partial{L}}{\partial\sigma2}=\frac{\partial{L}}{\partial{Z_{norm}i}}\frac{\partial{Z_{norm}i}}{\partial\sigma2}=\frac{\partial{L}}{\partial{Z_{norm}i}}(-\frac{1}{2})(\sigma2+\epsilon)^{\frac{-3}{2}}

∂σ2∂L​=∂Znormi​∂L​∂σ2∂Znormi​​=∂Znormi​∂L​(−21​)(σ2+ϵ)2−3​

L

μ

=

L

Z

n

o

r

m

i

Z

n

o

r

m

i

μ

L

σ

2

σ

2

μ

=

L

Z

n

o

r

m

i

1

σ

2

ϵ

L

σ

2

2

i

=

1

m

(

z

i

μ

)

m

\frac{\partial{L}}{\partial\mu}=\frac{\partial{L}}{\partial{Z_{norm}i}}\frac{\partial{Z_{norm}i}}{\partial\mu}+\frac{\partial{L}}{\partial\sigma2}\frac{\partial{\sigma2}}{\partial{\mu}}=\frac{\partial{L}}{\partial{Z_{norm}i}}\frac{-1}{\sqrt{\sigma2+\epsilon}}+\frac{\partial{L}}{\partial\sigma2}\frac{-2\sum_{i=1}{m}(z^i-\mu)}{m}

∂μ∂L​=∂Znormi​∂L​∂μ∂Znormi​​+∂σ2∂L​∂μ∂σ2​=∂Znormi​∂L​σ2+ϵ

​−1​+∂σ2∂L​m−2∑i=1m​(zi−μ)​

L

Z

i

=

L

Z

n

o

r

m

i

Z

n

o

r

m

i

Z

i

L

σ

2

σ

2

Z

i

L

μ

μ

Z

i

=

L

Z

n

o

r

m

i

1

σ

2

ϵ

L

σ

2

2

(

Z

i

μ

)

m

L

μ

1

m

\frac{\partial{L}}{\partial{Zi}}=\frac{\partial{L}}{\partial{Z_{norm}i}}\frac{\partial{Z_{norm}i}}{\partial{Zi}}+\frac{\partial{L}}{\partial\sigma2}\frac{\partial{\sigma2}}{\partial{Zi}}+\frac{\partial{L}}{\partial\mu}\frac{\partial\mu}{\partial{Zi}}=\frac{\partial{L}}{\partial{Z_{norm}i}}\frac{1}{\sqrt{\sigma2+\epsilon}}+\frac{\partial{L}}{\partial\sigma2}\frac{2(Zi-\mu)}{m}+\frac{\partial{L}}{\partial\mu}\frac{1}{m}

∂Zi∂L​=∂Znormi​∂L​∂Zi∂Znormi​​+∂σ2∂L​∂Zi∂σ2​+∂μ∂L​∂Zi∂μ​=∂Znormi​∂L​σ2+ϵ

​1​+∂σ2∂L​m2(Zi−μ)​+∂μ∂L​m1​

  • 测试: 测试时一般每次只送入一个数据,计算其均值和方差都是有偏估计,但训练过程中保存了每一组batch每一层的均值和方差,则对每一层都可以使用均值和方差的无偏估计:

μ

t

e

s

t

=

E

(

μ

b

a

t

c

h

)

\mu_{test}=E(\mu_{batch})

μtest​=E(μbatch​)

σ

t

e

s

t

2

=

m

m

1

E

(

σ

b

a

t

c

h

2

)

\sigma2_{test}=\frac{m}{m-1}E(\sigma2_{batch})

σtest2​=m−1m​E(σbatch2​)
然后计算该层的输出:

Z

~

i

=

γ

Z

t

e

s

t

i

μ

σ

t

e

s

t

2

ϵ

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Z

n

o

r

m

i

1

σ

2

ϵ

L

σ

2

2

i

=

1

m

(

z

i

μ

)

m

\frac{\partial{L}}{\partial\mu}=\frac{\partial{L}}{\partial{Z_{norm}i}}\frac{\partial{Z_{norm}i}}{\partial\mu}+\frac{\partial{L}}{\partial\sigma2}\frac{\partial{\sigma2}}{\partial{\mu}}=\frac{\partial{L}}{\partial{Z_{norm}i}}\frac{-1}{\sqrt{\sigma2+\epsilon}}+\frac{\partial{L}}{\partial\sigma2}\frac{-2\sum_{i=1}{m}(z^i-\mu)}{m}

∂μ∂L​=∂Znormi​∂L​∂μ∂Znormi​​+∂σ2∂L​∂μ∂σ2​=∂Znormi​∂L​σ2+ϵ

​−1​+∂σ2∂L​m−2∑i=1m​(zi−μ)​

L

Z

i

=

L

Z

n

o

r

m

i

Z

n

o

r

m

i

Z

i

L

σ

2

σ

2

Z

i

L

μ

μ

Z

i

=

L

Z

n

o

r

m

i

1

σ

2

ϵ

L

σ

2

2

(

Z

i

μ

)

m

L

μ

1

m

\frac{\partial{L}}{\partial{Zi}}=\frac{\partial{L}}{\partial{Z_{norm}i}}\frac{\partial{Z_{norm}i}}{\partial{Zi}}+\frac{\partial{L}}{\partial\sigma2}\frac{\partial{\sigma2}}{\partial{Zi}}+\frac{\partial{L}}{\partial\mu}\frac{\partial\mu}{\partial{Zi}}=\frac{\partial{L}}{\partial{Z_{norm}i}}\frac{1}{\sqrt{\sigma2+\epsilon}}+\frac{\partial{L}}{\partial\sigma2}\frac{2(Zi-\mu)}{m}+\frac{\partial{L}}{\partial\mu}\frac{1}{m}

∂Zi∂L​=∂Znormi​∂L​∂Zi∂Znormi​​+∂σ2∂L​∂Zi∂σ2​+∂μ∂L​∂Zi∂μ​=∂Znormi​∂L​σ2+ϵ

​1​+∂σ2∂L​m2(Zi−μ)​+∂μ∂L​m1​

  • 测试: 测试时一般每次只送入一个数据,计算其均值和方差都是有偏估计,但训练过程中保存了每一组batch每一层的均值和方差,则对每一层都可以使用均值和方差的无偏估计:

μ

t

e

s

t

=

E

(

μ

b

a

t

c

h

)

\mu_{test}=E(\mu_{batch})

μtest​=E(μbatch​)

σ

t

e

s

t

2

=

m

m

1

E

(

σ

b

a

t

c

h

2

)

\sigma2_{test}=\frac{m}{m-1}E(\sigma2_{batch})

σtest2​=m−1m​E(σbatch2​)
然后计算该层的输出:

Z

~

i

=

γ

Z

t

e

s

t

i

μ

σ

t

e

s

t

2

ϵ

[外链图片转存中…(img-dTbuTM3a-1715606204786)]
[外链图片转存中…(img-VMxSDZwv-1715606204786)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 14
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值