PyTorch中的张量

本文深入介绍了PyTorch中的张量创建、操作和转换方法,包括从数值和Numpy数组创建张量、指定形状和类型、生成固定值张量、随机张量以及线性、对数空间的值。同时,详细阐述了张量的基本操作,如张量的类型转换、数学运算、与Numpy的交互以及在CPU和GPU间的转换。此外,还讨论了张量的维度变换、数据连接、分割、索引选择和过滤等高级操作。
摘要由CSDN通过智能技术生成

定义张量

将已有数值转换成张量

>>> a = torch.tensor(5)
>>> a
tensor(5)
>>> anp = np.asarray([4])
>>> anp
array([4])
>>> a = torch.tensor(anp)
>>> a
tensor([4])

根据指定形状、类型生成张量

>>> torch.get_default_dtype()
torch.float32
>>> torch.set_default_dtype(torch.float64)
>>> torch.get_default_dtype()
torch.float64

# torch.Tensor()既可以指定形状又可以指定内容
>>> a = torch.Tensor(2)
>>> a
tensor([6.9418e-310, 6.9418e-310])

根据指定形状生成固定值的形状

torch.ones(),torch.zeros()  # 生成指定形状、值为1,0的张量数组
torch.ones_like(),torch.zeros_like()  # 生成和目标张量形状相同、值为0的张量数组
torch.randn()  # 函数生成指定形状的随机数张量数组
torch.eye()  # 生成对角矩阵的张量
torch.full()  # 生成全为1的矩阵的向量

生成随机值张量

设置随机值种子

torch.initial_seed()  # 查看随机数种子
torch.manual_seed(2)  # 设置随机数种子
if cuda:
    torch.cuda.manuad_seed()  # 为显卡设置随机种子

通过指定形状生成随机值

torch.randn(2,3)  # 生成指定形状的随机值

生成线性空间的随机值

>>> torch.linspace(1,5,steps=5)
tensor([1., 2., 3., 4., 5.])
>>> torch.arange(1,10,step=2)
tensor([1, 3, 5, 7, 9])

生成对数空间的随机值

>>> torch.logspace(1,9,steps=5)
tensor([1.0000e+01, 1.0000e+03, 1.0000e+05, 1.0000e+07, 1.0000e+09])

生成未初始化的矩阵

>>> torch.empty(1,2)
tensor([[6.4069e+02, 2.7489e+20]])

张量的基本操作

获取张量中元素的个数

>>> a=torch.Tensor(2)
>>> torch.numel(a)
2

张量的判断

>>> torch.is_tensor(a)
True

张量的类型转换

# 通过调用张量类中的type方法,可以实现张量的类型转换
>>> a = torch.FloatTensor([4])
>>> a
tensor([4.])
>>> a.type(torch.IntTensor)
tensor([4], dtype=torch.int32)
>>> a.type(torch.DoubleTensor)
tensor([4.], dtype=torch.float64)

张量类中的重载操作符函数

# 在张量类中定义了加减乘除等操作符同名的重载函数
>>> b = torch.add(a,a)
>>> b
tensor([8.])
>>> torch.add(a,a,out=b)
tensor([8.])
>>> b
tensor([8.])

张量类中的自变化运算函数

# 自变化运算函数是指在变量本身的基础上做运算
# 在pytorch中,所有的自变化运算都会带有一个下划线
>>> a.add_(b)
tensor([12.])
>>> a
tensor([12.])
>>> b
tensor([8.])

张量类中更多的数学运算函数

# pytorch为每个张量封装了强大的属性方法
# 可以在编译器中使用系统自带的提示符找到更多的运算符
>>> a.mean()
tensor(12.)
>>> a.sqrt()
tensor([3.4641])

张量和Numpy间的相互转换、

# 两种方法将numpy转换成张量
a = torch.from_numpy(b)
a = torch.tensor(b)

# 将张量转换成numpy
print(a.numpy())

张量和Numpy各自的形状获取

# 张量
>>> a.size()
torch.Size([1])
>>> a.shape
torch.Size([1])
>>> a.reshape([1,1])
tensor([[12.]])

# numpy
>>> import numpy as np
>>> anp = np.asarray([4,2])
>>> anp.shape
(2,)
>>> anp.size
2

