Bootstrap

pytorch----初识tensor张量(大致了解即可)

介绍:

在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))

;