卷积神经网络
注意:本教程面向TensorFlow的高级用户,并承担机器学习方面的专业知识和经验。
CIFAR-10分类是机器学习中常见的基准问题。问题是将RGB 32x32像素图像分为10类:
airplane, automobile, bird, cat, deer, dog, frog, horse, ship,and truck.
有关更多详细信息,请参阅CIFAR-10页面和Alex Krizhevsky的技术报告。
本教程的目标是构建用于识别图像的相对较小的卷积神经网络(CNN)。在此过程中,本教程:
选择CIFAR-10的原因是它足够复杂,可以大量运用TensorFlow扩展到大型车型的能力。同时,该模型足够小,可以快速训练,这对于尝试新想法和尝试新技术是非常理想的。
CIFAR-10教程演示了在TensorFlow中设计更大和更复杂的模型的几个重要结构:
我们还提供了一个多GPU版本的模型,演示如下:
我们希望本教程为TensorFlow上的视觉任务构建更大的CNN提供了启动点。
CIFAR-10教程中的模型是由交替卷积和非线性组成的多层架构。这些层之后是通向softmax分类器的完全连接的层。该模型遵循Alex Krizhevsky描述的架构,在几个层面上有一些差异。
该模型在GPU上的训练时间的几个小时内实现了大约86%的精度峰值性能。请参阅下面的代码和详细信息。它由1,068,298个可学习的参数组成,并且需要大约19.5M的乘法运算来计算单个图像上的推断。
本教程的代码位于tensorflow_models/tutorials/image/cifar10/
。
文件 | 目的 |
---|---|
cifar10_input.py | 读取本机CIFAR-10二进制文件格式。 |
cifar10.py | 构建CIFAR-10模型。 |
cifar10_train.py | 在CPU或GPU上训练CIFAR-10模型。 |
cifar10_multi_gpu_train.py | 在多个GPU上训练一个CIFAR-10模型。 |
cifar10_eval.py | 评估CIFAR-10模型的预测性能。 |
所述CIFAR-10网络主要是包含在cifar10.py
。完整的训练图包含大约765个操作。我们发现我们可以通过使用以下模块构建图来使代码最为可重用:
inputs()
并distorted_inputs()
添加分别读取和预处理CIFAR图像进行评估和训练的操作。inference()
添加对提供的图像执行推理即分类的操作。loss()
并train()
添加计算损失,梯度,变量更新和可视化摘要的操作。 模型的输入部分由功能构建,inputs()
并distorted_inputs()
从CIFAR-10二进制数据文件读取图像。这些文件包含固定的字节长度记录,所以我们使用tf.FixedLengthRecordReader
。请参阅阅读数据以了解有关Reader
课程的工作原理。
图像的处理如下:
对于训练,我们还应用一系列随机变形来人为增加数据集大小:
请参阅图像页面了解可用失真的列表。我们也附加tf.summary.image
到图像,以便我们可以在TensorBoard中可视化它们。这是验证输入正确构建的良好做法。
从磁盘读取图像并使其扭曲可以使用非常小的处理时间。为了防止这些操作减慢训练,我们在16个独立的线程中运行它们,它们不断地填充TensorFlow队列。
模型的预测部分由inference()
添加操作来计算预测逻辑的函数构成。该模型的一部分组织如下:
图层名称 | 描述 |
---|---|
conv1 | 卷积和纠正线性激活。 |
pool1 | 最大池。 |
norm1 | 本地响应规范化。 |
conv2 | 卷积和纠正线性激活。 |
norm2 | 本地响应规范化。 |
pool2 | 最大池。 |
local3 | 完全连接层与整流线性激活。 |
local4 | 完全连接层与整流线性激活。 |
softmax_linear | 线性变换产生逻辑。 |
这是从TensorBoard生成的描述推理操作的图:
练习:输出
inference
是非标准化逻辑。尝试编辑网络架构以返回使用的归一化预测tf.nn.softmax
。
该inputs()
和inference()
功能提供所有必要对模型进行评价的组成部分。我们现在将重点转移到建设模式的培训。
练习:模型架构
inference()
与cuda-convnet中指定的CIFAR-10模型略有不同。特别地,亚历克斯原始模型的顶层是本地连接的,并没有完全连接。尝试编辑架构以精确地再现顶层中的本地连接的体系结构。
训练网络进行N次分类的通常方法是多项Logistic回归。softmax回归。Softmax回归将softmax非线性应用于网络的输出,并计算标准化预测与标签的1-hot编码之间的交叉熵。对于正则化,我们还将所有学习变量的常规体重衰减损失应用于常规。模型的目标函数是函数返回的交叉熵损失和所有这些权重衰减项的和。 loss()
我们在TensorBoard中可以看出tf.summary.scalar
:
我们使用标准梯度下降算法(参见训练其他方法)训练模型,学习速率随时间呈指数衰减。
该train()
函数通过计算渐变和更新学习变量来增加最小化目标所需的操作(详见tf.train.GradientDescentOptimizer
详细信息)。它返回一个操作,执行训练和更新一批图像的模型所需的所有计算。
我们已经建立了模型,现在我们来启动它,并用脚本来运行训练操作cifar10_train.py
。
python cifar10_train.py |
---|
注意:首次在CIFAR-10教程中运行任何目标时,CIFAR-10数据集将自动下载。数据集是〜160MB,所以你可能想要一杯咖啡,首先运行。
你应该看到输出:
Filling queue with20000CIFAR images before starting to train. This will take a few minutes. 2015-11-0411:45:45.927302: step0, loss=4.68(2.0examples/sec;64.221sec/batch) 2015-11-0411:45:49.133065: step10, loss=4.66(533.8examples/sec;0.240sec/batch) 2015-11-0411:45:51.397710: step20, loss=4.64(597.4examples/sec;0.214sec/batch) 2015-11-0411:45:54.446850: step30, loss=4.62(391.0examples/sec;0.327sec/batch) 2015-11-0411:45:57.152676: step40, loss=4.61(430.2examples/sec;0.298sec/batch) 2015-11-0411:46:00.437717: step50, loss=4.59(406.4examples/sec;0.315sec/batch) ... |
---|
该脚本每10个步骤报告总损耗以及最后一批数据的处理速度。几条评论:
练习:在进行实验时,有时令人烦恼的是,第一个训练步骤可能需要很长时间。尝试减少最初填满队列的图像数量。搜索
min_fraction_of_examples_in_queue
在cifar10_input.py
。
cifar10_train.py
定期将所有模型参数保存在检查点文件中,但不会对模型进行评估。将使用检查点文件cifar10_eval.py
来测量预测性能(请参阅下面的评估模型)。
如果您遵循上述步骤,那么您现在已经开始训练CIFAR-10型号了。恭喜!
返回的终端文本cifar10_train.py
提供了对模型如何训练的最小了解。我们希望在培训期间更多地了解模型:
TensorBoard提供此功能,显示cifar10_train.py
通过a定期导出的数据tf.summary.FileWriter
。
例如,我们可以看到local3
在训练过程中,特征的激活分布和稀疏度如何发展:
个人损失功能以及总损失,随着时间的过去特别有趣。然而,由于训练所使用的小批量,损失表现出相当大的噪音。实际上,除了它们的原始值之外,我们发现它们可视化移动平均值非常有用。了解脚本如何tf.train.ExponentialMovingAverage
用于此目的。
现在让我们来评估训练模型在保留数据集上的表现。该模型由脚本进行评估cifar10_eval.py
。它使用该inference()
功能构建模型,并使用CIFAR-10评估集中的所有10,000个图像。它计算精度为1:顶部预测与图像的真实标签匹配的频率。
为了监控模型在训练过程中如何改进,评估脚本会定期运行在最新的检查点文件上cifar10_train.py
。
python cifar10_eval.py |
---|
不要在同一个GPU上运行评估和训练二进制文件,否则可能会耗尽内存。考虑在单独的GPU上运行评估,如果可用,或在同一GPU上运行评估,则暂停训练二进制文件。
你应该看到输出:
2015-11-0608:30:44.391206: precision @1=0.860 ... |
---|
脚本只会定期返回精度@ 1 - 在这种情况下,它返回了86%的精度。cifar10_eval.py还可以在TensorBoard中显示可以显示的摘要。这些摘要在评估过程中提供了对模型的更多洞察。
训练脚本计算所有学习变量的移动平均版本。评估脚本用移动平均版本代替所有学习的模型参数。这种替代在评估时提升了模型性能。
练习:采用平均参数可以将预测性能提高约3%,按精度@ 1测量。编辑
cifar10_eval.py
不使用模型的平均参数,并验证预测性能下降。
现代工作站可能包含多个用于科学计算的GPU。TensorFlow可以利用这种环境在多个卡上同时运行训练操作。
以并行,分布式方式培训模式需要协调培训过程。对于接下来我们将模型副本命名为数据子集上的模型训练的一个副本。
通过模拟参数的异步更新,导致了次优训练性能,因为可以对模型参数的陈旧副本进行单个模型副本的训练。相反,采用完全同步的更新将与最慢的模型副本一样慢。
在具有多个GPU卡的工作站中,每个GPU将具有相似的速度并包含足够的内存来运行整个CIFAR-10模型。因此,我们选择以下列方式设计培训系统:
这是一个这个模型的图: