PyTorch中的torch.nn.Parameter() 详解

这篇具有很好参考价值的文章主要介绍了PyTorch中的torch.nn.Parameter() 详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

PyTorch中的torch.nn.Parameter() 详解

今天来聊一下PyTorch中的torch.nn.Parameter()这个函数,笔者第一次见的时候也是大概能理解函数的用途,但是具体实现原理细节也是云里雾里,在参考了几篇博文,做过几个实验之后算是清晰了,本文在记录的同时希望给后来人一个参考,欢迎留言讨论。

分析

先看其名,parameter,中文意为参数。我们知道,使用PyTorch训练神经网络时,本质上就是训练一个函数,这个函数输入一个数据(如CV中输入一张图像),输出一个预测(如输出这张图像中的物体是属于什么类别)。而在我们给定这个函数的结构(如卷积、全连接等)之后,能学习的就是这个函数的参数了,我们设计一个损失函数,配合梯度下降法,使得我们学习到的函数(神经网络)能够尽量准确地完成预测任务。

通常,我们的参数都是一些常见的结构(卷积、全连接等)里面的计算参数。而当我们的网络有一些其他的设计时,会需要一些额外的参数同样很着整个网络的训练进行学习更新,最后得到最优的值,经典的例子有注意力机制中的权重参数、Vision Transformer中的class token和positional embedding等。

而这里的torch.nn.Parameter()就可以很好地适应这种应用场景。

下面是这篇博客的一个总结,笔者认为讲的比较明白,在这里引用一下:

首先可以把这个函数理解为类型转换函数,将一个不可训练的类型Tensor转换成可以训练的类型parameter并将这个parameter绑定到这个module里面(net.parameter()中就有这个绑定的parameter,所以在参数优化的时候可以进行优化的),所以经过类型转换这个self.v变成了模型的一部分,成为了模型中根据训练可以改动的参数了。使用这个函数的目的也是想让某些变量在学习的过程中不断的修改其值以达到最优化。

ViT中nn.Parameter()的实验

看过这个分析后,我们再看一下Vision Transformer中的用法:

...

self.pos_embedding = nn.Parameter(torch.randn(1, num_patches+1, dim))
self.cls_token = nn.Parameter(torch.randn(1, 1, dim))
...

我们知道在ViT中,positonal embedding和class token是两个需要随着网络训练学习的参数,但是它们又不属于FC、MLP、MSA等运算的参数,在这时,就可以用nn.Parameter()来将这个随机初始化的Tensor注册为可学习的参数Parameter。

为了确定这两个参数确实是被添加到了net.Parameters()内,笔者稍微改动源码,显式地指定这两个参数的初始数值为0.98,并打印迭代器net.Parameters()。

...

self.pos_embedding = nn.Parameter(torch.ones(1, num_patches+1, dim) * 0.98)
self.cls_token = nn.Parameter(torch.ones(1, 1, dim) * 0.98)
...

实例化一个ViT模型并打印net.Parameters():

net_vit = ViT(
        image_size = 256,
        patch_size = 32,
        num_classes = 1000,
        dim = 1024,
        depth = 6,
        heads = 16,
        mlp_dim = 2048,
        dropout = 0.1,
        emb_dropout = 0.1
    )

for para in net_vit.parameters():
        print(para.data)

输出结果中可以看到,最前两行就是我们显式指定为0.98的两个参数pos_embedding和cls_token:

tensor([[[0.9800, 0.9800, 0.9800,  ..., 0.9800, 0.9800, 0.9800],
         [0.9800, 0.9800, 0.9800,  ..., 0.9800, 0.9800, 0.9800],
         [0.9800, 0.9800, 0.9800,  ..., 0.9800, 0.9800, 0.9800],
         ...,
         [0.9800, 0.9800, 0.9800,  ..., 0.9800, 0.9800, 0.9800],
         [0.9800, 0.9800, 0.9800,  ..., 0.9800, 0.9800, 0.9800],
         [0.9800, 0.9800, 0.9800,  ..., 0.9800, 0.9800, 0.9800]]])
