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

在这里插入图片描述

在阅读一些深度学习项目的代码中,我们会发现这样一个问题,深度学习网络模型中常常要定义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()有了更深的理解了,到实践中去检验它们吧~

写在后面

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值