批量归一化和层归一化

  • 批量归一化是对每个特征/通道里的元素进行归一化。(不适合序列长度会变的NLP应用)
  • 层归一化是对每个样本里面的元素进行归一化。
ln = nn.LayerNorm(2)
bn = nn.BatchNorm1d(2)
X = torch.tensor([[1, 2], [2, 3]], dtype=torch.float32)
# 在训练模式下计算X的均值和方差
print('layer norm:', ln(X), '\nbatch norm:', bn(X))

输出:

layer norm: tensor([[-1.0000,  1.0000],
        [-1.0000,  1.0000]], grad_fn=<NativeLayerNormBackward>)
batch norm: tensor([[-1.0000, -1.0000],
        [ 1.0000,  1.0000]], grad_fn=<NativeBatchNormBackward>)

显然,[1, 2] 为样本1,[2, 3] 为样本2。layer norm对每个样本(2-D 数据里面的行)进行归一化。batch norm则是对每个特征(2-D 数据里面的列)进行归一化。

                             

这里,对NLP任务,b为 batch,d为tokens的维度, len 为序列的长度。所以,由于序列是变长的,所以不适用于Batch Norm。右图的LN 是对当前样本(序列)进行的归一化。

NLP中的LayerNorm

# NLP Example
batch, sentence_length, embedding_dim = 20, 5, 10
embedding = torch.randn(batch, sentence_length, embedding_dim)
layer_norm = nn.LayerNorm(embedding_dim)
# Activate module
layer_norm(embedding)

 这里是:nn.LayerNorm(embedding_dim)。所以是对序列中的每个单词进行的归一化。

CV 中的LayerNorm

# Image Example
N, C, H, W = 20, 5, 10, 10
input = torch.randn(N, C, H, W)
# Normalize over the last three dimensions (i.e. the channel and spatial dimensions)
# as shown in the image below
layer_norm = nn.LayerNorm([C, H, W])
output = layer_norm(input)

 这里,红色部分代表一张特征图,C代表有C张特征图。LN是对单个样本的归一化。

LayerNorm公式

不同的Norm的区别, 来自https://arxiv.org/pdf/1803.08494.pdf

参考:

1. 深入理解NLP中LayerNorm的原理以及LN的代码详解_白马金羁侠少年的博客-CSDN博客​​​​​​_layernorm层​​​​​​​​​​​​​

2. 68 Transformer【动手学深度学习v2】_哔哩哔哩_bilibili

3. 7.5. 批量规范化 — 动手学深度学习 2.0.0-beta0 documentation

4. LayerNorm — PyTorch 1.10.1 documentation

### 批归一化与梯度下降结合使用的示意图 在神经网络训练过程中,批归一化(Batch Normalization)梯度下降(Gradient Descent)是两个重要的技术。为了更好地理解两者如何协同工作,下面提供了一个简化版的流程图来展示这两个过程是如何交互的。 #### 流程概述 1. 输入数据通过前向传播进入每一层。 2. 在每层应用激活函数之前执行批归一化操作。 3. 计算损失并反向传播误差信号。 4. 使用梯度下降更新权重参数。 #### 示意代码实现 以下是Python伪代码表示该过程: ```python def forward_pass_with_bn(x, w, gamma, beta, eps=1e-5): mu = np.mean(x, axis=0) # Step 1: Calculate mean over batch var = np.var(x, axis=0) # Step 2: Calculate variance over batch x_hat = (x - mu) / np.sqrt(var + eps) # Step 3: Normalize input features out = gamma * x_hat + beta # Step 4: Scale and shift normalized data cache = (x, mu, var, x_hat, gamma, beta, eps) return out, cache def backward_pass_with_bn(dout, cache): x, mu, var, x_hat, gamma, beta, eps = cache N, D = dout.shape dbeta = np.sum(dout, axis=0) dgamma = np.sum(dout*x_hat, axis=0) dx_hat = dout * gamma divar = np.sum(dx_hat*(x-mu), axis=0) sqrtvar = np.sqrt(var + eps) dsqrtvar = -divar/(sqrtvar**2) dvar = 0.5*dsqrtvar/sqrtvar dsq = 1/N*np.ones((N,D))*dvar dxmu1 = 2*(x-mu)*dsq dxmu2 = dx_hat/sqrtvar dx1 = dxmu1 + dxmu2 dmu = -np.sum(dxmu1+dxmu2, axis=0) dx2 = 1/N*np.ones((N,D))*dmu dx = dx1 + dx2 return dx, dgamma, dbeta ``` 此段代码展示了带有批归一化的正向传递`forward_pass_with_bn()`以及相应的反向传递计算`backward_pass_with_bn()`. 这些步骤对于确保模型稳定性加速收敛至关重要[^1]. #### 结合梯度下降的过程描述 当涉及到实际优化时,在完成上述所有步骤之后,会利用链式法则沿着整个网络回传导数直到输入端,并据此调整各层中的可学习参数——即权值矩阵W及其偏置项b。这一系列动作构成了所谓的“梯度下降”。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

理心炼丹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值