本文主要来源于YouTube博主 EdjeElectronics的视频https://www.youtube.com/watch?v=Rgpfk6eYxJA (对于视频看不了的朋友,我把视频录制下来放到云盘里了https://pan.baidu.com/s/1hF8LA34szDhMK5563PqLXQ),以及对应的GitHub教程TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10
笔者只是按照YouTube视频和GitHub教程操作了一遍,亲测有效,原作者写的十分详尽。以下是对教程重点做了个翻译,并将整个过程中我碰到的问题也在下文中用红色标出,若还有其他的问题欢迎一起探讨
1. 安装TensorFlow-GPU 10
根据网上的安装指南或YouTube视频 https://www.youtube.com/watch?v=RplXYjxgZbw进行安装。注意在命令行中输入pip install tensorflow-gpu==1.10.0而非pip install tensorflow-gpu来安装并指定tensorflow-gpu版本,否则会安装最新版1.12.0,这个版本的tensorflow尚未有对应版本的cuDNN。
安装anaconda,并安装Python3.6(已经出了python3.7,但为了保证版本兼容性不安装最新版本)
2. 建立TensorFlow路径和Anaconda虚拟环境
为保证此文档的通用性,需要按照以下步骤建立特定的路径。并且需要额外的Python安装包、特定的路径变量以及安装指令,从而完成目标检测模型的训练和执行。
2.1 从GitHub下载TensorFlow Object Detection API
直接在C:盘建立文件夹并命名为tensorflow1,以保证之后各指令的通用性。该文件夹中包含所有TensorFlow目标检测的框架,以及训练图片、训练数据、训练好的分类器、参数文件等。
点击链接https://github.com/tensorflow/models下载压缩包,将解压后的models-master文件夹放入到C:\tensorflow1中,并将其重新命名为master。
2.2 从TensorFlow model zoo下载Faster-RCNN-InceptionV2-COCO模型
TensorFlow提供了很多目标检测模型(用特定神经网络进行预训练的分类器,比如Inception-V2) model zoo。其中一些网络(例如SSD-MobileNet)检测速度较快但精度不高,而另一些(例如Faster-RCNN)速度较慢但是精度高很多。
选择模型时,若要在计算能力较差的设备上(智能手机、树莓派、FPGA等嵌入式系统中),使用SSD-MobileNet系列,若在工作站上训练检测可使用RCNN系列。
以下训练基于Faster-RCNN-Inception-V2,点击下载模型Download the model here.并将faster_rcnn_inception_v2_coco_2018_01_28解压到C:\tensorflow1\models\research\object_detection。(模型的日期肯能会有更新,但应该仍适用于本教程)。
2.3 在GitHub中下载本教程的资源库
从https://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10#3-gather-and-label-pictures中下载资源。将解压后的文件直接放入到C:\tensorflow1\models\research\object_detection directory,(可以覆盖"README.md"文件)。建立这个指定的路径以确保教程中的后续操作成功执行。
至此,\object_detection文件夹应如下图所示:
这个资料库包括用于训练"Pinochle Deck"检测器的图片、标注数据、.csv文件,以及TFRecords。可以利用这些图片来训练自己的Pinochle Card检测器,并在图像、视频和网络摄像头中进行验证。
以下直接介绍如何训练自己的数据集。
首先删除以下文件(不要删除文件夹):
- \object_detection\images\train and \object_detection\images\test
- \object_detection\images中“test_labels.csv”和“train_labels.csv”文件
- \object_detection\training中所有文件
- \object_detection\inference_graph中所有文件
至此,默认以上文件均被删除,接下来将介绍如何用自己的数据集生成各类训练文件。
2.4 建立Anaconda虚拟环境
之后再Anaconda中建立tensorflow-gpu虚拟环境。从Windows菜单中找到Anaconda Prompt,以管理员身份运行(不是必须的)。
在命令终端中(任何路径下均可)输入以下命令建立名为tensorflow1的虚拟环境。(这部分和原文教程略有出入)
C:\> conda create -n tensorflow1 pip python=3.6
(最新Python版本已经是3.7,但为了保证兼容性,只安装3.6)
之后激活tensorflow1这个环境
C:\> activate tensorflow1
在该环境下安装tensorflow-gpu
(tensorflow1) C:\> pip install tensorflow-gpu==1.10
(目前tensorflow最新版本是1.12。但今早刚在微信公众号“机器之心”中看到tensorflow1.11/1.12版本中tf.keras Dropout层出了问题,导致用户调用model.fit时出现bug。此外笔者在实际操作时发现tensorflow1.12还没有对应的cuDNN版本,因此不得不将至tensorflow1.10版本。之后打开Anaconda,选择tensorflow1,在uninstalled中找到cudatoolkits9.x和cuDNN7.x进行安装,完成tensorflow-gpu的搭建)
之后安装必要安装包
(tensorflow1) C:\> conda install -c anaconda protobuf
(tensorflow1) C:\> pip install pillow
(tensorflow1) C:\> pip install lxml
(tensorflow1) C:\> pip install Cython
(tensorflow1) C:\> pip install jupyter
(tensorflow1) C:\> pip install matplotlib
(tensorflow1) C:\> pip install pandas
(tensorflow1) C:\> pip install opencv-python
2.5 配置PYTHONPATH环境变量
需要建立一个直指\models, \models\research, and \models\research\slim的路径。输入以下命令(任何路径下输入均可):
(tensorflow1) C:\> set PYTHONPATH=C:\tensorflow1\models;C:\tensorflow1\models\research;C:\tensorflow1\models\research\slim
(注意:每一次关闭Anaconda Prompt或者退出tensorflow1虚拟环境时,PYTHONPATH变量都会被重置,都要重新设置一遍)
2.6 编译Protobuf文件
之后编译Protobuf文件,TensorFlow用Protobuf文件来配置模型以及训练参数。
在Anaconda Prompt中将路径改到\models\research,输入下面的指令:
protoc --python_out=. .\object_detection\protos\anchor_generator.proto .\object_detection\protos\argmax_matcher.proto .\object_detection\protos\bipartite_matcher.proto .\object_detection\protos\box_coder.proto .\object_detection\protos\box_predictor.proto .\object_detection\protos\eval.proto .\object_detection\protos\faster_rcnn.proto .\object_detection\protos\faster_rcnn_box_coder.proto .\object_detection\protos\grid_anchor_generator.proto .\object_detection\protos\hyperparams.proto .\object_detection\protos\image_resizer.proto .\object_detection\protos\input_reader.proto .\object_detection\protos\losses.proto .\object_detection\protos\matcher.proto .\object_detection\protos\mean_stddev_box_coder.proto .\object_detection\protos\model.proto .\object_detection\protos\optimizer.proto .\object_detection\protos\pipeline.proto .\object_detection\protos\post_processing.proto .\object_detection\protos\preprocessor.proto .\object_detection\protos\region_similarity_calculator.proto .\object_detection\protos\square_box_coder.proto .\object_detection\protos\ssd.proto .\object_detection\protos\ssd_anchor_generator.proto .\object_detection\protos\string_int_label_map.proto .\object_detection\protos\train.proto .\object_detection\protos\keypoint_box_coder.proto .\object_detection\protos\multiscale_anchor_generator.proto .\object_detection\protos\graph_rewriter.proto
这个指令在\object_detection\protos文件夹中,给每一个name.proto对应生成了一个name_pb2.py文件。
最后在C:\tensorflow1\models\research路径下输入下面指令:
(tensorflow1) C:\tensorflow1\models\research> python setup.py build
(tensorflow1) C:\tensorflow1\models\research> python setup.py install
2.7 验证TensorFlow是否正确安装
至此TensorFlow Object Detection API已经完成安装和环境配置,可以应用预训练的模型或者训练自己的模型了,在此可以在\object_detection路径里通过Jupyter启动object_detection_tutorial.ipynb这个脚本来验证安装是否成功。输入以下指令:
(tensorflow1) C:\tensorflow1\models\research\object_detection> jupyter notebook object_detection_tutorial.ipynb
这将在默认的Web浏览器中打开脚本,并能一次一步地浏览代码部分。可以通过单击上面工具栏中的“运行”按钮逐步浏览每个部分。当小节旁边的“In[*]文本中的数字出现时,该节将完成运行(例如“In [1]”)。
(注意:其中有一步是从GitHub上下载ssd_mobilenet_v1模型,大约74M,需要多等一会,程序是在执行的,并不是死机或出错。静等In [*]中的*变成数字)
如果一切顺利,会看到两张检测图片:
如果出错,底部会有错误提示。如果运行未报错但没出现结果可能是因为:
- In[*]中的*未变成数字就运行下一步。
- 换个浏览器,开始在Microsoft Edge运行没显示出结果,换成FireFox就可以了。
如果走到了这里,恭喜诸位,万里征程已行半,繁琐的准备工作已经结束,接下来要开始构建数据集了!
3. 采集图片并标注
3.1 采集图片
具体操作不详细介绍,可以参考原文教程指南,在此要注意几点:
- 确保图片不会太大,每张不大于200KB
- 图像尺寸不大于720*1280
- 可以通过resizer.py更改图像尺寸
之后将图片按照8:2或者7:3的比例分别放置\object_detection\images\train路径和\object_detection\images\test路径下
3.2 图片标注
利用LabelImg对图片进行标注LabelImg GitHub link、或者LabelImg download link下载安装好后开始标注。
要对\images\train、\images\test中的所有图片进行标注。这回花费很多时间。
标注完成后文件会存为.xml文件格式,.xml文件用于生成TFRecords,TFRecords为TensorFlow训练器的输入之一。此外可以在命令行运行sizeChecker.py检查图片的尺寸大小是否正确:
(tensorflow1) C:\tensorflow1\models\research\object_detection> python sizeChecker.py --move
4.生成训练数据
将所有图片进行标注后,生成TensorFlow训练模型所用的输入文件TFRecords。本教程使用的是Dat Tran’s Raccoon Detector dataset中的xml_to_csv.py和generate_tfrecord.py文件。
首先将.xml文件转换成.csv文件:
(tensorflow1) C:\tensorflow1\models\research\object_detection> python xml_to_csv.py
执行后在\object_detection\images文件夹中生成train_labels.csv和test_labels.csv文件。
之后打开generate_tfrecord.py文件,从31行开始替换成自己的label map。这里每个物体都被赋予一个ID编号,并且在设置labelmap.pbtxt文件中会再一次用到。
比如,要训练的类别有basketballs, shirts,和shoes则在generate_tfrecord.py中将以下部分:
# TO-DO replace this with label map
def class_text_to_int(row_label):
if row_label == 'nine':
return 1
elif row_label == 'ten':
return 2
elif row_label == 'jack':
return 3
elif row_label == 'queen':
return 4
elif row_label == 'king':
return 5
elif row_label == 'ace':
return 6
else:
return None
替代为:
# TO-DO replace this with label map
def class_text_to_int(row_label):
if row_label == 'basketball':
return 1
elif row_label == 'shirt':
return 2
elif row_label == 'shoe':
return 3
else:
return None
之后在\object_detection文件夹路径下执行:
python generate_tfrecord.py --csv_input=images\train_labels.csv --image_dir=images\train --output_path=train.record
python generate_tfrecord.py --csv_input=images\test_labels.csv --image_dir=images\test --output_path=test.record
至此在\object_detection中生成train.record和test.record文件。这些文件将用于训练新的目标检测分类器。
(注意:生成的.csv文件用Excel打开检查一下,第一列的图片名称后面一定要跟上文件类型。比如:要把“图片1”修改为“图片1.JPG”否则这一步会报错,说找不到这个路径)
5. 构建标签映射(Label Map)和训练参数
训练前最后一步是构建label map并设置训练参数。
5.1 标签映射
标签映射通过定义类别名称和类别编号来告诉训练器每个对象是什么。建立文本文档,存入C:\tensorflow1\models\research\object_detection\training文件夹,注意要存成.pbtxt格式而非.txt格式。原文作者的Pinochle Deck Card对应的标签映射是:
item {
id: 1
name: 'nine'
}
item {
id: 2
name: 'ten'
}
item {
id: 3
name: 'jack'
}
item {
id: 4
name: 'queen'
}
item {
id: 5
name: 'king'
}
item {
id: 6
name: 'ace'
}
这里的内容要和generate_tfrecord.py中的一致。对于第4章basketball, shirt,和shoe的例子,对应的labelmap.pbtxt内容为:
item {
id: 1
name: 'basketball'
}
item {
id: 2
name: 'shirt'
}
item {
id: 3
name: 'shoe'
}
5.2 配置训练文件
最后,配置目标检测的训练文件。这会决定调用那个模型以及设置什么样的参数,这是训练前的最后一步。
定位到C:\tensorflow1\models\research\object_detection\samples\configs,并且将faster_rcnn_inception_v2_pets.config放入到\object_detection\training文件夹中。之后打开faster_rcnn_inception_v2_pets.config,进行微调。主要修改类别编号、把路径填入其中。
第9行:num_classes是类别个数,修改成自己的类别个数,对于basketball, shirt, 和shoe的例子,num_classes=3,
第110行:fine_tune_checkpoint修改为:
fine_tune_checkpoint : "C:/tensorflow1/models/research/object_detection/faster_rcnn_inception_v2_coco_2018_01_28/model.ckpt"
第126和128行:在train_input_reader部分, input_path和label_map_path改为:
input_path : "C:/tensorflow1/models/research/object_detection/train.record"
label_map_path: "C:/tensorflow1/models/research/object_detection/training/labelmap.pbtxt"
第132行:num_examples个数修改成\images\test文件夹中的图片数量
第140和142行:在eval_input_reader部分,把input_path和label_map_path路径修改成:
input_path : "C:/tensorflow1/models/research/object_detection/test.record"
label_map_path: "C:/tensorflow1/models/research/object_detection/training/labelmap.pbtxt"
(注意:修改路径中的”/”不要打成”//”或者”\”。以及”不要错打成’。此外,具体的行数可能会和本文对不上,但在附近不难找,或者参考视频。)
保存这个文件。
至此,所有配置都已完成,下一步开始训练!
6. 开始训练
这里注意有一些变动,"train.py"文件在/object_detection/legacy当中,把它放入到/object_detection中,继续以下步骤。
在路径\object_detection下输入指令:
python train.py --logtostderr --train_dir=training/ --pipeline_config_path=training/faster_rcnn_inception_v2_pets.config
如果一切设置正确的话,TensorFlow初始化之后就会开始训练。界面如下所示:
每一步训练都能看到损失函数。损失函数开始比较高,后来会下降下来。原文作者训练时,损失开始在3,后来很快下降到0.8。并建议损失函数在0.05以下基本就可以了。
查看具体的训练曲线可以利用tensorboard,另外打开一个新的Anaconda Prompt,激活tensorflow1,将路径改到C:\tensorflow1\models\research\object_detection,输入以下指令:
(tensorflow1) C:\tensorflow1\models\research\object_detection>tensorboard --logdir=training
(如果这里报错,检查两点:1.是否安装了tensorboard,如果没有,运行pip install tensorboard; 2.是否把tensorboard可执行文件添加至系统路径,如果没有,找到tensorboard路径后添加到系统路径中,具体方法参考百度。如果添加路径的时候显示注册表无法修改,记得把金山毒霸关闭掉!)
这一步对训练本身无影响,只是对训练过程能做一个可视化操作。
训练时,每五分钟会保存一次checkpoints。且可以通过在命令串口点击Ctrl+C终止训练(且只有这样训练才会停止,笔者在损失小于0.05后点击了Ctrl+C)。终止后再一次Ctrl+C继续上一个保存的checkpoints开始训练。Checkpoints训练步数最高的将被作为frozen inference graph。
7. 导出Inference Graph
训练已完成,最后一步是生成frozen inference graph (.pb文件)。在\object_detection路径下输入命令:
python export_inference_graph.py --input_type image_tensor --pipeline_config_path training/faster_rcnn_inception_v2_pets.config --trained_checkpoint_prefix training/model.ckpt-XXXX --output_directory inference_graph
并且将“model.ckpt-XXXX”中的“XXXX”修改为最高的数字(训练次数最高的那一个文件)
这个指令会在\object_detection\inference_graph文件夹中生成一个frozen_inference_graph.pb文件。这个文件包含了目标分类器。
8. 用新训练的模型做目标检测
原文作者写了图片检测,视频流检测和网络摄像头实时检测的程序,这里以图片检测为例(其余的可以参考原文和视频):
在运行Object_detection_image.py文件之前,将其中的NUM_CLASSES改成自己的类别个数,之后点击运行就可以了。