Object Detection APi物件辨識分類器實作-採用TensorFlow (CPU) 在Windows 10上
By: Qingyang Wu
Tags: Coin Detection, TensorFlow, Object Detection Api, Windows 10

在2017年6月，Google釋出了Object Detection API，該APi加速了建立Object Detection的過程，目前許多雲端服務或是深度學習的常見應用，幾乎還是停留在Image Classification，包含Google 的AutoML也還停留在Image Classification(在2019/4/10出了雲端版XD，有空來玩一下)。進一步的Object Detection雖然已經有許多許多成熟的技術，但是沒有一個較好平台來實作這個應用。

個人已經操作過這個APi一段時間，趁著這個有空的機會把他寫下來，今天就來實作Google 釋出的Object Detection API，並且是實作在Window 10上，緣由是因為該API在官方的教學文件都是實作在Linux上，但是Window 10的使用者還是非常多啊!!因此想記錄在Window 10上的實作過程。

環境設置以及測試範例執行

安裝TensorFlow-GPU， Anaconda

可能你已經有安裝TensorFlow-GPU在你的電腦上，又或是沒有的話採用CPU的版本即可，但是還是強力推薦採用GPU版本，因為訓練的速度真的快很多，但是小弟經費有限，目前這個實作採用CPU來實作。

Anaconda能確保你擁有完善的package，保證一定程度的相依完整度，但缺點也是肚子比較胖，若你是想在小型嵌入式系統，那麼還是先避免這個步驟。

設置TensorFlow 在Windows 10的資料夾目錄

從GitHub下載TensorFlow Repo.，點擊Clone或下載，接著在C碟中創造一個資料夾叫做tensorflow，然後將剛剛下載的models-master壓縮檔解壓縮在剛創建的C：\ tensorflow目錄中，並將名稱改為models。

TensorFlow提供許多Object Detection的模型(預先訓練好的一些特殊的網路架構)在model zoo。

其中包含SSD-MobileNet model，快速但是較低的精準度，還有 Faster-RCNN model，較慢但是精準度較高。個人在實作面喜歡精準度高一點的架構，因此該實作採用 Faster-RCNN-Inception-V2 model，若想實作在手機上，可以考慮採用SSD-MobileNet。

本實作為了精準度採用了與範例不同的 Faster-RCNN model，可以點連結下載。下載之後將檔案接壓縮到

C:\tensorflow\models\research\object_detection

接著下載Git Hub 的 repository

下載後進行解壓縮，將壓縮出的檔案貼到

C:\tensorflow\models\research\object_detection

下列資料夾會有該實作部分的資料，請自行刪除裡面的圖片以及各個檔案

\object_detection\images\train

\object_detection\images\test

\object_detection\images

\object_detection\training

\object_detection\inference_graph

設定Anaconda的虛擬環境

C:\> conda create -n tensorflow pip python=3.6

雖然新版的Anaconda已經將python帶到3.7，但是3.7還是有許多不穩定的地方，這邊將繼續沿用3.6

C:\> activate tensorflow

請用我們剛剛創建好的環境tensorflow

看到環境由base轉換成tensorflw就代表請用成功，接下來安裝tensorflow，這邊當然可以安裝gpu版本的，但是為了快速建置，這邊還是使用簡單的cpu版本安裝

C:\> pip install --ignore-installed --upgrade tensorflow

接著安裝其它必要packages

(tensorflow) C:\> conda install -c anaconda protobuf

(tensorflow) C:\> conda install jupyter

(tensorflow) C:\> pip install pillow

(tensorflow) C:\> pip install lxml

(tensorflow) C:\> pip install Cython

(tensorflow) C:\> pip install matplotlib

(tensorflow) C:\> pip install pandas

(tensorflow) C:\> pip install opencv-python

設置Windows 10的 PYTHONPATH

C:\tensorflow\models;

C:\tensorflow\models\research;

C:\tensorflow\models\research\slim

編譯Protobufs

Protobufs用來設置TensorFlow的模型與參數，在Anaconda Prompt下將目錄切換至\models\research，接著執行

