日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

深度学习-服务端训练+android客户端物体识别实战(caffe入门教程+mobilenet+ncnn+android)

發(fā)布時間:2025/3/11 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习-服务端训练+android客户端物体识别实战(caffe入门教程+mobilenet+ncnn+android) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 背景
  • 物體識別簡介

  • 自動駕駛

    • 淘寶京東使用物體識別技術(shù)
    • 公司業(yè)務(wù)需求
  • 深度學(xué)習(xí)簡介

  • 深度學(xué)習(xí)的位置

    • 深度學(xué)習(xí)概念
    • 深度學(xué)習(xí)優(yōu)勢
  • 深度學(xué)習(xí)基礎(chǔ)知識

  • 感知機

    • 激活函數(shù)
    • 多層感知機
    • 卷積神經(jīng)網(wǎng)絡(luò)
  • 卷積層 * 池化層

    • 模型訓(xùn)練
  • 前向傳播 * 反向傳播與參數(shù)優(yōu)化

  • 深度學(xué)習(xí)服務(wù)端框架

  • tensorFlow

    • keras
    • pytorch
    • Caffe/Caffe2.0
  • caffe框架

  • 為何選擇caffe

    • caffe環(huán)境搭建
    • caffe基礎(chǔ)
  • 數(shù)據(jù)集?模塊概要圖?solver(prototxt) 執(zhí)行者配置?神經(jīng)網(wǎng)絡(luò)可視化?caffe中的基礎(chǔ)概念

  • blobs?layer 神經(jīng)層?net 神經(jīng)網(wǎng)絡(luò) * forward/backward 前向傳播/反向傳播

* caffe+mnist數(shù)據(jù)集+lenet * caffe+cifar10+caffenet * caffe+cifar10+mobilenet * caffe+voc2012+vgg(finetune)+ssd(物體檢測模型)
  • 輕量級客戶端框架-ncnn

  • ncnn簡介

    • ncnn+caffe+mobilenet實戰(zhàn)
  • ncnn環(huán)境搭建 * 模型轉(zhuǎn)化(caffe格式-> ncnn格式)

    • 源碼解析
  • 文件目錄?執(zhí)行流程?重點代碼?效果展示?其他工程的效果圖

  • 相關(guān)學(xué)習(xí)資料

  • 教學(xué)視頻

    • 開源項目
    • 參考博客

背景

產(chǎn)品以后的發(fā)展需要添加更多科技元素,如下:

  • 人臉識別
  • 物體識別
  • 場景識別

以下以物體識別為重點,使用到了深度學(xué)習(xí)技術(shù),以下我們將逐一展開。
本次分享的重點是深度學(xué)習(xí)+caffe+ncnn,其余部分將簡單的進行帶過。
注:本文主要以有監(jiān)督的學(xué)習(xí)為主(分類和回歸問題),無監(jiān)督學(xué)習(xí)不作為分享范圍。

物體識別簡介

物體識別(俗稱Object detection),是近年來興起的技術(shù),這也是人工智能的首要目標(biāo)之一。這是一種完全模擬人眼識別的技術(shù),即使在物體旋轉(zhuǎn)、變色、部分展示等的情況下,同樣具備優(yōu)秀的識別效果。
人工智能目標(biāo)是:

  • 讓機器看世界
  • 讓機器聽世界
  • 讓機器獨立思考

自動駕駛

在駕駛領(lǐng)域中,引入物體識別技術(shù)將大大降低交通事故發(fā)生的概率。

淘寶京東使用物體識別技術(shù)

公司業(yè)務(wù)需求

近期產(chǎn)品提出物體識別的相應(yīng)需求,能識別出家長和老師發(fā)送圖片中的物體,來開展相應(yīng)的業(yè)務(wù)。以下是一張海邊游玩的照片。

深度學(xué)習(xí)簡介

深度學(xué)習(xí)的位置


深度學(xué)習(xí)分別屬于人工智能和機器學(xué)習(xí)的一部分。與深度學(xué)習(xí)相并行的另外一種機器學(xué)習(xí)方法,被稱之為傳統(tǒng)的機器學(xué)習(xí)(例如svm、邏輯回歸)。

深度學(xué)習(xí)概念

人工神經(jīng)網(wǎng)絡(luò)是一個分層的有向圖,第一層輸入節(jié)點接受輸入的信息,也稱為輸入層。來自這些點的數(shù)值按照它們輸出的弧的權(quán)重(wn),進行線性加權(quán)(得到G),然后再做一次函數(shù)變化f(G),賦給第二層的節(jié)點Y。
第二層的節(jié)點照此將數(shù)值向后傳遞,直到第三層節(jié)點,如此一層層傳遞,直到最后一層,最后一層又被稱為輸出層。在模式分類時,一個模式(圖像、語音、文字等)的特征值(比如坐標(biāo)),從輸入層開始,按照上面的規(guī)則和公式一層層向后傳遞。最后在輸出層,哪個節(jié)點的數(shù)值最大,輸入的模式就被分在了哪一類。
------------------引自《數(shù)學(xué)之美—Google大腦和人工神經(jīng)網(wǎng)絡(luò)》

深度學(xué)習(xí)優(yōu)勢

神經(jīng)網(wǎng)絡(luò)與傳統(tǒng)的機器學(xué)習(xí)相比:

  • 能支持更復(fù)雜的分類邊界
  • 非線性表征更加豐富
  • 準(zhǔn)確率會隨著數(shù)據(jù)集的增加而突破傳統(tǒng)學(xué)習(xí)的瓶頸
  • 與svm相比,在大數(shù)據(jù)集上收斂的更快
  • 輕量級神經(jīng)網(wǎng)絡(luò)具備高性能的前向傳播,方便部署到移動設(shè)備

深度學(xué)習(xí)基礎(chǔ)知識

參考:https://www.cnblogs.com/wj-1314/p/9754072.html

感知機

可以簡單的理解為是線性分類。假設(shè)訓(xùn)練數(shù)據(jù)集是線性可分的,感知機學(xué)習(xí)的目標(biāo)是求得一個能夠?qū)⒂?xùn)練數(shù)據(jù)集正實例點和負實例點完全正確分開的分離超平面。

感知機重點包含以下兩點:

  • 線性加權(quán)
  • 依靠損失函數(shù)進行權(quán)重優(yōu)化

數(shù)學(xué)公式略,將在其他博文中進行闡述。

感知機的缺陷:只支持線性分類,對于簡單的異或問題也不能進行分類。以下是異或問題中最簡單的情況,可以看到無論哪一條直線都不能進行完美的分割。

激活函數(shù)

針對于感知機不能表達非線性的問題,激活函數(shù)誕生了。

在人工神經(jīng)網(wǎng)絡(luò)中,規(guī)定神經(jīng)元函數(shù)只能對輸入變量(指向他的節(jié)點的值)線性組合后的結(jié)果進行一次非線性變換。
這次非線性變化成為“激活函數(shù)”
----《數(shù)學(xué)之美》

為了神經(jīng)網(wǎng)絡(luò)的通用性,每一層的非線性變化都選擇同一類函數(shù)。
激活函數(shù)包括:

  • relu
  • sigmoid
  • tanh
  • 等等

激活函數(shù)參考博客:https://blog.csdn.net/tyhj_sf/article/details/79932893

多層感知機

多層感知機(MLP,Multilayer Perceptron)也叫人工神經(jīng)網(wǎng)絡(luò)(ANN,Artificial Neural Network),除了輸入輸出層,它中間可以有多個隱層,最簡單的MLP只含一個隱層,即三層的結(jié)構(gòu)

  • 輸入層,輸入特征數(shù)據(jù)等加工或者沒有加工過的原始數(shù)據(jù)
  • 隱含層,隱含層可以很多,resnet有128層的,就是說的隱含層
  • 輸出層,輸出最后的計算結(jié)果,很多神經(jīng)網(wǎng)絡(luò)里面都把輸出層定義為概率值

多層感知機等同于全連接層,信息每向下傳遞一個神經(jīng)元,都會產(chǎn)生n*n的計算量(計算量會隨著輸入的維度增大而變得非常恐怖)

卷積神經(jīng)網(wǎng)絡(luò)

卷積神經(jīng)網(wǎng)絡(luò)是近年發(fā)展起來的,并引起廣泛重視的一種高效識別方法,20世紀60年代,Hubel和Wiesel在研究貓腦皮層中用于局部敏感和方向選擇的神經(jīng)元時發(fā)現(xiàn)其獨特的網(wǎng)絡(luò)結(jié)構(gòu)可以有效地降低反饋神經(jīng)網(wǎng)絡(luò)的復(fù)雜性,繼而提出了卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks-簡稱CNN)

參考資料:https://www.cnblogs.com/wj-1314/p/9754072.html

卷積的原理與人眼觀察事物極其相似,過程都是邊緣 -> 局部 -> 整體。卷積神經(jīng)網(wǎng)絡(luò)的核心就是使用多個局部特征來影響分類結(jié)果。

全連接的計算量非常大。而且是以整體來計算,沒有進行有效的特征提取,即使權(quán)重最終達到了收斂效果,也不能很好的進行預(yù)測。
卷積神經(jīng)網(wǎng)絡(luò)則不同,每次卷積完畢后,傳入下一層的數(shù)據(jù)大大降低了維度,而且經(jīng)過卷積,獲得了眾多局部特征,后面的層對這些特征數(shù)據(jù)進行訓(xùn)練,將變得既簡單又高效。

卷積層

簡單來說,卷積層用于特征提取。

根據(jù)卷積核的滑動,獲取到一個新的特征數(shù)據(jù)(Convolved Feature)。這個特征數(shù)據(jù)不是那么直觀,來看一下實物的效果。

針對于不同的通道(rgb)進行卷積后,會得到邊緣輪廓的圖。

池化層

池化層用于降低參數(shù),而降低參數(shù)的方法當(dāng)然是刪除參數(shù),保留最有效的參數(shù)。

一般我們有最大池化和平均池化。

  • 最大池化是現(xiàn)在使用最多的,可以突出局部特征
  • 平均池化則考慮了所有參數(shù),而計算出了平均值

需要注意的是,池化層一般放在卷積層后面。所以池化層池化的是卷積層的輸出。

模型訓(xùn)練

本博客重點關(guān)注有監(jiān)督的訓(xùn)練。在訓(xùn)練之前需要有一批標(biāo)注好的數(shù)據(jù),即訓(xùn)練數(shù)據(jù)。為了能在訓(xùn)練過程中動態(tài)的觀測模型的準(zhǔn)確率,同樣也需要一批標(biāo)注數(shù)據(jù)(推薦為訓(xùn)練數(shù)據(jù)/測試數(shù)據(jù)比例為4/1)

前向傳播


前向傳播,即訓(xùn)練數(shù)據(jù)在神經(jīng)網(wǎng)絡(luò)里從輸入層到輸出層的方向傳播一次,最終得到輸出層的輸出結(jié)果,即在每個分類的概率值。

反向傳播與參數(shù)優(yōu)化

用數(shù)據(jù)語言來表達:假設(shè)C為一個成本函數(shù)(Cost Function),它表示根據(jù)人工神經(jīng)網(wǎng)絡(luò)的輸出值(分類結(jié)果概率)和實際訓(xùn)練數(shù)據(jù)中的輸出值之間的差距。現(xiàn)在,訓(xùn)練人工神經(jīng)網(wǎng)絡(luò)的問題就變成了一個最優(yōu)化的問題,說的通俗點就是數(shù)學(xué)中的“找最大(最小)值”的問題。解決最優(yōu)化為題的常用方法是梯度下降法(Gradient Descent)

注:這里存在一個局部最優(yōu)解的問題,不過已經(jīng)被證明:在深度神經(jīng)網(wǎng)絡(luò)中,即使收斂過程進入了局部最優(yōu),最終結(jié)果也與全局最優(yōu)沒有明顯差異。

深度學(xué)習(xí)服務(wù)端框架

tensorFlow

2015年11月谷歌(Google)出品,基于Python和C++編寫。GitHub上最熱,谷歌搜索最多,使用人數(shù)最多(筆者也是其中之一),大多數(shù)網(wǎng)上招聘工作描述中也提到了它。由于Google在深度學(xué)習(xí)領(lǐng)域的巨大影響力和強大的推廣能力,TensorFlow一經(jīng)推出就獲得了極大的關(guān)注,并迅速成為如今用戶最多的深度學(xué)習(xí)框架。2019年3月已發(fā)布最新的TensorFlow2.0 版本。

官方網(wǎng)站:https://www.tensorflow.org/
優(yōu)點:

  • 自帶tensorboard可視化工具,能夠讓用戶實時監(jiān)控觀察訓(xùn)練過程
  • 擁有大量的開發(fā)者,有詳細的說明文檔、可查詢資料多
  • 支持多GPU、分布式訓(xùn)練,跨平臺運行能力強
  • 具備不局限于深度學(xué)習(xí)的多種用途,還有支持強化學(xué)習(xí)和其他算法的工具

缺點:

  • 頻繁變動的接口。TensorFlow的接口一直處于快速迭代之中,并且沒有很好地考慮向后兼容性,這導(dǎo)致現(xiàn)在許多開源代碼已經(jīng)無法在新版的TensorFlow上運行,同時也間接導(dǎo)致了許多基于TensorFlow的第三方框架出現(xiàn)BUG
  • 接口設(shè)計過于晦澀難懂,在設(shè)計TensorFlow時,創(chuàng)造了圖、會話、命名空間、PlaceHolder等諸多抽象概念,對初學(xué)者來說較難上手
  • 運行明顯比其他框架速度慢

keras

Keras 于2015年3月首次發(fā)布,擁有“為人類而不是機器設(shè)計的API”,得到Google的支持。它是一個用于快速構(gòu)建深度學(xué)習(xí)原型的高層神經(jīng)網(wǎng)絡(luò)庫,由純Python編寫而成,以TensorFlow,CNTK,Theano和MXNet為底層引擎,提供簡單易用的API接口,能夠極大地減少一般應(yīng)用下用戶的工作量。
如果你是深度學(xué)習(xí)的初學(xué)者,想要快速入門,建議從Keras開始。
官方網(wǎng)站:https://keras.io

優(yōu)點:

  • 更簡潔,更簡單的API
  • 豐富的教程和可重復(fù)使用的代碼
  • 更多的部署選項(直接并且通過TensorFlow后端),更簡單的模型導(dǎo)出

缺點:

  • 過度封裝導(dǎo)致喪失靈活性,導(dǎo)致用戶在新增操作或是獲取底層的數(shù)據(jù)信息時過于困難
  • 初學(xué)者容易依賴于 Keras 的易使用性而忽略底層原理

pytorch

PyTorch于2016年10月發(fā)布,是一款專注于直接處理數(shù)組表達式的低級API。 前身是 Torch(一個基于 Lua 語言的深度學(xué)習(xí)庫)。Facebook 人工智能研究院對PyTorch提供了強力支持。 PyTorch 支持動態(tài)計算圖,為更具數(shù)學(xué)傾向的用戶提供了更低層次的方法和更多的靈活性,目前許多新發(fā)表的論文都采用PyTorch作為論文實現(xiàn)的工具,成為學(xué)術(shù)研究的首選解決方案。

如果你是一名科研工作者,傾向于理解你的模型真正在做什么,那么就考慮選擇PyTorch。

官方網(wǎng)站:https://pytorch.org/

Caffe/Caffe2.0

Caffe的全稱是Convolutional Architecture for Fast Feature Embedding,它是一個清晰、高效的深度學(xué)習(xí)框架,于2013年底由加州大學(xué)伯克利分校開發(fā),核心語言是C++。它支持命令行、Python和MATLAB接口。Caffe的一個重要特色是可以在不編寫代碼的情況下訓(xùn)練和部署模型。

具體介紹見下文。

caffe框架

為何選擇caffe

我們暫時先選擇caffe框架作為分享目標(biāo),原因如下:

  • 與ncnn的兼容性好(最重點)
  • 不需要寫代碼就可以實現(xiàn)訓(xùn)練(可以作為深度學(xué)習(xí)的突破口)
  • 支持python接口,可以豐富編程化實現(xiàn)
  • 豐富的demo實現(xiàn)等

caffe環(huán)境搭建

推薦ubuntu系統(tǒng),參考博客:https://blog.csdn.net/wangjie5540/article/details/97786182
mac系統(tǒng)也可搭建,參考博客:https://blog.csdn.net/wangjie5540/article/details/99571832

caffe使用了眾多的依賴庫,再加上caffe年久失修,出現(xiàn)編譯兼容問題也不奇怪。推薦大家在ubuntu上進行編譯,可以驅(qū)動gpu,mac的最新14.14不支持n卡,據(jù)說需要降到14.13才可以。

caffe基礎(chǔ)

針對于神經(jīng)網(wǎng)絡(luò)的模型,caffe設(shè)計了對應(yīng)的概念。并且使用caffe來訓(xùn)練模型的過程非常簡單,甚至都不用寫一行代碼,僅僅改改配置文件也同樣能直接開始訓(xùn)練(當(dāng)然,用python去寫訓(xùn)練過程的話,會更加的靈活)。

數(shù)據(jù)集

  • 原始數(shù)據(jù),本文主要針對的是圖片數(shù)據(jù),可能有不同的格式(image格式、bytes格式、lmdb格式等)
  • 標(biāo)注數(shù)據(jù),監(jiān)督學(xué)習(xí),必須進行標(biāo)注

caffe傾向于先把數(shù)據(jù)集轉(zhuǎn)化成lmdb或者hdf5格式,然后輸入神經(jīng)網(wǎng)絡(luò)進行訓(xùn)練。

模塊概要圖


概要:

  • 使用數(shù)據(jù)構(gòu)建腳本,構(gòu)建訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)
  • caffe train命令加載solver的prototxt配置
  • solver配置加載神經(jīng)網(wǎng)絡(luò)配置
  • 神經(jīng)網(wǎng)絡(luò)對接訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)
  • 成千上萬次迭代,最終按照solver中的配置策略,周期性生成權(quán)重模型文件

solver(prototxt) 執(zhí)行者配置

超參數(shù)配置文件。
超參數(shù)的概念如下:

在機器學(xué)習(xí)的上下文中,超參數(shù)是在開始學(xué)習(xí)過程之前設(shè)置值的參數(shù),而不是通過訓(xùn)練得到的參數(shù)數(shù)據(jù)。通常情況下,需要對超參數(shù)進行優(yōu)化,給學(xué)習(xí)機選擇一組最優(yōu)超參數(shù),以提高學(xué)習(xí)的性能和效果

神經(jīng)網(wǎng)絡(luò)可視化

http://ethereon.github.io/netscope/#/editor
下面是對lenet的可視化,可以清楚的看到lenet的全貌。

  • mnist數(shù)據(jù)輸入
  • conv1,第一次卷積層
  • pool1,第一池化層
  • conv2,第二次卷積層
  • pool2,第二次池化層
  • ip1,全連接層(即多層感知機)
  • relu1,激活層
  • ip2,全連接層
  • loss,損失層(同時激發(fā)bn反向傳播操作)

caffe中的基礎(chǔ)概念

blobs

  • 對待處理數(shù)據(jù)帶一層封裝用于在Caffe中通信傳遞
  • 也為CPU和GPU間提供同步能力
  • 數(shù)學(xué)上,是一個N維的C風(fēng)格的存儲數(shù)組

總的來說,Caffe使用Blob來交流數(shù)據(jù),其是Caffe中標(biāo)準(zhǔn)的數(shù)組與統(tǒng)一的內(nèi)存接口,它是多功能的,在不同的應(yīng)用場景具有不同的含義,如可以是:batches of images, model parameters, and derivatives for optimization等
作者:漚江一流
鏈接:https://www.jianshu.com/p/0ac09c3ffec0

layer 神經(jīng)層

layer是caffe神經(jīng)網(wǎng)絡(luò)的基本組成單元。layer包括不同的種類:

  • Data,也就是blob的層
  • Convolution,卷積層
  • Pooling,池化層
  • InnerProduct,全連接
  • SoftmaxWithLoss,激活函數(shù)+loss層

不同的層次對應(yīng)了神經(jīng)網(wǎng)絡(luò)中的不通過概念。另外,每種類型的層在caffe的源碼中有特定的實現(xiàn),之后會在其他博客中展開討論,這里不再贅述。

net 神經(jīng)網(wǎng)絡(luò)

net是指神經(jīng)網(wǎng)絡(luò)定義,可以認為是layer的總和。在python版本編程中會出現(xiàn)net的概念。

forward/backward 前向傳播/反向傳播

forward和backward在python編程版本中會出現(xiàn),手動執(zhí)行會觸發(fā)一次前向傳播或反向傳播(python實現(xiàn)的caffe訓(xùn)練最終的本質(zhì)是在循環(huán)中每次手動觸發(fā)forward函數(shù),重點看一下本博客的caffe+mnist的python實現(xiàn)注釋版)。

caffe+mnist數(shù)據(jù)集+lenet

參考博客:https://blog.csdn.net/wangjie5540/article/details/98615226
python實現(xiàn)mnist(注釋版):https://gitee.com/simple_projects/caffe_learning/blob/master/01-learning-lenet-mine.ipynb

caffe+cifar10+caffenet

非常類似mnist數(shù)據(jù)集,參考:https://blog.csdn.net/wangjie5540/article/details/98615226

caffe+cifar10+mobilenet

參考:https://github.com/shicai/MobileNet-Caffe.git
shicai的mobilenet提供了預(yù)訓(xùn)練模型,可以直接進行數(shù)據(jù)預(yù)測。

大家肯定想,預(yù)訓(xùn)練模型沒什么意思,要自己訓(xùn)練才來實際。
參考:https://blog.csdn.net/lwplwf/article/details/82415525,可以使用cifar10進行模型訓(xùn)練。
(ps,作者用cpu訓(xùn)練了幾天,最終迭代了19w次,最終準(zhǔn)確率在70%,沒有達到很好的收斂效果。之后準(zhǔn)備好gpu的機器,還會再次訓(xùn)練,以觀后效)

注:cifar10的數(shù)據(jù)集進行模型訓(xùn)練的時候,出現(xiàn)mean的概念(即均值,rgb每個通道上的像素的平均值)。這樣做的目的是讓個像素的值以0為對稱點進行均勻分布,訓(xùn)練過程更容易收斂。有兩種獲取均值的方法:

  • 以數(shù)據(jù)集為目標(biāo),把每個通道上的像素值全部加和,然后求平均(caffe的cifar10就是使用的這種方法)
  • 直接使用均值(128,128,128),簡單暴力。(mobilenet+ssd的訓(xùn)練過程中就是這么做的,最終也能收斂)

以上兩種方法,暫時沒有證實哪個效果最好。

caffe+voc2012+vgg(finetune)+ssd(物體檢測模型)

參考:https://github.com/weiliu89/caffe.git
voc的數(shù)據(jù)集需要在外網(wǎng)下載,時間要好久好久。。我已經(jīng)把這些數(shù)據(jù)都下載完畢,上傳到云盤。以下是下載地址:https://download.csdn.net/download/wangjie5540/11598810
由于本次是遷移訓(xùn)練,預(yù)訓(xùn)練模型是vggnet,還需要下載vggnet,地址是:https://download.csdn.net/download/wangjie5540/11603902

注:博主用cpu訓(xùn)練跑了兩天,還沒有跑到第一次的快照地點。如果想自己訓(xùn)練的話,就選gpu的機器吧。

輕量級客戶端框架-ncnn

ncnn簡介

git地址:https://github.com/Tencent/ncnn
ncnn 是一個為手機端極致優(yōu)化的高性能神經(jīng)網(wǎng)絡(luò)前向計算框架。ncnn 從設(shè)計之初深刻考慮手機端的部署和使用。無第三方依賴,跨平臺,手機端 cpu 的速度快于目前所有已知的開源框架。基于 ncnn,開發(fā)者能夠?qū)⑸疃葘W(xué)習(xí)算法輕松移植到手機端高效執(zhí)行,開發(fā)出人工智能 APP,將 AI 帶到你的指尖。ncnn 目前已在騰訊多款應(yīng)用中使用,如 QQ,Qzone,微信,天天P圖等。

支持大部分常用的 CNN 網(wǎng)絡(luò)

  • Classical CNN: VGG AlexNet GoogleNet Inception …
  • Practical CNN: ResNet DenseNet SENet FPN …
  • Light-weight CNN: SqueezeNet MobileNetV1/V2/V3 ShuffleNetV1/V2 MNasNet …
  • Detection: MTCNN facedetection …
  • Detection: VGG-SSD MobileNet-SSD SqueezeNet-SSD MobileNetV2-SSDLite …
  • Detection: Faster-RCNN R-FCN …
  • Detection: YOLOV2 YOLOV3 MobileNet-YOLOV3 …
  • Segmentation: FCN PSPNet UNet …

ncnn+caffe+mobilenet實戰(zhàn)

ncnn環(huán)境搭建

先下載release版本的ncnn,我這里現(xiàn)在ncnn-20190611

$ cd <ncnn-root-dir> $ mkdir -p build-android-armv7 $ cd build-android-armv7$ cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \-DANDROID_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON \-DANDROID_PLATFORM=android-14 ..# if you want to enable vulkan, platform api version >= android-24 is needed $ cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \-DANDROID_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON \-DANDROID_PLATFORM=android-24 -DNCNN_VULKAN=ON ..$ make -j4 $ make installpick build-android-armv7/install folder for further jni usage

編譯完成后,生成以下文件

支持庫和頭文件供android的arm-v7a使用

模型轉(zhuǎn)化(caffe格式-> ncnn格式)

首先需要編譯caffe的環(huán)境。
參考:
https://blog.csdn.net/wangjie5540/article/details/97786182
https://blog.csdn.net/wangjie5540/article/details/99571832

源碼解析

文件目錄

├── README.md ├── app │ ├── build.gradle // android工程配置 │ ├── proguard-rules.pro // 混淆配置 │ └── src │ ├── androidTest │ │ └── java │ │ └── com │ │ └── ztjy │ │ └── ncnndemo │ │ └── ExampleInstrumentedTest.java │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ │ ├── mobilenet_v2.bin // mobilenet權(quán)重文件 │ │ │ ├── mobilenet_v2.param.bin // 神經(jīng)網(wǎng)絡(luò)參數(shù)文件 │ │ │ └── synset.txt // 分類索引文件 │ │ ├── cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── include // ncnn的頭文件 │ │ │ │ ├── allocator.h │ │ │ │ ├── benchmark.h │ │ │ │ ├── blob.h │ │ │ │ ├── caffe.pb.h │ │ │ │ ├── command.h │ │ │ │ ├── cpu.h │ │ │ │ ├── gpu.h │ │ │ │ ├── layer.h │ │ │ │ ├── layer_type.h │ │ │ │ ├── layer_type_enum.h │ │ │ │ ├── mat.h │ │ │ │ ├── mobilenet_v2.id.h │ │ │ │ ├── mobilenet_v2.mem.h │ │ │ │ ├── modelbin.h │ │ │ │ ├── net.h │ │ │ │ ├── opencv.h │ │ │ │ ├── option.h │ │ │ │ ├── paramdict.h │ │ │ │ ├── pipeline.h │ │ │ │ └── platform.h │ │ │ ├── jniLibs │ │ │ │ └── armeabi-v7a │ │ │ │ └── libncnn.a // ncnn靜態(tài)庫 │ │ │ └── native-lib.cpp │ │ ├── java │ │ │ └── com │ │ │ └── ztjy │ │ │ └── ncnndemo │ │ │ ├── MainActivity.java // 主窗體 │ │ │ ├── NcnnJni.java // jni交互文件 │ │ │ └── PhotoUtil.java // 圖片工具文類(從相冊中取文件) │ │ └── res │ │ ├── drawable │ │ │ └── ic_launcher_background.xml │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ ├── layout │ │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── ztjy │ └── ncnndemo │ └── ExampleUnitTest.java ├── build.gradle ├── gradle │ └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle

執(zhí)行流程

https://www.processon.com/view/link/5d5cfe08e4b08b95b82695bb

重點代碼

java層代碼

// predict imageprivate void predict_image(String image_path) {// picture to float arrayBitmap bmp = PhotoUtil.getScaleBitmap(image_path);Bitmap rgba = bmp.copy(Bitmap.Config.ARGB_8888, true);// resize to 227x227Bitmap input_bmp = Bitmap.createScaledBitmap(rgba, ddims[2], ddims[3], false);try {// Data format conversion takes too long// Log.d("inputData", Arrays.toString(inputData));long start = System.currentTimeMillis();// get predict result(調(diào)用jni層代碼,進行預(yù)測)float[] result = squeezencnn.detect(input_bmp);long end = System.currentTimeMillis();Log.d(TAG, "origin predict result:" + Arrays.toString(result));long time = end - start;Log.d(TAG, String.valueOf(result.length));// show predict result and timeint r = get_max_result(result);Log.d(TAG, r + "");Log.d(TAG, resultLabel.toString());Log.d(TAG, resultLabel.get(r));Log.d(TAG, result[r] + "");Log.d(TAG, time + "");String show_text = "result:" + r + ",name:" + resultLabel.get(r) + "\nprobability:" + result[r] + "\ntime:" + time + "ms";Log.d(TAG, show_text);result_text.setText(show_text);} catch (Exception e) {e.printStackTrace();}}

jni層代碼

// public native String Detect(Bitmap bitmap); JNIEXPORT jfloatArray JNICALL Java_com_ztjy_ncnndemo_NcnnJni_detect(JNIEnv *env, jobject thiz, jobject bitmap) {// ncnn from bitmapncnn::Mat in;{AndroidBitmapInfo info;// 獲取位圖信息AndroidBitmap_getInfo(env, bitmap, &info);// 獲取位圖寬高int width = info.width;int height = info.height;// demo只支持rgba格式的圖片if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888)return NULL;void *indata;AndroidBitmap_lockPixels(env, bitmap, &indata);// 把像素轉(zhuǎn)換成data,并指定通道順序in = ncnn::Mat::from_pixels((const unsigned char *) indata, ncnn::Mat::PIXEL_RGBA2BGR,width, height);AndroidBitmap_unlockPixels(env, bitmap);}// ncnn_net// std::vector<float> cls_scores;{// 減去均值和乘上比例(來源與caffe神經(jīng)網(wǎng)絡(luò)的配置文件,即prototxt文件)const float mean_vals[3] = {103.94f, 116.78f, 123.68f};const float scale[3] = {0.017f, 0.017f, 0.017f};// 設(shè)置均值與標(biāo)準(zhǔn)化參數(shù)in.substract_mean_normalize(mean_vals, scale);// 創(chuàng)建ncnn前向傳播的結(jié)果提取器ncnn::Extractor ex = ncnn_net.create_extractor();// 如果不加密使用ex.input("data", in);ex.input(mobilenet_v2_param_id::BLOB_data, in);ncnn::Mat out;// 如果不加密是使用ex.extract("prob", out);ex.extract(mobilenet_v2_param_id::BLOB_prob, out);int output_size = out.w;jfloat *output[output_size];for (int j = 0; j < out.w; j++) {output[j] = &out[j];}// 獲取結(jié)果預(yù)測結(jié)果,并返回給android層jfloatArray jOutputData = env->NewFloatArray(output_size);if (jOutputData == nullptr) return nullptr;env->SetFloatArrayRegion(jOutputData, 0, output_size,reinterpret_cast<const jfloat *>(*output)); // copyreturn jOutputData;} }

效果展示

caffe+mobilenet分類

其他工程的效果圖

https://github.com/chehongshu/ncnnforandroid_objectiondetection_Mobilenetssd.git
ncnn+mobilenet-ssd


相關(guān)學(xué)習(xí)資料

教學(xué)視頻

唐宇迪-深度學(xué)習(xí)Caffe框架入門視頻課程:https://edu.csdn.net/course/detail/3506
會寫代碼的好廚師-Caffe實戰(zhàn)入門:https://www.imooc.com/learn/1040

開源項目

caffe官網(wǎng):https://github.com/BVLC/caffe
ncnn:https://github.com/Tencent/ncnn.git
ncnn+mobilenet-ssd:https://github.com/chehongshu/ncnnforandroid_objectiondetection_Mobilenetssd
shicai_mobilenet:https://github.com/shicai/MobileNet-Caffe.git
weiliu89:https://github.com/weiliu89/caffe.git(需要check_out到ssd分支)

參考博客

在Android手機上使用騰訊的ncnn實現(xiàn)圖像分類:
https://blog.csdn.net/qq_33200967/article/details/82421089

總結(jié)

以上是生活随笔為你收集整理的深度学习-服务端训练+android客户端物体识别实战(caffe入门教程+mobilenet+ncnn+android)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。