基于InceptionResNetV2模型的猫狗识别

本文介绍了如何使用TensorFlow的InceptionResNetV2模型对猫狗图像进行分类,通过数据预处理、模型训练、F1分数评估,并展示了如何利用oneAPI进行模型优化以提升推理效率。实验结果显示,优化后的模型在测试集上的F1分数显著提升。
摘要由CSDN通过智能技术生成

一、项目简介

1、问题概述

问题描述:在问题中,你将面一个典的机器学分类挑——猫狗大。你的任是建立一个分类模型,能够准确地区分像中是猫是狗

期解决方案:

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

2、数据描述以及来源

本实验一共有两个数据集合,都在data目录下,整个数据集分为训练集和测试集,分别是test_dir与train_dir,其内容都是一些大小不等的jpg照片格式。其中train_dir有 25000 张图片,其格式为cat.xxxx.jpg与dog.xxxx.jpg,xxxx表示的是数据标号。猫狗各 12500 张。 而测试集tets_dir有张图片,其格式与train_dir的数据格式一样

数据集:

链接:百度网盘 请输入提取码

提取码:jc34

3、部分原始数据展示

猫示例图片展示
狗图片示意展示

4、运行平台

由于需要用到oneApI组件,因此本实验是在intel的devCloud平台下运行的,采用的框架是TensorFlow。

二、InceptionResNetV2结构设计

1、InceptionResNetV2的加载


CFG = dict(
    seed = 77,
    batch_size = 20,
    img_size = (299,299),
    epochs = 5,
    patience = 5
)
base_model = InceptionResNetV2(weights='imagenet', 
include_top=False, 
input_shape=(CFG['img_size'][0], 
CFG['img_size'][1], 3))

2、Flatten层


x = base_model.output
x = Flatten()(x)

3、定义优化器
 


optimizer = Adam()
model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])

4、保存模型

# 保存模型 
save_checkpoint = keras.callbacks.ModelCheckpoint(filepath='model.h5',
                                                  monitor='val_f1_score', 
                                                  save_best_only=True, verbose=1, 
                                                  mode='max', 
                                                  save_weights_only=False) 
early_stopping = keras.callbacks.EarlyStopping(monitor='val_loss', 
                                               patience=CFG['patience'],
                                               verbose=True)
# 定义计算 F1 分数的回调 
class F1ScoreCallback(keras.callbacks.Callback): 
    def __init__(self, validation_generator):
        self.validation_generator = validation_generator 
        def on_epoch_end(self, epoch, logs=None): 
            predictions = self.model.predict(self.validation_generator) 
            predictions_binary = np.round(predictions) 
            true_labels = self.validation_generator.classes 
            f1 = f1_score(true_labels, predictions_binary) 
            print(f'Validation F1 Score: {f1}')

5、模型训练

# 训练模型
history = model.fit(
        train_generator,
        steps_per_epoch=nb_train_samples // CFG['batch_size'],
        epochs=CFG['epochs'],
        callbacks=[save_checkpoint,early_stopping],
        validation_data=validation_generator,
        verbose=True,
        validation_steps=nb_validation_samples // CFG['batch_size'])

三、其余实现代码

1、导包准备


import numpy as np
import random
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.metrics import confusion_matrix
import seaborn as sns
sns.set(style='darkgrid', font_scale=1.5)
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications.inception_resnet_v2 import InceptionResNetV2, preprocess_input
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam

2、数据准备

import shutil

def move_images_by_prefix(source_folder, destination_folder_cat, destination_folder_dog, prefix_cat="cat", prefix_dog="dog"):
    # 创建目标文件夹
    os.makedirs(destination_folder_cat, exist_ok=True)
    os.makedirs(destination_folder_dog, exist_ok=True)

    # 遍历源文件夹中的文件
    for filename in os.listdir(source_folder):
        if filename.startswith(prefix_cat):
            # 如果文件名以 'cat' 开头,移动到 cats 文件夹
            shutil.move(os.path.join(source_folder, filename), os.path.join(destination_folder_cat, filename))
        elif filename.startswith(prefix_dog):
            # 如果文件名以 'dog' 开头,移动到 dogs 文件夹
            shutil.move(os.path.join(source_folder, filename), os.path.join(destination_folder_dog, filename))

# 目标文件夹路径
train = './train'
test = './test'

move_images_by_prefix(train, './data/train_dir/cats','./data/train_dir/dogs')
move_images_by_prefix(test, './data/test_dir/cats', './data/test_dir/dogs')

train_dir = './data/train_dir'
test_dir = './data/test_dir'

3、生成器加入数据增强防止过拟合

train_data_generator = ImageDataGenerator(
      validation_split=0.2,
       rotation_range = 40 ,
       width_shift_range = 0.2 ,
       height_shift_range = 0.2,
       shear_range =0.2 ,
       zoom_range = 0.2,
       horizontal_flip = True,
       fill_mode = 'nearest',
        preprocessing_function=preprocess_input)
# 获取指定目录下的所有文件和子目录,但过滤掉隐藏目录
contents = [item for item in os.listdir(train_dir) if not item.startswith('.')]

val_data_generator = ImageDataGenerator(preprocessing_function=preprocess_input, validation_split=0.20)
test_data_generator = ImageDataGenerator(preprocessing_function=preprocess_input)
# 将生成器连接到文件夹中的数据

# 将生成器连接到文件夹中的数据
train_generator = train_data_generator.flow_from_directory(train_dir,
                                                           target_size=CFG['img_size'],
                                                           shuffle=True, seed=CFG['seed'],
                                                           class_mode='categorical',
                                                           batch_size=CFG['batch_size'], 
                                                           subset="training",
                                                           classes=contents)
validation_generator = val_data_generator.flow_from_directory(train_dir,
                                                              target_size=CFG['img_size'],
                                                              shuffle=False, seed=CFG['seed'], 
                                                              class_mode='categorical',
                                                              batch_size=CFG['batch_size'], 
                                                              subset="validation",
                                                              classes=contents)
test_generator = test_data_generator.flow_from_directory(test_dir, 
                                                         target_size=CFG['img_size'],
                                                         shuffle=False, seed=CFG['seed'],
                                                         class_mode='categorical',
                                                         batch_size=CFG['batch_size'],
                                                         classes=contents)

生成器数据数量统计
统一为大小一致的图片

4、推理验证

import os
import random
from PIL import Image
import numpy as np
from tensorflow.keras.models import load_model
import matplotlib.pyplot as plt
# 加载模型
loaded_model = load_model('model.h5')  # 替换'model.h5'为你的模型文件名

# 图像文件夹路径
image_folder_path = './data/test_dir/dogs'  # 替换为你的图像文件夹路径

# 获取图像文件列表
image_files = [f for f in os.listdir(image_folder_path) if os.path.isfile(os.path.join(image_folder_path, f))]

# 从列表中随机选择一张图像
random_image_path = os.path.join(image_folder_path, random.choice(image_files))

# 加载和预处理图像
img = Image.open(random_image_path)
img = img.resize((299, 299))
img_array = np.array(img) / 255.0
img_array = np.expand_dims(img_array, axis=0)

# 进行预测
predictions = loaded_model.predict(img_array)

# 获取预测结果
predicted_class = np.argmax(predictions)
predicted_probability = predictions[0][predicted_class]

# 获取类别标签
class_labels = ['dog', 'cat']  # 替换为你的类别标签
predicted_label = class_labels[predicted_class]

# 显示图像和预测结果
plt.imshow(img)
plt.title(f'Predicted Class: {predicted_label}\nProbability: {predicted_probability:.2%}')
plt.show()

print(f'Randomly Selected Image: {random_image_path}')

 5、F1分数以及准确率展示

score = model.evaluate(test_generator, verbose=False)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

from sklearn.metrics import f1_score
test_prediction = model.predict(test_generator)
test_prediction_labels = np.argmax(test_prediction , axis = 1)
test_true_labels = test_generator.classes
f1 = f1_score(test_true_labels , test_prediction_labels , average = 'weighted')
print('test f1 Score:',f1)

在大小为5000的的测试集中,能够达到0.996的准确率,以及衡量二分类的分数也有0.996,可以看出这个模型十分不错。

四、oneAPI加速架构设计

1、oneAPI介绍

oneAPI 是由英特尔(Intel)推出的一个开发工具集合,旨在简化和统一在不同硬件架构上进行高性能计算的开发。oneAPI 提供了一套开放、灵活、跨平台的工具,使开发者能够利用 CPU、GPU、FPGA 和其他硬件加速器,以及异构系统中的各种硬件资源。

主要特点和组件:

  1. 统一编程模型: oneAPI 提供了一个统一的编程模型,让开发者能够在不同硬件上使用相似的代码进行高性能计算。这有助于简化代码的维护和移植。

  2. DPC++ 编程语言: oneAPI 引入了 DPC++ 编程语言,这是一种基于 C++ 的扩展,支持异构计算和硬件加速器。

  3. 适用于不同硬件: oneAPI 不仅适用于英特尔的 CPU 和 GPU,还支持 FPGAs(可编程逻辑门阵列)等硬件。这使得开发者能够在多种加速器上部署其代码。

  4. 工具和库: oneAPI 提供了一系列工具和库,包括调试器、性能分析器、数学库等,帮助开发者更轻松地构建和优化高性能应用。

  5. 开源: oneAPI 的组件是基于开源标准和开放规范构建的,这有助于促进跨行业的合作和创新。

  6. 支持异构计算: oneAPI 的设计目标之一是支持异构计算,使开发者能够更好地利用不同类型的处理单元,提高应用程序的性能。

2、代码展示

使用extension for tensorflow进行优化

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'  # 防止显示不必要的警告信息

# 设置TensorFlow为使用oneAPI加速
os.environ['TF_ENABLE_ONEAPI'] = '1'

# 加载已训练好的模型
model = tf.keras.models.load_model('./model.h5')

# 设置批量推理
batch_size = 20

# 使用oneAPI加速推理
with tf.device('/CPU:0'):
    predictions = model.predict(test_generator, batch_size=batch_size)
# 将预测结果转换为类别标签
# 保存模型
model.save('./model_intel.h5')

predicted_classes =test_generator.classes

# 计算并输出 F1 分数
true_labels = test_generator.classes
f1 = f1_score(true_labels, predicted_classes)
print("F1 score:", f1)
import os
import random
from PIL import Image
import numpy as np
from tensorflow.keras.models import load_model
import matplotlib.pyplot as plt
# 加载模型
loaded_model = load_model('model_intel.h5')  # 替换'model.h5'为你的模型文件名

# 图像文件夹路径
image_folder_path = './data/test_dir/dogs'  # 替换为你的图像文件夹路径

# 获取图像文件列表
image_files = [f for f in os.listdir(image_folder_path) if os.path.isfile(os.path.join(image_folder_path, f))]

# 从列表中随机选择一张图像
random_image_path = os.path.join(image_folder_path, random.choice(image_files))

# 加载和预处理图像
img = Image.open(random_image_path)
img = img.resize((299, 299))
img_array = np.array(img) / 255.0
img_array = np.expand_dims(img_array, axis=0)

# 进行预测
predictions = loaded_model.predict(img_array)

# 获取预测结果
predicted_class = np.argmax(predictions)
predicted_probability = predictions[0][predicted_class]

# 获取类别标签
class_labels = ['dog', 'cat']  # 替换为你的类别标签
predicted_label = class_labels[predicted_class]

# 显示图像和预测结果
plt.imshow(img)
plt.title(f'Predicted Class: {predicted_label}\nProbability: {predicted_probability:.2%}')
plt.show()

print(f'Randomly Selected Image: {random_image_path}')

五、运行效果展示

使用oneAPI优化组件后,计算F1分数与推理的时间虽然与没有优化之前差不多,但是F1的分数达到了1。

六、总结

本实验参考代码:基于tensorflow深度学习的猫狗分类识别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值