protoc --python_out=. .\object_detection\protos\anchor_generator.proto .\object_detection\protos\argmax_matcher.proto .\object_detection\protos\bipartite_matcher.proto .\object_detection\protos\box_coder.proto .\object_detection\protos\box_predictor.proto .\object_detection\protos\eval.proto .\object_detection\protos\faster_rcnn.proto .\object_detection\protos\faster_rcnn_box_coder.proto .\object_detection\protos\grid_anchor_generator.proto .\object_detection\protos\hyperparams.proto .\object_detection\protos\image_resizer.proto .\object_detection\protos\input_reader.proto .\object_detection\protos\losses.proto .\object_detection\protos\matcher.proto .\object_detection\protos\mean_stddev_box_coder.proto .\object_detection\protos\model.proto .\object_detection\protos\optimizer.proto .\object_detection\protos\pipeline.proto .\object_detection\protos\post_processing.proto .\object_detection\protos\preprocessor.proto .\object_detection\protos\region_similarity_calculator.proto .\object_detection\protos\square_box_coder.proto .\object_detection\protos\ssd.proto .\object_detection\protos\ssd_anchor_generator.proto .\object_detection\protos\string_int_label_map.proto .\object_detection\protos\train.proto .\object_detection\protos\keypoint_box_coder.proto .\object_detection\protos\multiscale_anchor_generator.proto .\object_detection\protos\graph_rewriter.proto

若是以上執行成功，你會在 \object_detection\protos的資料夾看到 許多name_pb2.py的檔案在裡面。接著在相同的目錄執行

(tensorflow) C:\tensorflow\models\research> python setup.py build

(tensorflow) C:\tensorflow\models\research> python setup.py install

測試一下整個APi是否安裝正確

將目錄切換到research\object_detection，接著執行

(tensorflow) C:\tensorflow\models\research\object_detection> jupyter notebook object_detection_tutorial.ipynb

object_detection_tutorial.ipynb是由官方所提供的測試範例，整個環境正確安裝無誤後就可以執行這個教學檔，

執行這部分時取決於你的網路速度，整個執行完之後應該會出現狗狗的辨識結果

以上是整個環境設定以及測試範例的執行，第二個部分要說明的是如何自己訓練自己想要的物件。

建置自己的訓練物件以及辨識

收集圖片以及標籤他們

在原本的Object detection APi 現有的模型已經能夠辨識生活中常見的類別，貓、狗、車等等。但是如果是特殊的類別當然就只能自己訓練，接下來要實作的是做一個能夠辨識1元、5元、10元的物件是別分類器

先準備一堆硬幣的圖片，為了讓訓練出來的分類器有良好的適應性，這裡提醒幾個重點：

圖像中的物件盡量隨機位置

訓練的背景盡量多樣化

可以讓物件被遮擋，或是與其他東西重疊

每個類別的樣本盡量均勻出現

由於這次實作的類別不多，因此總共拍攝25硬幣圖片來訓練，訓練先確保圖像檔案不會太大。它們每個應小於200KB，其解析度不應超過720x1280。圖像越大，訓練分類器所需的時間越長。如果圖像太大，使用resizer.py腳本來減小圖像的大小。

將圖片樣本都準備好之後，將20%數量的圖片放置 \object_detection\images\test，將80%數量的圖片放置 \object_detection\images\train

標籤圖像

LabelImg是一個能夠協助標籤圖像的工具，個人覺得非常好用

LabelImg GitHub連結

LabelImg下載連結

下載以及安裝後，就可以到剛剛的\object_detection\images\train以及\object_detection\images\test目錄下進行標籤，

標籤完圖像後，接下要生成 TFRecords以便餵入 TensorFlow的訓練模型，這邊會使用 xml_to_csv.py以及 generate_tfrecord.py來產生相關數據。

首先先執行xml_to_csv.py

(tensorflow) C:\tensorflow1\models\research\object_detection> python xml_to_csv.py

執行完後就換看到 train_labels.csv 以及test_labels.csv出現在 \object_detection\images資料夾

接下來打開 generate_tfrecord.py修改裡面的內容，

該實作要辨識三種硬幣，因此就修改成三個類別，名稱可以自己定義，接著在research\object_detection目錄下執行

python generate_tfrecord.py --csv_input=images\train_labels.csv --image_dir=images\train --output_path=train.record

python generate_tfrecord.py --csv_input=images\test_labels.csv --image_dir=images\test --output_path=test.record

最後來創造一個標籤地圖，這個標籤地圖是告訴訓練器，類別的名稱對應的類別id。在\object_detection\training的資料夾開一個名叫 labelmap.pbtxt的文字檔，請注意副檔名並不是txt而是pbtxt。

接著編輯內容，該類別名稱要'與剛剛的generate_tfrecord.py一致

item {

id: 1

name: '1 dollar'

}



item {

id: 2

name: '5 dollar'

}



item {

id: 3

name: '10 dollar'

}

最後在訓練之前，要修改幾個訓練參數，將目錄切換到 C:\tensorflow\models\research\object_detection\samples\configs，將 faster_rcnn_inception_v2_pets.config複製到 \object_detection\training的資料夾，然後用文字編輯器打開他，準備對他進行修改。注意修改的時候路徑的斜線必須採用反斜線/，以及採用雙引號"而不是單引號，以下是修改的內容

行數9:修改訓練類別，以該實作有3個類別就改為3

行數105:

fine_tune_checkpoint: "C:/tensorflow/models/research/object_detection/faster_rcnn_inception_v2_coco_2018_01_28/model.ckpt"

行數121:

input_path: "C:/tensorflow/models/research/object_detection/train.record" label_map_path: "C:/tensorflow/models/research/object_detection/training/labelmap.pbtxt"

行數128: num_examples改成你有幾張測試圖像

行數136:

input_path: "C:/tensorflow/models/research/object_detection/test.record" label_map_path: "C:/tensorflow/models/research/object_detection/training/labelmap.pbtxt"

修改後儲存起來，就可以來準備執行訓練囉！

訓練部分

首先先將在/object_detection/legacy的train.py移動到/object_detection目錄下，然後執行指令

python train.py --logtostderr --train_dir=training/ --pipeline_config_path=training/faster_rcnn_inception_v2_pets.config

如果以上都設定正確，以及參數也都正確，模型就會開始訓練，

每個訓練循環都會回報loss， Faster-RCNN-Inception-V2的模型訓練大概需要訓練到0.05的loss才算收斂完畢，時間取決你是採用CPU或是GPU，若想查看loss的收斂狀況，可以採用 TensorBoard，開啟一個新的 Anaconda Prompt的指令視窗，一樣切到tensorflow環境下執行

(tensorflow) C:\tensorflow\models\research\object_detection>tensorboard --logdir=training

由Total loss的圖表可以看到整體運行6千多步，總共耗時16個小時在CPU的平台上。

最後必須導出推理結果，將目錄切到\object_detection\training應該會看到許多.ckpt的檔案，記住號碼最高的即可，該例子是6579

接著在 \object_detection的目錄下執行

python export_inference_graph.py --input_type image_tensor --pipeline_config_path training/faster_rcnn_inception_v2_pets.config --trained_checkpoint_prefix training/model.ckpt-XXXX --output_directory inference_graph

將XXXX換成你剛剛記住的號碼，這個例子是6579，成功後會將整個推論結果記錄到\object_detection\inference_graph目錄

以上就已經做完訓練的準備了，接下來要測試訓練結果，在\object_detection的目錄下用文字編輯器打開 Object_detection_image.py，修改一下50行的NUM_CLASSES，這個例子有三個類別就改成3，另外是想偵測的圖像必須放在\object_detection的目錄下，修改34行，IMAGE_NAME為你想測試的圖片名稱

以上就是辨識後的結果，可以明顯看到硬幣有被辨識出來了，當然Box的大小以及字體都可以調整，這次實作先到這邊。

後續我將整個模型以flask的方式部屬到Heroku上，用一個小網頁來呈現模型的效果，只要右鍵下載範例圖片，就可以上傳圖片辨識結果。

當然這是一個範例網站，做的不是很好，還請見諒，而且由於該雲端伺服器選擇的是沒有GPU的方案，所以單張辨識大約要花30秒左右。

選擇檔案上傳後，稍微等待一下，右邊的辨識結果就會跑出來了。當然如果你手邊也有硬幣的圖片想測試當然可以，不過效果可能就會比較差一點，因為我們的訓練情境非常的少，並沒有考慮太多情境去做訓練。

這張的效果就很差了XD，因為完全是沒看過的情境，有些雜七雜八的東西亂入，而且當初沒有考慮到50元，有點失策XD。