当前位置: 首页 > news >正文

【机器学习】自定义数据集 使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测,对预测结果计算精确度和召回率及F1分数

一、使用pytorch框架实现逻辑回归

1. 数据部分

  • 首先自定义了一个简单的数据集,特征 X 是 100 个随机样本,每个样本一个特征,目标值 y 基于线性关系并添加了噪声。
  • 将 numpy 数组转换为 PyTorch 张量,方便后续在模型中使用。

2. 模型定义部分

方案 1:使用 nn.Sequential 直接按顺序定义了一个线性层,简洁直观。

import torch
import torch.nn as nn
import numpy as np
from sklearn.metrics import mean_squared_error, r2_score# 自定义数据集
X = np.random.rand(100, 1).astype(np.float32)
y = 2 * X + 1 + 0.3 * np.random.randn(100, 1).astype(np.float32)# 转换为 PyTorch 张量
X_tensor = torch.from_numpy(X)
y_tensor = torch.from_numpy(y)# 定义线性回归模型
model = nn.Sequential(nn.Linear(1, 1)
)# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):# 前向传播outputs = model(X_tensor)loss = criterion(outputs, y_tensor)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 模型评估
with torch.no_grad():y_pred = model(X_tensor).numpy()mse = mean_squared_error(y, y_pred)
r2 = r2_score(y, y_pred)
print(f"均方误差 (MSE): {mse}")
print(f"决定系数 (R²): {r2}")# 输出模型的系数和截距
print("模型系数:", model[0].weight.item())
print("模型截距:", model[0].bias.item())

方案 2:使用 nn.ModuleList 存储线性层,在 forward 方法中依次调用层进行前向传播,适合动态构建层序列。

import torch
import torch.nn as nn
import numpy as np
from sklearn.metrics import mean_squared_error, r2_score# 自定义数据集
X = np.random.rand(100, 1).astype(np.float32)
y = 2 * X + 1 + 0.3 * np.random.randn(100, 1).astype(np.float32)# 转换为 PyTorch 张量
X_tensor = torch.from_numpy(X)
y_tensor = torch.from_numpy(y)# 定义线性回归模型
class LinearRegression(nn.Module):def __init__(self):super(LinearRegression, self).__init__()self.layers = nn.ModuleList([nn.Linear(1, 1)])def forward(self, x):for layer in self.layers:x = layer(x)return xmodel = LinearRegression()# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):# 前向传播outputs = model(X_tensor)loss = criterion(outputs, y_tensor)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 模型评估
with torch.no_grad():y_pred = model(X_tensor).numpy()mse = mean_squared_error(y, y_pred)
r2 = r2_score(y, y_pred)
print(f"均方误差 (MSE): {mse}")
print(f"决定系数 (R²): {r2}")# 输出模型的系数和截距
print("模型系数:", model.layers[0].weight.item())
print("模型截距:", model.layers[0].bias.item())

方案 3:使用 nn.ModuleDict 以字典形式存储层,通过键名调用层,适合需要对层进行命名和灵活访问的场景。

import torch
import torch.nn as nn
import numpy as np
from sklearn.metrics import mean_squared_error, r2_score# 自定义数据集
X = np.random.rand(100, 1).astype(np.float32)
y = 2 * X + 1 + 0.3 * np.random.randn(100, 1).astype(np.float32)# 转换为 PyTorch 张量
X_tensor = torch.from_numpy(X)
y_tensor = torch.from_numpy(y)# 定义线性回归模型
class LinearRegression(nn.Module):def __init__(self):super(LinearRegression, self).__init__()self.layers = nn.ModuleDict({'linear': nn.Linear(1, 1)})def forward(self, x):x = self.layers['linear'](x)return xmodel = LinearRegression()# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):# 前向传播outputs = model(X_tensor)loss = criterion(outputs, y_tensor)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 模型评估
with torch.no_grad():y_pred = model(X_tensor).numpy()mse = mean_squared_error(y, y_pred)
r2 = r2_score(y, y_pred)
print(f"均方误差 (MSE): {mse}")
print(f"决定系数 (R²): {r2}")# 输出模型的系数和截距
print("模型系数:", model.layers['linear'].weight.item())
print("模型截距:", model.layers['linear'].bias.item())

方案 4:直接继承 nn.Module,在 __init__ 方法中定义线性层,在 forward 方法中实现前向传播逻辑,是最常见和基础的定义模型方式。

import torch
import torch.nn as nn
import numpy as np
from sklearn.metrics import mean_squared_error, r2_score# 自定义数据集
X = np.random.rand(100, 1).astype(np.float32)
y = 2 * X + 1 + 0.3 * np.random.randn(100, 1).astype(np.float32)# 转换为 PyTorch 张量
X_tensor = torch.from_numpy(X)
y_tensor = torch.from_numpy(y)# 定义线性回归模型
class LinearRegression(nn.Module):def __init__(self):super(LinearRegression, self).__init__()self.linear = nn.Linear(1, 1)def forward(self, x):return self.linear(x)model = LinearRegression()# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):# 前向传播outputs = model(X_tensor)loss = criterion(outputs, y_tensor)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 模型评估
with torch.no_grad():y_pred = model(X_tensor).numpy()mse = mean_squared_error(y, y_pred)
r2 = r2_score(y, y_pred)
print(f"均方误差 (MSE): {mse}")
print(f"决定系数 (R²): {r2}")# 输出模型的系数和截距
print("模型系数:", model.linear.weight.item())
print("模型截距:", model.linear.bias.item())

3. 训练和评估部分

  • 定义了均方误差损失函数 nn.MSELoss 和随机梯度下降优化器 torch.optim.SGD
  • 通过多个 epoch 进行训练,每个 epoch 包含前向传播、损失计算、反向传播和参数更新。
  • 训练结束后,在无梯度计算模式下进行预测,并使用 scikit-learn 的指标计算均方误差和决定系数评估模型性能,最后输出模型的系数和截距。

二、保存pytorch框架逻辑回归模型

在 PyTorch 中,有两种常见的保存模型的方式:保存模型的权重和其他参数,以及保存整个模型。下面将结合一个简单的逻辑回归模型示例,详细介绍这两种保存方式及对应的加载方法。

方式 1:保存模型的权重和其他参数

这种方式只保存模型的状态字典(state_dict),它包含了模型的所有可学习参数(如权重和偏置)。这种方法的优点是文件体积小,便于共享和迁移,缺点是加载时需要先定义模型结构。

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np# 自定义数据集
X = np.random.randn(100, 2).astype(np.float32)
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)X_tensor = torch.from_numpy(X)
y_tensor = torch.from_numpy(y)# 定义逻辑回归模型
class LogisticRegression(nn.Module):def __init__(self, input_size):super(LogisticRegression, self).__init__()self.linear = nn.Linear(input_size, 1)self.sigmoid = nn.Sigmoid()def forward(self, x):out = self.linear(x)out = self.sigmoid(out)return out# 初始化模型
input_size = 2
model = LogisticRegression(input_size)# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):outputs = model(X_tensor)loss = criterion(outputs, y_tensor)optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 保存模型的权重和其他参数
torch.save(model.state_dict(), 'model_weights.pth')# 加载模型的权重和其他参数
loaded_model = LogisticRegression(input_size)
loaded_model.load_state_dict(torch.load('model_weights.pth'))
loaded_model.eval()# 生成新数据进行预测
new_X = np.random.randn(10, 2).astype(np.float32)
new_X_tensor = torch.from_numpy(new_X)with torch.no_grad():predictions = loaded_model(new_X_tensor)predicted_labels = (predictions >= 0.5).float()print("预测概率:")
print(predictions.numpy())
print("预测标签:")
print(predicted_labels.numpy())

代码解释

  1. 模型训练:首先定义并训练一个逻辑回归模型。
  2. 保存模型:使用 torch.save(model.state_dict(), 'model_weights.pth') 保存模型的状态字典到文件 model_weights.pth
  3. 加载模型:先创建一个新的模型实例 loaded_model,然后使用 loaded_model.load_state_dict(torch.load('model_weights.pth')) 加载保存的状态字典。
  4. 预测:将模型设置为评估模式,生成新数据进行预测。

方式 2:保存整个模型

这种方式会保存整个模型对象,包括模型的结构和状态字典。优点是加载时不需要重新定义模型结构,缺点是文件体积较大,并且可能会受到 Python 版本和库版本的限制。

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np# 自定义数据集
X = np.random.randn(100, 2).astype(np.float32)
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)X_tensor = torch.from_numpy(X)
y_tensor = torch.from_numpy(y)# 定义逻辑回归模型
class LogisticRegression(nn.Module):def __init__(self, input_size):super(LogisticRegression, self).__init__()self.linear = nn.Linear(input_size, 1)self.sigmoid = nn.Sigmoid()def forward(self, x):out = self.linear(x)out = self.sigmoid(out)return out# 初始化模型
input_size = 2
model = LogisticRegression(input_size)# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):outputs = model(X_tensor)loss = criterion(outputs, y_tensor)optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 保存整个模型
torch.save(model, 'whole_model.pth')# 加载整个模型
loaded_model = torch.load('whole_model.pth')
loaded_model.eval()# 生成新数据进行预测
new_X = np.random.randn(10, 2).astype(np.float32)
new_X_tensor = torch.from_numpy(new_X)with torch.no_grad():predictions = loaded_model(new_X_tensor)predicted_labels = (predictions >= 0.5).float()print("预测概率:")
print(predictions.numpy())
print("预测标签:")
print(predicted_labels.numpy())

代码解释

  1. 模型训练:同样先定义并训练逻辑回归模型。
  2. 保存模型:使用 torch.save(model, 'whole_model.pth') 保存整个模型对象到文件 whole_model.pth
  3. 加载模型:使用 torch.load('whole_model.pth') 直接加载整个模型。
  4. 预测:将模型设置为评估模式,生成新数据进行预测。

通过以上两种方式,可以根据实际需求选择合适的模型保存和加载方法。

三、加载pytorch框架逻辑回归模型

以下将分别详细介绍在 PyTorch 中针对只保存模型参数和保存结构与参数这两种不同保存方式对应的模型加载方法,同时给出完整的代码示例。

方式 1:只保存模型参数的加载方式

当用户只保存了模型的参数(即 state_dict)时,在加载模型时需要先定义好与原模型相同结构的模型,再将保存的参数加载到该模型中。

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np# 自定义数据集
X = np.random.randn(100, 2).astype(np.float32)
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)X_tensor = torch.from_numpy(X)
y_tensor = torch.from_numpy(y)# 定义逻辑回归模型
class LogisticRegression(nn.Module):def __init__(self, input_size):super(LogisticRegression, self).__init__()self.linear = nn.Linear(input_size, 1)self.sigmoid = nn.Sigmoid()def forward(self, x):out = self.linear(x)out = self.sigmoid(out)return out# 初始化模型
input_size = 2
model = LogisticRegression(input_size)# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):outputs = model(X_tensor)loss = criterion(outputs, y_tensor)optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 保存模型的参数
torch.save(model.state_dict(), 'model_params.pth')# 加载模型的参数
# 重新定义模型结构
loaded_model = LogisticRegression(input_size)
# 加载保存的参数
loaded_model.load_state_dict(torch.load('model_params.pth'))
# 将模型设置为评估模式
loaded_model.eval()# 生成新数据进行预测
new_X = np.random.randn(10, 2).astype(np.float32)
new_X_tensor = torch.from_numpy(new_X)# 进行预测
with torch.no_grad():predictions = loaded_model(new_X_tensor)predicted_labels = (predictions >= 0.5).float()print("预测概率:")
print(predictions.numpy())
print("预测标签:")
print(predicted_labels.numpy())

代码解释

  1. 模型定义与训练:定义了一个简单的逻辑回归模型,并使用自定义数据集进行训练。
  2. 保存参数:使用 torch.save(model.state_dict(), 'model_params.pth') 保存模型的参数。
  3. 加载参数
    • 重新定义与原模型相同结构的 loaded_model
    • 使用 loaded_model.load_state_dict(torch.load('model_params.pth')) 加载保存的参数。
  4. 预测:将模型设置为评估模式,生成新数据进行预测。

方式 2:保存结构和参数的模型加载方式

当保存了模型的结构和参数时,加载模型就相对简单,直接使用 torch.load 函数即可加载整个模型。

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np# 自定义数据集
X = np.random.randn(100, 2).astype(np.float32)
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)X_tensor = torch.from_numpy(X)
y_tensor = torch.from_numpy(y)# 定义逻辑回归模型
class LogisticRegression(nn.Module):def __init__(self, input_size):super(LogisticRegression, self).__init__()self.linear = nn.Linear(input_size, 1)self.sigmoid = nn.Sigmoid()def forward(self, x):out = self.linear(x)out = self.sigmoid(out)return out# 初始化模型
input_size = 2
model = LogisticRegression(input_size)# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):outputs = model(X_tensor)loss = criterion(outputs, y_tensor)optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 保存整个模型(结构和参数)
torch.save(model, 'whole_model.pth')# 加载整个模型
loaded_model = torch.load('whole_model.pth')
# 将模型设置为评估模式
loaded_model.eval()# 生成新数据进行预测
new_X = np.random.randn(10, 2).astype(np.float32)
new_X_tensor = torch.from_numpy(new_X)# 进行预测
with torch.no_grad():predictions = loaded_model(new_X_tensor)predicted_labels = (predictions >= 0.5).float()print("预测概率:")
print(predictions.numpy())
print("预测标签:")
print(predicted_labels.numpy())

代码解释

  1. 模型定义与训练:同样定义并训练逻辑回归模型。
  2. 保存整个模型:使用 torch.save(model, 'whole_model.pth') 保存模型的结构和参数。
  3. 加载整个模型:使用 torch.load('whole_model.pth') 直接加载整个模型。
  4. 预测:将模型设置为评估模式,生成新数据进行预测。

通过以上两种方式,可以根据不同的保存情况正确加载 PyTorch 模型。

五、计算pytorch模型预测结果的精确度

在机器学习任务中,计算预测结果的精确度(Accuracy)是评估模型性能的重要指标。对于回归任务,通常使用均方误差(MSE)平均绝对误差(MAE)R² 分数 来评估模型的性能;而对于分类任务,则使用准确率(Accuracy)精确率(Precision)召回率(Recall) 等指标。

以下是如何在 PyTorch 中计算预测结果的精确度(以回归任务为例):

1. 分类任务的精确度计算

对于分类任务,常用的评估指标是准确率(Accuracy),即预测正确的样本数占总样本数的比例。

代码实现

import torch# 假设有真实标签和预测标签
y_true = torch.tensor([0, 1, 1, 0, 1, 0, 0, 1])  # 真实标签
y_pred = torch.tensor([0, 1, 0, 0, 1, 0, 1, 1])  # 预测标签# 计算准确率
accuracy = (y_true == y_pred).float().mean()
print(f"准确率: {accuracy.item():.4f}")

 2. 回归任务的精确度计算

对于回归任务,常用的评估指标包括:

  • 均方误差(MSE):预测值与真实值之间差异的平方的平均值。

  • 平均绝对误差(MAE):预测值与真实值之间差异的绝对值的平均值。

  • R² 分数:表示模型对数据的拟合程度,取值范围为 [0, 1],越接近 1 表示模型越好。

代码实现

import torch
import torch.nn as nn# 假设有真实值和预测值
y_true = torch.tensor([3.0, 5.0, 7.0, 9.0], dtype=torch.float32)
y_pred = torch.tensor([2.8, 5.1, 7.2, 8.9], dtype=torch.float32)# 计算均方误差 (MSE)
mse = nn.MSELoss()(y_pred, y_true)
print(f"Mean Squared Error (MSE): {mse.item():.4f}")# 计算平均绝对误差 (MAE)
mae = nn.L1Loss()(y_pred, y_true)
print(f"Mean Absolute Error (MAE): {mae.item():.4f}")# 计算 R² 分数
def r2_score(y_true, y_pred):ss_total = torch.sum((y_true - torch.mean(y_true)) ** 2)ss_residual = torch.sum((y_true - y_pred) ** 2)r2 = 1 - (ss_residual / ss_total)return r2r2 = r2_score(y_true, y_pred)
print(f"R²分数: {r2.item():.4f}")

六、计算pytorch模型预测结果的召回率

1. 召回率的定义

在分类任务中,召回率(Recall) 是一个重要的评估指标,用于衡量模型对正类样本的识别能力。召回率的定义是:

Recall= \frac{True Positives (TP)}{True Positives (TP)+False Negatives (FN)}

其中:

  • True Positives (TP):模型正确预测为正类的样本数。

  • False Negatives (FN):模型错误预测为负类的正类样本数。

2. 计算召回率的步骤

  1. 获取真实标签和预测标签

  • 真实标签(y_true):数据集中样本的真实类别。
  • 预测标签(y_pred):模型对样本的预测类别。
  1. 计算混淆矩阵

  • 通过比较 y_true 和 y_pred,计算混淆矩阵中的 TP 和 FN。
  1. 计算召回率

        使用公式 Recall= \frac{TP}{TP+FN} 计算召回率。

3. 二分类任务召回率代码

  • 对于二分类任务,召回率衡量模型对正类样本的识别能力。

import torch# 假设有真实标签和预测标签
y_true = torch.tensor([0, 1, 1, 0, 1, 0, 0, 1])  # 真实标签
y_pred = torch.tensor([0, 1, 0, 0, 1, 0, 1, 1])  # 预测标签# 计算混淆矩阵
def confusion_matrix(y_true, y_pred):TP = ((y_true == 1) & (y_pred == 1)).sum().item()  # 模型正确预测为正类的样本数FN = ((y_true == 1) & (y_pred == 0)).sum().item()  # 模型错误预测为负类的正类样本数FP = ((y_true == 0) & (y_pred == 1)).sum().item()  # 模型错误预测为正类的正类样本数TN = ((y_true == 0) & (y_pred == 0)).sum().item()  # 模型正确预测为负类的样本数return TP, FN, FP, TN# 计算召回率
def recall_score(y_true, y_pred):TP, FN, _, _ = confusion_matrix(y_true, y_pred)if TP + FN == 0:return 0.0  # 避免除以零return TP / (TP + FN)# 计算召回率
recall = recall_score(y_true, y_pred)
print(f"召回率: {recall:.4f}")

 4. 多分类任务召回率代码

  • 对于多分类任务,可以分别计算每个类别的召回率,然后取平均值。

import torch# 假设有真实标签和预测标签(多分类任务)
y_true = torch.tensor([0, 1, 2, 0, 1, 2])  # 真实标签
y_pred = torch.tensor([0, 1, 0, 0, 1, 2])  # 预测标签# 计算每个类别的召回率
def recall_score_multiclass(y_true, y_pred, num_classes):recall_scores = []for cls in range(num_classes):TP = ((y_true == cls) & (y_pred == cls)).sum().item()  # 模型正确预测为正类的样本数FN = ((y_true == cls) & (y_pred != cls)).sum().item()  # 模型错误预测为负类的正类样本数if TP + FN == 0:recall_scores.append(0.0)  # 避免除以零else:recall_scores.append(TP / (TP + FN))return recall_scores# 计算召回率
num_classes = 3
recall_scores = recall_score_multiclass(y_true, y_pred, num_classes)
for cls, recall in enumerate(recall_scores):print(f"每个类别的召回率 {cls}: {recall:.4f}")# 计算宏平均召回率
macro_recall = sum(recall_scores) / num_classes
print(f"宏平均召回率: {macro_recall:.4f}")

七、计算pytorch模型预测结果的F1分数

1. F1分数的定义

F1 分数(F1 Score) 是分类任务中常用的评估指标,结合了 精确率(Precision) 和 召回率(Recall) 的信息。F1 分数的定义是:

F1 Score= 2\times \frac{Precision\times ×Recall}{Precision+Recall}

其中:

  • 精确率(Precision):预测为正类的样本中,实际为正类的比例。

  • 召回率(Recall):实际为正类的样本中,预测为正类的比例。

F1 分数的取值范围为 [0, 1],越接近 1 表示模型性能越好。

2. 计算 F1 分数的步骤

  1. 获取真实标签和预测标签

  • 真实标签(y_true):数据集中样本的真实类别。
  • 预测标签(y_pred):模型对样本的预测类别。
  1. 计算混淆矩阵

  • 通过比较 y_true 和 y_pred,计算混淆矩阵中的 TP、FP 和 FN。
  1. 计算精确率和召回率

  • 精确率:

Precision=\frac{TP}{TP+FP}

  • 召回率:

Recall=\frac{TP}{TP+FN}

  1. 计算 F1 分数

  • 使用公式:

F1 Score= 2\times \frac{Precision\times ×Recall}{Precision+Recall}

3. 二分类任务F1分数代码

  • 对于二分类任务,F1 分数结合了精确率和召回率,是评估模型性能的重要指标。

import torch# 假设有真实标签和预测标签
y_true = torch.tensor([0, 1, 1, 0, 1, 0, 0, 1])  # 真实标签
y_pred = torch.tensor([0, 1, 0, 0, 1, 0, 1, 1])  # 预测标签# 计算混淆矩阵
def confusion_matrix(y_true, y_pred):TP = ((y_true == 1) & (y_pred == 1)).sum().item()  # 模型正确预测为正类的样本数FN = ((y_true == 1) & (y_pred == 0)).sum().item()  # 模型错误预测为负类的正类样本数FP = ((y_true == 0) & (y_pred == 1)).sum().item()  # 模型错误预测为正类的正类样本数TN = ((y_true == 0) & (y_pred == 0)).sum().item()  # 模型正确预测为负类的样本数return TP, FN, FP, TN# 计算 F1 分数
def f1_score(y_true, y_pred):TP, FN, FP, _ = confusion_matrix(y_true, y_pred)# 计算精确率和召回率precision = TP / (TP + FP) if (TP + FP) > 0 else 0.0recall = TP / (TP + FN) if (TP + FN) > 0 else 0.0# 计算 F1 分数if precision + recall == 0:return 0.0  # 避免除以零f1 = 2 * (precision * recall) / (precision + recall)return f1# 计算 F1 分数
f1 = f1_score(y_true, y_pred)
print(f"F1分数: {f1:.4f}")

4. 多分类任务F1分数代码

  • 对于多分类任务,可以分别计算每个类别的 F1 分数,然后取平均值。

import torch# 假设有真实标签和预测标签(多分类任务)
y_true = torch.tensor([0, 1, 2, 0, 1, 2])  # 真实标签
y_pred = torch.tensor([0, 1, 0, 0, 1, 2])  # 预测标签# 计算每个类别的 F1 分数
def f1_score_multiclass(y_true, y_pred, num_classes):f1_scores = []for cls in range(num_classes):TP = ((y_true == cls) & (y_pred == cls)).sum().item()  # 模型正确预测为正类的样本数FN = ((y_true == cls) & (y_pred != cls)).sum().item()  # 模型错误预测为负类的正类样本数FP = ((y_true != cls) & (y_pred == cls)).sum().item()  # 模型错误预测为正类的正类样本数# 计算精确率和召回率precision = TP / (TP + FP) if (TP + FP) > 0 else 0.0recall = TP / (TP + FN) if (TP + FN) > 0 else 0.0# 计算 F1 分数if precision + recall == 0:f1_scores.append(0.0)  # 避免除以零else:f1_scores.append(2 * (precision * recall) / (precision + recall))return f1_scores# 计算 F1 分数
num_classes = 3
f1_scores = f1_score_multiclass(y_true, y_pred, num_classes)
for cls, f1 in enumerate(f1_scores):print(f"每个类别的F1分数 {cls}: {f1:.4f}")# 计算宏平均 F1 分数
macro_f1 = sum(f1_scores) / num_classes
print(f"宏平均 F1 分数: {macro_f1:.4f}")

八、完整流程(使用直接继承 nn.Module逻辑回归,且仅保存模型的权重和其他参数,计算了二分类任务的精确度、召回率及F1分数)

1. 实现思路

① 自定义数据集

生成 100 个样本,每个样本有 2 个特征。

根据特征生成标签,使用简单的线性组合和阈值判断。

② 定义逻辑回归模型

使用 nn.Linear 定义一个线性层,并通过  实现逻辑回归。

③ 训练模型

使用二元交叉熵损失 (nn.BCELoss) 和随机梯度下降优化器 (optim.SGD) 训练模型。

④ 保存模型

使用 torch.save 保存模型参数。

⑤ 加载模型

使用 torch.load 加载模型参数。

⑥ 预测

加载模型后,使用新数据进行预测,并将概率转换为类别(0 或 1)。

⑦ 评估模型

计算模型的精确度、召回率和 F1 分数。

2. 代码示例

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np# 自定义数据集
# 生成 100 个样本,每个样本有 2 个特征
X = np.random.randn(100, 2).astype(np.float32)
# 根据特征生成标签,使用简单的线性组合和阈值判断
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)# 将 numpy 数组转换为 PyTorch 张量
X_tensor = torch.from_numpy(X)
y_tensor = torch.from_numpy(y)# 定义逻辑回归模型
class LogisticRegression(nn.Module):def __init__(self, input_size):super(LogisticRegression, self).__init__()self.linear = nn.Linear(input_size, 1)self.sigmoid = nn.Sigmoid()def forward(self, x):out = self.linear(x)out = self.sigmoid(out)return out# 初始化模型
input_size = 2
model = LogisticRegression(input_size)# 定义损失函数和优化器
criterion = nn.BCELoss()  # 二元交叉熵损失函数
optimizer = optim.SGD(model.parameters(), lr=0.01)# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):# 前向传播outputs = model(X_tensor)loss = criterion(outputs, y_tensor)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 保存模型
torch.save(model.state_dict(), 'logistic_regression_model.pth')# 加载模型
loaded_model = LogisticRegression(input_size)
loaded_model.load_state_dict(torch.load('logistic_regression_model.pth'))
loaded_model.eval()# 生成新数据进行预测
new_X = np.random.randn(10, 2).astype(np.float32)
new_X_tensor = torch.from_numpy(new_X)# 使用加载的模型进行预测
with torch.no_grad():predictions = loaded_model(new_X_tensor)predicted_labels = (predictions >= 0.5).float()print("预测概率:")
print(predictions.numpy())
print("预测标签:")
print(predicted_labels.numpy())# 计算精确度、召回率和 F1 分数
def evaluate_model(y_true, y_pred):# 计算混淆矩阵TP = ((y_true == 1) & (y_pred == 1)).sum().item()  # 模型正确预测为正类的样本数FN = ((y_true == 1) & (y_pred == 0)).sum().item()  # 模型错误预测为负类的正类样本数FP = ((y_true == 0) & (y_pred == 1)).sum().item()  # 模型错误预测为正类的正类样本数TN = ((y_true == 0) & (y_pred == 0)).sum().item()  # 模型正确预测为负类的样本数# 计算精确度、召回率和 F1 分数accuracy = (TP + TN) / (TP + TN + FP + FN) if (TP + TN + FP + FN) > 0 else 0.0precision = TP / (TP + FP) if (TP + FP) > 0 else 0.0recall = TP / (TP + FN) if (TP + FN) > 0 else 0.0f1 = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0.0return accuracy, precision, recall, f1# 对训练集进行预测,计算评估指标
with torch.no_grad():train_predictions = loaded_model(X_tensor)train_predicted_labels = (train_predictions >= 0.5).float()# 计算评估指标
accuracy, precision, recall, f1 = evaluate_model(y_tensor, train_predicted_labels)# 输出结果
print("\n模型评估结果:")
print(f"精确度: {accuracy:.4f}")
print(f"精确率: {precision:.4f}")
print(f"召回率: {recall:.4f}")
print(f"F1分数: {f1:.4f}")

3. 代码解释 

① 数据集生成:

  • X = np.random.randn(100, 2).astype(np.float32):生成 100 个样本,每个样本有 2 个特征。
  • y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1):根据特征的线性组合生成标签,大于 0 标记为 1,否则标记为 0。
  • X_tensor = torch.from_numpy(X) 和 y_tensor = torch.from_numpy(y):将 numpy 数组转换为 PyTorch 张量。

② 模型定义:

  • LogisticRegression 类继承自 nn.Module,包含一个线性层 nn.Linear 和一个 Sigmoid 激活函数 nn.Sigmoid
  • forward 方法定义了前向传播的逻辑。

③ 损失函数和优化器:

  • criterion = nn.BCELoss():使用二元交叉熵损失函数,适用于二分类问题。
  • optimizer = optim.SGD(model.parameters(), lr=0.01):使用随机梯度下降优化器,学习率为 0.01。

④ 模型训练:

  • 通过多次迭代进行前向传播、损失计算、反向传播和参数更新。
  • 每 100 个 epoch 打印一次损失值。

⑤ 模型保存:

  • torch.save(model.state_dict(), 'logistic_regression_model.pth'):保存模型的参数到本地文件 logistic_regression_model.pth

⑥ 模型加载和预测:

  1. loaded_model = LogisticRegression(input_size):创建一个新的模型实例。
  2. loaded_model.load_state_dict(torch.load('logistic_regression_model.pth')):加载保存的模型参数。
  3. loaded_model.eval():将模型设置为评估模式。
  4. 生成新数据 new_X 并转换为张量 new_X_tensor
  5. 使用 loaded_model 进行预测,通过 (predictions >= 0.5).float() 将预测概率转换为标签。

⑦ 模型评估

  • 定义 evaluate_model 函数:

        计算混淆矩阵(TP、FN、FP、TN)。

        计算精确度、精确率、召回率和 F1 分数。

  • 对训练集进行预测并计算评估指标:

        train_predictions = loaded_model(X_tensor):计算训练集的预测概率。

        train_predicted_labels = (train_predictions >= 0.5).float():将预测概率转换为标签。

  • 输出评估结果:

        精确度(Accuracy):模型预测正确的样本比例。

        精确率(Precision):预测为正类的样本中,实际为正类的比例。

        召回率(Recall):实际为正类的样本中,预测为正类的比例。

        F1 分数(F1 Score):精确率和召回率的调和平均值。

相关文章:

【机器学习】自定义数据集 使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测,对预测结果计算精确度和召回率及F1分数

一、使用pytorch框架实现逻辑回归 1. 数据部分: 首先自定义了一个简单的数据集,特征 X 是 100 个随机样本,每个样本一个特征,目标值 y 基于线性关系并添加了噪声。将 numpy 数组转换为 PyTorch 张量,方便后续在模型中…...

深入理解linux中的文件(上)

