炼数成金 门户 商业智能 深度学习 查看内容

大规模拥挤人群:一个破纪录的人群计数算法!

2019-4-17 16:50| 发布者: 炼数成金_小数| 查看: 22051| 评论: 0|原作者: 张雅慧 沈浩|来自: 沈浩老师

摘要: 人脸识别或人脸签到往往是1:1,或1:N的图像识别技术,但如何数人数,少量只要能识别人脸当然就可以数人数了。但当我们面临大规模拥挤的人群,我们可能不需要识别人脸,只是人群计数,是否可以实现呢?能帮我数数图片 ...

Python 算法 模型 计算机 计算机视觉 方法

人脸识别或人脸签到往往是1:1,或1:N的图像识别技术,但如何数人数,少量只要能识别人脸当然就可以数人数了。


但当我们面临大规模拥挤的人群,我们可能不需要识别人脸,只是人群计数,是否可以实现呢?

能帮我数数图片中这个活动有多少人参加吗?


太多了?那这个怎么样?

还是不行?没关系!

今天我们将教你创建一个基于深度学习的人群计数模型。

本文是基于卷积神经网络(CNN)的工作方式建立的,在进一步研究之前,您可以参考下面这篇文章来了解这个主题:

https://www.analyticsvidhya.com/blog/2018/12/guide-convolutional-neural-network-cnn/?utm_source=blog&utm_medium=crowd-counting

现在,我们正式开始介绍~

目录
 1.什么是人群计数?
 2.为什么要数人群?
 3.了解不同计算机视觉技术在人群计数中的应用
 4.CSRNet的体系结构与训练方法
 5.用Python构建自己的人群计数模型

什么是人群计数?
人群计数是一种计算或估计图像中的人数的技术。
还是这张图——


你能告诉我这个图片里大概有多少人吗?最直接的方法是手工算,但这有实际意义吗?当人群这么多的时候,一个一个数几乎是不可能的!
人群科学家们可以通过对图片区域划分,计算图像某些部分的人数,然后外推得出估计值。这种方法是现在较为普遍的方式,但是也存在误差。几十年来,我们不得不依靠粗略的指标来估计这个数字。

肯定有更好、更准确的方法吧?
没错,有!

虽然我们还没有算法可以给出确切的数字,但大多数计算机视觉技术可以产生几乎完美的较精确估计。让我们先了解为什么人群计数是重要的,然后再深入研究其背后的算法。

人群计数有什么用?
让我们用一个例子来理解人群计数的有用性。想象一下,中国传媒大学刚刚举办了一个大型的数据科学会议。活动期间举行了许多不同的会议。

你被要求分析和估计每一次参加会议的人数。这将帮助我们了解什么样的会议吸引了最多的人数(以及哪些会议在这方面失败了)。并由此可以针对性塑造明年的会议,所以这是一项重要的任务!

参加会议的人数太多了,如果人工数可能将需要很久!这就是学习人群计数技能的作用所在。只要获得每一次会议中人群的照片,就可以建立了一个计算机视觉模型来完成其余的工作!

还有很多其他情况下,人群计数算法正在改变行业的运作方式:
统计参加体育赛事的人数
估计有多少人参加了就职典礼或游行(可能是政治集会)
对交通繁忙地区的监察
协助人员配置和资源分配

不同计算机视觉技术在人群计数中的应用
概括地说,目前我们可以用四种方法来计算人群中的人数:
1.基于检测的方法
我们可以使用一个移动窗口式检测器来识别图像中的人,并计算出有多少人。用于检测的方法需要训练有素的分类器来提取低层次特征。虽然这些方法在人脸检测方面效果很好,但在拥挤的图像上效果不佳,因为大多数目标对象都不是清晰可见的。

2.回归方法
对于低级别的特征,上述方法使用并不有效,可以使用基于回归的方法。我们首先从图像中裁剪补丁,然后,针对每个补丁,提取低级别的特征。

3.基于密度估计的方法
我们首先为要检测的图片创建一个密度图。然后,该算法学习了提取的特征与目标密度映射之间的线性映射。我们也可以利用随机森林回归来学习非线性映射。

4.基于CNN的方法
我们不用看图像的补丁,而是使用可靠的卷积神经网络(CNN)构建一个端到端的回归方法。这将整个图像作为输入,并直接生成人群计数。CNN在回归或分类任务中非常有效,并且在生成密度图方面也证明了它们的价值。

CSRNet是我们在本文中将实现的一种技术,它部署了一个更深层次的CNN,用于捕获高级别的特性和生成高质量的密度图,而不需要扩展网络复杂性。在讲到编码部分之前,让我们先了解一下CSRNet是什么。

了解CSRNet的体系结构和培训方法
CSRNet以VGG-16为前端,具有很强的迁移学习能力.VGG的输出大小是原始输入大小的⅛。CSRNet还在后端使用膨胀的卷积层。

那么,什么是膨胀的卷积?请参考以下图像:


使用膨胀卷积的基本概念是在不增加参数的情况下扩大核。所以,如果膨胀率是1,我们取核并将它转到整个图像上。然而,如果我们将扩展率提高到2,内核就会像上面的图像所示的那样扩展(按照每个图像下面的标签)。它可以替代汇集图层。

基础数学(推荐,选择性了解)
我要花点时间解释一下数学是如何工作的。(请注意,在Python中实现算法并不是必须的,但我强烈建议学习基本思想。)当我们需要调整或修改模型时,这将派上用场。

假设我们有一个输入x(m,n),一个滤波器w(i,j),以及膨胀率r。输出y(m,n)为: 

我们可以用(k*k)核推广这个方程,其扩张率为r。内核扩展到:
([K+(k-1)*(r-1)]*[k+(k-1)*(r-1)])

因此,每一幅图像都产生了地面真相。在给定的图像中,每个人的头部都是用高斯核模糊的。所有图像都被裁剪成9个补丁,每个补丁的大小是图像原始大小的1/4。

前4个补丁分为4个四分之一,其他5个补丁随机裁剪。最后,每个补丁的镜像被取为训练集的两倍。 

简而言之,这就是CSRNet背后的体系结构细节。接下来,我们将查看它的培训细节,包括所使用的评估指标。

随机梯度下降用于训练CSRNet作为端到端结构。在训练期间,固定学习率设置为1e-6。损失函数被认为是欧几里德距离,以便测量地面之间的差异 真相和估计的密度图。这表示为:

其中N是训练批次的大小。CSRNet中使用的评估标准是mae和mse。,即平均误差和均方误差。这些建议是由以下方面提供的:

在这里,Ci是估计数:

L和W是预测密度图的宽度。

我们的模型将首先预测给定图像的密度图。如果没有人在场,像素值将为0。如果某个像素对应于某个人,则将指定某个预定义的值。因此,计算一个人的总像素值会给出图像中人的数量。

那么现在,是时候建立我们自己的人群计数模型了!

建立自己的人群计数模型
我们将在上海科技数据集上实现CSRNet。这包括1198个加注释的图片,总共有330,165人。您可以从这里下载。
https://www.dropbox.com//s/fipgjqxl7uj8hd5/ShanghaiTech.zip?dl=0

使用下面的代码块克隆CSRNet-py火炬存储库。这保存了用于创建数据集、培训模型和验证结果的全部代码:
git clone https://github.com/leeyeehoo/CSRNet-pytorch.git
请先安装CUDA和PyTorch。这些是我们将在下面使用的代码背后的主干。

现在,将数据集移动到您在上面克隆的存储库并解压它。然后我们需要创建基本事实值.make_dataset.ipynbfile是我们的救星。我们只需要在该笔记本中做一些小改动:
#setting the root to the Shanghai dataset you have downloaded
# change the root path as per your location of datasetroot = '/home/pulkit/CSRNet-pytorch/'
现在,让我们为part_A和part_B中的图像生成基本真值: 

