从 relu 的多种实现来看 torch.nn 与 torch.nn.functional 的区别与联系
从 relu 的多种实现来看 torch.nn 与 torch.nn.functional 的区别与联系
relu多种实现之间的关系
relu 函数在 pytorch 中总共有 3 次出现:
torch.nn.ReLU()torch.nn.functional.relu_()torch.nn.functional.relu_()torch.relu()torch.relu_()
而这3种不同的实现其实是有固定的包装关系,由上至下是由表及里的过程。
其中最后一个实际上并不被 pytorch 的官方文档包含,同时也找不到对应的 python 代码,只是在 __init__.pyi 中存在,因为他们来自于通过C++编写的THNN库。
下面通过分析源码来进行具体分析:
- torch.nn.ReLU()
torch.nn 中的类代表的是神经网络层,这里我们看到作为类出现的ReLU()实际上只是调用了torch.nn.functional中的relu relu_实现。
class ReLU(Module):
r"""Applies the rectified linear unit function element-wise:
:math:`\text{ReLU}(x)= \max(0, x)`
Args:
inplace: can optionally do the operation in-place. Default: ``False``
Shape:
- Input: :math:`(N, *)` where `*` means, any number of additional
dimensions
- Output: :math:`(N, *)`, same shape as the input
.. image:: scripts/activation_images/ReLU.png
Examples::
>>> m = nn.ReLU()
>>> input = torch.randn(2)
>>> output = m(input)
An implementation of CReLU - https://arxiv.org/abs/1603.05201
>>> m = nn.ReLU()
>>> input = torch.randn(2).unsqueeze(0)
>>> output = torch.cat((m(input),m(-input)))
"""
__constants__ = ['inplace']
def __init__(self, inplace=False):
super(ReLU, self).__init__()
self.inplace = inplace
@weak_script_method
def forward(self, input):
# F 来自于 import nn.functional as F
return F.relu(input, inplace=self.inplace)
def extra_repr(self):
inplace_str = 'inplace' if self.inplace else ''
return inplace_str
torch.nn.functional.relu()torch.nn.functional.relu_()
其实这两个函数也是调用了torch.relu() and torch.relu_()
def relu(input, inplace=False):
# type: (Tensor, bool) -> Tensor
r"""relu(input, inplace=False) -> Tensor
Applies the rectified linear unit function element-wise. See
:class:`~torch.nn.ReLU` for more details.
"""
if inplace:
result = torch.relu_(input)
else:
result = torch.relu(input)
return result
relu_ = _add_docstr(torch.relu_, r"""
relu_(input) -> Tensor
In-place version of :func:`~relu`.
""")
至此我们对 RELU 函数在 torch 中的出现有了一个深入的认识。实际上作为基础的两个包,torch.nn 与 torch.nn.functional 的关系是引用与包装的关系。
torch.nn 与 torch.nn.functional 的区别与联系
结合上述对 relu 的分析,我们能够更清晰的认识到两个库之间的联系。
通常来说 torch.nn.functional 调用了 THNN库,实现核心计算,但是不对 learnable_parameters 例如 weight bias ,进行管理,为模型的使用带来不便。而 torch.nn 中实现的模型则对 torch.nn.functional,本质上是官方给出的对 torch.nn.functional的使用范例,我们通过直接调用这些范例能够快速方便的使用 pytorch ,但是范例可能不能够照顾到所有人的使用需求,因此保留 torch.nn.functional 来为这些用户提供灵活性,他们可以自己组装需要的模型。因此 pytorch 能够在灵活性与易用性上取得平衡。
特别注意的是,torch.nn不全都是对torch.nn.functional的范例,有一些调用了来自其他库的函数,例如常用的RNN型神经网络族即没有在torch.nn.functional中出现。
我们带着这样的思考再来看下一个例子作为结束:
对于Linear请注意⚠️对比两个库下实现的不同:
- 对
learnable parameters的管理 - 相互之间的调用关系
- 初始化过程
class Linear(Module):
r"""Applies a linear transformation to the incoming data: :math:`y = xA^T + b`
Args:
in_features: size of each input sample
out_features: size of each output sample
bias: If set to ``False``, the layer will not learn an additive bias.
Default: ``True``
Shape:
- Input: :math:`(N, *, H_{in})` where :math:`*` means any number of
additional dimensions and :math:`H_{in} = \text{in\_features}`
- Output: :math:`(N, *, H_{out})` where all but the last dimension
are the same shape as the input and :math:`H_{out} = \text{out\_features}`.
Attributes:
weight: the learnable weights of the module of shape
:math:`(\text{out\_features}, \text{in\_features})`. The values are
initialized from :math:`\mathcal{U}(-\sqrt{k}, \sqrt{k})`, where
:math:`k = \frac{1}{\text{in\_features}}`
bias: the learnable bias of the module of shape :math:`(\text{out\_features})`.
If :attr:`bias` is ``True``, the values are initialized from
:math:`\mathcal{U}(-\sqrt{k}, \sqrt{k})` where
:math:`k = \frac{1}{\text{in\_features}}`
Examples::
>>> m = nn.Linear(20, 30)
>>> input = torch.randn(128, 20)
>>> output = m(input)
>>> print(output.size())
torch.Size([128, 30])
"""
__constants__ = ['bias']
def __init__(self, in_features, out_features, bias=True):
super(Linear, self).__init__()
self.in_features = in_features
self.out_features = out_features
self.weight = Parameter(torch.Tensor(out_features, in_features))
if bias:
self.bias = Parameter(torch.Tensor(out_features))
else:
self.register_parameter('bias', None)
self.reset_parameters()
def reset_parameters(self):
init.kaiming_uniform_(self.weight, a=math.sqrt(5))
if self.bias is not None:
fan_in, _ = init._calculate_fan_in_and_fan_out(self.weight)
bound = 1 / math.sqrt(fan_in)
init.uniform_(self.bias, -bound, bound)
@weak_script_method
def forward(self, input):
return F.linear(input, self.weight, self.bias)
def extra_repr(self):
return 'in_features={}, out_features={}, bias={}'.format(
self.in_features, self.out_features, self.bias is not None
)
def linear(input, weight, bias=None):
# type: (Tensor, Tensor, Optional[Tensor]) -> Tensor
r"""
Applies a linear transformation to the incoming data: :math:`y = xA^T + b`.
Shape:
- Input: :math:`(N, *, in\_features)` where `*` means any number of
additional dimensions
- Weight: :math:`(out\_features, in\_features)`
- Bias: :math:`(out\_features)`
- Output: :math:`(N, *, out\_features)`
"""
if input.dim() == 2 and bias is not None:
# fused op is marginally faster
ret = torch.addmm(bias, input, weight.t())
else:
output = input.matmul(weight.t())
if bias is not None:
output += bias
ret = output
return ret
从 relu 的多种实现来看 torch.nn 与 torch.nn.functional 的区别与联系的更多相关文章
- [pytorch笔记] torch.nn vs torch.nn.functional; model.eval() vs torch.no_grad(); nn.Sequential() vs nn.moduleList
1. torch.nn与torch.nn.functional之间的区别和联系 https://blog.csdn.net/GZHermit/article/details/78730856 nn和n ...
- Pytorch本人疑问(1) torch.nn和torch.nn.functional之间的区别
在写代码时发现我们在定义Model时,有两种定义方法: torch.nn.Conv2d()和torch.nn.functional.conv2d() 那么这两种方法到底有什么区别呢,我们通过下述代码看 ...
- 小白学习之pytorch框架(2)-动手学深度学习(begin-random.shuffle()、torch.index_select()、nn.Module、nn.Sequential())
在这向大家推荐一本书-花书-动手学深度学习pytorch版,原书用的深度学习框架是MXNet,这个框架经过Gluon重新再封装,使用风格非常接近pytorch,但是由于pytorch越来越火,个人又比 ...
- 【Pytorch】关于torch.matmul和torch.bmm的输出tensor数值不一致问题
发现 对于torch.matmul和torch.bmm,都能实现对于batch的矩阵乘法: a = torch.rand((2,3,10))b = torch.rand((2,2,10))### ma ...
- pytorch 损失函数(nn.BCELoss 和 nn.CrossEntropyLoss)(思考多标签分类问题)
一.BCELoss 二分类损失函数 输入维度为(n, ), 输出维度为(n, ) 如果说要预测二分类值为1的概率,则建议用该函数! 输入比如是3维,则每一个应该是在0--1区间内(随意通常配合sigm ...
- torch.rand、torch.randn、torch.normal、torch.linespace
torch.rand(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) # ...
- torch.cat()和torch.stack()
torch.cat() 和 torch.stack()略有不同torch.cat(tensors,dim=0,out=None)→ Tensortorch.cat()对tensors沿指定维度拼接,但 ...
- PyTorch - torch.eq、torch.ne、torch.gt、torch.lt、torch.ge、torch.le
PyTorch - torch.eq.torch.ne.torch.gt.torch.lt.torch.ge.torch.le 参考:https://flyfish.blog.csdn.net/art ...
- torch.sort 和 torch.argsort
定义 torch.sort(input,dim,descending) torch.argsort(input,dim,descending) 用法 torch.sort:对输入数据排序,返回两个值, ...
随机推荐
- 从三星官方uboot开始移植
移植前的准备 下载 android_uboot_smdkv210.tar.bz2 这个文件 开始移植 本人使用的开发板是九鼎的 x210,在三星 uboot 的主 Makefile 中找到了类似的 s ...
- Python 必知的 20 个骚操作!
以下为译文: Python 是一个解释型语言,可读性与易用性让它越来越热门. 正如 Python 之禅中所述: 优美胜于丑陋,明了胜于晦涩. 在你的日常编码中,以下技巧可以给你带来意想不到的收获. ...
- PHP时间格式
date 用法: date(格式,[时间]); 如果没有时间参数,则使用当前时间.格式是一个字符串,其中以下字符有特殊意义: Y - 年,四位数字; 如: "1999" y - 年 ...
- 编译安装常用包+阿里镜像源-常用资源-系统-下载-科莱软件下载-docker仓库包-安全圈-杏雨梨云-图形界面安装-docker私有双仓库-阿里源报错处理-centos7目录大小
yum install apr-util apr-util-devel apr apr-devel pcre pcre-devel zlib zlib-devel openssl openssl-de ...
- DevOps - 生命周期
章节 DevOps – 为什么 DevOps – 与传统方式区别 DevOps – 优势 DevOps – 不适用 DevOps – 生命周期 DevOps – 与敏捷方法区别 DevOps – 实施 ...
- webservice调试(XML参数)
<![CDATA[ <?xml version="1.0" encoding="UTF-8"?><MsgText> <use ...
- Easy_vb
拿到之后运行一下 之后使用ida打开先关键字搜索一下,结果就出来了
- 一个基于chrome扩展的自动答题器
1.写在前面 首先感谢小茗同学的文章-[干货]Chrome插件(扩展)开发全攻略, 基于这篇入门教程和demo,我才能写出这款 基于chrome扩展的自动答题器. git地址: https://git ...
- SciKit-Learn 数据集基本信息
## 保留版权所有,转帖注明出处 章节 SciKit-Learn 加载数据集 SciKit-Learn 数据集基本信息 SciKit-Learn 使用matplotlib可视化数据 SciKit-Le ...
- 51node 4个数和0
https://www.51nod.com/Challenge/Problem.html#problemId=1267 第一种方法:两个for+二分:很好理解,不用考虑重复的问题.但是这个还不够快 # ...