使用 Tensorflow 进行物品预测
序
这套流程主要是为了记录我在学习以及模型训练的过程,以及其中遇见的相关问题
环境
- CPU: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
- MEM: 384GB 2400 DDR4
- GPU: Matrox Electronics Systems Ltd. G200eR2
- DISK: 1.1 TB
- System: Ubuntu 18.04 LTS
- Python: 3.6.7
- TensorFlow: 1.12.0
因为 GPU 并不是 NVIDIA,所以不支持 CUDA 加速,目前只能使用 CPU 进行 Tensorflow 学习,在 10 月 20 日,Python 版本升级到了 3.7,然而到现在 (11 月 28 日),Tensorflow 还只支持 3.6,故 Python 版本我们选择了 3.6.7,也就是 Python 3.6 的最后一个版本
流程
1. 安装 Python
2. 编译并安装 Tensorflow 以及相关依赖
3. 安装 Tensorflow Model
4. 使用 labelImg 进行图片标注
5. 修改 Model 代码,生成 trainval.txt,将图片及标注文件转换成 TFRecord
6. 下载一套 COCO 数据集,并更改 pipeline.config
7. 进行 40000 次的模型训练,生成 ckpt 文件
8. 将 ckpt 转换成 GRAPH 的 pb 冻结图
9. 使用 pb 冻结图进行物品图片预测
Miniconda
conda 和 virtualenv 一样,可用于 Python 项目做多版本环境创建与切换的,也就是在同一个环境中,可以存在几个不同 python 版本或者不同 requirement 的虚拟环境,在安装依赖更新包都十分方便,anaconda 太大了,我也不需要那么多的包,所以我这里使用的是 Miniconda
下载
首先我们需要下载 Miniconda,可以点击这里,进入 Miniconda 的官网
右键复制他的下载地址,通过 wget 进行下载
1 | wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh |
等待进度条走完后完成下载
安装
现在完毕后我们使用 bash 命令运行这个 sh 文件
1 | bash Miniconda3-latest-Linux-x86_64.sh |
按下回车,查看 Licenses,并输入 yes 进行下一步安装
下一步输入安装路径,我这里是安装到了 /opt/miniconda3
这个目录下
经过解包后,会提示你是否添加环境变量,这里我们选择 yes,进行添加环境变量
最后完成环境 Miniconda 的安装
我们可以通过下面的命令查看环境变量是否添加
1 | tail .bashrc |
添加完环境变量后,我们需要用 source
更新一下,才能使环境变量生效
1 | source .bashrc |
使用
降级
因为 Tensorflow 现在只支持 3.6 版本的 Python,然而我们下载的是最新版本的 Miniconda,里面预装的是 3.7 最新版本的,所有我们需要进行降级,将 python 切换到 3.6.7
1 | conda install python=3.6.7 |
经过解析环境后 Solving environment
后,我们选择 yes,进行降级操作
经过一段时间的等待,我们就成功的将 Python 版本降到了 3.6.7
之后运行下面的命令 安装必要的包
1 | conda install numpy keras-preprocessing |
更新
可以使用下面的命令进行 conda 升级
1 | conda update conda |
可以使用下面的命令进行当前所有包进行升级
1 | conda update --all |
清理
conda 长时间使用后,体积会很大,可以使用下面命令将已经下载包进行清理
1 | conda clean -a -y |
卸载
如果需要需要卸载 conda,可以用下面的命令将相应位置的 Miniconda 目录直接删除
1 | rm -rf /opt/miniconda3/ |
然后使用下面的命令,编辑环境变量
1 | vi ~/.bashrc |
将环境变量中的关于 conda 的内容直接删除即可
Tensorflow
Tensorflow 目前分 2 个安装方法
- CPU 版
- GPU 版
除了通常的算术和逻辑,现代 CPU 提供了许多低级指令,称为扩展,例如, SSE2,SSE4,AVX 等来自维基百科:
高级矢量扩展(AVX)是英特尔在 2008 年 3 月提出的英特尔和 AMD 微处理器的 x86 指令集体系结构的扩展,英特尔首先通过 Sandy Bridge 处理器在 2011 年第一季度推出,随后由 AMD 推出 Bulldozer 处理器在 2011 年第三季度.AVX 提供了新功能,新指令和新编码方案。
特别是,AVX 引入了融合乘法累加(FMA)操作,加速了线性代数计算,即点积,矩阵乘法,卷积等。几乎所有机器学习训练都涉及大量这些操作,因此将会支持 AVX 和 FMA 的 CPU(最高达 300%)更快。该警告指出您的 CPU 确实支持 AVX(hooray!)。
在此强调一下:
这只限于 CPU。如果你有一个 GPU,你不应该关心 AVX 的支持,因为大多数昂贵的操作将被分派到一个 GPU 设备上(除非明确地设置)。在这种情况下,您可以简单地忽略此警告。
那为什么会出现这种警告呢?
由于 tensorflow 默认分布是在没有 CPU 扩展的情况下构建的,例如 SSE4.1,SSE4.2,AVX,AVX2,FMA 等。默认版本(来自 pip install tensorflow 的版本)旨在与尽可能多的 CPU 兼容。另一个观点是,即使使用这些扩展名,CPU 的速度也要比 GPU 慢很多,并且期望在 GPU 上执行中型和大型机器学习培训。
我们机器没有 GPU 能够使用,为了尽可能多地利用 CPU,且我们的 CPU 支持 AVX,AVX2,为了更好效率,我们使用 Bazel 重新构建 Tensorflow,不仅在以后的使用中,消除 AVX 等警报,还可以改善 Tensorflow 的性能
可以根据个人需求选择是否编译,也可以直接安装发行版本的 Tensorflow
JDK
安装 Bazel,需要 Java JDK1.8 或更高版本的支持,所以我们的第一项工作就是安装 JDK
关于 JDK 的安装教程,可以点击这里查看。
Bazel
依赖
首先运行下面的代码,安装 Bazel 相关依赖,因为我们已经安装过 python 就不需要安装了
1 | apt-get install pkg-config zip g++ zlib1g-dev unzip |
安装
请点击这里打开 Bazel Releases 下载页面,选择相应版本进行下载
然后运行下面的命令,给 sh 文件加权限并运行
1 | chmod +x bazel-0.19.2-installer-linux-x86_64.sh |
加载完毕后,看到 Bazel is now installed! 标明 Bazel 已安装成功
编译 Tensorflow
首先我们先用 git 把 Tensorflow 的源码下载下来
1 | git clone https://github.com/tensorflow/tensorflow.git |
现在完毕后,我们需要运行 configure, 做一些必要的配置
1 | cd tensorflow |
接下来,配置系统会给出各种询问,以确认编译时的配置参数,请根据个人情况配置参数,我这里全部选择的 n,其他的为默认选项
在配置完 Bazel 的编译选项之后,接下来就可以使用如下指令编译 TensorFlow 的源代码
1 | bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package |
这个时候,我们就可以去喝喝水,休息一会,等待编译完毕即可
半个小时后,当我们看到这个提示,就标明 tensorflow 已经编译成功,在临时文件夹中生成了一堆 binary,当前目录下也有软连接,可以直接运行下面的命令,生成 whl 文件,
1 | bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg |
成功生成 whl 文件
安装 Tensorflow
接下来运行下面的命令,直接安装生成的 whl
1 | pip install /tmp/tensorflow_pkg/tensorflow-1.12.0rc0-cp36-cp36m-linux_x86_64.whl |
在经过相关依赖安装之后,提示安装成功
接下来我们可以跑一个例子
1 | cd ~ |
如图所示,可以得到结果,则说明 Tensorflow 已成功安装了
Tensorflow Object Detection API
Tensorflow Object Detection API 可实现基于给定模型检测图像中的特定目标,是典型的深度学习在计算机视觉中的应用
包含在 Tensorflow Model 中
Tensorflow 旧版本自带 model,然而新版本已经没有了,就需要我们自己单独下载
下载
首先运行下面的命令,安装 Tensorflow Object Detection API 的依赖
1 | conda install Cython contextlib2 pillow lxml jupyter matplotlib |
虽然都在本次教程中,都不会全用上,但是以后总会用找到了
使用下面的命令,从 Tensorflow models 下载最新的文件
1 | git clone https://github.com/tensorflow/models.git |
如果网络不太好,就多 clone 几次,总会成功的
COCO API installation
我们需要使用 COCO 预处理数据集,需要下载 cocoapi,使用下面命令完成 COCO API 的安装
1 | git clone https://github.com/cocodataset/cocoapi.git |
Protobuf 编译器安装和使用
Tensorflow 对象检测 API 使用 Protobufs 配置模型和训练参数。
在使用框架之前,必须编译 Protobuf 库。
首先点击这里 Protobuf Releases 下载页面,选择相应版本进行下载
然后使用下面的命令解压 zip 的包到存储的目录下
1 | unzip -d /opt/protoc protoc-3.6.1-linux-x86_64.zip |
并将下面的信息添加至环境变量到.bashrc
1 | export PATH="/opt/protoc/bin:$PATH" |
添加完毕并 source 更新环境变量后,运行以下命令来编译 Protobuf 库
1 | cd /opt/models/research/ |
将库添加到 PYTHONPATH
在本地运行时,models/research/ 和 slim 目录应该附加到 PYTHONPATH。这可以通过从 tensorflow/models/research/ 运行以下命令来完成:
1 | export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim |
此命令需要从您启动的每个新终端运行。如果您希望避免手动运行,可以将其作为新行添加到~/.bashrc 文件的末尾,将
pwd
替换为系统上 tensorflow/models/research 的绝对路径。
如果你要添加环境变量,可以将下面的内容添加至环境变量并用 source 更新
1 | export PATH="/opt/models/research:/opt/models/research/slim:$PATH" |
测试安装
您可以测试是否已正确安装 Tensorflow 对象检测
通过运行以下命令 API:
1 | python object_detection/builders/model_builder_test.py |
运行结果如图所示,表明 Tensorflow Object Detection API 已配置完毕
LabelImg
首先需要先要标注图像相应标签,这里可以使用 labelImg 工具。
下载
请点击这里打开 LabelImg Download list 页面,下载合适版本的图片
使用
解压后,直接双击 labelImg.exe
文件运行
对对象物体画框,并记录相应对象的名称,save 完成保存 xml 文件完成标注
每标注一张样本,即生成一个 xml 的标注文件
并分类别保存,记得保持图片名称及 XML 标注文件名称一致,最后同一类别文件夹效果如图所示
一次完成,每个类别保证有 200 张左右的样本,多个类别下的图片再统一放到一个目录下,效果如图所示
填写 pbtxt 文件
在图片预测的时候,并不会直接把对象名字反馈回来,所以我们需要一个映射文件 pbtxt,进行标签名和数字的转换,格式如图所示
将自己标记的图片中对象及自己编号按照格式放到一个 pbtxt 文本中,之后会用得到
trainval.txt 文件生成
接下来就要进行 TFRecord 格式文件转换了,使用官方版的 Api 就可以生成 trainval.txt,但是为了方便多个类别的使用,我对代码进行了一些更改,对类别下的样本进行随机,并按 4:1 的比率生成 train.txt 和 val.txt,以保证总体样本上的随机,以提高数据的准确性
关键代码如图所示
最后会生成 2 个文件内容如图所示
TFRecord 文件生成
在生成 TFRecord 的时候,会根据 train.txt 和 val.txt 的内容,逐条生成产生 train.record 和 val.record
我是用的是 object_detection/dataset_tools/create_pet_tf_record.py,并进行了一定的更改,对 tainval 分别处理,进行图片格式转换,都转换成 JPEG 格式,对 mask 去除,并将输出 record 保存为一个
图片格式转换代码如图所示
最后生成 2 个文件,以便进行下一步训练
预训练模型下载
Tensorflow Object Detection API 提供了很多模型进行下载,可以点击这里打开 Tensorflow detection model zoo 页面,选择想要的模型进行下载
我选择的是 ssd_inception_v2_coco
模型下载,下载后将 object_detection/samples/configs/ssd_inception_v2_coco.config
这里的文件放到解压后的模型下,并修改参数
主要是 5 个地址进行修改,更换成刚刚生成好的 tfreord 文件地址,和模型下的 ckpt 地址
num_examples 是 val.txt 中测试样本的数目
num_steps 是训练步数
train 训练
首先说明我的目录结构如图所示,我直接将 object_detection
和 slim
到工程文件夹下了,使用起来更方便
修改完毕后,我们就可以进行样本训练了
在早期的版本 Tensorflow 中,使用 train.py
进行训练,在 object_detection
目录下,现在已经搬到 object_detection\legacy
目录下了,现在还可以使用,使用命令如下
1 | object_detection\legacy\train.py \ |
在新版本的 Tensorflow 中,都是使用 model_main.py
进行训练,在 object_detection
目录下,使用命令如下
1 | object_detection\model_main.py \ |
<name_to_project>
是我的项目名称
在经过漫长的等待 (2 天) 后,日志终于结束打印
我们也可以在输出文件夹 data/model
中看到相应步数的检查点
导出推理图
要在代码中使用模型,需要将检查点文件(model.ckpt-STEP_NUMBER.*)转换为推理图。
你可以运行下面的代码,将检查点的 ckpt 文件转换成推理图
1 | python object_detection\export_inference_graph.py \ |
导出后的文件如图所示,我们使用的就是 frozen_inference_graph.pb
文件
测试模型
如何使用模型呢,我们可以点击这里,这是 Jupyter 的运行文件,我们可以将运行代码拷贝到新建的一个 python 文件中,或者查找相应的转换工具使用
将 PATH_TO_TEST_IMAGES_DIR
参数改为自己要测试的图片
将 PATH_TO_FROZEN_GRAPH
参数改为 frozen_inference_graph.pb
的路径
将 PATH_TO_LABELS
参数改为 xxx.pbtxt
的路径
然后运行这个 python,稍等片刻,我们就看到的预测结果
附件
相关链接: