tensorflow和android零接触 (mac)

一. tensorflow和android的桥接库

源代码地址:

https://github.com/tensorflow/tensorflow

使用git下载下来:

git clone https://github.com/tensorflow/tensorflow.git

配置下编译环境:

vi WORKSPACE

找到下面两个配置,取消掉原有的注释,并且将本地路径填上去:

android_sdk_repository(

name = "androidsdk",

path = "---> here is your android sdk path <---",

)

android_ndk_repository(

name="androidndk",

path="---> here is your android ndk path <---",

api_level=14)

更改好后保存。 

从上面看,你要至少有android sdk,ndk的环境,没有的话自己百度下。

接着编译android对应的jar和so文件。

编译jar包:

bazel build //tensorflow/contrib/android:android_tensorflow_inference_java

产出物路径:

bazel-bin/tensorflow/contrib/android/libandroid_tensorflow_inference_java.jar

编译so文件:

bazel build -c opt //tensorflow/contrib/android:libtensorflow_inference.so--crosstool_top=//external:android/crosstool--host_crosstool_top=@bazel_tools//tools/cpp:toolchain--cpu=armeabi-v7a

产出物路径:

bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so

其中没有bazel工具的,可以通过brew安装下:

brew install bazel

最终的产出物,就是android和机器学习模型的一个桥梁,通过它们可以在android上加载机器学习的模型并且针对特定输入给予推荐的输出。

那么机器学习模型怎么获取呢?


二. 训练模型

先配置一下训练的环境。

python,可以下载2.7.13

https://www.python.org/downloads/release/python-2713/

直接包安装,记得刷新下环境变量。

source ~/.base_profile

tensorflow的python包,选择Mac CPU-only Python 2,下载好的文件假定是download_file

https://github.com/tensorflow/tensorflow

sudo pip install download_file

另外安装一些有用的包:

numpy,quandl,matplotlib

这里有numpy的介绍,它是python的一个计算库,提供丰富的数据结构:

https://docs.scipy.org/doc/numpy-dev/user/quickstart.html

环境都配置好了,我们以一个实际的例子,开始机器学习。


真实数据


上面的图形,展示了一组真实的数据,[x, y],我们希望通过已知的这些数据,预测当x=35时y的值。 (上面的数据,实际上是 y = 3 * x + 2 )

那么这个问题,怎么用机器学习的思路解决呢?

1. 需要建立一个模型,用于推测这些数据的规律。

如上面的数据,看起来是很简单的线性模型,我们建立模型如下:

y = a * x + b

2. 模型结构图

tensorflow提供了一个建立模型关系的框架,上述的数学模型可以分解为多个被称为tensor的节点,比如a, x,甚至乘法 *,这些形成一个单向图,如下:


模型图谱


上图把一个数学模型,分解成了由多个节点组成的单向图。

其中a和b,属于不确定的,我们希望通过数据训练得到的参数,在tensorflow中称为Variable;

而x和y,属于用于训练的原始数据,在tensorflow中称为placeholder,也就是占位符;

训练过程,就是持续不断的给这些占位符输入正确的数据,使得模型可以不断改进参数来尽量接近这些正确数据,最终训练的结果就是改进好的参数a和b; 这个过程,就像流水一样(flow),一遍遍的冲刷这个由tensor组成的模型图谱, 

3. 编程实现和训练

运行下面的py文件

#!/usr/bin/python

# -*- coding: utf-8 -*-

# 导入tensorflow和numpy

import tensorflow as tf

import numpy as np

# 准备训练数据,随机模拟[x, y]

tx = np.random.ranf(20)

ty = tx * 3 + 2

# 按照模型图谱,建立相应的节点

x = tf.placeholder("float", name='input')

y = tf.placeholder("float", name='output')

a = tf.Variable(0., name='a')

b = tf.Variable(0., name='b')

y_pred = tf.add(a * x,b, name='y_pred')

# 定义对训练效果的度量

error = tf.reduce_sum(tf.square(y - y_pred))

train = tf.train.GradientDescentOptimizer(0.03).minimize(error)

# 定义训练的最小偏差

min_loss = tf.constant(1e-3)

# 启动session

session = tf.Session()

session.run(tf.global_variables_initializer())

# 模拟训练

for i in range(500):

session.run(train, feed_dict={x : tx, y : ty})

a_value, b_value, error_value, is_ok = session.run([a, b, error, error < min_loss], feed_dict={x : tx, y : ty})

print a_value, b_value, error_value

if is_ok:

break

# 打印训练好的参数

result = session.run([a, b])

print result

# 保存模型和参数,文件为pb

output_graph_def = tf.graph_util.convert_variables_to_constants(session, session.graph_def,output_node_names=['input', 'output', 'a', 'b','y_pred'])

f = tf.gfile.FastGFile('fuck.pb', mode='wb')

f.write(output_graph_def.SerializeToString())

f.close()

# 终止会话

session.close()

训练结果展示:

2.61073 4.31385 89.048

1.30782 1.78556 29.8708

2.19754 3.12242 10.8184

1.83855 2.28745 4.55673

2.17195 2.68346 2.39239

2.10437 2.39156 1.55744

2.25308 2.49305 1.1679

2.27088 2.37789 0.93927

2.35422 2.38957 0.778111

2.39303 2.33406 0.652181

2.44999 2.3204 0.549087

2.49031 2.2868 0.463075

2.53413 2.2678 0.390786

2.57058 2.24364 0.329862

2.60621 2.22522 0.278461

2.63775 2.20617 0.235078

2.6674 2.18987 0.198456

2.69427 2.17421 0.167541

2.71916 2.1602 0.141441

2.74192 2.14712 0.119408

2.7629 2.13522 0.100807

2.78213 2.12422 0.0851035

2.79983 2.11415 0.0718459

2.81607 2.10487 0.060654

2.83101 2.09636 0.0512053

2.84473 2.08854 0.0432287

2.85733 2.08135 0.0364945

2.86892 2.07474 0.0308094

2.87956 2.06868 0.0260099

2.88934 2.0631 0.0219582

2.89832 2.05798 0.0185376

2.90657 2.05327 0.0156498

2.91416 2.04895 0.013212

2.92113 2.04497 0.0111538

2.92753 2.04132 0.0094163

2.93341 2.03797 0.00794944

2.93882 2.03488 0.00671111

2.94379 2.03205 0.00566565

2.94835 2.02945 0.00478304

2.95254 2.02706 0.00403797

2.9564 2.02486 0.00340894

2.95994 2.02284 0.00287788

2.96319 2.02099 0.00242957

2.96618 2.01929 0.00205113

2.96892 2.01772 0.0017316

2.97145 2.01628 0.00146184

2.97376 2.01496 0.00123412

2.97589 2.01375 0.00104187

2.97785 2.01263 0.000879567

[2.9778514, 2.012629]

上述程序运行后,会得到*.pb的文件,这个文件就是最终的模型和训练参数结果。

把这个结果保存下来,我们开始在android上,应用这个结果。


三. android上的模型应用

现在,我们已经得到了android桥接tensorflow的库(jar和so),还有一个训练好的模型(pb)。

新建一个android工程,将上述结果分别放置到:

1. jar包:   app/libs

2. so文件:app/src/jniLibs/armeabi/

3. pb文件:app/src/main/assets

然后在要使用的类中,加入对so的加载:

static {

    System.loadLibrary("tensorflow_inference");

}

最后导入TensorFlowInferenceInterface

mTensorFlowInterface = new TensorFlowInferenceInterface(getAssets(),"file:///android_asset/fuck.pb");

这样,相关的环境都ok了。

在使用pb前,我们回顾下,在上面的训练中导出的节点:

input(placeholder,需要提供数据)

output(placeholder,需要提供数据)

a, b(Variable,是训练好的参数或者需要训练的参数,这里可以作为输出数据)

y_pred(Operation,单向图节点,可以获取,可以作为输出)

开始三部曲:feed,run,fetch(提供数据,运行,获取数据)

1. 提供数据

mTensorFlowInterface.feed("input",new float[]{10.0f});

2. 运行目标节点

mTensorFlowInterface.run(new String[]{"y_pred"},false);

3. 获取结果

float[]result = new float[1];

mTensorFlowInterface.fetch("y_pred",result);

程序运行后展示:


demo展示

完整的demo如下:

链接: https://pan.baidu.com/s/1pLgEPMr 密码: 359f

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容

  • 与 TensorFlow 的初次相遇 https://jorditorres.org/wp-content/upl...
    布客飞龙阅读 3,932评论 2 89
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,672评论 2 59
  • 这两天在忙公司的事,没能写丰盛日记,看到群里小伙伴的丰盛和成长,内心非常开心,周围的人都如此上进;同时,内心也有一...
    吉祥_2022阅读 80评论 0 1
  • 瘦潘最近忧郁了 因为有一种叫青春的东西困扰着她 她不明白青春到底是什么?它的边界在哪里 只是隐隐觉得自己正与青春渐...
    曾国藩小姐姐阅读 145评论 0 12
  • 网上劲爆的陈羽凡发表离婚声明让吃瓜群众大跌眼镜 原来人家在2015年就已经离婚了哦 白百合人家那不算出轨 陈羽凡也...
    金澜爱写作阅读 581评论 0 0