生成每幅图像的密度图是一个时间步骤。所以,在代码运行时,去泡一杯咖啡吧。

到目前为止,我们已经在第A部分中为图像生成了地面真值,我们将对Part_B图像进行同样的处理。但在此之前,让我们看看一个示例图像,并绘制它的地面真实热图: 

生成每张图像的密度图是一个很长的时间。所以在代码运行时去冲泡一杯咖啡吧,耐心等待一下。 

到目前为止,我们已经为part_A中的图像生成了基本真值。 我们将对part_B图像执行相同的操作。但在此之前,让我们看一个示例图像并绘制其地面真实热图:

plt.imshow(Image.open(img_paths[0]))

gt_file = h5py.File(img_paths[0].replace('.jpg','.h5').replace('images','ground-truth'),'r')
groundtruth = np.asarray(gt_file['density'])
plt.imshow(groundtruth,cmap=CM.jet)

让我们数一下这张图片中有多少人在场:
np.sum(groundtruth)
270.32568 

同样,我们将为part_B生成值: 
我们将使用克隆目录中可用的.json文件。我们只需要更改JSON文件中图像的位置。为此,打开.json文件并将当前位置替换为图像所在的位置。

请注意,所有这些代码都是用Python 2编写的。如果您使用的是其他任何Python版本,请进行以下更改: 

1.在model.py中,将第18行中的xrange更改为range

2.在model.py中更改第19行:list(self.frontend.state_dict()。items())[i] [1] .data [:] = list(mod.state_dict()。items())[i][1]。数据[:]

3.在image.py中,将ground_truth替换为ground-true 

现在,打开一个新的终端窗口并键入以下命令:
cd CSRNet-pytorch
python train.py part_A_train.json part_A_val.json 0 0
这个步骤需要一些时间,耐心等一下。你也可以减少train.py文件中的纪元数量,以加快这个过程。你也可以从这里下载预先训练的重量,如果你不想等待的话。

最后,让我们检查一下我们的模型在看不见的数据上的性能。我们将使用val.ipynb文件来验证结果。记住要更改到预先训练过的权重和图像的路径。
#defining the image path
img_paths = []
for path in path_sets:
    for img_path in glob.glob(os.path.join(path, '*.jpg')):
       img_paths.append(img_path)
model = CSRNet()
#defining the model
model = model.cuda()
#loading the trained weights
checkpoint = torch.load('part_A/0model_best.pth.tar')
model.load_state_dict(checkpoint['state_dict'])
检查测试图像上的MAE(平均误差),以评估我们的模型:

我们得到的MAE值为75.69,相当不错。现在让我们检查一下单个图像上的预测:


哇,最初的数字是382,我们的模型估计图像中有384人。这几乎是一个完美的演绎!

恭喜你建立了自己的人群计数模型!

原始论文的评测图和结果

最后
您可以在https://colab.research.google.com上测试跑人群计数。
需要安装:Pytorch和Cuda


附论文下载地址:CSRNet: Dilated Convolutional Neural Networks for Understanding the HighlyCongested 

声明:本文版权归原作者所有,文章收集于网络,为传播信息而发,如有侵权,请联系小编及时处理,谢谢!

欢迎加入本站公开兴趣群
商业智能与数据分析群
兴趣范围包括各种让数据产生价值的办法,实际应用案例分享与讨论,分析工具,ETL工具,数据仓库,数据挖掘工具,报表系统等全方位知识
QQ群:81035754

鲜花
1

握手

雷人

路过

鸡蛋

刚表态过的朋友 (1 人)

相关阅读

最新评论

热门频道

  • 大数据
  • 商业智能
  • 量化投资
  • 科学探索
  • 创业

即将开课

 

GMT+8, 2019-7-19 00:05 , Processed in 0.215117 second(s), 24 queries .