『PyTorch』Tensor

1. 张量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Joq48dEn-1581861175874)(E:\我的学习\pytorch\Tensor\fig1.png)]

2. Variable类型(PyTorch 0.4之前)

Variabletorch.autograd中的数据类型,主要用于封装Tensor,进行自动求导

  • data
    被包装的张量
  • grad
    data的梯度
  • grad_fn
    创建Tensor的function,是自动求导的关键
  • requires_grad
    指示是否需要梯度,True表示需要计算梯度,False表示不需要计算梯度
  • is_leaf
    指示是否是叶子结点(张量)

3. Tensor类型(PyTorch 0.4之后)

Variable从PyTorch 0.4之后开始并入Tensor,多了3个主要属性

  • dtype·
    张量的数据类型,如torch.FloatTensortorch.cuda.FloatTensor
  • shape
    张量的形状,类似NumPy数组的shape
  • device
    张量所在设备,GPU/CPU,是加速的关键

4. 创建Tensor

4.1 直接创建

4.1.1 torch.tensor()

  • 函数
torch.tensor(data, dtype=None, device=None,requires_grad=False, pin_memory=False)
  • 功能
    从data创建Tensor

  • 参数

    • data:数据,可以是list,numpy的ndarray
    • dtype:数据类型,默认与data一致
    • device:所在设备,GPU/CPU
    • requires_grad:是否需要计算梯度
    • pin_memory:是否存于锁业内存,通常就是False,与转换效率有关
import torch
import numpy as np

# 通过torch.tensor()创建张量

ary = np.ones((3,3))
print(f"ndarray的数据类型:{ary.dtype}")

t = torch.tensor(ary)
print(t)

s = torch.tensor(ary,device="cuda")
print(s)

输出结果:

ndarray的数据类型:float64
tensor([[1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.]], dtype=torch.float64)
tensor([[1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.]], device=‘cuda:0’, dtype=torch.float64)

4.1.2 torch.from_numpy()

  • 函数
torch.from_numpy(ndarray)
  • 功能
    从NumPy创建Tensor

从torch.from_numpy创建的Tensor与原ndarray共享内存,当修改其中一个数据,另一个也将会被改动

import torch
import numpy as np

# 通过torch.from_numpy()创建张量
ary = np.random.randint(0, 20, size=9).reshape(3, 3)

t = torch.from_numpy(ary)

print(f"ndarray的数据类型为:{ary.dtype}")
print(t)

输出结果:

ndarray的数据类型为:int32
tensor([[13, 17, 3],
            [18, 11, 1],
            [17,  8,  4]], dtype=torch.int32)

4.2 依据数值创建

4.2.1 torch.zeros()

  • 函数
torch.zeros(*size,out=None,dtype=None,layout=torch.strided,device=None,requires_grad=False)
  • 功能
    根据size创建全0张量
  • 参数
    • size:张量的形状
    • out:输出的张量
    • layout:内存中布局形式,有strided,sparse_coo等,一般默认值
import torch
import numpy as np

# 通过torch.zeros()创建全0张量

out_t = torch.tensor([1])

t = torch.zeros((3,3),out=out_t)

print(t)
print(out_t)
print(id(t)==id(out_t))

输出结果:

tensor([[0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]])

tensor([[0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]])
True

4.2.2 torch.zeros_like()

  • 函数
torch.zeros_like(input,dtype=None,layout=None,device=None,requires_grad=False)
  • 功能
    根据input的形状创建全0张量
  • 参数
    • input:张量,创建的全0张量形状与此一致

4.2.3 torch.ones()

参考torch.zeros()

4.2.4 torch.ones_like()

参考torch.zeros_like()

4.2.5 torch.full()

  • 函数
torch.full(size,fill_value,out=None,dtype=None,
           layout=torch.strided,device=None,requires_grad=False)
  • 功能
    根据fill_value的值创建shape为size的张量

4.2.6 torch.full_like()

方法类似

4.2.7 torch.arrange()

  • 函数
torch.arange(end, *, out=None, dtype=None, device:=None, requires_grad=False)

torch.arange(start, end, *, out=None, dtype=None, device=None, requires_grad=False)

torch.arange(start, end, step, *, out=None, dtype=None, device=None, requires_grad=False)
  • 功能
    创建等差的一维张量

注意区间为 [ s t a r t , e n d ) [start, end) [start,end)

