近两年,有关人群计数的文章呈现出爆炸式增长。然而,人群计数不像其他任务(目标检测、语义分割等)有着简洁/易开发的开源代码框架,大大降低了我们对于idea的验证效率。
因此在2018年12月份,我萌生了自己搭一个人群计数框架的想法,尽可能兼顾当前主流数据集和主流算法。并于2019年3月底基本完成了主体框架。代码发布之后,由于缺少对于代码细节的文档介绍,issues和emails让人应接不暇。所以,在这里对该项目做一个代码层面上的介绍,并辅之以一些实验分析来帮助大家有效提高网络性能。更重要的,希望能够抛砖引玉,让大家利用c3f,更高效地研究出性能更好的人群计数网络,推动该领域的发展。
本文主要内容包括:
数据处理:不同数据集的处理过程。
模型:基于imagenet分类模型设计的人群计数器以及我们复现的一些主流网络。
训练技巧:一些常见的网络训练技巧。
实验结果:在shanghai tech part b数据集上的实验结果及分析。
总结。
致谢。
q&a:一些常见问题的解答。
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,我们通过实验发现,对于密度图乘以一个较大的放大因子,可以使网络更快的收敛,甚至取得更低的估计误差。有关这一点的更进一步分析、实验结果,移步实验部分。
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上的实验结果。
通过在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时,网络达到了最优性能。之后,随着放大因子的增加,网络的计数性能又逐步降低。
(注:实验中,其他参数均与results_reports/res50/shhb中的设置保持一致。)
下图展示了在六组不同的放大因子下,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项目。
rbgirshick/py-faster-rcnn
zijundeng/pytorch-semantic-segmentation
leeyeehoo/csrnet-pytorch
bigknight/sanet_implementation
gjy3035/enet.pytorch
gjy3035/gcc-sfcn
gjy3035/pcc-net(论文尚未发表,因此暂未公开源码)
7. q&a
q1:能否提供python3环境下的代码?a:会,但现在时机不成熟。原因是tensorboard暂时还不支持python3.7,加之人手不足,暂无开发计划。
q2:为什么在sht b上做实验?以后会不会对其他数据集进行验证?a:因为图像尺寸相同,便于多batch-size的训练和测试,能够最大化利用显卡,节省显卡资源和训练时间。对于其他数据集,由于自己的时间有限,也没有足够的显卡资源,暂时不会做其他数据集实验。
q3:语义分割和人群计数非常类似,能不能直接用一些分割网络呢?a:二者同属于逐像素任务,前者为逐像素分类,后者为逐像素回归。根据我的实验,某些分割网络直接修改最后一层为回归层后,其效果与backbone相比,提升非常有限。甚至性能会有所下降。深层问题暂时还没有仔细思考。不过据我所知,有人对此问题已经做了研究,大家耐心等待即可。
q4:正确的训练、验证、测试流程应该是怎样的?a:严格意义上,所有数据集应该都包含以上三种数据(如果没有验证集,则应该从训练集中随机选择一部分)。在本项目中,为了能够确保所有实验结果可以复现,我们直接将测试集当做验证集来监控训练过程。
q5:部分模型会在pytorch1.0下报上采样函数f.upsample的警告信息。a:该警告不影响训练。为了兼容0.4版本,我们依然采用f.upsample方法来对tensor进行放大尺寸的操作。
医疗行业中广泛应用的村田制作所的引线型NTC系列产品
瓴盛科技推出首款基于三星11纳米工艺制程的AIOT芯片JA310
电流互感器变比有哪些?型号汇总
建立时间和保持时间(setup time 和 hold time)
iPhone 12全系四款产品入网工信部,产品信息首次确认
代码+实验分析,助你全面理解C3F
5G在商用部署、技术和应用创新方面有哪些新特点?
基于里德堡原子临界增强的高灵敏微波传感
升压芯片FP5207在拉杆音箱中的应用
掌阅iReaderSmart超级智能本使用体验 带给我们的不仅仅是书写和阅读的乐趣
网络安全技术的基础设施需要国际之间的互相信任
MIT技术评论:2014年十大科技突破
开关电源芯片U6513全系列大盘点
小米推出Yeelight智能LED灯丝灯 售价129元
iPad商标权之争最新进展:商家接到iPad下架令,多地仍在售
选择工业相机的10个要点
小米6即将发布:双摄像头+256G存储,多色版本齐上阵!能否打一场漂亮的翻身仗?
怎么区分物理中定律、定理与定则?
如何考虑电路设计的元件容差
BACnet I/O模块:水利环境监测全自动控制系统组件之一