常用pytorch语法糖记录及tensor高维索引操作-截止2022.4.23

89 篇文章 11 订阅
65 篇文章 3 订阅

记录一些好的用法:
1.pytorch权重初始化代码,该代码放入nn.Module的初始化网络里。

for m in self.modules():
    if isinstance(m, nn.Conv2d):
        n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
        m.weight.data.normal_(0, math.sqrt(2. / n))
    elif isinstance(m, nn.BatchNorm2d):
        m.weight.data.fill_(1)
        m.bias.data.zero_()

2.生成带层名的网络的便捷方法

        layers = []
        # 下采样,步长为2,卷积核大小为3
        layers.append(("ds_conv", nn.Conv2d(self.inplanes, planes[1], kernel_size=3,
                                stride=2, padding=1, bias=False)))
        layers.append(("ds_bn", nn.BatchNorm2d(planes[1])))
        layers.append(("ds_relu", nn.LeakyReLU(0.1)))
        
        # 加入darknet模块,res_unit   
        self.inplanes = planes[1]
        for i in range(0, blocks):
            layers.append(("residual_{}".format(i), BasicBlock(self.inplanes, planes)))
        return nn.Sequential(OrderedDict(layers))

3.GPU tensor与CPUtensor之间的转换:

CPU张量 ---->  GPU张量, 使用data.cuda()

GPU张量 ----> CPU张量 使用data.cpu()

4.将参数放入字典,由类内字典直接加载:
“将参数写在类内,由字典进行加载,方便参数修改”

_defaults = {
    "sets": {0.5, 1, 1.5, 2},
    "units": [3, 7, 3],
    "chnl_sets": {0.5: [24, 48, 96, 192, 1024],
                  1: [24, 116, 232, 464, 1024],
                  1.5: [24, 176, 352, 704, 1024],
                  2: [24, 244, 488, 976, 2048]}
}
def __init__(self, scale, num_cls):
    super(ShuffleNet_v2, self).__init__()
    self.__dict__.update(self._defaults)

5.torch.tensor更改维度后保持连续性:

.permute(0, 1, 3, 4, 2).contiguous()

6.len(tensor)实际上取的是tensor的dim0的维度;如果dim0刚好为batchsize,可以用for循环遍历每个batchsize的具体内容。

7.两tensor,如a:size(1,2,4)及b:size(3,2,4),经过cat((a,b),0)后只有被cat的维度size改变为两者相加值,为:size(4,2,4)

8.torch.max的用法,,指定dim后,返回指定dim的最大值。同时返回的还有最大值所在dim的下标序号。keepdim=False,默认输出结果降低一个维度,如果True,则输出结果 不降维,只是将其余非max值从返回结果中去除掉。
(max, max_indices) = torch.max(input, dim, keepdim=False)
import torch
a = torch.tensor([[1, 5, 62, 54], [2, 6, 2, 6], [2, 65, 2, 6]])
print(a.shape)
print(‘a:’, a,
‘\n\ntorch.max(a):’, torch.max(a,dim=1),
‘\n\ntorch.max(a, 0):’, torch.max(a, dim=0)
)
输出值为:

a: tensor([[ 1,  5, 62, 54],
        [ 2,  6,  2,  6],
        [ 2, 65,  2,  6]]) 

torch.max(a): torch.return_types.max(
values=tensor([62,  6, 65]),
indices=tensor([2, 1, 1])) 

torch.max(a, 0): torch.return_types.max(
values=tensor([ 2, 65, 62, 54]),
indices=tensor([1, 2, 0, 0]))

当原始数组为3维时,对原始数组使用torch.max,并指定dim=0时,则后两维数组为2维tensor,为
2维tensor的逐元素大小比较。
size(2,3,1),不keepdim时:
dim=0,返回size(3,1)
dim=1,返回size(2,1)
dim=2,返回size(2,3)
keepdim时:
空缺维度补1:
dim=0,返回size(1,3,1)
dim=1,返回size(2,1,1)
dim=2,返回size(2,3,1)

注:dim=1,相当于对(1)找最大值,然后0维个最大值相拼。这种情况很少见。

9.tensor直接比较返回mask:

k=torch.FloatTensor([x for x in range(12)]).reshape(3,2,2)
# #测试:
m=(k>10)
print(m)

输出结果:

tensor([[[False, False],
         [False, False]],

        [[False, False],
         [False, False]],

        [[False, False],
         [False,  True]]])

接着可以将mask对原始数组k使用,返回筛选结果:
print(k[m])
返回的是一维数组:

tensor([11.])

