BatchNormalization

本文仅介绍BatchNormalization的理解,对于原理部分,网上博客资料很详细.

1 什么是BatchNormalization 

 在做图像的神经网络训练时,我们往往每次给神经网络喂食一个batch的数据,当然这些数据指的是一个个的image或者feature map.比如我们batch_size=32,即每次处理32张image或者 feature map.而这一个batch的数据的不能反映出该batch的分布情况,需要将其映射到某个区间上,以反映样本集的分布,这时候就需要使用normalization对数据进行处理.可以参考下面图片理解.使用了Normalizatio之后,它可以一直保持数据分布基本不变.而Batch_normallization就是对每个batch做处理.

2 有什么作用

        其作用可以加快模型训练时的收敛速度,使得模型训练过程更加稳定,避免梯度爆炸或者梯度消失。并且起到一定的正则化作用,几乎代替了Dropout。

3 怎么理解BatchNormalization的过程

 我们使用一张图来描述Batch_normalization,

        在做图像卷积操作或者其他操作时,输入是一个(batch_size,channel,height,width)4D 形状的tensor数据.我们把它变成(batch_size,channel,height*width)3D的shape.其中C表示channel ,N表示batch,H,w可以把他理解成将一个二维(H,W)的图像矩阵拉成一维的(H*W).

batch_size : 一个批次的样本数量

channel : 通道的数量

height : 一张image 或者是 feature map的高度 

width : 一张image 或者是 feature map的宽度

从上图可以看出它是对同一个channel ,不同的batch,不同的image信息进行做normalizaton.你可以直接看出,图中蓝色的部分就是从channel的角度切割的.

举个例子

        比如一个彩色Image的大小是32*32大小,我们一个batch有8个Images, channel是3(即RGB三个通道),tensor 的shape 就是:(8,3,32,32). 对这样的tensor数据进行normalization.

其实就是分别对image的R通道,G通道,B通道分别做normalization.

 公式: 

对每个颜色通道做一个Normalization.

4 代码实现

#!/usr/bin/env python
# coding:utf-8

# image = (N,C,H,W)
import torch 
import torch.nn as nn 
batch_size = 2 
channel = 3 
height = 32 
width = 32 
eps = 1e-5
# ======== officcal API =============
# 通道级别
def get_Batch_norm_API(x) :

    bn = nn.BatchNorm1d(channel,affine=True)
    y = bn(x)
    return y,y.shape 

# =======  手动计算batch_norm ===========
def get_Batch_norm(x):
    # 求均值
    bn_mean = x.mean(dim=(0,2) ,keepdim=True)
    # 求标准差
    bn_std = x.std(dim=(0,2) ,unbiased=False,keepdim=True ) 

    y = (x-bn_mean) /(bn_std + eps) 
    return y,y.shape 

x = torch.randn((batch_size ,channel ,height*width )) 

# 官方的api
bn_api,bn_api_size = get_Batch_norm_API(x)
# 自己的
bn,bn_size = get_Batch_norm(x)

print(bn_api)

print('=================') 
print(bn)
print(bn_size)

构建一个网络,使用写的batch_normalization

#!/usr/bin/env python
# Author: zhanghansen
# Created Time: 2023年03月28日 星期二 14时28分42秒

# coding:utf-8
#
import cv2 
import torch 
import torch.nn as nn
import numpy as np
import random
seed = 42
torch.cuda.manual_seed(seed)  # 为GPU设置种子
torch.cuda.manual_seed_all(seed)  # 当有多张GPU时,为所有GPU设置种子
np.random.seed(seed)  # 为Numpy设置随机种子
random.seed(seed)  # 
class Net1(nn.Module):

    def __init__(self,shape): 
        super().__init__()
        self.shape = shape 
        self.in_channel = self.shape[1] 
        self.out_channel = 16 
        self.conv1 = nn.Conv2d(self.in_channel,self.out_channel,kernel_size=3) 

    def forward(self,x) : 

        x = self.conv1(x)
        
        x = self.batch_norm2(x,x.shape[1]) 
        return x 

    # normalization 
    def batch_norm(self,x,channel): 
    
        bn = nn.BatchNorm2d(channel,affine=True)

        return bn(x)
    def batch_norm2(self,x,channel) : 
        eps = 1e-5
        # 均值
        bn_mean = x.mean(dim=(0,2,3),keepdim=True)
        bn_std = x.std(dim=(0,2,3),unbiased=False ,keepdim=True)
        
        bn = ( x- bn_mean) /( bn_std+eps) 
        return bn 
        # 方差
batch_size = 4 
in_channel = 3 
height = 32 
width = 32 
input_  = torch.rand((batch_size ,in_channel,height,width))

X = Net1([batch_size,in_channel,height,width]) 
y = X(input_) 

print(y.shape)


参考 :  

深入解读Batch Normalization_batchnorm 维度_我太难了...的博客-CSDN博客
深度学习之图像分类(八)--Batch Normalization_batch 图像_木卯_THU的博客-CSDN博客

Batch Normalization详解以及pytorch实验_太阳花的小绿豆的博客-CSDN博客

【基础算法】六问透彻理解BN(Batch Normalization) - 知乎

https://www.cnblogs.com/wevolf/p/15195143.html

猜你喜欢

转载自blog.csdn.net/qq_41661809/article/details/129811811