第三阶段-tensorflow项目之图像image相关--tensorflow搭建CNNs 之CIFAR-10多个GPU运行

本blog面向有TensorFlow经验的用户,并有机器学习方面的专业知识和经验。

1,Overview概述

CIFAR-10分类是机器学习中常见的标准基础问题。 问题是分类10个类别的RGB 32x32像素图像:

airplane, automobile, bird, cat, deer, dog, frog, horse, ship, and truck.

1.1,goals

本blog的目标是建立一个相对较小的卷积神经网络(CNN)来识别图像。 在这个过程中,本教程:

  • 突出网络架构,训练和评估的规范模板。
  • 为构建更大更复杂的模型提供了一个模板。

选择CIFAR-10的原因是它足够复杂,可以大量运用TensorFlow扩展到大型模型的能力。 同时,这个模型足够小,可以快速训练,这对于尝试新的想法和尝试新的技术是理想的。

1.2,Highlights of the Tutorial

CIFAR-10教程演示了在TensorFlow中设计更大和更复杂模型的几个重要结构:

  • 核心数学组件包括卷积(维基),纠正线性激活(维基),最大池(维基百科)和本地响应正常化(AlexNet论文第3.3章)。
  • 在培训期间网络活动的可视化,包括输入图像,激活和渐变的损失和分布。
  • 用于计算学习参数的移动平均数的例程,并在评估期间使用这些平均数来提高预测性能。
  • 实施随时间有系统地减少的学习率表。
  • 预取输入数据的队列以隔离模型和磁盘延迟以及昂贵的图像预处理。

我们还提供了一个多GPU版本的模型,它演示了:

  • 配置一个模型来并行训练多个GPU cards。
  • 在多个GPU之间共享和更新变量。

我们希望本教程为在TensorFlow上进行视觉任务构建更大的CNN提供了一个启动点。

1.3,Model Architecture

CIFAR-10教程中的模型是一个由交替卷积和非线性组成的多层体系结构。 这些层之后是完全连接的层,通向softmax分类器。 该模型遵循Alex Krizhevsky所描述的架构,在前几个层次中有一些差异。

这个模型在GPU的几个小时训练时间内达到了高达86%的精度。 请参阅下面的代码和细节。 它由1,068,298个可学习的参数组成,并且需要大约19.5M的乘加操作来计算单个图像上的inference 。

2,Code Organization

本教程的代码位于models / tutorials / image / cifar10 /中。

第三阶段-tensorflow项目之图像image相关--tensorflow搭建CNNs 之CIFAR-10多个GPU运行_第1张图片

3,CIFAR-10 Model

CIFAR-10网络主要包含在cifar10.py中。 完整的训练图包含大约765个操作。 我们发现,通过构建带有以下模块的图,我们可以使代码最为可重用:

  1. Model inputs:输入()和distorted_inputs()添加操作,分别读取和预处理CIFAR图像以进行评估和训练。
  2. Model prediction:推理()增加了对提供的图像进行处理(即分类)的操作。
  3. Model training:loss()和train()添加计算损失,梯度,变量更新和可视化摘要的操作。

3.1,Model Inputs

模型的输入部分由从CIFAR-10 二进制数据文件读取图像的函数inputs() 和distorted_inputs() 构建。 这些文件包含固定的字节长度记录,所以我们使用tf.FixedLengthRecordReader。 请参阅读取数据以了解有关Reader类如何工作的更多信息。

图像处理如下:

  • 它们裁剪为24 x 24像素,集中进行评估或随机进行训练。
  • 它们近似变白以使模型对动态范围不敏感。

对于训练,我们另外应用一系列随机失真来人为地增加数据集大小:

  • 随机从左到右翻转图像。
  • 随机扭曲图像的亮度。
  • 随机扭曲的图像对比度。

请参阅图像页面以获取可用失真的列表。 我们还附加一个tf.summary.image的图像,以便我们可以在TensorBoard中可视化他们。 这是验证输入是否正确构建的良好实践。

从磁盘读取图像并使其变形可以使用不重要的处理时间。 为了防止这些操作放慢训练速度,我们在连续填充TensorFlow队列的16个独立线程中运行它们。
3.2,Model Prediction

