神經(jīng)網(wǎng)絡(luò)目標計數(shù)概述:通過Faster R-CNN實現(xiàn)當前最佳的目標計數(shù)
在機器學(xué)習(xí)中,精確地計數(shù)給定圖像或視頻幀中的目標實例是很困難的一個問題。很多解決方案被發(fā)明出來用以計數(shù)行人、汽車和其他目標,但是無一堪稱***。當然,我們正在討論的是圖像處理,所以神經(jīng)網(wǎng)絡(luò)不失為解決這一問題的好辦法。
下面,本文將對神經(jīng)網(wǎng)絡(luò)目標計數(shù)領(lǐng)域的不同方法、一般問題、挑戰(zhàn)及***解決方案的作一個總體描述。文末,現(xiàn)有的 Faster R-CNN 網(wǎng)絡(luò)模型作為概念證明將被用于計數(shù)給定視頻中街道上的目標。
挑戰(zhàn)
找到該問題的合適方案取決于很多因素。除了神經(jīng)網(wǎng)絡(luò)圖像處理面臨的共同挑戰(zhàn)之外(比如訓(xùn)練數(shù)據(jù)的大小、質(zhì)量等),目標計數(shù)問題還有其特殊挑戰(zhàn):
- 計數(shù)目標的類型
- 重疊
- 透視
- 檢測到的目標的最小尺寸
- 訓(xùn)練和測試速度
這種被采用以計數(shù)高速公路上的汽車或者體育館前的擁擠人群的方法(其中大多數(shù)目標相互重疊,透視使得遠距離中存在很小的目標),將大不同于家庭照片中的目標計數(shù)方法。同樣,這一在單張照片上計數(shù)目標的方法也不同于在視頻中實時計數(shù)目標的方法。
簡單的需求,簡單的方案
在本文中我將嘗試使用樣本視頻(其中多個目標同時可見,但并不過于擁擠)解決街道上的目標計數(shù)問題。為了處理擁擠場景或者交通堵塞情況之下的圖像從而準確地計數(shù)目標實例,我建議深研一下該領(lǐng)域內(nèi)的一篇***論文:通過深度學(xué)習(xí)實現(xiàn)無視角的目標計數(shù)(Towards perspective-free object counting with deep learning,鏈接:
http://agamenon.tsc.uah.es/Investigacion/gram/publications/eccv2016-onoro.pdf)。通過 GitHub 上的開源代碼可以重現(xiàn)這篇論文中的結(jié)果。論文中提及的諸如 CCNN 和 Hydra CNN 方法在給定的只有少數(shù)幾類目標的圖像中表現(xiàn)欠佳;因此,不得不另尋他法。機器學(xué)習(xí)中有一個被稱作 RCNN(Region based Convolutional Neural Network)的非常有趣的方法,可以識別給定圖像中的多個目標和位置。
對于概念證明工作,我將使用改良型 Faster R-CNN 的 Keras 實現(xiàn)以處理視頻文件,并用給定類的檢測目標的計數(shù)對圖像進行注釋。
快與更快
有很多方法可以把目標位置尋找和識別的任務(wù)結(jié)合起來以提升速度和準確度。多年來,我們使用了標準 RCNN 網(wǎng)絡(luò)、Fast R-CNN 乃至 Faster R-CNN 取得了長足進展,其中 Faster R-CNN 被用于解決我們的簡單計數(shù)問題。Fast RCNN 建立在以前的工作上,從而可以使用深度卷積網(wǎng)絡(luò)高效地分類目標提案(object proposal)。相較于 RCNN,F(xiàn)ast R-CNN 的多項創(chuàng)新使其提升了訓(xùn)練和測試速度以及檢測準確度。
在多級管道中(首先檢測到目標框,接著進行識別)使用 RCNN 訓(xùn)練的模型的方法相當慢,且不適用于實時處理。這一方法的主要軟肋是速度,在檢測目標時,訓(xùn)練和實際測試速度都很慢。通過著名的 VGG16,用標準 RCNN 訓(xùn)練 5000 張圖像用時 2.5 個 GPU-Day,且需要數(shù)百 GB 的存儲。測試時使用 GPU 檢測目標每張圖像用時 47s。這主要是由于在卷曲神經(jīng)網(wǎng)絡(luò)中為每一個目標提案執(zhí)行前向傳遞而不分攤計算造成的。
Fast R-CNN 通過引進單步訓(xùn)練算法(可在單個處理階段分類目標及其空間位置)改善了 RCNN,F(xiàn)ast R-CNN 中引進的提升有:
- 更高的檢測質(zhì)量
- 通過多任務(wù)損失函數(shù)實現(xiàn)單一階段的訓(xùn)練
- 訓(xùn)練可更新所有的網(wǎng)絡(luò)層
- 功能緩存(feature caching)無需磁盤存儲
Faster R-CNN 引進了與檢測網(wǎng)絡(luò)共享全圖像(full-image)卷積功能的 RPN(Region Proposal Network,區(qū)域提案網(wǎng)絡(luò)),使得區(qū)域提案幾乎沒有成本。這一方案的 RPN 組件告知統(tǒng)一網(wǎng)絡(luò)檢測哪里。對于同一個 VGG-16 模型,F(xiàn)aster R-CNN 在 GPU 上的幀率為 5 fps,取得了當前***的檢測準確度。RPN 是一種全卷積網(wǎng)絡(luò),可以專門為生成檢測提案的任務(wù)進行端到端訓(xùn)練,旨在高效地預(yù)測縱橫比和范圍寬廣的預(yù)測區(qū)域提案。
上年,Pinterest 使用 Faster R-CNN 獲得了網(wǎng)站視覺搜索能力。下面,我們選擇了在被描述的 PoC 樣本視頻中檢測和計數(shù)目標實例。
概念證明
為了解決問題,我們將在一個支持 GPU 的 AWS 實例上使用上述帶有 Keras 的 Faster R-CNN 模型。深度學(xué)習(xí)框架不止一個,且彼此之間競爭激烈,這使我們處在了有利位置,可以下載最滿足我們需求和框架選擇的預(yù)訓(xùn)練模型。當然你也可以使用提供的訓(xùn)練 python 腳本自己訓(xùn)練模型,只要記住這可能花費很多天。
Faster R-CNN 已存在多個實現(xiàn),包括 Caffe、TensorFlow 等等。我們將在后端使用支持 TensorFlow 的 Keras(v.2.0.3),作為原始 Keras Fast R-CNN 實現(xiàn)的分叉的代碼可在 GitHub(鏈接:https://github.com/softberries/keras-frcnn)上獲取。
用于測試網(wǎng)絡(luò)的腳本被修改了,從而它可以處理視頻文件,并用合適的數(shù)據(jù)為被檢測的目標(帶有概率性)注釋每一幀以及被計數(shù)目標的摘要。在處理幀時,我也正使用 opencv 沉重地處理視頻和已訓(xùn)練的模型。有一些處理視頻的實用方法,比如:
- def convert_to_images():
- cam = cv2.VideoCapture(input_video_file)
- counter = 0
- while True:
- flag, frame = cam.read()
- if flag:
- cv2.imwrite(os.path.join(img_path, str(counter) + '.jpg'),frame)
- countercounter = counter + 1
- else:
- break
- if cv2.waitKey(1) == 27:
- break
- # press esc to quit
- cv2.destroyAllWindows()
并從處理的幀中保存視頻:
- def save_to_video():
- list_files = sorted(get_file_names(output_path), key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)])
- img0 = cv2.imread(os.path.join(output_path,'0.jpg'))
- height , width , layers = img0.shape
- # fourcc = cv2.cv.CV_FOURCC(*'mp4v')
- fourcc = cv2.VideoWriter_fourcc(*'mp4v')
- #fourcc = cv2.cv.CV_FOURCC(*'XVID')
- videowriter = cv2.VideoWriter(output_video_file,fourcc, frame_rate, (width,height))
- for f in list_files:
- print("saving..." + f)
- img = cv2.imread(os.path.join(output_path, f))
- videowriter.write(img)
- videowriter.release()
盡管目標檢測發(fā)生在測試中,我們創(chuàng)建了帶有被檢測目標類別和數(shù)字 1 的元組列表,其稍后將被減少以為特定目標類別計數(shù)發(fā)生的次數(shù):
- for jk in range(new_boxes.shape[0]):
- (x1, y1, x2, y2) = new_boxes[jk,:]
- cv2.rectangle(img_scaled,(x1, y1), (x2, y2), class_to_color[key],2)
- textLabel = '{}: {}'.format(key,int(100*new_probs[jk]))
- all_dets.append((key,100*new_probs[jk]))
- all_objects.append((key, 1))
以及減少的方法:
- def accumulate(l):
- it = itertools.groupby(l, operator.itemgetter(0))
- for key, subiter in it:
- yield key, sum(item[1] for item in subiter)
腳本參數(shù)具備相當?shù)淖晕医忉屝裕?/p>
- "—input_file",輸入視頻文件的路徑。
- "—output_file",輸出視頻文件的路徑。
- "—input_dir",存儲已處理幀的輸入工作目錄的路徑。
- "—output_dir",存儲已注釋處理幀的輸出工作目錄的路徑。
- "--frame_rate",在構(gòu)建視頻輸出時使用的幀率
總結(jié)
區(qū)域深度卷積網(wǎng)絡(luò)是令人興奮的工具,可以幫助軟件開發(fā)者解決很多有趣的問題。本文中展示的方案只是個開始。通過為特定數(shù)據(jù)集調(diào)試網(wǎng)絡(luò)或者從其他模型中使用遷移學(xué)習(xí),我們就可以在檢測目標時獲得高準確度和速度。
鏈接與下載
- PoC 項目 github 地址:https://github.com/softberries/keras-frcnn
- Keras 預(yù)訓(xùn)練模型:https://s3-eu-west-1.amazonaws.com/softwaremill-public/model_frcnn.hdf5
- Fast R-CNN 論文:http://www.cv-foundation.org/openaccess/content_iccv_2015/papers/Girshick_Fast_R-CNN_ICCV_2015_paper.pdf
- Faster R-CNN 論文:https://arxiv.org/pdf/1506.01497.pdf
- 本文中使用的視頻樣本:https://www.videezy.com/
原文:https://softwaremill.com/counting-objects-with-faster-rcnn/
【本文是51CTO專欄機構(gòu)“機器之心”的原創(chuàng)譯文,微信公眾號“機器之心( id: almosthuman2014)”】