本文首發於微信公衆號——世界上有意思的事,搬運轉載請註明出處,不然將追究版權責任。微信號:a1018998632,交流qq羣:859640274 node
最近學了近一個月半月的深度學習,因此想檢驗一下學習成果。正好畢設是圖像處理APP的實現,因此就把快速風格遷移 的前饋神經網絡 經過Tensorflow for Android 移植到了APP上面,做爲濾鏡快速風格遷移的 效果還挺不錯,就是速度有點慢。可能和如今Android端的深度學習還不支持gpu有關吧。android
1.關於MyPhotoShop
這是一個圖片處理APP,裏面使用了Opencv、深度學習、MVVM、Databinding、RxJava、各類設計模式等等 ,在後面一段時間我會寫一系列博客來一步步剖析這個項目,但願你們能多多關注。git
1.效果
2.項目相關
3.缺點
1.沒有組件化
2.沒有混淆
3.有些地方抽象不夠
2.深度學習和神經網絡的基本概念
1.什麼是深度學習
1.AI--》機器學習--》深度學習,前面三個概念是遞進的,簡單來講深度學習 是機器學習的一種,深度學習 就是利用機器來學習不少數據,而機器學習又是實現AI的一種方式。
2.在深度學習中有兩個重要的東西:數據和神經網絡。在深度學習中有兩個重要的過程:訓練和測試
1.數據和網絡:
1.數據:咱們想象一個簡單的圖片分類場景,咱們有10000張已經被人工分好類的圖片,每張圖片都有一個正確的分類,好比貓、狗等等。
2.網絡:這裏的神經網絡 咱們能夠想象成一個函數,咱們的輸入是一張圖片,輸出則是這張圖片在每一個分類下面的分數。也就是一個分數的數組。
2.訓練和測試:
1.訓練:在訓練的時候咱們會將圖片集中的圖片一次次的輸入到神經網絡 裏面去,而後會一次次獲得該圖片在每一個分類下的分數,每當咱們得出了一個分數數組以後咱們能夠計算當前的神經網絡 的損失值(當前的網絡準確率越高損失值越低) ,有了損失值 ,咱們的目標就是下降損失值 。瞭解導數的同窗都知道咱們能夠經過求導損失值函數 獲得讓損失值 下降的梯度方向,而後反饋到神經網絡 中。就這樣一次次的循環,讓損失值 降到最低。
2.測試:當咱們將神經網絡 訓練到了一個最佳的狀態,咱們就能夠將咱們須要進行分類的圖片,輸入到神經網絡 中,獲得最終神經網絡 對該圖片分類的結果。
3.總結:深度學習究竟是怎麼學習的呢?咱們能夠看見咱們的訓練數據是通過人的處理的,那麼深度學習的過程就是將人的處理過程固化到咱們的神經網絡 中,最終讓神經網絡 來代替人工處理的過程。
4.上面只是介紹深度學習的基本流程,若是要更深刻的瞭解能夠看這篇博客
2.什麼是神經網絡
咱們在上一節中說到了,最終人處理數據的過程經過咱們的訓練被固化到神經網絡 中去了。下面我會簡單介紹一下前面說到的神經網絡 。程序員
1.仍是在簡單的圖片分類場景:
1.咱們假設圖片爲x的大小爲100 * 100(咱們把圖片平鋪成爲1 * 10000的矩陣),圖片一共有10個分類。
2.那麼一個兩層的神經網絡 就是這樣的:y = x * w1 * w2(w1爲 10000 * a的矩陣,w2爲a * 10的矩陣),這裏最終y就是一張圖片在各個分類下的分數,式子中的乘法是矩陣乘法。
3.固然層數更多的神經網絡 就是有更多的w,咱們w1 和 w2中的a能夠本身定義。
2.解釋一下y = x * w1 * w2:
1.研究代表咱們在看x這張圖片的時候,咱們會先看圖片的輪廓,這裏咱們大腦中看圖片輪廓的神經元就至關於w1
2.看完輪廓以後咱們會對這個圖片中的東西有基本感受,判斷這張圖片屬於哪些類別,這裏的類別就是x * w1的結果
3.2中的結果會被輸入大腦中下一層神經元,這裏的神經元就至關於w2,通過w2以後咱們就會輸出一個結果這裏就是y。
4.固然人的神經元層數遠比上面說到的多
3.訓練y = x * w1 * w2的過程以人作對比就至關於:咱們有一堆圖片給一個啥也不懂的小孩看,剛開始他確定輸出的結果都是錯的,可是咱們只要每次糾正一下他的錯誤,那麼他腦殼中的神經元(w)就會不斷的修改而後識別的準確率不斷提升。
3.Android中的Tensorflow
這一節將會介紹如何在Android中使用已經訓練好的神經網絡 github
1.開始
本篇文章中,我只會以一個demo爲例子進行講解,前面提到的MyPhotoShop 項目會另起一個專題進行剖析。編程
1.demo地址:github地址
2.引入Tensorflow:compile 'org.tensorflow:tensorflow-android:+'
2.Tensorflow中的概念
1.圖(graph):咱們在前面講解了一個神經網絡 是什麼樣子的,在Tensorflow中神經網絡 的每一個神經元w都屬於圖中的一個節點,神經網絡 所有的節點就構成了一個有向無環圖也就是Tensorflow的圖的一部分。固然Tensorflow的圖中除了神經網絡 的節點外,還有其餘輔助的操做:好比圖片解碼、圖片編碼、圖片預處理操做等等。咱們舉一個圖的例子就是:圖片a--》解碼圖片產生b--》處理b產生圖片數據矩陣c(1 * 10000)--》c與w1(10000 * x)矩陣相乘產生d(1 * x)--》d與w2(x * 10)矩陣相乘產生e(1 * 10)--》選出e中值最大的分類,神經網絡 就判斷圖片a是這種分類的圖片。
2.節點(node):每一個節點都是圖的一部分,每一個節點有:入參、出參、具體操做函數(好比矩陣乘法)、可能有神經元值w。
3.TensorFlowInferenceInterface:一個Tensorflow中訓練的上下文,在不一樣語言中名字不一樣。內部包含了一個訓練中須要的所有實例。
3.demo代碼講解
咱們本次demo中只涉及Tensorflow在Android中神經網絡 模型的使用,並不涉及訓練的過程。緣由有兩個:1.移動端並不適合訓練神經網絡 2.Tensorflow for Android沒有訓練的API。設計模式
1.我此次使用的神經網絡 是已經訓練好的快速風格遷移網絡
2.對於模型咱們的輸入是:一張圖片轉化爲的float類型的張量,大小爲(1 * 800 * 600 * 3),輸入節點的名字是padsss:0 ,這裏的名字是在訓練過程當中定義的。
3.對於這個模型咱們的輸出是:大小爲(1 * 780 * 680 * 3)的float類型張量。輸出節點的名字是squeezesss:0 ,名字也是在訓練過程當中定義的。
4.咱們看代碼,先用RxPermission獲取了一下權限,獲取成功以後將assets中須要處理的圖片寫入到sd卡中一遍後面使用,進入make()方法
5.將4中的圖片讀取到內存中
6.以ARGB爲例咱們知道Bitmap中每一個像素是以int十六進制儲存像素的,相似這種形式FFFFFFFF ,那麼每兩位就是一個通道的數值,上限是256。因此接下來就是將Bitmap中的像素值,轉化爲float類型的數組,數組大小是(800 * 600 * 3)。
7.建立了一個TensorFlowInferenceInterface對象,入參是AssetManager和模型文件,這裏就表示將神經網絡 在內存中創建起來
8.輸出一下每一個節點的名字
9.向神經網絡 中傳入輸入節點的名字、輸入節點的數據、數據張量的維度
10.運行神經網絡 ,入參是輸出節點的名字
11.神經網絡 的運行時阻塞的,因此運行好了以後,就能獲取數據了,這裏將數據存入(780 * 580 * 3)的float數組中。
12.將float數組從新整合成Bitmap的像素值,而後寫入Bitmap中。
4.注意點
1.demo運行的時候速度會比較慢,耐心等待一下
2.我運行的設備是:小米mix二、Android8.0。其餘設備可能會有問題,要麼就是速度很是慢,還多是cpu或者系統版本不支持。
4.總結
在Android中運行一個已經訓練好的神經網絡 仍是比較簡單的,只要知道了輸入輸出,就像運行一個普通的函數那麼簡單。至於如何去訓練一個神經網絡 ,那就是另外的故事了,能夠關注個人我學機器學習 文集!裏面會持續更新我學習機器學習的心得和體會。數組
不販賣焦慮,也不標題黨。分享一些這個世界上有意思的事情。題材包括且不限於:科幻、科學、科技、互聯網、程序員、計算機編程。下面是個人微信公衆號:世界上有意思的事 ,乾貨多多等你來看。 微信