使用C++版本Mxnet進行預測的注意事項


現在越來越多的人選擇Mxnet作為深度學習框架,相應的中文社區非常活躍,而且后面推出的gluon以及gluoncv非常適合上手和實驗,特別是gluoncv中提供了非常多、非常新的預訓練model zoo,比如像yolov3這種~~不過網上(包括Mxnet社區、gluon論壇等等)大多是關於Python版本的話題,關於C++版本的資料卻非常少,最近在用C++版本的mxnet,進行人臉檢測和識別,踩到不少的坑,在這里總結一下。

1.C++版本的Mxnet需要進行手動編譯,里面有不同的數學計算加速方式,比如MKL,MKLDNN或者openblas(前者主要針對Intel的cpu架構,后者是一個比較通用的線性代數優化庫,MKLDNN針對神經網絡進行優化)等等,編譯完成之后可以使用里面的c_api,即#include <mxnet/c_predict_api.h>或者使用提供的cpp的api:#include "mxnet-cpp/MxNetCpp.h"。

2.如果手動編譯過Mxnet會發現Mxnet實際上是好幾個項目的集合,比如NNVM,mshadow,dmlc等等,后端引擎負責真正的計算部分,前端實現接口調用,而且作者花了大部分精力圍繞在Python接口的編寫上,所以關於Python方面的接口非常多,而像C、C++的接口真的很少,不過Mxnet是一個經常進行更新的項目,所以以后是否會完善這些拭目以待。

3.性能時間度量。以下:

(1)一定要注意mxnet前端語言可能會異步調用后端的計算結果,以Python為例,當你使用CPU對比較深的resnet模型進行一次預測,有時發現耗僅僅數毫秒,而在后面的asnumpy時卻使用了上百毫秒。避免這種情況出現的最好方式就是使用mxnet.ndarray.waitall(),強制等待前面的操作執行完成;

(2)很多操作第一次都會比較耗時,比如load參數到內存,甚至像opencv中的resize有時第一次也會比較耗時,所以如果想公平的統計某一時段的時間開銷,最好是先手動執行一次,然后跑多個loop取平均值進行比較。有些同學拿imread一次預測然后統計時間,這樣的話相當於把load參數等相關開銷都計算在內了,這是不適合的;

(3)關於batch操作。不止訓練階段有batch操作,預測(predict或者inference)也有,比如做人臉識別,需要把檢測出來的多個人臉的bounding box的圖像分別摳出來然后組成一個batch,這時候識別網絡的輸入就是batch_num x channel x high x width。為什么需要進行batch操作?假如我們使用GPU,很明顯可以進行cuda並行計算大大加快處理速度;如果使用CPU的話某些數學優化庫也會讓這個速度有一定提升,不過相比較而言不是非常明顯;使用batch操作非常需要注意的是一定要考慮內存是否足夠,實際處理的時候要評估一下最大的batch數目,否則很容易out of memory;

4.關於Mxnet C/C++的預測,一般用MXPredCreate創建識別引擎PredictorHandle,然后使用MXPredSetInput設置輸入,用MXPredForward進行預測,一定要注意的是創建的PredictorHandle在使用完之后一定別忘調用MXPredFree釋放,否則跑多次內存會泄漏的非常快。另外要注意C/C++提供的api中,預測的時候MXPredSetInput設置的參數維度是固定的,比如當你的batch數變化的時候PredictorHandle也需要改變,為了feed不同的輸入,可以用MXPredReshape重新改變batch_num x channel x high x width的輸入形狀,而不需要每次重新load參數再調MXPredCreate,因為MXPredCreate的開銷非常大,相比較而言MXPredReshape的開銷小一些。但MXPredReshape也並不是一點開銷沒有,當你需要識別的人臉數的batch一直在變,頻繁的reshape形狀毫無疑問開銷就會顯得比較大,這樣就有一個問題:怎么在使用loop進行識別(也就是對於每個人臉都丟進網絡里,輸入是1 x channel x high x width識別完一個再接着下一個)和batch方式(輸入是batch_num x channel x high x width)之間進行權衡?我覺得一方面要考慮使用的網絡在使用batch時到底能提升多大,一方面也需要考慮MXPredReshape本身的開銷,比如我們可以設置一個batch數的閾值,當大於這個值的時候進行MXPredReshape,否則直接循環進行預測。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM