PyTorch(1) torch.nn与torch.nn.functional之间的区别和联系

本文探讨了PyTorch中nn模块与nn.functional模块的使用场景及设计哲学,解析了为何某些层在__init__中定义,而另一些在forward中定义。文章指出,这种设计兼顾了灵活性与便利性,适用于不同特性的层。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在阅读PyTorch官网的教程的时候,发现介绍如何利用Pytorch搭建一个神经网络的示例代码是这样写。

迷惑的地方是在于forward的函数的定义方法。为什么要把网络中的一部分层在__init__()函数里定义出来,而另一部分层则是在__forward()__函数里定义?并且一个用的是nn,另一个用的是nn.functional。同一种层的API定义有两种,这样看似冗余的设计是为了什么呢?


通过阅读源码我们会发现,nnnn.functional之间的差别如下,我们以conv2d的定义为例。

torch.nn.Conv2d

 

torch.nn.functional.conv2d

从中我们可以发现,nn.Conv2d是一个类,而F.conv2d()是一个函数,而nn.Conv2d的forward()函数实现是用F.conv2d()实现的(在Module类里的__call__实现了forward()函数的调用,所以当实例化nn.Conv2d类时,forward()函数也被执行了,详细可阅读torch源码),所以两者功能并无区别,那么为什么要有这样的两种实现方式同时存在呢?

原因其实在于,为了兼顾灵活性和便利性。

在建图过程中,往往有两种层,一种如全连接层,卷积层等,当中有Variable,另一种如Pooling层,Relu层等,当中没有Variable。

如果所有的层都用nn.functional来定义,那么所有的Variable,如weights,bias等,都需要用户来手动定义,非常不方便。

而如果所有的层都换成nn来定义,那么即便是简单的计算都需要建类来做,而这些可以用更为简单的函数来代替的。
所以在定义网络的时候,如果层内有Variable,那么用nn定义,反之,则用nn.functional定义。
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值