本博客的内容是:在 BlackWalnut Labs 完成车牌标志识别实验的学习笔记
其中主要的部分是 BlackWalnut Labs 的实验过程介绍,少部分自己实验过程中的心得,所以就作为转载自 BlackWalnut 的一篇博文吧
这次车标识别实验,主要内容是通过机器学习,构建模型,区分不同车牌标志。本次“车标图像分类”项目,基于TensorFlow框架和MobileNet模型,将其应用于分类不同车标的图片,可以说是基于Google Codelabs项目 ——tensorflow-for-poets 的衍生。
本次实验中,我们将要使用 5 种车标图像训练一个 MobileNet模型,并将其应用于不同车标图片的识别分类。在实验中,我们将学到以下内容:
1.收集并分类车标图像
2.简单使用 MobileNet_v1_128 模型
3.尝试训练模型并测试效果
4.分别测试 Learning Rate 为 0.1、0.001、0.0001、0.00001 时的训练效果
5.测试将预训练模型替换为 MobileNet_v1_224 后的训练效果
6.学习如何选择最好的训练超参数,执行预测
1.对Linux和python命令基本了解
2.已经配置好tensorflow的Linux的开发环境
3.由于实验过程需要相关数据和开发环境,建议在BlackWalnut Labs注册账户,并使用该实验室提供的环境进行相关实验。注意:以下实验均在BlackWalnut Labs所提供的环境下进行。
4.如果想在自己的环境中进行本次试验,其图片数据建议在image_net网站自己下载。或者直接做tensorflow-for-poets这个项目。
首先,我们需要收集大量相关车牌的图片,并对图片数据进行分类标识。之后,通过这些图片数据集,对MobileNet模型进行训练,使之能够对新的数据进行预测和判断。最后,可以通过使用新的图片数据,对该模型进行准确性检验。
在用户目录下,新建名为Codelab的空目录,并在该目录下,新建名为data的子目录。在Codelab目录下,使用终端导入训练数据:
cp -r ../Tools/datasets/* data
在图像分类模型的训练过程中,模型需要知道训练的标签以及每个标签对应的图片,因此还需要图片按照车标种类分类。
在data目录下,新建标签文件夹,分别命名为:BUICK、CHANGAN、BMW、NISSAN、GM,之后将图片数据按照内容,分别移动到对应的文件夹下,执行以下命令:
cd ~/Codelab/data
mv 1521121* BUICK
mv 1521171* CHANGAN
mv 1521187* BMW
mv 1521189* NISSAN
mv 1521257* GM
MobileNet V1 模型目前支持 2 种分辨率的图像,分别为 128128 和 224224,其提供的训练程序会自动将传入的图片转换成指定的分辨率。下面使用MobileNet_v1_128模型,即分辨率为128*128的MobileNet_v1模型进行训练。
首先需要声明环境变量,即训练时所要用到的模型以及图像参数。在终端输入以下内容:
IMAGE_SIZE=128
ARCHITECTURE="MobileNet_1.0_${IMAGE_SIZE}"
其中,IMAGE_SIZE
表示输入图像的分辨率,ARCHITECTURE
定义了模型的相对大小。
车标识别的训练基于 Google 提供的 tensorflow-for-poets 项目,切换到终端界面,在 Codelab 目录下新建名为 scripts 的目录,进入 Codelab 目录,将 Tools/project 目录下提供的程序复制到该目录下。使用以下命令:
cd ~/ Codelab
cp -r ../Tools/project/* .
该项目在训练时会自动把数据集分类成三种数据集,一种是训练集,一种是测试集,一种是验证集,在默认情况下,这三种数据集的比例分别为 80%、10%、10%。下面开始训练模型,参照下面的做法执行训练,使用以下命令:
python3 -m scripts.retrain \
--bottleneck_dir=tmp/bottlenecks \
--how_many_training_steps=5000 \
--model_dir=model \
--summaries_dir=tmp/training_summaries/"${ARCHITECTURE}" \
--output_graph=output/retrained_graph_128_0_01.pb \
--output_labels=output/retrained_labels_128_0_01.txt \
--architecture="${ARCHITECTURE}" \
--testing_percentage=10 \
--validation_percentage=10 \
--image_dir=data \
--learning_rate=0.001
其中的 参数含义如下:
参数 | 解释 |
---|---|
bottleneck_dir | 表示训练集转换后的文件存放的目录 |
how_many_training_steps | 表示总训练的步数 |
model_dir | 表示模型文件存放的目录,如果目录下不存在模型则会自动下载 |
summaries_dir | 表示训练的中间结果存放的目录 |
output_graph 和 output_labels | 表示训练结果输出的目录 |
architecture | 设置的训练参数 |
image_dir | 数据集存放的目录。 |
testing_percentage | 测试集的比例,默认值为 10 |
validation_percentage | 验证集的比例,默认为 10 |
learning_rate | 作为模型训练的超参数 |
在执行训练后,程序会自动下载模型文件并进行训练,并且训练结束后在output 目录下生成 retrained_graph_128_0_01.pb
文件和retrained_labels_128_0_01.txt
文件。
模型训练结束之后,可以对模型进行评估,以查看模型识别的准确率。
模型评估有两种方式:一种是通过 Tensorboard 查看训练过程中各个参数的值,另一种是执行评估程序直接查看识别准确率。
①通过 Tensorboard查看训练参数
在终端中输入以下命令:
tensorboard --logdir= Codelab/tmp/training_summaries
其中,logdir
指向将数据序列化的目录。如果此 logdir 目录下有子目录,而子目录包含基于各个运行的序列化数据,则 TensorBoard 会将所有这些运行涉及的数据都可视化。TensorBoard 运行后,在浏览器中转到 localhost:6006
以查看 TensorBoard。
在TensorBoard中,选择scalars栏,其中的accuracy_1 曲线图即为识别的准确率随着训练步数的增加的变化情况。
②通过执行评估程序查看识别准确率
可以通过刚刚训练生成的retrained_graph_128_0_01.pb
文件和retrained_labels_128_0_01.txt
文件进行模型评估。
文件 | 含义 |
---|---|
retrained_graph_128_0_01.pb | which contains a version of the selected network with a final layer retrained on your categories. |
retrained_labels_128_0_01.txt | which is a text file containing labels. |
下面将使用evaluate
脚本查看识别的准确率,该脚本文件在Codelab/scripts目录下,在该文件中,需要注意以下内容:
文件内容 | 注意事项 |
---|---|
with load_graph(graph_file_name).as_default() as graph:ground_truth_input = tf.placeholder(tf.float32, [None, 5], name=‘GroundTruthInput’) | 其中的数字“5“标志训练模型中标签的数量,也就是模型的种类 |
image_dir = ‘tf_files/flower_photos’ image_dir | 定义了图片数据集的目录,这里应改为data |
with tf.Session(graph=graph) as sess:for filename, ground_truth in zip(filenames, ground_truths):image = Image.open(filename).resize((224,224),Image.ANTIALIAS) | 数字“224“表示图片的分辨率,这里应改为128 |
进入终端界面,输入以下命令:
python3 -m scripts.evaluate output/retrained_graph_128_0_01.pb
执行评估程序。输出值中 Accuracy
即为训练的准确率。
决定最终识别率的因素有三种,一种是训练的模型,一种是数据集的完整性和干净性,另一种是训练的超参数的合理性。
超参数即不会在训练过程中随着训练的进行而发生变化的训练参数,在本次练习中,选择 learning_rate
为超参数并将其调整为 0.1、0.001、0.0001、0.00001 再次训练。
使用retrain脚本可以对模型进行重新训练,以learning_rate为0.1为例,执行命令为:
python3 -m scripts.retrain \
--bottleneck_dir=tmp/bottlenecks \
--how_many_training_steps=5000 \
--model_dir=model \
--summaries_dir=tmp/training_summaries/"${ARCHITECTURE}" \
--output_graph=output/retrained_graph_128_0_1.pb \
--output_labels=output/retrained_labels_128_0_1.txt \
--architecture="${ARCHITECTURE}" \
--testing_percentage=10 \
--validation_percentage=10 \
--image_dir=data \
--learning_rate=0.1
其中参数的含义在上文中已经介绍。如果想要改变超参数learning_rate
,需要修改的参数有learning_rate
“、output_graph
和output_labels
,其中注意训练不同超参数的模型时,output_graph
和output_labels
的要改为不同的文件名。
注意:
该--learning_rate
参数控制训练期间最终层的更新幅度。目前,tensorflow-for-poets
项目已将其删除,因此程序使用默认learning_rate
的值为0.01。如果指定一个小的learning_rate
,比如0.005,训练需要更长时间,但整体精度可能会增加。值越高的learning_rate
,比如1.0,可以训练速度更快,但通常会降低精度,甚至使培训不稳定。
可以根据自己的需要,尝试改变--learning_rate
参数进行多次训练。之后再通过evaluate
脚本,对训练的模型进行评估。其命令举例如下:
python3 -m scripts.evaluate output/retrained_graph_128_0_001.pb
调整训练分辨率:
当然,训练时所使用的图像分辨率也是训练的超参数之一,不同的分辨率同样会影响模型的训练结果。我们同样可以对图像分辨率进行修改,再进行多次训练,对再训练的模型进行评估。其中需要注意的就是要更新环境变量IMAGE_SIZE
的值为224,还要修改evaluate.py
脚本中IMAGE_SIZE
相关的参数,这里就不再赘述了。
其实,当我们在“4.3.2模型训练“这一步结束之后,就可以直接通过训练生成的模型,进行图片识别测试了,” 4.3.3模型评估(可选)“和”4.3.4尝试其他超参数(可选)“这两节是为了让我们了解一下如何评估模型以及如何通过改变超参数,影响模型训练的精度。
Nice,现在我们得到了训练之后的模型,就可以对新的图片进行预测识别了。
我们现在~/Codelab目录下,新建一个test文件夹,以放置我们想要预测的图片,之后利用label_image
脚本,对这个图片进行预测,命令如下:
python3 -m scripts.label_image \
--graph=output/retrained_graph_224_0_01.pb \
--labels=output/retrained_labels_224_0_01.txt \
--input_height=224 \
--input_width=224 \
--image=test/image.jpg
其中参数的含义如下:
参数 | 含义 |
---|---|
–graph | 训练生成模型的.pb文件的路径 |
–labels | 训练生成模型的.txt文件的路径 |
–input_height | 设置图片的高度,注意要与训训练模型一致 |
–input_width | 设置图片的宽度,注意要与训训练模型一致 |
–image=test/image.jpg | 想要测试的图片的路径,注意图片的文件名 |
执行向上面的测试命令,如果你使用了BMW车标的图片,你可能会看到以下结果:
表示车牌的标签和该标签预测所得的分数,wow,bmw对应的得分最高,说明该模型预测,此图片为BMW标签的概率比较大,跟实际一样哦!
如果想进一步验证模型的准确性,需要对这五种标签的图片都进行测试。如果五种标签全部预测成功,才能更好的说明模型的准确性。
BlackWalnut Labs提供的线上开发环境,解决了开发环境配置的一些问题,对初学者非常友好。
虽然说按照实验导引可以完成整个实验,但是课后还是得自学一下tensorflow的基础内容,认真总结一下才能理解更加深入。