模型的预测部分由inference() 函数构造,该函数添加了用于计算预测的逻辑的操作。 模型的这部分组织如下:

第三阶段-tensorflow项目之图像image相关--tensorflow搭建CNNs 之CIFAR-10多个GPU运行_第2张图片

这是一个由TensorBoard生成的图形,描述了推理操作:
第三阶段-tensorflow项目之图像image相关--tensorflow搭建CNNs 之CIFAR-10多个GPU运行_第3张图片

  • 练习:相关的输出是非标准化的logits。 尝试使用tf.nn.softmax编辑网络体系结构以返回标准化预测。

inputs()和inference()函数提供了执行模型评估所需的所有组件。 我们现在把重点转移到训练模型的操作上。

  • 练习:inference()中的模型体系结构与cuda-convnet中指定的CIFAR-10模型略有不同。
    特别是Alex的原始模型的顶层是局部连接的而且没有完全连接。 尝试编辑体系结构以精确复制顶层中本地连接的体系结构。

3.3,Model Training

训练网络执行N路分类的通常方法是多项式逻辑回归,也就是说。 softmax回归。 Softmax回归将softmax非线性应用于网络的输出,并计算归一化预测与1-hot编码之间的交叉熵。 对于正则化,我们也将通常的权重衰减损失应用于所有学习的变量。 该模型的目标函数是交叉熵损失和所有这些权重衰减项之和,由loss()函数返回。

我们用tf.summary.scalar在TensorBoard中将其可视化:
第三阶段-tensorflow项目之图像image相关--tensorflow搭建CNNs 之CIFAR-10多个GPU运行_第4张图片

我们使用标准梯度下降算法(见其他方法的训练)训练模型,其学习速率随着时间呈指数衰减。

第三阶段-tensorflow项目之图像image相关--tensorflow搭建CNNs 之CIFAR-10多个GPU运行_第5张图片

train()函数通过计算梯度和更新已学习的变量(请参阅tf.train.GradientDescentOptimizer获取详细信息),添加通过最小化目标所需的操作。 它返回一个执行所有计算的操作,以训练和更新一批图像的模型。

4,Launching and Training the Model

我们已经建立了模型,现在启动它,并使用脚本cifar10_train.py运行训练操作。

python cifar10_train.py
Filling queue with 20000 CIFAR images before starting to train. This will take a few minutes.
2015-11-04 11:45:45.927302: step 0, loss = 4.68 (2.0 examples/sec; 64.221 sec/batch)
2015-11-04 11:45:49.133065: step 10, loss = 4.66 (533.8 examples/sec; 0.240 sec/batch)
2015-11-04 11:45:51.397710: step 20, loss = 4.64 (597.4 examples/sec; 0.214 sec/batch)
2015-11-04 11:45:54.446850: step 30, loss = 4.62 (391.0 examples/sec; 0.327 sec/batch)
2015-11-04 11:45:57.152676: step 40, loss = 4.61 (430.2 examples/sec; 0.298 sec/batch)
2015-11-04 11:46:00.437717: step 50, loss = 4.59 (406.4 examples/sec; 0.315 sec/batch)
...

The script reports the total loss every 10 steps as well as the speed at which the last batch of data was processed. A few comments:

  • 第一批数据可能非常慢(例如几分钟),因为预处理线程用20,000个处理的CIFAR图像填充混洗队列。
  • 报告的损失是最近一批的平均损失。 请记住,这个损失是交叉熵和所有重量衰减项之和。
  • 密切关注批次的处理速度。 上面显示的数字是在Tesla K40c上获得的。 如果您在CPU上运行,则预计性能会降低。

5,Evaluating a Model

现在让我们来评估训练好的模型在保持数据集上的表现如何。该模型由脚本cifar10_eval.py进行评估。它使用inference()函数构建模型,并在CIFAR-10的评估集中使用所有10,000个图像。它计算精度为1:顶部预测与图像的真实标签匹配的频率。

要在训练期间监控模型的改进情况,评估脚本定期在由cifar10_train.py创建的最新检查点文件上运行。

python cifar10_eval.py
  • 小心不要在同一个GPU上运行评估和训练二进制文件,否则可能会导致内存不足。考虑在单独的GPU上运行评估(如果可用)或在同一GPU上运行评估时挂起训练二进制文件。

你应该看到输出:

2015-11-06 083044.391206:精度@ 1 = 0.860
...

该脚本只是定期返回精度@ 1,在这种情况下它返回86%的精度。 cifar10_eval.py也导出可能在TensorBoard中可视化的摘要。这些总结在评估过程中为模型提供了更多的信息。

训练脚本计算所有学习变量的移动平均版本。评估脚本将所有学习的模型参数替换为移动平均版本。这种替代提高了评估时的模型性能。

  • 练习:使用平均参数可以提高约3%的预测性能,如精度@
    1所示。编辑cifar10_eval.py以不使用模型的平均参数,并验证预测性能下降。

6,Training a Model Using Multiple GPU Cards

现代工作站可能包含多个GPU进行科学计算。 TensorFlow可以利用这个环境在多个卡上同时运行培训操作。

以平行分布的方式培训模型需要协调培训流程。对于下面的内容,我们称模型副本为数据子集的模型训练副本。

天真地使用模型参数的异步更新导致次优的训练性能,因为单个模型副本可能在模型参数的陈旧副本上被训练。相反,使用完全同步的更新将会像最慢的模型副本一样慢。

在具有多个GPU卡的工作站中,每个GPU将具有相似的速度并且包含足够的内存来运行整个CIFAR-10模型。因此,我们选择以如下方式设计我们的培训系统:

  • 在每个GPU上放置一个模型副本。
  • 等待所有GPU完成一批数据的处理,同步更新模型参数。

这是这个模型的图表:

第三阶段-tensorflow项目之图像image相关--tensorflow搭建CNNs 之CIFAR-10多个GPU运行_第6张图片

  • 请注意,每个GPU都会计算推断以及独特批次数据的渐变。 这种设置有效地允许在GPU上划分大量的数据。

此设置要求所有GPU共享模型参数。 一个众所周知的事实是,将数据传输到GPU和从GPU传输数据相当缓慢。 出于这个原因,我们决定存储和更新CPU上的所有模型参数(参见绿色框)。 当新的一批数据被所有GPU处理时,一组新的模型参数被传送到GPU。

GPU在运行中同步。 所有渐变都从GPU中累积并取平均值(见绿色框)。 模型参数使用所有模型复本平均的梯度进行更新。

6.1,Placing Variables and Operations on Devices

在设备上放置操作和变量需要一些特殊的抽象。

我们需要的第一个抽象是用于计算单个模型副本的推理和梯度的函数。 在代码中,我们将这个抽象称为“塔”。 我们必须为每个塔设置两个属性:

  • 塔内所有操作的唯一名称。 tf.name_scope通过预先定义一个范围来提供这个唯一的名字。
    例如,第一塔中的所有操作都以塔_0作为前缀。tower_0/ CONV 1/ Conv2D。
  • 在塔内运行操作的首选硬件设备。 tf.device指定了这个。 例如,第一个塔中的所有操作都驻留在设备(’/device:GPU:0’)范围内,指示它们应该在第一个GPU上运行。

所有变量都固定在CPU上,并通过tf.get_variable访问,以便在多GPU版本中共享。 查看如何共享变量。

6.2,Launching and Training the Model on Multiple GPU cards

如果您的计算机上安装了多个GPU卡,则可以使用它们更快地使用cifar10_multi_gpu_train.py脚本来训练模型。 这个版本的训练脚本在多个GPU卡上并行化模型。

python cifar10_multi_gpu_train.py --num_gpus = 2

请注意,所使用的GPU卡的数量默认为1.此外,如果您的机器上只有1个GPU可用,则即使您要求更多,所有计算也将被放置在其上。

  • 练习:cifar10_train.py的默认设置是以128的批处理大小运行。尝试在2个GPU上运行批处理大小为64的cifar10_multi_gpu_train.py并比较训练速度。

完。

你可能感兴趣的:(tensorflow1.4,tensorflow,cifar-10,cnn神经网络,模板)