TensorFlow 智能移动项目:1~5(1)

简介: TensorFlow 智能移动项目:1~5

一、移动 TensorFlow 入门

本章介绍如何设置开发环境,以使用 TensorFlow 构建所有 iOS 或 Android 应用,本书其余部分对此进行了讨论。 我们不会详细讨论可用于开发的所有受支持的 TensorFlow 版本,OS 版本,Xcode 和 Android Studio 版本,因为可以在 TensorFlow 网站或通过 Google。 相反,我们将在本章中简要讨论示例工作环境,以便我们能够快速了解可使用该环境构建的所有出色应用。

如果您已经安装了 TensorFlow,Xcode 和 Android Studio,并且可以运行和测试示例 TensorFlow iOS 和 Android 应用,并且如果您已经安装了 NVIDIA GPU 以进行更快的深度学习模型训练,则可以跳过本章。 或者,您可以直接跳到您不熟悉的部分。

我们将在本章涵盖以下主题(如何设置 Raspberry Pi 开发环境将在第 12 章,“在 Raspberry Pi 上开发 TensorFlow 应用”中进行讨论):

  • 设置 TensorFlow
  • 设置 Xcode
  • 设置 Android Studio
  • TensorFlow Mobile 与 TensorFlow Lite
  • 运行示例 TensorFlow iOS 应用
  • 运行示例 TensorFlow Android 应用

设置 TensorFlow

TensorFlow 是领先的机器智能开源框架。 当 Google 在 2015 年 11 月将 TensorFlow 作为一个开源项目发布时,已经有其他一些类似的深度学习开源框架:Caffe,Torch 和 Theano。 在 5 月 10 日的 Google I/O 2018 上,GitHub 上的 TensorFlow 已达到 99000 星,在 4 个月内增加了 14k 星,而 Caffe 仅增加了 2k 至 24k 星。 两年后,它已经成为最流行的开源框架,用于训练和部署深度学习模型(它对传统机器学习也有很好的支持)。 截至 2018 年 1 月,TensorFlow 在 GitHub 上拥有近 8.5 万颗星,而其他三个领先的开源深度学习框架 CaffeCNTKMxnet 分别拥有 22k,13k 和 12k 颗星。

如果您对机器学习,深度学习,机器智能和人工智能(AI)的流行语有些困惑,这里有个简短的摘要:机器智能和 AI 确实是同一回事。 机器学习是 AI 的一个领域,也是最受欢迎的领域; 深度学习是机器学习的一种特殊类型,也是解决诸如计算机视觉,语音识别和合成以及自然语言处理之类的复杂问题的现代且最有效的方法。 因此,在本书中,当我们说 AI 时,我们主要是指深度学习,这是将 AI 从漫长的冬天带到夏天的救星。 有关 AI 冬季和深度学习的更多信息,您可以查看这里这里

我们假设您已经对 TensorFlow 有了基本的了解,但是如果您还没有,请查看入门教程部分或 Awesome TensorFlow 教程。 关于该主题的两本好书是《Python 机器学习:Python , scikit-learn 和 TensorFlow 机器学习和深度学习》和《使用 Scikit-Learn 和 TensorFlow 动手进行机器学习》。

TensorFlow 可以安装在 MacOS,Ubuntu 或 Windows 上。 我们将介绍在 MacOS X El Capitan(10.11.6),macOS Sierra(10.12.6)和 Ubuntu 16.04 上从源代码安装 TensorFlow 1.4 的步骤。 如果您使用其他操作系统或版本,则可以参考 TensorFlow 安装文档以获取更多信息。 当您阅读本书时,可能会出现更新的 TensorFlow 版本。 尽管您仍然应该能够使用较新版本运行本书中的代码,但这并不能保证,因此我们在 Mac 和 Ubuntu 上使用 TensorFlow 1.4 发行源代码来设置 TensorFlow; 这样,您可以轻松地测试运行并与书中的应用一起玩。

自从我们于 2017 年 12 月撰写以上段落以来,TensorFlow 已有四个新的正式版本(1.5、1.6、1.7 和 1.8),以及截至 2018 年 5 月的新版本 Xcode(9.3),您可以在以下位置下载, 或在 TensorFlow 源代码仓库。 TensorFlow 的较新版本(例如 1.8)默认情况下支持 NVIDIA CUDA 和 cuDNN 的较新版本(有关详细信息,请参阅“在 Ubuntu 上设置基于 GPU 的 TensorFlow”部分),并且最好遵循官方的 TensorFlow 文档来安装具有 GPU 支持的最新 TensorFlow 版本。 在本章及以下各章中,我们将以特定的 TensorFlow 版本为例,但将对所有 iOS,Android 和 Python 代码进行测试,并在需要时针对其中的最新 TensorFlow,Xcode 和 Android Studio 版本进行更新。 本书的源代码仓库位于这里

总体而言,我们将在 Mac 上使用 TensorFlow 开发 iOS 和 Android TensorFlow 应用,并在 Ubuntu 上使用 TensorFlow 训练应用中使用的深度学习模型。

在 MacOS 上设置 TensorFlow

通常,您应该使用 VirtualEnv,Docker 或 Anaconda 安装在单独的环境中安装 TensorFlow。 但是由于我们必须使用 TensorFlow 源代码构建 iOS 和 Android TensorFlow 应用,因此我们不妨从源代码构建 TensorFlow 本身,在这种情况下,使用本机 PIP 安装选择可能比其他选择更容易。 如果您想尝试不同的 TensorFlow 版本,我们建议您使用 VirtualEnv,Docker 和 Anaconda 选项之一安装其他 TensorFlow 版本。 在这里,我们将使用本地 PIP 和 Python 2.7.10 直接在 MacOS 系统上安装 TensorFlow 1.4。

请按照以下步骤在 MacOS 上下载并安装 TensorFlow 1.4:

  1. 从 GitHub 上的 TensorFlow 发布页面下载 TensorFlow 1.4.0 源代码ziptar.gz
  2. 解压缩下载的文件并将tensorflow-1.4.0文件夹拖到您的主目录
  3. 确保已安装 Xcode 8.2.1 或更高版本(否则,请先阅读“设置 Xcode”部分)
  4. 打开一个新的终端窗口,然后单击cd tensorflow-1.4.0
  5. 运行xcode-select --install以安装命令行工具
  6. 运行以下命令以安装构建 TensorFlow 所需的其他工具和包:
sudo pip install six numpy wheel  
brew install automake 
brew install libtool 
./configure 
brew upgrade bazel
  1. 从 TensorFlow 源代码构建,仅提供 CPU 支持(我们将在下一部分介绍 GPU 支持),并生成带有.whl文件扩展名的 PIP 包文件:
bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package 
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
  1. 安装 TensorFlow 1.4.0 CPU 包:
sudo pip install --upgrade /tmp/tensorflow_pkg/tensorflow-1.4.0-cp27-cp27m-macosx_10_12_intel.whl

老实说,如果您在此过程中遇到任何错误,则搜索错误消息应该是修复该错误的最佳方法,因为我们打算在本书中重点介绍从我们长期积累的技巧和知识,从数小时的构建和调试实用的移动 TensorFlow 应用中获取,它们在其他地方不易获得。 运行sudo pip install命令时,您可能会看到的一个特定错误是Operation not permitted错误。 要解决此问题,您可以通过重新启动 Mac 并点击Cmd + R键来禁用 Mac 的系统完整性保护SIP) 要进入恢复模式,请在工具终端下,在重新启动 Mac 之前运行csrutil disable。 如果您对禁用 SIP 不满意,可以按照 TensorFlow 文档尝试使用更复杂的安装方法之一,例如 VirtualEnv。

如果一切顺利,则应该能够在终端窗口,Python 或最好在 IPython 上运行,然后运行import tensorflow as tftf.__version__将 1.4.0 作为输出。

在 GPU 驱动的 Ubuntu 上设置 TensorFlow

使用良好的深度学习框架(例如 TensorFlow)的好处之一是在模型训练中无缝支持使用图形处理单元GPU) 。 在 GPU 上训练非平凡的基于 TensorFlow 的模型要比在 CPU 上训练要快得多,并且当前 NVIDIA 提供 TensorFlow 支持的最佳和最具成本效益的 GPU。 Ubuntu 是使用 TensorFlow 运行 NVIDIA GPU 的最佳操作系统。 您可以花几百美元轻松购买一个 GPU,然后将其安装在带有 Ubuntu 系统的廉价台式机上。 您也可以在 Windows 上安装 NVIDIA GPU,但 TensorFlow 对 Windows 的支持不如对 Ubuntu 的支持。

为了训练本书中应用中部署的模型,我们使用 NVIDIA GTX 1070,您可以在 Amazon 或 eBay 上以大约 400 美元的价格购买。 蒂姆·戴特默斯(Tim Dettmers)有一个不错的博客,其中介绍了用于深度学习的 GPU。 在获得这样的 GPU 并将其安装在 Ubuntu 系统上之后,以及在安装启用 GPU 的 TensorFlow 之前,您需要安装 NVIDIA CUDA 8.0(或 9.0)和 cuDNN(CUDA-DeepNeuralNetwork)6.0 (或 7.0),两者均受 TensorFlow 1.4 支持。

使用 TensorFlow 设置自己的 GPU 驱动的 Ubuntu 的另一种方法是在支持 GPU 的云服务(例如 Google Cloud Platform 的 Cloud ML Engine)中使用 TensorFlow。 每个选项都有优点和缺点。 云服务通常是基于时间的计费。 如果您的目标是训练或重新训练要在移动设备上部署的模型,这意味着模型并不复杂,并且如果您计划长时间进行机器学习训练,那么拥有自己的 GPU 成本效益更高并且令人满意。

请按照以下步骤在 Ubuntu 16.04 上安装 CUDA 8.0 和 cuDNN 6.0(您应该能够以类似的方式下载并安装 CUDA 9.0 和 cuDNN 7.0):

  1. 这个页面中找到 NVIDIA CUDA 8.0 GA2 版本,并进行以下屏幕截图中所示的选择:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-24owtE5N-1681653027406)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/intel-mobi-proj-tf/img/0e74beec-5ac6-4755-8268-dcf83c27a700.png)]

图 1.1:准备在 Ubuntu 16.04 上下载 CUDA 8.0

  1. 下载基本安装程序,如以下屏幕快照所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wQ8ALCmL-1681653027407)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/intel-mobi-proj-tf/img/49296f66-83aa-48a5-973b-a4d9c8dd4348.png)]

图 1.2:为 Ubuntu 16.04 选择 CUDA 8.0 安装程序文件

  1. 打开一个新的终端并运行以下命令(您还需要将最后两个命令添加到.bashrc文件中,以使两个环境变量在您下次启动新终端时生效):
sudo dpkg -i /home/jeff/Downloads/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb  
sudo apt-get update 
sudo apt-get install cuda-8-0 
export CUDA_HOME=/usr/local/cuda 
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
  1. 通过这里下载用于 CUDA 8.0 的 NVIDIA cuDNN 6.0,您将被要求先免费注册一个 NVIDIA 开发者帐户(免费)。 您可以下载它,如下一个屏幕截图所示(选择突出显示的 cuDNN v6.0 Linux 版):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wl1Sp3ho-1681653027408)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/intel-mobi-proj-tf/img/f8e7636c-a193-4915-8c4f-8a234ffaf788.png)]