张量和NumPy各自的切片操作

>>> a=torch.rand([1,2])
>>> a
tensor([[0.4032, 0.6065]])
>>> a[:]
tensor([[0.4032, 0.6065]])
>>> anp = np.asarray([4,2])
>>> anp[:]
array([4, 2])

张量和Numpy相互转换的陷阱

# 使用from_numpy转换成tensor时只是简单的给指针赋值,并不会发生复制
# pytorch考虑到这一点如果转换之后的tensor被修改就会触发复制机制
# 但是更改之前的numpy也会导致tensor发生改变
# 如果在对numpy进行变化时,不使用替换内存的操作,则不会遇到这个问题

# 使用torch.tensor()则不会出现上述的情况
>>> anp=np.array([1,2])
>>> x=torch.tensor(anp)
>>> x
tensor([1, 2])
>>> anp
array([1, 2])
>>> anp+=1
>>> anp
array([2, 3])
>>> x
tensor([1, 2])
>>> y=torch.from_numpy(anp)
>>> y
tensor([2, 3])
>>> anp+=1
>>> y
tensor([3, 4])

# 使用了不替换内存的操作也不会发生这样的情况
>>> anp=anp+1
>>> y
tensor([3, 4])

在CPU和GPU控制的内存中定义张量

将CPU内存中的张量复制到GPU内存中

>>> a = torch.FloatTensor([4])
>>> a
tensor([4.])
>>> b=a.cuda()
>>> b
tensor([4.], device='cuda:0')

直接在GPU中定义张量

>>> a= torch.tensor([4],device='cuda:0')
>>> a
tensor([4], device='cuda:0')

使用to()方法来指定设备

>>> a.to("cuda:0")
tensor([4.], device='cuda:0')

使用环境变量CUDA_VISIBLE_DEVICES来指定设备

CUDA_VISIBLE_DEVICES=0 python test.py  # 指定自己的代码在第一块GPU中运行

# 这里也表示在第1块GPU中运行
import os
os.environ["CUDA_VISIBLE_DEVICES"]='0'

张量间的数据操作

用reshape()函数实现数据维度的变换

# 将其转换为一行数据的张量
# 在使用reshape()函数时,要求指定的目标形状必须和原来的输入张量元素个数一致,
# 否则会报错,必须对其进行形状变换
>>> a= torch.tensor([[1,2],[3,4]])
>>> a.shape
torch.Size([2, 2])
>>> torch.reshape(a,(1,-1))
tensor([[1, 2, 3, 4]])

# 使用reshape时必须保持目标形状和原来的输入张量元素个数保持一致
# 在指定形状的过程中,可以使用-1来代表该维度由系统自动计算
a.reshapea((1, -1))
a.view((1, -1))

实现张量数据的矩阵转置

# 定义1个2维张量
>>> b = torch.tensor([[1,2,3],[4,5,6]])
# torch.t()较为简单
>>> torch.t(b)
tensor([[1, 4],
        [2, 5],
        [3, 6]])

# torch.transpose()功能比较强大
>>> torch.transpose(b,dim0=1,dim1=0)
tensor([[1, 4],
        [2, 5],
        [3, 6]])

# 交换0维和第1维
>>> b.permute(1,0)
tensor([[1, 4],
        [2, 5],
        [3, 6]])

view()和contiguous()方法

# view只能作用于整块内存中的连续变量,而pytorch中111的张量有些是由不同的数据块组成,没有分布在# # 整块的内存中。view无法对其变形,同样也无法对用过transpose和permute方法的改变形状后的张量进行
# 变形,通过is_contiguous()方法判断张量的内存是否连续。
# 建议:若要使用view方法,最好配合contiguous()方法一起使用

>>> b.is_contiguous()
True
>>> b.permute(1,0)
tensor([[1, 4],
        [2, 5],
        [3, 6]])
>>> b.is_contiguous()
True
>>> b.is_contiguous().view(-1,0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'bool' object has no attribute 'view'
>>> b.contiguous().view(-1)
tensor([1, 2, 3, 4, 5, 6])
>>> b.is_contiguous()
True
>>> b.contiguous().view(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: shape '[0]' is invalid for input of size 6
>>> b.contiguous().view(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: shape '[1]' is invalid for input of size 6
>>> b.contiguous().view(6,1)
tensor([[1],
        [2],
        [3],
        [4],
        [5],
        [6]])
>>> b.contiguous().view(-1)

用torch.cat()函数实现数据连接

# 将两个张量数据按照指定的维度连接起来
# torch.cat()常用于实现多分支卷积、残差网络、注意力机制等结构

>>> a = torch.tensor([[1,2,3],[4,5,6]])
# 将张量a、b沿着第0维度连接,输出
>>> torch.cat([a,b],dim=0)
tensor([[1, 2, 3],
        [4, 5, 6],
        [1, 2, 3],
        [4, 5, 6]])

# 将张量a、b沿着第1维度连接,输出
>>> torch.cat([a,b],dim=1)
tensor([[1, 2, 3, 1, 2, 3],
        [4, 5, 6, 4, 5, 6]])

用torch.chunk实现数据均匀分割

# torch.chunk可以将一个多维张量按照指定的维度和拆分个数进行分割
# 在语义分割等大型网络中会用到该函数

>>> torch.chunk(a,chunks=2,dim=0)
(tensor([[1, 2, 3]]), tensor([[4, 5, 6]]))

# chunks指用于指定拆分的个数 返回值是一个元组
>>> torch.chunk(a,chunks=3,dim=1)
(tensor([[1],
        [4]]), 
tensor([[2],
        [5]]), 
tensor([[3],
        [6]]))

>>> torch.chunk(a,chunks=2,dim=1)
(tensor([[1, 2],
        [4, 5]]), 
tensor([[3],
        [6]]))

用torch.split()实现数据不均匀分割

# 不均匀分割
>>> torch.split(a, split_size_or_sections=(1,2),dim=1)  # 将张量b沿着第1维度分割成两部分
(tensor([[1],
        [4]]), tensor([[2, 3],
        [5, 6]]))
# 不满足指定个数的剩余数据 将被作为分割数据的一部分

用torch.gather()函数对张量数据继续检索

# 该函数的作用是使张量数据中的值按照指定的索引和顺序进行排列
# 具体用法如下:
b = [[1,2,3],[4,5,6]]
# index 必须是张量类型,而且要与输入的维度相同
>>> torch.gather(b,dim=1,index=torch.tensor([[1,0],[1,2]]))  # 沿着第1维度,按照index的形状进行取值排列

tensor([[2, 1],
        [5, 6]])

torch.index_select(b,dim=0,index=torch.tensor(1))
tensor([[4, 5, 6]])

按照指定的阈值对张量进行过滤

>>> a = torch.tensor([[1,2],[3,4]])
>>> a.ge(2)
tensor([[False,  True],
        [ True,  True]])
>>> mask=a.ge(2)
>>> mask
tensor([[False,  True],
        [ True,  True]])

# 常用的逻辑比较函数有大于gt(),大于等于ge(),小于lt(),小于等于le()

找出张量中的非0值索引

>>> eye = torch.eye(3)
>>> eye
tensor([[1., 0., 0.],
        [0., 1., 0.],
        [0., 0., 1.]])

# 输出对角矩阵中的非0值索引
>>> torch.nonzero(eye)
tensor([[0, 0],
        [1, 1],
        [2, 2]])

根据多个条件对多个张量取值

将b中值大于5和c中值不大于5的元素取出
>>> b= torch.tensor([[5,6,7],[2,8,0]])
>>> c = torch.ones_like(b)
>>> c
tensor([[1, 1, 1],
        [1, 1, 1]])
>>> torch.where(b>5,b,c)
tensor([[1, 6, 7],
        [1, 8, 1]])

根据阈值进行数据截断

# 对于不符合情况的数据进行填充
>>> torch.clamp(b,min=3,max=8)
tensor([[5, 6, 7],
        [3, 8, 3]])

获取数据中最大值、最小值的索引

# torch.argmax()和torch.argmin()用于输出最大值和最小值索引。
# torch.max()和torch.min()函数不仅可以输出最大值和最小值,还可以输出其对应的索引

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hithithithithit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值