当前位置:   article > 正文

批量归一化_多输入数据归一化

多输入数据归一化

引言

在深度学习中,批量归一化(Batch Normalization, BN)是一种非常重要的技术,它可以加速神经网络的训练,提高模型的泛化性能。本文将详细介绍批量归一化的原理、方法和实现过程,并给出PyTorch代码示例。

原理

在深度神经网络中,输入数据经过多层非线性变换后,分布会逐渐发生变化,导致每一层的输入分布都不同,这会影响网络的训练效果。批量归一化通过对每一层的输入进行归一化处理,使得每一层的输入分布相对稳定,从而加速网络的收敛速度,提高模型的泛化性能。

方法

批量归一化的方法如下:

  1. 对每个mini-batch的数据,计算其均值和方差;
  2. 对每个输入数据进行归一化处理;
  3. 对归一化后的数据进行线性变换,得到新的特征值;
  4. 对新的特征值进行缩放和平移,得到最终的输出。

具体来说,对于一个mini-batch的数据 B = { x 1 , x 2 , . . . , x m } B=\{x_1,x_2,...,x_m\} B={x1,x2,...,xm},其中 x i x_i xi表示第 i i i个输入数据,其均值和方差分别为:

μ B = 1 m ∑ i = 1 m x i \mu_B = \frac{1}{m}\sum_{i=1}^m x_i μB=m1i=1mxi

σ B 2 = 1 m ∑ i = 1 m ( x i − μ B ) 2 \sigma_B^2 = \frac{1}{m}\sum_{i=1}^m (x_i-\mu_B)^2 σB2=m1i=1m(xiμB)2

对每个输入数据进行归一化处理:

x i ^ = x i − μ B σ B 2 + ϵ \hat{x_i} = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2+\epsilon}} xi^=σB2+ϵ xiμB

其中 ϵ \epsilon ϵ是一个较小的常数,避免分母为0。

对归一化后的数据进行线性变换:

y i = γ x i ^ + β y_i = \gamma\hat{x_i} + \beta yi=γxi^+β

其中 γ \gamma γ β \beta β是可学习的参数,用于缩放和平移数据分布。

实现

在PyTorch中,可以使用nn.BatchNorm2d来实现批量归一化。下面是一个简单的示例:

import torch
import torch.nn as nn

# 定义一个简单的网络
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.bn1 = nn.BatchNorm2d(6)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.bn2 = nn.BatchNorm2d(16)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = nn.functional.relu(x)
        x = nn.functional.max_pool2d(x, 2)
        x = self.conv2(x)
        x = self.bn2(x)
        x = nn.functional.relu(x)
        x = nn.functional.max_pool2d(x, 2)
        x = x.view(-1, 16 * 5 * 5)
        x = self.fc1(x)
        x = nn.functional.relu(x)
        x = self.fc2(x)
        x = nn.functional.relu(x)
        x = self.fc3(x)
        return x

# 定义一个简单的训练过程
def train(net, trainloader, loss_func, optimizer, device):
    net.train()
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()

        outputs = net(inputs)
        loss = loss_func(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if i % 2000 == 1999:
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

# 加载数据集并进行训练
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transforms.ToTensor())
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64,
                                          shuffle=True, num_workers=2)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net = Net().to(device)
loss_func = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

for epoch in range(10):
    train(net, trainloader, loss_func, optimizer, device)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

结构图

使用Mermaid代码可以绘制批量归一化的结构图,如下所示:

Input
Normalization
Linear Transform
Scaling and Shifting
Output

其中,输入数据经过归一化、线性变换、缩放和平移后,得到最终的输出。

总结

批量归一化是一种非常重要的技术,它可以加速神经网络的训练,提高模型的泛化性能。本文介绍了批量归一化的原理、方法和实现过程,并给出了PyTorch代码示例。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/213468
推荐阅读
相关标签
  

闽ICP备14008679号