Pytorch常用统计和矩阵运算

发布于:2025-05-13 ⋅ 阅读:(15) ⋅ 点赞:(0)

常用统计函数

函数 语法 作用 案例
torch.mean() torch.mean(input, dim=None) 计算张量均值 torch.mean(torch.tensor([1., 2., 3.]))2.0
torch.sum() torch.sum(input, dim=None) 计算张量元素和 torch.sum(torch.tensor([[1, 2], [3, 4]]))10
torch.max() torch.max(input, dim=None) 返回最大值及索引(若指定dim torch.max(torch.tensor([1, 4, 2]))4
torch.min() torch.min(input, dim=None) 返回最小值及索引(若指定dim torch.min(torch.tensor([[1, 2], [3, 0]]), dim=1)(values=tensor([1, 0]), indices=tensor([0, 1]))
torch.argmax() torch.argmax(input, dim=None) 返回最大值索引 torch.argmax(torch.tensor([1, 4, 2]))1
torch.argmin() torch.argmin(input, dim=None) 返回最小值索引 torch.argmin(torch.tensor([1, 0, 2]))1
torch.std() torch.std(input, dim=None) 计算标准差 torch.std(torch.tensor([1., 2., 3.]))1.0
torch.var() torch.var(input, dim=None) 计算方差 torch.var(torch.tensor([1., 2., 3.]))1.0
torch.median() torch.median(input, dim=None) 返回中位数及索引(若指定dim torch.median(torch.tensor([1, 3, 2]))2
torch.mode() torch.mode(input, dim=None) 返回众数及索引(若指定dim torch.mode(torch.tensor([1, 2, 2, 3]))(values=tensor(2), indices=tensor(1))
torch.prod() torch.prod(input, dim=None) 计算张量元素乘积 torch.prod(torch.tensor([2, 3]))6
torch.unique() torch.unique(input, return_counts=False) 返回唯一值及计数(可选) torch.unique(torch.tensor([1, 2, 1]))tensor([1, 2])
torch.histc() torch.histc(input, bins=100) 计算直方图 torch.histc(torch.tensor([1, 2, 1]), bins=2)tensor([2, 1])
torch.topk() torch.topk(input, k, dim=None) 返回前k个最大值及索引 torch.topk(torch.tensor([1, 4, 2]), k=2)(values=tensor([4, 2]), indices=tensor([1, 2]))
torch.sort() torch.sort(input, dim=None, descending=False) 排序张量并返回索引 torch.sort(torch.tensor([3, 1, 2]))(values=tensor([1, 2, 3]), indices=tensor([1, 2, 0]))
torch.cumsum() torch.cumsum(input, dim) 计算沿维度的累积和 torch.cumsum(torch.tensor([1, 2, 3]), dim=0)tensor([1, 3, 6])
torch.cumprod() torch.cumprod(input, dim) 计算沿维度的累积积 torch.cumprod(torch.tensor([2, 3, 2]), dim=0)tensor([2, 6, 12])

说明:

  1. dim参数:多数函数支持指定维度(如dim=0对每列操作,dim=1对每行操作),默认为全局计算。
  2. 返回值:部分函数(如maxminmedian)在指定dim时会返回元组(值, 索引)。
  3. 案例简化:实际使用时可能需要处理更高维张量或添加keepdim=True等参数。

torch.prod()求积

  • 使用函数torch.prod()求所有元素的积
torch.prod(input, dim=None, keepdim=False)
  • input: 输入张量
  • dim:指定沿哪个维度进行乘积运算。默认值为None,表示计算整个张量的乘积。0,列相乘;1,行相乘。
  • keepdim:布尔值,表示是否保持原始张量的维度。默认值为False,表示不保持原始维度。如果设置为True,则结果张量的维度与输入张量相同,但指定的维度大小为1。
import torch
#创建一个2×2的张量a
a = torch.tensor([[1, 2], [3, 4]])
#计算张量a中所有元素的乘积,并将结果赋值给result
result = torch.prod(a)
print(result)#输出:24

#沿着第0维(行)计算张量a中元素的乘积,并将结果赋值给result_dim
result_dim = torch.prod(a,dim=0)
print(result_dim) #输出:tensor([3,8])

# 沿着第0维(行)计算张量a中元素的乘积,并保持原始维度,将结果赋值给result_keepdim
result_keepdim = torch.prod(a, dim=0, keepdim=True)
print(result_keepdim) # 输出:tensor([[3, 8]])

torch.sum()求和

  • 使用torch.sum(函数求和
# 计算输入张量input中所有元素的和,返回一个标量值
torch.sum(input, dtype=None)
# 计算输入张量input在指定维度dim上的和,并返回一个新的张量
torch.sum(input, dim, keepdim=False, dtype=None)
  • input:输入一个张量
  • dim:要求和的维度,可以是一个列表。当dim=0时,即第0个维度会缩减,也就是说将N行压缩成一行,故相当于对列进行求和;当dim=1时,对行进行求和。
  • keepdim:求和之后这个dim的元素个数为1,所以要被去掉,如果要保留这个维度,则要保证keepdim=True。如果keepdim为True,则保留原始张量的维度;如果keepdim为False,则不保留原始张量的维度。
import torch
a=torch.rand(2,2)
print(a)
a_sum1=torch.sum(a)
print(a_sum1)
a_sum2=torch.sum(a,dim=(0,1))
print(a_sum2)
a_sum3=torch.sum(a,dim=0)
print(a_sum3)
a_sum4=torch.sum(a,dim=1)
print(a_sum4)
a_sum5=torch.sum(a,dim=(0,1),keepdim=True)
print(a_sum5)
a_sum6=torch.sum(a,dim=0,keepdim=True)
print(a_sum6)
a_sum7=torch.sum(a,dim=1,keepdim=True)
print(a_sum7)

torch.mean()求均值

  • 使用torch.mean()函数求平均值,该函数对输入的张量数据的某一维度求平均值。
torch.mean(input, dtype=None)
torch.mean(input, dim, keepdim=False, dtype=None)
  • input:输入一个张量
  • dim:要求和的维度,可以是一个列表。当dim=0时,即第0个维度会缩减,也就是说将N行压缩成一行,故相当于对列进行求和;当dim=1时,对行进行求和。
  • keepdim:求和之后这个dim的元素个数为1,所以要被去掉,如果要保留这个维度,则要保证keepdim=True。如果keepdim为True,则保留原始张量的维度;如果keepdim为False,则不保留原始张量的维度。
#导入torch库
import torch
#创建一个张量a
a=torch.tensor([[1,2],[3,4]],dtype=torch.float32)
#沿着第0维和第1维计算张量a的元素平均值,并保持原始维度,将结果赋值给a12
a12 = torch.mean(a, dim=(0,1), keepdim=True)
#沿着第0维计算张量a的元素平均值,并保持原始维度,将结果赋值给a13
a13 = torch.mean(a, dim=(0, ), keepdim=True)
#沿着第1维计算张量a的元素平均值,并保持原始维度,将结果赋值给a14
a14 = torch.mean(a, dim=(1, ), keepdim=True)
#打印a12、a13和a14的值
print(a12)
print(a13)
print(a14)

torch.max()求最值

  • 使用torch.max()函数求最大值,参数与torch.sum()函数类似,但是参数dim须为整数
torch.max(input, dtype=None)
torch.max(input, dim, keepdim=False, dtype=None)
#导入torch库
import torch
#创建一个张量a
a=torch.tensor([[1,2],[3,4]],dtype=torch.float32)
a12 = torch.max(a, 0, keepdim=True)
a13 = torch.max(a, 1, keepdim=True)
print(a12)
print(a13)

torch.var() 方差

  • 使用torch.varO函数求方差,该函数返回输入张量中所有元素的方差
torch.var(input, unbiased=True)
torch.var(input, dim, unbiased=True, keepdim=False, *, out=None)
  • input:输入一个张量。
  • dim:要求和的维度,可以是一个列表,当dim=0时,即第0个维度会缩减,也就是说将N行压缩成一行,故相当于对列进行求和,当dim=1时,对行进行求和。
  • unbiased:是否使用无偏估计,布尔型。如果unbiased为False,则将通过有偏估计量计算方差,否则将使用“贝塞尔校正”更正。
  • keepdim:求和之后,这个dim的元素个数为1,所以要被去掉,如果要保留这个维度,则应该将keepdim设置为True。
#导入torch库
import torch
#创建一个张量a
a = torch.tensor([[1.,2.], [3., 4.]])
#沿着第l维计算张量a的元素方差,并将结果赋值给变量var_result
var_result =torch.var(a,1,unbiased=True,keepdim=True)
#打印var_result的值
print(var_result)

torch.std()标准差

  • 使用torch.std()函数求标准差,该函数返回输入张量中所有元素的标准差
torch.std(input,unbiased=True)
torch.std(input,dim,unbiased=True,keepdim=False,*,out=None)
#导入torch库
import torch
#创建一个张量a
a = torch.tensor([[1., 2.],[3., 4.]])
#沿着第l维计算张量a的元素标准差,并将结果赋值给变量std_result
std_result = torch.std(a, 1,keepdim=True)
#打印std_result的值
print(std_result)

常见矩阵运算

矩阵乘法

import torch

# 创建两个随机矩阵
A = torch.randn(3, 4)  # 3x4矩阵
B = torch.randn(4, 5)  # 4x5矩阵

# 矩阵乘法两种写法
result1 = torch.matmul(A, B)
result2 = A @ B  # Python 3.5+支持的运算符

print("矩阵乘法结果(3x5):\n", result1)
print("结果是否相同:", torch.allclose(result1, result2))

参数说明

  • input:第一个张量
  • other:第二个张量
  • out(可选):输出张量

广播规则

  • 如果两个张量都是一维的,返回点积(标量)
  • 如果两个张量都是二维的,返回矩阵乘积
  • 如果其中一个张量是一维的,会在其前面添加一个1,矩阵乘法后会移除添加的维度
  • 如果两个张量都是至少一维且其中一个至少是二维的,会进行批量矩阵乘法

点积 (torch.dot)

# 创建两个向量
v1 = torch.tensor([1.0, 2.0, 3.0])
v2 = torch.tensor([4.0, 5.0, 6.0])

# 计算点积
dot_product = torch.dot(v1, v2)
print("\n向量点积结果:", dot_product.item())  # 1*4 + 2*5 + 3*6 = 32

批量矩阵乘法 (torch.bmm)

# 创建批量矩阵 (batch_size, m, n)
batch_A = torch.randn(10, 3, 4)  # 10个3x4矩阵
batch_B = torch.randn(10, 4, 5)  # 10个4x5矩阵

# 批量矩阵乘法
batch_result = torch.bmm(batch_A, batch_B)
print("\n批量矩阵乘法结果形状:", batch_result.shape)  # torch.Size([10, 3, 5])

参数说明

  • input:形状为(b, n, m)的批量矩阵
  • mat2:形状为(b, m, p)的批量矩阵
  • out(可选):输出张量

##矩阵转置 (torch.t / torch.transpose)

# 矩阵转置
matrix = torch.randn(3, 4)
transposed = matrix.t()  # 等同于 torch.transpose(matrix, 0, 1)

print("\n原始矩阵形状:", matrix.shape)
print("转置矩阵形状:", transposed.shape)

# 高维张量转置
tensor_3d = torch.randn(2, 3, 4)
transposed_3d = torch.transpose(tensor_3d, 1, 2)  # 交换维度1和2
print("\n3D张量转置后形状:", transposed_3d.shape)  # torch.Size([2, 4, 3])

参数说明

  • input:输入张量
  • dim0:要转置的第一个维度
  • dim1:要转置的第二个维度

奇异值分解 (SVD)

# 创建一个随机矩阵
matrix = torch.randn(5, 3)

# 进行SVD分解
U, S, V = torch.svd(matrix)

print("\nU矩阵形状:", U.shape)  # torch.Size([5, 5])
print("奇异值:", S)           # 对角矩阵的非零元素
print("V矩阵形状:", V.shape)  # torch.Size([3, 3])

# 重构原始矩阵
reconstructed = U[:, :3] @ torch.diag(S) @ V.t()
print("\n重构误差:", torch.norm(matrix - reconstructed).item())

参数说明

  • input:输入矩阵
  • some(可选):如果True(默认),计算简化SVD;如果False,计算完全SVD
  • compute_uv(可选):是否计算U和V
  • out(可选):输出元组(U, S, V)

特征分解 (torch.eig)

# 创建一个对称矩阵
matrix = torch.randn(3, 3)
symmetric_matrix = matrix @ matrix.t()  # 使其对称

# 计算特征值和特征向量
eigenvalues, eigenvectors = torch.linalg.eig(symmetric_matrix)

print("\n特征值:\n", eigenvalues)
print("特征向量:\n", eigenvectors)

矩阵求逆 (torch.inverse)

# 创建一个可逆方阵
matrix = torch.tensor([[4.0, 7.0], [2.0, 6.0]])

# 计算逆矩阵
inv_matrix = torch.inverse(matrix)

print("\n原始矩阵:\n", matrix)
print("逆矩阵:\n", inv_matrix)
print("验证结果(应接近单位矩阵):\n", matrix @ inv_matrix)

参数说明

  • input:输入方阵
  • out(可选):输出张量

伪逆 (torch.pinverse)

# 创建一个非方阵
matrix = torch.randn(3, 4)

# 计算伪逆(Moore-Penrose伪逆)
pseudo_inv = torch.pinverse(matrix)

print("\n原始矩阵形状:", matrix.shape)
print("伪逆矩阵形状:", pseudo_inv.shape)  # torch.Size([4, 3])

参数说明

  • input:输入矩阵
  • rcond:奇异值截断阈值

拟合余弦函数曲线练习

import torch
import torch.nn as nn
from torch.utils.data import DataLoader,TensorDataset
import numpy as np
import matplotlib.pyplot as plt

# 设置支持中文的字体
plt.rcParams['font.sans-serif'] = ['SimHei']
# 解决负号显示问题,确保在图表中正确显示负号
plt.rcParams['axes.unicode_minus'] = False

# 1 准备拟合数据
x=np.linspace(-2*np.pi,2*np.pi,500)
y=np.cos(x)
# 将×扩展为一维数组x,即在列方向上增加一个维度
x=np.expand_dims(x,axis=1)
y=y.reshape(500,-1)


# 2 设置神经网络
class Net(nn.Module):
    # 构造函数
    def __init__(self):
        # 调用父类的构造函数
        super(Net, self).__init__()
        # 构造一个序列型神经网络
        self.net=nn.Sequential(
            # 输入特征数为1,输出特征数为10的线性层
            nn.Linear(1, 10),
            nn.ReLU(),
            nn.Linear(10, 100),
            nn.ReLU(),
            nn.Linear(100, 10),
            nn.ReLU(),
            nn.Linear(10, 1)
        )
    def forward(self, input: torch.FloatTensor):
        return self.net(input)


net =Net()

# 设置优化器和损失函数
optimizer = torch.optim.Adam(Net.parameters(net), lr=0.001)
loss_func = nn.MSELoss()

# 将 x 和y转换为 torch.Tensor 类型 将数据移动到GPU,并组成数据集 dataset
dataset = TensorDataset(torch.tensor(x, dtype=torch.float), torch.tensor(y,dtype=torch.float))
#创建数据加载器dataloader,批次大小为10,数据打乱
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)

# 训练模型
for epoch in range(100):
    loss=None
    for batch_x,batch_y in dataloader:
        # 前向传播
        output = net(batch_x)
        # 计算损失
        loss = loss_func(output, batch_y)
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    if (epoch+1) % 10 == 0:
        print('epoch:', epoch+1, 'loss:', loss.item())

# 预测
predict=net(torch.tensor(x,dtype=torch.float))

# 绘制结果图
plt.figure(figsize=(12, 7),dpi=160)
# 绘制实际值曲线
plt.plot(x,y,label='实际值',marker='x')
#  绘制预测值曲线
plt.plot(x,predict.detach().numpy(),label='预测值',marker='o')
# 设置坐标轴标签
plt.xlabel('x',size=15)
plt.ylabel('cos(x)',size=15)
# 设置刻度字体大小
plt.xticks(size=15)
plt.yticks(size=15)
# 显示图例
plt.legend(fontsize=15)
# 设置标题
plt.title('拟合cos(x)',size=15)
# 显示图像
plt.show()

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到