深度学习实战-基于EfficientNetB5的家禽鸡病图像分类识别模型

🤵‍♂️ 个人主页:@艾派森的个人主页

✍🏻作者简介:Python学习者

🐋 希望大家多多支持,我们一起进步!😄

如果文章对你有帮助的话,

欢迎评论 💬点赞👍🏻 收藏 📂加关注+


目录

1.项目背景

2.数据集介绍

3.技术工具

4.实验过程

4.1导入数据

4.2数据可视化

4.3特征工程

4.4构建模型

4.5训练模型

4.6模型评估

4.7模型预测

5.总结

源代码


1.项目背景

在中小规模家禽养殖产业中,疫病的早期发现与精准诊断直接关系到农户的经济命脉。然而,传统的兽医诊断模式往往受限于地理位置与技术资源,特别是在坦桑尼亚的阿鲁沙(Arusha)和乞力马扎罗(Kilimanjaro)等偏远地区,养殖户很难在疫病爆发初期获得及时的专家指导。为了打破这一壁垒,本项目利用开放数据工具包(ODK)应用,通过手机采集了大量真实场景下的家禽粪便图像。这些图像不仅承载了球虫病、新城疫、沙门氏菌等常见致命疫病的视觉病理特征,更包含了复杂的环境背景噪声,具有极高的实战分析价值。我们希望通过引入高性能的 EfficientNetB5 深度学习架构,构建一套能够精准识别家禽健康状态的自动化分类模型,为缺乏兽医资源的农户提供一种低成本、高效率的即时诊断手段,从而为智慧农业的防灾减损贡献技术方案。

2.数据集介绍

本实验数据集来源于Kaggle,用于家禽疾病诊断的机器学习数据集,本数据集包含用于中小规模家禽养殖户的家禽疾病诊断标注数据,其中包括家禽粪便图像。这些图像于2020年9月至2021年2月期间在坦桑尼亚的阿鲁沙和乞力马扎罗地区使用手机上的开放数据工具包(ODK)应用程序拍摄。图像类别包括"球虫病"、"健康"、"新城疫"和"沙门氏菌"。图像尺寸调整为224像素×224像素。

3.技术工具

Python版本:3.9

代码编辑器:jupyter notebook

4.实验过程

4.1导入数据

在正式构建家禽疾病识别模型之前,环境配置与原始数据的清洗工作是决定模型上限的关键。由于家禽疾病图像(如各种鸡类病害表现)在细节上往往非常微妙,我们需要利用高效的数据处理库来精确定位每一张样本及其对应的病理标签。这一阶段,我们首先调动了核心的数值计算与自动化路径处理工具,并重点通过 Pandas 框架加载存储在 CSV 文件中的元数据,为后续的高分辨率图像读取打下坚实的基础。

python 复制代码
import numpy as np # 用于大规模矩阵运算
import pandas as pd # 用于高效的数据分析与 CSV 文件处理
import os          # 提供跨平台的操作系统接口,用于路径管理
import time        # 用于记录训练与推理的时间开销
import matplotlib.pyplot as plt # 用于可视化图像与训练曲线
import cv2         # 强大的计算机视觉库,用于图像读取与预处理

# 定义训练集所在的根目录路径
sdir = r'/kaggle/input/chicken-disease-1/Train'
# 定义存储图像路径与对应标签映射关系的 CSV 文件路径
csvpath = r'/kaggle/input/chicken-disease-1/train_data.csv'

# 使用 pandas 读取 CSV 数据,将其转化为结构化的 DataFrame 对象
df = pd.read_csv(csvpath)
# 统一重命名列名为 'filepaths'(文件路径)和 'labels'(疾病标签),确保后续调用的规范性
df.columns = ['filepaths', 'labels']

# 预览数据表的前几行,确认数据加载是否正确且列名映射无误
df.head()

4.2数据可视化

在正式进入模型训练之前,通过肉眼观察样本图像是必不可少的一步。家禽疾病的病理特征往往隐藏在复杂的背景中,直接观察原始图像有助于我们确认数据标注的准确性,并评估图像质量是否足以支撑 EfficientNetB5 这种深层网络的学习需求。利用 Matplotlib 的子图布局,我们可以从数据集中随机抽取并展示代表性样本,确保输入模型的数据符合预期。

python 复制代码
# 创建一个 3x3 的画布布局,设置较大的尺寸以便清晰观察图像细节
fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(20, 20))
# 将多维的 axes 数组展平为一维,方便后续通过循环索引进行访问
ax = ax.ravel()
# 循环读取前 9 张图像并进行展示
for idx in range(min(9, len(df))):
    # 使用 OpenCV 根据 CSV 文件中的路径加载图像
    img = cv2.imread(df['filepaths'][idx])    
    if img is not None:
        # 将图像统一缩放至 224x224 像素,这是许多深度学习模型的标准输入尺寸
        img = cv2.resize(img, (224, 224))
        # 由于 OpenCV 默认读取的是 BGR 格式,需要转换为 RGB 格式才能用 Matplotlib 正确显示色彩
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # 在对应的子图中显示图像
        ax[idx].imshow(img_rgb)        
        # 从 DataFrame 中提取对应的疾病标签
        label = df['labels'][idx]        
        # 将标签设置为当前子图的标题,方便对照图像与病害种类
        ax[idx].title.set_text(label)
        # 隐藏坐标轴刻度,使可视化界面更加整洁、聚焦
        ax[idx].axis('off')
    else:
        # 如果路径失效或文件损坏,打印错误提示以方便排查数据问题
        print(f"索引为 {idx} 的图像未找到或无法加载,请检查文件路径。")
# 自动调整子图间距,防止标题与图像发生重叠
plt.tight_layout()
plt.show()

4.3特征工程

原始数据往往包含不同分辨率的图片和文本分类标签,这无法直接输入神经网络。我们编写了 transform_data 函数,将所有图像统一缩放到180 x180分辨率,并进行归一化处理,将像素值缩减到 [0, 1] 区间,以加速模型的收敛。同时,针对疾病名称这种定性标签,我们先通过标签编码器将其转换为整数,再利用独热编码转换为分类向量,确保损失函数能够正确计算类别间的差异。

python 复制代码
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.utils import to_categorical
def transform_data(df, image_size=(180, 180)):
    """
    数据转换核心函数:涵盖图像读取、缩放、归一化以及标签的数字化编码
    """
    images = []
    labels = []    
    # 遍历 DataFrame 中的每一行数据
    for _, row in df.iterrows():
        # 读取指定路径的图像
        img = cv2.imread(row['filepaths'])
        if img is not None:
            img = cv2.resize(img, image_size)  # 统一修改图像尺寸,适配模型输入
            img = img / 255.0  # 归一化处理:将像素值从 [0, 255] 映射到 [0, 1]
            images.append(img)
            labels.append(row['labels'])
    
    # 将列表结构转换为 NumPy 矩阵,方便张量运算
    X = np.array(images)   
    # 实例化标签编码器
    lb = LabelEncoder()
    # 第一步:将文本标签(如 'Coccidiosis')转换为整数索引(如 0, 1, 2...)
    y = lb.fit_transform(labels)
    # 第二步:将整数索引转换为独热编码(One-hot),本项目共涉及 4 个疾病类别
    y = to_categorical(y, num_classes=4)
    
    return X, y
def load_data(X, y):
    # 此函数预留用于数据的进一步加载或磁盘持久化操作
    return X, y
# 第一步:执行转换逻辑,获取预处理后的特征矩阵 X 和标签矩阵 y
X, y = transform_data(df)
# 第三步:正式加载数据
X_train_raw, y_train_raw = load_data(X, y)
# 打印处理后的形状,确认样本量与维度是否正确
print(f"Data shape: {X_train.shape}, Labels shape: {y_train.shape}")

为了科学评估 EfficientNetB5 的泛化能力,我们需要将处理好的数据划分为训练集、验证集和测试集。这里我们采用了"二阶段切分法":首先剥离出 80% 的数据用于模型学习,剩下的 20% 则平分为两半,分别充当训练过程中的"监考官"(验证集)和期末考的"考卷"(测试集)。特别地,我们开启了 stratify 参数,确保在每一份子集中,各类家禽疾病的样本比例保持一致,防止模型产生分类偏见。

python 复制代码
from sklearn.model_selection import train_test_split

# 第一次切分:8:2 比例划分出训练集和临时集(验证+测试)
# stratify=y 保证了分类标签在各数据集中的分布比例与原始数据完全一致
train_df, temp_df, train_labels, temp_labels = train_test_split(
    X, y, train_size=0.8, shuffle=True, random_state=123, stratify=y
)

# 第二次切分:将 20% 的临时集对半分,生成最终的验证集(10%)和测试集(10%)
val_df, test_df, val_labels, test_labels = train_test_split(
    temp_df, temp_labels, test_size=0.5, shuffle=True, random_state=123, stratify=temp_labels
)

# 输出各阶段切分后的样本规模,确保总数闭环
print("Train set:", train_df.shape, train_labels.shape)
print("Validation set:", val_df.shape, val_labels.shape)
print("Test set:", test_df.shape, test_labels.shape)

4.4构建模型

在处理复杂的农业图像数据时,样本的多样性直接影响模型的鲁棒性。我们首先通过 ImageDataGenerator 引入了实时数据增强技术,通过旋转、缩放、平移和镜像等手段,模拟实际养殖场中光照变化或拍摄角度不一的复杂情况。核心架构上,我们选择了经典的 EfficientNetB5 作为底层特征提取器。为了充分发挥迁移学习的优势,我们加载了在 ImageNet 上预训练的权重,并在此基础上构建了一个全连接层序列。通过引入 BatchNormalization(批标准化)层来稳定训练过程,并利用 ReLU 激活函数增强非线性表达能力,最后通过 Softmax 层输出 4 类疾病的预测概率。

python 复制代码
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import EfficientNetB5
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, BatchNormalization
from tensorflow.keras.optimizers import Adam
# 配置数据增强生成器,提升模型对不同环境干扰的抵抗力
train_datagen = ImageDataGenerator(
    rescale=1./255,          # 像素重放缩(通常在上一阶段已处理,此处作为生成器配置)
    rotation_range=20,       # 随机旋转角度范围
    width_shift_range=0.2,   # 水平平移比例
    height_shift_range=0.2,  # 垂直平移比例
    shear_range=0.2,         # 剪切变换强度
    zoom_range=0.2,          # 随机缩放比例
    horizontal_flip=True,    # 开启水平翻转
    fill_mode='nearest'      # 变换后空缺处的填充模式
)
# 实例化 EfficientNetB5 基座模型
# include_top=False 表示舍弃原有的分类头,以便我们自定义输出层
base_model = EfficientNetB5(weights='imagenet', include_top=False, input_shape=(180, 180, 3))
# 开启基座模型的可训练属性,以便进行深度微调(Fine-tuning)
base_model.trainable = True
# 采用 Sequential 顺序容器构建自定义模型顶层
model = Sequential([
    base_model,              # 嵌入预训练基座
    Flatten(),               # 展平高维特征图
    Dense(256, activation='relu'),      # 第一个全连接层:捕捉高阶特征
    BatchNormalization(),               # 批标准化:加速收敛并防止梯度爆炸
    Dense(128, activation='relu'),      # 第二个全连接层
    Dense(64, activation='relu'),       # 第三个全连接层
    Dense(4, activation='softmax')      # 输出层:对应 4 个疾病类别,使用 Softmax 归一化概率
])
# 显式构建模型并指定输入形状
model.build(input_shape=(None, 180, 180, 3))
# 配置模型编译参数
# 使用较低的学习率(0.0001)以确保在微调阶段不会破坏预训练好的权重
model.compile(
    optimizer=Adam(learning_rate=0.0001), 
    loss='categorical_crossentropy',  # 配合上一阶段的独热编码使用交叉熵损失
    metrics=['accuracy']              # 监控准确率指标
)

