Pytorch 深度学习常用函数记录

view()

l= torch.arange(0,10) * 2
print(l.view(2,5))
print(l.view(2,-1))

result:

tensor([[ 0,  2,  4,  6,  8],
       [10, 12, 14, 16, 18]])
tensor([[ 0,  2,  4,  6,  8],
       [10, 12, 14, 16, 18]])

expand()

把tensor扩展成size的形状

x = torch.tensor([1, 2, 3])
print(x.expand(3, 3))
print(x) # 没有分配新的内存
tensor([[1, 2, 3],
        [1, 2, 3],
        [1, 2, 3]])
tensor([1, 2, 3])

expand_as()

把tensor_1扩展成和tensor_2一样的形状

mat1 = torch.randn((2,1,1))
mat2 = torch.randn((2,4,2))
mat1 = mat1.expand_as(mat2)
print(mat1.shape)
torch.Size([2, 4, 2])

repeat()

print(x.repeat(2,4))
print(x)
tensor([[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3],
        [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]])
tensor([1, 2, 3])

感觉就是对第 i 维度重复 n 次

tensor维度中使用None

import torch
tensor = torch.randn(3, 4)
print('tensor size:', tensor.size())
tensor_1 = tensor[:, None]
print('tensor_1 size:', tensor_1.size())
tensor_2 = tensor[:, :, None]
print('tensor_2 size', tensor_2.size())
tensor size: torch.Size([3, 4])
tensor_1 size: torch.Size([3, 1, 4])
tensor_2 size torch.Size([3, 4, 1])

从实验结果可以看出, None 功能类似torch.unsqueeze(),方便扩展维度,而不改变数据排列顺序。

stack()

沿着一个新的维度对张量进行拼接

T1 = torch.tensor([[1, 2, 3],
        		[4, 5, 6],
        		[7, 8, 9]])
T2 = torch.tensor([[10, 20, 30],
        		[40, 50, 60],
        		[70, 80, 90]])
print(torch.stack((T1,T2),dim=0).shape)
print(torch.stack((T1,T2),dim=1).shape)
print(torch.stack((T1,T2),dim=2).shape)
print(torch.stack((T1,T2),dim=-1).shape) # 按照最后一维度进行拼接
print(torch.stack((T1,T2),dim=3).shape) # 报错!
# outputs:
torch.Size([2, 3, 3])
torch.Size([3, 2, 3])
torch.Size([3, 3, 2])
torch.Size([3, 3, 2])

cat()

将两个张量(tensor)拼接在一起

A = torch.ones((2,3))
B = torch.ones((4,3)) * 2
print(A)
print(B)
C = torch.cat((A,B),dim=0) # shape:6,3
print(C)
# D = torch.cat((A,B),dim=1) # 报错,2 and 4 dimension error
# print(D)
D = torch.cat((A,torch.ones(2,4) * 3),dim=1)
print(D)
tensor([[1., 1., 1.],
        [1., 1., 1.]])
tensor([[2., 2., 2.],
        [2., 2., 2.],
        [2., 2., 2.],
        [2., 2., 2.]])
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [2., 2., 2.],
        [2., 2., 2.],
        [2., 2., 2.],
        [2., 2., 2.]])
tensor([[1., 1., 1., 3., 3., 3., 3.],
        [1., 1., 1., 3., 3., 3., 3.]])

any()

any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True。
注:元素除了是 0、空、FALSE 外都算 TRUE。

tmp = torch.randn((2,1,2))
print(torch.zeros_like(tmp))
print(torch.zeros_like(tmp).shape)
tensor([[[0., 0.]],

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

new_full()

tmp = torch.randn((2,3,2))
t = tmp.new_full((2,),100)
print(t)
print(tmp.device == t.device)
tensor([100., 100.])
True

permute()

维度换位

tmp = torch.randn((1,3,2))
print(tmp.shape)
print(tmp.permute(2,0,1).shape)
torch.Size([1, 3, 2])
torch.Size([2, 1, 3])

nn.GroupNorm()

输入通道被分成num_groups组,每个组包含num_channels / num_groups个通道。分别计算每组的平均值和标准差。

    mat = torch.randn((2,6,10,10))
    bn1 = nn.GroupNorm(3,6)  # 划分成3组,每组进行batchnorm
    print(bn1(mat))
    bn2 = nn.GroupNorm(6,6)
    print(bn2(mat))
    bn3 = nn.GroupNorm(1,6)
    print(bn3(mat))

torch.contiguous()

返回一个内存连续的有相同数据的tensor,如果原tensor内存连续,则返回原tensor

contiguous一般与transpose,permute,view搭配使用:使用transpose或permute进行维度变换后,调用contiguous,然后方可使用view对维度进行变形(如:tensor_var.contiguous().view() ),如下:

    mat = torch.Tensor(5,6)
    y = mat.permute(1,0) # 等价于 transpose
    # y.view(-1)  # 会报错
    y = mat.permute(1,0).contiguous()
    y.view(-1)
    print(y.shape)

报错原因分析:
1.transpose、permute等维度变换操作后tensor在内存中不再是连续存储的,而view操作要求tensor的内存连续存储,所以需要contiguous来返回一个contiguous copy;

2.维度变换后的变量是之前变量的浅拷贝,指向同一区域,即view操作会连带原来的变量一同变形,这是不合法的,所以也会报错;---- 这个解释有部分道理,也即contiguous返回了tensor的深拷贝contiguous copy数据

torch.unsqueeze()

返回一个新的张量,对输入的既定位置插入维度 1

注意: 返回张量与输入张量共享内存,所以改变其中一个的内容会改变另一个

x = torch.Tensor(range(24))
x = torch.reshape(x,(2,3,4))
print(x.shape)

x1 = torch.unsqueeze(x,0)
print(x1.shape)
print(x1)
x2 = torch.unsqueeze(x,1)
print(x2.shape)
torch.Size([2, 3, 4])
torch.Size([1, 2, 3, 4])
tensor([[[[ 0.,  1.,  2.,  3.],
          [ 4.,  5.,  6.,  7.],
          [ 8.,  9., 10., 11.]],

         [[12., 13., 14., 15.],
          [16., 17., 18., 19.],
          [20., 21., 22., 23.]]]])
torch.Size([2, 1, 3, 4])

sequeeze()

对数据的维度进行压缩,去掉维数为1的的维度

    x = torch.randn(8).reshape(2,1,1, 4)
    print(x.shape)
    y = torch.squeeze(x)
    x[0][0] = 100
    print(x)
    print(y.shape)
    print(y)  # 可见两者共享同一块内存
torch.Size([2, 1, 1, 4])
tensor([[[[ 1.0000e+02,  1.0000e+02,  1.0000e+02,  1.0000e+02]]],


        [[[ 7.9778e-01, -6.9345e-01,  7.1565e-03,  3.3529e-01]]]])
torch.Size([2, 4])
tensor([[ 1.0000e+02,  1.0000e+02,  1.0000e+02,  1.0000e+02],
        [ 7.9778e-01, -6.9345e-01,  7.1565e-03,  3.3529e-01]])

torch tensor 索引操作

    x = torch.Tensor(range(120))
    x = torch.reshape(x,(4,3,2,5)) # 可以看成 4张图片 每张图片3个通道 每个通道的(维度)size是2*5
    print(x[0].shape)
    print(x[0,0].shape)
    print(x[0,0,0].shape)
    print(x[0,0,0,0])
    print('-' * 40)
    # 采用切片
    print(x[2:,:,:,:].shape)
    print(x[1:2,2:,-2:,:].shape)
    print(x[:,:,::2,::2].shape)
    print('-' * 40)
    # 采用 ... 索引任意多的维度
    print(x[...].shape)
    print(x[0,...].shape)  # 第一张图片的所有维度
    print(x[:,1,...].shape)  # 所有图片第2通道的所有维度
    print(x[...,:2].shape) # 所有图片所有通道所有行的第一、二列
    print(x[...,::2].shape) # 所有图片所有通道所有行的奇数列
torch.Size([3, 2, 5])
torch.Size([2, 5])
torch.Size([5])
tensor(0.)
----------------------------------------
torch.Size([2, 3, 2, 5])
torch.Size([1, 1, 2, 5])
torch.Size([4, 3, 1, 3])
----------------------------------------
torch.Size([4, 3, 2, 5])
torch.Size([3, 2, 5])
torch.Size([4, 2, 5])
torch.Size([4, 3, 2, 2])
torch.Size([4, 3, 2, 3])

Tensor.reshape()

重新修改Tensor的形状,但是依旧是原来的哪一块内存

x = torch.Tensor(range(24))
y = x.reshape(-1, 6)
print(x.shape)
x[0]= 100
print(y.shape)
print(x)
print(y) # 共用同一块内存
torch.Size([24])
torch.Size([4, 6])
tensor([100.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,  11.,
         12.,  13.,  14.,  15.,  16.,  17.,  18.,  19.,  20.,  21.,  22.,  23.])
tensor([[100.,   1.,   2.,   3.,   4.,   5.],
        [  6.,   7.,   8.,   9.,  10.,  11.],
        [ 12.,  13.,  14.,  15.,  16.,  17.],
        [ 18.,  19.,  20.,  21.,  22.,  23.]])

torch.nn.functional.linear()

对输入的数据应用线性变换 y = x A T + b y = xA^T+b y=xAT+b

    x = torch.Tensor(range(24))
    y = x.reshape(-1, 6)
    print(y.shape)
    linear = nn.Linear(6,8)
    out = linear(y)
    print(out.shape)
torch.Size([4, 6])
torch.Size([4, 8])

torch.nonzero() / Tensor.nonzero

    x = torch.randn(8).reshape(-1, 4)
    x[0][2] = x[1][3] = x[1][1] = 0
    print(x)
    # nonzero_idx = x.nonzero() # 官方建议 使用 torch.nonzero()代替
    nonzero_idx = torch.nonzero(x)
    print(nonzero_idx)
tensor([[-0.0937,  0.6384,  0.0000, -0.3853],
        [-0.7973,  0.0000,  0.4418,  0.0000]])
tensor([[0, 0],
        [0, 1],
        [0, 3],
        [1, 0],
        [1, 2]])
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值