【计算机视觉基础CV-图像分类】05 - 深入解析ResNet与GoogLeNet:从基础理论到实际应用
引言
在上一篇文章中,我们详细介绍了ResNet与GoogLeNet的网络结构、设计理念及其在图像分类中的应用。本文将继续深入探讨如何在实际项目中应用这些模型,特别是如何保存训练好的模型、加载模型以及使用模型进行新图像的预测。通过这些步骤,读者将能够完整地掌握从模型训练到部署的全过程。
ps:数据集已经发布~
目录:
-
ResNet简介
-
ResNet的网络结构
-
残差块
-
ResNet模型架构
-
-
GoogLeNet简介
-
GoogLeNet的网络结构
-
Inception模块
-
GoogLeNet模型架构
-
-
ResNet与GoogLeNet的对比
-
实际应用:利用ResNet进行图像分类
-
数据准备与预处理
-
模型实例化与参数设置
-
模型训练与评估
-
模型保存与加载
-
新图像预测
-
完整代码实现详解
-
-
总结与展望
-
参考文献
ResNet简介
随着深度神经网络层数的增加,模型的表达能力显著提升。然而,网络越深,训练过程中面临的梯度消失、梯度爆炸等问题也愈加严重,导致模型性能难以进一步提升。2015年,何凯明等人提出了残差网络(ResNet),通过引入“跳跃连接”(Shortcut Connections)有效缓解了深层网络训练中的退化问题,使得训练超过百层的深度网络成为可能。ResNet在2015年的ImageNet图像识别挑战赛中取得了显著成绩,极大地影响了后续深度神经网络的设计。
ResNet的网络结构
残差块
在传统的深层神经网络中,随着网络深度的增加,模型的训练误差往往呈现上升趋势,这被称为“退化问题”。ResNet通过引入残差块(Residual Block)解决了这一问题。
这种结构被称为“跳跃连接”(Shortcut Connection),它允许梯度直接在网络中传播,缓解了梯度消失的问题。基础残差块
输入 x|Conv3x3|BatchNorm|ReLU|Conv3x3|BatchNorm|+-----+| |x || |+-----+|ReLU|输出 H(x) = F(x) + x
瓶颈残差块
输入 x|Conv1x1|BatchNorm|ReLU|Conv3x3|BatchNorm|ReLU|Conv1x1|BatchNorm|+-----+| |x || |+-----+|ReLU|输出 H(x) = F(x) + x
ResNet模型架构
ResNet的整体架构由多个残差块堆叠而成,不同的ResNet版本(如ResNet-18、ResNet-34、ResNet-50、ResNet-101、ResNet-152)主要区别在于残差块的类型及其数量。以ResNet-50为例,其结构如下:
图2:ResNet-34架构图 来源
下图:ResNet 的常见版本架构
GoogLeNet简介
GoogLeNet,又称为Inception v1,是Google在2014年提出的一种深度卷积神经网络模型。与ResNet不同,GoogLeNet主要通过Inception模块的设计,实现了网络结构的深度和宽度的有效扩展,同时控制了计算复杂度。GoogLeNet在2014年的ImageNet挑战赛中取得了优异成绩,显著降低了参数数量。
图3:GoogLeNet架构图 来源
GoogLeNet的网络结构
Inception模块
Inception模块是GoogLeNet的核心创新,通过在同一层次上并行应用不同尺寸的卷积核和池化操作,捕捉多尺度的特征信息。具体来说,一个Inception模块通常包括以下几部分:
-
1x1卷积:用于减少维度,降低计算量。
-
3x3卷积:处理空间信息。
-
5x5卷积:处理更大范围的空间信息。
-
3x3最大池化:用于下采样,后接1x1卷积。
通过这些并行的操作,Inception模块能够同时捕捉到不同尺度的特征,提高了模型的表达能力。
GoogLeNet模型架构
图4:Inception模块示意图 来源
ResNet与GoogLeNet的对比
| 特性 | ResNet | GoogLeNet |
|---|---|---|
| 核心创新 | 残差学习(Residual Learning) | Inception模块 |
| 网络深度 | 可扩展至超过100层 | 22层,后续版本如Inception v2、v3更深 |
| 参数数量 | 随层数增加显著 | 通过Inception模块有效控制参数数量 |
| 训练难度 | 残差块设计缓解深层网络的训练难题 | 多路径结构复杂,需精心设计和训练 |
| 应用场景 | 图像分类、目标检测、语义分割等多种任务 | 主要用于图像分类,后续版本扩展至其他任务 |
| 计算效率 | 残差块结构相对简单,计算效率高 | Inception模块复杂,但通过1x1卷积降低计算量 |
实际应用:利用ResNet进行图像分类
本文将以ResNet-18为例,演示如何在PyTorch框架下构建、训练和评估一个图像分类模型。以鲜花种类识别为案例,读者可以通过本文的步骤,掌握从数据准备到模型训练、保存、加载及预测的完整流程。
数据准备与预处理
首先,确保已下载并整理好鲜花数据集。数据集通常分为训练集和测试集,分别存放在不同的文件夹中。为了适应ResNet-18的输入要求,需要将图像尺寸调整为224x224。
from torchvision import transforms
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
# 指定批次大小
batch_size = 16
# 指定数据集路径
flower_train_path = './dataset/flower_datas/train/'
flower_test_path = './dataset/flower_datas/val/'
# 数据预处理:调整图像大小并转换为Tensor
dataset_transform = transforms.Compose([transforms.Resize((224, 224)), # 调整图像大小为224x224transforms.ToTensor() # 将图像转换为Tensor
])
# 加载训练集和测试集
flower_train = ImageFolder(flower_train_path, transform=dataset_transform)
flower_test = ImageFolder(flower_test_path, transform=dataset_transform)
# 创建数据加载器
train_loader = DataLoader(dataset=flower_train, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=flower_test, batch_size=batch_size, shuffle=False)
说明:
-
使用
transforms.Resize将图像调整为224x224,以匹配ResNet的输入要求。 -
使用
ImageFolder加载数据集,确保数据集目录结构符合PyTorch的要求(每个类别一个文件夹)。 -
使用
DataLoader创建训练和测试数据加载器,设置批次大小和是否打乱数据。
模型实例化与参数设置
使用PyTorch内置的ResNet-18模型,并根据任务需要调整输出类别数。
import torch
import torchvision.models as models
# 实例化ResNet-18模型,调整输出类别数为5
model = models.resnet18(num_classes=5)
# 设置训练设备为GPU(如果可用)否则为CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
# 定义优化器(Adam)和损失函数(交叉熵损失)
learning_rate = 1e-3
num_epochs = 25
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
loss_fn = torch.nn.CrossEntropyLoss()
说明:
-
models.resnet18(num_classes=5):加载ResNet-18模型,并将最后的全连接层调整为输出5个类别。 -
device:自动检测是否有GPU可用,并将模型移动到对应设备以加速训练。 -
optimizer:选择Adam优化器,并设置学习率。 -
loss_fn:使用交叉熵损失函数,适用于多分类任务。
模型训练与评估
定义训练和评估函数,逐步训练模型并监控其性能。
import matplotlib.pyplot as plt
# 评估模型准确率
def evaluate_accuracy(data_iter, model):model.eval() # 设置模型为评估模式correct = 0total = 0with torch.no_grad(): # 不计算梯度for images, labels in data_iter:images, labels = images.to(device), labels.to(device)outputs = model(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()return correct / total
# 训练模型
def train_model(model, train_loader, test_loader, optimizer, loss_fn, num_epochs):train_losses = []train_accuracies = []test_accuracies = []for epoch in range(num_epochs):model.train() # 设置模型为训练模式running_loss = 0.0correct = 0total = 0for images, labels in train_loader:images, labels = images.to(device), labels.to(device)# 前向传播outputs = model(images)loss = loss_fn(outputs, labels)# 反向传播和优化optimizer.zero_grad() # 清除之前的梯度loss.backward() # 反向传播计算梯度optimizer.step() # 更新参数# 统计损失和准确率running_loss += loss.item()_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()# 计算平均损失和准确率epoch_loss = running_loss / len(train_loader)epoch_acc = correct / totaltest_acc = evaluate_accuracy(test_loader, model)train_losses.append(epoch_loss)train_accuracies.append(epoch_acc)test_accuracies.append(test_acc)print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {epoch_loss:.4f}, 'f'Train Acc: {epoch_acc:.3f}, Test Acc: {test_acc:.3f}')print('训练完成')# 绘制损失和准确率曲线epochs = range(1, num_epochs+1)plt.figure(figsize=(12,5))# 绘制训练损失曲线plt.subplot(1,2,1)plt.plot(epochs, train_losses, 'r', label='训练损失')plt.xlabel('Epoch')plt.ylabel('Loss')plt.title('训练损失曲线')plt.legend()# 绘制训练和测试准确率曲线plt.subplot(1,2,2)plt.plot(epochs, train_accuracies, 'g', label='训练准确率')plt.plot(epochs, test_accuracies, 'b', label='测试准确率')plt.xlabel('Epoch')plt.ylabel('Accuracy')plt.title('准确率曲线')plt.legend()plt.show()
说明:
-
evaluate_accuracy函数用于评估模型在测试集上的准确率,设置模型为评估模式,避免梯度计算。 -
train_model函数负责整个训练过程,包括前向传播、计算损失、反向传播、优化参数,以及记录和绘制损失与准确率曲线。 -
在每个epoch结束后,输出当前epoch的损失、训练准确率和测试准确率。
输出:
模型保存与加载
在完成模型训练后,保存训练好的模型是非常重要的步骤。保存模型不仅可以避免重复训练,还可以在需要时加载模型进行预测或进一步训练。
1. 保存模型
使用PyTorch的torch.save函数可以方便地保存模型的参数(state_dict)或整个模型。
# 保存模型参数
torch.save(model.state_dict(), 'resnet18_flower.pth')
print("模型已保存为 resnet18_flower.pth")
说明:
-
model.state_dict():获取模型的所有参数。 -
torch.save:将参数保存到指定路径。 -
推荐保存模型的参数而不是整个模型,因为保存参数更加灵活,适用于不同的应用场景。
2. 加载模型
在需要使用保存的模型时,可以通过加载模型参数来恢复模型。
# 实例化模型结构
model_loaded = models.resnet18(num_classes=5)
# 加载模型参数
model_loaded.load_state_dict(torch.load('resnet18_flower.pth'))
# 设置模型为评估模式
model_loaded.eval()
# 将模型移动到对应设备
model_loaded = model_loaded.to(device)
print("模型已加载并准备就绪")
说明:
-
实例化与保存时相同结构的模型。
-
使用
load_state_dict加载保存的参数。 -
设置模型为评估模式,避免在推理时启用训练模式的行为(如Dropout)。
-
将模型移动到相应设备(GPU或CPU)。
新图像预测
完成模型的加载后,可以使用模型对新图像进行预测。以下步骤展示了如何加载新图像、进行预处理、并使用模型进行预测。
from PIL import Image
import numpy as np
# 定义类别标签(根据实际数据集调整)
class_names = ['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']
# 图像预处理函数
def preprocess_image(image_path):# 定义与训练时相同的预处理步骤transform = transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor()])# 打开图像image = Image.open(image_path).convert('RGB')# 应用预处理image = transform(image)# 增加批次维度image = image.unsqueeze(0)return image
# 预测函数
def predict(image_path, model, class_names):# 预处理图像image = preprocess_image(image_path)image = image.to(device)# 进行预测model.eval()with torch.no_grad():outputs = model(image)_, predicted = torch.max(outputs.data, 1)# 获取预测结果predicted_class = class_names[predicted.item()]return predicted_class
# 示例:预测新图像
new_image_path = './dataset/flower_datas/test/daisy/daisy_001.jpg' # 替换为实际图像路径
predicted_label = predict(new_image_path, model_loaded, class_names)
print(f"预测结果:{predicted_label}")
说明:
-
preprocess_image函数:加载并预处理新图像,使其符合模型输入要求。 -
predict函数:加载预处理后的图像,使用模型进行前向传播,获取预测结果。 -
class_names:根据实际数据集定义类别标签。 -
示例中替换
new_image_path为实际需要预测的图像路径。
完整代码实现详解
以下是完整的代码实现,包括数据准备、模型定义、训练、保存、加载及新图像预测。代码中包含详细注释,帮助您理解每一步的具体操作。
# 导入相关的工具包
import torch
import torchvision.models as models
from torchvision import transforms
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
# 指定批次大小
batch_size = 16
# 指定数据集路径
flower_train_path = './dataset/flower_datas/train/'
flower_test_path = './dataset/flower_datas/val/'
# 数据预处理:调整图像大小并转换为Tensor
dataset_transform = transforms.Compose([transforms.Resize((224, 224)), # 调整图像大小为224x224transforms.ToTensor() # 将图像转换为Tensor
])
# 加载训练集和测试集
flower_train = ImageFolder(flower_train_path, transform=dataset_transform)
flower_test = ImageFolder(flower_test_path, transform=dataset_transform)
# 创建数据加载器
train_loader = DataLoader(dataset=flower_train, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=flower_test, batch_size=batch_size, shuffle=False)
# 实例化ResNet-18模型,调整输出类别数为5
model = models.resnet18(num_classes=5)
# 设置训练设备为GPU(如果可用)否则为CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
# 定义优化器(Adam)和损失函数(交叉熵损失)
learning_rate = 1e-3
num_epochs = 25
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
loss_fn = torch.nn.CrossEntropyLoss()
# 评估模型准确率
def evaluate_accuracy(data_iter, model):model.eval() # 设置模型为评估模式correct = 0total = 0with torch.no_grad(): # 不计算梯度for images, labels in data_iter:images, labels = images.to(device), labels.to(device)outputs = model(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()return correct / total
# 训练模型
def train_model(model, train_loader, test_loader, optimizer, loss_fn, num_epochs):train_losses = []train_accuracies = []test_accuracies = []for epoch in range(num_epochs):model.train() # 设置模型为训练模式running_loss = 0.0correct = 0total = 0for images, labels in train_loader:images, labels = images.to(device), labels.to(device)# 前向传播outputs = model(images)loss = loss_fn(outputs, labels)# 反向传播和优化optimizer.zero_grad() # 清除之前的梯度loss.backward() # 反向传播计算梯度optimizer.step() # 更新参数# 统计损失和准确率running_loss += loss.item()_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()# 计算平均损失和准确率epoch_loss = running_loss / len(train_loader)epoch_acc = correct / totaltest_acc = evaluate_accuracy(test_loader, model)train_losses.append(epoch_loss)train_accuracies.append(epoch_acc)test_accuracies.append(test_acc)print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {epoch_loss:.4f}, 'f'Train Acc: {epoch_acc:.3f}, Test Acc: {test_acc:.3f}')print('训练完成')# 绘制损失和准确率曲线epochs = range(1, num_epochs+1)plt.figure(figsize=(12,5))# 绘制训练损失曲线plt.subplot(1,2,1)plt.plot(epochs, train_losses, 'r', label='训练损失')plt.xlabel('Epoch')plt.ylabel('Loss')plt.title('训练损失曲线')plt.legend()# 绘制训练和测试准确率曲线plt.subplot(1,2,2)plt.plot(epochs, train_accuracies, 'g', label='训练准确率')plt.plot(epochs, test_accuracies, 'b', label='测试准确率')plt.xlabel('Epoch')plt.ylabel('Accuracy')plt.title('准确率曲线')plt.legend()plt.show()
# 保存模型参数
def save_model(model, path='resnet18_flower.pth'):torch.save(model.state_dict(), path)print(f"模型已保存为 {path}")
# 加载模型参数
def load_model(path='resnet18_flower.pth'):model_loaded = models.resnet18(num_classes=5)model_loaded.load_state_dict(torch.load(path))model_loaded = model_loaded.to(device)model_loaded.eval()print("模型已加载并准备就绪")return model_loaded
# 图像预处理函数
def preprocess_image(image_path):# 定义与训练时相同的预处理步骤transform = transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor()])# 打开图像image = Image.open(image_path).convert('RGB')# 应用预处理image = transform(image)# 增加批次维度image = image.unsqueeze(0)return image
# 预测函数
def predict(image_path, model, class_names):# 预处理图像image = preprocess_image(image_path)image = image.to(device)# 进行预测model.eval()with torch.no_grad():outputs = model(image)_, predicted = torch.max(outputs.data, 1)# 获取预测结果predicted_class = class_names[predicted.item()]return predicted_class
# 定义类别标签(根据实际数据集调整)
class_names = ['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']
# 开始训练
train_model(model, train_loader, test_loader, optimizer, loss_fn, num_epochs)
# 保存训练好的模型
save_model(model, 'resnet18_flower.pth')
# 加载保存的模型
model_loaded = load_model('resnet18_flower.pth')
# 示例:预测新图像
new_image_path = './dataset/flower_datas/test/daisy/daisy_001.jpg' # 替换为实际图像路径
predicted_label = predict(new_image_path, model_loaded, class_names)
print(f"预测结果:{predicted_label}")
代码注释详解:
-
数据准备:
-
使用
transforms.Resize将图像调整为224x224,以匹配ResNet的输入要求。 -
使用
ImageFolder加载数据集,确保每个类别的图像存放在单独的文件夹中。 -
使用
DataLoader创建训练和测试数据加载器,设置批次大小和是否打乱数据。
-
-
模型实例化与参数设置:
-
使用
models.resnet18加载ResNet-18模型,并将最后的全连接层调整为5个输出类别。 -
检测是否有GPU可用,并将模型移动到对应设备以加速训练。
-
定义优化器(Adam)和损失函数(交叉熵损失),设置学习率和训练轮数。
-
-
训练与评估:
-
定义
evaluate_accuracy函数,用于在测试集上评估模型的准确率,设置模型为评估模式,避免梯度计算。 -
定义
train_model
函数,包含整个训练过程:
-
设置模型为训练模式。
-
遍历每个epoch和每个batch,进行前向传播、计算损失、反向传播和优化参数。
-
记录每个epoch的损失和准确率。
-
在每个epoch结束后,评估模型在测试集上的准确率。
-
绘制训练损失和准确率曲线,直观展示模型的训练过程。
-
-
-
模型保存与加载:
-
定义
save_model函数,使用torch.save将模型的参数保存到指定路径。 -
定义
load_model函数,实例化相同结构的模型,并使用load_state_dict加载保存的参数。设置模型为评估模式,并移动到对应设备。
-
-
新图像预测:
-
定义
preprocess_image函数,加载并预处理新图像,使其符合模型输入要求。 -
定义
predict函数,加载预处理后的图像,使用模型进行前向传播,获取预测结果。 -
示例中替换
new_image_path为实际需要预测的图像路径,打印预测结果。
-
完整流程说明:
-
数据准备:加载并预处理数据集,包括图像尺寸调整和格式转换。
-
模型定义与参数设置:实例化ResNet-18模型,定义优化器和损失函数,并将模型移动到训练设备。
-
模型训练与评估:通过训练函数,迭代训练模型,并在每个epoch后评估模型性能。
-
模型保存:训练完成后,使用
torch.save保存模型的参数。 -
模型加载:在需要使用模型时,实例化相同结构的模型,并加载保存的参数。
-
新图像预测:加载并预处理新图像,使用加载的模型进行预测,输出预测结果。
示例运行结果
训练过程的输出如下:
Epoch [1/25], Loss: 1.3775, Train Acc: 0.442, Test Acc: 0.516 Epoch [2/25], Loss: 1.1998, Train Acc: 0.528, Test Acc: 0.552 ... Epoch [25/25], Loss: 0.7376, Train Acc: 0.730, Test Acc: 0.684 训练完成 模型已保存为 resnet18_flower.pth 模型已加载并准备就绪 预测结果:daisy
通过绘制的损失和准确率曲线,可以直观地观察模型的训练过程和性能提升情况。
总结与展望
本文详细介绍了ResNet与GoogLeNet两种经典深度卷积神经网络的结构与设计理念,并通过实际案例演示了如何在PyTorch框架下应用ResNet进行图像分类任务。特别是通过增加模型保存、加载和新图像预测的步骤,展示了完整的从训练到部署的流程。
关键总结:
-
ResNet通过引入残差块有效解决了深层网络的训练难题,使得训练超过100层的深度网络成为可能。
-
GoogLeNet通过Inception模块实现了网络深度和宽度的有效扩展,同时控制了计算复杂度,适用于计算资源有限的场景。
-
实际应用中,选择适当的网络结构和参数设置对于提升模型性能至关重要。
-
模型的保存与加载是深度学习项目中重要的步骤,确保训练成果能够被复用和部署。
未来展望:
随着深度学习技术的不断发展,更多高效的网络架构不断涌现,如DenseNet、EfficientNet等。结合更先进的优化算法和硬件加速技术,深度神经网络将在计算机视觉、自然语言处理等领域发挥更大的作用。此外,模型压缩与加速技术的发展,也将推动深度学习模型在移动设备和边缘计算中的广泛应用。
参考文献
-
He, K., Zhang, X., Ren, S., & Sun, J. (2016). Deep Residual Learning for Image Recognition. arXiv preprint arXiv:1512.03385.
-
Szegedy, C., Liu, W., Jia, Y., Sermanet, P., Reed, S., Anguelov, D., ... & Rabinovich, A. (2015). Going deeper with convolutions. Proceedings of the IEEE conference on computer vision and pattern recognition.
-
He, K., Zhang, X., Ren, S., & Sun, J. (2016). Identity Mappings in Deep Residual Networks. European Conference on Computer Vision (ECCV).
-
Ioffe, S., & Szegedy, C. (2015). Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift. International Conference on Machine Learning (ICML).
本文内容结合了公开的学术论文与实践经验,旨在为读者提供清晰、系统的ResNet与GoogLeNet解析。如有任何问题或建议,欢迎在评论区交流讨论。
相关文章:
【计算机视觉基础CV-图像分类】05 - 深入解析ResNet与GoogLeNet:从基础理论到实际应用
引言 在上一篇文章中,我们详细介绍了ResNet与GoogLeNet的网络结构、设计理念及其在图像分类中的应用。本文将继续深入探讨如何在实际项目中应用这些模型,特别是如何保存训练好的模型、加载模型以及使用模型进行新图像的预测。通过这些步骤,读…...
【人工智能-初级】基于用户的协同过滤推荐算法
文章目录 1. 数据集2. 实验代码3. 代码解释4. 实验结果5. 评估基于用户的协同过滤算法是一种常见的推荐算法,它的核心思想是根据用户之间的相似性来进行推荐。 实验案例: 使用的是电影推荐数据集 MovieLens,实验中我们会通过用户评分数据计算用户之间的相似性,并使用基于用户…...
如何识别钓鱼邮件和诈骗网站?(附网络安全意识培训PPT资料)
识别钓鱼邮件和诈骗网站是网络安全中的一个重要环节。以下是一些识别钓鱼邮件和诈骗网站的方法: 识别钓鱼邮件: 检查发件人地址: 仔细查看发件人的电子邮件地址,看是否与官方域名一致。 检查邮件内容: 留意邮件中是否…...
Rust 在前端基建中的使用
摘要 随着前端技术的不断发展,前端基础设施(前端基建)的建设已成为提升开发效率、保障产品质量的关键环节。然而,在应对复杂业务场景与高性能需求时,传统的前端技术栈逐渐暴露出诸多不足。近年来,Rust语言…...
【人工智能】基于Python和OpenCV实现实时人脸识别系统:从基础到应用
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着人工智能和计算机视觉的快速发展,人脸识别技术已广泛应用于监控、安全、社交媒体、金融和医疗等领域。本文将介绍如何利用Python和Ope…...
Python 自动化 打开网站 填表登陆 例子
图样 简价: 简要说明这个程序的功能: 1. **基本功能**: - 自动打开网站 - 自动填写登录信息(号、公司名称、密码) - 显示半透明状态窗口实时提示操作进度 2. **操作流程**: - 打开网站后自动…...
【Chrome】浏览器提示警告Chrome is moving towards a new experience
文章目录 前言一、如何去掉 前言 Chrome is moving towards a new experience that allows users to choose to browse without third-party cookies. 这是谷歌浏览器(Chrome)关于隐私策略更新相关的提示 提示:以下是本篇文章正文内容&…...
网络下载ts流媒体
网络下载ts流媒体 查看下载排序合并 很多视频网站,尤其是微信小程序中的长视频无法获取到准确视频地址,只能抓取到.ts片段地址,下载后发现基本都是5~8秒时长。 例如: 我们需要将以上地址片段全部下载后排序后再合成新的长视频。 …...
iDP3复现代码模型训练全流程(一)——train_policy.sh
iDP3 核心脚本包括三个:deploy_policy.sh、vis_dataset.sh、train_policy.sh,分别代表了部署、预处理和训练,分别作为对应 py 脚本的参数设置前置环节 训练环节仅需运行指令: # 3d policy bash scripts/train_policy.sh idp3 gr1…...
重温设计模式--单例模式
文章目录 单例模式(Singleton Pattern)概述单例模式的实现方式及代码示例1. 饿汉式单例(在程序启动时就创建实例)2. 懒汉式单例(在第一次使用时才创建实例) 单例模式的注意事项应用场景 C代码懒汉模式-经典…...
【人工智能】Python中的机器学习管道:如何用scikit-learn构建高效的ML管道
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在机器学习项目中,数据预处理、特征工程、模型训练与评估是不可或缺的环节。随着项目规模的扩大和复杂度的增加,手动管理这些步骤不仅繁琐…...
Redis存在安全漏洞
Redis是美国Redis公司的一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值(Key-Value)存储数据库,并提供多种语言的API。 Redis存在安全漏洞。攻击者利用该漏洞使用特制的Lua脚本触发堆栈缓冲区溢出漏洞,从…...
Scala图书管理系统
项目创建并实现基础UI package org.appimport scala.io.StdInobject Main {def main(args: Array[String]): Unit {var running truewhile (running) {println("欢迎来到我的图书管理系统,请选择")println("1.查看所有图书")println("2…...
【数据可视化案列】白葡萄酒质量数据的EDA可视化分析
🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...
Postman接口测试:全局变量/接口关联/加密/解密
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 全局变量和环境变量 全局变量:在postman全局生效的变量,全局唯一 环境变量:在特定环境下生效的变量,本环境内唯一 …...
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
一、vueelementui实现下拉表格多选搜索1.0 二、vueelementui实现下拉表格多选搜索分页回显全选2.0 在1.0的基础上,终于可以实现在下拉框表格分页的前提下不同页码的回显辣,分页是前端来分页的(代码略乱且没有封装还很长,随便看看…...
电商系统-产品经理
电视产品经理的工作体系: 产品经理的分类与职责 C端产品经理:面向个人用户,关注用户体验和产品易用性B端产品经理:面向企业客户,注重功能完整性和商业价值专业方向细分: 用户产品经理:专注用户…...
《庐山派从入门到...》PWM板载蜂鸣器
《庐山派从入门到...》PWM板载蜂鸣器 配置PWM模块控制板载无源蜂鸣器播放【一闪一闪亮晶晶】播放do re mi 《庐山派从入门到...》PWM控制无源蜂鸣器 PWM(Pulse Width Modulation,脉宽调制)是一种在嵌入式系统中常用的技术,它可以用…...
【河南新标】豫财预〔2024〕105号-《关于省级政务信息化建设项目支出预算标准的规定》-费用标准解读系列29
2024年12月3日,河南省财政厅发布了《关于省级政务信息化建设项目支出预算标准的规定》豫财预〔2024〕105号。《关于省级政务信息化建设项目支出预算标准的规定 (试行)》(豫财预 〔2020〕81号)同时废止。新的豫财预〔20…...
【数据结构】数据结构整体大纲
数据结构用来干什么的?很简单,存数据用的。 (这篇文章仅介绍数据结构的大纲,详细讲解放在后面的每一个章节中,逐个击破) 那为什么不直接使用数组、集合来存储呢 ——> 如果有成千上亿条数据呢ÿ…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
ArcPy扩展模块的使用(3)
管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如,可以更新、修复或替换图层数据源,修改图层的符号系统,甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...
轻量级Docker管理工具Docker Switchboard
简介 什么是 Docker Switchboard ? Docker Switchboard 是一个轻量级的 Web 应用程序,用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器,使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...
Ray框架:分布式AI训练与调参实践
Ray框架:分布式AI训练与调参实践 系统化学习人工智能网站(收藏):https://www.captainbed.cn/flu 文章目录 Ray框架:分布式AI训练与调参实践摘要引言框架架构解析1. 核心组件设计2. 关键技术实现2.1 动态资源调度2.2 …...
