pytorch学习笔记1 Tensor的创建、变型与变维、索引、类型

注:本文是笔者结合自己阅读和使用pytorch的经验,又系统学习了一遍https://github.com/chenyuntc/pytorch-book的过程中,将自己认为有必要掌握和记住的知识整理成的学习笔记,并非系统的教程,主要目的是为了方便自己梳理、记忆知识,以及方便有相同需求的读者查阅某些知识。

tensor的创建

1、使用torch.Tensor创建

根据参数不同,具体分为两种

(1)如果参数直接是int,那么表示创建此形状

In [1]: torch.Tensor(2,3,4)
Out[1]: tensor([[[0., 0., 0., 0.],
                 [0., 0., 0., 0.],
                 [0., 0., 0., 0.]],

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

(2)如果参数是list或tuple,表示将这个list或tuple转为tensor

In [1]: torch.Tensor([[1,2,3],[4,5,6]])
Out[1]: tensor([[1., 2., 3.],
                [4., 5., 6.]])


2、使用torch.tensor创建:

参数只能是list或tuple,与torch.Tensor中情况(2)相似

In [1]: torch.tensor([[1,2,3], [4,5,6]])
Out[1]: tensor([[1, 2, 3],
                [4, 5, 6]])


3、使用其他的函数,比如torch.ones, torch.zero, torch.arange等时,参数只能用int表示形状,即torch.Tensor的前一种

常用torch操作

1、torch.view:    

e.g.   a = torch.randn(2,3),b = a.view(-1,6),此时a的形状并没有变,但ab已经共享了内存,如果修改a[1][2],那么b[0][5]也会跟着变

In [1]: a = torch.randn(2,3)
In [2]: b = a.view(-1,6)
In [3]: a[1][2] = 100
In [4]: b
Out[4]: tensor([[ -2.6326,  -0.5585,   0.9266,   1.5645,   1.2182, 100.0000]])

tensor索引

1、区分“变形”和“变维”:形状为(2,3,4)的tensor变成(2,3,2),只“变形”,不“变维”,因为维度仍然是3维

2、用下标进行索引的话,如果其中某一维指定为了一个数而不是一个区间的话,得到的tensor会降维,比如a = torch.randn(2,3,4),则a[:,0,:]的size为(2,4),可见该tensor是降维了;如果所有下标都是区间,那么只可能变形,不可能降维,比如a[:,:2,1:4]的size为(2,2,3),在下标都是区间时,有a[:] = a[:,:],也就是说不说明的维度默认是全部拉满

3、在使用下标进行索引时,可以用None实现增加维度,原则是 哪里写None哪里增加维度:e.g. a = torch.randn(3,4),则a[:,None,:,None,None]的size为(3,1,4,1,1),注意a[None]表示在最前面增维,即a[None]的size为(1,3,4)

4、index_select函数:

index_select(x, dim, index)

x是原始tensor,dim是一个int,表示在哪一维上取数,index是一个一维的LongTensor,里面放的是全部在第dim维要索引的内容;index_select后得到的结果与x相比只变形,不变维,哪怕index里只有一个数

In [1]: a = torch.randn(2,3)
In [2]: a
Out[2]: tensor([[ 8.7729e-01, -1.0760e-03, -4.6932e-01],
                [-8.6138e-02,  1.8144e+00,  1.1691e+00]])
In [3]: indices = torch.LongTensor([0])
In [4]: b = torch.index_select(a, 0, indices)
In [5]: b, b.size()
Out[5]: (tensor([[ 0.8773, -0.0011, -0.4693]]), torch.Size([1, 3]))

5、mask式取值:

mask取值的目的是从一个tensor(假设叫a)中取出其中的一部分值,这些取出的值将构成一个一维的tensor,注意mask式取值的结果一定是一个一维的tensor。至于取哪些值,我们需要一个mask,这个mask与a同形,且它的dtype要求是uint8。比如我们希望从a中取出所有大于0的值

In [1]: a = torch.randn(3,4)
In [2]: a
Out[2]: tensor([[-0.4152,  1.4335,  0.2631, -0.6139],
                [-0.8419, -0.1434,  0.3215,  1.1045],
                [ 0.5557, -1.7449, -0.0087,  0.3759]])

在pytorch中,一个tensor与数字比较得到的就是一个dtype是uint8的同形tensor

In [3]: a > 0
Out[3]: tensor([[0, 1, 0, 0],
                [0, 0, 0, 1],
                [0, 0, 0, 0]], dtype=torch.uint8)

在有了原张量a和mask张量后,两种方法可以实现mask式取值

In [4]: a[a>1] #方法一
Out[4]: tensor([1.4335, 1.1045])
In [5]: torch.masked_select(a, a>1) #方法二
Out[5]: tensor([1.4335, 1.1045])

6、对tensor的任何索引操作仍是一个tensor,想要获取标准的python对象数值,需要调用tensor.item(), 这个方法只对包含一个元素的tensor适用

高级索引

对于一个tensor x,假设其维数为dim,可以用dim个等长的列表进行索引

In [1]: x = torch.arange(0,27).view(3,3,3)
In [2]: x
Out[2]: 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.],
                 [ 24.,  25.,  26.]]])
In [3]: x[[1, 2], [1, 2], [2, 0]] # x[1,1,2]和x[2,2,0]
Out[3]: tensor([ 14.,  24.])

如果dim个列表不等长,则相当于做一个多重的for进行枚举

In [4]: x[[2, 1, 0], [0], [1]] # x[2,0,1],x[1,0,1],x[0,0,1]
Out[4]: tensor([ 19.,  10.,   1.])

还可以使用...,此时返回的不再是一维的tensor

In [5]: x[[0, 2], ...] # x[0] 和 x[2]
Out[5]: tensor([[[  0.,   1.,   2.],
                 [  3.,   4.,   5.],
                 [  6.,   7.,   8.]],

                [[ 18.,  19.,  20.],
                 [ 21.,  22.,  23.],
                 [ 24.,  25.,  26.]]])

tensor类型

根据tensor中元素的数据类型的不同,tensor又分为诸如32位浮点数、64位浮点数、8位整数、16位整数等多种类型;其中,每个数据类型又对应CPU版本和GPU版本两种。第一列表示的就是所有的数据类型。

pytorch学习笔记1 Tensor的创建、变型与变维、索引、类型_第1张图片

1、默认的tensor类型

默认的tensor类型为32位的浮点数类型,也就是第一行。可以通过torch.set_default_tensor_type函数设置默认的tensor类型,其参数是第三列或第四列中的对应值,比如torch.set_default_tensor_type('torch.IntTensor')可以使32位int型tensor作为默认的tensor数据类型

2、特定数据类型tensor的创建

对应本文最开始tensor的创建,创建特定类型的tensor的方式也是有着对应的两种:

(1)使用第三四列创建:比如torch.DoubleTensor(3,4)创建一个3*4的张量,或者torch.LongTensor([2,3,4])创建一个一维张量;其实torch.Tensor创建张量就是这种方法的一个特例,其类型为默认类型

(2)使用torch.tensor方法创建tensor:这时可以通过制定一个参数dtype为第二列中的某一个,实现创建特定数据类型的tensor,比如torch.tensor([[1,4,3], [2,3,6]], dtype=torch.int64)

3、不同数据类型tensor的转换

可以直接调用tensor的type方法,其参数为第三列或第四列中对应的类型

In [1]: a = torch.Tensor(2,3)
In [2]: a.dtype
Out[2]: torch.float32
In [3]: a = a.type(torch.DoubleTensor)
Out[3]: torch.float64

4、GPU与CPU版本的转换

对于一个张量a,在GPU与CPU之间主要有两种方法:

(1)a.cpu() 转换为CPU版本,a.cuda()转换为GPU版本

(2)a.to(device)转换为相应的版本

你可能感兴趣的:(深度学习,人工智能,pytorch)