• 基于卷积神经网络的猫种类的识别


    1.介绍

    图像分类是计算机视觉中的一个关键任务,而猫种类识别作为一个有趣且实用的应用场景,通过卷积神经网络(CNN)的模型能够识别猫的不同品种。在这篇博客中,将详细介绍如何利用深度学习技术构建模型,从而实现猫种类的自动识别。将探讨数据集的获取和预处理、模型的构建与训练,以及模型的评估和应用。

    2.数据集准备与预处理

    使用的数据集包含布偶猫、橘猫、蓝猫和虎斑猫等四种猫的图片。这个数据集包含了多个角度和不同环境下的猫的图像。在数据预处理阶段,加载了图像数据,并进行了多方面的处理:图片大小调整、灰度处理、归一化和标签编码等。致力于创建一个高质量、多样性和均衡性的数据集,以保证模型的有效性和泛化能力。

    2.1 数据集准备

    百度图片搜索猫咪图片 ——放到对应文件夹下

    2.2 预处理 统一图片大小及后缀名

    预处理是图像处理中至关重要的步骤之一,特别是在图像分类任务中。在进行猫种类识别之前,我们需要对图像进行预处理,以确保数据的一致性和适应模型的需求。在这个任务中,我们执行了两个关键的预处理步骤:统一图片大小和统一图片后缀名。

    统一图片大小: 图像大小的不一致会对模型训练产生影响。因此,我们将所有的图像调整为相同的尺寸,例如将所有图像调整为100x100像素大小。通过这样的处理,我们确保了训练数据的一致性,使模型能够更好地学习和识别特征。

    统一图片后缀名: 在数据收集过程中,不同来源的图像可能具有不同的后缀名或格式。为了方便统一处理,我们将所有图像的后缀名或格式转换为相同的格式,例如将所有图像统一保存为.jpg格式。这样做有利于数据加载和处理,并减少了数据集混乱性和不一致性所带来的问题。

    在这里插入图片描述

    import os
    from PIL import Image
    import random
    import shutil
    
    # 输入目录和输出目录
    input_directory = '/kaggle/input/mycatdataset/'
    output_directory = '/kaggle/working/data/'
    
    # 创建输出目录
    train_directory = os.path.join(output_directory, 'train')
    test_directory = os.path.join(output_directory, 'test')
    os.makedirs(train_directory, exist_ok=True)
    os.makedirs(test_directory, exist_ok=True)
    
    # 定义一个函数来处理文件名和图片大小,并分配到训练集和测试集中
    def process_images(category_folder, prefix, train_output_directory, test_output_directory):
        category_path = os.path.join(input_directory, category_folder)
        
        files = os.listdir(category_path)
        random.shuffle(files)  # 打乱文件顺序
    
        # 将前80%的图片分配到训练集,剩余的20%分配到测试集
        num_train = int(len(files) * 0.8)
        train_files = files[:num_train]
        test_files = files[num_train:]
    
        for index, file in enumerate(train_files):
            image_path = os.path.join(category_path, file)
            img = Image.open(image_path)
            img = img.resize((100, 100))
            output_file_name = f"{prefix}{index}.jpg"
            output_path = os.path.join(train_output_directory, output_file_name)
            img.save(output_path)
    
        for index, file in enumerate(test_files):
            image_path = os.path.join(category_path, file)
            img = Image.open(image_path)
            img = img.resize((100, 100))
            output_file_name = f"{prefix}{index}.jpg"
            output_path = os.path.join(test_output_directory, output_file_name)
            img.save(output_path)
    
    # 处理不同的猫的文件夹
    process_images('布偶猫', '0_', train_directory, test_directory)
    process_images('橘猫', '1_', train_directory, test_directory)
    process_images('蓝猫', '2_', train_directory, test_directory)
    process_images('虎斑猫', '3_', train_directory, test_directory)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    3.训练

    参考采用VGG模型

    设计了一个深度卷积神经网络来处理猫种类的分类任务。该模型由卷积层、池化层和全连接层组成,具有良好的特征提取和抽象能力。使用了ReLU激活函数、Dropout层和Softmax输出层,并且选择了合适的损失函数和优化器。通过对模型进行反复调整和优化,确保了模型在处理猫图像时的有效性和鲁棒性。

    import os
    import numpy as np
    from PIL import Image
    import tensorflow as tf
    import matplotlib.pyplot as plt
    
    # 获取训练集和测试集的图片路径列表
    train_path = '/kaggle/working/data/train'
    test_path = '/kaggle/working/data/test'
    train_images = os.listdir(train_path)
    test_images = os.listdir(test_path)
    
    # 读取图像并转换为Numpy数组的函数
    def load_images(path, image_list):
        images = []
        labels = []
        for img in image_list:
            image = Image.open(os.path.join(path, img)).convert('RGB')
            image = image.resize((100, 100))  # 调整图像大小为100x100
            images.append(np.array(image))
            label = int(img.split('_')[0])  # 根据文件名提取标签
            labels.append(label)
        return np.array(images), np.array(labels)
    
    # 读取训练集和测试集图像数据
    x_train, y_train = load_images(train_path, train_images)
    x_test, y_test = load_images(test_path, test_images)
    
    # 数据预处理
    x_train = x_train.astype('float32') / 255.0  # 将图像像素值缩放到[0, 1]范围内
    x_test = x_test.astype('float32') / 255.0
    
    y_train = tf.keras.utils.to_categorical(y_train)  # 将训练集标签进行one-hot编码
    y_test = tf.keras.utils.to_categorical(y_test)
    
    # 构建卷积神经网络模型
    model = tf.keras.Sequential([
        tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)),
        tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
        tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
        tf.keras.layers.Dropout(0.25),
        
        tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
        tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
        tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
        tf.keras.layers.Dropout(0.25),
        
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(256, activation='relu'),
        tf.keras.layers.Dropout(0.5),
        tf.keras.layers.Dense(4, activation='softmax')
    ])
    
    # 编译模型
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    
    # 训练模型
    history = model.fit(x_train, y_train, batch_size=20, epochs=50, validation_data=(x_test, y_test))
    
    # 保存模型
    model.save('/kaggle/working/cat_model.h5')
    
    # 评估模型
    score = model.evaluate(x_test, y_test)
    print('Test loss:', score[0])
    print('Test accuracy:', score[1])
    # 可视化测试结果
    plt.figure(figsize=(12, 6))
    
    # 绘制训练集和验证集的损失
    plt.subplot(1, 2, 1)
    plt.plot(history.history['loss'], label='Training Loss')
    plt.plot(history.history['val_loss'], label='Validation Loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.title('Training and Validation Loss')
    plt.legend()
    
    # 绘制训练集和验证集的准确率
    plt.subplot(1, 2, 2)
    plt.plot(history.history['accuracy'], label='Training Accuracy')
    plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.title('Training and Validation Accuracy')
    plt.legend()
    
    plt.tight_layout()
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    在训练过程中,将数据集划分为训练集和验证集,并对模型进行了多轮次的训练。记录了训练和验证集上的损失值和准确率,以便了解模型的训练情况和性能表现。通过使用验证集进行评估,检查了模型的泛化能力和过拟合情况。

    训练结果:
    在这里插入图片描述

    4.图像识别与预测

    最后,使用训练好的模型对新的猫图像进行了预测。通过加载模型并使用其对待识别的图像进行预处理和推理,得到了预测的猫种类标签和模型对该标签的置信度。这项实验展示了模型在实际应用中的效果和可靠性。

    import os
    import numpy as np
    from PIL import Image
    import tensorflow as tf
    
    # 加载模型
    model = tf.keras.models.load_model('/kaggle/working/cat_model.h5')
    
    # 定义类别标签
    class_labels = {0: '布偶猫', 1: '橘猫', 2: '蓝猫', 3: '虎斑猫'}
    
    # 准备待分类的图像
    def load_image(file_path):
        img = Image.open(file_path).convert('RGB')
        img = img.resize((100, 100))
        img_array = np.array(img)
        img_array = img_array.astype('float32') / 255.0
        img_array = np.expand_dims(img_array, axis=0)  # 增加维度以符合模型输入格式
        return img_array
    
    # 用模型进行图像分类
    def predict_image(image_path):
        img = load_image(image_path)
        predictions = model.predict(img)
        predicted_class = np.argmax(predictions)
        predicted_label = class_labels[predicted_class]
        confidence = predictions[0][predicted_class]
        return predicted_label, confidence
    
    # 指定待分类的图像路径
    image_path_to_classify = '/kaggle/input/cat-image/85d7dcff30734677667a1c8f3aa860a5.jpeg'
    
    # 进行图像分类预测
    predicted_label, confidence = predict_image(image_path_to_classify)
    print(f'Predicted Label: {predicted_label}')
    print(f'Confidence: {confidence * 100:.2f}%')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在这里插入图片描述

    模型下载:传送门

  • 相关阅读:
    Git常用命令及解释
    Unity之管理自己的Unitypackages
    2022杭电多校(二)
    对象的解构赋值(基本用法2)
    前后端分离项目服务器部署
    JAVA实现智能停车场管理系统 开源
    zemax埃尔弗目镜
    【Flink】设置了watermark,没有使用watermark触发窗口计算
    码农跃迁三角色:程序员、技术主管与架构师
    WordPress(6)网站侧边栏倒计时进度小工具
  • 原文地址:https://blog.csdn.net/qq_37655607/article/details/134422457