pytorch 一些方法

net.parameters()&net.state_dict()

前者用于优化器的初始化,后者多用于模型的保存

register_buffer

回顾模型保存:torch.save(model.state_dict()),model.state_dict()是一个字典,里边存着我们模型各个部分的参数。在model中,我们需要更新其中的参数,训练结束将参数保存下来。但在某些时候,我们可能希望模型中的某些参数参数不更新(从开始到结束均保持不变),但又希望参数保存下来(model.state_dict() ),这是我们就会用到 register_buffer() 。

self.register_buffer(‘my_buffer’, self.tensor):my_buffer是名字,str类型;

self.tensor是需要进行register登记的张量。这样我们就得到了一个新的张量,这个张量会保存在model.state_dict()中,也就可以随着模型一起通过.cuda()复制到gpu上

self.register_buffer('weight_epsilon',torch.FloatTensor(out_features,in_features))

torch中的参数dim

一般-1代表最后一维,也就是最小的维度,比如二维dim=0,1 那么-1等价于1。dim=0,1,2,那么-1等价于2

data=torch.rand([2,3])
print(data)
#下面两个结果一样
print(torch.cat([data,data],dim=-1))
print(torch.cat([data,data],dim=1))

with torch.no_grad()

则主要是用于停止autograd模块的工作,以起到加速和节省显存的作用。它的作用是将该with语句包裹起来的部分停止梯度的更新,从而节省了GPU算力和显存,但是并不会影响dropout和BN层的行为

torch.eval()

eval()的作用是不启用 Batch Normalization 和 Dropout,并且不会保存中间变量、计算图。

torch.clamp()&torch.clip()数值裁剪

两个函数用法一样,效果也一样
将输入input张量每个元素的值压缩到区间 [min,max],并返回结果到一个新张量

torch.clamp(input, min, max, out=None) → Tensor
input:输入张量;min:限制范围下限; max:限制范围上限;out:输出张量。

a=torch.rand(5)
a=torch.clip(a,-0.5,0.5)
print(a)

torch.eye()

返回一个二维数组,对角线为1,其余为0

torch.eye(n,m=None,out=None)
n:行数;m:列数

print(torch.eye(2))
print(torch.eye(3,4))

torch.stack()

沿一个新维度对输入张量序列进行连接,序列中所有张量应为相同形状;stack 函数返回的结果会新增一个维度,而stack()函数指定的dim参数,就是新增维度的(下标)位置。

torch.stack(sequence, dim=0)
sequence:参与创建新张量的几个张量;dim:新增维度的(下标)位置,当dim = -1时默认最后一个维度;

import torch
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = torch.tensor([[11, 22, 33], [44, 55, 66], [77, 88, 99]])
#可以自己按不同的维度进行连接
c = torch.stack([a, b], dim=0)
print(a)
print(b)
print(c)
 
# 输出信息:
tensor([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]])
tensor([[11, 22, 33],
        [44, 55, 66],
        [77, 88, 99]])
tensor([[[ 1,  2,  3],
         [ 4,  5,  6],
         [ 7,  8,  9]],
 
        [[11, 22, 33],
         [44, 55, 66],
         [77, 88, 99]]])

param.requires_grad = False

屏蔽预训练模型的权重,只训练全连接层的权重

torch.bmm()

完成三维tensor的矩阵乘法运算,矩阵必须是3维数据(nrowcol )

格式: bmm(input, mat2, *, out=None) -> Tensor
其中两个tensor的第一维必须相等,然后第一个数组的第三维和第二个数组的第二维度要求一样

矩阵维度必须为三维,不然会报错

c=torch.rand((10,2,5))
d=torch.rand((10,5,2))
res=torch.bmm(c,d)
print(res)

torch.norm()

def norm(input, p=“fro”, dim=None, keepdim=False, out=None, dtype=None):

  1. input:输入tensor类型的数据
  2. p:指定的范数
    在这里插入图片描述
  3. dim:指定在哪个维度进行,如果不指定,则是在所有维度进行计算。
  4. keepdim:True or False,如果True,则保留dim指定的维度,False则不保留。
  5. out:输出的tensor,文档没说具体含义,暂时不知。
  6. dtype:指定输出的tensor的数据类型。
