TensorFlow在iOS和Mac上的使用

简介: 一、环境 1、首先你得安装好Xcode 8,确定开发者目录指向你安装Xcode的位置并且已经被激活。(如果你在安装Xcode之前已经安装了Homebrew,这可能会指向错误的地址,导致TensorFlow安装失败): sudo xcode-select -s /Applications/Xcode.

一、环境


1首先你得安装好Xcode 8,确定开发者目录指向你安装Xcode的位置并且已经被激活。(如果你在安装Xcode之前已经安装了Homebrew,这可能会指向错误的地址,导致TensorFlow安装失败):


sudo xcode-select -s /Applications/Xcode.app/Contents/Developer


2、安装Homebrewhttps://brew.sh/index_zh-cn.html


3Homebrew安装其他软件


brew install python3

brew cask install java

brew install bazel

brew install automake

brew install libtool

brew install wget


4、命令:brew list 查看已安装的软件

FBD439D4-C8D0-4DF5-8DF3-FFAFF50AEAEE.png


5、成功安装了python3,那pip3也随着被安装了,使用python3 的包管理器pip3来安装所需要的包。


pip3 install numpy

pip3 install scipy

pip3 install scikit-learn

pip3 install pandas

pip3 install tensorflow


6、命令:pip3 list 查看已安装的包

5fc5acfe44cdb3c50c9fa399db4daa95d6699128


这些包会安装在/usr/local/lib/python3.6/site-packages目录下。


7、下载TensorFlow源码,需要使用源码文件编译模型,并且使用官方iOSDemo

克隆TensorFlow GitHub仓库。注意,一定要保存在没有空格的路径下,否则bazel会拒绝构建。我是克隆到我的主目录下:


cd /Users/javalong/Downloads/Tensorflow

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

  