1.前置知识: (1)文章 内容 属性 (2)访问文件之前,都必须打开它(打开文件,等价于把文件加载到内存中) 如果不打开文件,文件就在磁盘中 (3&…...

分布式微服务系统架构第90集:现代化金融核心系统

#1.1 深化数字化转型,核心面临新挑战 1、架构侧:无法敏捷协同数字金融经营模式转型。 2、需求侧:业务需求传导低效始终困扰金融机构。 3、开发侧:创新产品上市速度低于期望。 4、运维侧:传统面向资源型监控体系难以支撑…...

Vue简介

目录 Vue是什么?为什么要使用Vue?Vue的三种加载方式拓展:什么是渐进式框架? Vue是什么? Vue是一套用于构建用户界面的渐进式 JavaScript (主张最少)框架 ,开发者只需关注视图层。另一方面,当与…...

【Linux】从零开始:编写你的第一个Linux进度条小程序

Linux相关知识点可以通过点击以下链接进行学习一起加油!初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具 🌈个人主页:是店小二呀 🌈C语言专栏:C语言 &am…...

FFmpeg工具使用基础

一、FFmpeg工具介绍 FFmpeg命令行工具主要包括以下几个部分: ‌ffmpeg‌:编解码工具‌ffprobe‌:多媒体分析器‌ffplay‌:简单的音视频播放器这些工具共同构成了FFmpeg的核心功能,支持各种音视频格式的处理和转换‌ 二、在Ubuntu18.04上安装FFmpeg工具 1、sudo apt-upda…...

数据库管理-第287期 Oracle DB 23.7新特性一览(20250124)

数据库管理287期 2025-01-24 数据库管理-第287期 Oracle DB 23.7新特性一览(20250124)1 AI向量搜索:算术和聚合运算2 更改Compatible至23.6.0,以使用23.6或更高版本中的新AI向量搜索功能3 Cloud Developer包4 DBMS_DEVELOPER.GET_…...

快速提升网站收录:利用网站FAQ页面

本文转自:百万收录网 原文链接:https://www.baiwanshoulu.com/48.html 利用网站FAQ(FrequentlyAskedQuestions,常见问题解答)页面是快速提升网站收录的有效策略之一。以下是一些具体的方法和建议,以帮助你…...

AtCoder Beginner Contest 391(ABCDE)

A - Lucky Direction 翻译: 给你一个字符串 D,代表八个方向(北、东、西、南、东北、西北、东南、西南)之一。方向与其代表字符串之间的对应关系如下。 北: N东: E西: W南: S东…...

解决Django非ORM模型提示初始化request问题

提问 Django在DRF时候自定义显示一些非model的字段提示TypeError: Field.__init__() got an unexpected keyword argument request 解答1 错误提示 TypeError: Field.__init__() got an unexpected keyword argument request 显示在创建序列化器实例时,传递了一个…...

【机器学习】自定义数据集 使用scikit-learn中svm的包实现svm分类

一、支持向量机(support vector machines. ,SVM)概念 1. SVM 绪论 支持向量机(SVM)的核心思想是找到一个最优的超平面,将不同类别的数据点分开。SVM 的关键特点包括: ① 分类与回归: SVM 可以用于分类&a…...

hunyuan 混元学习

使用了5个subset,也是用了text-image和text-video进行训练的 也是进行了复杂的视频选择。同movie gen. 也进行了模型切断,用拉普拉斯算子找到最清晰的一帧作为训练的起始 训练了不同的模型去选择数据,比如用Dover去选择美观度比较好的数据&#xff0c…...

.Net / C# 繁体中文 与 简体中文 互相转换, 支持地方特色词汇

版本号 Nuget 搜索 “OpenCCNET”, 注意别找错, 好多库的名字都差不多 支持 “繁,简” 的互相转换, 支持多个地区常用词汇的转换, 还支持 日文的新旧转换. OpenCC 在 .Net 中的实现 https://github.com/CosineG/OpenCC.NET <PackageReference Include"OpenCCNET"…...

仿真设计|基于51单片机的温湿度、一氧化碳、甲醛检测报警系统

目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现&#xff08;protues8.7&#xff09; 程序&#xff08;Keil5&#xff09; 全部内容 资料获取 具体实现功能 &#xff08;1&#xff09;温湿度传感器、CO传感器、甲醛传感器实时检测温湿度值、CO值和甲醛值进…...

Vue- 组件通信2

一、props props 是使用频率最高的一种通信方式&#xff0c;常用于&#xff1a;父 ↔ 子 若 父传子&#xff1a;属性值是非函数&#xff1b;若 子传父&#xff1a;属性值是函数。 Props: 指的是传递给子组件的属性。子组件通过 props 接收数据。单向数据流: 数据通过 props…...

春晚舞台上的人形机器人:科技与文化的奇妙融合

文章目录 人形机器人Unitree H1的“硬核”实力传统文化与现代科技的创新融合网友热议与文化共鸣未来展望&#xff1a;科技与文化的更多可能结语 2025 年央视春晚的舞台&#xff0c;无疑是全球华人目光聚焦的焦点。就在这个盛大的舞台上&#xff0c;一场名为《秧BOT》的创意融合…...

向上调整算法(详解)c++

算法流程&#xff1a; 与⽗结点的权值作⽐较&#xff0c;如果⽐它⼤&#xff0c;就与⽗亲交换&#xff1b; 交换完之后&#xff0c;重复 1 操作&#xff0c;直到⽐⽗亲⼩&#xff0c;或者换到根节点的位置 这里为什么插入85完后合法&#xff1f; 我们插入一个85&#xff0c;…...

Python之Excel操作 - 写入数据

我们将使用 openpyxl 库&#xff0c;它是一个功能强大且易于使用的库&#xff0c;专门用于处理 Excel 文件。 1. 安装 openpyxl 首先&#xff0c;你需要安装 openpyxl 库。你可以使用 pip 命令进行安装&#xff1a; pip install openpyxl创建一个文件 example.xlsx&#xff…...

MYSQL--一条SQL执行的流程,分析MYSQL的架构

文章目录 第一步建立连接第二部解析 SQL第三步执行 sql预处理优化阶段执行阶段索引下推 执行一条select 语句中间会发生什么&#xff1f; 这个是对 mysql 架构的深入理解。 select * from product where id 1;对于mysql的架构分层: mysql 架构分成了 Server 层和存储引擎层&a…...

【开源免费】基于Vue和SpringBoot的流浪宠物管理系统(附论文)

本文项目编号 T 182 &#xff0c;文末自助获取源码 \color{red}{T182&#xff0c;文末自助获取源码} T182&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

您与此网站之间建立的连接不安全

网站建立好后&#xff0c;用360浏览器打开后地址栏有一个灰色小锁打着红色叉点击后显示“您与此网站之间建立的连接不安全”“请勿在此网站上输入任何敏感信息&#xff08;例如密码或信用卡信息&#xff09;&#xff0c;因为攻击者可能会盗取这些信息。” 出现这个提示的主要原…...

kamailio-ACC模块介绍【kamailio6.0. X】

Acc 模块 作者 Jiri Kuthan iptel.org jiriiptel.org Bogdan-Andrei Iancu Voice Sistem SRL bogdanvoice-system.ro Ramona-Elena Modroiu rosdev.ro ramonarosdev.ro 编辑 Bogdan-Andrei Iancu Voice Sistem SRL bogdanvoice-system.ro Sven Knoblich 1&1 Internet …...

图漾相机——Sample_V1示例程序

文章目录 1.SDK支持的平台类型1.1 Windows 平台1.2 Linux平台 2.SDK基本知识2.1 SDK目录结构2.2 设备组件简介2.3 设备组件属性2.4 设备的帧数据管理机制2.5 SDK中的坐标系变换 3.Sample_V1示例程序3.1 DeviceStorage3.2 DumpCalibInfo3.3 NetStatistic3.4 SimpleView_SaveLoad…...

谈谈你所了解的AR技术吧!

深入探讨 AR 技术的原理与应用 在科技飞速发展的今天&#xff0c;AR&#xff08;增强现实&#xff09;技术已经悄然改变了我们与周围世界互动的方式。你是否曾想象过如何能够通过手机屏幕与虚拟物体进行实时互动&#xff1f;在这篇文章中&#xff0c;我们将深入探讨AR技术的原…...

C++计算特定随机操作后序列元素乘积的期望

有一个长度为 n n n的序列 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1​,a2​,...,an​。初始序列的所有元素均为 0 0 0。再给定正整数 m m m、 c c c和 ( n − m 1 ) (n-m1) (n−m1)个正整数 b 1 , b 2 , . . . , b n − m 1 b_1,b_2,...,b_{n-m1} b1​,b2​,...,bn−m1​…...

【机器学习理论】朴素贝叶斯网络

基础知识&#xff1a; 先验概率&#xff1a;对某个事件发生的概率的估计。可以是基于历史数据的估计&#xff0c;可以由专家知识得出等等。一般是单独事件概率。 后验概率&#xff1a;指某件事已经发生&#xff0c;计算事情发生是由某个因素引起的概率。一般是一个条件概率。 …...

NPM 使用介绍

NPM 使用介绍 引言 NPM(Node Package Manager)是Node.js生态系统中的一个核心工具,用于管理JavaScript项目的依赖包。无论是开发一个小型脚本还是构建大型应用程序,NPM都能极大地提高开发效率。本文将详细介绍NPM的使用方法,包括安装、配置、依赖管理、包发布等,帮助您…...

langchain 实现多智能体多轮对话

这里写目录标题 工具定义模型选择graph节点函数定义graph 运行 工具定义 import random from typing import Annotated, Literalfrom langchain_core.tools import tool from langchain_core.tools.base import InjectedToolCallId from langgraph.prebuilt import InjectedSt…...

网络攻防实战指北专栏讲解大纲与网络安全法

专栏 本专栏为网络攻防实战指北&#xff0c;大纲如下所示 进度&#xff1a;目前已更完准备篇、HTML基础 计划&#xff1a;所谓基础不牢&#xff0c;地动山摇。所以下一步将持续更新基础篇内容 讲解信息安全时&#xff0c;结合《中华人民共和国网络安全法》&#xff08;以下简…...

四、jQuery笔记

(一)jQuery概述 jQuery本身是js的一个轻量级的库,封装了一个对象jQuery,jquery的所有语法都在jQuery对象中 浏览器不认识jquery,只渲染html、css和js代码,需要先导入jQuery文件,官网下载即可 jQuery中文说明文档:https://hemin.cn/jq/ (二)jQuery要点 1、jQuery对象 …...

解锁微服务:五大进阶业务场景深度剖析

目录 医疗行业&#xff1a;智能诊疗的加速引擎 电商领域&#xff1a;数据依赖的破局之道 金融行业&#xff1a;运维可观测性的提升之路 物流行业&#xff1a;智慧物流的创新架构 综合业务&#xff1a;服务依赖的优化策略 医疗行业&#xff1a;智能诊疗的加速引擎 在医疗行业迈…...

C++:虚函数与多态性习题2

题目内容&#xff1a; 编写程序&#xff0c;声明抽象基类Shape&#xff0c;由它派生出3个派生类&#xff1a;Circle、Rectangle、Triangle&#xff0c;用虚函数分别计算图形面积&#xff0c;并求它们的和。要求用基类指针数组&#xff0c;使它每一个元素指向一个派生类对象。 …...

开源软件协议介绍

一、可以闭源使用/不具传染性的协议 允许商业使用和分发 1、BSD&#xff1a;详细介绍 2、LGPL许可证&#xff1a;详细介绍 3、MPL2.0&#xff1a;详细介绍 二、具有传染性/使用后需要开源自身软件的协议 不建议商业使用 1、GPL许可证&#xff1a;详细介绍...

MapReduce简单应用(一)——WordCount

目录 1. 执行过程1.1 分割1.2 Map1.3 Combine1.4 Reduce 2. 代码和结果2.1 pom.xml中依赖配置2.2 工具类util2.3 WordCount2.4 结果 参考 1. 执行过程 假设WordCount的两个输入文本text1.txt和text2.txt如下。 Hello World Bye WorldHello Hadoop Bye Hadoop1.1 分割 将每个文…...

【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)

目录 1 -> 生命周期 1.1 -> 应用生命周期 1.2 -> 页面生命周期 2 -> 资源限定与访问 2.1 -> 资源限定词 2.2 -> 资源限定词的命名要求 2.3 -> 限定词与设备状态的匹配规则 2.4 -> 引用JS模块内resources资源 3 -> 多语言支持 3.1 -> 定…...

(9) 上:学习与验证 linux 里的 epoll 对象里的 EPOLLIN、 EPOLLHUP 与 EPOLLRDHUP 的不同

&#xff08;1&#xff09;经过之前的学习。俺认为结论是这样的&#xff0c;因为三次握手到四次挥手&#xff0c;到 RST 报文&#xff0c;都是 tcp 连接上收到了报文&#xff0c;这都属于读事件。所以&#xff1a; EPOLLIN : 包含了读事件&#xff0c; FIN 报文的正常四次挥手、…...

Avalonia与QtQuick的简单对比

这个是Avalonia开发的示例应用程序&#xff08;官方入门示例&#xff09;&#xff08;Avalonia 11.1.0 .Net 9.0&#xff09; 刚启动时&#xff0c;内存占用150M左右&#xff0c;稍等一会儿后&#xff0c;内存占用降低到77M左右&#xff0c;CPU占用一直都在&#xff0c;我i9-…...

WebForms DataList 深入解析

WebForms DataList 深入解析 引言 在Web开发领域,控件是构建用户界面(UI)的核心组件。ASP.NET WebForms框架提供了丰富的控件,其中DataList控件是一个灵活且强大的数据绑定控件。本文将深入探讨WebForms DataList控件的功能、用法以及在实际开发中的应用。 DataList控件…...

jetson编译torchvision出现 No such file or directory: ‘:/usr/local/cuda/bin/nvcc‘

文章目录 1. 完整报错2. 解决方法 1. 完整报错 jetson编译torchvision,执行python3 setup.py install --user遇到报错 running build_ext error: [Errno 2] No such file or directory: :/usr/local/cuda/bin/nvcc完整报错信息如下&#xff1a; (pytorch) nxnx-desktop:~/Do…...

《苍穹外卖》项目学习记录-Day10订单状态定时处理

利用Cron表达式生成器生成Cron表达式 1.处理超时订单 查询订单表把超时的订单查询出来&#xff0c;也就是订单的状态为待付款&#xff0c;下单的时间已经超过了15分钟。 //select * from orders where status ? and order_time < (当前时间 - 15分钟) 遍历集合把数据库…...

“新月智能武器系统”CIWS,开启智能武器的新纪元

新月人物传记&#xff1a;人物传记之新月篇-CSDN博客 相关文章链接&#xff1a;星际战争模拟系统&#xff1a;新月的编程之道-CSDN博客 新月智能护甲系统CMIA--未来战场的守护者-CSDN博客 “新月之智”智能战术头盔系统&#xff08;CITHS&#xff09;-CSDN博客 目录 智能武…...

FPGA| 使用Quartus II报错Top-level design entity ““ is undefined

1、使用FPGA准备点亮LED测试下板子&#xff0c;发现这个报错Error (12007): Top-level design entity "LEDLED" is undefined 工程如上图 报错如下图 2、分析到原因是因为工程名称和顶层模块里面的module名称不一样导致 解决办法&#xff1a;修改module名称和顶层模…...

如何实现滑动列表功能

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了沉浸式状态栏相关的内容&#xff0c;本章回中将介绍SliverList组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在这里介绍的SliverList组件是一种列表类组件&#xff0c;类似我们之前介…...

数据结构:优先级队列—堆

一、优先级队列 1、优先级队列概念 优先级队列&#xff0c;听名字我们就知道他是一种队列&#xff0c;队列在前面我们已经学习过了&#xff0c;它是一种先进先出的数据结构&#xff0c;但是在特殊的情况下&#xff0c;我们我们队列中元素是带有一定优先级的&#xff0c;它需要…...

SpringCloud系列教程:微服务的未来(十八)雪崩问题、服务保护方案、Sentinel快速入门

前言 在分布式系统中&#xff0c;雪崩效应&#xff08;Avalanche Effect&#xff09;是一种常见的故障现象&#xff0c;通常发生在系统中某个组件出现故障时&#xff0c;导致其他组件级联失败&#xff0c;最终引发整个系统的崩溃。为了有效应对雪崩效应&#xff0c;服务保护方…...

Java小白入门教程:Object

目录 一、定义 二、作用 三、使用场景 四、语法以及示例 1、创建Object类型的对象 2、使用 toString()方法 3、使用 equals()方法 4、使用 hashCode()方法 5、使用 getClass()方法 6、使用 clone()方法 7、使用 finalize()方法 一、定义 在Java中&#xff0c; object…...

ubuntu 更新24LTS中断导致“系统出错且无法恢复,请联系系统管理员”

22LTS to 24LTS 更新过程中手jian把更新程序controlC导致的。 解决 目前企图完成更新来恢复&#xff0c;重启后有软件包冲突&#xff0c;sudo apt upgrade报冲突。无法进行。 将原来source.list重新 sudo dpkg --configure -a sudo apt install -f 这些都不管用。还是显示gno…...

【单细胞第二节:单细胞示例数据分析-GSE218208】

GSE218208 1.创建Seurat对象 #untar(“GSE218208_RAW.tar”) rm(list ls()) a data.table::fread("GSM6736629_10x-PBMC-1_ds0.1974_CountMatrix.tsv.gz",data.table F) a[1:4,1:4] library(tidyverse) a$alias:gene str_split(a$alias:gene,":",si…...

ComfyUI安装调用DeepSeek——DeepSeek多模态之图形模型安装问题解决(ComfyUI-Janus-Pro)

ComfyUI 的 Janus-Pro 节点&#xff0c;一个统一的多模态理解和生成框架。 试用&#xff1a; https://huggingface.co/spaces/deepseek-ai/Janus-1.3B https://huggingface.co/spaces/deepseek-ai/Janus-Pro-7B https://huggingface.co/spaces/deepseek-ai/JanusFlow-1.3B 安装…...

FLTK - FLTK1.4.1 - demo - bitmap

文章目录 FLTK - FLTK1.4.1 - demo - bitmap概述笔记END FLTK - FLTK1.4.1 - demo - bitmap 概述 // 功能 : 演示位图数据在按钮上的显示 // * 以按钮为范围或者以窗口为范围移动 // * 上下左右, 文字和图像的相对位置 // 失能按钮&#xff0c;使能按钮 // 知识点 // FLTK可…...