用 TensorFlow 追蹤千年隼號
TensorFlow 是個機器學習的開源庫。這篇文章中作者將用 TensorFlow 來訓練識別自定義模型,并給出了詳細的過程(星戰迷 = =|| )。
在寫這篇博客時,許多大型技術公司(如 IBM,Google,Microsoft,Amazon)都有簡單易用的視覺識別 API。一些小點的公司同樣提供了類似的服務,比如 Clarifai 。但它們都沒有提供對象識別。
下面的圖片都使用了相同的 Watson 視覺識別 默認分類器標簽。第一個已經通過對象識別模型處理過了。
對象識別可以遠遠超過視覺識別本身。但如果你想要對象識別,你就要親自動手。
取決于你的用例,你或許不需要自定義對象識別模型。 TensorFlow 的對象識別 API 提供了幾種不同速度和精度的模型,它們給予 COCO 數據集 。
為了讓你方便,我放上了一個 COCO 模型可以識別的完整對象列表:
如果你想要識別一些標志或者不在上面這個表的東西,你需要構建自己的對象識別器。我想要可以識別千年隼號和一些鈦戰機。這顯然是個極其重要的用例,因為你永遠不知道……
給你的圖片作注解
訓練自己的模型要大量工夫。現在,你可能會想,“哇,哇,哇!我不想要費大量工夫!”如果是這樣,你可以看看我的關于使用現有模型的 其他文章 。這是個更平滑的方向。
你需要收集大量的圖片,并且寫上注解。注解包括聲明對象的坐標以及關聯的標簽。比如一張有兩架鈦戰機的圖片,注解看起來像這樣;
<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。還要費很多工夫,相信我。我用了三到四個小時不間斷的工作才把整個數據集注解完。
如果你有錢,你可以讓別人來做,比如實習生。你可以用像 Mechanical Turk 這樣的資源。如果你是個窮大學生像我這樣的,或者,以單調的工作為樂子的人,你還得自己來。
當創造注解時,如果你不想寫自己的轉換腳本,確保它們導出為 PASCAL VOC 格式。這是我和許多其他人用的格式,你可以“偷”我上面的腳本(其實是從別人那偷的)。
在開始運行為 TensorFlow 準備數據的腳本之前,我們需要做一些設置。
克隆倉庫
從克隆我的 倉庫 開始。
目錄結構看起來是這樣的:
models |-- annotations | |-- label_map.pbtxt | |-- trainval.txt | `-- xmls | |-- 1.xml | |-- 2.xml | |-- 3.xml | `-- ... |-- images | |-- 1.jpg | |-- 2.jpg | |-- 3.jpg | `-- ... |-- 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.ckpt 文件移動到我們庫的根目錄。
你應該會看到一個 faster_rcnn_resnet101.config 文件。它和 faster_rcnn_resnet101_coco 模型一起工作。如果你使用其他模型,你可以從 這里 找到對應的配置文件。
準備訓練
運行下面的腳本,然后就能開始訓練了!
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: ...
這玩意兒要跑多久?
我在視頻中使用的模型運行大概要運行 22,000 步。
等等,什么?!
我用的是 MacBook Pro,如果你運行的設備和我的差不多,我假設每一步你大約需要花 15 秒,那么得到一個像樣的模型需要不間斷的運行三到四天。
好吧,這太傻了。我沒有這么多時間做這個:dizzy_face:
PowerAI 來救場了!
PowerAI
PowerAI 讓我們在 IBM Power System 中用 P100 GPUs 快速地訓練我們的模型!
訓練 10,000 步只需要大約一個小時。但是,這僅僅用了一個 GPU。PowerAI 中真正的力量來源于分布式地使用幾百個 GPU 進行深度學習的能力,效率可以達到 95%。
有了 PowerAI 的幫助,IBM 創造了一項圖片識別紀錄:在 7 小時內識別準確率達到 33.8%。超過了之前 Microsoft 的紀錄 —— 10 天 29.9 %的準確率。
超快快快!
因為我沒有訓練幾百萬張圖片,我當然不需要這種資源。一個 GPU 夠了。
創建 Nimbix 賬戶
Nimbix 給開發者提供了一個 10 小時免費體驗 PowerAI 平臺的體驗賬戶。你可以在 這里 注冊。
提示 :這個過程不是自動的,審核通過要 24 小時。
一旦審核通過,你就會收到一個創建賬戶的確認郵件。它會要你提供促銷代碼,留空白就行了。
你現在可以在 這里登錄 了。
部署 PowerAI 筆記本應用
從搜索 PowerAI Notebooks 開始:
點中它,然后選擇 TensorFlow。
選擇機器類型為:32 線程 POWER8,128G RAM, 1 * P100 GPU w/NVLink(np8g1)。
開始后,下面的工作臺就會出現。當服務器狀態變成運行時,服務器就準備好了。
點擊 click to show 得到密碼。然后點擊 click here to connect 啟動筆記本。
登錄使用 nimbix 的賬戶和密碼。
開始訓練
通過點擊 New 下拉菜單,選擇 Terminal 打開一個新的終端。
你應該熟悉這個界面了:
提示:終端在 Safari 上可能有問題。
訓練的步驟和我們在本地運行的時候相同。如果你使用我的訓練數據,你可以克隆我的倉庫:
git clone https://github.com/bourdakos1/Custom-Object-Detection.git
然后去到這個目錄:
cd Custom-Object-Detection
運行下面的片段,下載 faster_rcnn_resnet101_coco 模型:
wget http://storage.googleapis.com/download.tensorflow.org/models/object_detection/faster_rcnn_resnet101_coco_11_06_2017.tar.gz tar -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 步時趨于穩定。在 20,000 步時達到頂峰。我甚至讓它訓練到了 200,000 步,但是沒有任何增加。
我建議在每 5000 步左右下載你的模型,評估一下它,要確保你在正確的道路上。
點擊左上角的 Jupyter 標志,然后,去到 Custom-Object-Detection/train。
下載所有的帶有最大數字的 model.ckpt 文件。
model.ckpt-STEP_NUMBER.data-00000-of-00001
model.ckpt-STEP_NUMBER.index
model.ckpt-STEP_NUMBER.meta
提示: 你一次只能下載一個。
提示:確保在完成后點擊紅色電源按鈕,否則計時將不會停止。
導出推理圖
想要在我們的代碼中使用模型,我們需要把檢查點文件(model.ckpt-STEP_NUMBER.*)轉換成凍結 推理圖 。
把剛剛下載的檢查點文件移動到之前我們使用的庫的根目錄。
然后運行命令:
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
它會找到 output_inference_graph/frozen_inference_graph.pb 文件,用你的對象識別模型去識別 test_images 目錄下的所有圖片,然后把結果輸出到 output/test_images 目錄。
結果
以下是我們在“星球大戰:原力覺醒”這個片段中的所有幀上運行模型時得到的結果。
推薦閱讀: