【Intel校企合作课程】猫狗大战图像分类

2024-03-20 14:30

本文主要是介绍【Intel校企合作课程】猫狗大战图像分类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.作业简介

1.1问题描述

在这个问题中,你将面临一个经典的机器学习分类挑战——猫狗大战。你的任务是建立一个分类模型,能够准确地区分图像中是猫还是狗。

1.2预期解决方案

你的目标是通过训练一个机器学习模型,使其在给定一张图像时能够准确地预测图像中是猫还是狗。模型应该能够推广到未见过的图像,并在测试数据上表现良好。我们期待您将其部署到模拟的生产环境中——这里推理时间和二分类准确度(F1分数)将作为评分的主要依据。

1.3数据集

数据集:

链接:https://pan.baidu.com/s/1kfIuyXuvexREWAJ1ndFs1w

提取码:jc34

2.数据预处理

2.1数据集结构

本项目数据集分为两部分,train和test文件夹,本次项目由于需要在测试中结果进行F1评估,故只使用train数据集中带有标签的数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

查看train中一张图片。

在这里插入图片描述

2.2数据集拆分

为了在模型训练后有带有标签的数据来验证模型的正确性,我这里将上文中的train数据集拆分成train和test数据集。

import os
import shutil# 设置数据集路径
dataset_dir = '/kaggle/working/dac_train/train'  # 替换为您存储数据集的实际路径# 创建训练集和测试集目录
train_dir = '/kaggle/working/train'  # 替换为您希望创建训练集的目录路径
test_dir = '/kaggle/working/test'  # 替换为您希望创建测试集的目录路径
os.makedirs(train_dir, exist_ok=True)
os.makedirs(test_dir, exist_ok=True)# 将猫狗图像分别复制到训练集和测试集目录
for filename in os.listdir(dataset_dir):if 'cat' in filename:# 复制猫图像到训练集或测试集src = os.path.join(dataset_dir, filename)if int(filename.split('.')[1]) < 10000:dst = os.path.join(train_dir, filename)else:dst = os.path.join(test_dir, filename)shutil.copyfile(src, dst)elif 'dog' in filename:# 复制狗图像到训练集或测试集src = os.path.join(dataset_dir, filename)if int(filename.split('.')[1]) < 10000:dst = os.path.join(train_dir, filename)else:dst = os.path.join(test_dir, filename)shutil.copyfile(src, dst)

2.3预处理数据

为保证后续送入模型的数据的一致性,我定义了一个preprocess_data的函数,来对图片数据进行预处理,包括标签的提取、图片大小的统一和数据归一化。

import os
import cv2
import numpy as nptrain_dir = '/kaggle/working/train'  # 替换为您希望创建训练集的目录路径
test_dir = '/kaggle/working/test'  # 替换为您希望创建测试集的目录路径
img_size = 224  # 调整图像大小为 224x224 像素(可根据需要调整)def preprocess_data(directory):images = []labels = []for filename in os.listdir(directory):if 'cat' in filename:label = 0elif 'dog' in filename:label = 1else:continueimg_path = os.path.join(directory, filename)img = cv2.imread(img_path)if img is None:print(f"Failed to load image: {img_path}")continueimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)img = cv2.resize(img, (img_size, img_size))img = img.astype('float32') / 255.0  # 归一化像素值到[0, 1]之间images.append(img)labels.append(label)return np.array(images), np.array(labels)# 预处理训练集数据
train_images, train_labels = preprocess_data(train_dir)# 预处理测试集数据
test_images, test_labels = preprocess_data(test_dir)

2.4定义数据集

本项目中,我自定义了一个CustomDataset对象,来保存处理过后的图像和标签,便于后续data loader对模型训练进行数据批量输入。

class CustomDataset(Dataset):def __init__(self, images, labels, transform=None):self.images = imagesself.labels = labelsself.transform = transformdef __len__(self):return len(self.images)def __getitem__(self, index):image = self.images[index]label = self.labels[index]if self.transform:image = self.transform(image)return image, label

2.5构建数据集

利用我定义的数据集对象,将之前预处理的图像和标签加载进去,并将数据集放进data loader等待后续训练取用。

transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])# Create data loaders for the training and test sets
train_dataset = CustomDataset(train_images, train_labels, transform=transform)
test_dataset = CustomDataset(test_images, test_labels, transform=transform)train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

3.使用卷积神经网络识别猫狗图像

3.1神经网络结构

当涉及到神经网络的结构时,一个简单的示例是单层感知器(Perceptron)。感知器是一种最基本的神经网络模型,它由输入层、权重、激活函数和输出层组成。以下是一个简单的感知器结构:

  1. 输入层(Input Layer): 接收输入特征的层。每个输入特征都与一个权重相关联。
  2. 权重(Weights): 每个输入特征都有一个相关联的权重,表示其对模型的影响程度。权重用于调整输入的重要性。
  3. 加权和(Weighted Sum): 输入层的每个特征乘以其相应的权重,然后将这些加权的输入求和,形成加权和。
  4. 激活函数(Activation Function): 加权和通过激活函数,激活函数决定了神经元是否激活。常用的激活函数包括阶跃函数、sigmoid函数、ReLU(Rectified Linear Unit)等。
  5. 输出层(Output Layer): 激活函数的输出作为神经网络的最终输出。

3.2卷积神经网络

卷积神经网络(Convolutional Neural Network,CNN)是一种专门用于处理具有网格结构数据(如图像和视频)的深度学习模型。CNN 在计算机视觉任务中取得了巨大成功,因为它能够有效地捕获图像中的空间结构信息。

3.3深度神经网络

深度神经网络(Deep Neural Network,DNN)是一种神经网络结构,其具有多个隐藏层,使其成为深层次模型。深度神经网络是深度学习的核心组成部分,能够学习和表示更抽象、更复杂的数据特征,适用于各种机器学习任务。

3.4自定义网络结构

针对本项目,猫狗的分类属于二分类任务,我使用PyTorch自定义了一个四层卷积-池化的卷积神经网络,可以满足猫狗分类任务的要求。

class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, stride=1, padding=1)self.bn1 = nn.BatchNorm2d(64)self.relu = nn.ReLU()self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)self.conv2 = nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, stride=1, padding=1)self.bn2 = nn.BatchNorm2d(64)self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)self.conv3 = nn.Conv2d(in_channels=64, out_channels=32, kernel_size=3, stride=1, padding=1)self.bn3 = nn.BatchNorm2d(32)self.pool3 = nn.MaxPool2d(kernel_size=2, stride=2)self.conv4 = nn.Conv2d(in_channels=32, out_channels=32, kernel_size=3, stride=1, padding=1)self.bn4 = nn.BatchNorm2d(32)self.pool4 = nn.MaxPool2d(kernel_size=2, stride=2)self.flatten = nn.Flatten()self.fc1 = nn.Linear(in_features=32*14*14, out_features=2)def forward(self, x):x = self.conv1(x)x = self.bn1(x)x = self.relu(x)x = self.pool1(x)x = self.conv2(x)x = self.bn2(x)x = self.relu(x)x = self.pool2(x)x = self.conv3(x)x = self.bn3(x)x = self.relu(x)x = self.pool3(x)x = self.conv4(x)x = self.bn4(x)x = self.relu(x)x = self.pool4(x)x = self.flatten(x)x = self.fc1(x)return x

下图为该模型的网络结构。

在这里插入图片描述

4.在GPU上训练

4.1参数设置

创建自定义的网络模型,并将模型设置为GPU模式,再简单设置一下优化器等参数。

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = CNN()
model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

4.2在GPU上训练

将训练数据送入模型进行训练,共训练10轮,每送入256批数据打印一次Loss。

num_epochs = 10
print_every = 256  # 输出损失的频率for epoch in range(num_epochs):running_loss = 0.0for batch_idx, (images, labels) in enumerate(train_loader, 1):images, labels = images.to(device), labels.to(device)optimizer.zero_grad()outputs = model(images)loss = criterion(outputs, labels)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx % print_every == 0:print(f"Epoch {epoch+1}, Batch {batch_idx}/{len(train_loader)}, Loss: {running_loss/print_every}")running_loss = 0.0

下图为训练过程展示。

在这里插入图片描述

4.3查看test数据集F1分数和时间

将test数据集的数据送入模型,进行推理,评估F1分数并记录推理时间。

import timepredicted_labels = []
true_labels = []correct = 0
total = 0# 将模型移动到 GPU 上
model.to(device)with torch.no_grad():inference_start_time = time.time()for images, labels in test_loader:# 将输入数据和标签移到 GPU 上images, labels = images.to(device), labels.to(device)outputs = model(images)_, predicted = torch.max(outputs, 1)total += labels.size(0)correct += (predicted == labels).sum().item()predicted_labels.extend(predicted.cpu().numpy())  # 注意这里使用 .cpu() 将数据移回 CPUtrue_labels.extend(labels.cpu().numpy())# 计算整个测试集的推理时间inference_end_time = time.time()total_inference_time = inference_end_time - inference_start_timeprint(f"Total Inference Time: {total_inference_time} seconds")# 计算 F1 Score for PyTorch
f1 = f1_score(true_labels, predicted_labels)
print(f"F1 Score: {f1}")# 计算 Test Accuracy for PyTorch
accuracy = 100 * correct / total
print(f"Test Accuracy: {accuracy}%")

运行结果如下。

在这里插入图片描述

4.4保存模型

将模型保存。

torch.save(model, 'model.pth')

5.转移到CPU上

5.1创建模型结构

在CPU设备上创建相同的网络结构,然后载入我们保存的模型文件。

model = torch.load('model.pth')
model.eval()  # 将模型设置为评估模式

5.2尝试在CPU上进行推理

在CPU设备上用和GPU设备上相同的方式,预处理数据,并载入data loader。使用模型对测试集进行推理,查看推理时间和F1分数。

import timepredicted_labels = []
true_labels = []correct = 0
total = 0# 记录整个推理开始时间
inference_start_time = time.time()with torch.no_grad():for images, labels in test_loader:outputs = model(images)_, predicted = torch.max(outputs, 1)total += labels.size(0)correct += (predicted == labels).sum().item()predicted_labels.extend(predicted.numpy())true_labels.extend(labels.numpy())# 记录整个推理结束时间
inference_end_time = time.time()# 计算整个测试集的推理时间
total_inference_time = inference_end_time - inference_start_time
print(f"Total Inference Time: {total_inference_time} seconds")# 计算 F1 Score for PyTorch
f1 = f1_score(true_labels, predicted_labels)
print(f"F1 Score: {f1}")# 计算 Test Accuracy for PyTorch
accuracy = 100 * correct / total
print(f"Test Accuracy: {accuracy}%")

运行结果如下。

在这里插入图片描述

对比GPU下运行结果,我发现CPU上的推理时间比GPU上的慢了不少。

6.使用oneAPI组件

6.1使用Intel Extension for PyTorch进行优化

在上一章中,我发现在CPU上的测试效果并不好,因此在这里我使用Intel Extension for PyTorch对模型进行加速优化,加快模型的推理速度。

import intel_extension_for_pytorch as ipex
import torchmodel = torch.load('model.pth')
model.eval()  # 将模型设置为评估模式# 移动模型和优化器到IPEX设备(CPU)
model= ipex.optimize(model=model, dtype=torch.float32)

我们将优化后的模型在进行一次推理测试,运行结果如下。

在这里插入图片描述

对比未优化的模型,推理速度快了近一半。

6.2保存优化后的模型

保存优化后的模型。

torch.save(model.state_dict(), 'optimized_model.pth')

6.3使用Intel® Neural Compressor量化模型

这里对优化后的模型再做一次量化,以缩小模型体积,加快运行速度。

import os
import torch
from neural_compressor.config import PostTrainingQuantConfig, AccuracyCriterion
from neural_compressor import quantization
from sklearn.metrics import confusion_matrix, accuracy_score, balanced_accuracy_score# 定义评估函数
def eval_func(model):with torch.no_grad():y_true = []y_pred = []for inputs, labels in train_loader:inputs = inputs.to('cpu')labels = labels.to('cpu')preds_probs = model(inputs)preds_class = torch.argmax(preds_probs, dim=-1)y_true.extend(labels.numpy())y_pred.extend(preds_class.numpy())return accuracy_score(y_true, y_pred)# 配置量化参数
conf = PostTrainingQuantConfig(backend='ipex',  # 使用 Intel PyTorch Extensionaccuracy_criterion=AccuracyCriterion(higher_is_better=True, criterion='relative',  tolerable_loss=0.01))# 执行量化
q_model = quantization.fit(model,conf,calib_dataloader=train_loader,eval_func=eval_func)# 保存量化模型
quantized_model_path = './quantized_models'
if not os.path.exists(quantized_model_path):os.makedirs(quantized_model_path)q_model.save(quantized_model_path)

量化成功后会出现如下输出。

在这里插入图片描述

查看量化后的模型,分别保存为pt文件和json文件。

在这里插入图片描述

6.4使用量化后的模型在CPU上进行推理

最后加载我们量化后的模型。

import torch
import json# 指定模型和配置文件的路径
model_path = 'quantized_models/best_model.pt'
json_config_path = 'quantized_models/best_configure.json'# 加载 PyTorch 模型
quantized_model = torch.load(model_path, map_location='cpu')# 加载 JSON 配置文件
with open(json_config_path, 'r') as json_file:json_config = json.load(json_file)

对其进行一次推理,查看运行结果。

在这里插入图片描述

我们发现量化后,模型比量化前更快了,并且准确率也没有改变。

7.总结

在使用oneAPI的优化组件后,可以看见模型的推理时间大幅度下降,从原来的28s到目前的14s,其次,在使用量化工具后,推理时间又下降到了7s,并且整个优化和量化的过程,F1分数并没有很大的波动,一直稳定在0.9左右。本次项目充分证明了oneAPI优秀的模型压缩能力,在保证模型精确度的同时还能缩小模型规模,加快模型运行速度。

这篇关于【Intel校企合作课程】猫狗大战图像分类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/829756

相关文章

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

Verybot之OpenCV应用一:安装与图像采集测试

在Verybot上安装OpenCV是很简单的,只需要执行:         sudo apt-get update         sudo apt-get install libopencv-dev         sudo apt-get install python-opencv         下面就对安装好的OpenCV进行一下测试,编写一个通过USB摄像头采

用Pytho解决分类问题_DBSCAN聚类算法模板

一:DBSCAN聚类算法的介绍 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,DBSCAN算法的核心思想是将具有足够高密度的区域划分为簇,并能够在具有噪声的空间数据库中发现任意形状的簇。 DBSCAN算法的主要特点包括: 1. 基于密度的聚类:DBSCAN算法通过识别被低密

PMP–一、二、三模–分类–14.敏捷–技巧–看板面板与燃尽图燃起图

文章目录 技巧一模14.敏捷--方法--看板(类似卡片)1、 [单选] 根据项目的特点,项目经理建议选择一种敏捷方法,该方法限制团队成员在任何给定时间执行的任务数。此方法还允许团队提高工作过程中问题和瓶颈的可见性。项目经理建议采用以下哪种方法? 易错14.敏捷--精益、敏捷、看板(类似卡片)--敏捷、精益和看板方法共同的重点在于交付价值、尊重人、减少浪费、透明化、适应变更以及持续改善等方面。

【python计算机视觉编程——7.图像搜索】

python计算机视觉编程——7.图像搜索 7.图像搜索7.1 基于内容的图像检索(CBIR)从文本挖掘中获取灵感——矢量空间模型(BOW表示模型)7.2 视觉单词**思想****特征提取**: 创建词汇7.3 图像索引7.3.1 建立数据库7.3.2 添加图像 7.4 在数据库中搜索图像7.4.1 利用索引获取获选图像7.4.2 用一幅图像进行查询7.4.3 确定对比基准并绘制结果 7.

《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》P98

更改为 差分的数学表达式从泰勒级数展开式可得: 后悔没听廖老师的。 禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》 禹晶、肖创柏、廖庆敏《数字图像处理》资源二维码

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法(KNN)8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特征8.4.3 多类支持向量机8.4.4 提取单元格并识别字符8.4.5 图像校正

PMP–一、二、三模–分类–14.敏捷–技巧–原型MVP

文章目录 技巧一模14.敏捷--原型法--项目生命周期--迭代型生命周期,通过连续的原型或概念验证来改进产品或成果。每个新的原型都能带来新的干系人新的反馈和团队见解。题目中明确提到需要反馈,因此原型法比较好用。23、 [单选] 一个敏捷团队的任务是开发一款机器人。项目经理希望确保在机器人被实际建造之前,团队能够收到关于需求的早期反馈并相应地调整设计。项目经理应该使用以下哪一项来实现这个目标?

HalconDotNet中的图像特征与提取详解

文章目录 简介一、边缘特征提取二、角点特征提取三、区域特征提取四、纹理特征提取五、形状特征提取 简介   图像特征提取是图像处理中的一个重要步骤,用于从图像中提取有意义的特征,以便进行进一步的分析和处理。HalconDotNet提供了多种图像特征提取方法,每种方法都有其特定的应用场景和优缺点。 一、边缘特征提取   边缘特征提取是图像处理中最基本的特征提取方法之一,通过检