掘金 人工智能 05月30日 14:53
基于CNN的多种类蝴蝶图像分类
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文基于卷积神经网络(CNN),对包含75种不同类别、共计9285张蝴蝶图像的数据集进行分类研究。首先对数据进行可视化分析,然后构建并训练CNN模型。该模型包含多个卷积层、池化层、全连接层以及Dropout层,用于提取图像特征并进行分类。实验结果表明,该模型在蝴蝶图像分类任务中取得了超过70%的准确率。文章还展示了如何加载预训练模型进行预测,并提供了数据集和代码的获取链接。

🦋 **数据分析与可视化**:文章首先对蝴蝶图像数据集进行分析,包括查看数据信息、空值以及各类蝴蝶的数量分布,并通过条形图进行可视化展示,帮助读者了解数据集的整体情况。

🖼️ **数据预处理与增强**:为了提高模型的泛化能力,文章采用了数据增强技术,包括随机旋转、平移、缩放和翻转等操作。同时,使用ImageDataGenerator对图像数据进行预处理,并将其划分为训练集和验证集。

🧠 **CNN模型构建与训练**:文章详细介绍了CNN模型的结构,包括卷积层、池化层、全连接层和Dropout层。模型使用ReLU激活函数和softmax输出层,并通过Adam优化器进行训练,最终在验证集上取得了超过70%的准确率。

📈 **模型评估与预测**:文章通过绘制训练集和验证集的准确率和损失曲线,评估模型的性能。同时,加载预训练模型对验证集图像进行预测,并将预测结果与真实标签进行对比展示。

基于CNN的多种类蝴蝶图像分类🦋

基于卷积神经网络对6499+2786张图像,75种不同类别的蝴蝶进行可视化分析、模型训练及分类展示

导入库

import pandas as pdimport osimport matplotlib.pyplot as pltimport seaborn as snsimport numpy as npfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import classification_report, confusion_matriximport tensorflow as tffrom tensorflow.keras import layers, modelsfrom tensorflow.keras.preprocessing.image import ImageDataGeneratorfrom tensorflow.keras.preprocessing.image import load_img, img_to_arrayfrom tensorflow.keras.models import Sequential, load_modelfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropoutfrom tensorflow.keras import regularizersimport warningswarnings.filterwarnings("ignore", category=UserWarning, message=r"Your `PyDataset` class should call `super().__init__\(\*\*kwargs\)`")

数据分析及可视化

df = pd.read_csv("/home/mw/input/btfl7333/btfl/btfl/Training_set.csv")df.head(10)

print("查看数据信息")print(df.describe())print("查看空值")print(df.isnull().sum())

查看各个类别包含的数据量

labelcounts = df['label'].value_counts().sort_index()plt.figure(figsize=(14, 8))sns.barplot(x=labelcounts.index, y=labelcounts.values, palette='viridis')plt.title('蝴蝶类型数目详细信息')plt.xlabel('蝴蝶类型')plt.ylabel('类别数量')plt.xticks(rotation=90)plt.tight_layout()plt.show()

随机查看部分图片及其对应的标签

