C3F:首个开源人群计数算法框架

举报
风吹稻花香 发表于 2021/06/04 23:58:42 2021/06/04
【摘要】 C3F:首个开源人群计数算法框架   导读:52CV曾经报道多篇拥挤人群计数相关的技术,比如最近的:   CVPR 2019 | 西北工业大学开源拥挤人群数据集生成工具,大幅提升算法精度   开源地址: https://github.com/gjy3035/C-3-Framework 这个有个核心网络加自己的人数计数,比如resn...

C3F:首个开源人群计数算法框架

 

导读:52CV曾经报道多篇拥挤人群计数相关的技术,比如最近的:

 

CVPR 2019 | 西北工业大学开源拥挤人群数据集生成工具,大幅提升算法精度

 

开源地址:

https://github.com/gjy3035/C-3-Framework

这个有个核心网络加自己的人数计数,比如resnet101+计数网络。

 

视频监控的普及,需求推动技术的快速进步。


 

1. 数据处理

我们提供了常见的六个主流数据库的预处理代码,处理好的数据集以及PyTorch下的data loader,包括:

  • UCF_CC_50[[1]](UCF50),

  • Shanghai Tech Part A/B[[2]](SHT A/B),

  • WorldExpo'10[[3]](WE),

  • UCF-QNRF[[4]](QNRF),

  • GCC[[5]]。

后期还会提供UCSD[[11]]和MALL[[12]]数据集的相关内容。

 

1.1 生成密度图-处理参数

 

注:

1. 为了能够使得输入图像兼容更多的网络,预处理时对图像的高和宽进行了限制,使其能够被16整除。确保网络中一些含有降采样操作的层(conv with stride2 或者池化)能够正确输出。在人群计数领域中,常见encoder中一般输出为1/8原图尺寸,因此被16整除完全满足需求。

2. 为节约显存,对QNRF和GCC的图像进行了保持长宽比的降采样操作。

 

1.2 多Batch-size训练

由于UCF50、SHT A、QNRF所包含的图像尺寸不一,为了实现多batch size的训练,我们重写了`collate_fn`函数。该函数在随机拿到N张图像和GT后,选择最小的高h_min和最小的宽w_min对所有图像进行crop,拼成Tensor送入到网络中进行训练。

 

根据经验,如果是from scratch training,对于这几个数据集建议采用多batch size训练或者采用GCC-SFCN中加padding的方案,对于有预训练参数的模型(AlexNet,VGG,ResNet等),建议采用单一batch size进行训练。

 

1.3 Label Transform

代码中我们提供了两种对密度图进行transform的操作。一种参考了CSRNet源码[[6]]中对密度图进行降采样的操作(`GTScaleDown`),一种是对密度图点乘一个放大因子(`LabelNormalize`)。

 

1.3.1 GTScaleDown

由于CSRNet中,网络回归的密度图为原图的1/8,因此作者对密度图进行了降采样,并点乘64以保证密度图之和依然约等于总人数。该操作会带来一个问题:会影响PSNR和SSIM的值。因此我们不建议使用该操作。在我们实现其他网络过程中,也会出现网络输出为1/4,1/8等尺寸,为避免该问题,在网络内部增加上采样层实现与原图大小的密度图。

 

1.3.2 LabelNormalize

这算是一个训练的trick,我们通过实验发现,对于密度图乘以一个较大的放大因子,可以使网络更快的收敛,甚至取得更低的估计误差。

 

1.4 数据增强

 

2 模型

这一部分,我们介绍几种常见分类网络(AlexNet,VGG,ResNet等)“魔改”为人群计数的网络。

 

2.1 Baseline模型

 

2.1.1 AlexNet

 

对于AlexNet网络[[7]],我们小幅修改了conv1和conv2层的padding,以保证其对于feature map的大小能够正常整除。同时,截取conv5之前的网络,作为人群计数的encoder,其大小为原始输入的1/16。decoder的设计依然遵循简约的原则,用“两层卷积+上采样”直接回归到1-channel的密度图。

 

2.1.2 VGG系列:VGG和VGG+decoder

 

对于VGG网络[[8]]的两个变体,我们完全采用了VGG-16模型的前10个卷积层。其中,VGG采用了最为简单的decoder,而VGG+decoder则是简单设计了一个含有三个反卷积的模块。下表展示了二者在SHT上的实验结果。


VGG系列性能对比:

 

 

VGG系列可视化对比:

 

VGG结果

 

VGG+decoder结果

 

通过在SHT B上实验结果来看,两者的模型性能(MAE,MSE)差不多,但VGG+decoder有着更为精细的密度图。二者的性能非常接近CSRNet(同样的backbone)的结果。

 

2.1.3 ResNet系列:Res50和Res101

 

对于ResNet[[9]],为了保证密度图的大小不至于过小(不小于原图尺寸的1/8),我们修改了res.layer3中第一层stride的大小(将原本的2改为1),以此当做encoder。本着简单的原则,decoder由两层卷积构成。从实验结果来看,ResNet展现除了强大的特征提取能力,在SHT B上直接达到了现有SOTA的水平。据我们所知,截止目前(2019.4),已发表/录用文章中最好的是PACNN+[[10]],其MAE/MSE为:7.6/11.8。我们的模型在SHT B数据集上具体表现如下:

 

 

2.2 C3F框架下复现模型比较

 

除了上述基于ImageNet分类模型设计的Baselines以外,我们也尝试在C3F下复现了以下几个主流算法的结果,包括MCNN[[2]],CMTL[[13]],CSRNet[[6]]以及SANet[[14]]。我们复现的模型在SHT B数据集上具体表现如下:

 

 

注:

1. 在MCNN复现过程中,与原网络结构唯一不同在于,我们的MCNN处理的是RGB图像。

2. 原始的CMTL在训练前,通过随机裁剪生成好了训练集。我们采用在线裁剪的方法可以使训练覆盖更多的裁剪区域。此外,由于选择了在线裁剪,CMTL中的分类任务的标签页适应性地改成了在线计算与分配。

3. 据我们所知,SANet复现结果,是当前所有复现中最接近论文结果的,虽然这一结果与论文结果依然相差甚远。

 

3 训练技巧

 

3.1 LabelNormalize的调参

 

在C3F已公布的实验结果中,均对密度图进行了点乘100的操作。实验过程中,我们也发现,设置一个合适的放大因子,对于网络的有效训练非常有益。这一节,我们简要说一下为什么这样一个简单的操作会有效的原因。

 

一个初始化好的计数网络来说,自身参数符合一定的分布,如果目标分布和初始化分布相差过大的话,网络会陷入一个比较差的局部解,难以训练出好的结果。该特性在使用预训练分类模型的计数网络时,显得更为重要。

 

这一节,我们选择Res50网络,分别测试在对密度图分别乘以[1,10,100,1000,2000,4000]时,网络的计数性能差异。下表展示了不同放大因子下在SHT B上的实验结果。

 

我们发现,当采用原始密度图时,网络并不能正确收敛。观察结果发现,网络一直输出一张全0的密度图。陷入到一个局部解无法进一步优化。当放大因子为1000时,网络达到了最优性能。之后,随着放大因子的增加,网络的计数性能又逐步降低。

 

 

下图展示了在六组不同的放大因子下,MAE和MSE在验证集上随时间的变化曲线。橙色曲线表示对密度图不进行放大情况下,网络性能的表现。我们发现,网络陷入到一个局部解难以跳出。

 

不同放大因子的实验对比:

 

 

由于橙色曲线会干扰我们对其他参数曲线的对比,因此,下图展示了移除掉橙色曲线后,即放大因子为[10,100,1000,2000,4000]的曲线对比。从图中可以看出,除了放大因子取10时,效果较差,其他几种曲线重合度非常高。

 

不同放大因子的实验对比:

 

 

综上,我们设定一个较大的放大因子,不仅可以促使模型快速收敛,也可以帮助模型取得一个更优的性能。

 

3.2 特征图大小对比:1/8 size v.s 1/16 size

 

过小的特征图尺寸会对计数的性能产生非常大的影响。这里,我们进行两组对比试验:

1) ResNet-50中res.layer3以前的层原封不动当做backbone,最终输出密度图作16x的上采样;

2) C3F最终采用的方案,输出密度图作8x的上采样。

 

 

从实验结果可以看出,在将stride改为1后,模型输出了分辨率更高的密度图,同时在计数误差上取得了更好的效果。同时,我们也对比一下两者在训练过程中,测试集上MAE和MSE的表现,如下图所示。其中蓝色部分为stride=2的结果,橙色为stride=1的结果。能够很直观的看出,平滑后的曲线图,橙色曲线整体要低于蓝色曲线。(注:实验中,其他参数均与`results_reports/Res50/SHHB`中的设置保持一致。)

 

不同特征图大小的实验对比:

 

 

3.3 数据归一化中,均值和标准差对实验结果的影响

 

C3F中,在`misc`中我们提供了`cal_mean.py`来计算数据集中的训练数据中均值和标准差。大多数人会使用ImageNet的均值和标准差(也就是`mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]`),经过实测,该参数对最终的性能影响有限。我们继续使用Res50和MCNN网络进行试验,用两种均值、标准差进行归一化,比较最终的计数误差,结果见下表。(注:Res50实验中,其他参数均与`results_reports/Res50/SHHB`中的设置保持一致。MCNN实验则是与`results_reports/MCNN/SHHB`中的设置保持一致)

 

 