tensor([[[0.9800, 0.9800, 0.9800,  ..., 0.9800, 0.9800, 0.9800]]])
tensor([[-0.0026, -0.0064,  0.0111,  ...,  0.0091, -0.0041, -0.0060],
        [ 0.0003,  0.0115,  0.0059,  ..., -0.0052, -0.0056,  0.0010],
        [ 0.0079,  0.0016, -0.0094,  ...,  0.0174,  0.0065,  0.0001],
        ...,
        [-0.0110, -0.0137,  0.0102,  ...,  0.0145, -0.0105, -0.0167],
        [-0.0116, -0.0147,  0.0030,  ...,  0.0087,  0.0022,  0.0108],
        [-0.0079,  0.0033, -0.0087,  ..., -0.0174,  0.0103,  0.0021]])
...
...

这就可以确定nn.Parameter()添加的参数确实是被添加到了Parameters列表中,会被送入优化器中随训练一起学习更新。

from torch.optim import Adam
opt = Adam(net_vit.parameters(), learning_rate=0.001)

其他解释

以下是国外StackOverflow的一个大佬的解读,笔者自行翻译并放在这里供大家参考,想查看原文的同学请戳这里。

我们知道Tensor相当于是一个高维度的矩阵,它是Variable类的子类。Variable和Parameter之间的差异体现在与Module关联时。当Parameter作为model的属性与module相关联时,它会被自动添加到Parameters列表中,并且可以使用net.Parameters()迭代器进行访问。
最初在Torch中,一个Variable(例如可以是某个中间state)也会在赋值时被添加为模型的Parameter。在某些实例中,需要缓存变量,而不是将它们添加到Parameters列表中。
文档中提到的一种情况是RNN,在这种情况下,您需要保存最后一个hidden state,这样就不必一次又一次地传递它。需要缓存一个Variable,而不是让它自动注册为模型的Parameter,这就是为什么我们有一个显式的方法将参数注册到我们的模型,即nn.Parameter类。

举个例子:

import torch
import torch.nn as nn
from torch.optim import Adam

class NN_Network(nn.Module):
    def __init__(self,in_dim,hid,out_dim):
        super(NN_Network, self).__init__()
        self.linear1 = nn.Linear(in_dim,hid)
        self.linear2 = nn.Linear(hid,out_dim)
        self.linear1.weight = torch.nn.Parameter(torch.zeros(in_dim,hid))
        self.linear1.bias = torch.nn.Parameter(torch.ones(hid))
        self.linear2.weight = torch.nn.Parameter(torch.zeros(in_dim,hid))
        self.linear2.bias = torch.nn.Parameter(torch.ones(hid))

    def forward(self, input_array):
        h = self.linear1(input_array)
        y_pred = self.linear2(h)
        return y_pred

in_d = 5
hidn = 2
out_d = 3
net = NN_Network(in_d, hidn, out_d)

然后检查一下这个模型的Parameters列表:

for param in net.parameters():
    print(type(param.data), param.size())

""" Output
<class 'torch.FloatTensor'> torch.Size([5, 2])
<class 'torch.FloatTensor'> torch.Size([2])
<class 'torch.FloatTensor'> torch.Size([5, 2])
<class 'torch.FloatTensor'> torch.Size([2])
"""

可以轻易地送入到优化器中:

opt = Adam(net.parameters(), learning_rate=0.001)

另外,请注意Parameter的require_grad会自动设定。

各位读者有疑惑或异议的地方,欢迎留言讨论。

参考:

https://www.jianshu.com/p/d8b77cc02410

https://stackoverflow.com/questions/50935345/understanding-torch-nn-parameter文章来源地址https://www.toymoban.com/news/detail-403503.html