image_dir = "/home/mw/input/btfl7333/btfl/btfl/train"sample_images = df.sample(12, random_state=43)fig, axes = plt.subplots(4, 3, figsize=(15, 15))for i, (index, row) in enumerate(sample_images.iterrows()):    img_path = os.path.join(image_dir, row['filename'])    img = load_img(img_path, target_size=(150, 150))    img_array = img_to_array(img) / 255.0          ax = axes[i // 3, i % 3]    ax.imshow(img_array)    ax.set_title(f"类别: {row['label']}")    ax.axis('off')plt.tight_layout()plt.show()

数据预处理

为图像分类任务准备训练和验证数据
使用train_test_split将数据集按照80%的比例划分为训练集 (train_df) 和验证集 (val_df)。
创建训练集的数据生成器,对训练数据进行数据增强,同时将标签转换为独热编码形式
创建验证集的数据生成器,对测试数据进行像素归一化

train_df, val_df = train_test_split(df, test_size=0.2, random_state=42)train_datagen = ImageDataGenerator(    rescale=1./255, # 将像素值归一化到 [0, 1] 范围    rotation_range=40, # 随机旋转图片,范围为0到40度    width_shift_range=0.2, # 随机水平和垂直平移图片,范围为20%    height_shift_range=0.2,    shear_range=0.2,    zoom_range=0.2, # 随机缩放图片    horizontal_flip=True,    fill_mode='nearest' # 在变换时填充空白区域,使用最近邻插值)val_datagen = ImageDataGenerator(rescale=1./255)train_generator = train_datagen.flow_from_dataframe(    dataframe=train_df,    directory=image_dir,    x_col='filename',    y_col='label',    target_size=(150, 150),    batch_size=32,    class_mode='categorical' # 将标签转换为独热编码形式)val_generator = val_datagen.flow_from_dataframe(    dataframe=val_df,    directory=image_dir,    x_col='filename',    y_col='label',    target_size=(150, 150),    batch_size=32,    class_mode='categorical')

展示部分处理后的数据

上一步已经对标签进行了编码

images, labels = next(train_generator)# 设置绘图参数plt.figure(figsize=(12, 8))# 显示前10张图片及其标签for i in range(10):    plt.subplot(5, 2, i + 1)    plt.imshow(images[i])  # 显示图片    plt.title(f'Label: {labels[i]}')  # 显示标签    plt.axis('off')  # 不显示坐标轴plt.tight_layout()plt.show()

构建模型

构建的是卷积神经网络CNN的模型,如下
输入层: 形状为 (150, 150, 3) 的图像输入。
卷积层 1: 32 个卷积核,尺寸为 (3, 3),激活函数为 ReLU。
池化层 1: 最大池化层,池化窗口为 (2, 2)。
卷积层 2: 64 个卷积核,尺寸为 (3, 3),激活函数为 ReLU。
池化层 2: 最大池化层,池化窗口为 (2, 2)。
卷积层 3: 128 个卷积核,尺寸为 (3, 3),激活函数为 ReLU。
池化层 3: 最大池化层,池化窗口为 (2, 2)。
展平层: 将多维特征图展平为一维。
全连接层 1: 128 个节点,激活函数为 ReLU。
dropout 层: 以减少过拟合,丢弃率为 0.5。
全连接层 2(输出层): 节点数与类别数相同,激活函数为 softmax

# 获取类别数量num_classes = len(train_generator.class_indices)# 构建模型model = Sequential()model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Conv2D(64, (3, 3), activation='relu'))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Conv2D(128, (3, 3), activation='relu'))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Flatten())model.add(Dense(128, activation='relu'))model.add(Dropout(0.5))model.add(Dense(num_classes, activation='softmax'))  # 使用 num_classes
model.summary()

# 编译模型model.compile(optimizer='adam',               loss='categorical_crossentropy',               metrics=['accuracy'])
# 训练模型history = model.fit(train_generator,                     steps_per_epoch=train_generator.n // train_generator.batch_size,                     validation_data=val_generator,                     validation_steps=val_generator.n // val_generator.batch_size,                     epochs=40)

模型评估

plt.plot(history.history['acc'], label='Train Accuracy')plt.plot(history.history['val_acc'], label='Validation Accuracy')plt.title('Model Accuracy')plt.ylabel('Accuracy')plt.xlabel('Epoch')plt.legend()plt.show()

plt.plot(history.history['loss'], label='Train Loss')plt.plot(history.history['val_loss'], label='Validation Loss')plt.title('Model Loss')plt.ylabel('Loss')plt.xlabel('Epoch')plt.legend()plt.show()

# 保存模型model.save('butterfly_classifier.h5')

使用模型进行预测展示

# 加载之前保存的模型model = load_model('butterfly_classifier.h5')val_images, val_labels = next(val_generator)# 进行预测predictions = model.predict(val_images)pred_labels = np.argmax(predictions, axis=1)true_labels = np.argmax(val_labels, axis=1)# 获取类别映射class_indices = val_generator.class_indicesclass_names = {v: k for k, v in class_indices.items()}# 定义显示图像的函数def display_images(images, true_labels, pred_labels, class_names, num_images=9):    plt.figure(figsize=(15, 15))    for i in range(num_images):        plt.subplot(3, 3, i + 1)        plt.imshow(images[i])        true_label = class_names[int(true_labels[i])]        pred_label = class_names[int(pred_labels[i])]        plt.title(f"True: {true_label}\nPred: {pred_label}")        plt.axis('off')    plt.tight_layout()    plt.show()# 调用显示函数display_images(val_images, true_labels, pred_labels, class_names, num_images=9)

总结

这次这个基于cnn的图像分类,获得了高于 70% 的准确率。可以加载我保存好的模型进行预测试试,感兴趣的还可以继续调参训练

# 若需要完整数据集以及代码https://mbd.pub/o/bread/aJaVmJ9s

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

CNN 图像分类 蝴蝶识别 深度学习
相关文章