自定義物件檢測問題:使用TensorFlow追蹤星球大戰中的千年隼號宇宙飛船
大多數的大型科技公司(如IBM,谷歌,微軟,亞馬遜)都有易於使用的視覺識別API。一些規模較小的公司也提供類似的產品,如Clarifai。但沒有公司能夠提供物件檢測。
千年隼號宇宙飛船的檢測
以下圖片都使用Watson視覺識別預設分類器被作了相同的標記。第一張圖,是先通過一個物件檢測模型執行的。
- Watson視覺識別預設分類器地址:https://www.ibm.com/watson/services/visual-recognition/
物件檢測遠遠優於視覺識別。但如果你想要進行物件檢測,你就得動手去操作。
根據你的用例,你可能不需要一個自定義物件檢測模型。TensorFlow的物件檢測API提供了幾種不同速度和精度的模型,這些模型都是基於COCO資料集的。
- COCO資料集地址:http://cocodataset.org/#home
為了方便起見,我整理了一份可被COCO模型檢測到的物件清單:
如果你想檢測的物件不在這份名單上,那麼你就必須構建你自己的自定義物件探測器。我希望能夠檢測到電影“星球大戰”中的千年隼號宇宙飛船和一些TIE戰鬥機。這篇文章將會實現我的這一想法。
給圖片註釋 你需要收集很多圖片和註釋。註釋包括指定物件的座標和對應的標籤。對於一張有兩個TIE戰鬥機的影象,註釋可能看起來像這樣:
<annotation> <folder>images</folder> <filename>image1.jpg</filename> <size> <width>1000</width> <height>563</height> </size> <segmented>0</segmented> <object> <name>Tie Fighter</name> <bndbox> <xmin>112</xmin> <ymin>281</ymin> <xmax>122</xmax> <ymax>291</ymax> </bndbox> </object> <object> <name>Tie Fighter</name> <bndbox> <xmin>87</xmin> <ymin>260</ymin> <xmax>95</xmax> <ymax>268</ymax> </bndbox> </object> </annotation>
對於我的“星球大戰”的模型,我收集了308張圖片,每張圖片包括兩個或三個物件。我建議每個物件找200 – 300個例子。你可能會想,“哇,只通過幾百張圖片,我就能為每張圖片寫一堆XML(可擴充套件標記語言)嗎?”
當然不是!現在的註釋工具有很多,如labelImg和RectLabel。我用的是RectLabel,但它只適用於macOS系統。我花了大約3、4個小時的時間不間斷地將我整個資料集做了註釋。
當建立註釋時,如果你不想寫自己的轉換指令碼,那麼確保它們以PASCAL VOC格式(這是我和許多其他人都在使用的格式)匯出。
在執行指令碼為TensorFlow準備資料之前,我們需要做一些設定。
- 本專案Repo地址:https://github.com/bourdakos1/Custom-Object-Detection
目標結構:
我已經包含了我的訓練資料,因此你需要立即執行它。但是如果你想用你自己的資料建立一個模型,你需要將你的訓練影象新增到images中,新增你的XML註釋到annotations/xmls中,更新trainval.txt和label_map.pbtxt。
trainval.txt是一個檔名的列表,它允許我們找到並且關聯JPG和XML檔案。下面的trainval.txt列表讓我們可以找到abc.jpg
,abc.xml
, 123.jpg
, 123.xml
, xyz.jpg
和 xyz.xml
:
abc
123
xyz
注意:確保你的JPG和XML檔名匹配,去掉字尾名。
label_map.pbtxt是我們我們要檢測的物件列表,它看起來應該是這樣的:
item {
id: 1
name: 'Millennium Falcon'
}
item {
id: 2
name: 'Tie Fighter'
}
執行指令碼 首先, 安裝Python和pip, 安裝指令碼要求:
pip install -r requirements.txt
將models
和 models/slim
新增到你的PYTHONPATH
:
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
- 重要提示:每次執行你必須開啟終端,或新增到你的~/.bashrc檔案中。
執行指令碼:
python object_detection/create_tf_record.py
指令碼執行完成後,你將以一個train.record和val.record檔案告終,這兩個檔案將訓練我們的模型。
下載一個基本模型 從頭開始訓練物件探測器需要耗費幾天的時間,即使你使用了多個GPU。為了加快訓練速度,我們將一個物件檢測器訓練在一個不同的資料集,並且重新使用它的一些引數來初始化我們的新模型。
你可以從model zoo下載一個模型。每個模型有不同精度和速度。我使用了faster_rcnn_resnet101_coco。
model zoo地址:https://github.com/bourdakos1/Custom-Object-Detection/blob/master/ object_detection/g3doc/detection_model_zoo.md
提取並將所有model.ckpt檔案移到我的Repo中的根目錄。
你應該會看到一個名為faster_rcnn_resnet101.config的檔案。它與faster_rcnn_resnet101_coco模型一起工作。如果你使用另一個模型,你可以在github裡找到一個相應的配置檔案。
Github地址:https://github.com/bourdakos1/Custom-Object-Detection/tree/master/
object_detection/samples/configs
準備訓練 執行以下指令碼,它就可以開始訓練了!
python object_detection/train.py
--logtostderr
--train_dir=train
--pipeline_config_path=faster_rcnn_resnet101.config
注意:pipeline_config_path換成你的配置檔案的位置。
global step 1:
global step 2:
global step 3:
global step 4:
...
很好,它開始工作了! 10分鐘後…
global step 41:
global step 42:
global step 43:
global step 44:
...
再過一會兒
global step 71:
global step 72:
global step 73:
global step 74:
...
這個東西應該執行多長時間? 我使用MacBook Pro。如果你也在類似的計算機上執行的話,我假設你一個步長需要花費15秒左右的時間。按照這個速度需要大約三到四天的不間斷執行才能得到一個合適的模型。
因此我們需要PowerAI的救援!
PowerAI地址:https://www.ibm.com/bs-en/marketplace/deep-learning-platform
PowerAI PowerAI讓我們在IBM Power Systems上使用P100 GPU快速地訓練我們的模型!10000個步長只花了大約一個小時的訓練時間。然而,這還只是用了一個GPU。在PowerAI的幫助下,IBM創造了一個新的影象識別的記錄,花費7小時達到33.8%的準確率。它超過了以前的行業紀錄-微軟在10天內創造的29.9%的準確率。
建立一個Nimbix帳戶 Nimbix為開發人員提供了一個試用帳戶,他們在PowerAI平臺上有十個小時的免費處理時間。
註冊地址:https://www.nimbix.net/cognitive-journey/
注意:這個申請過程不是自動的,所以可能需要24個小時的稽核時間。一旦批准,你應該會收到一封電子郵件和建立你的帳戶的說明。
登入地址:https://mc.jarvice.com/
部署PowerAI Notebooks應用 首先搜尋PowerAI Notebooks。
點選它,然後選擇TensorFlow。
選擇機器型別:32 thread POWER8, 128GB RAM, 1x P100 GPU w/NVLink (np8g1)。
一旦啟動,以下儀表盤面板將顯示出來。當伺服器狀態轉向處理(processing),伺服器就可以訪問。
通過點選(click to show)獲取密碼。
然後,點選Click here to connect連線啟動Notebook。
使用使用者名稱nimbix和之前提供的密碼登入。
開始訓練 通過點選New下拉並選擇Terminal得到一個新的終端視窗。
你會看到一個熟悉的內容:
注意:終端可能不能在Safari上工作。
當我們本地執行時,這個訓練的步驟是一樣的。如果你使用我的訓練資料,那麼你可以在通過複製下面這個repo執行:
git clone https://github.com/bourdakos1/Custom-Object-Detection.git
然後轉換到根目錄:
cd Custom-Object-Detection
執行這個snippet,下載我們之前下載過的預訓練的faster_rcnn_resnet101_coco模型。
wget http://storage.googleapis.com/download.tensorflow.org/models/object_detection/faster_rcnn_resnet101_coco_11_06_2017.tar.gztar -xvf faster_rcnn_resnet101_coco_11_06_2017.tar.gz
mv faster_rcnn_resnet101_coco_11_06_2017/model.ckpt.* .
然後我們需要再次更新我們的PYTHONPATH,因為它在一個新的終端:
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
然後我們終於可以再次執行訓練命令:
python object_detection/train.py
--logtostderr
--train_dir=train
--pipeline_config_path=faster_rcnn_resnet101.config
下載你的模型 模型什麼時候可以開始工作取決於你的訓練資料。資料越多,你就需要更多的步長。我的模型需要近4500個步長。上限大約為20000個步長。
我建議每經過5000個步長就下載你的模型或者對它進行評估,以確保它能夠正確地執行。
單擊左上角的Jupyter標誌。然後,找到檔案樹(file tree)Custom-Object-Detection/train。
下載所有帶有最高的數字的model.ckpt檔案。
model.ckpt-STEP_NUMBER.data-00000-of-00001
model.ckpt-STEP_NUMBER.index
model.ckpt-STEP_NUMBER.meta
注意:你只能下載一次。
注意:完成時,一定要在你的機器上點選紅色電源按鈕。否則,計時將繼續下去。
輸出推理圖(inference graph) 在我們的程式碼中使用模型時,我們需要將檢查點檔案(model.ckpt-STEP_NUMBER。*)轉換成一個推理圖。
推理圖地址:http://deepdive.stanford.edu/inference
將剛才下載的檢查點檔案移動到你一直使用的repo裡的根資料夾中。然後執行這個命令:
python object_detection/export_inference_graph.py
--input_type image_tensor
--pipeline_config_path faster_rcnn_resnet101.config
--trained_checkpoint_prefix model.ckpt-STEP_NUMBER
--output_directory output_inference_graph
記住export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
你應該看到了一個新的output_inference_graph目錄和一個frozen_inference_graph.pb檔案。這正是我們需要的檔案。
測試模型 現在,執行以下命令:
python object_detection/object_detection_runner.py
在test_images目錄並在output/test_images目錄輸出結果的所有影象中,它將在output_inference_graph/frozen_inference_graph.pb執行你的目標檢測模型。
結果 觀看視訊:https://youtu.be/xW2hpkoaIiM