PyTorch : torch.nn.xxx 和 torch.nn.functional.xxx

在写 PyTorch 代码时,我们会发现在 torch.nn.xxxtorch.nn.functional.xxx 中有一些功能重复的操作,比如卷积、激活、池化。这些操作有什么不同?各有什么用处?

首先可以观察源码:

eg:torch.nn.Conv2d

CLASS torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')

eg:torch.nn.functional

torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1) → Tensor

从中,我们可以发现,nn.Conv2d 是一个类,而 nn.functional.conv2d是一个函数。

换言之:

  • nn.Module 实现的 layer 是由 class Layer(nn.Module) 定义的特殊类
  • nn.functional 中的函数更像是纯函数,由 def function(input) 定义

此外:

  1. 两者的调用方式不同:调用 nn.xxx 时要先在里面传入超参数,然后再将数据以函数调用的方式传入 nn.xxx

    # torch.nn
    inputs = torch.randn(64, 3, 244, 244)
    self.conv = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1)
    outputs = self.conv(inputs) # torch.nn.functional 需要同时传入数据和 weight,bias等参数
    inputs = torch.randn(64, 3, 244, 244)
    weight = torch.randn(64, 3, 3, 3)
    bias = torch.randn(64)
    outputs = nn.functinoal.conv2d(inputs, weight, bias, padding=1)
  2. nn.xxx 能够放在 nn.Sequential里,而 nn.functional.xxx 就不行

  3. nn.functional.xxx 需要自己定义 weight,每次调用时都需要手动传入 weight,而 nn.xxx 则不用

    import torch
    import torch.nn as nn
    import torch.nn.functional as F # torch.nn 定义的CNN
    class CNN(nn.Module):
    def __init__(self):
    super(CNN, self).__init__() self.conv_1 = nn.Conv2d(1, 16, krenel_size=5, padding=0)
    self.relu_1 = nn.ReLU(inplace=True)
    self.maxpool_1 = nn.MaxPool2d(kernel_size=2) self.conv_2 = nn.Conv2d(16, 32, krenel_size=5, padding=0)
    self.relu_2 = nn.ReLU(inplace=True)
    self.maxpool_2 = nn.MaxPool2d(kernel_size=2) self.linear = nn.Linear(4*4*32, 10) def forward(self, x):
    x = x.view(x.size(0), -1)
    out = self.maxpool_1(self.relu_1(self.conv_1(x)))
    out = self.maxpool_2(self.relu_2(self.conv_2(out)))
    out = self.linear(out.view(x.size(0), -1))
    return out # torch.nn.functional 定义一个相同的CNN
    class CNN(nn.Module):
    def __init__(self):
    super(CNN, self).__init__() self.conv_1_weight = nn.Parameter(torch.randn(16, 1, 5, 5))
    self.bias_1_weight = nn.Parameter(torch.randn(16)) self.conv_2_weight = nn.Parameter(torch.randn(32, 16, 5, 5))
    self.bias_2_weight = nn.Parameter(torch.randn(32)) self.linear_weight = nn.Parameter(torch.randn(4 * 4 * 32, 10))
    self.bias_weight = nn.Parameter(torch.randn(10)) def forward(self, x):
    x = x.view(x.size(0), -1)
    out = F.conv2d(x, self.conv_1_weight, self.bias_1_weight)
    out = F.conv2d(out, self.conv_2_weight, self.bias_2_weight)
    out = F.linear(out.view(x.size(0), -1), self.linear_weight, self.bias_weight)
  4. 在使用Dropout时,推荐使用 nn.xxx。因为一般只有训练时才使用 Dropout,在验证或测试时不需要使用 Dropout。使用 nn.Dropout时,如果调用 model.eval() ,模型的 Dropout 层都会关闭;但如果使用 nn.functional.dropout,在调用 model.eval() 时,不会关闭 Dropout。

  5. 当我们想要自定义卷积核时,是不能使用torch.nn.ConvNd 的,因为它里面的权重都是需要学习的参数,没有办法自行定义。但是,我们可以使用 torch.nn.functional.conv2d()

References:

  1. pytorch:nn与nn.functional的区别——简书

