• Pytorch张量操作


    1.数据类型

    如何表示string?

    • One-hot         [0,1,0,0,...]
    • Embedding    Word2vec,glove

    类型推断

    1 #type check
    2 a=torch.randn(2,3)       
    3 print(a.type())                            #torch.FloatTensor
    4 print(type(a))                             #<class 'torch.Tensor'>  这种情况比较少
    5 print(isinstance(a, torch.FloatTensor))    #True

    标量

    1 #标量 dimension 0/rank 0(常用于loss)
    2 b=torch.tensor(1.3)
    3 print(b)                 #tensor(1.3000)
    4 print(b.shape)           #torch.Size([])  成员
    5 print(len(b.shape))      #0
    6 print(b.size())          #torch.Size([])  成员函数

    张量

     1 #张量 dimension 1(常用于bias)
     2 print(torch.tensor([1.1]))    #tensor([1.1000]) 指定具体数据,可以是N维
     3 print(torch.FloatTensor(1))   #tensor([9.6429e-39]) 指定具体维度,随机初始化
     4 data=np.ones(2)
     5 print(torch.from_numpy(data)) #tensor([1., 1.], dtype=torch.float64) 从numpy引入
     6 
     7 c=torch.ones(2)
     8 print(c.shape)                #torch.Size([2])
     9 
    10 #张量 dimension 2
    11 d=torch.randn(2,3)
    12 print(d)
    13 #tensor([[-1.8543, -0.7280,  0.6671],
    14 #        [ 1.1492, -0.6379, -0.4835]])
    15 print(d.shape)          #torch.Size([2, 3])
    16 print(d.shape[0])       #2
    17 print(d.size(1))        #3    
    18 
    19 #张量 dimension 3
    20 f=torch.rand(1,2,3)
    21 print(f)
    22 #tensor([[[0.3690, 0.5702, 0.2382],
    23 #         [0.3130, 0.5591, 0.3829]]])
    24 print(f.shape)         #torch.Size([1, 2, 3])
    25 print(f[0])            #取第一个维度
    26 #tensor([[0.4535, 0.4307, 0.6469],
    27 #        [0.1591, 0.0778, 0.4489]])
    28 print(f[0][1])         #tensor([0.1591, 0.0778, 0.4489])

    四维适合表示图片类型

    eg:a=torch.rand(b,c,h,w)表示b张c通道、h*w的图片

    1 a=torch.rand(2,3,28,28)
    2 print(a.numel())       #4704 全部元素个数
    3 print(a.dim())         #4 维度数量 

    2.创建Tensor

     1 #方法一:import from numpy
     2 a=np.ones([2,3])
     3 print(torch.from_numpy(a))
     4 #tensor([[1., 1., 1.],
     5 #        [1., 1., 1.]], dtype=torch.float64)
     6 
     7 #方法二:import from List
     8 print(torch.tensor([[2.,3.2],[1.,22.3]]))
     9 #tensor([[ 2.0000,  3.2000],
    10 #        [ 1.0000, 22.3000]])

    Tip:torch.tensor接受现成的数据

             torch.Tensor/torch.FloatTensor接受shape或者现成的数据

    未初始化的方法(作为容器,要用其他类型把数据覆盖掉):

    • torch.empty()
    • torch.FlostTensor(d1,d2,d3)
    • torch.IntTensor(d1,d2,d3)
    1 #设置默认类型
    2 print(torch.tensor([1.2,3]).type())               #torch.FloatTensor(不设定的话,默认值)
    3 torch.set_default_tensor_type(torch.DoubleTensor)
    4 print(torch.tensor([1.2,3]).type())               #torch.DoubleTensor

    随机初始化

    1 #rand [0,1]
    2 a=torch.rand(2,2)
    3 print(a)
    4 print(torch.rand_like(a))         #根据a的形状生成,也可用dtype指定新类型
    5 
    6 #randint [min,max)不包含max
    7 print(torch.randint(1,10,[3,3]))  #第1个参数是min,第二个参数是max,第三个参数是shape

    正态分布

    1 #正态分布
    2 print(torch.randn(3,3))         #N(0,1)
    3 print(torch.normal(mean=torch.full([10],0),std=torch.arange(1,0,-0.1)))    #normal得到的维度为1
    4 #tensor([ 0.1445, -0.5133, -0.5565,  0.0831,  0.1350,  0.1023, -0.6264, -0.1651, 0.2856,  0.0187])

    其他

     1 #ones全1,zeros全0,eye对角,ones_like
     2 print(torch.full([2,3],7))             #第一个参数是shape,第二个参数是value
     3 #tensor([[7., 7., 7.],
     4 #        [7., 7., 7.]])
     5 print(torch.full([], 7))               #tensor(7.) 生成标量
     6 
     7 #生成 [0,n-1]的等差数列
     8 print(torch.arange(0,10,2))            #tensor([0, 2, 4, 6, 8])
     9 
    10 #[0,10]等间距切割成steps份
    11 print(torch.linspace(0, 10, steps=6))  #tensor([ 0.,  2.,  4.,  6.,  8., 10.])
    12 print(torch.logspace(0, 1, steps=5))   #tensor([ 1.0000,  1.7783,  3.1623,  5.6234, 10.0000])
    13 
    14 
    15 #randperm
    16 print(torch.randperm(10))             #tensor([8, 5, 2, 4, 7, 1, 3, 9, 6, 0])
    17 
    18 a=torch.rand(2, 3) 
    19 idx=torch.randperm(2)
    20 print(idx)                            #tensor([1, 0])
    21 print(a[idx])
    22 #tensor([[0.6159, 0.9362, 0.5502],
    23 #        [0.9774, 0.6772, 0.2909]])

    3.索引与切片

    1 #切片与索引
    2 a=torch.rand(4,3,28,28)
    3 print(a[0].shape)               #torch.Size([3, 28, 28])
    4 print(a[0,0].shape)             #torch.Size([28, 28])
    5 print(a[0,0,2,4])               #tensor(0.7309)
    6 
    7 print(a[:2,:1].shape)           #torch.Size([2, 1, 28, 28])  等价于a[:2,:1,:,:].shape
    8 print(a[:,:,::2,::2].shape)     #torch.Size([4, 3, 14, 14])

    使用特定索引index_select

    1 #select by specific index
    2 print(a.index_select(2, torch.arange(8)).shape)  #torch.Size([4, 3, 8, 28])  第1个参数表示维度,第2个参数表示索引号(Tensor类型)
    3 #...表示任意多的维度
    4 print(a[0,...].shape)           #torch.Size([3, 28, 28])
    5 print(a[:,1,...].shape)         #torch.Size([4, 28, 28]) 

    使用掩码索引masked_select

    1 #select by mask
    2 x=torch.randn(3,4)
    3 mask=x.ge(0.5)                  #greater equal大于等于
    4 print(mask)
    5 #tensor([[False,  True, False, False],
    6 #        [ True, False, False,  True],
    7 #        [ True, False,  True, False]])
    8 torch.masked_select(x, mask)    #tensor([1.1361, 0.5963, 0.6286, 0.5664, 0.5152]) 维度为1

    take索引(在原来Tensor的shape基础上打平,然后在打平后的Tensor上进行索引)

    1 #select by flatten index
    2 src=torch.tensor([[4, 3, 5],[6, 7, 8]])
    3 print(torch.take(src,torch.tensor([0, 2, 5])))  #tensor([4, 5, 8])

    4.维度变换

     reshape/view可以调整Tensor的shape,返回一个新shape的Tensor

    1 a=torch.rand(4,1,28,28)
    2 print(a.view(4,28*28).shape)        #torch.Size([4, 784])
    3 print(a.reshape(4*28,28).shape)     #torch.Size([112, 28])

    unsqueeze(index)增加维度

    index的范围[-a.dim()-1,a.dim()+1)    eg.a的维度=4,范围是[-5,5)

    新增加的这一个维度不会改变数据本身,只是为数据新增加了一个组别,这个组别是什么由我们自己定义。

     1 a=torch.rand(4,1,28,28)
     2 print(a.unsqueeze(0).shape)         #torch.Size([1, 4, 1, 28, 28]
     3 
     4 b=torch.tensor([1.2, 2.3])          #torch.Size([2])
     5 print(b.unsqueeze(0))               #tensor([[1.2000, 2.3000]])   torch.Size([2, 1])
     6 print(b.unsqueeze(-1)) 
     7 #tensor([[1.2000],
     8 #        [2.3000]])
     9 
    10 x=torch.rand(32)
    11 y=torch.rand(4,32,14,14)
    12 x=x.unsqueeze(1).unsqueeze(2).unsqueeze(0)      #[32]->[32,1]->[32,1,1]->[1,32,1,1]
    13 print(x.shape)                                  #torch.Size([1, 32, 1, 1])) 再进行扩展即可计算x+y 

    squeeze(index)删减维度,删除size=1的维度

    1 a=torch.rand(1,32,1,1)
    2 print(a.squeeze().shape)             #torch.Size([32])  不指定维度就挤压全部
    3 print(a.squeeze(0).shape)            #torch.Size([32, 1, 1])
    4 print(a.squeeze(-1).shape)           #torch.Size([1, 32, 1])
    5 print(a.squeeze(1).shape)            #torch.Size([1, 32, 1, 1])  size不等于1,删减不了

    expand维度扩展:broadcasting(只是改变了理解方式,并没有增加数据)

    某个size=1的维度上扩展size

    1 x=torch.rand(32)
    2 y=torch.rand(4,32,14,14)
    3 x=x.unsqueeze(1).unsqueeze(2).unsqueeze(0)      #[32]->[32,1]->[32,1,1]->[1,32,1,1]
    4 print(x.shape)                                  # torch.Size([1, 32, 1, 1])
    5 
    6 print(x.expand(4,32,14,14).shape)               #torch.Size([4, 32, 14, 14])
    7 print(x.expand(-1,32,3,-1).shape)               #torch.Size([1, 32, 3, 1])  -1指该维度不变
    8 
    9 print((x.expand(4,32,14,14)+y).shape)           #torch.Size([4, 32, 14, 14])

    repeat维度重复:memory copied(增加了数据)

    repeat会重新申请内存空间,repeat()参数表示各个维度指定的重复次数。

    1 a=torch.rand(1,32,1,1)
    2 print(a.repeat(4,32,1,1).shape)                 #torch.Size([4, 1024, 1, 1])
    3 print(a.repeat(4,1,1,1).shape)                  #torch.Size([4, 32, 1, 1])

    转置操作

    .t操作指适用于矩阵

    1 a=torch.rand(3, 4)
    2 print(a.t().shape)                             #torch.Size([4, 3])

    transpose维度交换

    1 a=torch.rand(4,3,32,32)
    2 b=a.transpose(1, 3).contiguous().view(4,3*32*32).view(4,32,32,3).transpose(1, 3)               
    3 #[b,c,h,w]->[b,w,h,c]->[b,whc]->[b,w,h,c]->[b,c,h,w]  展开时按原来的顺序展开whc对应32,32,3
    4 print(torch.all(torch.eq(a,b)))                       #tensor(True)

    permute

    四个维度表示的[batch,channel,h,w] ,如果想把channel放到最后去,形成[batch,h,w,channel],那么如果使用前面的维度交换,至少要交换两次(先13交换再12交换)。而使用permute可以直接指定维度新的所处位置,更加方便。

    1 b=torch.rand(4,3,28,32)
    2 print(b.transpose(1, 3).shape)                      #torch.Size([4, 32, 28, 3])
    3 print(b.transpose(1, 3).transpose(1, 2).shape)      #torch.Size([4, 28, 32, 3])
    4 
    5 print(b.permute(0,2,3,1).shape)                     #torch.Size([4, 28, 32, 3]
  • 相关阅读:
    【Unity】校验身份证号有效性
    【Unity】敏感词过滤
    【C#】2.C#程序结构
    常用Git命令手册
    Android删除指定路径下指定前缀或后缀的文件
    《Android源码设计模式》学习笔记之ImageLoader
    Android截屏的几种实现
    react 项目 合并单元格解决方案
    iconfont字体图标的使用方法(转)
    如何让antd的Modal组件的确认和取消不显示(或自定义按钮)(转载)
  • 原文地址:https://www.cnblogs.com/cxq1126/p/13211147.html
Copyright © 2020-2023  润新知