图 1.3:在 Linux 上为 CUDA 8.0 选择 cuDNN 6.0

  1. 假设下载的文件位于默认的~/Downloads目录下,请解压缩该文件,然后您会看到一个名为cuda的文件夹,其中包含两个名为includelib64的子文件夹
  2. 将 cuDNN includelib64文件复制到CUDA_HOMElib64include文件夹中:
sudo cp ~/Downloads/cuda/lib64/* /usr/local/cuda/lib64 
sudo cp ~/Downloads/cuda/include/cudnn.h /usr/local/cuda/include

现在我们准备在 Ubuntu 上安装启用 GPU 的 TensorFlow 1.4(此处给出的前两个步骤与在 MacOS 上设置 TensorFlow 一节中描述的步骤相同):

  1. GitHub 上的 TensorFlow 发布页面下载 TensorFlow 1.4.0 源代码(ziptar.gz
  2. 解压缩下载的文件并将文件夹拖到主目录
  3. 这里下载 bazel 安装程序
  4. 打开一个新的终端窗口,然后运行以下命令以安装构建 TensorFlow 所需的工具和包:
sudo pip install six numpy wheel  
cd ~/Downloads 
chmod +x bazel-0.5.4-installer-linux-x86_64.sh 
./bazel-0.5.4-installer-linux-x86_64.sh --user
  1. 从具有 GPU 支持的 TensorFlow 源进行构建,并生成带有.whl文件扩展名的 pip 包文件:
cd ~/tensorflow-1.4.0 
./configure 
bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package 
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
  1. 安装 TensorFlow 1.4.0 GPU 包:
sudo pip install --upgrade /tmp/tensorflow_pkg/tensorflow-1.4.0-cp27-cp27mu-linux_x86_64.whl

现在,如果一切顺利,您可以启动 IPython 并输入以下脚本以查看 TensorFlow 使用的 GPU 信息:

In [1]: import tensorflow as tf 
In [2]: tf.__version__ 
Out[2]: '1.4.0' 
In [3]: sess=tf.Session() 
2017-12-28 23:45:37.599904: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:892] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero 
2017-12-28 23:45:37.600173: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1030] Found device 0 with properties:  
name: GeForce GTX 1070 major: 6 minor: 1 memoryClockRate(GHz): 1.7845 
pciBusID: 0000:01:00.0 
totalMemory: 7.92GiB freeMemory: 7.60GiB 
2017-12-28 23:45:37.600186: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1120] Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0, compute capability: 6.1)

恭喜你! 现在,您就可以训练本书中应用中使用的深度学习模型了。 在我们开始玩我们的新玩具并用它来训练我们的炫酷模型然后在移动设备上部署和运行它们之前,我们首先来看看准备好开发移动应用需要做什么。

设置 Xcode

Xcode 用于开发 iOS 应用,您需要 Mac 电脑和免费的 Apple ID 才能下载和安装它。 如果您的 Mac 相对较旧并且使用 OS X El Capitan(版本 10.11.6),则可以从这里下载 Xcode 8.2.1。 或者,如果您安装了 macOS Sierra(10.12.6 版)或更高版本,则可以从前面的链接下载 Xcode 9.2 或 9.3(截至 2018 年 5 月的最新版本)。 本书中的所有 iOS 应用均已在 Xcode 8.2.1、9.2 和 9.3 中进行了测试。

要安装 Xcode,只需双击下载的文件,然后按照屏幕上的步骤进行操作。 这很简单。 现在,您可以在 Xcode 随附的 iOS 模拟器或您自己的 iOS 设备上运行应用。 从 Xcode 7 开始,您可以在 iOS 设备上免费运行和调试 iOS 应用,但如果要分发或发布您的应用,则需要以每年 99 美元的价格参加 Apple 开发人员计划

尽管您可以使用 Xcode 模拟器测试运行书中的许多应用,但是书中的某些应用需要使用实际的 iOS 设备上的相机拍摄照片,然后才能使用经过 TensorFlow 训练的深度学习模型对其进行处理。 此外,通常最好在实际设备上测试模型的准确表现和内存使用情况:在模拟器中运行良好的模型可能会崩溃或在实际设备中运行太慢。 因此,强烈建议或要求您(如果并非总是)至少在您的实际 iOS 设备上测试并运行本书中的 iOS 应用一次。

本书假定您熟悉 iOS 编程,但是如果您不熟悉 iOS 开发,则可以从许多出色的在线教程中学习,例如 Ray Wenderlich 的 iOS 教程。 我们不会介绍复杂的 iOS 编程; 我们将主要向您展示如何在我们的 iOS 应用中使用 TensorFlow C++ API 来运行 TensorFlow 训练有素的模型来执行各种智能任务。 Apple 的两种官方 iOS 编程语言 Objective-C 和 Swift 代码都将用于与我们的移动 AI 应用中的 C++ 代码进行交互。

设置 Android Studio

Android Studio 是开发 Android 应用的最佳工具,并且 TensorFlow 对其使用提供了强大的支持。 与 Xcode 不同,您可以在 Mac,Windows 或 Linux 上安装并运行 Android Studio。 有关详细的系统要求,请参阅 Android Studio 网站。 在这里,我们将介绍如何在 Mac 上设置 Android Studio 3.0 或 3.0.1-本书中的所有应用均已在两个版本上进行了测试。

首先,从前面的链接下载 Android Studio 3.0.1,如果最新版本是 3.0.1 以上,并且您不介意解决可能的小问题,请下载最新版本。 您也可以从这里的存档中下载 3.0.1 或 3.0。

然后,双击下载的文件并将Android Studio.app图标拖放到Applications。 如果您以前安装了 Android Studio,则系统会提示您是否要用较新的 Android Studio 替换它。 您只需选择替换即可。

接下来,打开 Android Studio,您需要提供 Android SDK 的路径,如果您安装了以前版本的 Android Studio,则默认情况下它位于~/Library/Android/sdk中,或者您可以选择打开现有的 Android Studio 项目,然后转到“在 MacOS 上设置 TensorFlow”一节中创建的 TensorFlow 1.4 源目录,然后打开tensorflow/examples/android文件夹。 之后,您可以通过单击安装工具消息的链接或转到 Android Studio 的Tools | Android | SDK Manager来下载 Android SDK,如以下屏幕截图所示。 从 SDK 工具标签中,您可以选中特定版本的 Android SDK 工具旁边的框,然后单击确定按钮以安装该版本:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0zQGe2Xr-1681653027408)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/intel-mobi-proj-tf/img/3b90efdb-6655-4e35-b74a-a44e69e17487.png)]

图 1.4:Android SDK Manager,用于安装 SDK 工具和 NDK

最后,由于 TensorFlow Android 应用使用 C++ 中的本机 TensorFlow 库来加载和运行 TensorFlow 模型,因此您需要安装 Android 本机开发套件NDK),您可以执行以下任一操作,从上一个屏幕快照中显示的 Android SDK Manager 中获取,或者直接从这里下载 NDK。 NDK 版本 r16b 和 r15c 均已通过测试可运行本书中的 Android 应用。 如果直接下载 NDK,则在打开项目并选择 Android Studio 的File | Project Structure后,您可能还需要设置 Android NDK 位置,如以下屏幕截图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qqIIkRPs-1681653027408)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/intel-mobi-proj-tf/img/1f6a2d74-0be0-4f36-9796-2cf66eb1694f.png)]

图 1.5:设置项目级别的 Android NDK 位置

安装并设置了 Android SDK 和 NDK 之后,您就可以测试运行示例 TensorFlow Android 应用了。

TensorFlow Mobile 与 TensorFlow Lite

在我们开始运行示例 TensorFlow iOS 和 Android 应用之前,让我们澄清一下。 TensorFlow 当前有两种在移动设备上开发和部署深度学习应用的方法:TensorFlow Mobile 和 TensorFlow Lite。 TensorFlow Mobile 从一开始就是 TensorFlow 的一部分,而 TensorFlow Lite 是开发和部署 TensorFlow 应用的较新方法,因为它具有更好的性能和更小的应用大小。 但是有一个关键因素可以让我们在本书中专注于 TensorFlow Mobile,同时仍在一个章节中介绍 TensorFlow Lite:从 TensorFlow 1.8 和 2018 年 5 月的 Google I/O 开始,TensorFlow Lite 仍在开发人员预览版中。 现在,准备投入生产的移动 TensorFlow 应用,您必须按照 Google 的建议使用 TensorFlow Mobile。

我们决定现在专注于 TensorFlow Mobile 的另一个原因是,虽然 TensorFlow Lite 仅对模型运算符提供了有限的支持,但 TensorFlow Mobile 支持自定义以添加默认情况下 TensorFlow Mobile 不支持的新运算符,您会发现它经常发生在我们的各种模型中 AI 应用的模型。

但是将来,当 TensorFlow Lite 不在开发人员预览版中时,它很可能会取代 TensorFlow Mobile,或者至少克服其当前的局限性。 为了为此做好准备,我们将在下一章中详细介绍 TensorFlow Lite。

运行示例 TensorFlow iOS 应用

在本章的最后两部分中,我们将测试运行 TensorFlow 1.4 随附的三个示例 iOS 应用和四个示例 Android 应用,以确保您正确设置了移动 TensorFlow 开发环境并快速预览了其中的一些内容 TensorFlow 移动应用可以做到。

三个示例 TensorFlow iOS 应用的源代码位于tensorflow/examples/ios: simplecamerabenchmark。 为了成功运行这些样本,您需要首先下载一个由 Google 训练的深度学习模型,称为 Inception,用于图像识别。 Inception 有多个版本:v1 到 v4,在每个较新的版本中准确率更高。 在这里,我们将使用 Inception v1 作为为其开发的示例。 下载模型文件后,将与模型相关的文件复制到每个样本的data文件夹中:

curl -o ~/graphs/inception5h.zip https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip 
unzip ~/graphs/inception5h.zip -d ~/graphs/inception5h 
cd tensorflow/examples/ios 
cp ~/graphs/inception5h/* simple/data/ 
cp ~/graphs/inception5h/* camera/data/ 
cp ~/graphs/inception5h/* benchmark/data/

现在,在打开和运行应用之前,转到每个app文件夹并运行以下命令以下载每个应用所需的 Pod:

cd simple 
pod install 
open tf_simple_example.xcworkspace 
cd ../camera 
pod install 
open tf_camera_example.xcworkspace 
cd ../benchmark 
pod install 
open tf_benchmark_example.xcworkspace

然后,您可以在 iOS 设备上运行这三个应用,或者在 iOS 模拟器上运行简单和基准的应用。 如果在运行简单应用后点击运行模型按钮,您将看到一条文本消息,提示已加载 TensorFlow Inception 模型,随后是几个顶级识别结果以及置信度值。

如果在运行基准测试应用后点击 Benchmark Model 按钮,您将看到运行模型超过 20 次的平均时间。 例如,在我的 iPhone 6 上平均需要大约 0.2089 秒,在 iPhone 6 模拟器上平均需要 0.0359 秒。

最后,在 iOS 设备上运行照相机应用并将其对准相机可以向您实时显示该应用看到和识别的对象。

运行示例 TensorFlow Android 应用

tensorflow/examples/android中有四个样本 TensorFlow Android 应用,分别为 TF 分类,TF 检测,TF 语音和 TF 风格化。 运行这些示例的最简单方法是使用 Android Studio 在前面的文件夹中打开项目,如“设置 Android Studio”部分中所示,然后通过编辑项目的build.gradle文件进行单个更改,并将def nativeBuildSystem = 'bazel'更改为def nativeBuildSystem = 'none'

现在,将 Android 设备连接到您的计算机,然后通过选择 Android Studio 的Run | Run 'android'构建,安装和运行该应用。这会在您的设备上安装四个名称为“TF 分类”,“TF 检测”,“TF 语音”和“TF 风格化”的 Android 应用。 “TF 分类”就像 iOS 相机应用一样,使用 TensorFlow Inception v1 模型对设备相机进行实时对象分类。 “TF 检测”使用另一种模型,称为单发多框检测器SSD)和 MobileNet,这是 Google 发布的一组新的深度学习模型,专门针对移动和嵌入式设备, 要执行对象检测,请在检测到的对象上绘制矩形。 “TF 语音”使用另一种不同的深度学习(语音识别)模型来收听和识别一小部分单词,例如YesNoLeftRightStopStart。 “TF 风格化”使用另一种模型来更改相机看到的图像样式。 有关这些应用的更多详细信息,您可以在这个页面中查看 TensorFlow Android 示例文档。

总结

在本章中,我们介绍了如何在 Mac 和 Ubuntu 上安装 TensorFlow 1.4,如何在 Ubuntu 上设置具有成本效益的 NVIDIA GPU 以便进行更快的模型训练以及如何为移动 AI 应用开发设置 Xcode 和 Android Studio。 我们还向您展示了如何运行一些很酷的 TensorFlow 示例 iOS 和 Android 应用。 在本书的其余部分,我们将详细讨论如何在基于 GPU 的 Ubuntu 系统上构建和训练或重新训练应用中使用的每个模型以及其他模型,并向您展示如何在以下环境中部署模型 iOS 和 Android 应用,并编写代码以在移动 AI 应用中使用模型。 现在我们已经准备就绪,我们已经迫不及待要上路了。 这将是一段激动人心的旅程,我们当然很乐意与朋友分享这一旅程。 那么,为什么不从我们最好的朋友开始,让我们看看构建狗品种识别应用需要什么呢?

二、通过迁移学习对图像进行分类

上一章中描述的示例 TensorFlow iOS 应用,Simple 和 Camera 以及 Android 应用“TF 分类”都使用了 Inception v1 模型,该模型是 Google 公开提供的预训练的图像分类深度神经网络模型。 该模型针对 ImageNet 进行了训练,ImageNet 是最大和最知名的图像数据库之一,其中有超过一千万个图像被标注为对象类别。 Inception 模型可用于将图像分类为列出的 1,000 个类别之一。 这 1000 个对象类别包括很多对象中的很多犬种。 但是,识别狗品种的准确率不是很高,约为 70%,因为模型经过训练可以识别大量对象,而不是像狗品种之类的特定对象。

如果我们想提高准确率并在使用改进模型的智能手机上构建移动应用怎么办,那么当我们四处走走并看到一只有趣的狗时,我们可以使用该应用告诉我们它是哪种狗。

在本章中,我们将首先讨论为什么对于这样的图像分类任务,迁移学习或重新训练经过预训练的深度学习模型是完成任务的最经济有效的方法。 然后,我们将向您展示如何使用良好的狗数据集对一些最佳图像分类模型进行再训练,以及在第 1 章,“移动 TensorFlow 入门”。 此外,我们还将分步说明如何将 TensorFlow 添加到基于 Objective-C 或 Swift 的 iOS 和 Android 应用中。

总而言之,我们将在本章中介绍以下主题:

  • 迁移学习 - 什么和为什么
  • 将 Inception v3 模型用于再训练
  • 将 MobileNet 模型用于再训练
  • 在示例 iOS 应用中使用经过重新训练的模型
  • 在示例 Android 应用中使用经过重新训练的模型
  • 将 TensorFlow 添加到您自己的 iOS 应用中
  • 将 TensorFlow 添加到您自己的 Android 应用中

迁移学习 – 什么和为什么

我们人类不会从头开始学习新事物。 取而代之的是,无论是否有意识地,我们都充分利用所学到的知识。 人工智能中的迁移学习试图做同样的事情-这种技术通常只需要训练的大型模型中的一小块,然后将其重新用于相关任务的新模型中,而无需访问大型训练数据和计算资源来训练原始模型。 总体而言,迁移学习仍然是 AI 中的一个开放问题,因为在许多情况下,仅需人类反复尝试几个例子,然后再学习掌握新事物,就会花很多时间来训练和学习 AI。 但是,在图像识别领域,迁移学习已被证明是非常有效的。

用于图像识别的现代深度学习模型通常是深度神经网络,或更具体地说,是具有许多层的深度卷积神经网络CNN)。 这种 CNN 的较低层负责学习和识别较低层的特征,例如图像的边缘,轮廓和零件,而最后一层则确定图像的类别。 对于不同类型的对象,例如犬种或花朵类型,我们不需要重新学习网络较低层的参数或权重。 实际上,从头开始需要花费数周的训练来学习用于图像识别的现代 CNN 的所有权重,通常是数百万甚至更多。 在图像分类的情况下,迁移学习使我们能够使用特定的图像集重新训练此类 CNN 的最后一层,通常不到一小时,而所有其他层都保持不变,并且达到了几乎相同的精度,就像我们从头开始训练整个网络数周一样。

迁移学习的第二个主要好处是,我们只需要少量的训练数据就可以重新训练 CNN 的最后一层。 如果必须从头开始训练深层 CNN 的数百万个参数,则需要大量的训练数据。 例如,对于我们的狗品种再训练,我们只需要为每个狗品种提供 100 幅以上的图像,即可建立一个比原始图像分类模型更好的狗品种分类模型。

如果您不熟悉 CNN,请查看其中的最佳资源之一的视频和评论,这是 Stanford CS231n 课程“用于视觉识别的 CNN”。 CNN 的另一个很好的资源是 Michael Nielsen 的在线书籍《神经网络和深度学习》的第 6 章

在接下来的两个部分中,我们将使用针对 TensorFlow 的两个最佳的经过预训练的 CNN 模型和一个犬种数据集来重新训练模型并生成更好的犬种识别模型。 第一个模型是 Inception v3,它是比 Inception v1 更准确的模型,已针对准确率进行了优化,但大小较大。 另一个模型是 MobileNet,它针对移动设备的大小和效率进行了优化。 TensorFlow 支持的预训练模型的详细列表位于这里

将 Inception v3 模型用于再训练

在上一章中设置的 TensorFlow 源代码中,有一个 Python 脚本tensorflow/examples/image_retraining/retrain.py,可用于重新训练 Inception v3 或 MobileNet 模型。 在运行脚本以重新训练 Inception v3 模型以进行狗品种识别之前,我们需要首先下载斯坦福狗数据集, 120 个犬种的图片(您只需要在链接中下载图片,而不是标注即可)。

~/Downloads中解压缩下载的狗images.tar文件,您应该在~/Downloads/Images中看到文件夹列表,如以下屏幕截图所示。 每个文件夹对应一个犬种,并且包含约 150 张图像(您无需为图像提供显式标签,因为文件夹名称用于标记文件夹中包含的图像):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BNHjmcvF-1681653027408)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/intel-mobi-proj-tf/img/c8c4fa68-5db2-406d-9444-fbf1fdeb5418.png)]

图 2.1:由文件夹或狗的品种分开的狗集图像

您可以下载数据集,然后在 Mac 上运行retrain.py脚本,因为该脚本在相对位置上运行不会花费太长时间(少于一小时) 小型数据集(总共约 20,000 张图像),但是,如上一章所述,如果您在 GPU 驱动的 Ubuntu 上执行此操作,则该脚本仅需几分钟即可完成。 此外,当使用大型图像数据集进行再训练时,在 Mac 上运行可能需要花费数小时或数天,因此在 GPU 驱动的计算机上运行它是有意义的。

假设您已经创建了/tf_file目录和/tf_file/dogs_bottleneck目录,那么重新训练模型的命令如下:

python tensorflow/examples/image_retraining/retrain.py  
--model_dir=/tf_files/inception-v3  
--output_graph=/tf_files/dog_retrained.pb  
--output_labels=/tf_files/dog_retrained_labels.txt  
--image_dir ~/Downloads/Images  
--bottleneck_dir=/tf_files/dogs_bottleneck

这五个参数在这里需要一些解释:

  • --model_dir指定应该由retrain.py自动下载 Inception v3 模型的目录路径,除非它已经在目录中。
  • --output_graph表示再训练模型的名称和路径。
  • --output_labels是由图像数据集的文件夹(标签)名称组成的文件,稍后将其与经过重新训练的模型一起使用以对新图像进行分类。
  • --image_dir是用于重新训练 Inception v3 模型的图像数据集的路径。
  • --bottleneck_dir用于缓存在瓶颈(最后一层之前的那一层)上生成的结果; 最后一层使用这些结果进行分类。 在重新训练期间,每个映像都使用了几次,但该映像的瓶颈值保持不变,即使将来重新运行重新训练脚本也是如此。 因此,第一次运行需要更长的时间,因为它需要创建瓶颈结果。

在再训练期间,您将每 10 步看到 3 个值,默认总计 4,000 步。 前 20 个步骤和后 20 个步骤以及最终精度如下所示:

INFO:tensorflow:2018-01-03 10:42:53.127219: Step 0: Train accuracy = 21.0% 
INFO:tensorflow:2018-01-03 10:42:53.127414: Step 0: Cross entropy = 4.767182 
INFO:tensorflow:2018-01-03 10:42:55.384347: Step 0: Validation accuracy = 3.0% (N=100) 
INFO:tensorflow:2018-01-03 10:43:11.591877: Step 10: Train accuracy = 34.0% 
INFO:tensorflow:2018-01-03 10:43:11.592048: Step 10: Cross entropy = 4.704726 
INFO:tensorflow:2018-01-03 10:43:12.915417: Step 10: Validation accuracy = 22.0% (N=100) 
... 
... 
INFO:tensorflow:2018-01-03 10:56:16.579971: Step 3990: Train accuracy = 93.0% 
INFO:tensorflow:2018-01-03 10:56:16.580140: Step 3990: Cross entropy = 0.326892 
INFO:tensorflow:2018-01-03 10:56:16.692935: Step 3990: Validation accuracy = 89.0% (N=100) 
INFO:tensorflow:2018-01-03 10:56:17.735986: Step 3999: Train accuracy = 93.0% 
INFO:tensorflow:2018-01-03 10:56:17.736167: Step 3999: Cross entropy = 0.379192 
INFO:tensorflow:2018-01-03 10:56:17.846976: Step 3999: Validation accuracy = 90.0% (N=100) 
INFO:tensorflow:Final test accuracy = 91.0% (N=2109)

训练精度是神经网络用于训练的图像上的分类精度,而验证精度是神经网络未用于训练的图像上的验证精度。 因此,验证准确率是衡量模型准确率的一种更可靠的度量,并且通常应该比训练准确率小一点,但是如果训练收敛并进行得很好,也就是说,训练的模型是否既不欠拟合也不过拟合。

如果训练精度很高,但验证精度仍然很低,则意味着模型过拟合。 如果训练精度仍然很低,则表明模型不适合。 同样,交叉熵是损失函数值,如果再训练顺利进行,则总体上应该越来越小。 最后,测试准确率取决于尚未用于训练或验证的图像。 通常,这是我们可以说出的关于重新训练模型的最准确的值。

如前面的输出所示,在再训练结束时,我们看到验证精度与训练精度相似(90% 和 93%,相比之初为 3% 和 21%),最终测试精度为 91% 。 交叉熵也从开始时的 4.767 下降到最后的 0.379。 因此,我们现在有了一个很好的再训练狗品种识别模型。

为了进一步提高准确率,您可以使用retrain.py的其他参数(例如训练步骤) (--how_many_training_steps),学习率(--learning_rate),和数据扩充(--flip_left_right, --random_crop, --random_scale, --random_brightness). 通常,这是一个乏味的过程,涉及到许多“肮脏的工作”,这是最著名的深度学习专家之一 Andrew Ng 在他的“应用深度学习的基本原理”演讲中提到的(视频可在以下位置找到)。

您可以使用另一个 Python 脚本label_image来对经过重新训练的模型进行快速测试,以测试自己的图像(例如/tmp/lab1.jpg中的 Labrador Retriever 图像),您可以在首先对其进行如下构建后运行该脚本:

bazel build tensorflow/examples/image_retraining:label_image 
bazel-bin/tensorflow/examples/label_image/label_image  
--graph=/tf_files/dog_retrained.pb  
--image=/tmp/lab1.jpg  
--input_layer=Mul  
--output_layer=final_result  
--labels=/tf_files/dog_retrained_labels.txt

您会看到与以下内容相似的前五个分类结果(但是,因为网络随机变化,可能不完全相同)如下:

n02099712 labrador retriever (41): 0.75551 
n02099601 golden retriever (64): 0.137506 
n02104029 kuvasz (76): 0.0228538 
n02090379 redbone (32): 0.00943663 
n02088364 beagle (20): 0.00672507

--input_layer (Mul)--output_layer (final_result)的值非常重要–必须与模型中定义的值相同,这样分类才能完全起作用。 如果您想知道如何获取它们(从图,aka 模型,文件dog_retrained.pb中获取),则有两个 TensorFlow 工具可能会有所帮助。 第一个是适当命名的summarize_graph。 这是构建和运行它的方法:

bazel build tensorflow/tools/graph_transforms:summarize_graph
bazel-bin/tensorflow/tools/graph_transforms/summarize_graph --in_graph=/tf_files/dog_retrained.pb

您将看到类似于以下内容的摘要结果:

No inputs spotted.
No variables spotted.
Found 1 possible outputs: (name=final_result, op=Softmax)
Found 22067948 (22.07M) const parameters, 0 (0) variable parameters, and 99 control_edges
Op types used: 489 Const, 101 Identity, 99 CheckNumerics, 94 Relu, 94 BatchNormWithGlobalNormalization, 94 Conv2D, 11 Concat, 9 AvgPool, 5 MaxPool, 1 DecodeJpeg, 1 ExpandDims, 1 Cast, 1 MatMul, 1 Mul, 1 PlaceholderWithDefault, 1 Add, 1 Reshape, 1 ResizeBilinear, 1 Softmax, 1 Sub

有一个可能的输出,名称为final_result。 不幸的是,有时summarize_graph工具没有告诉我们输入名称,因为它似乎对用于训练的节点感到困惑。 删除仅用于训练的节点(我们将在稍后讨论)之后,summarize_graph工具将返回正确的输入名称。 另一个名为 TensorBoard 的工具为我们提供了更完整的模型图。 如果直接从二进制文件安装了 TensorFlow,则应该可以只运行 TensorBoard,因为默认情况下,它安装在/usr/local/bin中。 但是,如果像我们之前那样从源代码安装 TensorFlow,则可以运行以下命令来构建 TensorBoard:

git clone https://github.com/tensorflow/tensorboard 
cd tensorboard/ 
bazel build //tensorboard

现在,确保您具有/tmp/retrained_logs,在运行retrain.py时自动创建并运行:

bazel-bin/tensorboard/tensorboard --logdir /tmp/retrain_logs

然后在浏览器中启动 URL http://localhost:6006。 首先,您将看到准确率图,如以下屏幕截图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GFin3z7h-1681653027409)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/intel-mobi-proj-tf/img/3ae39776-c298-4b42-9125-f25ca84c9ed2.png)]

图 2.2:Inception v3 重新训练模型的训练和验证准确率

在下面的屏幕截图中的交叉熵图,和我们之前对于运行retrain.py的输出所描述的一样:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hpiU85KV-1681653027409)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/intel-mobi-proj-tf/img/cd4cea6a-8847-40bd-9ec4-3d9696972a5f.png)]

图 2.3:Inception v3 重新训练模型的训练和验证交叉熵

现在单击GRAPHS选项卡,您将看到一个名为Mul的操作,另一个名为final_result的操作 ,如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K2HEMYPh-1681653027409)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/intel-mobi-proj-tf/img/18aa75d8-28e3-497c-ba8f-145baa6cee37.png)]

图 2.4:重新训练模型中的Mulfinal_result节点

实际上,如果您希望与 TensorFlow 进行小的交互,则可以尝试几行 Python 代码来找出输出层和输入层的名称,如 iPython 交互所示:

In [1]: import tensorflow as tf 
In [2]: g=tf.GraphDef() 
In [3]: g.ParseFromString(open("/tf_files/dog_retrained.pb", "rb").read()) 
In [4]: x=[n.name for n in g.node] 
In [5]: x[-1:] 
Out[5]: [u'final_result']

请注意,由于无法保证节点的顺序,因此此代码段并不总是有效,但它通常会为您提供所需的信息或验证。

现在,我们准备讨论如何进一步修改重新训练的模型,以便可以在移动设备上部署和运行它。 重新训练的模型文件dog_retrained.pb的大小太大,大约 80MB,在部署到移动设备之前,应该经过两个步骤进行优化:

  1. 去除未使用的节点:删除模型中仅在训练期间使用但在推理期间不需要的节点。
  2. 量化模型:将模型参数的所有 32 位浮点数转换为 8 位值。 这样可以将模型大小减小到其原始大小的 25%,同时保持推理精度大致相同。

TensorFlow 文档提供有关量化及其工作原理的更多详细信息。

有两种方法可以执行前面的两个任务:使用strip_unused工具的旧方法和使用transform_graph工具的新方法。

让我们看看旧方法的工作原理:首先运行以下命令以创建一个模型,其中所有未使用的节点都将被删除:

bazel build tensorflow/python/tools:strip_unused 
bazel-bin/tensorflow/python/tools/strip_unused  
  --input_graph=/tf_files/dog_retrained.pb  
  --output_graph=/tf_files/stripped_dog_retrained.pb  
  --input_node_names=Mul  
  --output_node_names=final_result  
     --input_binary=true

如果在输出图中运行前面的 Python 代码,则可以找到正确的输入层名称:

In [1]: import tensorflow as tf 
In [2]: g=tf.GraphDef() 
In [3]: g.ParseFromString(open("/tf_files/ stripped_dog_retrained.pb", "rb").read()) 
In [4]: x=[n.name for n in g.node] 
In [5]: x[0] 
Out[5]: [u'Mul']

现在运行以下命令来量化模型:

python tensorflow/tools/quantization/quantize_graph.py  
   --input=/tf_files/stripped_dog_retrained.pb   
--output_node_names=final_result   
--output=/tf_files/quantized_stripped_dogs_retrained.pb  
   --mode=weights

之后,可以在 iOS 和 Android 应用中部署和使用模型quantized_stripped_dogs_retrained.pb,我们将在本章的以下部分中看到。

剥离未使用的节点并量化模型的另一种方法是使用称为transform_graph的工具。 这是 TensorFlow 1.4 中推荐的新方法,并且可以在 Python label_image脚本中正常工作,但是在部署到 iOS 和 Android 应用时仍然会导致不正确的识别结果。

bazel build tensorflow/tools/graph_transforms:transform_graph
bazel-bin/tensorflow/tools/graph_transforms/transform_graph  
  --in_graph=/tf_files/dog_retrained.pb  
  --out_graph=/tf_files/transform_dog_retrained.pb  
  --inputs='Mul'  
  --outputs='final_result'  
  --transforms=' 
    strip_unused_nodes(type=float, shape="1,299,299,3") 
    fold_constants(ignore_errors=true) 
    fold_batch_norms 
    fold_old_batch_norms 
    quantize_weights'

在测试中使用label_image脚本可以正确运行quantized_stripped_dogs_retrained.pbtransform_dog_retrained.pb。 但是只有第一个可以在 iOS 和 Android 应用中正常工作。

有关图转换工具的详细文档,请参见其 GitHub README

TensorFlow 智能移动项目:1~5(2)https://developer.aliyun.com/article/1426903

相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
5天前
|
TensorFlow 语音技术 算法框架/工具
TensorFlow 智能移动项目:1~5(5)
TensorFlow 智能移动项目:1~5(5)
41 0
|
5天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
TensorFlow 智能移动项目:1~5(4)
TensorFlow 智能移动项目:1~5(4)
37 0
|
5天前
|
TensorFlow 算法框架/工具 Android开发
TensorFlow 智能移动项目:1~5(2)
TensorFlow 智能移动项目:1~5(2)
45 0
|
5天前
|
TensorFlow 算法框架/工具 开发工具
使用 TensorFlow 构建机器学习项目:6~10(3)
使用 TensorFlow 构建机器学习项目:6~10(3)
25 0
|
5天前
|
机器学习/深度学习 机器人 TensorFlow
TensorFlow 智能移动项目:11~12
TensorFlow 智能移动项目:11~12
42 0
|
5天前
|
机器学习/深度学习 TensorFlow API
TensorFlow 智能移动项目:1~5(3)
TensorFlow 智能移动项目:1~5(3)
43 0
|
5天前
|
TensorFlow 算法框架/工具 Docker
使用 TensorFlow 构建机器学习项目:6~10(2)
使用 TensorFlow 构建机器学习项目:6~10(2)
48 0
|
5天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
使用 TensorFlow 构建机器学习项目:6~10(1)
使用 TensorFlow 构建机器学习项目:6~10
23 0
|
5天前
|
机器学习/深度学习 算法 TensorFlow
使用 TensorFlow 构建机器学习项目:1~5
使用 TensorFlow 构建机器学习项目:1~5
202 0
|
2天前
|
机器学习/深度学习 数据可视化 TensorFlow
使用TensorFlow进行深度学习入门
【5月更文挑战第18天】本文介绍了TensorFlow深度学习入门,包括TensorFlow的概述和一个简单的CNN手写数字识别例子。TensorFlow是由谷歌开发的开源机器学习框架,以其灵活性、可扩展性和高效性著称。文中展示了如何安装TensorFlow,加载MNIST数据集,构建并编译CNN模型,以及训练和评估模型。此外,还提供了预测及可视化结果的代码示例。