【深度之眼】Pytorch框架班第五期-Batch Normalization代码调试

Batch Normalization

Batch Normalization: 批标准化

  • 批:一批数据,通常为mini-batch
  • 标准化:0均值,1方差

优点:
1、可以用更大的学习率,加速模型的收敛
2、可以不用精心设计权值初始化
3、可以不用dropout或者较小的dropout
4、可以不用L2或者较小的weight decay
5、可以不用LRN(local response normalization)

计算方式

在这里插入图片描述

代码

import torch
import numpy as np
import torch.nn as nn

import sys, os
hello_pytorch_DIR = os.path.abspath(os.path.dirname(__file__)+os.path.sep+".."+os.path.sep+"..")
sys.path.append(hello_pytorch_DIR)

from tools.common_tools import set_seed

set_seed(1)  # 设置随机种子


class MLP(nn.Module):
    def __init__(self, neural_num, layers=100):
        super(MLP, self).__init__()
        self.linears = nn.ModuleList([nn.Linear(neural_num, neural_num, bias=False) for i in range(layers)])
        self.bns = nn.ModuleList([nn.BatchNorm1d(neural_num) for i in range(layers)])
        self.neural_num = neural_num

    def forward(self, x):

        for (i, linear), bn in zip(enumerate(self.linears), self.bns):
            x = linear(x)
            # x = bn(x)
            x = torch.relu(x)

            if torch.isnan(x.std()):
                print("output is nan in {} layers".format(i))
                break

            print("layers:{}, std:{}".format(i, x.std().item()))

        return x

    def initialize(self):
        for m in self.modules():
            if isinstance(m, nn.Linear):

                # method 1
                nn.init.normal_(m.weight.data, std=1)    # normal: mean=0, std=1

                # method 2 kaiming
                # nn.init.kaiming_normal_(m.weight.data)


neural_nums = 256
layer_nums = 100
batch_size = 16

net = MLP(neural_nums, layer_nums)
# net.initialize()

inputs = torch.randn((batch_size, neural_nums))  # normal: mean=0, std=1

output = net(inputs)
print(output)

不进行权值初始化的结果

在这里插入图片描述
我们可以看到在第99层得到的方差是非常小的,导致网络模型无法使用。梯度消失。

对权值进行初始化,采用均值为0,标准差为1的正态分布

取消net.initialize()的注释,我们可以从下图发现,标准差特别大,而且在第35层出现了nan。梯度爆炸。在这里插入图片描述

采用kaiming方法进行权值初始化

在这里插入图片描述
此时我们的数据尺度有一个很好的分布,标准差前后相差不大。

加入BN层

在这里插入图片描述
效果更好。

使用BN层的同时不进行权值初始化

在这里插入图片描述
效果仍然很好,所以有了BN层我们可以不用精心设置权值初始化,甚至可以不进行权值初始化。

RMB二分类的BN层效果

1、原始LeNet,不进行权值初始化

在这里插入图片描述

2、原始LeNet,进行权值初始化

在这里插入图片描述

3、有BN层的LeNet,不进行权值初始化

在LeNet的每一个卷积后添加BN层。

在这里插入图片描述

_BatchNorm

__init__(self, num_features, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)

nn.BatchNorm1d
nn.BatchNorm2d
nn.BatchNorm3d
参数:

  • num_features: 一个样本特征数量
  • eps:分母修正项
  • momentum: 指数加权平均估计当前mean/var
  • affine: 是否需要affine transform
  • track_running_stats: 是训练状态还是测试状态

主要属性:

在这里插入图片描述

  • running_mean: 均值
  • running_var: 方差
  • weight: affine transform 中的gamma
  • bias: affine transform 中的beta
    训练:均值和方差采用指数加权平均计算
    测试:当前统计值

running_mean = (1-momentum) * pre_running_mean + momentum * mean_t
running_var = (1-momentum) * pre_running_var + momentum * var_t

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值