以下的过程中都是在train模式下进行的,并且没有进行损失计算和梯度更新,
但这个过程中running_mean和running_var会进行更新,所以也验证了
running_mean和running_var只受模型的模式(train模型或eval模型)的影响,
与是否进行反向传播(loss.backward)和梯度更新(optimiter.step)没有关系。
实验一:
1. 标准库函数的参数设置为 torch.nn.BatchNorm1d(linear1_features,momentum=0.1)
2. 自定义函数的参数设置为 MyBatchnorm1d(linear1_features,momentum=0.9)
3. 相同的输入,对比输出的参数值是否相同
实验二:
1. 标准库函数的参数设置为 torch.nn.BatchNorm1d(linear1_features,momentum=None)
2. 自定义函数的参数设置为 MyBatchnorm1d(linear1_features,momentum=None)
3. 相同的输入,对比输出的参数值是否相同

针对标准库torch.nn.BatchNorm1d()中running_mean和running_var计算方法的结论:

为方便描述,规定:

  • rm表示running_mean;
  • rv表示running_var;
  • m表示momemtum
  • b_num表示batchnum,代表当前batch之前的batch个数

一、在train模式下

1. 带动量时,即指定momentum为一个大于0小于1的数值时,相当于当前值与历史值的加权平均

其中mean_bn是当前batch数据的batch平均值。这里的momentum是对当前值的加权系数!!默认为0.1

其中var_bn是当前batch数据的方差平均值(这里是方差,不是标准差,标准差的平方=方差)

2. 不带动量时,即momentum=None,直接让历史值与当前值取平均

二、在eval模型下

直接用rm、rv作为当前batch均值和方差

代码如下:

# -*- coding: utf-8 -*-
import torch
from torch.autograd import Variable
import torch.optim as optimbatchsize = 16
batchnum = 100
# rawdata = torch.randn([batchsize*batchnum,3])
# torch.save(rawdata,'./debug_running_var_mean_rawdata.pth')
#加载数据,保证数据是不变的
rawdata = torch.load('./debug_running_var_mean_rawdata.pth')
print(rawdata.size())y = Variable(torch.FloatTensor([4,5]))
dataset = [Variable(rawdata[curpos:curpos + batchsize]) for curpos in range(0,len(rawdata),batchsize)]class SimpleModel(torch.nn.Module):def __init__(self):super(SimpleModel,self).__init__()linear1_features = 5self.linear1 = torch.nn.Linear(3,linear1_features)self.relu = torch.nn.ReLU()self.linear2 = torch.nn.Linear(linear1_features,2)#设计时batchnorm放在linear1后面,所以这里用linear1的输出维度self.batch_norm = torch.nn.BatchNorm1d(linear1_features,momentum=0.1)  #标准库中的Barchnorm,track_running_stats默认为True# self.batch_norm = torch.nn.BatchNorm1d(linear1_features,momentum=None)  #标准库中的Barchnorm,track_running_stats默认为Truedef forward(self,x):x = self.linear1(x)x = self.relu(x)x = self.batch_norm(x)x = self.linear2(x)return x#先进行一下简单训练之后,保存参数,后面的模型可以加载此函数,这样相当于给用于实验的两个模型初始化了相同的参数
train_demo = 0
if train_demo == 1:model = SimpleModel()# print(list(model.parameters()))# #查看模型的初始参数# print(model.state_dict().keys())# # for i, j in model.named_parameters():# for i,j in model.state_dict().items():#     print('++++',i)#     print('\t',j)loss_fn = torch.nn.MSELoss(size_average=False)optimizer = optim.SGD(model.parameters(),lr=0.001,momentum=0.9)model.train()for t,x in enumerate(dataset):y_pred = model(x)loss = loss_fn(y_pred,y)print(t,loss.data)model.zero_grad()loss.backward()optimizer.step()#查看训练后的模型参数print('##################The trained Model parameters###############')print(model.state_dict().keys())# for i, j in model.named_parameters():for i,j in model.state_dict().items():print('++++',i)print('\t',j)#保存模型参数state = {'model': model.state_dict()}torch.save(state,'debug_batchnorm.pth')class MyBatchnorm1d(torch.nn.Module):def __init__(self,num_features,momentum=0.9):'''自定义的batchnorm:param num_features::param momentum: 动量系数,大于等于0小于1,表示保留原来变量值的比例,与标准库torch.nn.Batchnorm1d正好相反当取None时,采用简单的取平均的方式计算running_mean和running_var'''super(MyBatchnorm1d,self).__init__()self.weight = torch.nn.Parameter(torch.ones(num_features).float())self.bias = torch.nn.Parameter(torch.zeros(num_features).float())#register_buffer相当于requires_grad=False的Parameter,所以两种方法都可以#方法一:self.register_buffer('running_mean',torch.zeros(num_features))self.register_buffer('running_var',torch.zeros(num_features))self.register_buffer('num_batches_tracked',torch.tensor(0))#方法二:# self.running_mean = torch.nn.Parameter(torch.zeros(num_features),requires_grad=False)# self.running_var = torch.nn.Parameter(torch.ones(num_features),requires_grad=False)# self.num_batches_tracked = torch.nn.Parameter(torch.tensor(0),requires_grad=False)self.momentum = momentumdef forward(self,x):if self.training: #训练模型#数据是二维的情况下,可以这么处理,其他维的时候不是这样的,但原理都一样。mean_bn = x.mean(0, keepdim=True).squeeze(0) #相当于x.mean(0, keepdim=False)var_bn = x.var(0, keepdim=True).squeeze(0) #相当于x.var(0, keepdim=False)if self.momentum is not None:self.running_mean.mul_(self.momentum)self.running_mean.add_((1 - self.momentum) * mean_bn.data)self.running_var.mul_(self.momentum)self.running_var.add_((1 - self.momentum) * var_bn.data)else:  #直接取平均,以下是公式变形,即 m_new = (m_old*n + new_value)/(n+1)self.running_mean = self.running_mean+(mean_bn.data-self.running_mean)/(self.num_batches_tracked+1)self.running_var = self.running_var+(var_bn.data-self.running_var)/(self.num_batches_tracked+1)self.num_batches_tracked += 1else: #eval模式mean_bn = torch.autograd.Variable(self.running_mean)var_bn = torch.autograd.Variable(self.running_var)eps = 1e-5x_normalized = (x - mean_bn) / torch.sqrt(var_bn + eps)results = self.weight * x_normalized + self.biasreturn resultsclass DebugSimpleModel(torch.nn.Module):def __init__(self):super(DebugSimpleModel,self).__init__()linear1_features = 5self.linear1 = torch.nn.Linear(3,linear1_features)self.relu = torch.nn.ReLU()self.linear2 = torch.nn.Linear(linear1_features,2)self.batch_norm = MyBatchnorm1d(linear1_features,momentum=0.9)  #使用自定义的Batchnorm# self.batch_norm = MyBatchnorm1d(linear1_features,momentum=None)  #使用自定义的Batchnormdef forward(self,x):x = self.linear1(x)x = self.relu(x)x = self.batch_norm(x)x = self.linear2(x)return x#查看训练后的模型参数
print('##################The trained Model parameters###############')
model_param_dict = torch.load('debug_batchnorm.pth')['model']
print(model_param_dict.keys())
# for i, j in model.named_parameters():
for i,j in model_param_dict.items():print('++++',i)print('\t',j)'''
以下的过程中都是在train模式下进行的,并且没有进行损失计算和梯度更新,
但这个过程中running_mean和running_var会进行更新,所以也验证了
running_mean和running_var只受模型的模式(train模型或eval模型)的影响,
与是否进行反向传播(loss.backward)和梯度更新(optimiter.step)没有关系。
实验一:
1. 标准库函数的参数设置为 torch.nn.BatchNorm1d(linear1_features,momentum=0.1)
2. 自定义函数的参数设置为 MyBatchnorm1d(linear1_features,momentum=0.9)
3. 相同的输入,对比输出的参数值是否相同
实验二:
1. 标准库函数的参数设置为 torch.nn.BatchNorm1d(linear1_features,momentum=None)
2. 自定义函数的参数设置为 MyBatchnorm1d(linear1_features,momentum=None)
3. 相同的输入,对比输出的参数值是否相同'''
test_demo = 1
if test_demo == 1:test_model = SimpleModel()test_model.load_state_dict(torch.load('debug_batchnorm.pth')['model'])test_model.train()for t,x in enumerate(dataset):y_pred = test_model(x)print('\n++++++++++  Norm output  ++++++++++++++++')for i,j in test_model.state_dict().items():print('++++',i)print('\t',j)debug_demo = 1
if debug_demo == 1:debug_model = DebugSimpleModel()#因为自定义的模型参数与标准模型的参数完全一样,所以把标准模型作为预训练的模型(即可以加载标准模型的训练后的参数作为自己的参数)debug_model.load_state_dict(torch.load('debug_batchnorm.pth')['model'])debug_model.train()for t,x in enumerate(dataset):y_pred = debug_model(x)print('\n++++++++++++ Mymodel Output ++++++++++++++')for i,j in debug_model.state_dict().items():print('++++',i)print('\t',j)

Pytorch中BatchNorm中running_mean和running_var的计算方法相关推荐

  1. pytorch训练过程中loss出现NaN的原因及可采取的方法

    在pytorch训练过程中出现loss=nan的情况 1.学习率太高. 2.loss函数 3.对于回归问题,可能出现了除0 的计算,加一个很小的余项可能可以解决 4.数据本身,是否存在Nan,可以用n ...

  2. PyTorch 1.4 中文文档校对活动正式启动 | ApacheCN

    一如既往,PyTorch 1.4 中文文档校对活动启动了! 认领须知 请您勇敢地去翻译和改进翻译.虽然我们追求卓越,但我们并不要求您做到十全十美,因此请不要担心因为翻译上犯错--在大部分情况下,我们的 ...

  3. PyTorch 1.2 中文文档校对活动 | ApacheCN

    整体进度:https://github.com/apachecn/pytorch-doc-zh/issues/422 贡献指南:https://github.com/apachecn/pytorch- ...

  4. Pytorch以及tensorflow中KLdivergence的计算

    1. KL divergence是什么 KL 散度是一个距离衡量指标,衡量的是两个概率分布之间的差异. y p r e d y_{pred} ypred​指的是模型的输出的预测概率,形如[0.35,0 ...

  5. pytorch中Dataloader()中的num_workers设置问题

    pytorch中Dataloader()中的num_workers设置问题: 如果num_workers的值大于0,要在运行的部分放进__main__()函数里,才不会有错: import numpy ...

  6. Pytorch的BatchNorm层使用中容易出现的问题

    前言 本文主要介绍在pytorch中的Batch Normalization的使用以及在其中容易出现的各种小问题,本来此文应该归属于[1]中的,但是考虑到此文的篇幅可能会比较大,因此独立成篇,希望能够 ...

  7. pytorch之BatchNorm

    为了解决 Internal Covariate Shift问题引入,该问题具体表现为: 中间层输入分布总是变化,增加了模型拟合的难度. 中间层输入分布会使输出逐渐靠近激活函数梯度较小的地方,导致梯度消 ...

  8. win10html5无法播放,win10系统中网页中无法播放视频怎么办

    近日有win10系统用户要通过浏览器来打开网页观看视频的时候,却发现在网页中打开视频的时却无法播放,这是怎么回事呢,经过分析是由于Adobe Flash Player ActiveX插件未安装.版本过 ...

  9. Oracle EBS R12 运行adadmin 安装中文语言包过程中意外中断后的处理

    介绍Oracle EBS R12 运行adadmin 安装中文语言包过程中意外中断后的处. Oracle EBS R12 运行adadmin 安装中文语言包过程中意外中断或关机后,重新开机,运行数据库 ...

  10. Python中sklearn中HistGradientBoostingRegressor回归器配置单调约束参数monotonic_cst提高回归模型的抗噪声以及局部扰动的能力

    Python中sklearn中HistGradientBoostingRegressor回归器配置单调约束参数monotonic_cst提高回归模型的抗噪声以及局部扰动的能力 目录

最新文章

  1. Ajax实现DataGrid/DataList动态ToolTip
  2. Linux-DNS服务器的配置与管理(上)
  3. python常用标准库有哪些-Python 常用的标准库以及第三方库有哪些?
  4. http响应头里没有或者有content-length的几种可能性
  5. 《python网络数据采集》读后感 第六章:读取文档
  6. 根据自己的博客数据统计国内IT人群
  7. Python对IP地址列表排序、对列表进行去重、IP地址与MAC地址组合的多个元组的列表排序
  8. 自我监督学习和无监督学习_弱和自我监督的学习-第4部分
  9. 蛋糕是叫胚子还是坯子_这个生日蛋糕太适合手残党了,不会裱花也能做,学会再不买着吃了...
  10. 学习使用DCMTK工具
  11. 逆向破解flash视频url
  12. google保存网页为图片
  13. ppt插入 html,PPT中嵌入网页的方法:使用webbrowser控件
  14. rust阿尔法辅助_和平精英阿尔法辅助器
  15. 初识Kinect之一
  16. 点云IO篇之stl文件读写
  17. 【Trailhead题目解析】Prepare your salesforce org for users - 5Create Chatter Groups
  18. 同程艺龙通过港交所上市聆讯 要冲刺小程序第一股
  19. 【转载】linux修改文件的所有者权限[root权限更改为用户权限]
  20. 2018年​最酷的APP手机UI设计趋势

热门文章

  1. 基于JARM指纹的C2识别
  2. 布同:如何循序渐进学习Python语言(转载)
  3. 桌面计算机图标怎么取消,win7图标箭头怎么取消,win7去除电脑桌面图标箭头
  4. android 亮屏 激活自动亮度调节,Android 屏幕亮度调节(2.0以后出现亮度自动调节)如何开启、关闭亮度自动调节...
  5. docker学习(十三)docker安装dejavu
  6. FlashFXP官方U盘绿色版
  7. 一文读懂自然语言处理NLP(图解+学习资料)
  8. hdoj 5510 Bazinga
  9. php 处理eml,php读取eml实例、php解析eml、eml解析成网页
  10. Spring注解@Value在controller无法获取到值