PyTorch : torch.nn.xxx 和 torch.nn.functional.xxx的更多相关文章

  1. [深度学习] Pytorch学习(二)—— torch.nn 实践:训练分类器(含多GPU训练CPU加载预测的使用方法)

    Learn From: Pytroch 官方Tutorials Pytorch 官方文档 环境:python3.6 CUDA10 pytorch1.3 vscode+jupyter扩展 #%% #%% ...

  2. PyTorch 介绍 | AUTOMATIC DIFFERENTIATION WITH TORCH.AUTOGRAD

    训练神经网络时,最常用的算法就是反向传播.在该算法中,参数(模型权重)会根据损失函数关于对应参数的梯度进行调整. 为了计算这些梯度,PyTorch内置了名为 torch.autograd 的微分引擎. ...

  3. 『PyTorch』第十三弹_torch.nn.init参数初始化

    初始化参数的方法 nn.Module模块对于参数进行了内置的较为合理的初始化方式,当我们使用nn.Parameter时,初始化就很重要,而且我们也可以指定代替内置初始化的方式对nn.Module模块进 ...

  4. [深度学习] Pytorch学习(一)—— torch tensor

    [深度学习] Pytorch学习(一)-- torch tensor 学习笔记 . 记录 分享 . 学习的代码环境:python3.6 torch1.3 vscode+jupyter扩展 #%% im ...

  5. href="javascript:xxx(this);"和onclick="javascript:xxx(this);"的区别

    href="javascript:xxx(this);"和onclick="javascript:xxx(this);" 一直以为这两种写法是等同的,今天在项目 ...

  6. 项目 XXX 的 NuGet 程序包还原失败:找不到“xxx”版本的程序包“xxx”

    项目 XXX 的 NuGet 程序包还原失败:找不到“xxx”版本的程序包“xxx” 编译新下载的代码出错 修改包管理器的源为 http://www.nuget.org/api/v2/ .重试后成功 ...

  7. There is no getter for property named xxx' in 'class java.lang.xxx'

    在xxxMapper.xml我们使用sql片段来提高sql代码的复用性,当时新手传入参数时常常出现这样的错误: There is no getter for property named xxx' i ...

  8. Android JS桥交互("Uncaught ReferenceError: xxx is not defined or xxx has no method")

    网上android和js交互的代码有不少,也很容易搜到.最近在做的项目需要用到js桥,遇到了一些问题,记录下来,希望以后遇到能马上解决掉. 一开始我找的demo是从这个:http://blog.csd ...

  9. git@github.com: Permission denied (publickey).////remote: Permission to xxx/test.git denied to xxx.等权限问题

    Error msg git@github.com: Permission denied (publickey) 或者: remote: Permission to xxx/test.git denie ...

随机推荐

  1. C++判断图像中一点是否在矩形中

    需要判断出四条之间组成的矩形的范围,其中矩形的边缘可能是倾斜不平行于x或者y轴. 考虑和很久,参考博客http://blog.csdn.net/dapengbusi/article/details/5 ...

  2. isMemberOfClass、isKindOfClass原理分析

    isMemberOfClass - 调用者必须是传入的类的实例对象才返回YES- 判断调用者是否是传入对象的实例,别弄反了,如 [s1 isMemberOfClass:p1] ,意思是s1是否是p1的 ...

  3. 【iOS】UIAlertController 弹出框

    UIAlertView 虽然还能用,但已经废弃了.因此以后尽量用 UIAlertController.示例代码如下: UIAlertController *alert = [UIAlertContro ...

  4. Python—三目运算

    Python 可通过 if 语句来实现三目运算的功能,因此可以近似地把这种 if 语句当成三目运算符.作为三目运算符的 if 语句的语法格式如下: (True_statements) if (expr ...

  5. js常用事件列表

    onmousedown.onmouseup 以及 onclick 事件 onmousedown, onmouseup 以及 onclick 构成了鼠标点击事件的所有部分.首先当点击鼠标按钮时,会触发 ...

  6. Linux基础用户管理

    一.用户管理 (一).用户和组的基本概念 Users and groups:. Every process (running program) on the system runs as a part ...

  7. 【原创】JAVA进程突然消失的原因?

    引言 值此七夕佳节,烟哥放弃了无数妹纸的邀约,坐在电脑面前码字,就是为了给读者带来新的知识,这是一件伟大的事业! 好吧,实际情况是没人约.为了化解尴尬,我决定卖力写文章,嗯,一定是我过于屌丝! 好了, ...

  8. Docker系列之烹饪披萨(二)

    前言 上一篇我们讲解了虚拟机和容器的区别,本节我们来讲讲Docker中关于Dockerfile.镜像.容器等基本概念.Docker是一个在容器内开发.部署.运行应用程序的平台,Docker本质上是容器 ...

  9. 用CSS来定义<p>标签,要求实现以下效果:字体颜色再IE6下为黑色,IE7下为红色,IE8下为绿色,其他浏览器下为黄色。

    <!DOCTYPE html><html><head><meta charset="utf-8"><meta name=&qu ...

  10. 浅谈微服务架构与服务治理的Eureka和Dubbo

    前言 本来计划周五+周末三天自驾游,谁知人算不如天算,周六恰逢台风来袭,湖州附近的景点全部关停,不得已只能周五玩完之后,于周六踩着台风的边缘逃回上海.周末过得如此艰难,这次就聊点务虚的话题,一是浅谈微 ...