# 输出模型结构摘要,检查参数总量及各层连接情况
model.summary()

4.5训练模型

训练过程是模型将预训练的通用视觉特征转化为家禽疾病识别能力的"进化"过程。我们设置了 30 个迭代轮数(Epochs),并采用 32 的批大小(Batch Size),这在显存占用与梯度更新稳定性之间取得了较好的平衡。通过实时监控验证集(Validation Data)的表现,我们可以直观地看到模型在未见数据上的泛化性能提升曲线。

python 复制代码
# 启动模型训练流程
# 使用处理好的训练集数据与对应的标签进行拟合
history = model.fit(
    train_df, train_labels,           # 训练数据与标签
    validation_data=(val_df, val_labels), # 验证集:用于每个 epoch 后评估模型泛化能力
    epochs=30,                        # 迭代轮数:根据收敛情况可灵活调整
    batch_size=32,                    # 批处理大小:兼顾训练速度与内存开销
    verbose=1                         # 日志显示模式:1 为输出进度条记录
)

4.6模型评估

训练完成后,我们首先在完全独立、未参与过训练的测试集上运行 model.evaluate,获取最真实的泛化性能指标。随后,通过绘制训练集与验证集的准确率(Accuracy)和损失值(Loss)随迭代次数(Epochs)变化的曲线,我们可以直观地评估模型是否存在欠拟合或过拟合现象。一个理想的训练轨迹应该是两条曲线趋于平稳且间距较小。

python 复制代码
# 在独立的测试集上评估模型性能,获取最终的损失值和准确率
test_loss, test_accuracy = model.evaluate(test_df, test_labels)
print(f"测试集损失: {test_loss:.4f}, 测试集准确率: {test_accuracy:.4f}")
# --- 绘制模型准确率变化曲线 ---
plt.plot(history.history['accuracy'], label='训练集准确率')
plt.plot(history.history['val_accuracy'], label='验证集准确率')
plt.title('模型准确率演变图')
plt.ylabel('准确率')
plt.xlabel('迭代轮数 (Epochs)')
plt.legend()
plt.show()
# --- 绘制模型损失值变化曲线 ---
plt.plot(history.history['loss'], label='训练集损失')
plt.plot(history.history['val_loss'], label='验证集损失')
plt.title('模型损失演变图')
plt.ylabel('损失值')
plt.xlabel('迭代轮数 (Epochs)')
plt.legend()
plt.show()

单纯的准确率往往会掩盖一些细节问题,例如模型是否容易将 A 病误判为 B 病。为了深入剖析模型的分类逻辑,我们利用 confusion_matrix 生成了混淆矩阵。通过对预测标签与真实标签的交叉比对,我们可以清晰地看到模型在 4 类家禽疾病上的识别偏好。矩阵对角线上的数值越高,代表模型对该类别的识别越精准。

python 复制代码
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
# 重新验证测试集,确保评估的一致性
test_loss, test_accuracy = model.evaluate(test_df, test_labels, verbose=1)
print("最终测试准确率:", test_accuracy)
# 执行模型推理:获取测试集所有样本的预测概率分布
predictions = model.predict(test_df)
# 使用 argmax 提取概率最大的索引作为预测类别
predicted_labels = np.argmax(predictions, axis=1)
# 同样提取真实标签的索引,以便进行比对
true_labels = np.argmax(test_labels, axis=1)
# 计算混淆矩阵,统计各类别之间的预测分布情况
cm = confusion_matrix(true_labels, predicted_labels)
# 使用 ConfusionMatrixDisplay 以热力图的形式进行可视化展示
# cmap="Blues" 可以让数值较高的区域颜色更深,视觉对比更明显
disp = ConfusionMatrixDisplay(confusion_matrix=cm)
disp.plot(cmap="Blues")
plt.title("家禽疾病分类混淆矩阵")
plt.show()

4.7模型预测

在完成所有评估指标的计算后,最直观的验证方式莫过于将模型置于实际的测试样本中进行"盲测"。我们从测试集中随机抽取 9 张家禽图像,让训练好的 EfficientNetB5 模型给出判断结果,并将其与真实标签进行比对。为了提高可读性,我们通过颜色标识来区分预测结果:绿色代表判断正确,红色则警示预测偏差,这能帮助我们快速复盘模型在处理特定病症(如新城疫或沙门氏菌感染)时的视觉辨析逻辑。

python 复制代码
import matplotlib.pyplot as plt
# 第一步:对测试集数据进行推理,获取每个样本属于各疾病类别的概率
predictions = model.predict(test_df)
# 第二步:将预测的概率分布转换为具体的类别索引
# 取概率最大的索引作为模型最终的预测结论
encoded_predictions = np.argmax(predictions, axis=1)
# 第三步:将数字索引还原为人类可读的疾病名称
# 手动定义类别名称映射表:球虫病、健康、新城疫、沙门氏菌
lb = LabelEncoder()
lb.classes_ = np.array(['Coccidiosis', 'Healthy', 'New Castle Disease', 'Salmonella'])
# 还原预测标签和真实标签
decoded_predictions = lb.inverse_transform(encoded_predictions)
decoded_real_labels = lb.inverse_transform(np.argmax(test_labels, axis=1))
# 设置绘图画布大小,准备展示 3x3 的九宫格预测图
plt.figure(figsize=(12, 12))
# 遍历前 9 个测试样本进行可视化对比
for i in range(9):
    # 提取第 i 个测试样本的图像数据
    img = test_df[i]
    real_label = decoded_real_labels[i]
    predicted_label = decoded_predictions[i]
    # 在 3x3 布局中定位子图
    plt.subplot(3, 3, i + 1)
    # 显示原始图像(已归一化处理,imshow 会自动适配 [0, 1] 范围)
    plt.imshow(img)
    plt.axis('off') # 隐藏坐标轴  
    # 动态设置标题颜色:预测正确显示绿色,预测错误显示红色
    title_color = "green" if predicted_label == real_label else "red"
    # 在图像上方标注预测值与真实值
    plt.title(f"Pred: {predicted_label}\nActual: {real_label}", color=title_color)

# 优化子图排版,确保标题与图片不发生重叠
plt.tight_layout()
plt.show()

最后可以可视化并保存模型的架构

python 复制代码
from tensorflow.keras.utils import plot_model
from IPython.display import Image, display

plot_model(model, to_file='model_architecture.png', show_shapes=True, show_layer_names=True)

5.总结

本实验基于 Kaggle 提供的家禽疾病诊断数据集,深入探索了深度学习在中小规模养殖场景下的实战应用。该数据集具有极强的现实意义,所有粪便样本图像均由养殖户通过移动端 ODK 应用在坦桑尼亚阿鲁沙及乞力马扎罗地区实地采集,涵盖了球虫病、新城疫、沙门氏菌及健康状态四个核心类别。在模型构建中,我们通过将图像标准化为224x224像素并引入 EfficientNetB5 强力主干网络,成功捕获了不同病害在视觉特征上的细微差异。实验结果显示,模型在经过 30 轮迭代后表现出了卓越的性能,训练准确率达到了 97.79%,而独立测试集的准确率也稳定在 97.40% 左右,且损失值控制在极低的 0.0974。这一高精度的识别表现充分证明了迁移学习架构在处理真实农业场景、辅助养殖户进行低成本疫病预警方面的巨大潜力,为后续开发便携式智能诊疗工具提供了坚实的算法基础。

