首页 > 编程语言 >一文搞懂!Python中的 __call__以及其与自动调用forward()的关系

一文搞懂!Python中的 __call__以及其与自动调用forward()的关系

时间:2024-03-30 13:05:00浏览次数:16  
标签:__ 调用 Python age call forward 搞懂 self

在这里插入图片描述

在阅读一些深度学习项目的代码中,我们会发现这样一个问题,深度学习网络模型中常常要定义forward()方法,但是在使用该函数时却没有显式地调用函数的forward(),却好像“自动”地执行了。
比如下面这个例子(不可执行的代码,仅描述常见网络模型的大致定义框架、模型实例化和获取输出的过程),实例化网络模型后并没有调用forward()函数,却执行forward()处理了输入,并得到了输出结果,这是为什么呢?让我们一起来探索吧!

class Model(nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        ```
        网络定义部分
        ```

    def forward(self,输入):
        ```
        前向传播部分
        ```
        return 处理后的输入

#实例化网络模型
model = Model()
输出 = model(输入)

文章目录

一、答案揭晓

答案就在于Model()类继承自nn.Modulenn.Module中定义了__call__函数,而在__call__函数中又调用了forward()方法,然后因为Model()类重写了forward()方法,所以看起来就好像自动调用了重写后的forward()方法。

那么接下来,就让我们一起看看__call__函数的使用!

二、_ _call _ _

来看这样一个例子:

class Cat():
    def __call__(self, name):
        print("小猫的名字叫",name)

    def eat(self, food):
        print("小猫要吃",food)

miao = Cat()
miao('miao')
miao.eat('fish')

输出:

小猫的名字叫 miao
小猫要吃 fish

在这个例子中,我们能看出来,__call__的调用可以直接用实例化对象名调用,而不需要写成对象.__call__()的形式。

三、_ _call _ _与forward()

本来想看看nn.Module__call__具体是怎样调用forward()函数的,但是点开nn.Module,代码简直太复杂了,读不懂一点,所以我们采用下面这样一个例子来大概展现下,__call__是如何自动调用forward()函数的。

# 类比class Model()
class Baby():
    def __init__(self, init_age=1):
        self.age = init_age
        print('init实现——我的初始年龄是:', self.age)

    def __call__(self, added_age):
        print('call实现——我增加的年龄是:', added_age)
        age = self.forward(added_age)
        return age

    def forward(self, added_age):
        self.age = self.age + added_age
        print('forward实现——我最终的年龄是:', self.age)
        return self.age


# 类比model = Model()
baby = Baby()
# 类比output = model(input)
age = baby(2)
print('最终结果——我最终的年龄是:', age)

输出:

init实现——我的初始年龄是: 1
call实现——我增加的年龄是: 2
forward实现——我最终的年龄是: 3
最终结果——我最终的年龄是: 3

通过这个例子,我们能够学习到,在进行实例化后,__call__()可以直接用实例化对象名调用,然后在__call__()中又调用了forward(),因此用实例化对象名可以直接得到forward()的输出赋值给最终的age

相信通过这几个例子,能够让我们对于__call__以及forward()有了更深的理解了,到实践中去检验它们吧~

写在后面

这个专栏主要是我在实现深度学习项目中总结的一些问题,以备未来笔试和面试之需,不过由于学习的不深入,也只是走马观花,很多问题总结得也不是很透彻,望读者见谅,如果有错误和不足之处,还望大家在评论区指出。希望能给大家的学习带来一点帮助,共同进步!!!

标签:__,调用,Python,age,call,forward,搞懂,self
From: https://blog.csdn.net/weixin_51193374/article/details/137142540

相关文章

  • 35.网络游戏逆向分析与漏洞攻防-游戏网络通信数据解析-登录成功数据包内容分析
    免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!如果看不懂、不知道现在做的什么,那就跟着做完看效果内容参考于:易道云信息技术研究院VIP课上一个内容:34.登录数据包的监视与模拟首先登陆游戏,到角色选择界面,如下图,可以看到这个数据包很大2421个字节首先确定......
  • Git 删除分支——如何删除本地或远程分支
    Git删除分支——如何删除本地或远程分支Git是一种流行的版本控制系统,也是Web开发人员工具包中必不可少的工具。分支是使用Git的一个强大且不可或缺的部分。在本文中,您将学习有关如何在Git中删除本地和远程分支的基础知识。Git中的分支是什么?分支是指向提交的指针。......
  • 深度学习pytorch——经典卷积网络之ResNet(持续更新)
    错误率前五的神经网络(图-1):图-1可以很直观的看到,随着层数的增加Error也在逐渐降低,因此深度是非常重要的,但是学习更好的网络模型和堆叠层数一样简单吗?通过实现表明(图-2),并不是如此,会出现梯度消失和梯度爆炸的现象,甚至比堆叠之前的训练效果更差,这种现象被称为梯度......
  • Windows12安装Docker
    环境及工具(文末提供)DockerDesktopInstaller.exe(官网)一、查看windows相关配置查看是否开启相应的功能,如果没有需要开启,然后重启电脑打开任务管理器(CTRL+SHIFT+ESC)->选择性能->CPU->虚拟化,确认是否已启用二、开始安装(我这边已经安装完成)三、可能遇到的问题St......
  • 24、C++的一维数组概念
    数组是一组数据类型相同的变量,可以存放一组数据。1、创建数组声明数组的语法:数据类型数组名[数组长度];注意:数组长度必须是整数,可以是常量,也可以是变量和表达式。C90规定必须用常量表达式指明数组的大小,C99允许使用整型非常量表达式。经测试,在VS中可以用用整型非常量表达......
  • 登录者个人信息查询
    目录......
  • Vue怎么使用Upload组件进行图片上传到阿里云OSS,并
    基于前端用Vue2后端用Springboot进行讲解一、创建阿里云OSS       对象存储OSS_云存储服务_企业数据管理_存储-阿里云(aliyun.com),打开网站进行开通    开通后我们来到Bucket列表,创建Bucket            创建过程:后面就默认就行了   ......
  • 金工实习、C语言课设、数据结构课设-报告
    源代码丢失了只剩下报告,配图流程图齐全,可直接使用C语言课设报告:香水管理系统数据结构课设报告:西邮导航金工实习:车工学习、钳工学习、数控学习 文章头部下载三篇报告压缩包~......
  • ICPC2023 陕西邀请赛 题解
    G-PermutationQuestion找到一个排列\(p\),使得\(\prod_{i=1}^nlcm(p_i,p_{(imodn)+1})\)最大Solution考虑到\(x\)和\(x-1\)必然是互质的所以顺序排列即可Code#include<bits/stdc++.h>usingnamespacestd;intmain(){intn;cin>>n;for(inti......
  • 图像分类实践
    图像分类实践了解使用简单的卷积神经网络来完成图像分类。实际上,对于一些较为复杂的数据集,简单的卷积神经网络无法达到一个较高的分类准确度,而深度学习实践中的网络结构通常可以达到几十甚至上百层的数目。知识点数据加载器迁移学习猫狗识别卷积神经网络可视化数据集计......