从表格中,我们可以看出,使用了自身数据集的均值和标准差,性能要略微优于使用ImageNet上的均值和标准差所得到的的结果。下图展示了训练过程中验证集上MAE和MSE的变化曲线,其中橙色代表采用了SHT B的均值和标准差的实验,蓝色则为采用了ImageNet的结果。从图中可以看出,二者的重合度非常高。


 

Res50:不同均值标准差的实验对比:

 

 

MCNN:不同均值标准差的实验对比

 

 

由于人群图像和ImageNet数据均属于自然图像,计算出的均值和标准差也比较类似。因此,改值对实验结果的影响并不是很大。当然,影响程度也与数据集有关,如果数据具有很强的偏置,最好还是采用数据对应的均值和标准差。总的来说,我们还是建议使用训练数据的均值和标准差,以取得更好的计数性能。

 

4 实验结果

 

本节,我们将复现的所有算法在SHT B上的性能展示出来,方便大家做最终的对比。我们发现,得益于ResNet-101强大的学习能力,以其为Backbone的人群计数器在MAE和MSE指标上超越了其他所有算法。此外,我们还发现,对于有预训练参数的网络,甚至可以不需要对网络进行过多的设计,例如Dilated Conv、Multi-column Conv、Scale Aggregation等,就可以达到一个较好的结果。

 

 

5 总结展望

 

本项目旨在提供一个简单、高效、易用、灵活的人群计数框架,方便新手快速上手入门、资深研究者高效实现idea以及最大化模型性能。

 

本技术报告则是对该项目的一个简单介绍,使大家能够对我们的项目有一个更深的理解,这样用起来也会更加顺手,最大化框架的使用度。

 

同时,我们英文Technical Report(为本文的精简内容)也将在arxiv上预印。如果大家有任何问题、建议,欢迎大家在仓库中提issue和PR,让C3F变得更好!

 

6 致谢

 

在整个项目推进的过程中,得到了很多人的大力支持。

特别地,感谢@wwwzxoe303com对关键代码的检查和测试,感谢@PetitBai对项目Readme.md的校对,感谢Google Colab提供免费实验资源。

 

此外,我们的部分代码、设计逻辑参考或直接借用了以下作者的仓库/项目/代码,在此一并表示感谢!正是有了以下几个出色的开源代码,我们才得以完成C3F项目。

py-faster-rcnn:

https://github.com/rbgirshick/py-faster-rcnn)

pytorch-semantic-segmentation:

https://github.com/zijundeng/pytorch-semantic-segmentation

CSRNet-pytorch:

https://github.com/leeyeehoo/CSRNet-pytorch

SANet_implementation:

https://github.com/BIGKnight/SANet_implementation

enet.pytorch:

https://github.com/gjy3035/enet.pytorch

GCC-SFCN:

https://github.com/gjy3035/GCC-SFCN

PCC-Net:

https://github.com/gjy3035/PCC-Net(论文尚未发表,因此暂未公开源码)

 

7 Q&A

 

1. Q:能否提供Python3环境下的代码?

A:会,但现在时机不成熟。原因是Tensorboard暂时还不支持Python3.7,加之人手不足,暂无开发计划。

 

2. Q:为什么在SHT B上做实验?以后会不会对其他数据集进行验证?

A:因为图像尺寸相同,便于多batch-size的训练和测试,能够最大化利用显卡,节省显卡资源和训练时间。对于其他数据集,由于自己的时间有限,也没有足够的显卡资源,暂时不会做其他数据集实验。

 

3. Q:语义分割和人群计数非常类似,能不能直接用一些分割网络呢?

A:二者同属于逐像素任务,前者为逐像素分类,后者为逐像素回归。根据我的实验,某些分割网络直接修改最后一层为回归层后,其效果与backbone相比,提升非常有限。甚至性能会有所下降。深层问题暂时还没有仔细思考。不过据我所知,有人对此问题已经做了研究,大家耐心等待即可。

 

4. Q:正确的训练、验证、测试流程应该是怎样的?

A:严格意义上,所有数据集应该都包含以上三种数据(如果没有验证集,则应该从训练集中随机选择一部分)。在本项目中,为了能够确保所有实验结果可以复现,我们直接将测试集当做验证集来监控训练过程。

 

5. Q:部分模型会在PyTorch1.0下报上采样函数`F.upsample`的警告信息。

A:该警告不影响训练。为了兼容0.4版本,我们依然采用`F.upsample`方法来对Tensor进行放大尺寸的操作。

文章来源: blog.csdn.net,作者:网奇,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/jacke121/article/details/90235875

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。