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




目录
相关文章
|
11月前
|
Shell
(Mac)remotedebug-ios-webkit-adapter 无法运行,出现以下错误:ios_webkit_debug_proxy找不到。请安装 ios_webkit_debug_proxy (https://github.com/google/ios-webkit-debug-proxy) #74
(Mac)remotedebug-ios-webkit-adapter 无法运行,出现以下错误:ios_webkit_debug_proxy找不到。请安装 ios_webkit_debug_proxy (https://github.com/google/ios-webkit-debug-proxy) #74
412 0
|
12月前
|
编解码 API iOS开发
[✔️] mac/ios openal
[✔️] mac/ios openal
80 0
|
安全 数据安全/隐私保护 iOS开发
iMazing官网下载安装教程 2023最新版兼容Win和Mac的iOS设备管理软件
iMazing是一款功能强大的iOS设备管理软件,它可以帮助用户备份和管理他们的iPhone、iPad或iPod Touch上的数据。除此之外,它还可以将备份数据转移到新的设备中、管理应用程序、导入和导出媒体文件等。本文将详细介绍iMazing的功能和安全性,并教大家如何使用iMazing来恢复备份数据。
402 0
|
数据安全/隐私保护 iOS开发 MacOS
更新 | iOS 15.4 测试版支持口罩解锁,iPad 可用 Mac控制!
昨天苹果更新了 iOS 15.3,今天紧接着推出了 iOS 15.4 Beta 1 版本,这一版本带来了让人激动的口罩解锁,一起来看看吧!
115 0
|
Web App开发 弹性计算 Android开发
阿里云无影云桌面客户端下载Win/Mac/iOS/安卓/Web端均支持
阿里云无影客户端下载系统Win/Mac/iOS/安卓/Web端均支持
3730 0
阿里云无影云桌面客户端下载Win/Mac/iOS/安卓/Web端均支持
|
机器学习/深度学习 机器人 PyTorch
金玉良缘易配而木石前盟难得|M1 Mac os(Apple Silicon)天生一对Python3开发环境搭建(集成深度学习框架Tensorflow/Pytorch)
笔者投入M1的怀抱已经有一段时间了,俗话说得好,但闻新人笑,不见旧人哭,Intel mac早已被束之高阁,而M1 mac已经不能用真香来形容了,简直就是“香透满堂金玉彩,扇遮半面桃花开!”,轻抚M1 mac那滑若柔荑的秒控键盘,别说996了,就是007,我们也能安之若素,也可以笑慰平生。好了,日常吹M1的环节结束,正所谓剑虽利,不厉不断,材虽美,不学不高。本次我们尝试在M1 Mac os 中搭建Python3的开发环境。
金玉良缘易配而木石前盟难得|M1 Mac os(Apple Silicon)天生一对Python3开发环境搭建(集成深度学习框架Tensorflow/Pytorch)
|
Web App开发 Shell Android开发
iOS逆向小知识:模拟鼠标点击(针对Mac)
iOS逆向小知识:模拟鼠标点击(针对Mac)
912 0
iOS逆向小知识:模拟鼠标点击(针对Mac)
|
存储 安全 iOS开发
iOS开发 - 继udid,Mac地址等一系列唯一标识无效后,如何用KeyChain来实现设备唯一性
iOS开发 - 继udid,Mac地址等一系列唯一标识无效后,如何用KeyChain来实现设备唯一性
401 0
iOS开发 - 继udid,Mac地址等一系列唯一标识无效后,如何用KeyChain来实现设备唯一性
|
TensorFlow 算法框架/工具 iOS开发
《从零到一:IOS平台TensorFlow入门及应用详解(附源》电子版地址
从零到一:IOS平台TensorFlow入门及应用详解(附源
60 0
《从零到一:IOS平台TensorFlow入门及应用详解(附源》电子版地址
|
TensorFlow 算法框架/工具 iOS开发
《从零到一:IOS平台TensorFlow入门及应用详解(附源码)》电子版地址
从零到一:IOS平台TensorFlow入门及应用详解(附源码)
96 0
《从零到一:IOS平台TensorFlow入门及应用详解(附源码)》电子版地址