前言

国庆期间读了CSRNet这篇论文,本文不是对论文进行翻译,只是对文章进行简略的总结,并对部分内容写出我的理解,主要是将自己阅读和复现过程中遇到的些问题在这里记录一下,希望可以帮助到有需要的人,同时,本文的内容均为个人理解,如若有误,欢迎在评论区或者邮件指正。

博客不知道出了什么问题,图像上传一直出问题,所以本文的图麻烦大家自己对照原论文去查看。

论文原文: CSRNet: Dilated Convolutional Neural Networks for Understanding the Highly Congested Scenes | IEEE Conference Publication | IEEE Xplore

源代码 :leeyeehoo/CSRNet-pytorch: CSRNet: Dilated Convolutional Neural Networks for Understanding the Highly Congested Scenes (github.com)

环境调试

环境调试可以参考文章[CSRNet] CSRNet-pytorch 复现过程记录-CSDN博客,这篇文章介绍的很详细,我就不在这里赘述了,可以参考这篇文章的过程完成调试。

不想调试的也可以去看我调试之后的代码,同时代码中还加上了我自己对代码理解的中文注释。PaperRecurrent/CSRNet at main · LengNian/PaperRecurrent (github.com)

读论文

这篇文章提出一个可以应用到高度拥挤场景的卷积神经网络CSRNet。CSRNet是由两部分组成,前置的网络就是有卷积层,池化层等组成,后置网络则是由空洞卷积层组成。值得注意的是,前置的网络,作者直接使用了VGG16的网络结构。

在这篇论文中,作者通过对MCNN进行测试,如图所示,发现MCNN的三列在不同样本上错误率几乎相同,所以不排除是在同一个地方犯错的可能,这可能说明这三列学习到的特征是几乎相同的,这似乎就违背了作者设计MCNN的初衷,也就是利用有不同感受野的三列去学习不同尺度的特征。

Fig 1(对应论文中的Figure 2)

如果一味的追求网络深度去堆积卷积层和池化层会使图像的尺寸变小,同时也会影响生成密度图的质量,哪么怎样可以不压缩图像大小呢?作者提到,如果使用转置卷积会增加模型的复杂度,并且速度慢,在这里并不合适,而使用空洞卷积既可以扩大感受野,也不会增加参数量和计算量。(比如,使用卷积核大小为k×k的空洞卷积,其尺寸会被放大为k+(k-1)(r-1),r为步长)。

作者通过一系列操作验证了空洞卷积比转置卷积更有效,即进行两组实验,一组是使用空洞卷积,另一组是使用卷积+池化+转置卷积,因为第二组的尺寸会变小,为了保持和第一组的大小保持一致,作者对图像进行上采样,对比结果如图所示。很明显可以看到空洞卷积的效果更好。

Fig 2(对应论文中的Figure 4)

作者提出四种不同的CSRNet架构,通过实验最后使用了B结构。

Fig 3(对应论文中的Table 3)

此外,作者还在论文中提到了数据增强,会生成9张图像,其中前4张是不重叠的原图像的四分之一的图像,后五张是随机裁剪。

源码理解

感觉这篇文章的代码阅读起来相比MCNN容易一些。

在train.py中有这么一段代码

save_checkpoint({
    'epoch': epoch + 1,
    'arch': args.pre,
    'state_dict': model.state_dict(),
    'best_prec1': best_prec1,
    'optimizer' : optimizer.state_dict(),
}, is_best,args.task)

这里提到了保存优化器的状态,我以前没有注意过这点,上网查阅以后,这通常是一种预防措施,并不会占用太多的存储空间,而且处理起来也相对比较简单。

在val.py中对图像进行标准化,作者有这么一段代码

img[0,:,:]=img[0,:,:]-92.8207477031
img[1,:,:]=img[1,:,:]-95.2757037428
img[2,:,:]=img[2,:,:]-104.877445883

刚开始减这么一串数字我不太理解,后来在github中看到有人说这些数字可能是每个通道的均值。(但是每幅图的均值应该是不一样的吧,所以这里还是不太明白,如果我说的有错误,欢迎大家给我指正。)

论文中提到裁剪四分之一的图像,在dataset.py中实现listDataset中提到

if train:
	root = root *4
random.shuffle(root)

通过对路径*4,并打乱,完成四个不同四分之一图像的裁剪。

在image.py中

if False:
    crop_size = (img.size[0]/2,img.size[1]/2)
    if random.randint(0,9)<= -1:

我认为这里的False应该改为train,结合其它地方也可以得出,这里是标记是否要开启数据增强。

在Shanghai Tech中,数据集的作者给出了.jpg和.mat文件,然后CSRNet的作者在make_dataset.ipynb文件中利用.mat文件生成了.h5文件,.h5文件在image.py中用于作为标签使用。

参考文献

[CSRNet] CSRNet-pytorch 复现过程记录-CSDN博客

CSRNet浅析_csrnet代码解读-CSDN博客

深度学习:人群密度估计CSRNet(cvpr 2018)论文源代码详解_data.py train.py test.py utils.py-CSDN博客