一旦GitHub仓库克隆完毕,你就需要运行配置脚本(configure script:


cd /Users/javalong/Downloads/Tensorflow/tensorflow-master

./configure


这里有些地方可能需要你自行配置,比如:


Please specify the location of python. [Default is /usr/bin/python]:


我写的是/usr/local/bin/python3,因为我使用的是Python 3.6。如果你选择默认选项,就会使用Python 2.7来创建TensorFlow


Please specify optimization flags to use during compilation [Default is 

-march=native]:


这里只需要按Enter键。后面两个问题,只需要选择n(表示 no)。当询问使用哪个Python库时,按Enter键选择默认选项(应该是Python 3.6 库)。剩下的问题都选择n。随后,这个脚本将会下载大量的依赖项并准备构建TensorFlow所需的一切。


8、构建静态库

有两种方法构建TensorFlow1.Mac上使用bazel工具;2.IOS上,使用Makefile。我们是在IOS上构建,所以选择第2种方式。不过因为会用到一些工具,也会用到第一种方式。


TensorFlow的目录中执行以下脚本:


tensorflow/contrib/makefile/build_all_ios.sh


这个脚本首先会下载一些依赖项,然后开始构建。一切顺利的话,它会创建三个链入你的app的静态库:libtensorflow-core.a libprotobuf.a libprotobuf-lite.a

还有另外两个工具需要构建,在终端运行如下两行命令:


bazel build tensorflow/python/tools:freeze_graph

bazel build tensorflow/python/tools:optimize_for_inference


Note: 这个过程至少需要20分钟,因为它会从头开始构建TensorFlow(本次使用的是bazel)。如果遇到问题,请参考官方指导



9iOS工程配置引用参考:


9.1Other Linker Flags : 

-force_load $(SRCROOT)/../../makefile/gen/lib/libtensorflow-core.a

如图:

8b6d1f87e498c091361659e199c46660b9380dc3


9.2、Header Search Paths : 

$(SRCROOT)/../../makefile/gen/proto $(SRCROOT)/../../makefile/downloads/eigen $(SRCROOT)/../../makefile/downloads $(SRCROOT)/../../makefile/downloads/protobuf/src/ $(SRCROOT)/../../../..


9.3、Libaray Search Paths :

$(SRCROOT)/../../makefile/gen/lib $(SRCROOT)/../../makefile/gen/protobuf_ios/lib


如图:

fc8f8800da4e2bbc7c51127bebc9405c6cd5ec31


9.4、Demo工程与makefile目录相对关系如图:

ef15fed656748c65635bedec2d2184e1208473ff


10、库的引用如图:

6ab50187f6d9616aed236634a119de2df2160085


二、模型训练


1.下载数据


cd /Users/javalong/Desktop

mkdir Test

cd Test

curl -O http://download.tensorflow.org/example_images/flower_photos.tgz

tar xzf flower_photos.tgz


进入flower_photos,可以看到5个文件夹,daisy dandelion roses sunflowers tulips


d9bb3338f89439ed8cf5711a521e3e62e364c955



2. 利用预训练模型训练数据


模型是谷歌的Inceptionv3http://arxiv.org/abs/1512.00567)。在2012年的imageNet上进行训练,并在2012ImageNet上取得了3.4%top-5准确率(人类的只有5%

这么一个复杂的网络若是直接自己训练,起码需要几天甚至十几天的时间。所以这里我采用复用深度学习的方法。即模型前面的层的参数都不变,而只训练最后一层的方法。最后一层是一个softmax分类器,这个分类器在原来的网络上是1000个输出节点(ImageNet1000个类),所以需要删除网络的最后的一层,变为所需要的输出节点数量,然后再进行训练。

tensorflow/examples/image_retraining/retrain.py 中采用的方法是这样的:将自己的训练集中的每张图像输入网络,最后在瓶颈层(bottleneck),就是倒数第二层,会生成一个2048维度的特征向量,将这个特征保存在一个txt文件中,再用这个特征来训练softmax分类器。


进入tensorflow源代码目录


2.1

cd /Users/javalong/Downloads/Tensorflow/tensorflow-master


2.2

python3 tensorflow/examples/image_retraining/retrain.py \

--bottleneck_dir=/Users/javalong/Desktop/Test/ \

--how_many_training_steps 100000 \

--model_dir=/Users/javalong/Desktop/Test/inception2 \

--output_graph=/Users/javalong/Desktop/Test/retrained_graph2.pb \

--output_labels=/Users/javalong/Desktop/Test/retrained_labels.txt \

--image_dir=/Users/javalong/Desktop/Test/flower_photos


脚本会下载Inceptionv3模型,80多兆,可以提前下载好放到Testinception2目录下

模型路径:http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz

训练完成后,在Test目录下看到模型文件retrained_graph.pb和标签retrained_labels.txt


3. 模型验证


新建文件label_image.py,注意格式,代码缩进使用tab


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

import os

import numpy as np

import tensorflow as tf

from sklearn import metrics



# 随便一张玫瑰花图片

image_path = "test1.jpg"


# read in the image_data

image_data = tf.gfile.FastGFile(image_path, "rb").read()


# Loads label file, strips off carriage return

label_lines = [line.strip() for line in tf.gfile.GFile("retrained_labels.txt")]


# Unpersists graph from file

with tf.gfile.FastGFile("retrained_graph2.pb", "rb") as f:

    graph_def = tf.GraphDef()

    graph_def.ParseFromString(f.read())

    _ = tf.import_graph_def(graph_def, name="")


with tf.Session() as sess:

# Feed the image_data as input to the graph and get first prediction

    softmax_tensor = sess.graph.get_tensor_by_name("final_result:0")

    preditions = sess.run(softmax_tensor, {"DecodeJpeg/contents:0":image_data})

# sort to show labels of first prediction in order of confidence

    top_k = preditions[0].argsort()[-len(preditions[0]):][::-1]

    for node_id in top_k:

        human_string = label_lines[node_id]

        score = preditions[0][node_id]

        print('%s (score = %.5f' %(human_string, score))


执行文件

python label_image.py 


得到类似下图结果

1d9742b24d5ccd4af906516a34476abf074b7bb9




、编译模型


将模型文件转化成ios可以上可以运行的文件


1、首先编译tensorflow源码示例中的label_image来测试retrained_graph2.pb模型

1.1

cd /Users/javalong/Downloads/Tensorflow/tensorflow-master


1.2

bazel build tensorflow/examples/label_image:label_image


1.3

bazel-bin/tensorflow/examples/label_image/label_image \

--output_layer=final_result \

--labels=/Users/javalong/Desktop/Test/retrained_labels.txt \

--image=/Users/javalong/Desktop/Test/flower_photos/daisy/5547758_eea9edfd54_n.jpg \

--graph=/Users/javalong/Desktop/Test/retrained_graph2.pb


如图所示:

9455ebd24166d4b52bb2ce935fcd7c2476a703a2


2、优化模型并去掉ios不支持的算子

翻译文章中说明如下:

由于移动设备内存有限,并且app需要下载,因此TensorFlowiOS版本只支持那些推理中常见的算子(ops,提供英文原文以防翻译错误),没有大量支持扩展的依赖项。你可以在tensorflow/contrib/makefile/tf_op_files.txt这个文件中找到可以使用的算子列表。

文章中提到,DecodeJpeg是不能使用的算子之一,因为其实现方法依赖于libjpeg,而它在iOS上运行非常麻烦(painful to support),并且增加binary footprint(不懂。。。)。尽管可以用iOS原生的图像库实现,大部分应用其实直接图像buffer而不需要对jpeg进行编码。

问题麻烦的地方在于,我们使用的Inception模型包括了DecodeJpeg算子。我们通过直接将图片数据传给Mul结点绕过DecodeJpeg操作。尽管如此,图被加载的时候,如果平台不支持,即使算子没有被调用,还是会报错,因此我们利用optimize_for_inference去掉所有没有被输入和输出结点用到的结点。这个脚本同时会完成一些优化来加速,例如将batch normalization转换成卷积权重(the convolutional weights)来减少计算次数。


2.1、

bazel build tensorflow/python/tools:optimize_for_inference


2.2

bazel-bin/tensorflow/python/tools/optimize_for_inference \

--input=/Users/javalong/Desktop/Test/retrained_graph2.pb \

--output=/Users/javalong/Desktop/Test/optimized_graph.pb \

--input_names=Mul \

--output_names=final_result


如图所示:

0c845d2225e22821a527441f525fdd09a6df48f5


同样可以通过label_image验证optimized_graph.pb模型的有效性。


3、将模型的权重变成256之内的常数

优化前模型87.5M,优化后的模型还是有87.2M,可以损失一定的精确度,将模型的权重从浮点型转化成整数。

3.1、 

bazel build tensorflow/tools/quantization:quantize_graph


3.2

bazel-bin/tensorflow/tools/quantization/quantize_graph --input=/Users/javalong/Desktop/Test/optimized_graph.pb \

--output=/Users/javalong/Desktop/Test/rounded_graph.pb \

--output_node_names=final_result \

--mode=weights_rounded


如图所示:

6c877e5ebcd31fd41e8d6a6cadd19b025a5e092e


4、验证rounded_graph.pb模型

4.1、

bazel-bin/tensorflow/examples/label_image/label_image \

--output_layer=final_result \

--labels=/Users/javalong/Desktop/Test/retrained_labels.txt \

--image=/Users/javalong/Desktop/Test/flower_photos/daisy/5547758_eea9edfd54_n.jpg \

--graph=/Users/javalong/Desktop/Test/rounded_graph.pb


如图所示:

458b3b4b19f5db9305eaefa7864c189ecda05e04


5、内存映射(memory mapping

由于app87M的模型权值加载到内存中,会对RAM带来压力导致稳定性问题,因为OS可能会杀死占用内存太多的应用。幸运的是,这些缓冲区的内容是只读的,能以os在内存遇到压力的时候很容易释放的方式将模型映射到内存中。为此,我们将模型转换成可以从GraphDef分别加载到形式。

5.1、

bazel build tensorflow/contrib/util:convert_graphdef_memmapped_format


5.2

bazel-bin/tensorflow/contrib/util/convert_graphdef_memmapped_format \

--in_graph=/Users/javalong/Desktop/Test/rounded_graph.pb \

--out_graph=/Users/javalong/Desktop/Test/mmapped_graph.pb


需要注意的是,此时模型文件已经不是一般的GraphDef protobuf,所以如果还按照以前的方法加载会遇到错误。


5.3、

bazel-bin/tensorflow/examples/label_image/label_image \

--output_layer=final_result \

--labels=/Users/javalong/Desktop/Test/retrained_labels.txt \

--image=/Users/javalong/Desktop/Test/flower_photos/daisy/5547758_eea9edfd54_n.jpg \

--graph=/Users/javalong/Desktop/Test/mmapped_graph.pb


如图所示:

5213021205abcf7851bf3b6b60567baf8d300fdd


四、使用iOS Demo工程


1demo是在tensorflow官方提供的ios示例代码camera的基础上进行的修改,工程路径:tensorflow/contrib/ios_examples/camera

2、将rounded_graph.pbretrained_labels.txt导入到data目录下。

3、修改CameraExampleViewController.mm中要加载到文件,图片等尺寸,结点的名字和如何缩放像素值。


a47c2f0423974ca3963a820bc43c84da87f699bd


4、最后程序运行的结果如下:


b39adfa86faae031e8e48c6618f39204d0467ed1




目录
相关文章
|
Linux Android开发 iOS开发
基于.Net开发的ChatGPT客户端,兼容Windows、IOS、安卓、MacOS、Linux
基于.Net开发的ChatGPT客户端,兼容Windows、IOS、安卓、MacOS、Linux
175 0
|
24天前
|
TensorFlow 算法框架/工具 iOS开发
手把手教你-MAC虚拟环境搭建TensorFlow开发环境
手把手教你-MAC虚拟环境搭建TensorFlow开发环境
41 0
|
30天前
|
iOS开发 开发者 MacOS
在线创建ios打包证书无需mac
这个文件并不一定需要使用mac OS去创建,在苹果开发者中心,生成了cer格式的证书后,导出p12证书这个过程,其实也并不一定需要mac电脑来完成。
21 0
|
3月前
|
测试技术 Linux 虚拟化
iOS自动化测试方案(五):保姆级VMware虚拟机安装MacOS
详细的VMware虚拟机安装macOS Big Sur的保姆级教程,包括下载VMware和macOS镜像、图解安装步骤和遇到问题时的解决方案,旨在帮助读者顺利搭建macOS虚拟机环境。
123 3
iOS自动化测试方案(五):保姆级VMware虚拟机安装MacOS
|
3月前
|
测试技术 开发工具 虚拟化
iOS自动化测试方案(一):MacOS虚拟机保姆级安装Xcode教程
这篇文章提供了一份保姆级的教程,指导如何在MacOS虚拟机上安装Xcode,包括环境准备、基础软件安装以及USB扩展插件的使用,以实现iOS自动化测试方案的第一步。
97 0
iOS自动化测试方案(一):MacOS虚拟机保姆级安装Xcode教程
|
3月前
|
iOS开发
mac不通过Xcode直接打开IOS模拟器
mac不通过Xcode直接打开IOS模拟器
213 2
|
3月前
|
TensorFlow 算法框架/工具 Python
【Mac 系统】解决VSCode用Conda成功安装TensorFlow但程序报错显示红色波浪线Unable to import ‘tensorflow‘ pylint(import-error)
本文解决在Mac系统上使用VSCode时遇到的TensorFlow无法导入问题,原因是Python解析器未正确设置为Conda环境下的版本。通过在VSCode左下角选择正确的Python解析器,即可解决import TensorFlow时报错和显示红色波浪线的问题。
131 9
|
3月前
|
iOS开发 Android开发 MacOS
从零到全能开发者:解锁Uno Platform,一键跨越多平台应用开发的神奇之旅,让你的代码飞遍Windows、iOS、Android、macOS及Web,技术小白也能秒变跨平台大神!
【8月更文挑战第31天】从零开始,踏上使用Uno Platform开发跨平台应用的旅程。只需编写一次代码,即可轻松部署到Windows、iOS、macOS、Android及Web(通过WASM)等多个平台。Uno Platform为.NET生态带来前所未有的灵活性和效率,简化跨平台开发。首先确保安装了Visual Studio或VS Code及.NET SDK,然后选择合适的项目模板创建新项目。项目结构类似传统.NET MAUI或WPF项目,包含核心NuGet包。通过简单的按钮示例,你可以快速上手并构建应用。Uno Platform让你的技术探索之旅充满无限可能。
66 0
|
6月前
|
前端开发 JavaScript 程序员
HBuilderX使用mac打包ios应用提示苹果根证书没有安装
HBuilderX使用mac打包ios应用提示苹果根证书没有安装
133 0
|
数据安全/隐私保护 Android开发 iOS开发
解决第三方邮箱APP登陆QQ、163邮箱无法验证账户名或密码的问题(IOS、MacOS、Windows、Android)
解决第三方邮箱APP登陆QQ、163邮箱无法验证账户名或密码的问题(IOS、MacOS、Windows、Android)
212 0