神經網路目標計數概述:通過Faster R-CNN實現當前最佳的目標計數

黃小天發表於2017-06-09

在機器學習中,精確地計數給定影象或視訊幀中的目標例項是很困難的一個問題。很多解決方案被髮明出來用以計數行人、汽車和其他目標,但是無一堪稱完美。當然,我們正在討論的是影象處理,所以神經網路不失為解決這一問題的好辦法。

下面,本文將對神經網路目標計數領域的不同方法、一般問題、挑戰及最新解決方案的作一個總體描述。文末,現有的 Faster R-CNN 網路模型作為概念證明將被用於計數給定視訊中街道上的目標。

挑戰

神經網路目標計數概述:通過Faster R-CNN實現當前最佳的目標計數

找到該問題的合適方案取決於很多因素。除了神經網路影象處理面臨的共同挑戰之外(比如訓練資料的大小、質量等),目標計數問題還有其特殊挑戰:

  • 計數目標的型別
  • 重疊
  • 透視
  • 檢測到的目標的最小尺寸
  • 訓練和測試速度

這種被採用以計數高速公路上的汽車或者體育館前的擁擠人群的方法(其中大多數目標相互重疊,透視使得遠距離中存在很小的目標),將大不同於家庭照片中的目標計數方法。同樣,這一在單張照片上計數目標的方法也不同於在視訊中實時計數目標的方法。

簡單的需求,簡單的方案

在本文中我將嘗試使用樣本視訊(其中多個目標同時可見,但並不過於擁擠)解決街道上的目標計數問題。為了處理擁擠場景或者交通堵塞情況之下的影象從而準確地計數目標例項,我建議深研一下該領域內的一篇最新論文:通過深度學習實現無視角的目標計數(Towards perspective-free object counting with deep learning,連結:http://agamenon.tsc.uah.es/Investigacion/gram/publications/eccv2016-onoro.pdf)。通過 GitHub 上的開原始碼可以重現這篇論文中的結果。論文中提及的諸如 CCNN 和 Hydra CNN 方法在給定的只有少數幾類目標的影象中表現欠佳;因此,不得不另尋他法。機器學習中有一個被稱作 RCNN(Region based Convolutional Neural Network)的非常有趣的方法,可以識別給定影象中的多個目標和位置。

對於概念證明工作,我將使用改良型 Faster R-CNN 的 Keras 實現以處理視訊檔案,並用給定類的檢測目標的計數對影象進行註釋。

快與更快

有很多方法可以把目標位置尋找和識別的任務結合起來以提升速度和準確度。多年來,我們使用了標準 RCNN 網路、Fast R-CNN 乃至 Faster R-CNN 取得了長足進展,其中 Faster R-CNN 被用於解決我們的簡單計數問題。Fast RCNN 建立在以前的工作上,從而可以使用深度卷積網路高效地分類目標提案(object proposal)。相較於 RCNN,Fast R-CNN 的多項創新使其提升了訓練和測試速度以及檢測準確度。

在多級管道中(首先檢測到目標框,接著進行識別)使用 RCNN 訓練的模型的方法相當慢,且不適用於實時處理。這一方法的主要軟肋是速度,在檢測目標時,訓練和實際測試速度都很慢。通過著名的 VGG16,用標準 RCNN 訓練 5000 張影象用時 2.5 個 GPU-Day,且需要數百 GB 的儲存。測試時使用 GPU 檢測目標每張影象用時 47s。這主要是由於在捲曲神經網路中為每一個目標提案執行前向傳遞而不分攤計算造成的。

Fast R-CNN 通過引進單步訓練演算法(可在單個處理階段分類目標及其空間位置)改善了 RCNN,Fast R-CNN 中引進的提升有:

  • 更高的檢測質量
  • 通過多工損失函式實現單一階段的訓練
  • 訓練可更新所有的網路層
  • 功能快取(feature caching)無需磁碟儲存

Faster R-CNN 引進了與檢測網路共享全影象(full-image)卷積功能的 RPN(Region Proposal Network,區域提案網路),使得區域提案几乎沒有成本。這一方案的 RPN 元件告知統一網路檢測哪裡。對於同一個 VGG-16 模型,Faster R-CNN 在 GPU 上的幀率為 5 fps,取得了當前最佳的檢測準確度。RPN 是一種全卷積網路,可以專門為生成檢測提案的任務進行端到端訓練,旨在高效地預測縱橫比和範圍寬廣的預測區域提案。

上年,Pinterest 使用 Faster R-CNN 獲得了網站視覺搜尋能力。下面,我們選擇了在被描述的 PoC 樣本視訊中檢測和計數目標例項。

概念證明

為了解決問題,我們將在一個支援 GPU 的 AWS 例項上使用上述帶有 Keras 的 Faster R-CNN 模型。深度學習框架不止一個,且彼此之間競爭激烈,這使我們處在了有利位置,可以下載最滿足我們需求和框架選擇的預訓練模型。當然你也可以使用提供的訓練 python 指令碼自己訓練模型,只要記住這可能花費很多天。

Faster R-CNN 已存在多個實現,包括 Caffe、TensorFlow 等等。我們將在後端使用支援 TensorFlow 的 Keras(v.2.0.3),作為原始 Keras Fast R-CNN 實現的分叉的程式碼可在 GitHub(連結:https://github.com/softberries/keras-frcnn)上獲取。

用於測試網路的指令碼被修改了,從而它可以處理視訊檔案,並用合適的資料為被檢測的目標(帶有概率性)註釋每一幀以及被計數目標的摘要。在處理幀時,我也正使用 opencv 沉重地處理視訊和已訓練的模型。有一些處理視訊的實用方法,比如:

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)

 counter = 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()

儘管目標檢測發生在測試中,我們建立了帶有被檢測目標類別和數字 1 的元組列表,其稍後將被減少以為特定目標類別計數發生的次數:

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)

指令碼引數具備相當的自我解釋性:

  • "—input_file",輸入視訊檔案的路徑。
  • "—output_file",輸出視訊檔案的路徑。
  • "—input_dir",儲存已處理幀的輸入工作目錄的路徑。
  • "—output_dir",儲存已註釋處理幀的輸出工作目錄的路徑。
  • "--frame_rate",在構建視訊輸出時使用的幀率

被指令碼處理的幾個例項:

總結

區域深度卷積網路是令人興奮的工具,可以幫助軟體開發者解決很多有趣的問題。本文中展示的方案只是個開始。通過為特定資料集除錯網路或者從其他模型中使用遷移學習,我們就可以在檢測目標時獲得高準確度和速度。

連結與下載

  • PoC 專案 github 地址:https://github.com/softberries/keras-frcnn
  • Keras 預訓練模型: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/神經網路目標計數概述:通過Faster R-CNN實現當前最佳的目標計數


原文連結:https://softwaremill.com/counting-objects-with-faster-rcnn/

相關文章