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. 2019前端面试系列——Vue面试题

    Vue 双向绑定原理        mvvm 双向绑定,采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter.getter,在数 ...

  2. springBoot的过滤器,监听器,拦截器

    概述 在开发中,我们经常要考虑一些问题,对敏感词进行过滤,用户是否已经登录,是否需要对他的请求进行拦截,或者领导问现在在线人数有多少人?我们如何实现这些功能哪 @WebFilter package c ...

  3. windows server2008下搭建ftp服务

    在工作中不光使用linux系统下的ftp服务,也得使用windows下的,今天领导让我做一个,踩了很多坑,终于是做完了,重现下过程,我们就来一步一步搭建我们的windows下的ftp服务器: 1.环境 ...

  4. 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!

    1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...

  5. codeforces 327 A Ciel and Dancing

    题目链接 给你一串只有0和1的数字,然后对某一区间的数翻转1次(0变1 1变0),只翻转一次而且不能不翻转,然后让你计算最多可能出现多少个1. 这里要注意很多细节 比如全为1,要求必须翻转,这时候我们 ...

  6. JAVA并发编程之倒计数器CountDownLatch

    CountDownLatch 的使用场景:在主线程中开启多线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后汇总返回结果. 我把源码中的英文注释全部删除,写上自己的注释.就剩下 70 行不到的 ...

  7. c#将字符串转化为合理的文件名

    string name = System.Text.RegularExpressions.Regex.Replace(url, "[<>/\\|:\"?*]" ...

  8. 客户端埋点实时OLAP指标计算方案

    背景 产品经理想要实时查询一些指标数据,在新版本的APP上线之后,我们APP的一些质量指标,比如课堂连接掉线率,课堂内崩溃率,APP崩溃率等指标,以此来看APP升级之后上课的体验是否有所提升,上课质量 ...

  9. [实践]activemq安全设置 设置admin的用户名和密码

    (1)打开/opt/app/amq/apache-activemq-5.9.0/conf/jetty.xml 找到 将property name为authenticate的属性value=" ...

  10. JavaWeb——使用会话维持状态3

    这次的例子是使用会话给上一个例子添加登陆功能 1.页面逻辑 首先是登陆页面,这里需要输入账号和密码,输入正确后将进入商品列表页面,输入错误将会提示账号或者密码错误 其次是商品列表和购物车页面,添加了注 ...