BatchNorm中forward未被调用原因

1.nn.Module类理解

pytorch里面一切自定义操作基本上都是继承nn.Module类来实现的

方法预览:

class Module(object):def __init__(self):def forward(self, *input):def add_module(self, name, module):def cuda(self, device=None):def cpu(self):def __call__(self, *input, **kwargs):def parameters(self, recurse=True):def named_parameters(self, prefix='', recurse=True):def children(self):def named_children(self):def modules(self):  def named_modules(self, memo=None, prefix=''):def train(self, mode=True):def eval(self):def zero_grad(self):def __repr__(self):def __dir__(self):
'''
有一部分没有完全列出来
'''

我们在定义自已的网络的时候,需要继承nn.Module类,并重新实现构造函数__init__和forward这两个方法。但有一些注意技巧:

(1)一般把网络中具有可学习参数的层(如全连接层、卷积层等)放在构造函数__init__()中,当然我也可以吧不具有参数的层也放在里面;

(2)一般把不具有可学习参数的层(如ReLU、dropout、BatchNormanation层)可放在构造函数中,也可不放在构造函数中,如果不放在构造函数__init__里面,则在forward方法里面可以使用nn.functional来代替
    
(3)forward方法是必须要重写的,它是实现模型的功能,实现各个层之间的连接关系的核心
总结:

torch.nn是专门为神经网络设计的模块化接口。nn构建于autograd之上,可以用来定义和运行神经网络。
nn.Module是nn中十分重要的类,包含网络各层的定义及forward方法
定义自已的网络:
  需要继承nn.Module类,并实现forward方法。
  一般把网络中具有可学习参数的层放在构造函数__init__()中,
  不具有可学习参数的层(如ReLU)可放在构造函数中,也可不放在构造函数中(而在forward中使用nn.functional来代替)
  只要在nn.Module的子类中定义了forward函数,backward函数就会被自动实现(利用Autograd)。
  在forward函数中可以使用任何Variable支持的函数,毕竟在整个pytorch构建的图中,是Variable在流动。还可以使用if,for,print,log等python语法.
注:Pytorch基于nn.Module构建的模型中,只支持mini-batch的Variable输入方式

2.forward()函数自动调用的理解和分析

最近在使用pytorch的时候,模型训练时,不需要使用forward,只要在实例化一个对象中传入对应的参数就可以自动调用 forward 函数

自动调用 forward 函数原因分析:

利用Python的语言特性,y = model(x)是调用了对象model的__call__方法,而nn.Module把__call__方法实现为类对象的forward函数,所以任意继承了nn.Module的类对象都可以这样简写来调用forward函数。

案例:

class LeNet(nn.Module):def __init__(self):super(LeNet, self).__init__()layer1 = nn.Sequential()layer1.add_module('conv1', nn.Conv(1, 6, 3, padding=1))layer1.add_moudle('pool1', nn.MaxPool2d(2, 2))self.layer1 = layer1layer2 = nn.Sequential()layer2.add_module('conv2', nn.Conv(6, 16, 5))layer2.add_moudle('pool2', nn.MaxPool2d(2, 2))self.layer2 = layer2layer3 = nn.Sequential()layer3.add_module('fc1', nn.Linear(400, 120))layer3.add_moudle('fc2', nn.Linear(120, 84))layer3.add_moudle('fc3', nn.Linear(84, 10))self.layer3 = layer3def forward(self, x):x = self.layer1(x)x = self.layer2(x)x = x.view(x.size(0), -1)x = self.layer3(x)return x

模型调用:

model = LeNet()
y = model(x)

调用forward方法的具体流程是:

执行y = model(x)时,由于LeNet类继承了Module类,而Module这个基类中定义了__call__方法,所以会执行__call__方法,而__call__方法中调用了forward()方法

只要定义类型的时候,实现__call__函数,这个类型就成为可调用的。 换句话说,我们可以把这个类型的对象当作函数来使用

定义__call__方法的类可以当作函数调用(参见:https://www.cnblogs.com/luckyplj/p/13378008.html)

def __call__(self, *input, **kwargs):for hook in self._forward_pre_hooks.values():result = hook(self, input)if result is not None:if not isinstance(result, tuple):result = (result,)input = resultif torch._C._get_tracing_state():result = self._slow_forward(*input, **kwargs)else:result = self.forward(*input, **kwargs)for hook in self._forward_hooks.values():hook_result = hook(self, input, result)if hook_result is not None:result = hook_resultif len(self._backward_hooks) > 0:var = resultwhile not isinstance(var, torch.Tensor):if isinstance(var, dict):var = next((v for v in var.values() if isinstance(v, torch.Tensor)))else:var = var[0]grad_fn = var.grad_fnif grad_fn is not None:for hook in self._backward_hooks.values():wrapper = functools.partial(hook, self)functools.update_wrapper(wrapper, hook)grad_fn.register_hook(wrapper)return result

总结:当执行model(x)的时候,底层自动调用forward方法计算结果

参考文献:
Pytorch学习笔记07----nn.Module类与前向传播函数forward的理解 - 雨后观山色 - 博客园

我的理解:

为什么会看不到调用forward()呢,

模型训练时,不需要使用forward,只要在实例化一个对象中传入对应的参数就可以自动调用 forward 函数,是因为Module中定义了__call__()函数,该函数调用了forward()函数,当执行BatchNorm(x)的时候,会自动调用__call__()函数 

我们在定义自已的网络的时候,需要继承nn.Module类,并重新实现构造函数__init__和forward这两个方法。

class BatchNorm(nn.Module):# `num_features`:完全连接层的输出数量或卷积层的输出通道数。# `num_dims`:2表示完全连接层,4表示卷积层def __init__(self, num_features, num_dims):super().__init__()if num_dims == 2:shape = (1, num_features)else:shape = (1, num_features, 1, 1)# 参与求梯度和迭代的拉伸和偏移参数,分别初始化成1和0self.gamma = nn.Parameter(torch.ones(shape))self.beta = nn.Parameter(torch.zeros(shape))# 非模型参数的变量初始化为0和1self.moving_mean = torch.zeros(shape)self.moving_var = torch.ones(shape)def forward(self, X):# 如果 `X` 不在内存上,将 `moving_mean` 和 `moving_var`# 复制到 `X` 所在显存上if self.moving_mean.device != X.device:self.moving_mean = self.moving_mean.to(X.device)self.moving_var = self.moving_var.to(X.device)# 保存更新过的 `moving_mean` 和 `moving_var`Y, self.moving_mean, self.moving_var = batch_norm(X, self.gamma, self.beta, self.moving_mean, self.moving_var,eps=1e-5, momentum=0.9)return Y     

Pytorch中什么时候调用forward()函数_good good study的博客-CSDN博客_forward调用

动手学深度学习(二十三)——批量归一化(BN)_jerry_liufeng的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567490.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git上传分支的原理_GIT分支,创建分支与合并分支的工作原理与教程

开发一个版本,采用的发布流程:(1).从master的最新代码拉取一个开发分支,在上面进行开发(2).在开发分支上不断地进行提交版本,期间,master也会有因为其他版本上线而不停有版本合并(3).要发布的时候,把分支重…

有十五个数按由大到小顺序存放在一个数组中_「图形化编程」前导知识-数组(一)...

今天我们来学习一个新的概念-数组。这节课将通过一个小程序讲解数组的基本概念-数组的长度和下标定义数组指的是有序元素的集合,数组中的每个元素具有相同的类型,按照顺序排列的形式组织在一起。我们可以把数组想象为一个抽屉柜,每个抽屉只能…

octave错误-error: ‘squareThisNumber‘ undefined near line 1 column 1

.m文件名称也应为大写:squareThisNumber.m 问题2: parse error near line 1 of file C:\Users\asus\squareThisNumber.m syntax error >>> {\rtf1\ansi\ansicpg936\deff0\nouicompat{\fonttbl{\f0\fnil\fcharset134 \cb\ce\cc\e5;}} 解决方案…

工业机器人几个自由度_工业机器人有多少个运动自由度呢?

2008-09-11psp有什么好游戏?自由度很高的自由的高的游戏,如果不限定位动作游戏的话还是有一些的。首先就是楼主所说的GTA,自由度高的典范。然后楼上MM说的《怪物猎人》,同样超高自由度的动作游戏,推荐。《魔界战记》,…

python矩阵中找满足条件的元素_Python 找到列表中满足某些条件的元素方法

Python 找到列表中满足某些条件的元素方法 更新时间:2018年06月26日 11:20:17 作者:CS_network 今天小编就为大家分享一篇Python 找到列表中满足某些条件的元素方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看…

计算机启动过程-阮一峰

从打开电源到开始操作,计算机的启动是一个非常复杂的过程。 我一直搞不清楚,这个过程到底是怎么回事,只看见屏幕快速滚动各种提示...... 这几天,我查了一些资料,试图搞懂它。下面就是我整理的笔记。 零、boot的含义 …

python全局名称空间_python名称空间,命名空间

全局名称空间:在python解释器开始执行之后, 就会在内存中开辟一个空间, 每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了, 至于函数内部的变量和逻辑, 解释器是不关心的. 也…

10分钟带你了解python_ComeOn!10分钟带你了解Python的变量和数据类型

对任何语言来说,变量和数据类型都是非常重要和基础的内容。这篇文章就带你用10分钟的时间,学会Python的变量和数据类型这个知识点。一、知识点python 关键字变量的定义与赋值input() 函数字符串的格式化二、实验步骤每一种编程语言都有它们自己的语法规则…

python神经网络实例_Python编程实现的简单神经网络算法示例

本文实例讲述了Python编程实现的简单神经网络算法。分享给大家供大家参考,具体如下: python实现二层神经网络 包括输入层和输出层 # -*- coding:utf-8 -*- #! python2 import numpy as np #sigmoid function def nonlin(x, deriv False): if(deriv Tru…

由于被认为是客户端对错误(例如:畸形的请求语法、无效的请求信息帧或者虚拟的请求路由),服务器无法或不会处理当前请求。

问题描述: 由于被认为是客户端对错误(例如:畸形的请求语法、无效的请求信息帧或者虚拟的请求路由),服务器无法或不会处理当前请求。 在实现向数据库中添加记录时,请求发送无效,参数也未传递到控…

为什么服务器要选择 Linux,这里总结了 10 大理由

从最近的统计数据可以看到,全球大量数据中心的服务器已经开始向基于 Linux Server 平台转移。相较 Windows Server 而言,Linux Server 提供了更多优势。包括 Google、Twitter、Facebook 和 Amazon 在内的诸多国际互联网巨头,都在基于 Linux S…

华南x79主板u盘装系统教程_华南x79怎么用u盘重装系统

现如今电脑已经走进千家万户,大家生活和工作基本上都离不开电脑,接下来介绍一下华南x79主板的电脑怎么用U盘重装系统,以重装win7为例,分享一下华南x79主板的电脑u盘重装系统的方法步骤。华南x79主板电脑用u盘重装系统步骤阅读1、插…

怎么通过id渲染页面_完全理解Vue的渲染watcher、computed和user watcher

作者:Naicehttps://segmentfault.com/a/1190000023196603这篇文章将带大家全面理解vue的watcher、computed和user watcher,其实computed和user watcher都是基于Watcher来实现的,我们通过一个一个功能点去敲代码,让大家全面理解其中…

VS2015启动调试程序变慢

问题描述## 标题 vs2015编译速度很快,运行时不停显示加载xxx.dll动态库,加载很慢 解决方案## 标题 打开vs2015,依次点击工具-》选项-》调试-》符号,点击勾选去掉Microsoft符号服务器,清空符号缓存完毕 转载自VS2015启动调试程序变…

广联达深思6代锁_广联达|新版加密锁驱动使用文档

查看已购如何“查看已购”?老版的以下功能:1. 查看已购产品程序2. 产品密码注册程序3. 加密锁设置程序4. 授权服务控制程序新版中我们对这些功能做了整理和重设计:5. 新版的“广联达新驱动”包含以上所有功能“查看已购”入口去哪了&#xff…

根可达算法的根_我的JVM(六):GC的基础概念以及GC算法

一、概述垃圾收集Garbage Collection通常被称为GC,但是GC一般也指Garbage Collecting(垃圾回收这个动作)或Garbage Collector(垃圾回收器),这些都是是JVM知识体系中非常重要的知识,也是程序员必须要掌握的技能,本文将详细讲述Java…

docker开放的端口_docker-5-解决宿主机没有开放81端口却可以直接访问docker启动的81端口nginx容器的问题...

我以为经过前面四篇博文的学习,自己对docker的了解最起码入门了,但是当我用docker启动一个81端口的nginx后(宿主机:容器/81:80),在宿主机的firwall防火墙没有添加81端口的情况下,竟然可以直接访问成功,然后试下docker运…

测试计划与测试方案

测试计划与测试方案主要有以下几点区别: 1.测试计划是一个偏管理性质的文档,而测试方案是一个偏技术类型的文档; 2.测试计划通俗来讲就是解决【谁来做?】【做什么?】的问题,而测试方案是解决【怎么做&#…

docker 删除包含关键字的镜像_30分钟带你轻松掌握Docker原理

前言Docker是什么?Docker是Go语言开发实现的容器。2013年发布至今,备受推崇。相关文档、学习资料十分详尽。近期有docker相关项目,得重新学习一下。博客以笔记为什么要使用 Docker?Docker 容器的启动在秒级Docker 对系统资源利用率…

ssm访问不到html_IDEA解决SSM项目的静态资源路径问题:HTML,CSS,JS--详解

直接上图(项目目录结构):我们主要关注webapp。如上图,建议把js,css,layui,首页等文件放在WEB-INF外部,WEB-INF放程序的主要网页,index页面,welcome,各种管理页面等(如下图…