pytorch tensor一些操作

前言

本博客主要用于记录本人学习pytorch过程中一些笔记,并非零基础入门,方便自己查询,主要是深度学习计算机视觉方向。

一些概念

  1. 深度学习模型输入一般为数个图像构成的张量,张量shape为**[B, C, H, W]**的形式。
  2. torch中分类损失函数如CrossEntropyLoss()BCELoss(),会自动对输入标签进行进行one-hot

以多分类问题为例,输入一张图像,其标签为2,计算时会将其变为(0, 0, 1)。

  1. torch中很多张量操作可以事先给出是在哪个dim上进行操作,这里对dim的理解,参照官方文档,就是以不要这个维度为目的进行的操作
    dim (int or tuple of python:ints) – the dimension or dimensions to reduce

tensor

  1. torch中创建tensor有两种方式。
import torch
torch.Tensor(3, 3)  # 传入的是size
torch.tensor([[1, 2],[3, 4]])  # 传入的就是要创建的张量

tensor维度调整

  1. 在调整shape时,比如reshapeview,如果给定shape中有-1,那么torch会根据其余给定的数据推算-1代表的数值。
  2. 使用transpose进行维度转换时,一次只能交换两个数值,而permute方法一次可交换多个维度。
  3. 使用squeezeunsqueeze可快速减少或添加数字为1的dim。

tensor堆叠

  1. 使用cat可拼接多个张量,可指定维度进行拼接,但除了指定的维度,其他维度上的数字必须相同。

对于两个张量来说,a.shape=(a, b, r),b.shape=(a, b, m),拼接只能在dim=2上进行,最终得到c.shape=(a, b, r+m)。

  1. 使用stack可堆积多个张量,但相较于cat会产生一个新的维度,且要求参与堆积的张量的shape必须一样。

对于两个张量来说,a.shape=(a, b, r),b.shape=(a, b, r),最终得到c.shape=(2, a, b, r)。

import torch
a1 = torch.tensor([1, 2, 3])
a2 = torch.tensor([4, 5, 6])
a = [a1, a2]
c = torch.stack(a, dim=1)
print(c)
d = torch.cat(a, dim=0)
print(d)
tensor([[1, 4],
        [2, 5],
        [3, 6]])
tensor([1, 2, 3, 4, 5, 6])

tensor筛选

  1. torch中常会采用生成一个mask的形式,对原张量中进行某种条件的筛选。

mask是一个与原张量shape相同的bool类型,采用a[mask]所返回的值,只是mask中True对应的值。

import torch
a = torch.tensor([1, 2, 3, 4, 5])
mask = a > 2
print(mask)
print(a[mask])
tensor([False, False,  True,  True,  True])
tensor([3, 4, 5])
  1. torch中nonzero可获取tensor中满足条件的值的索引。

返回索引永远是一个二维张量,shape=(x, y),x表示满足条件的元素数目,y为a的维度,其内容为索引。

通过squeeze可获取到索引

import torch
a = torch.tensor([[[2, 1, 6],
                    [8, 5, 6]],
                    [[2, 1, 6],
                    [8, 5, 6]]])
b = torch.tensor([2, 1, 6, 8, 5, 6])
print(a.shape)
print(torch.nonzero(a > 4))
print('############')
print(torch.nonzero(b > 4))
torch.Size([2, 2, 3])
tensor([[0, 0, 2],
        [0, 1, 0],
        [0, 1, 1],
        [0, 1, 2],
        [1, 0, 2],
        [1, 1, 0],
        [1, 1, 1],
        [1, 1, 2]])
############
tensor([[2],
        [3],
        [4],
        [5]])
  1. torch中where可实现类似nonzero的筛选,但返回值不同。

返回值为一个tuple,len(tuple)等于tensor的dim,以a中第一个满足条件的索引为例,读取方式为(0, 0, 2),取三个tensor相同位置的数值

对于一维张量,取元组第一个即为索引

import torch
a = torch.tensor([[[2, 1, 6],
                    [8, 5, 6]],
                    [[2, 1, 6],
                    [8, 5, 6]]])
b = torch.tensor([2, 1, 6, 8, 5, 6])
print(torch.where(a > 4))
print(torch.where(b > 4))
(tensor([0, 0, 0, 0, 1, 1, 1, 1]), tensor([0, 1, 1, 1, 0, 1, 1, 1]), tensor([2, 0, 1, 2, 2, 0, 1, 2]))
(tensor([2, 3, 4, 5]),)

tensor排序

  1. torch中max可获取原张量进行取大值操作,若不指定dim,只返回一个值,即最大值,若指定dim,返回一个列表,第一个为数值,第二个为索引。
import torch
a = torch.tensor([[6, 3, 2],
                  [1, 5, 9]])
out =torch.max(a, dim=0)
print(out)
print('#####################')
print(out[0])
print(out[1])
torch.return_types.max(
values=tensor([6, 5, 9]),
indices=tensor([0, 1, 1]))
#####################
tensor([6, 5, 9])
tensor([0, 1, 1])
  1. torch中sort可实现与max一样的效果,但返回值不同,第一个返回排序后的数值,第二个返回索引。

默认为升序排列(descending=False)

import torch
a = torch.tensor([[6, 3, 2],
                  [1, 5, 9]])
out =torch.sort(a, dim=0, descending=False)
print(out)
print('#####################')
print(out[0])
print(out[1])
torch.return_types.sort(
values=tensor([[1, 3, 2],
               [6, 5, 9]]),
indices=tensor([[1, 0, 0],
                [0, 1, 1]]))
#####################
tensor([[1, 3, 2],
        [6, 5, 9]])
tensor([[1, 0, 0],
        [0, 1, 1]])
  1. torch.argmax(),或是torch.argsort(),本质用法和sort,max一样,只不过只返回索引,也可指定dim。

tensor替换数值

  1. torch中index_fill可根据索引替换tensor中数值。

torch中某些函数操作后面带有_,如index_fill_,相较于index_fill,直接返回修改后的数据,即:a.index_fill_(),等同于a = a.index_fill()

import torch
a = torch.tensor([[1, 2, 3],
                  [4, 5, 6]])
index = torch.tensor([0, 2])
a.index_fill_(1, index, 0)  # 第一个代表修改的维度,第二个代表修改位置的索引(张量),第三个为填充的数值
print(a)
tensor([[0, 2, 0],
        [0, 5, 0]])

tensor分割

  1. torch中split可对tensor进行分割取出的操作。

可以使用torch.split,也可以使用a.split

import torch
a = torch.tensor([[1, 3, 2],
                  [6, 9, 7]])
print(a.split(split_size=1, dim=0))  # 第一个参数表示分割的尺寸,第二个是维度,torch会自动计算,2/1=2,得到两个张量
(tensor([[1, 3, 2]]), tensor([[6, 9, 7]]))

其他操作

  1. torch中广播操作有时应用十分方便(None)。

广播:如果两个张量的后缘维度(shape),即从末尾开始算起的维度相同,或是其中一方的维度存在1,那么就会认为是广播兼容的,在计算时会自动在缺失或维度为1的方向进行扩充,使运算正常进行。

None的位置即代表维度1添加的位置,对于例子中a就变为(4, 1),这样可以进行广播,如果是a[None, :]这样是不行的

import torch
a = torch.tensor([1, 2, 3, 4])
b = torch.tensor([1, 1, 1])
print(a[:, None] + b)
tensor([[2, 2, 2],
        [3, 3, 3],
        [4, 4, 4],
        [5, 5, 5]])
  1. a.to(b)可以将a转化成与b相同的数据类型和相同GPU或CPU类型。

常见的如a.to(cuda)这种

  1. 创建一个新的Tensor,该Tensor的type和device都和原有Tensor一致,且无内容,创建方法有两种。
import torch
b = a.new()
b = torch.Tensor.new(a)
import torch
a = torch.tensor([1, 2, 3])
b = a.new()
print(b)
print(b.dtype == a.dtype)
print(b.device == a.device)
tensor([], dtype=torch.int64)
True
True
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值