源代码

python 复制代码
import numpy as np
import pandas as pd
import os
import time
import matplotlib.pyplot as plt
import cv2
sdir=r'/kaggle/input/chicken-disease-1/Train'
csvpath=r'/kaggle/input/chicken-disease-1/train_data.csv'
df=pd.read_csv(csvpath)
df.columns=['filepaths', 'labels' ]
df.head()
# Adjust the figure to have 3 rows and 3 columns
fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(20, 20))
ax = ax.ravel()  # Flatten the axes array for easier indexing

# Loop through the images (up to 9)
for idx in range(min(9, len(df))):  # Get up to 9 images
    # Load the image from the file path
    img = cv2.imread(df['filepaths'][idx])
    
    if img is not None:
        img = cv2.resize(img, (224, 224))  # Resize if needed
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # Convert to RGB format
        ax[idx].imshow(img_rgb)  # Display the image
        
        # Get the label
        label = df['labels'][idx]
        
        # Set title based on the label
        ax[idx].title.set_text(label)
        ax[idx].axis('off')  # Hide axes for a cleaner look
    else:
        print(f"Image at index {idx} not found or couldn't be loaded.")

plt.tight_layout()
plt.show()
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.utils import to_categorical

def transform_data(df, image_size=(180, 180)):
    images = []
    labels = []
    
    # Load and preprocess images
    for _, row in df.iterrows():
        img = cv2.imread(row['filepaths'])
        if img is not None:
            img = cv2.resize(img, image_size)  # Resize image
            img = img / 255.0  # Normalize image
            images.append(img)
            labels.append(row['labels'])
    
    # Convert to NumPy arrays
    X = np.array(images)
    
    # Encode labels
    lb = LabelEncoder()
    y = lb.fit_transform(labels)  # Integer encode labels
    y = to_categorical(y, num_classes=4)  # One-hot encode labels for 4 classes
    
    return X, y


def load_data(X, y):
    # This step can involve saving to disk, or directly using in model training
    return X, y

# Step 1: Transform
X, y = transform_data(df)

# Step 3: Load
X_train, y_train = load_data(X, y)
print(f"Data shape: {X_train.shape}, Labels shape: {y_train.shape}")
from sklearn.model_selection import train_test_split

# Initial 80-20 split for train and temp (test + validation)
train_df, temp_df, train_labels, temp_labels = train_test_split(
    X, y, train_size=0.8, shuffle=True, random_state=123, stratify=y
)

# Split the temporary set equally (50-50) into validation and test sets
val_df, test_df, val_labels, test_labels = train_test_split(
    temp_df, temp_labels, test_size=0.5, shuffle=True, random_state=123, stratify=temp_labels
)

# This results in:
# - train_df and train_labels: 80% of the data
# - val_df and val_labels: 10% of the data (validation set)
# - test_df and test_labels: 10% of the data (test set)

print("Train set:", train_df.shape, train_labels.shape)
print("Validation set:", val_df.shape, val_labels.shape)
print("Test set:", test_df.shape, test_labels.shape)
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import EfficientNetB5
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, BatchNormalization
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

# Data Augmentation
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest'
)



# Define the model using EfficientNetB5
base_model = EfficientNetB5(weights='imagenet', include_top=False, input_shape=(180, 180, 3))

# Freeze the layers in the base model
base_model.trainable = True  # Optionally keep this True for fine-tuning

# Create the model
model = Sequential([
    base_model,
    Flatten(),
    Dense(256, activation='relu'),
    BatchNormalization(),
    Dense(128, activation='relu'),
    Dense(64, activation='relu'),
    Dense(4, activation='softmax')  # Adjust output layer for the number of classes
])

# Build the model with the input shape
model.build(input_shape=(None, 180, 180, 3))  # Include the channel dimension




# Adjust the model compilation
model.compile(optimizer=Adam(learning_rate=0.0001), 
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])


