PyTorch框架详解(1)
目录
代码会放在每条解释的后面
一.概念:
2.张量的概念:
3.张量的创建
4.张量的数据类型及转换
二.tensor和numpy互转
三.张量的运算
四.索引的操作
五.张量形状操作
维度交换:
六.张量拼接操作
代码会放在每条解释的后面
一.概念:
pytorch是基于python语言的深度学习框架,它将数据封装成张量来进行处理
安装:pip install torch
2.张量的概念:
张量(tensor)就是元素为同一种数据类型的多维矩阵。在pytorch中,张量以“类”的形式封装起来。只有张量有GPU加速功能
3.张量的创建
Ⅰ张量的基本创建方式:
① torch.tensor(data=,dtype=) : 只能指定数据,dtype指定类型
②torch.Tensor(data=, size=()):既能指定数据,又能指定形状
③torch.IntTensor()/FloatTensor()...:Tensor直接指定类型创建
import numpy as np
import torch# TODO 1.tensor(data)创建张量
print(torch.tensor(10).ndim)
print(torch.tensor([10]).ndim)
print(torch.tensor([[10]]).ndim)
print(torch.tensor([[[10]]]).ndim)
# 通过列表创建张量
print(torch.tensor([[10, 20], [40, 50]]), torch.tensor([[10, 20], [40, 50]]).dtype)
# 通过numpy创建张量
print(torch.tensor(np.array([[10, 20], [40, 50]])))
print('----------------------------------------')
# dtype 指定类型创建张量
t1 = torch.tensor([[10, 20], [40, 50]], dtype=torch.float)
print(t1, t1.dtype)
# TODO 注意: 浮点数转为整数会丢失精度,自动向下取整
t1 = torch.tensor([[10.9, 20.9], [40.9, 50.9]], dtype=torch.int)
print(t1)
print('===============================================')
# TODO 2.Tensor(data,size)创建张量
print(torch.Tensor(5)) # 指定形状
print(torch.Tensor(2, 3)) # 指定形状
print(torch.Tensor(size=(2, 3))) # 指定形状
print(torch.Tensor([10]).ndim)
print(torch.Tensor([[10]]).ndim)
print(torch.Tensor([[[10]]]).ndim)
# 通过列表创建张量
print(torch.Tensor([[10, 20], [40, 50]]), torch.tensor([[10, 20], [40, 50]]).dtype)
# 通过numpy创建张量
print(torch.Tensor(np.array([[10, 20], [40, 50]])))
print('----------------------------------------')
# TODO 3.IntTensor/FloatTensor创建张量
print(torch.ShortTensor([[10, 20]]))
print(torch.IntTensor([[10, 20]]))
print(torch.LongTensor([[10, 20]]), torch.LongTensor([[10, 20]]).dtype)
print(torch.HalfTensor([[10, 20]]))
print(torch.FloatTensor([[10, 20]]), torch.FloatTensor([[10, 20]]).dtype)
print(torch.DoubleTensor([[10, 20]]))
结果:
0
1
2
3
tensor([[10, 20],[40, 50]]) torch.int64
tensor([[10, 20],[40, 50]], dtype=torch.int32)
----------------------------------------
tensor([[10., 20.],[40., 50.]]) torch.float32
tensor([[10, 20],[40, 50]], dtype=torch.int32)
===============================================
tensor([-2.1644e+09, 1.0608e-42, 0.0000e+00, 0.0000e+00, 0.0000e+00])
tensor([[-2.1644e+09, 1.0608e-42, 0.0000e+00],[ 0.0000e+00, 0.0000e+00, 0.0000e+00]])
tensor([[-2.1645e+09, 1.0608e-42, 0.0000e+00],[ 0.0000e+00, 0.0000e+00, 0.0000e+00]])
1
2
3
tensor([[10., 20.],[40., 50.]]) torch.int64
tensor([[10., 20.],[40., 50.]])
----------------------------------------
tensor([[10, 20]], dtype=torch.int16)
tensor([[10, 20]], dtype=torch.int32)
tensor([[10, 20]]) torch.int64
tensor([[10., 20.]], dtype=torch.float16)
tensor([[10., 20.]]) torch.float32
tensor([[10., 20.]], dtype=torch.float64)
Ⅱ 线性和随机张量:
线性张量:
① torch.arange(start=,end=,step=)
② torch.linspace(start=,end=,steps=)
start: 开始位置
end: 结束位置(含)
steps: 个数
随机张量:
①torch.rand():
随机生成0到1的浮点数
②torch.randn(size=()):
随机生成正态分布的浮点数
③torch.randint(low=,high=,size=()):
随机生成整数
④ 随机种子:
设置:manual_seed(常数)
查看:initial_seed()
Ⅲ 0/1/指定值张量:
① torch.zeros/ones(size=):
根据指定形状直接生成全0/全1的张量
② torch.zeros_like/ones_like(input=tensor):
根据指定张量的形状间接生成全0/全1的张量
③ torch.full(size=, fill_value=):
根据指定形状和指定值生成张量
④ torch.full_like(input=tensor, fill_value=):
根据指定张量的形状和指定值生成张量
import torch# TODO 1.创建线性张量
# arange() 包左不包右
print(torch.arange(10))
print(torch.arange(2, 10))
print(torch.arange(2, 10, 2))
print('-------------------------------------')
# linspace() 包左包右
print(torch.linspace(2, 10, 5))
print(torch.linspace(2, 10, 6))
print('==================================================')
# TODO 2.创建随机张量
print(torch.rand(2, 3)) # rand随机生成0-1的浮点数张量
print(torch.randn(2, 3)) # randn随机生成正态分布的浮点数张量
print(torch.randint(10, (2, 3))) # randint随机生成整数张量
print(torch.randint(10, 20, (2, 3)))
print('--------------------------------------')
# TODO 随机种子的设置和获取
# manual_seed() : 设置随机种子,保证随机数生成一致
print(torch.manual_seed(666))
print(torch.rand(2, 3))
print(torch.randn(2, 3))
print(torch.randint(10, (2, 3)))
print(torch.randint(10, 20, (2, 3)))
# initial_seed(): 获取当前随机种子
print(torch.initial_seed())
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
tensor([2, 3, 4, 5, 6, 7, 8, 9])
tensor([2, 4, 6, 8])
-------------------------------------
tensor([ 2., 4., 6., 8., 10.])
tensor([ 2.0000, 3.6000, 5.2000, 6.8000, 8.4000, 10.0000])
==================================================
tensor([[0.1639, 0.6426, 0.6234],[0.8373, 0.1003, 0.0621]])
tensor([[-0.5436, -2.3693, 0.0441],[-0.1403, -1.1286, 0.7755]])
tensor([[3, 3, 4],[2, 6, 3]])
tensor([[15, 14, 17],[10, 10, 10]])
--------------------------------------
<torch._C.Generator object at 0x000001DFBD18F510>
tensor([[0.3119, 0.2701, 0.1118],[0.1012, 0.1877, 0.0181]])
tensor([[-0.7581, -1.0902, 0.2354],[ 0.0240, 1.4281, -0.2853]])
tensor([[1, 6, 2],[8, 9, 7]])
tensor([[10, 18, 15],[11, 15, 11]])
666
4.张量的数据类型及转换
Ⅰ张量只能是数值类型
① 整数
short->int16
int -> int32
long -> int64
② 浮点数
half -> float16
float -> float32
double -> float64
③ 布尔
④ 复数
Ⅱ创建有类型的张量:
torch.tensor
torch.int位数/torch.float位数
torch.Tensor
Ⅲ张量.类型函数()
half()/float()/double()/int()/long()
import torch# 创建一个张量,然后数据类型转换
data = torch.randint(0, 10, [2, 5])
print(data.dtype)
# TODO 张量.类型函数()
print(data.short())
print(data.int())
print(data.long())
print(data.half())
print(data.float())
print(data.double())
print('==========================================')
# TODO 张量.type(指定类型)
# 类型转换方式1 torch.小写类型名
print(data.type(torch.short))
print(data.type(torch.int))
print(data.type(torch.long), data.type(torch.long).dtype)
print(data.type(torch.half))
print(data.type(torch.float), data.type(torch.float).dtype)
print(data.type(torch.double))
print('--------------------------')
# 类型转换方式2 torch.int位数/torch.float位数
print(data.type(torch.int16))
print(data.type(torch.int32))
print(data.type(torch.int64))
print(data.type(torch.float16))
print(data.type(torch.float32))
print(data.type(torch.float64))
print('--------------------------')
# 类型转换方式3 torch.大写类型Tensor 有警告
print(data.type(torch.ShortTensor))
print(data.type(torch.IntTensor))
print(data.type(torch.LongTensor))
print(data.type(torch.HalfTensor))
print(data.type(torch.FloatTensor))
print(data.type(torch.DoubleTensor))
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]], dtype=torch.int16)
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]], dtype=torch.int32)
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]])
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]], dtype=torch.float16)
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]])
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]], dtype=torch.float64)
==========================================
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]], dtype=torch.int16)
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]], dtype=torch.int32)
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]]) torch.int64
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]], dtype=torch.float16)
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]]) torch.float32
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]], dtype=torch.float64)
--------------------------
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]], dtype=torch.int16)
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]], dtype=torch.int32)
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]])
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]], dtype=torch.float16)
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]])
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]], dtype=torch.float64)
--------------------------
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]], dtype=torch.int16)
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]], dtype=torch.int32)
tensor([[9, 0, 3, 2, 0],[5, 6, 1, 3, 7]])
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]], dtype=torch.float16)
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]])
tensor([[9., 0., 3., 2., 0.],[5., 6., 1., 3., 7.]], dtype=torch.float64)
二.tensor和numpy互转
1.张量转换成numpy数组:
① tensor.numpy():共享内存
②tensor.numpy().copy():不共享内存
import numpy as np
import torch# TODO 1.numpy数组转换为张量
# todo from_numpy()将numpy数组转换为张量,但是共享内存
# 创建numpy数组
n1 = np.array([1, 2, 3])
t1 = torch.from_numpy(n1)
print(n1, type(n1))
print(t1, type(t1))
# 演示from_numpy()结果共享内存
n1[0] = 100
print(n1, id(n1))
print(t1, id(t1))
print('------------------------------')
# todo torch.tensor(ndarray)将numpy数组转换为张量,不会共享内存
# 创建numpy数组
n2 = np.array([1, 2, 3])
t2 = torch.tensor(n2)
print(n2, type(n2))
print(t2, type(t2))
# 演示tensor(ndarray)结果不共享内存
n2[0] = 200
print(n2, id(n2))
print(t2, id(t2))
print('========================================================')
# TODO 2.张量转换为numpy数组
# todo numpy()将张量转换为numpy数组
# 创建张量
t3 = torch.tensor([1, 2, 3])
# 转换
n3 = t3.numpy()
print(t3, type(t3))
print(n3, type(n3))
# 演示numpy()结果共享内存
t3[0] = 300
print(t3, id(t3))
print(n3, id(n3))
print('------------------------------')
# todo numpy().copy()将张量转换为numpy数组
# 创建张量
t4 = torch.tensor([1, 2, 3])
# 转换
n4 = t4.numpy().copy()
print(t4, type(t4))
print(n4, type(n4))
# 演示numpy().copy()结果不共享内存
t4[0] = 300
print(t4, id(t4))
print(n4, id(n4))
tensor([1, 2, 3], dtype=torch.int32) <class 'torch.Tensor'>
[100 2 3] 2510262623120
tensor([100, 2, 3], dtype=torch.int32) 2510261756992
------------------------------
[1 2 3] <class 'numpy.ndarray'>
tensor([1, 2, 3], dtype=torch.int32) <class 'torch.Tensor'>
[200 2 3] 2508302536304
tensor([1, 2, 3], dtype=torch.int32) 2510316399552
========================================================
tensor([1, 2, 3]) <class 'torch.Tensor'>
[1 2 3] <class 'numpy.ndarray'>
tensor([300, 2, 3]) 2510317607008
[300 2 3] 2508296293040
------------------------------
tensor([1, 2, 3]) <class 'torch.Tensor'>
[1 2 3] <class 'numpy.ndarray'>
tensor([300, 2, 3]) 2508302991680
[1 2 3] 2508295928208
2.numpy数组转换成张量
torch.from_numpy(data=ndarray)
共享内存
torch.tensor(data=ndarray)
不共享内存
3.仅有一个元素的张量和标量互转
torch.tensor(标量)
tensor.item()
import torch# TODO 标量转张量
a1 = 10
t1 = torch.tensor(a1)
print(a1, type(a1))
print(t1, type(t1))
print('------------------')
# TODO 张量转标量
a2 = t1.item()
print(t1, type(t1))
print(a2, type(a2))
10 <class 'int'>
tensor(10) <class 'torch.Tensor'>
------------------
tensor(10) <class 'torch.Tensor'>
10 <class 'int'>
三.张量的运算
1.基本运算
可以直接进行运算的符号:+ - * /
add()/sub()/mul()/div()/neg()
add_()/sub_()/mul_()/div_()/neg_():修改原数据
import torch# TODO 张量的加减乘除负号基本运算
t1 = torch.tensor([[1, 2], [3, 4]])
print(t1 + 2)
print(t1 - 2)
print(t1 * 2)
print(t1 / 2)
print('----------------------')
print(torch.add(t1, 2))
print(torch.sub(t1, 2))
print(torch.mul(t1, 2))
print(torch.div(t1, 2))
print(torch.neg(t1))
print('----------------------')
# TODO add_, sub_, mul_, div_, neg_直接修改原有张量,但是类型不能变更
print(t1)
t1.add_(2)
print(t1)
t1.sub_(2)
print(t1)
t1.mul_(2)
print(t1)
# t1.div_(2) # 注意:除以2后结果是浮点类型,原来数据是整数类型,此行报错! 因为不能直接变更原有张量元素类型
t1.neg_()
print(t1)
[5, 6]])
tensor([[-1, 0],[ 1, 2]])
tensor([[2, 4],[6, 8]])
tensor([[0.5000, 1.0000],[1.5000, 2.0000]])
----------------------
tensor([[3, 4],[5, 6]])
tensor([[-1, 0],[ 1, 2]])
tensor([[2, 4],[6, 8]])
tensor([[0.5000, 1.0000],[1.5000, 2.0000]])
tensor([[-1, -2],[-3, -4]])
----------------------
tensor([[1, 2],[3, 4]])
tensor([[3, 4],[5, 6]])
tensor([[1, 2],[3, 4]])
tensor([[2, 4],[6, 8]])
tensor([[-2, -4],[-6, -8]])
2.点乘运算
元素级乘法, 对应位置的元素进行相乘,相乘的两个张量形状必须相同
mul()/*
3.矩阵乘法运算
方法: 行*列, 行每个数据和列每个数据相乘求和
规则: (n, m) * (m, p) =(n, p)
@/torch.matmul()
import numpy as np
import torch# 矩阵的乘法运算 已知A(n,m)和B(m,p)
# 如果A列=B行, 则A和B可以相乘. 结果是C(n,p)
# 创建张量
A = torch.tensor([[1, 2], [3, 4], [5, 6]])
B = torch.tensor([[5, 6], [7, 8]])
# TODO 张量(矩阵)乘法运算 @和matmul
# 方式1: @
print(A @ B)
print('-----------------------')
# 方式2: torch.matmul
print(torch.matmul(A, B))
print('-----------------------')
# TODO 张量中有dot()函数,但是只能用于一维张量!!!
# C3 = torch.dot(A, B) # todo 报错,因为torch中dot只支持1维!!!
print(torch.dot(A[0], B[0]))
print('=================================================')
# TODO 回顾numpy的矩阵乘法运算
AA = np.array([[1, 2], [3, 4], [5, 6]])
BB = np.array([[5, 6], [7, 8]])
print(AA @ BB)
print('-----------------------')
print(np.matmul(AA, BB))
print('-----------------------')
print(np.dot(AA, BB)) # todo numpy中dot可以用于2维!!!
print('-----------------------')
print(np.dot(AA[0], BB[0])) # numpy中dot可以用于1维!!!
tensor([[19, 22],[43, 50],[67, 78]])
-----------------------
tensor([[19, 22],[43, 50],[67, 78]])
-----------------------
tensor(17)
=================================================
[[19 22][43 50][67 78]]
-----------------------
[[19 22][43 50][67 78]]
-----------------------
[[19 22][43 50][67 78]]
-----------------------
17
4.张量运算函数
① min/max/mean/sum(dim=)
不设置dim参数, 对所有元素进行计算
设置dim参数, 对应维度元素进行计算
② sqrt():平方根, 开根号
③ log()/log2()/log10()/log1p():对数
④ pow(exponent=):幂次方 x^n
⑤ exp():指数 e^x
# 张量的其他运算函数
import torch# 设置随机种子(方便使用统一数据)
torch.manual_seed(666)
# 创建张量
t = torch.randint(1, 10, (2, 3), dtype=torch.float64)
print(t)
print('----------------------------------------------')
# TODO 演示sum()/mean()/max()/min()/pow()/sqrt()/log()/log2()/log10()/exp()
print(t.sum())
print(t.sum(dim=0)) # dim=0,按列求和
print(t.sum(dim=1)) # dim=1 按行求和
print('----------------------------------------------')
print(t.mean())
print(t.mean(dim=0)) # dim=0 按列求均值
print(t.mean(dim=1)) # dim=1 按行求均值
print('----------------------------------------------')
print(t.max()) # 打印t的最大值
print('----------------------------------------------')
print(t.min()) # 打印t的最小值
print('----------------------------------------------')
print(t.pow(2)) # 打印t的平方
print(t.pow(3)) # 打印t的立方
print('----------------------------------------------')
print(t.sqrt()) # 打印t的平方根
print('----------------------------------------------')
print(t.log()) # 打印t的自然对数
print(t.log2()) # 打印t的以2为底的对数
print(t.log10()) # 打印t的以10为底的对数
print('----------------------------------------------')
print(t.exp()) # 打印t的指数函数结果:以e为底,tensor中每个元素的指数函数结果
print('----------------------------------------------')
# 回顾math
import mathprint(math.e)
[7., 4., 7.]], dtype=torch.float64)
----------------------------------------------
tensor(36., dtype=torch.float64)
tensor([13., 8., 15.], dtype=torch.float64)
tensor([18., 18.], dtype=torch.float64)
----------------------------------------------
tensor(6., dtype=torch.float64)
tensor([6.5000, 4.0000, 7.5000], dtype=torch.float64)
tensor([6., 6.], dtype=torch.float64)
----------------------------------------------
tensor(8., dtype=torch.float64)
----------------------------------------------
tensor(4., dtype=torch.float64)
----------------------------------------------
tensor([[36., 16., 64.],[49., 16., 49.]], dtype=torch.float64)
tensor([[216., 64., 512.],[343., 64., 343.]], dtype=torch.float64)
----------------------------------------------
tensor([[2.4495, 2.0000, 2.8284],[2.6458, 2.0000, 2.6458]], dtype=torch.float64)
----------------------------------------------
tensor([[1.7918, 1.3863, 2.0794],[1.9459, 1.3863, 1.9459]], dtype=torch.float64)
tensor([[2.5850, 2.0000, 3.0000],[2.8074, 2.0000, 2.8074]], dtype=torch.float64)
tensor([[0.7782, 0.6021, 0.9031],[0.8451, 0.6021, 0.8451]], dtype=torch.float64)
----------------------------------------------
tensor([[ 403.4288, 54.5982, 2980.9580],[1096.6332, 54.5982, 1096.6332]], dtype=torch.float64)
----------------------------------------------
2.718281828459045
四.索引的操作
作用:根据索引获取对应位置的数据
1. tensor[0轴下标, 1轴下标, ...]
从左到右从0开始, 0->第一个数据
从右到左从-1开始, -1->最后一个数据
2. 下标取值
tensor[0]->0轴第一个数据
tensor[:, 0] ->1轴第一个数据
3. 列表取值
tensor[[0,1], [2,4]]->0轴第1个1轴第3个值, 0轴第2个1轴第5个值
4.范围取值(切片)
tensor[起始索引:结束索引:步长,...]
5. 布尔取值
tensor[:, 0]>10:判断1轴第1组数据大于10->返回T/F
tensor[tensor[:, 0]>10]:获取True对应的0轴数据
import torch# 提前设置随机数种子,保证数据统一
torch.manual_seed(666)
# 创建张量
data = torch.randint(0, 10, (4, 5))
print(data)
print('======================================')
# TODO 演示索引获取数据格式为: 张量[行,列]
# TODO 注意: 行列表现形式:单个 列表 切片 布尔索引
# TODO 1.演示单个索引获取数据
# 需求: 获取张量中第2行数据
print(data[1, :])
print(data[1,])
print(data[1])
print('-------------------------------')
# 需求: 获取张量中第2列数据
print(data[:, 1])
print('======================================')
# TODO 2.演示列表指定多个索引获取数据
# 需求: 获取张量中第1行和第3行数据
print(data[[0, 2], :])
print('-------------------------------')
# 需求: 获取张量中第1列和第3列数据
print(data[:, [0, 2]])
print('-------------------------------')
# 需求: 获取张量中第1行和第3行数据中第1列和第3列数据
# TODO 注意: 如果用以下方式的话:它是自动把找的(0,0)(2,2)两个位置的数据
print(data[[0, 2], [0, 2]])
# TODO 如果要真正拿到符合当前需求的数据,需要用列表嵌套的方式
print(data[[[0], [2]], [0, 2]])
print('======================================')
# TODO 3.演示切片获取数据
# 需求: 获取张量中第1行到第3行数据
print(data[0:3, :])
print(data[:3, :])
print('-------------------------------')
# 需求: 获取张量中第1列到第3列数据
print(data[:, 0:3])
print(data[:, :3])
print('======================================')
# TODO 4.演示布尔索引
# 需求: 获取张量中数据大于5的数据
print(data[data > 5])
print('-------------------------------')
# 需求: 判断第1行数据是否大于5
print(data[0] > 5) # tensor([False, False, True, True, False])
# 需求: 先判断第1行是否大于5,根据布尔索引获取数据
print(data[:, torch.tensor([False, False, True, True, False])])
print(data[:, data[0] > 5])
print('-------------------------------')
# 需求: 判断第1列数据是否大于3
print(data[:, 0] > 3) # tensor([False, False, True, False])
# 需求: 先判断第1列是否大于3,根据布尔索引获取数据
print(data[torch.tensor([False, False, True, False]), :])
print(data[data[:, 0] > 3, :])
[2, 7, 0, 4, 7],[5, 4, 1, 8, 5],[0, 2, 9, 1, 6]])
======================================
tensor([2, 7, 0, 4, 7])
tensor([2, 7, 0, 4, 7])
tensor([2, 7, 0, 4, 7])
-------------------------------
tensor([4, 7, 4, 2])
======================================
tensor([[0, 4, 9, 8, 4],[5, 4, 1, 8, 5]])
-------------------------------
tensor([[0, 9],[2, 0],[5, 1],[0, 9]])
-------------------------------
tensor([0, 1])
tensor([[0, 9],[5, 1]])
======================================
tensor([[0, 4, 9, 8, 4],[2, 7, 0, 4, 7],[5, 4, 1, 8, 5]])
tensor([[0, 4, 9, 8, 4],[2, 7, 0, 4, 7],[5, 4, 1, 8, 5]])
-------------------------------
tensor([[0, 4, 9],[2, 7, 0],[5, 4, 1],[0, 2, 9]])
tensor([[0, 4, 9],[2, 7, 0],[5, 4, 1],[0, 2, 9]])
======================================
tensor([9, 8, 7, 7, 8, 9, 6])
-------------------------------
tensor([False, False, True, True, False])
tensor([[9, 8],[0, 4],[1, 8],[9, 1]])
tensor([[9, 8],[0, 4],[1, 8],[9, 1]])
-------------------------------
tensor([False, False, True, False])
tensor([[5, 4, 1, 8, 5]])
tensor([[5, 4, 1, 8, 5]])
多维索引
import torch
# 提前设置种子
torch.manual_seed(666)
# 创建三位张量
data = torch.randint(1, 10, (3, 4, 5))
print(data)
print(data[:, :, :])
# 格式: data[0轴索引,1轴索引,2轴索引]
print('----------------------------------')
# 获取0轴上的第一个数据
print(data[0, :, :])
print(data[0])
print('----------------------------------')
# 获取1轴上的第一个数据
print(data[:, 0, :])
print('----------------------------------')
# 获取2轴上的第一个数据
print(data[:, :, 0])
[7, 1, 4, 7, 4],[9, 7, 1, 2, 1],[4, 9, 4, 9, 2]],[[9, 7, 9, 8, 1],[1, 9, 3, 8, 8],[6, 5, 9, 1, 6],[2, 8, 2, 5, 4]],[[8, 3, 4, 1, 3],[7, 8, 4, 7, 9],[5, 3, 1, 9, 2],[6, 6, 1, 4, 2]]])
tensor([[[6, 4, 8, 7, 4],[7, 1, 4, 7, 4],[9, 7, 1, 2, 1],[4, 9, 4, 9, 2]],[[9, 7, 9, 8, 1],[1, 9, 3, 8, 8],[6, 5, 9, 1, 6],[2, 8, 2, 5, 4]],[[8, 3, 4, 1, 3],[7, 8, 4, 7, 9],[5, 3, 1, 9, 2],[6, 6, 1, 4, 2]]])
----------------------------------
tensor([[6, 4, 8, 7, 4],[7, 1, 4, 7, 4],[9, 7, 1, 2, 1],[4, 9, 4, 9, 2]])
tensor([[6, 4, 8, 7, 4],[7, 1, 4, 7, 4],[9, 7, 1, 2, 1],[4, 9, 4, 9, 2]])
----------------------------------
tensor([[6, 4, 8, 7, 4],[9, 7, 9, 8, 1],[8, 3, 4, 1, 3]])
----------------------------------
tensor([[6, 7, 9, 4],[9, 1, 6, 2],[8, 7, 5, 6]])
五.张量形状操作
1.tensor.reshape(shape=)
在保证数据不变的前提下, 修改连续和非连续张量形状
修改前后的张量元素个数一致
-1:自动计算
2. tensor.squeeze(dim=)
删除维度值为1的维度, 可以通过dim指定删除维度
3.tensor.unsqueeze(dim=):
在指定维度上增加维度值1
4.tensor.transpose(dim0=, dim1=):
交换指定两个维度的数据
参数值是维度下标值
5. tensor.permute(dims=()):
交换任意维度的数据
参数值是维度下标值
6. tensor.view(shape=) : 修改连续张量的形状, 操作等同于reshape
tensor.contiguous() : 转换成连续张量
tensor.is_contiguous() : 判断张量是否连续
获取形状
import torch# 创建张量
t = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(t)
print('===================================')
# TODO shape获取形状
print(t.shape, t.shape[0], t.shape[1], t.shape[-1])
print(t.size(), t.size()[0], t.size()[1], t.size()[-1])
print('===================================')
# TODO reshape修改形状(元素个数不会变化)
print(t.reshape(3, 2))
print('--------------------')
print(t.reshape(1, 6))
print('--------------------')
print(t.reshape(6, 1))
print('--------------------')
# print(t.reshape(2, 2)) # 个数不匹配就报错!!!
[4, 5, 6]])
===================================
torch.Size([2, 3]) 2 3 3
torch.Size([2, 3]) 2 3 3
===================================
tensor([[1, 2],[3, 4],[5, 6]])
--------------------
tensor([[1, 2, 3, 4, 5, 6]])
--------------------
tensor([[1],[2],[3],[4],[5],[6]])
--------------------
张量的升维和降维
import torch# 创建张量
t = torch.tensor([1, 2, 3, 4, 5, 6])
print(t, t.shape, t.ndim)
print('==============================================')
# TODO 先使用reshape()变向完成升维操作,可以操作连续喝非连续的张量
t2 = t.reshape(2, 3)
print(t2, t2.shape, t2.ndim)
t3 = t.reshape(1, 2, 3)
print(t3, t3.shape, t3.ndim)
print('----------------------------')
# TODO 再使用专业的升维操作: unsqueeze()
t4 = t.unsqueeze(dim=0) # (1,6)
print(t4, t4.shape, t4.ndim)
t5 = t.unsqueeze(dim=1) # (6,1)
print(t5, t5.shape, t5.ndim)
# tt = t.unsqueeze(dim=2) # 报错: 维度超出范围(预期应在[-2, 1]范围内,但得到的是 2)
tt = t.unsqueeze(dim=-1)
print(tt, tt.shape, tt.ndim)
tt = t.unsqueeze(dim=-2)
print(tt, tt.shape, tt.ndim)
print('==============================================')
# TODO 使用专业的降维操作: squeeze()
t6 = t4.squeeze()
print(t6, t6.shape, t6.ndim)
t7 = t5.squeeze()
print(t7, t7.shape, t7.ndim)
==============================================
tensor([[1, 2, 3],[4, 5, 6]]) torch.Size([2, 3]) 2
tensor([[[1, 2, 3],[4, 5, 6]]]) torch.Size([1, 2, 3]) 3
----------------------------
tensor([[1, 2, 3, 4, 5, 6]]) torch.Size([1, 6]) 2
tensor([[1],[2],[3],[4],[5],[6]]) torch.Size([6, 1]) 2
tensor([[1],[2],[3],[4],[5],[6]]) torch.Size([6, 1]) 2
tensor([[1, 2, 3, 4, 5, 6]]) torch.Size([1, 6]) 2
==============================================
tensor([1, 2, 3, 4, 5, 6]) torch.Size([6]) 1
tensor([1, 2, 3, 4, 5, 6]) torch.Size([6]) 1
维度交换:
import torch# 提前设置一个种子
torch.manual_seed(666)
# 创建三维张量
t = torch.randint(1, 5, (3, 4, 5))
print(t, t.shape)
# TODO 需求: 把张量形状(3,4,5)转变为(4,5,3)
print('=====================================================')
# TODO transpose方式: 交换多次
t2 = t.transpose(1, 0) # (3,4,5)->(4,3,5)
print(t2, t2.shape)
print('------------------------------------------------')
t3 = t2.transpose(2, 1) # (4,3,5)->(4,5,3)
print(t3, t3.shape)
print('=====================================================')
# TODO permute方式: 一次指定多个维度
t4 = t.permute(dims=(1, 2, 0)) # (3,4,5)->(4,5,3)
print(t4, t4.shape)
# 注意: 还可以直接使用torch调用transpose()和permute()
[3, 2, 3, 1, 2],[4, 3, 4, 1, 4],[1, 3, 2, 4, 1]],[[3, 1, 4, 2, 3],[1, 4, 2, 2, 2],[1, 4, 1, 1, 1],[1, 1, 1, 3, 3]],[[3, 4, 1, 2, 1],[3, 2, 3, 4, 2],[2, 1, 3, 1, 4],[3, 3, 3, 3, 1]]]) torch.Size([3, 4, 5])
=====================================================
tensor([[[1, 3, 2, 3, 3],[3, 1, 4, 2, 3],[3, 4, 1, 2, 1]],[[3, 2, 3, 1, 2],[1, 4, 2, 2, 2],[3, 2, 3, 4, 2]],[[4, 3, 4, 1, 4],[1, 4, 1, 1, 1],[2, 1, 3, 1, 4]],[[1, 3, 2, 4, 1],[1, 1, 1, 3, 3],[3, 3, 3, 3, 1]]]) torch.Size([4, 3, 5])
------------------------------------------------
tensor([[[1, 3, 3],[3, 1, 4],[2, 4, 1],[3, 2, 2],[3, 3, 1]],[[3, 1, 3],[2, 4, 2],[3, 2, 3],[1, 2, 4],[2, 2, 2]],[[4, 1, 2],[3, 4, 1],[4, 1, 3],[1, 1, 1],[4, 1, 4]],[[1, 1, 3],[3, 1, 3],[2, 1, 3],[4, 3, 3],[1, 3, 1]]]) torch.Size([4, 5, 3])
=====================================================
tensor([[[1, 3, 3],[3, 1, 4],[2, 4, 1],[3, 2, 2],[3, 3, 1]],[[3, 1, 3],[2, 4, 2],[3, 2, 3],[1, 2, 4],[2, 2, 2]],[[4, 1, 2],[3, 4, 1],[4, 1, 3],[1, 1, 1],[4, 1, 4]],[[1, 1, 3],[3, 1, 3],[2, 1, 3],[4, 3, 3],[1, 3, 1]]]) torch.Size([4, 5, 3])
六.张量拼接操作
1. torch.cat([t1, t2, ...], dim=)
在指定维度上对张量进行拼接
其他维度值相同, 不改变新张量的维度
指定维度的维度值相加
2. torch.stack([t1, t2, ...], dim=)
在指定维度上对张量进行堆叠
其他维度值相同, 新张量在指定维度新增维度
指定维度的维度值就是张量个数
import torch# 提前设置一个随机种子
torch.manual_seed(666)
# TODO cat()拼接三维案例:对应维度上的维数相加
# 创建张量
t1 = torch.randint(1, 5, (1, 2, 3))
t2 = torch.randint(1, 5, (1, 2, 3))
print('----------------------------')
# 拼接
print(torch.cat([t1, t2], dim=0)) # (2, 2, 3)
print('----------------------------')
# 拼接
print(torch.cat([t1, t2], dim=1)) # (1, 4, 3)
print('----------------------------')
# 拼接
print(torch.cat([t1, t2], dim=2)) # (1, 2, 6)
print('=========================================================')
# TODO cat()拼接的是除拼接维度外,其他所有张量的形状必须完全相同。
t1 = torch.randint(1, 5, (2, 3))
t2 = torch.randint(1, 5, (1, 3))
# 拼接0轴上
print(torch.cat([t1, t2], dim=0)) # (3, 3)print('=========================================================')
# TODO stack()拼接的是所有张量的形状必须完全相同(所有维度一致)。
t1 = torch.randint(1, 5, (2, 3))
t2 = torch.randint(1, 5, (2, 3))
print(t1)
print(t2)
print(torch.stack([t1, t2], dim=0)) # (2,2,3)
print(torch.stack([t1, t2], dim=1)) # (2,2,3)
print(torch.stack([t1, t2], dim=2)) # (2,3,2)
tensor([[[1, 3, 2],[3, 3, 3]],[[2, 3, 1],[2, 4, 3]]])
----------------------------
tensor([[[1, 3, 2],[3, 3, 3],[2, 3, 1],[2, 4, 3]]])
----------------------------
tensor([[[1, 3, 2, 2, 3, 1],[3, 3, 3, 2, 4, 3]]])
=========================================================
tensor([[4, 1, 4],[1, 3, 2],[4, 1, 3]])
=========================================================
tensor([[[1, 4, 2],[3, 1, 4]],[[2, 2, 2],[1, 4, 1]]])
tensor([[[1, 4, 2],[2, 2, 2]],[[3, 1, 4],[1, 4, 1]]])
tensor([[[1, 2],[4, 2],[2, 2]],[[3, 1],[1, 4],[4, 1]]])