注意,使用mask操作会破坏最外围结构,如果最外层是batchsize,应先用for循环脱去最外维,对里面剩下的维度进行处理,保留处理结果与batchsize之间的关系。
10.
使用unique能产生集合,对类别置信度进行去重

x = torch.tensor([4,0,1,2,1,2,3])
print(x)
out = torch.unique(x) 返回结果默认升序排序
print(out)#将处理结果打印出来
#结果如下:
#tensor([0, 1, 2, 3, 4]) 
out = torch.unique(x,return_counts=True) #返回每个独立元素的个数
print(out)
#输出结果如下
#(tensor([0, 1, 2, 3, 4]), tensor([1, 2, 2, 1, 1])) 

11.unsqueeze函数:快速在指定维度增加1维

k=torch.FloatTensor([x for x in range(12)]).reshape(3,2,2)
print(k.shape)
k=k.unsqueeze(1)
print(k.shape)

输出:

torch.Size([3, 2, 2])
torch.Size([3, 1, 2, 2])

12.torchvision自带nms:

import torch
a=torch.Tensor([[1,1,2,2],[1,1,3.100001,3],[1,1,3.1,3]])
b=torch.Tensor([0.9,0.98,0.980005])
from torchvision.ops import nms
#3个参数为box数组,格式[[x1,y1,x2,y2]],得分tensor[],及阈值,大于该阈值会被舍弃
ccc=nms(a,b,0.4)
print(ccc)
print(a[ccc])

输出结果为:

tensor([2, 0])
tensor([[1.0000, 1.0000, 3.1000, 3.0000],
        [1.0000, 1.0000, 2.0000, 2.0000]])

需要注意的是tensor索引:

a的size为(34)
a[02]为第一维取0,第二维取第3个元素,自动从左向右进行索引,结果为[2].
a[[0,2]]为取第0维中的第0和第3个元素,为:tensor([[1.0000, 1.0000, 2.0000, 2.0000],[1.0000, 1.0000, 3.1000, 3.0000]])
注意用:输出降维的情况:
a=torch.Tensor([[1,1,2,2],[1,1,3.100001,3],[1,1,3.1,3]])
print(a[:,2])
输出:(第一维全要,每个第二维只取一个元素,然后堆叠在一起,输出一个1维序列)
tensor([2.0000, 3.1000, 3.1000])
如果第二维取两个元素:某种程度上相当于特殊的:,输出维度不变
print(a[:,[2,3]])
输出:
tensor([[2.0000, 2.0000],
        [3.1000, 3.0000],
        [3.1000, 3.0000]])

13.不规则间隔索引
比如取0维的第0个和第1个元素:

a=torch.rand(10,3,24,24)
a.index_select(0,torch.tensor([0,2])).shape

输出结果:

torch.Size([2, 3, 24, 24])

14.除法的意义:
a b \frac{a}{b} ba
除法的基本意义是被除数被均分,是以b表示a,b作为单位。
有图片1,其size(a1,a1);经缩放后产生图片2,size(b1,b1)
当图片1以图片2为基准时,设有比例因子scale=a1/b1;该比例用法为,已知图1某长度比例求图2中相同的比例,其实是先乘a1得到实际长度,再除以b1,即乘以该比例因子。

15.用多维tensor做tensor的索引的理解及其输出维度:
a[[0, 1], …] 等价 a[0] 和 a[1],相当于索引张量的第一行和第二行元素

Tensor = torch.FloatTensor(range(24)).view(3,2,4)
a = Tensor[1]
print(a.shape)
a = Tensor[[1]]
print(a.shape)

输出:

torch.Size([2, 4])
torch.Size([1, 2, 4])

a = Tensor[[1]]意义为,第一个维度取1,再组合,故保持3维不变。
扩展有:

Tensor = torch.FloatTensor(range(24)).view(3,2,4)
a = Tensor[[[1],[1]]]
print(a.shape)
a = Tensor[1,1]
print(a.shape)

输出为:

torch.Size([1, 4])
torch.Size([4])

a = Tensor[[[1],[1]]]意义为,第一维取1,第二维取1,再组合,故为torch.Size([1, 4])

16.张量的自动求导特性:
梯度(gradient)是一个向量(矢量,有方向),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大。损失函数沿梯度相反方向收敛最快(既能最快找到极值点)。
梯度下降法在于求解梯度,并依次迭代地让输入x沿梯度的反方向进行移动,当梯度为0时,标志函数取到了一个极值点。
tenor的自动求导属性:
grad:该Tensor对应的梯度,类型为Tensor,并与Tensor同维度。
grad_fn:指向function对象,即该Tensor经过了什么样的操作,用作反向传播的梯度计算,如果该Tensor由用户自己创建,则该grad_fn为None。
通过requires_grad_使tensor变为需要求导的对象。

17.tensor的上下值截取操作:

a=torch.randint(low=0,high=10,size=(10,1))
print(a)
a=torch.clamp(a,3,9)
print(a)

最终结果的各分量值介于3及9之间。

18.梯度累加,每次梯度下降后不立刻将累计梯度值清0,而是做累加,可以在有限内存的情况下,变相扩大批大小,相关代码如下:

for i,(image, label) in enumerate(train_loader):
    pred = model(image)
    loss = criterion(pred, label)
    #使损失值相应减小
    loss = loss / accumulation_steps  
    loss.backward()
    if (i+1) % accumulation_steps == 0:
        # optimizer the net
        optimizer.step()        # update parameters of net
        optimizer.zero_grad()   # reset gradient

原理公式为:
在这里插入图片描述
19.用切片的方法保留维度:虽然同样第二维只取一个元素,但是保留了原始维度

k=torch.rand(3,10)
print(k[:,0])
print(k[:,0:1])

输出结果为:

tensor([0.8416, 0.6899, 0.4022])
tensor([[0.8416],
        [0.6899],
        [0.4022]])

20.重复tensor中的某些维度:
对齐方式是原始tensor和repeat中的元素右对其,原始tensor不够长时,原始tensor最左侧补1,再repeat。

k=torch.FloatTensor([x for x in range(6)]).view(2,3)
print(k)
print(k.repeat(2,1).shape)
k=torch.FloatTensor([x for x in range(6)]).view(2,3)
print(k.repeat(2,1,1).shape)
print(k.repeat(2,1,1))

输出结果为:

tensor([[0., 1., 2.],
        [3., 4., 5.]])
torch.Size([4, 3])
torch.Size([2, 2, 3])
tensor([[[0., 1., 2.],
         [3., 4., 5.]],

        [[0., 1., 2.],
         [3., 4., 5.]]])

21.同形索引直接赋值:

k=torch.FloatTensor([x for x in range(12)]).view(2,3,2)
print(k>3)
k[k>3]=0
print(k)

输出结果:

tensor([[[False, False],
         [False, False],
         [ True,  True]],

        [[ True,  True],
         [ True,  True],
         [ True,  True]]])
tensor([[[0., 1.],
         [2., 3.],
         [0., 0.]],

        [[0., 0.],
         [0., 0.],
         [0., 0.]]])

22.求二值交叉熵函数的使用:

#默认为mean
print(nn.BCELoss()(k,b))
#不做操作时返回原矩阵
print(nn.BCELoss(reduction='none')(k,b))

输出:

tensor(0.8345)
tensor([[0.0166, 1.1610, 0.6610],
        [1.4049, 1.7156, 0.0480]])

23.快速产生指定范围的整形tensor
target = torch.empty(2,3, dtype=torch.long).random_(5)
empty生成未初始化的tensor,.random_(5)将tensor中的每个元素限制在0到5,含0不含5

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PyTorch是一个用于科学计算的开源机器学习库。以下是一些PyTorch的基础语法: 1. 创建张量: 通过torch.tensor()函数创建张量,可以指定张量的形状和数据类型。例如,torch.tensor([2.,3.2])创建了一个形状为的浮点张量。torch.Tensor()函数也可以用于创建张量,可以指定形状作为参数。例如,torch.Tensor(2,3)创建了一个形状为[2,3]的张量。默认情况下,PyTorch的张量类型是torch.FloatTensor。 2. 改变默认类型: 使用torch.set_default_tensor_type()函数可以改变默认张量类型。例如,torch.set_default_tensor_type(torch.DoubleTensor)可以将默认类型改为torch.DoubleTensor。 3. 初始化张量: 使用torch.rand()函数可以创建一个具有随机分布的张量。例如,a1=torch.rand(4,3,16,32)创建了一个形状为[4,3,16,32]的张量。 4. 张量的拼接: 使用torch.cat()函数可以将两个张量沿指定维度拼接在一起。例如,torch.cat([a1,a2], dim=2)可以将a1和a2沿第2个维度拼接在一起,得到形状为[4,3,32,32]的张量。另外,使用torch.stack()函数也可以实现拼接,不同之处在于它会额外创建一个新的维度。例如,torch.stack([a1,a2], dim=2)得到形状为[4,3,2,16,32]的张量。 5. 张量的分割: 使用torch.split()函数可以将一个张量沿指定维度分割成多个子张量。例如,torch.split(b, 2)可以将长度为2的张量b分割成两个子张量。 这些是PyTorch的一些基础语法,可以帮助你开始使用PyTorch进行科学计算和机器学习。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颢师傅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值