4.2.8 torch.linspace()

  • 函数
torch.linspace(start, end, steps=100, *, out=None, dtype=None, 
               layout=strided, device: =None, requires_grad=False)
  • 功能
    创建均分的一维张量,数值区间为 [ s t a r t , e n d ] [start, end] [start,end],steps是该张量元素个数,步长要自己算

4.2.9 torch.logspace()

  • 函数
torch.logspace(start, end, steps=100, base=10.0, *, out=None, 
               dtype=None, layout=strided, device=None, requires_grad=False)
  • 功能
    创建对数均分的一维张量,数值区间为 [ b a s e s t a r t , b a s e e n d ] \displaystyle\Big[{base}^{start}, {base}^{end}\Big] [basestart,baseend],steps是该张量元素个数,步长要自己算
import torch

t = torch.logspace(2, 6, 5, base=2)
print(t)

输出结果:

tensor([ 4., 8., 16., 32., 64.])

从这可以看出,是把 [ s t a r t , e n d ] [start, end] [start,end] 进行等分,得到指数序列 L,然后,输出的Tensor每个元素是 b a s e L [ i ] {base}^{L[i]} baseL[i]

4.2.10 torch.eye()

  • 函数
torch.eye(n, m, *, out=None, dtype=None, layout=strided, device=None, requires_grad=False) 

torch.eye(n, *, out=None, dtype=None, layout=strided, device=None, requires_grad=False)
  • 功能
    创建单位矩阵(二维张量),默认方阵
import torch

t = torch.eye(4)
print(t)

s = torch.eye(3, 4)
print(s)

输出结果:

tensor([[1., 0., 0., 0.],
            [0., 1., 0., 0.],
            [0., 0., 1., 0.],
            [0., 0., 0., 1.]])

tensor([[1., 0., 0., 0.],
            [0., 1., 0., 0.],
            [0., 0., 1., 0.]])

4.3 依据概率分布创建

4.3.1 torch.normal()

  • 均值和标准差都是标量

    • 函数

      torch.normal(mean, std, size, *, generator=None, out=None, 
                   dtype=None, layout=strided, device=None, requires_grad=False)
      
    • 功能
      根据均值mean,标准差std采样,返回的张量shape为size

      t_normal = torch.normal(0, 1., size=(2,3))
      
      print(t_normal)
      

      输出结果:

      tensor([[ 0.4256, -0.6451, -0.2785],
                  [-0.7766, -1.0419, -0.0259]])

  • 均值和标准差都是张量

    • 函数

      torch.normal(mean, std, *, generator=None, out=None) 
      
    • 功能
      返回张量,mean和std的shape必须一致,且返回结果的shape和mean以及std的shape一致,返回结果对应位置的元素值,是根据mean和std的对应位置的值作为均值和标准差采样的

      mean = torch.arange(1, 5, dtype=torch.float)
      std = torch.arange(1, 5, dtype=torch.float)
      t_normal = torch.normal(mean, std)
      print(f"mean:{mean}")
      print(f"std:{std}")
      print(t_normal)
      

      输出结果:

      mean:tensor([1., 2., 3., 4.])
      std:tensor([1., 2., 3., 4.])
      tensor([1.6039, 3.3902, 5.8297, 1.5644])

  • 均值和标准差有一个是张量
    标量会做broadcast处理,参考都是张量的情况

4.3.2 torch.randn()

  • 函数

    torch.rand(size, *, generator=None, out=None, 
                 dtype=None, layout=strided, device=None, requires_grad=False)
    
  • 功能
    [ 0 , 1 ) [0, 1) [0,1)均匀分布中采样,返回shape为size的张量

    torch.rand_like()参考前面类似的like函数

4.3.3 torch.randint()

  • 函数

    torch.randint(low, high, size, *, generator=None, out=None, 
                 dtype=None, layout=strided, device=None, requires_grad=False)
    
    torch.randint(high, size, *, generator=None, out=None, 
                 dtype=None, layout=strided, device=None, requires_grad=False)
    
  • 功能
    [ l o w , h i g h ) [low, high) [low,high)均匀分布中采样,返回shape为size的张量,第二种定义从 [ 0 , h i g h ) [0,high) [0,high)均匀分布采样

    torch.randint_like()参考前面类似的like函数

4.3.4 torch.randperm()

  • 函数

    torch.randperm(n, *, generator, out=None, dtype=None, 
                   layout=strided, device=None, requires_grad=False)
    
  • 功能
    生成从 0 0 0 n − 1 n-1 n1 的随机排列

4.3.5 torch.bernoulli()

  • 函数

    torch.bernoulli(p, *, generator=None, out=None)
    
  • 功能
    p p p 为概率,生成伯努利分布( 0 − 1 0-1 01分布,两点分布)

5. 张量的常用操作

有些方法是可以直接用Tensor对象.方法

5.1 张量的拼接与切分

5.1.1 torch.cat()

  • 函数

    torch.cat(tensors, dim=0, *, out)
    
  • 功能
    将张量按照指定维度拼接

    import torch
    
    t = torch.ones(2, 3)
    
    t_0 = torch.cat([t, t], dim=0)
    t_1 = torch.cat([t, t], dim=1)
    t_2 = torch.cat([t, t, t], dim=1)
    
    print(t)
    print(t_0)
    print(t_1)
    print(t_2)
    

    输出结果:

    tensor([[1., 1., 1.],
                [1., 1., 1.]])

    tensor([[1., 1., 1.],
                [1., 1., 1.],
                [1., 1., 1.],
                [1., 1., 1.]])

    tensor([[1., 1., 1., 1., 1., 1.],
                [1., 1., 1., 1., 1., 1.]])

    tensor([[1., 1., 1., 1., 1., 1., 1., 1., 1.],
                [1., 1., 1., 1., 1., 1., 1., 1., 1.]])

5.1.2 torch.stack()

  • 函数

    torch.stack(tensors, dim=0, *, out=None)
    
  • 功能
    在新创建的维度dim上进行拼接,用到时先实验一下,别想当然,记不住的

    import torch
    
    t = torch.ones(2, 3)
    
    t_stack_0 = torch.stack([t, t, t, t], dim=0)
    t_stack_1 = torch.stack([t, t, t, t], dim=1)
    t_stack_2 = torch.stack([t, t, t, t], dim=2)
    
    print(f"t 的shape:{t.shape}")
    print(f"t_stack_0的shape:{t_stack_0.shape}")
    print(f"t_stack_1的shape:{t_stack_1.shape}")
    print(f"t_stack_2的shape:{t_stack_2.shape}")
    

    输出结果:

    t 的shape:torch.Size([2, 3])
    t_stack_0的shape:torch.Size([4, 2, 3])
    t_stack_1的shape:torch.Size([2, 4, 3])
    t_stack_2的shape:torch.Size([2, 3, 4])

5.1.3 torch.chunk()

  • 函数

    torch.chunk(chunks, dim=0)
    
  • 功能
    将张量按维度dim进行平均切分,返回张量列表
    【注意】若不能整除,最后一个张量小于其他张量

    import torch
    
    t = torch.ones(2, 7)
    
    tensors = torch.chunk(t, dim=1, chunks=3)
    
    for index, tensor in enumerate(tensors):
        print(f"第{index + 1}个张量:{tensor},shape is {tensor.shape}")
    
    

    输出结果:

    第1个张量: tensor([[1., 1., 1.],
                                  [1., 1., 1.]]),shape is torch.Size([2, 3])

    第2个张量: tensor([[1., 1., 1.],
                                   [1., 1., 1.]]),shape is torch.Size([2, 3])

    第3个张量: tensor([[1.],
                                  [1.]]),shape is torch.Size([2, 1])

5.1.4 torch.split()

  • 函数

    torch.split(tensor, split_size_or_sections, dim=0)
    
  • 功能
    将张量按维度dim进行切分,返回张量列表

  • 参数

    • split_size_or_sections
      • int时,表示每一份的长度
      • list时,按list元素大小切分(元素和要和切割的维度上元素数一致)
    import torch
    
    t = torch.ones(2, 5)
    
    tensors = torch.split(t, 3, dim=1)
    tensors1 = torch.split(t, [2, 1, 2], dim=1)
    
    for index, tensor in enumerate(tensors):
        print(f"第{index + 1}个张量:{tensor},shape is {tensor.shape}")
    
    for index, tensor in enumerate(tensors1):
        print(f"第{index + 1}个张量:{tensor},shape is {tensor.shape}")
        
    

    输出结果:

    第1个张量: tensor([[1., 1., 1.],
                                   [1., 1., 1.]]),shape is torch.Size([2, 3])

    第2个张量: tensor([[1., 1.],
                                   [1., 1.]]),shape is torch.Size([2, 2])

    第1个张量: tensor([[1., 1.],
                                   [1., 1.]]),shape is torch.Size([2, 2])

    第2个张量: tensor([[1.],
                                   [1.]]),shape is torch.Size([2, 1])

    第3个张量: tensor([[1., 1.],
                                   [1., 1.]]),shape is torch.Size([2, 2])

5.2 张量的索引

5.2.1 torch.index_select()

  • 函数

    torch.index_select(tensor, dim, index, *, out=None)
    
  • 功能
    在维度dim上,按照index索引数据,返回搜索结果拼接而成的张量
    【注意】index必须是long类型的一维Tensor

    import torch
    
    t = torch.randint(0, 9, size=(3, 3))
    idx = torch.tensor([0, 2], dtype=torch.long)  # 作为索引,这里必须是long
    t_select = torch.index_select(t, dim=1, index=idx)
    
    print(t)
    print(t_select)
    

    输出结果:

    tensor([[4, 7, 2],
                [7, 3, 7],
                [7, 5, 7]])
    tensor([[4, 2],
                [7, 7],
                [7, 7]])

5.2.2 torch.mask_select()

  • 函数

    torch.masked_select(tensor, mask, *, out=None)
    
  • 功能
    按mask中的True进行索引,返回一维张量

    import torch
    
    t = torch.randint(0, 9, size=(3, 3))
    mask = t.ge(5)  # ge:>= , gt:> ,  le  ,  lt
    t_select = torch.masked_select(t, mask)
    
    
    print(t)
    print(mask)
    print(t_select)
    

    输出结果:

    tensor([[0, 4, 8],
                [2, 7, 5],
                [6, 7, 6]])

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

    tensor([8, 7, 5, 6, 7, 6])

5.3 张量变换

5.3.1 torch.reshape()

  • 函数

    torch.masked_select(tensor, mask, *, out=None)
    
  • 功能
    重塑形状,但是元素个数要对的上

    import torch
    
    t = torch.randint(0, 9, size=(3, 3))
    
    print(t)
    
    t = t.reshape(1, -1)
    s = torch.reshape(t, (1, -1))
    
    print(t)
    print(s)
    

    输出结果:

    tensor([[3, 4, 8],
                [7, 8, 1],
                [1, 3, 0]])
    tensor([[3, 4, 8, 7, 8, 1, 1, 3, 0]])
    tensor([[3, 4, 8, 7, 8, 1, 1, 3, 0]])

  • 注意——内存共享

    import torch
    
    t = torch.randint(0, 9, size=(3, 3))
    
    print(t)
    
    s = t.reshape(1, -1)
    s[0][2] = 100  # 内存共享,更改它也会影响原Tensor
    
    print(s)
    print(t)
    

    输出结果:

    tensor([[5, 3, 7],
                [0, 4, 5],
                [3, 0, 7]])

    tensor([[ 5, 3, 100, 0, 4, 5, 3, 0, 7]])

    tensor([[ 5, 3, 100],
                [ 0, 4,     5],
                [ 3, 0,     7]])

5.3.2 torch.transpose()

  • 函数

    torch.transpose(dim0, dim1)
    
  • 功能
    交换两个维度,比如一般卷积神经网络输入channel×height×width,交换0和1维,然后交换1和2维,得到height×width×channel

    import torch
    
    t = torch.randint(0, 24, size=(2, 3, 4))
    
    print(t.shape)
    
    s = t.transpose(0, 2)
    
    print(s.shape)
    

    输出结果:

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

5.3.3 torch.t()

  • 功能:转置二维张量

5.3.4 torch.squeeze()

  • 功能

    压缩长度为1的轴

    • 不输入参数,则移除所有长度为1的维度
    • 若指定维度,则当且仅当该维度长度为1时,可以删除该维度

5.3.5 torch.unsqueeze()

  • 功能
    扩充张量维度

    import torch
    
    t = torch.ones(2, 3, 4)
    
    print(t.shape)
    
    s = t.unsqueeze(2)
    p = t.unsqueeze(0)
    print(s.shape)
    print(p.shape)
    

    输出结果:

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

6. 张量的数学运算

需要用到时查询使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值