# Compile the model
model.compile(optimizer=Adam(learning_rate=0.0001), 
              loss='categorical_crossentropy',  # Use sparse categorical if labels are not one-hot encoded
              metrics=['accuracy'])

# Print the model summary
model.summary()
# Train the model without data generators
history = model.fit(
    train_df, train_labels,
    validation_data=(val_df, val_labels),
    epochs=30,  # Adjust the number of epochs as needed
    batch_size=32,
    verbose=1
)
# Evaluate the model on the test set
test_loss, test_accuracy = model.evaluate(test_df, test_labels)
print(f"Test Loss: {test_loss:.4f}, Test Accuracy: {test_accuracy:.4f}")

# Visualize training history
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
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('Epochs')
plt.legend()
plt.show()
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
test_loss, test_accuracy = model.evaluate(test_df, test_labels, verbose=1)
print("Test Accuracy:", test_accuracy)
# Make predictions on the test data
predictions = model.predict(test_df)
predicted_labels = np.argmax(predictions, axis=1)
true_labels = np.argmax(test_labels, axis=1)

# Calculate the confusion matrix
cm = confusion_matrix(true_labels, predicted_labels)

# Display the confusion matrix
disp = ConfusionMatrixDisplay(confusion_matrix=cm)
disp.plot(cmap="Blues")
plt.title("Confusion Matrix")
plt.show()
import matplotlib.pyplot as plt

# Assume `X_test` and `y_test` are your test data and test labels, respectively

# Step 1: Make predictions on the test set
predictions = model.predict(test_df)

# Step 2: Convert predictions from one-hot encoding to label indices
# This gets the index with the highest probability for each prediction
encoded_predictions = np.argmax(predictions, axis=1)

# Step 3: Decode the predictions and true labels to get original label names
lb = LabelEncoder()
lb.classes_ = np.array(['Coccidiosis', 'Healthy', 'New Castle Disease', 'Salmonella'])  # Define your classes
decoded_predictions = lb.inverse_transform(encoded_predictions)
decoded_real_labels = lb.inverse_transform(np.argmax(test_labels, axis=1))

# Plot settings
plt.figure(figsize=(12, 12))

# Display 9 sample predictions with images
for i in range(9):
    # Select image and labels for the i-th sample
    img = test_df[i]
    real_label = decoded_real_labels[i]
    predicted_label = decoded_predictions[i]

    # Plotting the image
    plt.subplot(3, 3, i + 1)
    plt.imshow(img)
    plt.axis('off')
    
    # Display predicted and actual labels
    plt.title(f"Pred: {predicted_label}\nActual: {real_label}", color="green" if predicted_label == real_label else "red")

# Show the plot
plt.tight_layout()
plt.show()

资料获取,更多粉丝福利,关注下方公众号获取

相关推荐
研究点啥好呢1 小时前
快手多模态算法工程师面试题精选:10道高频考题+答案解析
java·开发语言·人工智能·ai·面试·笔试
深海鱼在掘金1 小时前
深入浅出 LangChain —— 第八章:RAG 检索增强生成
人工智能·langchain·agent
深海鱼在掘金1 小时前
深入浅出 LangChain —— 第九章:多 Agent 系统
人工智能·langchain·agent
心静财富之门1 小时前
Django 超详细初级教程(零基础可学)
python·django
用户068866817511 小时前
Windows端Codex接入第三方模型(DeekSeek,BaiLian)
人工智能
bucenggaibian1 小时前
Nearoh:9年开发者从零造语言,Python的简洁+C的性能
c语言·python·开发者·编程语言·nearoh
陈天伟教授1 小时前
AI 未来趋势:产业应用范式之变
大数据·开发语言·人工智能·gpt
Luhui Dev1 小时前
AHE 深度解析:Coding Agent 的 Harness 如何自动演化
人工智能·agent·luhuidev
小小测试开发2 小时前
EasyOCR用法全攻略:Python开源OCR工具快速上手,图文识别零门槛
python·开源·ocr