深度學習的模型有很多,但是考慮到移動端的硬件限制,并不是所有模型都適合移植,在這里整理一下適合移植的模型。
圖片
“凍結”計算圖
train.py 將計算圖定義保存在了 .pb 文件當中。遺憾的是,大家無法直接將該計算圖加載至應用當中。完整的計算圖中包含的操作目前還不受TensorFlow C++/Java API的支持。正因為如此,我們才需要使用上圖中的工具。其中 freeze_graph 負責獲取 .pb 以及包含有 w 與 b 訓練結果值的 checkpoint 文件。其還會移除一切在移動端之上不受支持的操作。
在 tensorflow 目錄下運行該工具:
bazel-bin/tensorflow/python/tools/freeze_graph \
--input_graph=/tmp/voice/graph.pb --input_checkpoint=/tmp/voice/model \
--output_node_names=model/y_pred,inference/inference --input_binary \
--output_graph=/tmp/voice/frozen.pb
以上命令將在 frozen.pb 當中創(chuàng)建一套經過簡化的計算圖,其僅具備 y_pred 與 inference 兩個節(jié)點,不包含任何用于訓練的計算圖節(jié)點。
使用 freeze_graph 的好處在于,其還將固定該文件中的權重值,這樣大家就無需分別進行權重值加載了:frozen.pb中已經包含我們需要的一切。而 optimize 工具則負責對計算圖進行進一步簡化。其將作為 grozen.pb 文件的輸入內容,并寫入 inference.pb 作為輸出結果。我們隨后會將此文件嵌入至應用當中。使用以下命令運行該工具:
bazel-bin/tensorflow/python/tools/optimize_for_inference \
--input=/tmp/voice/frozen.pb --output=/tmp/voice/inference.pb \
--input_names=inputs/x --output_names=model/y_pred,inference/inference \
--frozen_graph=True
實現(xiàn)過程
- 了解模型結構(LeNet、AlexNet、VGG、Incetption V3...)
- 在 pc 端做
遷移學習
(深度學習訓練需要數(shù)周時間、遷移學習只需幾小時),保存為 pb 模型
注:遷移學習是利用已有模型,在最后一層進行重新分類訓練 - 在 pc 端進行簡單的模型準確度驗證
- 對 pb 模型進行優(yōu)化、壓縮移植到移動端(可以使模型大小減小75%,精度僅略微下降)
- 在移動端恢復模型
- 模型產品化
在移動端要做的事情不多,一般來說,只需完成以下工作:
- 從.pb文件中加載計算圖與權重值
- 利用此計算圖創(chuàng)建一項會話
- 將您的數(shù)據放置在一個輸入張量內
- 在一個或者多個節(jié)點上運行計算圖
- 從輸出結果張量中獲取結果z
demo: 實時識別出是哪一種公仔(coin 存錢罐、羊年公仔、猴年公仔)
聲音
訓練集 由3,168個聲音樣本組成,并區(qū)分為男聲和女聲。通過分析聲音的20種聲學特性,可以達到99%的準確度。
可以看一下基于這個訓練集的 web 應用: What is Your Voice Gender?
識別效果圖:
下載該數(shù)據集并打開 voice.csv 文件之后,大家會看到其中包含著一排排數(shù)字:
這里列出的并非實際音頻數(shù)據,這些數(shù)字代表著語音記錄當中的不同聲學特征。這些屬性或者特征由一套腳本自音頻記錄中提取得出,并被轉化為這個 CSV 文件。具體提取方式可點擊此處查閱 R 源代碼。
每一項示例中存在20項聲學特征,例如:
- 以kHz為單位的平均頻率
- 頻率的標準差
- 頻譜平坦度
- 頻譜熵
- 峰度
- 聲學信號中測得的最大基頻
- 調制指數(shù)
- 等等……
在以下示意圖當中,大家可以看到這20個數(shù)字全部接入一個名為 sum 的小框。這些連接擁有不同的 weights(權重),對于分類器而言代表著這20個數(shù)字各自不同的重要程度。
sum = x[0]*w[0] + x[1]*w[1] + x[2]*w[2] + ... + x[19]*w[19] + b
數(shù)組 w 中的權重與值 b 代表著此分類器所學習到的經驗。對該分類器進行訓練的過程,實際上是為了幫助其找到與 w 及 b 正確匹配的數(shù)字。最初,我們將首先將全部 w 與 b 設置為0。在數(shù)輪訓練之后,w 與 b 則將包含一組數(shù)字,分類器將利用這些數(shù)字將輸入語音中的男聲與女聲區(qū)分開來。為了能夠將 sum 轉化為一條概率值——其取值在0與1之間——我們在這里使用 sigmoid 函數(shù):
y_pred = 1 / (1 + exp(-sum))
如果 sum 是一個較大正數(shù),則 sigmoid 函數(shù)返回1或者概率為100%; 如果 sum 是一個較大負數(shù),則 sigmoid 函數(shù)返回0。因此對于較大的正或者負數(shù),我們即可得出較為肯定的“是”或者“否”預測結論。
現(xiàn)在 y_pred 中包含的預測結果顯示,該語音為男聲的可能性更高。如果其概率高于0.5,則我們認為語音為男聲; 相反則為女聲。
決策樹:
移植到安卓端:
floatValues 數(shù)組:這里面保存的是20種聲音聲學特性
如果大家希望在一款應用程序當中使用此分類器,通過錄音或者來自麥克風的音頻信息檢測語音性別,則首先需要從此類音頻數(shù)據中提取聲學特征。在擁有了這20個數(shù)字之后,大家即可對其分類器加以訓練,并利用其判斷語音內容為男聲還是女聲。
更多參考資料:
http://www.primaryobjects.com/2016/06/22/identifying-the-gender-of-a-voice-using-machine-learning
https://github.com/primaryobjects/voice-gender
http://www.infoq.com/cn/articles/getting-started-with-tensorflow-on-ios
char-rnn
char-rnn 是一個字符水平的語言模型,通過訓練文本文件可以預測序列中下一個出現(xiàn)的字符,并以此來生成完整的文本。
應用場景
- 寫武俠小說
- 訓練汪峰歌詞可以得到汪峰風格的歌詞
我在這里中的夜里
就像一場是一種生命的意旪
就像我的生活變得在我一樣
可我們這是一個知道
我只是一天你會怎嗎
可我們這是我們的是不要為你
我們想這有一種生活的時候
我在哭泣
我不能及你的時光
我是我們在這是一種無法少得可以沒有一天
我們想這樣
我們遠在一場我在我一個相多地在此向
可我是個想已經把我的時候
我看到在心悄一種痛定的時候
我看著我的感覺在飛歌
我不能在這多在心中
就像在我一瞬間
我的生命中的感覺
我在我一次到孤獨所
我們在這是一看可以是一場我們在這樣
我在這里失命
我不能在這感覺在天里
夜里
夜里
沒有一天 我想心的是不嗎到了
- 寫古詩
優(yōu)勢:對于大多數(shù)用戶來說,不在乎詩的平仄、韻律,而在于其中的意境(用戶鐘愛情詩和藏頭詩)
目前在云 GPU 上完成模型的訓練,并在 pc 上實現(xiàn)自動寫詩功能
奇了了不為
點石上風煙
你憑欄干將
好事系在邊
參考文章:
http://www.infoq.com/cn/articles/getting-started-with-tensorflow-on-ios
https://www.zhihu.com/question/21329754
https://github.com/primaryobjects/voice-gender
深度學習1--淺談char-rnn三種模型