赞
踩
Pytorch框架为深度学习提供了一个很好的平台,使用Pytorch框架完成深度学习任务时,对于数据类型,一般情况下都是对tensor类型进行操作,我们可以把tensor类型的数据叫做张量,其实,掌握对tensor的操作是十分重要的,这牵涉到我们对于代码中数据变换的理解,如果对tensor操作熟练的话,我们会很快地通过代码看出数据是如何变化的。以下是我觉得比较重要的操作:
这里有一个同化定理:向整数tensor中插入浮点数,浮点数会被自动截断为整数;向浮点数tensor中插入整数,整数会被升级为浮点数。同时,如果整数张量和浮点数张量做运算的话,最后的结果张量会变成浮点型。(这个大家自己去验证,在此不作代码演示了)
比如我们想知道一个tensor的形状是什么样,我们可以直接调用.shape来查看该张量的形状,同时我们也可以把张量的形状作为参数进行一些张量初始化等等(比如初始化一个全零张量arr = torch.zeros((1,1,2,3)))
在进行数据维度变换的时候,我们通常需要使用reshape()函数进行操作,这个函数方便之处在于我们可以给定了其他维度的值之后,剩下一个维度可以直接填0,不需要去计算。比如:
- #创建一个0-14的一维张量
- x = torch.arange(15)
- print(x)
- #将该张量转化为三行五列的二维张量
- y = x.reshape(3, -1)
- print(y)
x = torch.tensor([1, 2, 3])
- #创建一个0-14的一维张量
- y = torch.arange(15)
- #创建1-20每隔2个数取一次的一维张量
- z = torch.arange(1, 21, 2)
- #全零张量
- arr1 = torch.zeros((2, 2))
- #全一张量
- arr2 = torch.ones((2, 2, 3))
- #创建一个符合标准正态分布的三维张量
- arr1 = torch.randn(2, 2, 2)
- #创建一个在0-1之间均匀分布的一维张量
- arr2 = torch.rand(10)
- #创建一个0-5递增的一维张量,访问该一维张量的第三个元素
- x = torch.arange(5)
- print(x[2])
- #创建一个1-15递增的一维张量,然后将其重塑为三行五列的二维张量
- arr1 = torch.arange(1, 16).reshape(3, 5)
- #获取该二维张量的0-1行
- print(arr1[ :2, :])
- #获取0-2列
- print(arr1[:, : 3])
- #获取0-1行的0-1列
- print(arr1[ :2, :2])
- #从第0行开始每隔两行获取,从第0列开始,每隔两列获取
- print(arr1[: :2, : : 2])
- #创建一个1-15的一维张量
- arr2 = torch.arange(1, 16)
- #将该张量掐头去尾
- arr = arr2[1:-1]
- #改变arr的第一个元素(其实是改变了arr2张量的第二个元素)
- arr[0] = 100
- print(arr2)
-
- #输出:tensor([ 1, 100, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
这里注意,切片仅仅是视图,系统为了节约内存,并没有为arr变量重新创建一个张量,而是将arr2的视图传递给了arr,如果改变arr,那么arr2相应的元素也会发生改变,解决方法如下:
- #创建一个1-15的一维张量
- arr2 = torch.arange(1, 16)
- #将该张量掐头去尾,并复制成为新的张量
- arr = arr2[1:-1].clone()
- #改变arr的第一个元素(其实是改变了arr2张量的第二个元素)
- arr[0] = 100
- print(arr2)
-
- #输出:tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
- x = torch.ones(4, 3, 24, 24)
- print(x.transpose(1, 2).shape)
- print(x.permute(1, 0, 2, 3).shape)
- '''
- output:
- torch.Size([4, 24, 3, 24])
- torch.Size([3, 4, 24, 24])
- '''
这里隆重介绍两个张量翻转的函数:transpose和permute,这两个函数在功能上是一样的,但是在使用上会有一些不同,transpose函数只有两个参数,这两个参数代表维度,并且维度顺序可以随便写,比如transpose(0,1)和transpose(1,0)是一样的,都是交换第0个维度和第1个维度的元素;permute函数的参数必须是该张量的所有维度,并且维度顺序是按照最后你所需要的维度顺序写的。
- #创建一个1-30的一维张量,并把它重塑为(3,2,5)的张量
- x = torch.arange(1, 31).reshape(3, 2, -1)
- print(x)
- '''
- 输出:
- tensor([[[ 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, 27, 28, 29, 30]]])
- '''
- #两个二维张量可以按不同维度进行拼接,但是拼接时必须注意维度的吻合
- arr1 = torch.tensor([[1, 2, 3], [4, 5, 6]])
- arr2 = torch.tensor([[7, 8, 9], [10, 11, 12]])
- #按第一个维度拼接
- arr3 = torch.cat([arr1, arr2]) #axis = 0
- print(arr3)
- '''
- output:tensor([[ 1, 2, 3],
- [ 4, 5, 6],
- [ 7, 8, 9],
- [10, 11, 12]])
- '''
- #按第二个维度拼接
- arr4 = torch.cat([arr1, arr2], axis=1)
- print(arr4)
- '''
- output:tensor([[ 1, 2, 3, 7, 8, 9],
- [ 4, 5, 6, 10, 11, 12]])
- '''
注意张量的运算具有广播性质,一个张量和一个常数做运算时,张量中的每一个元素都要和这个数做运算,接下来主要说一下广播:
当一个(*,x,y)形状的张量和一个一维张量运算时,该一维张量的形状必须为y
- arr = torch.ones(2, 2, 3)
- y = torch.tensor([1, 2, 3])
- print(arr + y)
- '''
- output:tensor([[[2., 3., 4.],
- [2., 3., 4.]],
- [[2., 3., 4.],
- [2., 3., 4.]]])
- '''
- x = torch.ones(2, 3)
- y = torch.ones(3, 4)
- print(x @ y) #也可以记为torch.matmul(x, y)
- arr = torch.arange(16).reshape(4, 4)
- arr = arr * 1.
- #求最大值
- print(torch.max(arr, axis=0))
- print(torch.max(arr, axis=1))
- print(torch.max(arr))
- #求和
- print(torch.sum(arr, axis=0))
- print(torch.sum(arr, axis=1))
- print(torch.sum(arr))
- #求均值和标准差
- print(torch.mean(arr))
- print(torch.std(arr))
- arr = torch.arange(16).reshape(4, 4)
- print(arr > 6)
- print(torch.sum(arr > 6)) #统计arr张量中元素大于6的元素的个数
- '''
- output:tensor([[False, False, False, False],
- [False, False, False, True],
- [ True, True, True, True],
- [ True, True, True, True]])
- tensor(9)
- '''
一般来说,布尔型张量做掩码都是对张量中的元素进行筛选,筛选之后的张量变为一维张量
- arr = torch.arange(16).reshape(4, 4)
- print(arr[arr > 6])
- '''
- output:tensor([ 7, 8, 9, 10, 11, 12, 13, 14, 15])
- '''
返回索引位置:
- arr = torch.arange(16).reshape(4, 4)
- #找出最大元素所在的位置
- print(torch.where(arr == torch.max(arr)))
- #找出元素大于8的所有元素的位置
- print(torch.where(arr > 8))
-
- '''
- output:(tensor([3]), tensor([3]))
- (tensor([2, 2, 2, 3, 3, 3, 3]), tensor([1, 2, 3, 0, 1, 2, 3]))
- '''
最后提供一个比较全面的视频:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。