介绍:
在PyTorch中,张量是torch.Tensor
类型的变量,它支持各种数学运算,如加减乘除、指数、对数、线性代数运算等,并且可以在CPU和GPU之间无缝迁移,以便进行高效的计算1。
一.类型转换
import torch
import numpy as np
# 二维numpy数组
a = np.array([[1, 2], [3, 4]])
print(type(a)) # Output: <class 'numpy.ndarray'>
print(a) # Output: [[1 2]
# [3 4]]
# 二维tensor张量
b = torch.tensor([[1, 2], [3, 4]])
print(type(b)) # Output: <class 'torch.Tensor'>
print(b) # Output: tensor([[1, 2],
# [3, 4]])
# tensor 转 numpy
c = b.numpy()
print(type(c)) # Output: <class 'numpy.ndarray'>
print(c) # Output: [[1 2]
# [3 4]]
# numpy 转 tensor
d = torch.from_numpy(c)
print(type(d)) # Output: <class 'torch.Tensor'>
print(d) # Output: tensor([[1, 2],
# [3, 4]], dtype=torch.int32)
二.tensor的创建
import torch
import numpy as np
print("1.用numpy或list初始化创建")
# 用numpy初始化创建
a = np.array([[1, 2], [3, 4]])
print(a) # 输出: [[1 2]
# [3 4]]
b = torch.from_numpy(a)
print(b) # 输出: tensor([[1, 2],
# [3, 4]], dtype=torch.int32)
# 用list初始化创建
c = torch.tensor([2., 1.2])
print(c) # 输出: tensor([2.0000, 1.2000])
d = torch.tensor([[3, 5], [1, 6]])
print(d) # 输出: tensor([[3, 5],
# [1, 6]])
print("2.未初始化创建")
e = torch.empty(1)
print(e) # 输出: tensor([0.]) 或者 tensor([某个随机值])
f = torch.Tensor([2, 3])
print(f) # 输出: tensor([2., 3.])
print("3.随机生成创建")
g = torch.rand(3, 2)
print(g) # 输出: 一个3x2的随机数张量,值在[0, 1)范围内
h = torch.randn(3, 3)
print(h) # 输出: 一个3x3的随机数张量,值从标准正态分布中抽取
i1 = torch.randn_like(g)
print(i1) # 输出: 一个3x2的随机数张量,值从标准正态分布中抽取
i2 = torch.rand_like(h)
print(i2) # 输出: 一个3x3的随机数张量,值在[0, 1)范围内
print("3.序列生成创建")
print(torch.arange(1, 10)) # 其值介于区间[1,10),第三个数为步长,默认值为1
# 输出: tensor([1, 2, 3, 4, 5, 6, 7, 8, 9])
print(torch.arange(1, 10, 2)) # 输出: tensor([1, 3, 5, 7, 9])
print(torch.linspace(1, 10, 5)) # 输出: tensor([1.0000, 3.2500, 5.5000, 7.7500, 10.0000]) (头,尾,n个数)输出从头到尾n个等距数值
print(torch.eye(2, 5)) # 生成对角线为1其余全为0的矩阵
# 输出: tensor([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.]])
print(torch.eye(2)) # 输出: tensor([[1., 0.],
# [0., 1.]])
三.tensor属性和变形
torch的属性
import torch
print("定义tensor属性")
a = torch.tensor([[1, 2, 3], [2, 3, 4]], dtype=torch.float)
print(a) # 输出: tensor([[1., 2., 3.],
# [2., 3., 4.]])
print("tensor类型")
print(a.dtype) # 输出: torch.float32
print("tensor形状")
print(a.shape) # 输出: torch.Size([2, 3])
print("tensor形状,比shape类型更灵活,主要体现在维度上")
print(a.size()) # 输出: torch.Size([2, 3])
print("tensor第一维的大小")
print(a.size(0)) # 输出: 2
print("tensor第二维的大小")
print(a.size(1)) # 输出: 3
print("tensor维度大小")
print(a.dim()) # 输出: 2
print("tensor梯度")
print(a.grad) # 输出: None
print("tensor所在设备")
print(a.device) # 输出: cpu
torch.size()
import torch
x=torch.tensor([1.0,2.0,3.0,4.0,5.0],dtype=torch.float32)
print(x.size())
y=x.reshape(1,5)
print(y.size())
print(x)
print(y)
tensor的变形
import torch # 导入PyTorch库
# 创建一个二维张量 a,形状为 (2, 3)
a = torch.tensor([[1, 2, 3], [2, 3, 4]], dtype=torch.float)
# 打印 a 的值和形状
print("a的值", a)
print("a的形状", a.shape)
# 将 a 拉平为一维张量 b
b = a.flatten()
# 打印 b 的值和形状
print("b的值", b)
print("b的形状", b.shape)
# 使用 reshape 改变 b 的形状为 (2, 3)
c = b.reshape(2, 3)
# 打印 c 的值和形状
print("c的值", c)
print("c的形状", c.shape)
# 使用 view 改变 b 的形状为 (1, 6)
d = b.view(1, 6)
# 打印 d 的值和形状
print("d的值", d)
print("d的形状", d.shape)
# 使用 squeeze 移除 d 中维度大小为 1 的维度
e = torch.squeeze(d)
# 打印 e 的值和形状
print("e的值", e)
print("e的形状", e.shape)
# 使用 unsqueeze 在指定位置插入一个新的维度
f1 = torch.unsqueeze(e, 0)
f2 = torch.unsqueeze(e, 1)
# 打印 f1 和 f2 的值和形状
print("f1的值", f1)
print("f1的形状", f1.shape)
print("f2的值", f2)
print("f2的形状", f2.shape)
四.tensor的索引和切片
import torch # 导入PyTorch库
# 创建两个三维张量 a 和 b
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float)
b = torch.tensor([[10, 10, 10], [10, 10, 10], [10, 10, 10]], dtype=torch.float)
# 打印索引操作的结果
print("索引")
print("a的值", a)
print("a[1,2]的值:", a[1, 2]) # 获取第二行第三列的元素
print("a[-1,-1]的值:", a[-1, -1]) # 获取最后一行最后一列的元素
print("a第2行中的第1列和第3列的值:", a[[1], [0, 2]]) # 获取第二行的第一个和第三个元素
print("a的大于4的索引:", a > 4) # 获取所有大于4的元素的布尔索引
print("a的大于4的值:", a[a > 4]) # 获取所有大于4的元素的实际值
print("大于5输出a的值,否则输出b:\n", torch.where(a > 6, a, b)) # 根据条件选择a或b的值
# 打印切片操作的结果
print("\n切片")
print("a的值", a)
print("a的第1列:", a[:, 0]) # 获取所有行的第一列
print("a的第3列:", a[:, 2]) # 获取所有行的第三列
print("a的第3列:", a[:, -1]) # 同样获取所有行的第三列,使用负索引
print("a的1到3列:", a[:, 0:2]) # 获取所有行的第一列到第二列(不包括第三列)
print("a的第1行:", a[0, :]) # 获取第一行的所有列
print("a的第2行:", a[1, :]) # 获取第二行的所有列
print("a的最后1行", a[-1, :]) # 获取最后一行的所有列,使用负索引
print("a的间隔行值:", a[::2]) # 获取所有行的每隔一行,步长为2
五.tensor的连接和拆分
import torch # 导入PyTorch库
# 创建两个三维张量 a 和 b
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float)
b = torch.tensor([[10, 10, 10], [10, 10, 10], [10, 10, 10]], dtype=torch.float)
# 打印原始张量 a 和 b
print(a)
print(b)
# 使用 cat 函数进行拼接,维度不变
print("cat,维度不变")
print("a,b按行拼接:\n", torch.cat((a, b), dim=0)) # 沿第0维(行)拼接
print("a,b按行拼接:\n", torch.cat((a, b), dim=0).shape) # 打印拼接后的形状
print("a,b按列拼接:\n", torch.cat((a, b), dim=1)) # 沿第1维(列)拼接
print("a,b按列拼接:\n", torch.cat((a, b), dim=1).shape) # 打印拼接后的形状
# 使用 stack 函数进行拼接,维度加一
print("stack,维度加一")
print("a,b按行拼接:\n", torch.stack((a, b), dim=0)) # 沿新的第0维拼接
print("a,b按行拼接:\n", torch.stack((a, b), dim=0).shape) # 打印拼接后的形状
print("a,b按列拼接:\n", torch.stack((a, b), dim=1)) # 沿新的第1维拼接
print("a,b按列拼接:\n", torch.stack((a, b), dim=1).shape) # 打印拼接后的形状
# 使用 split 函数进行分割
print("split")
print(a) # 打印原始张量 a
print(torch.split(a, 2, dim=0)) # 沿第0维(行)分割成两部分,每部分包含两行
print(torch.split(a, 1, dim=0)) # 沿第0维(行)分割成三部分,每部分包含一行
print(torch.split(a, 1, dim=1)) # 沿第1维(列)分割成三部分,每部分包含一列
# 使用 chunk 函数进行分割
print("chunk")
print(torch.chunk(a, 2, dim=0)) # 沿第0维(行)分割成两部分
print(torch.chunk(a, 2, dim=1)) # 沿第1维(列)分割成两部分
torch.stack()
import torch
# 创建两个形状为 (3,) 的一维张量
tensor1 = torch.tensor([1, 2, 3])
tensor2 = torch.tensor([4, 5, 6])
# 按行(dim=0)堆叠
stacked_row = torch.stack((tensor1, tensor2), dim=0)
print("Stacked row-wise:\n", stacked_row)
# 输出结果应该是:
# Stacked row-wise:
# tensor([[1, 2, 3],
# [4, 5, 6]])
# 按列(dim=1)堆叠
stacked_col = torch.stack((tensor1, tensor2), dim=1)
print("Stacked column-wise:\n", stacked_col)
# 输出结果应该是:
# Stacked column-wise:
# tensor([[1, 4],
# [2, 5],
# [3, 6]])
torch.split
要展示代码运行的结果,我们需要运行代码。以下是假设运行上述代码片段可能得到的结果。请注意,这些结果是基于代码逻辑的预期输出,实际运行时可能会因为环境或其他因素有所不同。
首先,我们有以下张量a
:
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float)
然后,我们使用torch.split
进行分割:
print(torch.split(a, 2, dim=0))
预期输出:
(tensor([[1., 2., 3.],
[4., 5., 6.]]), tensor([[7., 8., 9.]]))
这里,a
被沿着第0维(行)分割成两部分,前两行成为第一个张量,最后一行成为第二个张量。
接下来,我们使用torch.split
再次分割:
print(torch.split(a, 1, dim=0))
预期输出:
(tensor([[1., 2., 3.]]), tensor([[4., 5., 6.]]), tensor([[7., 8., 9.]]))
这里,a
被沿着第0维(行)分割成三个部分,每部分包含一行。
然后,我们在第1维(列)上分割:
print(torch.split(a, 1, dim=1))
预期输出:
(tensor([[1.],
[4.],
[7.]]), tensor([[2.],
[5.],
[8.]]), tensor([[3.],
[6.],
[9.]]))
这里,a
被沿着第1维(列)分割成三个部分,每部分包含一列。
torch.chunk
进行分割:
print("chunk")
print(torch.chunk(a, 2, dim=0))
print(torch.chunk(a, 2, dim=1))
预期输出:
chunk
(tensor([[1., 2., 3.],
[4., 5., 6.]]), tensor([[7., 8., 9.]]))
(tensor([[1., 2., 3.],
[4., 5., 6.]]), tensor([[7., 8., 9.]]))
这里,a
被沿着第0维(行)分割成两部分,每部分包含两行。
六.tensor的换位与置换
import torch
a=torch.tensor([[1,2,3],[4,5,6],[7,8,9]],dtype=torch.float)
print("二维")
print(a)
print(a.T)
print(torch.t(a))
print("..............")
print(torch.transpose(a,1,0))
print(torch.transpose(a,0,1))
print("多维")
print(a.permute(1,0))
print()
c=torch.unsqueeze(a,0)
print(c)
print(c.shape)
print(c)
print(c.permute(1,0,2).shape)
七.tensor的运算
import torch
# 创建张量
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float)
b = torch.tensor([[10, 10, 10], [10, 10, 10], [10, 10, 10]], dtype=torch.float)
print("a:", a)
print("b:", b)
# 点加
print("\n点加 a + 100:", a + 100)
print("点加 a + b:", a + b)
print("点加 a.add(b):", a.add(b))
# 点乘
print("\n点乘 a * b:", a * b)
# 矩阵相乘
print("\n矩阵相乘 a @ b:", a @ b)
print("矩阵相乘 a.matmul(b):", a.matmul(b))
print("矩阵相乘 torch.mm(a, b):", torch.mm(a, b))
输出结果如下:
a: tensor([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]])
b: tensor([[10., 10., 10.],
[10., 10., 10.],
[10., 10., 10.]])
点加 a + 100: tensor([[101., 102., 103.],
[104., 105., 106.],
[107., 108., 109.]])
点加 a + b: tensor([[11., 12., 13.],
[14., 15., 16.],
[17., 18., 19.]])
点加 a.add(b): tensor([[11., 12., 13.],
[14., 15., 16.],
[17., 18., 19.]])
点乘 a * b: tensor([[10., 20., 30.],
[40., 50., 60.],
[70., 80., 90.]])
矩阵相乘 a @ b: tensor([[ 30., 30., 30.],
[ 60., 60., 60.],
[ 90., 90., 90.]])
矩阵相乘 a.matmul(b): tensor([[ 30., 30., 30.],
[ 60., 60., 60.],
[ 90., 90., 90.]])
矩阵相乘 torch.mm(a, b): tensor([[ 30., 30., 30.],
[ 60., 60., 60.],
[ 90., 90., 90.]])
tensor的微分运算
import torch
x=torch.tensor([1.0,2.0,3.0,4.0,5.0],requires_grad=True,dtype=torch.float32)
print(x.requires_grad) # 是否需要求导
print(x.grad) # 输出张量的梯度
print(x.grad_fn) # 指向运算生成此张量的方法
print()
y=torch.sum(x**2) # 标量,只是一个数值
print(y)
print(y.item()) # 打印计算值
print(y.grad_fn) # 打印计算方法
print()
print(x.grad)
y.backward() # 利用自动微分计算微分
# y对 x的微分值
print('shape:{0};{1}'.format(x.grad.size(),x.grad))