導讀:52CV曾經報導多篇擁擠人群計數相關的技術,比如最近的:CVPR 2019 | 西北工業大學開源擁擠人群資料集生成工具,大幅提升演算法精度視訊監控的普及,需求推動技術的快速進步。
本文為首個PyTorch人群計數框架C3F開發者投稿,詳細介紹了該框架的方方面面,歡迎大家參考。
開源地址:
https://github.com/gjy3035/C-3-Framework
近兩年,有關人群計數的文章呈現出爆炸式增長。然而,人群計數不像其他任務(目標檢測、語義分割等)有著簡潔/易開發的開原始碼框架,大大降低了我們對於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,我們通過實驗發現,對於密度圖乘以一個較大的放大因子,可以使網路更快的收斂,甚至取得更低的估計誤差。
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上直接達到了現有SO他的水平。據我們所知,截止目前(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進行放大尺寸的操作。
參考文獻
[1] H. Idrees, I. Saleemi, C. Seibert, and M. Shah. Multi-source multi-scale counting in extremely dense crowd images. In CVPR, 2013.
[2] Y. Zhang, D. Zhou, S. Chen, S. Gao, and Y. Ma. Single image crowd counting via multi-column convolutional neural network. In CVPR, 2016.
[3] C. Zhang, K. Kang, H. Li, X. Wang, R. Xie, and X. Yang. Data-driven crowd understanding: a baseline for a largescale crowd dataset. IEEE T-MM, 2016.
[4] H. Idrees, M. Tayyab, K. Athrey, D. Zhang, S. Al-Maadeed, N. Rajpoot, and M. Shah. Composition loss for counting, density map estimation and localization in dense crowds. In ECCV, 2018.
[5] Q. Wang, J. Gao, W. Lin, and Y. Yuan. Learning from synthetic data for crowd counting in the wild. In CVPR, 2019.
[6] Y. Li, X. Zhang, and D. Chen. Csrnet: Dilated convolutional neural networks for understanding the highly congested scenes. In CVPR, 2018.
[7] A. Krizhevsky, I. Sutskever, and G. Hinton. Imagenet classification with deep convolutional neural networks. In NIPS, 2012.
[8] K. Simonyan and A. Zisserman. Very deep convolutional networks for large-scale image recognition. In ICLR, 2015.
[9] K. He, X. Zhang, S. Ren, and J. Sun. Deep residual learning for image recognition. In CVPR, 2016.
[10] M. Shi, Z. Yang, C. Xu, and Q. Chen. Revisiting Perspective Information for Efficient Crowd Counting. In CVPR, 2019.
[11] A. B. Chan, Z.-S. J. Liang, and N. Vasconcelos. Privacy preserving crowd monitoring: Counting people without people models or tracking. In CVPR, 2008.
[12] K. Chen, C. C. Loy, S. Gong, and T. Xiang. Feature mining for localised crowd counting. In BMVC, 2012.
[13] V. A. Sindagi and V. M. Patel. Cnn-based cascaded multitask learning of high-level prior and density estimation for crowd counting. In AVSS, 2017.
[14] X. Cao, Z. Wang, Y. Zhao, and F. Su. Scale aggregation network for accurate and efficient crowd counting. In ECCV, 2018.
開源地址:
https://github.com/gjy3035/C-3-Framework