OpenCV的dnn模塊調用TesorFlow訓練的MoblieNet

機器學習 OpenCV 深度學習 固態硬盤 計算機視覺與機器學習 計算機視覺與機器學習 2017-11-03

一、初得模型

那是一個月之前的事情了,我利用 TesorFlow Object Detection API 訓練了現在目標檢測裡面應該是最快的網絡

MobileNet。當時的目的就只是學習整個 finetuning 的流程,於是我只是用了20張自己標註的人臉樣本圖片作為訓練集去 finetuning ,訓練完之後的模型通過修改 TesorFlow Object Detection API 自帶的例程代碼,即

object_detection_tutorial.ipynb ,運行結果竟然還不錯,對於圖片中的大小適中的人臉能夠比較準確地檢測,

畢竟我只用了20個樣本訓練啊。當然,瞭解了流程和方法之後,以後多少樣本的訓練都不在話下......只要有足夠數據和夠好的顯卡...

OpenCV的dnn模塊調用TesorFlow訓練的MoblieNet

tensorflow 自帶例子檢測結果

二、C++調用之難,難於上西天

然而,其實我訓練的目標檢測模型是要在 C++ 環境下用的。 TensorFlow 也提供了 C++ API ,但是要用的話需要自

己從源碼編譯,而且用的是 Bazel 。是的,我用的是Windows,所以,在嘗試安裝 Bazel N次失敗之後,我嘗試用OpenCV3.3.0新出的dnn模塊調用訓練好的模型。然而新出的dnn模塊當時支持的模型太少了,它支持 ssd-mobilenet 的caffe模型,但是並不支持mobilenet的tensorflow模型,當時也看到了github上有人提交issue提到這個問題。

問題的issue參考這裡:Unable to import mobilenet model using latest OpenCV.#9462。

有人在這裡給出了一個解決方案:Layers for MobileNet from TensorFlow #9517。

解決方案裡面最後一步: Modify for DNN: fuse batch normalizations and remove Squeeze op. 需要用到一個工具: transform_graph 。而這個工具需要用bazel編譯......又回到了bazel......

三、柳暗花明

在沒能力自己修復問題之前,只能等待大神解決。一個月期間,多次嘗試bazel,包括windows環境和ubuntu環境,可能對這些工具不熟悉吧,總之沒能成功解決。終於盼到十月份OpenCV3.3.1出來,果然對此有了更新。而且加載模型的API也有了變化,從原來的一個參數變成了兩個參數。而且針對MobileNet還給出了一種解決方案。目前尚不能確定這種方案是否適用於其他模型,比如Inception等。

現在把這種方法記錄如下,以備後用,以防遺忘,同時幫助同道中人。

  • 首先通過TensorFlow detection_model_zoo下載他們訓練好的模型,或者用 TesorFlow Object Detection API 訓練或者 finetuning 之後,由 models-master\object_detection\export_inference_graph.py 導出的模型文件 frozen_inference_graph.pb 。(利用 object_detection_tutorial.ipynb 的話,只是這一個文件就夠了。)

  • 下載 ssd_mobilenet_v1_coco.pbtxt 。然後把這個文件的第2222行修改為 attr { key: "num_classes" value { i: 2 } } 。其中這個2根據自己的需要改成 目標數+1 。比如我這裡只有一類——人臉,所以我改為2。

  • 參考 mobilenet_ssd_python.py 。

  • 還有一點,要用最新的OpenCV3.3.1,OpenCV3.3.0是不行的。

最後的測試結果如下:

OpenCV的dnn模塊調用TesorFlow訓練的MoblieNet

opencv調用模型的檢測結果

四、路漫漫

對比兩種方式的檢測結果,我覺得還是tensorflow的方框更精確一點,而且後者的圖片是裁剪過的。另外,兩種結果的confidence不一樣,估計是實現的方式不太一樣。這一點還需要繼續探究,今天先把方法記下來。同時歡迎大家指點,集思廣益。

相關推薦

推薦中...