1。介绍
TensorFlow是用于数值计算的开源库,专门用于机器学习应用程序。笔者: csdn -固本培元
在这个codelab中,您将学习如何在单台机器上运行TensorFlow,并且将训练一个简单的分类器来对花朵图像进行分类。
图片由Retinafunk CC-BY
daisy (score = 0.99071) sunflowers (score = 0.00595) dandelion (score = 0.00252) roses (score = 0.00049) tulips (score = 0.00032)
我们将使用转移学习,这意味着我们从一个已经接受另一个问题培训的模型开始。然后,我们将对其进行再培训,解决类似的问题。从头开始深入学习可能需要数天时间,但转移学习可以在短时间内完成。
我们将使用在ImageNet大型视觉识别挑战数据集上训练的模型。这些模型可以区分达尔马提亚或洗碗机等1,000个不同的类别。您将可以选择模型架构,因此您可以确定问题的速度,大小和准确性之间的正确权衡。
我们将使用这个相同的模型,但重新训练它以基于我们自己的例子分解少数类。
你会学到什么
如何使用Python和TensorFlow来训练图像分类器
如何使用训练出的分类器对图像进行分类
你需要什么
对Linux命令的基本了解
2。建立
安装TensorFlow
在我们开始本教程之前,您需要安装tensorflow。
如果您已经安装了TensorFlow,请确保它是最新版本。这个codelab至少需要1.2版本。您可以使用升级到最新的稳定分支
> pip安装 - 升级tensorflow
克隆git存储库
此代码中使用的所有代码都包含在此git存储库中。克隆存储库并将其放入CD中。这是我们将要工作的地方。
git clone https://github.com/googlecodelabs/tensorflow-for-poets-2cd tensorflow-for-poets-2
3。下载训练图像
在开始任何培训之前,您需要一组图像来教授模型有关您想要识别的新课程。我们创建了一个创意共享许可花卉照片的档案,以供初次使用。通过调用以下两个命令下载照片(218 MB):
curl http://download.tensorflow.org/example_images/flower_photos.tgz \ | tar xz -C tf_files
您现在应该在工作目录中拥有花卉照片的副本。通过发出以下命令来确认工作目录的内容:
ls tf_files / flower_photos
上述命令应显示以下对象:
daisy/ dandelion/ roses/ sunflowers/ tulip/ LICENSE.txt
4。迁移学习
配置你的MobileNet
再培训脚本可以重新训练Inception V3模型或MobileNet。在这个练习中,我们将使用MobileNet。主要区别在于Inception V3针对精确性进行了优化,而MobileNet则以一些精确度为代价进行了优化,使其体积小巧高效。
Inception V3在ImageNet上的首选精度为78%,但是大小为85MB,需要比即使是最大的MobileNet配置高出许多倍,处理精度达到70.5%,只需下载19MB。
选择以下配置选项:
输入图像分辨率:128,160,192或224px。毫不奇怪,摄入更高分辨率的图像需要更多的处理时间,但会导致更好的分类准确性。我们推荐使用224作为初始设置。
模型的相对大小作为最大的MobileNet的一小部分:1.0,0.75,0.50或0.25。我们推荐0.5作为初始设置。较小的模型运行速度明显更快,但要以准确性为代价。
使用推荐的设置,通常只需几分钟即可在笔记本电脑上进行再培训。您将在Linux shell变量中传递设置。设置这些shell变量如下:
IMAGE_SIZE=224 ARCHITECTURE="mobilenet_0.50_${IMAGE_SIZE}"
下图显示了这些配置的首选精度(y轴),所需的计算次数(x轴)以及模型的大小(圆形区域)。
移动网显示16点。对于4个模型尺寸(图中的圆圈区域),每个图像分辨率设置都有一个点。128px图像大小模型由每个集合中的左下角点表示,而224px模型位于右上角。
其他值得注意的体系结构也包含在内供参考。本图中的“GoogleNet”是本表中的“Inception V1”。
启动TensorBoard
在开始训练之前,tensorboard
在后台启动。TensorBoard是一种包含在tensorflow中的监测和检测工具。您将使用它来监控训练进度。
tensorboard --logdir tf_files/training_summaries &
如果您已经有一个tensorboard正在运行,那么该命令将失败,并显示以下错误:ERROR:tensorflow:TensorBoard attempted to bind to port 6006, but it was already in use
您可以用以下命令杀死所有现有的TensorBoard实例:
pkill -f "tensorboard"
运行迁移学习脚本
迁移学习脚本是tensorflow 仓库一部分,但不作为pip软件包的一部分进行安装。所以为了简单起见,我将它包含在codelab存储库中。您可以使用python命令运行脚本。花一点时间浏览一下“帮助”。
python -m scripts.retrain -h
运行训练
正如引言中所述,Imagenet模型是具有数百万参数的网络,可以区分大量的类。我们只训练该网络的最后一层,因此训练将在合理的时间内结束。
用一个大命令开始你的再训练(注意--summaries_dir
选项,发送训练进度报告到tensorboard正在监测的目录):
python -m scripts.retrain \ --bottleneck_dir=tf_files/bottlenecks \ --how_many_training_steps=500 \ --model_dir=tf_files/models/ \ --summaries_dir=tf_files/training_summaries/"${ARCHITECTURE}"\ --output_graph=tf_files/retrained_graph.pb \ --output_labels=tf_files/retrained_labels.txt \ --architecture="${ARCHITECTURE}" \ --image_dir=/mnt/hgfs/E/recipeRes/prelabeled/
IMAGE_SIZE=224 ARCHITECTURE="mobilenet_1.0_${IMAGE_SIZE}" python -m scripts.retrain \ --bottleneck_dir=tf_files/bottlenecks_rec\ --how_many_training_steps=500\ --model_dir=tf_files/models/\ --summaries_dir=tf_files/training_summaries_rec/"${ARCHITECTURE}"\ --output_graph=tf_files/retrained_graph_rec.pb\ --output_labels=tf_files/retrained_labels_rec.txt\ --architecture="${ARCHITECTURE}"\ --image_dir=/mnt/hgfs/E/result/
该脚本下载预先训练好的模型,添加一个新的最终图层,并在您下载的花卉照片上训练该图层。
如果您使用的是Docker,并且上述命令无法报告:ERRO[XXXX] error getting events from daemon: EOF
你可能遇到过这个错误。将Docker cpu分配增加到4个或更多,在OSX上,您可以通过从Docker菜单中选择“Preferences ...”来设置此设置,该设置位于“高级”选项卡上。
ImageNet不包括我们在这里培训的任何这些花卉物种。但是,使ImageNet可以区分1,000个类别的信息种类对区分其他对象也很有用。通过使用这个预先训练的网络,我们将这些信息用作最终分类层的输入,以区分我们的花类。
可选项目:指定训练epoch 迭代
第一个重新训练命令只重复500次。通过训练更长时间,您很可能会获得更好的结果(即更高的准确性)。要获得此改进,请移除参数--how_many_training_steps
以使用默认的4,000次迭代。
python -m scripts.retrain \ --bottleneck_dir=tf_files/bottlenecks \ --model_dir=tf_files/models/ \ --summaries_dir=tf_files/training_summaries/“${ARCHITECTURE}”\ --output_graph=tf_files/retrained_graph.pb \ --output_labels=tf_files/retrained_labels.txt \ --architecture="${ARCHITECTURE}" \ --image_dir=tf_files/flower_photos
更多关于瓶颈层
本部分和下一部分提供了有关迁移训练过程如何工作的背景知识。
第一阶段分析磁盘上的所有图像并计算每个图像的瓶颈值。什么是瓶颈层?
这些ImageNet模型由多个层叠在一起组成,TensorBoard的Inception V3的简化图片如上所示。这些图层是预先训练好的,对于查找和总结有助于对大多数图像进行分类的信息已经非常有价值。对于这个codelab,你只训练最后一层(final_training_ops
在下图中)。尽管之前的所有图层都保留了他们已经训练好的状态。
在上图中,左侧标记为“softmax”的节点是原始模型的输出层。而“softmax”右侧的所有节点都是由再培训脚本添加的。
上图是张量板的截图。您可以在浏览器中打开TensorBoard,以更好地观察它。您可以在“图表”选项卡中找到它。
请注意,这只会在迁移学习脚本完成生成“瓶颈层”文件后才起作用。
一个瓶颈层是一个非正式的术语,我们只是实际执行分类的最终输出层之前经常使用的层。“Bottelneck”不是用来暗示该层正在放慢网络。我们使用术语瓶颈,因为在输出附近,表示比网络的主体更紧凑。
在训练过程中,每个图像都会重复使用多次。计算每个图像瓶颈背后的图层需要花费大量的时间。由于网络的这些较低层没有被修改,它们的输出可以被缓存和重用。
所以脚本运行网络的不变部分,Bottlene...
上面标记的节点下面的所有内容,并缓存结果。
您运行的命令将这些文件保存到bottlenecks/
目录中。如果你重新运行脚本,它们将被重用,所以你不必再等待这部分。
更多关于训练
一旦脚本完成生成所有瓶颈层文件,网络的最后一层的实际培训就开始了。
通过将每个图像的缓存值提供给瓶颈层,训练可以高效运行。每个图像的真实标签也被输入到标有节点的节点中。GroundTruth.
只需这两个输入就足以计算分类概率,训练更新和各种性能指标。
在训练时,您会看到一系列步骤输出,每个输出都显示训练准确性,验证准确性和交叉熵:
该训练精度显示了标有正确的类,目前的培训一批使用的图像的百分比。
验证准确性:验证准确性是从不同集合随机选择的一组图像中的精确度(正确标记图像的百分比)。
交叉熵是一种损失函数,可以窥见学习过程的进展情况(此处的数字越低越好)。
下图显示了模型精度和交叉熵在训练过程中的进展情况。如果您的模型已经完成了瓶颈文件的生成,您可以打开TensorBoard检查模型的进度 ,然后单击图的名称以显示它们。TensorBoard可能会向您的命令行输出警告。这些可以安全地被忽略。
衡量网络性能的一个真正指标就是衡量一个不在训练数据中的数据集的性能。该性能是使用验证准确度来衡量的。如果训练准确度高但验证准确度仍然很低,那意味着网络过度拟合,并且网络正在记忆训练图像中的特定特征,这不利于更一般地对图像进行分类。
培训的目标是使交叉熵尽可能小,因此您可以通过关注损失是否持续下降趋势来判断学习是否奏效,而忽略短期噪音。
默认情况下,此脚本运行4,000个训练步骤。每个步骤从训练集中随机选择10幅图像,从高速缓存中找到它们的瓶颈,并将它们馈送到最终图层以获得预测结果。然后将这些预测与实际标签进行比较,以通过反向传播过程更新最终图层的权重。
随着过程的继续,您应该看到报告的准确性提高。在所有训练步骤完成后,该脚本对与训练和验证图片分开保存的一组图像进行最终测试精度评估。该测试评估提供了训练模型如何在分类任务上执行的最佳估计。
您应该看到85%到99%之间的准确度值,但由于训练过程中存在随机性,所以准确值会因运行而异。(如果您只在两个分类进行训练,则应该期望更高的准确性。)此数值表示测试集中图像在模型完全训练后获得正确标签的百分比。
5。使用迁移训练模型
迁移训练脚本将数据写入以下两个文件:
tf_files/retrained_graph.pb
,其中包含所选网络的一个版本,并在您的类别上重新培训最后一层。tf_files/retrained_labels.txt
,这是一个包含标签的文本文件。
分类图像
codelab repo还包含tensorflow的label_image.py示例的副本,您可以使用它来测试您的网络。花一点时间阅读此脚本的帮助:
python -m scripts.label_image -h
正如你所看到的,这个Python程序需要很多参数。默认设置都是为这个项目设置的,但是如果您使用的MobileNet架构的图像大小不同,您需要--input_size
使用您之前创建的变量来设置参数:--input_size = $ {IMAGE_SIZE}。
现在,让我们在雏菊的这个图像上运行脚本:
flower_photos/daisy/21652746_cc379e0eea_m.jpg
图片由Retinafunk CC-BY
python -m scripts.label_image \ --graph=tf_files/retrained_graph.pb \ --image=tf_files/flower_photos/daisy/21652746_cc379e0eea_m.jpg
每次执行都会打印出花标的列表,在大多数情况下,正确的花在上面(尽管每个再培训的模型可能略有不同)。
你可能会得到这样的雏菊照片的结果:
daisy (score = 0.99071) sunflowers (score = 0.00595) dandelion (score = 0.00252) roses (score = 0.00049) tulips (score = 0.00032)
这表明图像是菊花的高信度(〜99%),并且对于任何其他标签具有低置信度。
您可以使用label_image.py
来分类您选择的任何图像文件,无论是从下载的集合还是新的。您只需将--image
文件名参数更改指向脚本。
flower_photos/roses/2414954629_3708a1a04d.jpg
Image由Lori Branham提供的CC-BY
python -m scripts.label_image \ --graph = tf_files/retrained_graph.pb \ --image = tf_files/flower_photos/roses/2414954629_3708a1a04d.jpg
6。可选步骤:尝试其他超参数
迁移训练脚本还有其他几个可用的命令行选项。
您可以在再培训脚本的帮助中阅读这些选项:
python -m scripts.retrain -h
尝试调整其中的一些选项,以查看是否可以提高最终验证的准确性。
例如,该--learning_rate
参数控制训练期间最后一层更新的大小。到目前为止,我们已经放弃了它,所以程序使用了默认的learning_rate值0.01。如果您指定一个小的learning_rate,如0.005,则训练将花费更长时间,但整体精度可能会增加。learning_rate的较高值(如1.0)可以训练得更快,但通常会降低精度,甚至会使训练不稳定。
你需要仔细试验,看看你的情况是什么。
如果你给每个实验一个独立不一样的名字,这对于这种类型的工作非常有用,所以它们在TensorBoard中显示为单独的条目,不会相互干扰影响。
这--summaries_dir
是控制tensorboard中名称的选项。之前我们使用过:
--summaries_dir=training_summaries/basic
TensorBoard监视training_summaries
目录的内容,因此设置--summarys_dir
为training_summaries
或任何子目录都training_summaries
可以工作。
您可能需要一起设置以下两个选项,以便您的结果清晰地标定:
--learning_rate=0.5
--summaries_dir=training_summaries/LR_0.5
7。可选步骤:根据您自己的数据集进行训练
看到脚本处理花图像后,您可以开始使用不同数据集训练网络,以识别不同的类别。
从理论上讲,你需要做的就是运行该工具,指定一组特定的子文件夹。每个子文件夹都按照您的某个类别命名,并仅包含该类别的图像。
如果您完成此步骤并传递子目录的根文件夹作为参数的--image_dir
参数,那么脚本应该训练您提供的图像,就像它为花一样。
分类脚本使用文件夹名称作为标签名称,每个文件夹内的图像应该是与该标签相对应的图片,如花卉档案中所示:
尽可能收集每个标签的尽可能多的图片,并尝试一下!
Yufeng Guo使用这些技术来制作他的糖果分拣机演示。他使用的一个快捷方式是使用ffmpeg将训练图像从每个类别的对象视频中分离出来。
8。下一步
恭喜,您迈出了深入学习的更大的世界!
您可以在TensorFlow网站或TensorFlow Github项目中看到更多关于使用TensorFlow的信息。TensorFlow还有许多其他资源,包括讨论组和白皮书。
如果你制作了一个你想在生产环境中运行的训练模型,你还应该看看TensorFlow Serving,一个开源项目,它可以更容易地管理TensorFlow项目。
如果您有兴趣在移动设备上运行TensorFlow,请尝试本教程的第二部分,该教程将向您展示如何优化您的模型以在Android上运行。
或者去TensorFlow Playground玩一下吧!
这个codelab是基于Pete Warden的诗人TensorFlow博客文章和这个再培训教程。
翻译: csdn -固本培元