定义张量
将已有数值转换成张量
>>> 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()函数不仅可以输出最大值和最小值,还可以输出其对应的索引