65.9K
CodeProject 正在变化。 阅读更多。
Home

AI 队列长度检测:使用 Keras 进行对象检测

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2020 年 10 月 26 日

CPOL

5分钟阅读

viewsIcon

7354

downloadIcon

121

这是我们系列文章的第一篇,我们将展示如何制作一个 AI 队列长度检测器。

引言

看到人们排队进入您的咖啡店或商店是一件令人高兴的事情,因为更多的顾客意味着更多的生意。但根据最新研究,长队会劝退更多人加入。例如,当您饥肠辘辘时,您最不想做的事情就是在排队等候吃饭。这就是为什么企业拥有有效的排队策略至关重要。十年前,让计算机数清排队的人数是一个非常困难的问题。公司通常不得不聘请整个学术研究团队来准确地做到这一点。然后深度学习出现了。曾经极其困难的问题,现在任何人都可以通过一台体面的 GPU 或经济实惠的云 GPU 实例来解决。

在本系列文章中,我们将展示如何制作一个 AI 队列长度检测器。我们将从头开始实现一个简单的对象检测器,并在我们自己的数据集上进行训练,然后逐步实现实时检测和跟踪对象(在我们的例子中是人)。稍后,我们还将学习如何通过使用像 YOLO 这样的预训练对象检测网络来提高解决方案的效率。

AI 队列长度检测:使用 Keras 进行对象检测

对象检测被认为是复杂的计算机视觉问题,因为我们需要找到给定图像或视频中所需对象/对象的位置,并确定检测到的对象类型。基于深度学习的模型的最新进展使得开发对象检测应用程序变得更加容易。不仅性能有显著提升,这些模型还利用了最先进的技术和海量数据集来高效地获得理想的结果。

在本文中,我们将保持简单,尝试实现一个卷积神经网络(CNN)来进行对象检测。在进入编码部分之前,让我们先快速回顾一下什么是 CNN。

卷积神经网络

简单地说,CNN 是一类深度神经网络,常用于分析视觉图像。与其他神经网络一样,它由不同的层组成(即输入层、一个或多个隐藏层和输出层)。它可以接受图像作为输入,为图像中的不同方面或对象分配权重,并区分它们。每个隐藏层使用特定的模式和特征转换其输入,然后传递给下一层,而最后一层通常对对象进行分类。

训练 CNN 检测对象

在我们继续之前,重要的是要注意,我将假设您对 Python 有一定的了解,并且对深度学习也有一定的理解,因此我将跳过常见 Python 库的安装过程。我将使用 Windows 上的 Anaconda 发行版在 Jupyter Notebook 中进行工作,但您可以随意选择任何 IDE 来配合。代码不是平台特定的,应该可以正常工作。

在本文中,我们将使用 cifar10 数据集来训练一个简单的对象检测器。

让我们开始导入我们需要的库。

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from keras import losses,metrics
from keras.optimizers import Adam
from keras.models import Sequential
from keras.callbacks import EarlyStopping
from keras.utils.np_utils import to_categorical
from keras.layers import MaxPool2D, Dense, Conv2D, Flatten
from sklearn.metrics import classification_report,confusion_matrix,accuracy_score

下一步是加载数据。您可以使用以下行直接在笔记本中下载它。

from keras.datasets import cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

让我们验证每个集合的形状。

X_train.shape

X_test.shape

y_train.shape
Y_test.shape

cifar10 数据集有十种不同的对象类别,计数相等,因此这将有助于算法平等地学习所有类别。可以通过以下方式验证此点:

np.unique(y_train,return_counts=True)

我们需要标准化这些数据,然后才能将其馈送到神经网络,同时还要将类别变量更改为矩阵。

x_train=x_train.astype('float32')
x_test=x_test.astype('float32')
x_train /= 200
x_test /= 200
 
y_train=to_categorical(y_train)
y_test=to_categorical(y_test)

现在是定义模型来分类这些对象的时候了。我们将使用一个带有两个卷积层的顺序模型。这些层将有 32 个过滤器(稍后我们将应用最大池化来减小空间尺寸)。我们将使用 Adam 激活函数编译我们的模型。

model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(32, 32, 3),activation='relu'))
model.add(Conv2D(32, (3, 3),activation='relu'))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3),activation='relu'))
model.add(Conv2D(64, (3, 3),activation='relu'))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.compile(loss=losses.categorical_crossentropy,
          	optimizer=Adam(),
              metrics=[metrics.categorical_accuracy])

您可以看到如下的模型摘要:

model.summary()

现在让我们在我们的训练数据上拟合模型。

early=EarlyStopping(monitor='loss')
hist=model.fit(x_train,y_train,batch_size=100,validation_split=0.2,epochs=5,callbacks=[early])

测试我们的模型

现在我们的模型已经训练好,我们可以使用 evaluate 函数来评估我们的模型表现如何。

model.evaluate(x_test,y_test,batch_size=100)

您应该会看到类似以下的输出:

100/100 [==============================] - 10s 97ms/step - loss: 0.8231 - categorical_accuracy: 0.7128
[0.8231054544448853, 0.7128000259399414]

我们获得了 71% 的准确率,这已经足够好了,因为我们可以看到它没有过拟合。我们也可以绘制训练和验证的准确率。

现在让我们使用我们刚刚训练好的模型预测测试数据集的类别。

y_pred = model.predict_classes(x_test)

我们可以再次使用 accuracy_score 来测试我们模型的准确率。

print(accuracy_score(y_test_classes,y_pred))

我们获得了 72% 的分数,这并不算太差,因为我们实现了一个非常简单的 CNN 架构。只要有我们所需的计算能力和内存,我们仍然可以提高这些分数。目前,我们的模型在整个数据上泛化良好,并提供了我们如何使用 CNN 进行对象检测的概述。

下一步是什么?

在本文中,我们只是初步了解了对象检测。我们训练的模型可以用来检测一般对象,准确率为 72%。如果我们想进一步提高性能怎么办?传统 CNN 并非总是对象检测的理想选择。我们的模型之所以表现良好,是因为数据集中每个类别的计数都相同;在现实世界中处理时,情况通常并非如此。如果我们尝试训练模型进行自定义对象检测,我们将面临许多问题。在下一篇文章中,我们将探讨用于对象检测的其他一些算法,并学习如何将它们应用于自定义对象检测。

© . All rights reserved.