import torch
t = torch.ones(64, 3, 3, 3)
t_norm = t.norm(1, 3)
print(t_norm)

指定p=1,dim=3。也就是在t的第3个维度(从0开始)进行1范数计算。
调试一下可以发现:t_norm的shape为(64,3,3),keepdim默认设置的是False,所以第3个维度对应的3消失了,如果keepdim=True,将会保留第3个维度,但是会变成(64,3,3,1)

torch.sign()

torch.sign(input, out=None) → Tensor

该函数的作用就是输出input通过sign函数后的张量,其中sign函数就是符号函数,如下图所示。
在这里插入图片描述

>>> a = torch.tensor([0.7, -1.2, 0., 2.3])
>>> a
tensor([ 0.7000, -1.2000,  0.0000,  2.3000])
>>> torch.sign(a)
tensor([ 1., -1.,  0.,  1.])

detach()

在 PyTorch 中,detach() 方法用于返回一个新的 Tensor,这个 Tensor 和原来的 Tensor 共享相同的内存空间,但是不会被计算图所追踪,也就是说它不会参与反向传播,不会影响到原有的计算图,这使得它成为处理中间结果的一种有效方式,通常在以下两种情况下使用:

  1. 在计算图中间,需要截断反向传播的梯度计算时。例如,当计算某个 Tensor 的梯度时,我们希望在此处截断反向传播,而不是将梯度一直传递到计算图的顶部,从而减少计算量和内存占用。此时可以使用 detach() 方法将 Tensor 分离出来。
  2. 在将 Tensor 从 GPU 上拷贝到 CPU 上时,由于 Tensor 默认是在 GPU 上存储的,所以直接进行拷贝可能会导致内存不一致的问题。此时可以使用 detach() 方法先将 Tensor 分离出来,然后再将分离出来的 Tensor 拷贝到 CPU 上。

detach的例子:
首先detach()方法返回一个新的变量,这个变量跟data tensor共享同一个地址,返回的变量干了两件事:

  1. 将requires_grad = false
  2. 将 grad_fn = None’

当改变返回的变量时会被autograd追踪到,因为in-place保护机制,导致对我想对原变量进行backward()的时候就会报错。出错的机制是因为保护机制.

x=torch.rand(3,4,requires_grad=True)
y=x.detach()
print(x)
print(y)
"""
x    tensor([[0.0745, 0.6469, 0.4452, 0.0843],
        [0.5808, 0.3859, 0.8170, 0.4534],
        [0.7095, 0.2628, 0.8021, 0.9705]], requires_grad=True)
y	 tensor([[0.0745, 0.6469, 0.4452, 0.0843],
        [0.5808, 0.3859, 0.8170, 0.4534],
        [0.7095, 0.2628, 0.8021, 0.9705]])
"""

x=torch.ones(5,requires_grad=True)
y=x.detach()*2
z=y.sum()#y没有梯度
z.backward()#RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
x=torch.ones(5,requires_grad=True)
y=x**2
z=x**3
r=(z+y).sum()
r.backward()
print(x.grad)#tensor([5., 5., 5., 5., 5.])
x=torch.ones(5,requires_grad=True)
y=x**2
z=x.detach()**3
r=(y+z).sum()
r.backward()
#梯度通过y传递
print(x.grad)#tensor([2., 2., 2., 2., 2.])

分别修改x.detach和x.data
修改x.detach 梯度不变

x=torch.ones(5,requires_grad=True)
z=x**2
x.detach=torch.tensor([2,2,2,2,2],dtype=float)
y=x**3
k=(z+y).sum()
k.backward()
print(x.grad)#tensor([5., 5., 5., 5., 5.])

修改x.data梯度改变

x=torch.ones(5,requires_grad=True)
z=x**2
x.data=torch.tensor([2,2,2,2,2],dtype=float)
y=x**3
k=(z+y).sum()
k.backward()
print(x.grad)#tensor([16., 16., 16., 16., 16.], dtype=torch.float64)
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值