到了这里,关于PyTorch中的torch.nn.Parameter() 详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Pytorch计算余弦相似度距离——torch.nn.CosineSimilarity函数中的dim参数使用方法

    前言 一、官方函数用法 二、实验验证 1.计算高维数组中各个像素位置的余弦距离 2.验证高维数组中任意一个像素位置的余弦距离 总结 现在要使用Pytorch中自带的 torch.nn. CosineSimilarity函数计算两个高维特征图(B,C,H,W)中各个像素位置的特征相似度,即特征图中的每个像素位置上

    2024年02月13日
    浏览(42)
  • pytorch中nn.Parameter()使用方法

    对于 nn.Parameter() 是pytorch中定义 可学习参数 的一种方法,因为我们在搭建网络时,网络中会存在一些矩阵,这些矩阵内部的参数是可学习的,也就是可梯度求导的。 对于一些常用的网络层,例如 nn.Conv2d()卷积层 、 nn.LInear()线性层 、 nn.LSTM()循环网络层 等,这些网络层在pyt

    2024年02月13日
    浏览(36)
  • Pytorch因nn.Parameter导致实验不可复现的一种情况

    文章首发见博客:https://mwhls.top/4871.html。 无图/格式错误/后续更新请见首发页。 更多更新请到mwhls.top查看 欢迎留言提问或批评建议,私信不回。 没解决,只是记录这种情况。 也可以多次实验取均值以避免结果复现。 场景 自己的模块中,包含一个与 x 相加的可学习参数,导

    2024年02月07日
    浏览(32)
  • Pytorch学习:神经网络模块torch.nn.Module和torch.nn.Sequential

    官方文档:torch.nn.Module CLASS torch.nn.Module(*args, **kwargs) 所有神经网络模块的基类。 您的模型也应该对此类进行子类化。 模块还可以包含其他模块,允许将它们嵌套在树结构中。您可以将子模块分配为常规属性: training(bool) -布尔值表示此模块是处于训练模式还是评估模式。

    2024年02月10日
    浏览(43)
  • Pytorch:torch.nn.Module

    torch.nn.Module 是 PyTorch 中神经网络模型的基类,它提供了模型定义、参数管理和其他相关功能。 以下是关于 torch.nn.Module 的详细说明: 1. torch.nn.Module 的定义: torch.nn.Module 是 PyTorch 中所有神经网络模型的基类,它提供了模型定义和许多实用方法。自定义的神经网络模型应该继

    2024年01月16日
    浏览(47)
  • 【Pytorch】torch.nn.LeakyReLU()

    Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~   ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金,有幸在竞赛中拿过一些国奖、省奖…已保研 学习经验:扎实基础 + 多做

    2024年02月02日
    浏览(37)
  • Pytorch-----torch.nn.Module.modules()

    在使用pytorch构建神经网络时,定义的网络模型必须要继承自torch.nn.Module这一父类。在Module类中,有一个函数可以返回网络中所有模块的迭代器。这就是torch.nn.Module.modules() 提示:以下是本篇文章正文内容,下面案例可供参考 源码中的解释如下: 不只是返回网络中的某一层,

    2024年02月14日
    浏览(48)
  • 深度学习之pytorch 中 torch.nn介绍

    pytorch 中必用的包就是 torch.nn,torch.nn 中按照功能分,主要如下有几类: 1. Layers(层):包括全连接层、卷积层、池化层等。 2. Activation Functions(激活函数):包括ReLU、Sigmoid、Tanh等。 3. Loss Functions(损失函数):包括交叉熵损失、均方误差等。 4. Optimizers(优化器):包括

    2024年02月22日
    浏览(45)
  • 深入浅出Pytorch函数——torch.nn.Module

    分类目录:《深入浅出Pytorch函数》总目录 Pytorch中所有网络的基类,我们的模型也应该继承这个类。 Modules 也可以包含其它 Modules ,允许使用树结构嵌入他们,我们还可以将子模块赋值给模型属性。 语法 方法 torch.nn.Module.apply 实例 通过上面方式赋值的 submodule 会被注册,当调

    2024年02月12日
    浏览(67)
  • 深入浅出Pytorch函数——torch.nn.Linear

    分类目录:《深入浅出Pytorch函数》总目录 对输入数据做线性变换 y = x A T + b y=xA^T+b y = x A T + b 语法 参数 in_features :[ int ] 每个输入样本的大小 out_features :[ int ] 每个输出样本的大小 bias :[ bool ] 若设置为 False ,则该层不会学习偏置项目,默认值为 True 变量形状 输入变量:

    2024年02月12日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包