使用深度学习检测植物疾病
#python #machinelearning #deeplearning #model

介绍

在这篇文章中,我们将使用深度学习建立植物疾病检测模型。我们将使用Kaggle的New Plant Diseases Dataset数据集。

数据集

数据集由大约87,000张健康和患病的植物叶片组成。数据集包含38种不同类别的植物叶。总数据集分为训练和验证集的80/20比率,以保留目录结构。还为测试模型创建了一个新的目录。

导入库

import pandas as pd
import numpy as np
import tensorflow as tf
from tensorflow.keras import models, layers
import matplotlib.pyplot as plt

设置超参数

我们将为模型设置超参数。我们将使用以下超参数:

image_size = 256
batch_size =32
channels = 3
epoches = 12

加载数据集

用于加载数据集,我们将使用image_dataset_from_directory函数。此功能采用数据集目录的路径并返回tf.data.Dataset对象。 tf.data.Dataset对象是用于构建张量流型号的输入管道的强大工具。它使我们可以轻松地从磁盘加载数据,应用转换并将数据馈送到我们的模型中。

dataset = tf.keras.preprocessing.image_dataset_from_directory(
    '../input/new-plant-diseases-dataset/',
    shuffle = True,
    image_size = (image_size, image_size),
    batch_size = batch_size
)

存储和打印班级名称

class_names = dataset.class_names
print(class_names)

可视化图像

plt.figure(figsize=(10, 10))
for image_batch, label_batch in dataset.take(1):
    for i in range(12):
        ax = plt.subplot(3, 4, i+1)
        plt.imshow(image_batch[i].numpy().astype("uint8"))
        plt.title(class_names[label_batch[i]])

在上面的代码中,我们从数据集中获取第一批图像和标签,然后绘制带有相应标签的图像。

拆分数据集

我们将将数据集分解为培训,验证和测试集。

def get_dataset_partitions_tf(ds, train_split=0.8, val_split=0.1, test_split=0.1, shuffle=True, shuffle_size = 10000):
    ds_size = len(ds)

    if shuffle:
        ds = ds.shuffle(shuffle_size, seed = 12)

    train_size = int(train_split * ds_size)
    val_size = int(val_split*ds_size)

    train_ds = ds.take(train_size)

    val_ds = ds.skip(train_size).take(val_size)
    test_ds = ds.skip(train_size).skip(val_size)

    return train_ds, val_ds, test_ds

在上面的代码中,我们定义一个功能,该函数将数据集分解为培训,验证和测试集。该功能将数据集和拆分比为输入,并返回培训,验证和测试集。

train_ds, val_ds, test_ds = get_dataset_partitions_tf(dataset)

获得培训,验证和测试集的长度

print("Len train_set = ", len(train_ds))
print("Len val_set = ", len(val_ds))
print("Len test_set = ", len(test_ds))

缓存,预取和批处理数据集

train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
val_ds = val_ds.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
test_ds = test_ds.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)

上面我们正在缓存,改组和预取数据集。缓存数据集将图像在第一个时期内加载磁盘后将图像存储在内存中。这将确保训练模型时数据集不会成为瓶颈。改组数据集将确保在每个时期内都不会看到模型相同的示例顺序。预拿数据集将确保数据立即可用于下一次培训的下一次迭代。

调整和重新缩放图像

resize_and_rescale = tf.keras.Sequential([
    layers.experimental.preprocessing.Resizing(image_size, image_size),
    layers.experimental.preprocessing.Rescaling(1.0/255)
])

上面我们将图像大小调整到指定的大小,并将图像重新缩放到0到1的范围。

数据增强

data_augumentation = tf.keras.Sequential([
    layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical"),
    layers.experimental.preprocessing.RandomRotation(0.2)
])

上面我们正在对图像进行数据增强。数据增强是一种从现有培训数据中人为创建新培训数据的技术。这有助于避免过度拟合并帮助模型更好地概括。

构建模型

input_shape = (batch_size, image_size, image_size, channels)
num_classes = 38
model = models.Sequential([
    resize_and_rescale, 
    data_augumentation,
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape),
    layers.MaxPooling2D((2, 2)), 
    layers.Conv2D(64, kernel_size = (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)), 
    layers.Conv2D(64, kernel_size = (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)), 
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)), 
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)), 
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)), 
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    layers.Dense(num_classes, activation='softmax'),
])

model.build(input_shape)

model.summary()

我们正在使用以下层的顺序模型:

  • 调整大小和恢复层 - 该层将图像调整为指定的大小,并将图像重新缩放到0到1的范围。
  • 数据增强层 - 该层在图像上执行数据增强。数据增强是一种从现有培训数据中人为创建新培训数据的技术。这有助于避免过度拟合并帮助模型更好地推广。
  • 卷积层 - 该层在输入图像上执行卷积。卷积是一种数学操作,采用两个输入,例如图像矩阵和一个过滤器或内核。过滤器应用于输入图像,输出是特征映射。
  • 最大池层 - 此层在输入图像上执行最大池。最大池是降低输入图像的维度的技术。它是通过从内核覆盖的图像的部分获取最大值来完成的。
  • 平坦的层 - 该层将输入图像扁平到单个维度。
  • 密集层 - 该层执行输出=激活的操作(DOT(输入,内核) +偏差)。它用于在输入图像上执行分类。

编译模型

model.compile(
    optimizer='adam', 
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
    metrics = ['accuracy']
)

我们正在使用以下参数编译模型:

  • 优化器 - 这是将用于更新模型权重的优化器。我们正在使用Adam Optimizer。
  • 损失 - 这是用于计算模型损耗的损失函数。我们使用的是稀疏的分类杂交损失函数。
  • 指标 - 这是用于评估模型性能的指标。我们正在使用准确度量。

训练模型

history = model.fit(
    train_ds, 
    epochs = epoches,
    batch_size = batch_size,
    verbose=1,
    validation_data = val_ds
)

我们正在使用以下参数训练模型:

  • 培训数据集 - 这是用于培训模型的培训数据集。
  • 时代 - 这是对模型进行训练的时期数量。
  • 批处理大小 - 这是用于训练模型的批次大小。
  • 冗长 - 这是用于训练模型的详细模式。
  • 验证数据集 - 这是用于验证模型的验证数据集。

评估模型

model.evaluate(test_ds)

我们正在评估测试数据集上的模型。该模型在测试数据集上达到了0.96的精度。这意味着该模型能够正确对测试数据集中的96%的图像进行分类。这是一个很好的准确性。我们可以使用更复杂的模型体系结构,使用较大的数据集,使用不同的优化功能,使用不同的损耗函数,使用不同的度量,使用不同的批次大小,使用不同数量的时期,我们可以使用更复杂的模型体系结构来进一步提高模型的准确性。等等。我们还可以使用转移学习来提高模型的准确性。

保存模型

model.save("model.h5")

我们正在以H5格式保存模型。 H5格式是一种数据文件格式,用于存储模型的权重和体系结构。我们可以使用load_model()函数从H5文件加载模型。

结论

在此博客中,我们学会了如何使用深度学习来检测植物叶中的疾病。我们学会了如何使用Keras API构建深度学习模型。我们学会了如何使用卷积层,最大池层,平坦的层,密集的层等构建顺序模型。我们学会了如何使用Adam Optimizer,稀疏的分类CrossTrentRopy损失函数和准确度量来编译模型。我们学会了如何在培训数据集上培训模型并在测试数据集上评估模型。我们学会了如何以H5格式保存模型。

Voyla!我们已经成功建立了一个深度学习模型来检测植物叶中的疾病。

感谢您的阅读!