MobileNet教程(2):用TensorFlow搭建安卓手機上的圖像分類App

2021-02-15 量子位
王瀚宸 編譯自 Hackernoon
量子位 報導 | 公眾號 QbitAI

上周末,量子位翻譯了一份MobileNet教程,其中講述了怎樣在一個新的數據集上重新訓練MobileNet,那篇文章的成果,是一個分類器,能在電腦上以每秒鐘400張的速度,識別圖片是否為道路。

MobileNet是為移動端量身打造的,因此這次我們準備把之前做的辨別道路的模型應用到一個Android App中,看看它在行動裝置上效果如何。

目標和計劃

首先,讓我們明確目標和計劃,我們希望做到:

為了達到這些目標,我們的計劃是:

生成一個新的訓練數據集;

訓練多個MobileNet結構,從而尋找所能夠達到準確率目標(95%)的最小型網絡;

與在Android上運行的Inception V3做對比;

將TensorFlow上Android example App中的模型替換為我們的MobileNet;

大量的測試;

進行調試,從而將CPU的佔用調到5%以下。

建立數據集

在前一篇推送中,我們為了辨認「道路/非道路」,從多個來源拉取了圖片作為訓練素材。

現在我們再來思考一下這樣做是否有必要。

如果你記得的話,這個項目的目標是為了保護用戶隱私,當車上的攝像頭打開的時候,如果它看見的不是道路,就應該自動關掉。

所以,為了建立我們的訓練數據集,我需要錄製一些(跟駕駛相關)日常生活中的場景:比說我家的周圍、我車子的外部,我在車上擺弄收音機、逗貓等等。這些會被當做非道路的數據用來訓練模型。

 一些「非道路」的示例圖片

而訓練數據的「道路」部分,是從Coastline driving dataset中隨機取出的,這些圖片都是由車的前置攝像頭拍攝的。

 一些「道路」的示例圖片,注意這些圖片中都有山坡,因此,為了防止模型把判斷道路錯認為判斷山坡,我們需要對訓練數據進行一些擴展。

為道路和非道路數據集各收集3000張圖片後,下一步就是開始訓練了。

用特定數據集訓練MobileNet

下一步,是看看不同結構的MobileNet在經過訓練後能達到什麼樣的準確度。

我們先從最「寬」的MobileNet開始訓練:MobileNet 1.0 @ 128。 因為我們想把這個模型應用到行動裝置上,因此我們將會採用權值量化,從而進一步減少內存佔用。

關於重新訓練MobileNet的操作細節,可以看我的前一篇推送。

在TensorFlow的根目錄下,運行以下腳本:

python tensorflow/examples/image_retraining/retrain.py \  --image_dir ~/ml/blogs/road-not-road/data/ \  --learning_rate=0.0005 \  --testing_percentage=15 \  --validation_percentage=15 \  --train_batch_size=32 \  --validation_batch_size=-1 \  --flip_left_right True \  --random_scale=30 \  --random_brightness=30 \  --eval_step_interval=100 \  --how_many_training_steps=1000 \  --architecture mobilenet_1.0_128_quantized

在經歷1000步的訓練後,我們在測試集上達到了99.7%的準確率。

以下是模型做出了錯誤判斷的一些圖片:

 被錯認為道路的非道路圖片,我不得不說這種失誤是可以接受的,這顯然是路,但不是我們要的類型 。

 被錯認為非道路的道路圖片,我認為這是因為在訓練集中沒有出現橋架在道路上的圖片,更多的訓練數據能解決這個問題。

接下來讓我們在最小的MobileNet上(0.25@128)訓練,同樣採用權值量化。在1000步訓練後,我們達到了92.6%的正確率,沒有達到我們的目標。

那麼讓它稍微變寬些呢,比如說0.5@128?

準確率達到了95%,最終的模型大小為1.6MB。值得一提的是我們訓練模型只用了10分鐘10fps的視頻,所以在訓練數據的收集上還有很大的提升空間。

接下來我們很快試一下看看模型是否能夠如預計般工作:

python tensorflow/examples/label_image/label_image.py \  --graph=/tmp/output_graph.pb \  --labels=/tmp/output_labels.txt \  --image=/home/harvitronix/ml/blogs/road-not-road/test-image.jpg \  --input_layer=input \  --output_layer=final_result \  --input_mean=128 \  --input_std=128 \  --input_width=128 \  --input_height=128

 系統認為這張圖片是道路的可能性為99.023%

這個系統速度很快,在我們搭載NVIDIA GeForce 960m GPU的筆記本上,識別1,000張圖片只需要3.36秒,即每秒鐘能識別297.6張圖片。

把MobileNet應用到Android App中

現在我們擁有了一個小巧、快速、足夠精確的模型,接下來我們準備把它搭載到一個Android App上,從而在真實環境中進行測試。

繼續使用TensorFlow提供的工具,我們馬上就會使用裡面的Android示例項目完成模型的搭載。

1. 建立項目

如果你還沒有準備好,可以從TensorFlow的repository下載這個Android示例項目:

git clone https://github.com/tensorflow/tensorflow.git --depth 1

具體的文件夾是tensorflow/examples/android。用Android Studio打開這個文件夾,編譯,然後把生成的APK安裝包搭載到你的手機上,你就得到了一個搭載著在ImageNet數據集上訓練出的Inception V3模型的圖像分類器App,它能夠準確地把貓咪跟鴨嘴獸區分開來。

如果你編譯apk安裝包過程有問題,可以參考他們的readme文檔中的指示。(https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android)

我遇到的最大的挑戰是NDK(Native Developer Kit)的版本問題,降級到r12b版本後才能正常的編譯。

2. 評測搭載了Inception的App

我們現在運行的app上搭載的是Inception模型,讓我們它做一些測評,從而可以與之後的MobileNet模型比較。

搭載了Inception的這個app的大小是53.9Mb,而搭載MobileNet的只有1.6Mb。它能夠以240ms的速度識別一張圖片(即4fps),CPU的佔用達到了40%。

 搭載Inception V3的App在4fps速度下運行時的CPU佔用情況

讓我們把運行速度調到1fps試試:

 搭載Inception V3的app在1fps速度下運行時的CPU佔用情況

現在,內存的佔用仍然在35%以上,讓我們盼著MobileNet能夠比這表現得好些,否則我們就達不到之前定下的目標了(內存佔用上限為5%)。

3. 換成MobileNet

接下裡讓我們對這個Android project做一些小修改,從而搭載上我們的MobileNet。

首先,把你的模型和標籤文件複製到project的assets文件夾裡。我的是分別是/tmp/output_graph.pb 和 /tmp/output_labels.txt。

接下來,打開ClassifierActivity,具體地址是在:

tensorflow/examples/android/src/org/tensorflow/demo/ClassifierActivity.java

將這個文件中的開頭部分中定義的參數設置為我們的新模型。即從一打開時的這樣:

private static final int INPUT_SIZE = 224;private static final int IMAGE_MEAN = 117;private static final float IMAGE_STD = 1;private static final String INPUT_NAME = "input";private static final String OUTPUT_NAME = "output";private static final String MODEL_FILE = "file:///android_asset/tensorflow_inception_graph.pb";private static final String LABEL_FILE =    "file:///android_asset/imagenet_comp_graph_label_strings.txt";

改為這樣:

private static final int INPUT_SIZE = 128;private static final int IMAGE_MEAN = 128;private static final float IMAGE_STD = 128;private static final String INPUT_NAME = "input";private static final String OUTPUT_NAME = "final_result";private static final String MODEL_FILE = "file:///android_asset/output_graph.pb";private static final String LABEL_FILE =    "file:///android_asset/output_labels.txt";

點擊運行從而開始編譯,然後在你的手機上運行相應的apk安裝包,你就得到了自己的道路識別器。

結果

下面是我實際使用我這個app的視頻,我對UI進行了一些小改動,從而使顯示結果更直觀。

那麼它運行速度和CPU佔用的情況怎樣呢?

在我的小米5上,它識別一張圖片需要55毫秒,也就是每秒18幀(18fps)。

不過,在這個識別速度下,CPU的佔用也比較大。在加足馬力運行的情況下,CPU的佔用大概為25到30%。

 搭載MobileNet的App在18fps速度下運行時的CPU佔用情況

如果我們希望這個數字能到5%,那麼我們可以降低app的運行速度,因為在我們的使用場景中並不需要連續地進行圖像識別。將識別速度調整到每秒1張,CPU的佔用的平均值就下降到了5.5%。

 搭載MobileNet的App在1fps速度下運行時的內存佔用和CPU佔用情況

總結一下,我們的MobileNet的模型只有Inception的1/30,而運行起來識別圖片的速度大概是後者的三倍,同時使用了佔用的CPU空間也更少。

相關連結

教程原文:
https://hackernoon.com/building-an-insanely-fast-image-classifier-on-android-with-mobilenets-in-tensorflow-dc3e0c4410d4

下載作者訓練好的模型:
https://s3-us-west-1.amazonaws.com/coastline-automation/demo/mobilenet-road-not-road.tar.gz
這裡面包括一個.pb模型文件和一個存儲標籤(「road」,「not road」)的.txt文件。

8月9日(周三)晚,量子位邀請三角獸首席科學家王寶勳,分享基於對抗學習的生成式對話模型,歡迎掃碼報名 ▼

量子位AI社群6群即將滿員,歡迎對AI感興趣的同學加入,加群請添加微信號qbitbot2;

此外,量子位的專業細分群(自動駕駛CVNLP機器學習等)正在招募,面向正在從事相關領域的工程師及研究人員。

進群請添加微信號qbitbot2,並務必備註相應群的關鍵詞~通過審核後我們將邀請進群。(專業群審核較嚴,敬請諒解)

量子位正在招募編輯/記者,工作地點在北京中關村。期待有才氣、有熱情的同學加入我們!相關細節,請在量子位公眾號(QbitAI)對話界面,回復「招聘」兩個字。

相關焦點

  • 在TensorFlow中使用MobileNet,創建在手機上運行的快速圖像分類器
    當你想要識別一個圖像時,會把圖像發送到網上,在遠程伺服器上進行識別,然後把結果發回到你的手機上。這個情況現在正在快速發生變化。手機的計算能力正在快速增長,而計算機視覺需要的網絡複雜度正在縮小(感謝像SqueezeNet和MobileNet這樣的架構)。不需要連接網際網路的AI有很多優點,尤其適合一些對響應速度要求很高的場景。
  • 在瀏覽器中使用Keras MobileNet模型以及Tensorflow.js進行圖片分類
    具體的實現可以參見:https://github.com/Gogul09/mobile-net-projectsPython中的基礎MobileNet神經網絡模型在Keras中,MobileNet存在applications模塊中。如果要預測的類別在ImageNet類別中可用,Keras使用MobileNet提供現成的圖像分類。
  • TensorFlow圖像分類教程
    本教程旨在把一個事先被放到訓練過的類別裡的圖片,通過運行一個命令以識別該圖像具體屬於哪個類別。步驟如下圖所示:標註:管理訓練數據。例如花卉,將雛菊的圖像放到「雛菊」目錄下,將玫瑰放到「玫瑰」目錄下等等,將儘可能多的不同種類的花朵按照類別不同放在不同的目錄下。如果我們不標註「蕨類植物」,那麼分類器永遠也不會返回「蕨類植物」。
  • Android中使用TensorFlow Lite實現圖像分類
    本篇來自 夜雨飄零 的投稿,分享了關於 Android中如何使用TensorFlow Lite實現圖像分類,一起來看看!希望大家喜歡。夜雨飄零 的博客地址:https://blog.csdn.net/qq_33200967TensorFlow Lite是一款專門針對行動裝置的深度學習框架,行動裝置深度學習框架是部署在手機或者樹莓派等小型行動裝置上的深度學習框架,可以使用訓練好的模型在手機等設備上完成推理任務。
  • 【乾貨】快速上手圖像識別:用TensorFlow API實現圖像分類實例
    作者通過TensorFlow API快捷地實現一個命令行圖像分類例子,詳細介紹了如何按步驟下載模型、加載圖像、執行圖像識別命令。你不需要GPU,只要有一臺筆記本就可以按照作者的步驟進行操作,並最終完成圖像識別任務。教程非常方便快捷,讀完本文之後相信你能秒秒鐘實現一個圖像分類任務。專知內容組編輯整理。
  • 用TensorFlow訓練一個目標檢測器(手把手教學版)
    用LabelImg標註的文件是PASCAL VOC格式的,tensorflow提供了一個腳本將PASCAL VOC格式的標註文件和相應的圖片轉換為TFRecord,不過,要用這個腳本,我們需要先搭建TensorFlow環境以及安裝TensorFlow object detection api ,關於這兩個部分,請參閱我的系列文章《Ubuntu 16.04下搭建TensorFlow運行環境(用Anaconda
  • 讓深度學習進入移動端:在安卓上運行 TensorFlow
    簡歷投遞:jobs@aiera.com.cnHR 微信:13552313024新智元為COO和執行總編提供最高超百萬的年薪激勵;為骨幹員工提供最完整的培訓體系、高於業界平均水平的工資和獎金老實講,在筆記本上對圖片進行分類是很花時間的:需要下載分類用的圖片,並在終端裡輸入很多行命令來運行分類。不過,儘管沒有很多的公開資料,好消息是你也可以在有攝像頭的手機上運行TensofrFlow的Inception分類器,甚至是你自定義的分類器。然後你只要把攝像頭對準你希望做分類的東西,TensorFlow就會告訴你它認為這是什麼東西。
  • 教程 | 如何用TensorFlow在安卓設備上實現深度學習推斷
    她在 Insight 工作的時候,在安卓系統上用 TensorFlow 部署了一個 WaveNet 模型。本文詳細介紹了部署和實現過程。對於個人和公司來說,存在許多狀況是更希望在本地設備上做深度學習推斷的:想像一下當你在旅行途中沒有可靠的網際網路連結時,或是要處理傳輸數據到雲服務的隱私問題和延遲問題時。
  • 在安卓上運行TensorFlow:讓深度學習進入移動端
    老實講,在筆記本上對圖片進行分類是很花時間的:需要下載分類用的圖片,並在終端裡輸入很多行命令來運行分類。不過,儘管沒有很多的公開資料,好消息是你也可以在有攝像頭的手機上運行TensofrFlow的Inception分類器,甚至是你自定義的分類器。然後你只要把攝像頭對準你希望做分類的東西,TensorFlow就會告訴你它認為這是什麼東西。
  • 【乾貨】TensorFlow實戰——圖像分類神經網絡模型
    2.訓練(Training)的過程是在我們標註的數據(圖像)的基礎上,使用某種工具隨機抓取其中的一些數據(圖像),然後輸入到模型中,再使用模型來猜測每種花的類型並且測試猜測的準確性,重複這一過程直到大部分訓練數據都被使用。最後一批未使用的圖像(測試集)用於檢驗訓練模型的準確性。
  • 【官方教程】TensorFlow在圖像識別中的應用
    一系列的模型不斷展現了性能的提升,每次都刷新了業界的最好成績:QuocNet, AlexNet, Inception(GoogLeNet), BN-Inception-v2。谷歌的以及其它的研究員已經發表了論文解釋這些模型,但是那些結果仍然很難被重現。我們正在準備發布代碼,在最新的模型Inception-v3 上運行圖像識別任務。
  • 如何使用 TensorFlow mobile 將 PyTorch 和 Keras 模型部署到行動裝置
    截止到今年,已經有超過 20 億活躍的安卓設備。安卓手機的迅速普及很大程度上是因為各式各樣的智能 app,從地圖到圖片編輯器應有盡有。
  • TensorFlow 2.0 教程 01:基本圖形分類
    本教程將指導您使用深度學習構建一個簡單的CIFAR-10圖像分類器。在本教程中,我們將:定義一個模型設置一個數據管道訓練模型使用多GPU加速訓練速度為監控過程/更新學習計劃添加回調。本教程中的代碼可以在這裡找到。
  • Tensorflow教程-雙向的LSTM文本分類
    今天的教程就是利用雙向的LSTM進行文本分類,單向的LSTM的文本分類可以參考Tensorflow教程-循環神經網絡文本分類。然後用bidirectional_dynamic_rnn將兩個LSTM結合起來得到輸出結果,因為輸入結果是outputs是有向前和向後的LSTM輸出的結果,所以利用concat方法進行連接。另外,因為輸出只需要最後輸出的結果,所以output_rnn[:,-1,:]獲得shape等於[None,2 * num_hidden]的矩陣。
  • 教程 | 從零開始:TensorFlow機器學習模型快速部署指南
    DN 啟用分類器:https://github.com/hiveml/simple-ml-serving/blob/master/test/test_p2p_proxy.sh生產環境中的機器學習第一次進入 Hive 的機器學習空間,我們就已經擁有數百萬個真值標註圖像,這可以讓我們在一周時間內從頭訓練(即隨機權重)適用於特定使用案例的頂尖深度卷積圖像分類模型
  • TensorFlow.js 實例上手指南
    【導讀】來吧,三行代碼實現圖像分類。
  • TensorFlow Lite 助力產品落地
    我們很高興地發布 TensorFlow Lite Model Maker,這款工具簡單易用。通過遷移學習,您可在您的數據集上應用前沿的機器學習模型。此工具將複雜的機器學習概念封裝在直觀的 API 中,無需機器學習專業知識,您也可以開啟機器學習之旅。
  • 圖像分類任務中,Tensorflow 與 Keras 到底哪個更厲害?
    讓我們看看這個問題在圖像分類的實際應用中的答案。在此之前,先介紹Keras和Tensorflow這兩個術語,幫助你在10分鐘內構建強大的圖像分類器。TensorflowTensorflow是開發深度學習模型最常用的庫。它是有史以來最好的庫,在日常實驗中被許多極客選擇。
  • 【深度學習系列】用PaddlePaddle和Tensorflow進行圖像分類
    ,熟悉Tensorflow,PaddlePaddle等深度學習框架,負責過多個機器學習落地項目,如垃圾評論自動過濾,用戶分級精準營銷,分布式深度學習平臺搭建等,都取了的不錯的效果。這篇主要跟大家講講如何用PaddlePaddle和Tensorflow做圖像分類。所有程序都在我的github裡(https://github.com/huxiaoman7/PaddlePaddle_code),可以自行下載訓練。在卷積神經網絡中,有五大經典模型,分別是:LeNet-5,AlexNet,GoogleNet,Vgg和ResNet。
  • 6 種方法部署 TensorFlow2 機器學習模型,簡單 + 快速 + 跨平臺!
    環境配置目前,TensorFlow 2 已正式發布,你需要通過 pip install -U tensorflow 進行升級安裝。線上環境中,我們需要先卸載老版本,然後再安裝 TensorFlow 2。# 解決線上環境的一些依賴問題,本地無需這些操作!