TensorFlow集成Android工程的框架

歡迎Follow我的GitHub痹束,關(guān)注我的簡(jiǎn)書

在Android工程中宇色,集成TensorFlow模型。運(yùn)行TensorFlow的默認(rèn)Android工程施禾,請(qǐng)參考脚线。

Android源碼:https://github.com/SpikeKing/TFAndroid/tree/master

庫(kù)及模型的大小

libtensorflow_inference.so  10.2 M
libandroid_tensorflow_inference_java.jar  27 KB
optimized_tfdroid.pb  291 B

如果將so轉(zhuǎn)換為jar庫(kù),參考弥搞,則TF的so由10.2M縮小至4.1M邮绿。

TF Android

TensorFlow

TF模型源碼:
https://github.com/SpikeKing/MachineLearningTutorial/blob/master/tests/android_test.py

創(chuàng)建TensorFlow模型,簡(jiǎn)單的y=WX+b攀例,存儲(chǔ)圖信息write_graph船逮,存儲(chǔ)參數(shù)信息saver.save。輸入數(shù)據(jù)placeholder是I肛度,輸出數(shù)據(jù)是O傻唾。

import tensorflow as tf

I = tf.placeholder(tf.float32, shape=[None, 3], name='I')  # input
W = tf.Variable(tf.zeros(shape=[3, 2]), dtype=tf.float32, name='W')  # weights
b = tf.Variable(tf.zeros(shape=[2]), dtype=tf.float32, name='b')  # biases
O = tf.nn.relu(tf.matmul(I, W) + b, name='O')  # activation / output

saver = tf.train.Saver()
init_op = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init_op)

    tf.train.write_graph(sess.graph_def, './data/android/', 'tfdroid.pbtxt')  # 存儲(chǔ)TensorFlow的圖

    # 訓(xùn)練數(shù)據(jù),本例直接賦值
    sess.run(tf.assign(W, [[1, 2], [4, 5], [7, 8]]))
    sess.run(tf.assign(b, [1, 1]))

    # 存儲(chǔ)checkpoint文件承耿,即參數(shù)信息
    saver.save(sess, './data/android/tfdroid.ckpt')

創(chuàng)建Freeze的圖冠骄,將圖結(jié)構(gòu)與參數(shù)組合在一起,生成模型加袋,參考凛辣。

def gnr_freeze_graph(input_graph, input_saver, input_binary, input_checkpoint,
                     output_node_names, output_graph, clear_devices):
    """
    將輸入圖與參數(shù)結(jié)合在一起
    
    :param input_graph: 輸入圖
    :param input_saver: Saver解析器
    :param input_binary: 輸入圖的格式,false是文本职烧,true是二進(jìn)制
    :param input_checkpoint: checkpoint扁誓,檢查點(diǎn)文件
    
    :param output_node_names: 輸出節(jié)點(diǎn)名稱
    :param output_graph: 保存輸出文件
    :param clear_devices: 清除訓(xùn)練設(shè)備
    :return: NULL
    """
    restore_op_name = "save/restore_all"
    filename_tensor_name = "save/Const:0"

    freeze_graph.freeze_graph(
        input_graph=input_graph,  # 輸入圖
        input_saver=input_saver,  # Saver解析器
        input_binary=input_binary,  # 輸入圖的格式,false是文本蚀之,true是二進(jìn)制
        input_checkpoint=input_checkpoint,  # checkpoint蝗敢,檢查點(diǎn)文件
        output_node_names=output_node_names,  # 輸出節(jié)點(diǎn)名稱
        restore_op_name=restore_op_name,  # 從模型恢復(fù)節(jié)點(diǎn)的名字
        filename_tensor_name=filename_tensor_name,  # tensor名稱
        output_graph=output_graph,  # 保存輸出文件
        clear_devices=clear_devices,  # 清除訓(xùn)練設(shè)備
        initializer_nodes="")  # 初始化節(jié)點(diǎn)

優(yōu)化模型,剪切節(jié)點(diǎn)足删,模型只保留輸入輸出的參數(shù)寿谴。

def gnr_optimize_graph(graph_path, optimized_graph_path):
    """
    優(yōu)化圖
    :param graph_path: 原始圖
    :param optimized_graph_path: 優(yōu)化的圖
    :return: NULL
    """
    input_graph_def = tf.GraphDef()  # 讀取原始圖
    with tf.gfile.Open(graph_path, "r") as f:
        data = f.read()
        input_graph_def.ParseFromString(data)

    # 設(shè)置輸入輸出節(jié)點(diǎn),剪切分支失受,大約節(jié)省1/4
    output_graph_def = optimize_for_inference_lib.optimize_for_inference(
        input_graph_def,
        ["I"],  # an array of the input node(s)
        ["O"],  # an array of output nodes
        tf.float32.as_datatype_enum)

    # 存儲(chǔ)優(yōu)化的圖
    f = tf.gfile.FastGFile(optimized_graph_path, "w")
    f.write(output_graph_def.SerializeToString())

執(zhí)行函數(shù)讶泰,生成模型咏瑟,frozen_tfdroid.pboptimized_tfdroid.pb

if __name__ == "__main__":
    input_graph_path = MODEL_FOLDER + MODEL_NAME + '.pbtxt'  # 輸入圖
    checkpoint_path = MODEL_FOLDER + MODEL_NAME + '.ckpt'  # 輸入?yún)?shù)
    output_path = MODEL_FOLDER + 'frozen_' + MODEL_NAME + '.pb'  # Freeze模型

    gnr_freeze_graph(input_graph=input_graph_path, input_saver="",
                     input_binary=False, input_checkpoint=checkpoint_path,
                     output_node_names="O", output_graph=output_path, clear_devices=True)

    optimized_output_graph = MODEL_FOLDER + 'optimized_' + MODEL_NAME + '.pb'

    gnr_optimize_graph(output_path, optimized_output_graph)

Android

編譯Android的庫(kù)痪署,參考码泞,或者,直接在Nightly中下載狼犯,參考余寥,archive.zip,大約158M辜王。

創(chuàng)建Android工程劈狐,添加app/libs/中添加庫(kù)文件。

armeabi-v7a/libtensorflow_inference.so
libandroid_tensorflow_inference_java.jar

在build.gradle中呐馆,添加

android {
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}

在app/src/main/assets中肥缔,添加模型optimized_tfdroid.pb文件。

在MainActivity中汹来,添加so庫(kù)续膳。

static {
    System.loadLibrary("tensorflow_inference");
}

模型文件在assets中,TF的核心接口類TensorFlowInferenceInterface收班。

private static final String MODEL_FILE = "file:///android_asset/optimized_tfdroid.pb";

private TensorFlowInferenceInterface mInferenceInterface;

初始模型文件

mInferenceInterface = new TensorFlowInferenceInterface();
mInferenceInterface.initializeTensorFlow(getAssets(), MODEL_FILE);

模型Feed數(shù)據(jù)坟岔,輸入點(diǎn)名稱是INPUT_NODE,輸入結(jié)構(gòu)INPUT_SIZE摔桦,輸入數(shù)據(jù)inputFloats社付。

float[] inputFloats = {num1, num2, num3};
mInferenceInterface.fillNodeFloat(INPUT_NODE, INPUT_SIZE, inputFloats);

模型執(zhí)行文件,輸出點(diǎn)名稱是OUTPUT_NODE邻耕,即"O"

mInferenceInterface.runInference(new String[]{OUTPUT_NODE});

輸出數(shù)據(jù)結(jié)構(gòu)

float[] resu = {0, 0};
mInferenceInterface.readNodeFloat(OUTPUT_NODE, resu);

最后鸥咖,在layout中創(chuàng)建GUI布局。

效果

Demo

TensorFlow集成至春雨醫(yī)生

CY-TF

That's all! Enjoy it!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末兄世,一起剝皮案震驚了整個(gè)濱河市啼辣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌御滩,老刑警劉巖鸥拧,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異削解,居然都是意外死亡富弦,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門氛驮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)腕柜,“玉大人,你說(shuō)我怎么就攤上這事∠蔽眨” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵磷脯,是天一觀的道長(zhǎng)蛾找。 經(jīng)常有香客問(wèn)我,道長(zhǎng)赵誓,這世上最難降的妖魔是什么打毛? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮俩功,結(jié)果婚禮上幻枉,老公的妹妹穿的比我還像新娘。我一直安慰自己诡蜓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著警儒,像睡著了一般荠耽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上豺谈,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天郑象,我揣著相機(jī)與錄音,去河邊找鬼茬末。 笑死厂榛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丽惭。 我是一名探鬼主播击奶,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吐根!你這毒婦竟也來(lái)了正歼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拷橘,失蹤者是張志新(化名)和其女友劉穎局义,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冗疮,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萄唇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了术幔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片另萤。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出四敞,到底是詐尸還是另有隱情泛源,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布忿危,位于F島的核電站达箍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏铺厨。R本人自食惡果不足惜缎玫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望解滓。 院中可真熱鬧赃磨,春花似錦、人聲如沸洼裤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)逸邦。三九已至恩沛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缕减,已是汗流浹背雷客。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桥狡,地道東北人搅裙。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像裹芝,于是被迫代替她去往敵國(guó)和親部逮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,756評(píng)論 25 707
  • 曾國(guó)藩把學(xué)習(xí)作為提高個(gè)人修養(yǎng)的基本要求嫂易,將“敬德修業(yè)”當(dāng)做自己進(jìn)步的基礎(chǔ)兄朋。在他看來(lái),要想取得事業(yè)的成功怜械,就必須要積...
    friend6522閱讀 1,024評(píng)論 0 0
  • 這篇文章是本人在閱讀Dozer官方文檔(5.5.1版本颅和,官網(wǎng)已經(jīng)一年多沒(méi)更新了)的過(guò)程中,整理下來(lái)我認(rèn)為比較基礎(chǔ)的...
    靜默虛空閱讀 15,354評(píng)論 2 13
  • 原帖:http://www.cnblogs.com/kym/archive/2012/05/14/2498728....
    iFavorite閱讀 606評(píng)論 0 0
  • 那一曲戀歌教届,吟唱多年 您聽過(guò)鯉魚跳躍的聲音嗎响鹃?這是清晨的易湖湖畔,請(qǐng)你側(cè)耳傾聽案训。多少人一生沒(méi)有聽過(guò)這種聲音买置,住在湖...
    躲開讓我來(lái)閱讀 81評(píng)論 0 0