1. 程式人生 > >一頭栽進了tensorflow lite的巨坑裡

一頭栽進了tensorflow lite的巨坑裡

image

之前寫過一篇《這個中秋,我開發了一個識別狗狗的app》。圖片識別可以算作是深度學習領域爛大街的主題,幾乎每本書和教程都會拿來作為入門示例。移動端的圖片識別的教程也很多,大多數都脫胎於Google的教程《TensorFlow for Poets》和《TensorFlow for Poets 2: Android》。有了現成的教程,我對實現狗狗的影象識別信心滿滿,認為重點在於資訊的展示及狗狗資訊的收集。

然而多年的開發經驗告訴我,真正自己做起來,一定會碰到問題,特別是像tensorflow lite這種頻繁迭代的產品。果然,我就一頭栽進了tensorflow lite 的巨坑裡。下面我就說道說道這個坑。

參考上面提到的教程,將基本功能實現出來還算順利。然而,等程式碼build出來,安裝到手機上一測試,拿一張狗狗的圖片識別,結果的top 1概率都是0.0 ~ 0.02之間,使用訓練的圖片測試也是如此。為了更好的進行測試,我寫了一個測試用例:predictSingleImage(),直接測試sd卡上的圖片。排查問題過程如下:

  1. 確認傳遞給ImageClassifier的bitmap是正常的,這個可以通過將bitmap儲存到檔案確認。經過人眼觀察,送到ImageClassifier的bitmap中狗狗的影象還是很明顯的。
  2. 確認模型問題。我開始採用的是Google Inception V3模型,換成教程中使用的mobilenet模型,問題依舊。將我訓練出來的mobilenet模型放到
    TensorFlow for Poets 2: Android
    的示例程式碼中,工作正常,雖然準確率不高,但至少top 1的概率大於0.4。可以確認模型沒有問題。

這個帖子將問題步驟描述得很詳細,最後貼出了測試結果:

image

然而,這個問題沒有人回答。這一下子又陷入了困頓,有一陣子甚至開始懷疑人生:識別靜態照片和camer流中一幀影象難道有本質區別嗎?

一次搜尋中,我無意中看到一個帖子:TfLite Image classification score is not consistent it keeps increasing for same image untill it reaches to some saturation(actual score)

。連結地址:https://groups.google.com/a/tensorflow.org/forum/#!topic/tflite/fREwHb4rAPM

外國人提問題都比較嚴謹,這個帖子也貼了程式碼,大意就是說對於同一張圖片,Tflite的圖片分類的結果不一樣,每識別一次,top 1概率就會提升,直到到達一個固定值。

看到這裡,我才恍然大悟。回想我的程式碼和教程程式碼不同之處就在於:我只呼叫了一次識別過程,而教程是針對影象幀進行識別,會反覆呼叫識別過程,可能之前的概率很低,但很快被後面的結果給覆蓋了。

開始,我猜測是程式碼中tensorflow lite沒有初始化好就呼叫其識別過程。但我在測試程式碼中加入延時,沒有效果。加入迴圈,對一個圖片反覆識別幾次,後面的識別就正常了。值得一提的是,不需要反覆識別同一圖片,換幾個圖片識別,後面再換其他的圖片識別一樣沒問題。為此我添加了predictImages()方法,測試一系列圖片,可以看到開始的top 1 score很低,但識別了幾張之後,後面的top 1概率就正常了。

這時,我算是明白,我真的跌進tensorflow lite的巨坑裡面了。Tensorflow Lite出現這樣一個問題也真是匪夷所思,同樣的輸入和同樣的處理,輸出結果卻不同,真的顛覆了我對程式設計的理解。

image

當年愛因斯坦面對量子力學,提出了“上帝是在執骰子嗎?”的疑問。

深度學習也是如此?

image