第三课:把tensorflow,模型和测试数据导入Android工程
关于Android项目的创建这里就不做赘述了,我们直接进入主题,看下如何把机器学习库和训练的模型导入一个安卓应用中。
导入 Inference Interface
在上一课时中我们下载了 Inference Interface 的 nightly build 的 AAR 文件,这个AAR其实就是库文件,需要把这个文件导入到项目中,通常会把这个 AAR 文件放在 app/libs 下面:
为了导入这个 AAR,首先需要在 app/build.gradle 中声明一个本地的 flatDir 仓库:
repositories {
flatDir {
dirs 'libs'
}
}
然后指定依赖:
compile name: 'tensorflow', ext: 'aar'
最后再做一个 Project Sync 就完成了 Inference Interface 的导入,完整的 app/build.gradle 应该是这样的:
....
repositories {
flatDir {
dirs 'libs'
}
}
android{
.....
}
dependencies{
.....
compile name: 'tensorflow', ext: 'aar'
.....
}
导入 Pre-trained Model
在上一课时中已经下载了 Pre-trained model 的二进制包,解压缩这个包,会发现里面有这些文件:
其中model.ckpt.* 是我们在训练自己的模型时会用到的文件(下一系列课程我们会专门讲解如何训练自己的模型),这里暂时忽略;frozen_inference_graph.pb 文件正是我们需要的,开箱即用的模型文件,把这个文件作为一个 asset 导入项目中。在 Android Studio 中,单击 New | Folder | Assets Folder 命令创建一个 assets 目录,将 frozen_inference_graph.pb 复制到 assets 目录中,重命名为 model.pb。
导入测试数据
在机器学习的世界里面,绝大部分的输入和输出数据都是数字,换句话来说,当训练这个识别模型的时候,你不会告诉它这张图片上的是人,而是告诉它这个图片上面的物体代号是 1;模型在输出识别结果的时候,也不会输出人,汽车这样的字符,而是输出 1、2、3 这样的数字,那么这些数字代表的是什么,去哪里找这样的对应关系呢?
首先我们要清楚一点,模型和训练数据要存在一一对应关系。要么是使用的数据提前训练了模型,要么数据当下训练模型。因为TensorFlow Object Detection API 中的模型训练时使用的是 MS COCO 的物体数据集合,所以我们可以在这里(关注公众号,后台留言提供下载链接)下载到相应的标签文件, 我们打开这个文件:
0: unlabeled
1: person
2: bicycle
3: car
4: motorcycle
5: airplane
6: bus
7: train
8: truck
9: boat
10: traffic light
11: fire hydrant
12: street sign
13: stop sign
14: parking meter
15: bench
16: bird
17: cat
18: dog
19: horse
20: sheep
21: cow
22: elephant
23: bear
把这个文件也存到 assets 目录中,重命名为 labels.txt,现在 assets 目录应该是这样的:
关键的代码
现在相关的资源都导入到项目里面了,接下来我们写一点代码把模型和数据加载起来!
想一想我们需要做哪些工作:
- 加载模型 model.pb,获取一个 TensorFlowInferenceInterface 来进行后续操作。
TensorFlowInferenceInterface inferenceInterface = new TensorFlowInferenceInterface(getAssets(), "model.pb");
获取到 TensorFlowInferenceInterface 的对象之后就可以在这个对象上面输入图片数据并获取识别结果了。夸张的讲人工智能科学家大牛们现在研究的就是如何实现这个接口,这里我们先不探究原理,只会用就好,以后的系列课程我们慢慢的去剖析机器学习的原理。
- 把数据集 labels.txt 的内容读到数组中,供查询识别结果中的物体名称;
List<String> labels = new ArrayList<>();
InputStream labelsInput = getAssets().open("labels.text");
BufferedReader br = new BufferedReader(new InputStreamReader(labelsInput));
String line;
while ((line = br.readLine()) != null) {
labels.add(line);
}
br.close();
至此,相信你应该了解了tensorflow框架,训练模型,测试数据是如何在一个应用程序中实现的。是不是很简单!下一课程让我们一起完成一个完整的apk程序,也会把完成的源代码后台发给大家!
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Nautilus:一款基于语法的反馈式模糊测试工具
- R可视化 | 地理信息空间(下)
- 21页优雅读博指南:佐治亚理工学院助理教授Eric Gilbert撰写,入坑前必读
- Too old resource version 引起 Flink JobManager 崩溃的问题定位
- SharpHose:一款基于C#开发的Windows异步密码喷射工具
- PyTorch版YOLOv4更新了,不仅适用于自定义数据集,还集成了注意力和MobileNet
- 一行代码不用写,就可以训练、测试、使用模型,这个star量1.5k的项目帮你做到
- Android画板开发之橡皮擦功能
- Android画板开发之基本画笔功能
- python递归函数求n的阶乘,优缺点及递归次数设置方式
- Python 给下载文件显示进度条和下载时间的实现
- pytorch 中的重要模块化接口nn.Module的使用
- 东京大学版「一生一芯」:自制CPU、C编译器,还成功运行了类Unix系统
- python实现将range()函数生成的数字存储在一个列表中
- Pytorch 使用不同版本的cuda的方法步骤