NVIDIA DIGITS

TensorFlow 入门 DIGITS

摘要

TensorFlow 入门 DIGITS 指南概述了如何将 DIGITS 与 TensorFlow 结合使用。


DIGITS(深度学习 GPU 训练系统)是一个用于训练深度学习模型的 Web 应用程序。TensorFlow 是当前支持的框架。DIGITS 将深度学习的力量掌握在工程师和数据科学家手中。

DIGITS 不是一个框架。DIGITS 是 TensorFlow 的一个封装器;它为这些框架提供了一个图形化的 Web 界面,而无需直接在命令行上处理它们。

DIGITS 可用于快速训练高度精确的深度神经网络 (DNN),用于图像分类、分割、对象检测任务等。DIGITS 简化了常见的深度学习任务,例如管理数据、在多 GPU 系统上设计和训练神经网络、通过高级可视化实时监控性能,以及从结果浏览器中选择性能最佳的模型进行部署。DIGITS 是完全交互式的,因此数据科学家可以专注于设计和训练网络,而不是编程和调试。DIGITS 可通过多种渠道获得,例如:

  • GitHub 下载
  • NVIDIA 的 Docker 存储库,nvcr.io

DIGITS 还包括 NVIDIA Caffe 和 TensorFlow 深度学习框架。

1.1. DIGITS 应用程序的内容

在 NVIDIA® GPU Cloud™ (NGC) 注册表和 NVIDIA® DGX™ 容器注册表 nvcr.io 中提供的容器镜像已预先构建并安装到 /usr/local/python/ 目录中。

DIGITS 还包括 TensorFlow 深度学习框架。

如果 DIGITS 检测到系统中安装了 TensorFlow-gpu,它将自动启用对 TensorFlow 的支持。这是通过一行 python 代码完成的,该代码尝试导入 tensorflow 以查看它是否实际导入。

如果 DIGITS 无法启用 TensorFlow,则会在控制台中打印一条消息,内容为:TensorFlow 支持已禁用。

关于此任务

单击“模型创建”页面上的 TensorFlow 选项卡:

standard_network_tab.png

注意

注意

默认情况下,Torch7 根据 LeCun, Yann A. 等人在“高效反向传播”中介绍的方法初始化线性和卷积层的权重。神经网络:行业技巧。施普林格出版社,柏林,海德堡,2012 年。9-48.. 虽然这种权重初始化方案在许多不同的情况下表现相当好,但这很少是最佳的,您可能会注意到,当使用例如 Xavier 初始化时,Caffe 有时能够更快地学习。有关更多信息,请参阅 这些示例

3.1. 在 DIGITS 中定义 TensorFlow 模型

要在 DIGITS 中定义 TensorFlow 模型,您需要编写一个 python 类,该类遵循以下基本模板

复制
已复制!
            

class UserModel(Tower): @model_propertyOther TensorFlow Tools in DIGITS def inference(self): # Your code here return model @model_property#with tf.variable_scope(digits.GraphKeys.MODEL, reuse=None): def loss(self): # Your code here return loss

例如,对于 LeNet-5(Yann Lecun 为手写数字分类创建的模型),它看起来像这样

复制
已复制!
            

class UserModel(Tower): @model_property def inference(self): x = tf.reshape(self.x, shape=[-1, self.input_shape[0], self.input_shape[1], self.input_shape[2]]) # scale (divide by MNIST std) x = x * 0.0125 with slim.arg_scope([slim.conv2d, slim.fully_connected], weights_initializer=tf.contrib.layers.xavier_initializer(), weights_regularizer=slim.l2_regularizer(0.0005) ): model = slim.conv2d(x, 20, [5, 5], padding='VALID', scope='conv1') model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='pool1') model = slim.conv2d(model, 50, [5, 5], padding='VALID', scope='conv2') model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='pool2') model = slim.flatten(model) model = slim.fully_connected(model, 500, scope='fc1') model = slim.dropout(model, 0.5, is_training=self.is_training, scope='do1') model = slim.fully_connected(model, self.nclasses, activation_fn=None, scope='fc2') return model @model_property def loss(self): loss = digits.classification_loss(self.inference, self.y) accuracy = digits.classification_accuracy(self.inference, self.y) self.summaries.append(tf.summary.scalar(accuracy.op.name, accuracy)) return loss

必须定义属性 inference 和 loss,并且该类必须命名为 UserModel,并且必须继承 Tower。这就是 DIGITS 与 python 代码交互的方式。

3.1.1. 提供的属性

可通过 self 访问的属性

属性名称 类型 描述
nclasses 数字 类别的数量(对于分类数据集)。对于其他类型的数据集,这是未定义的。
input_shape 张量 第一个输入张量的形状(1D 张量)。对于图像数据,这设置为高度、宽度和通道,分别可通过 [0]、[1] 和 [2] 访问。
is_training 布尔值 这是否是训练图。
is_inference 布尔值 这是否是为推理/测试创建的图。
x 张量 输入节点,形状为 [N, H, W, C]。
y 张量 标签,标量标签为 [N],否则为 [N, H, W, C]。仅当 self.is_training 为 True 时才定义。
fineTuneHook 函数 一个函数 (net),返回用于微调的模型。未调整的模型作为函数参数传递。
disableAutoDataParallelism 布尔值 默认情况下,模型封装在 nn.DataParallelTable 容器中,以便在选择多个 GPU 时启用多 GPU 训练。将此标志设置为 true 将禁用此机制。

3.1.2. 内部属性

这些属性位于用户编写的 UserModel 类中

属性名称 类型 描述
__init()__ UserModel 类的构造函数。
inference() 张量 在训练和推理期间调用。
loss() 张量 在训练期间调用以确定损失和要训练的变量。

3.1.3. 张量

网络以 NxCxHxW 格式(批次索引 x 通道 x 高度 x 宽度)接收 TensorFlow 张量对象作为输入。如果 GPU 可用,则张量作为 Cuda 张量提供,模型和准则通过调用其 cuda() 方法移动到 GPU。在没有 GPU 的情况下,张量作为 Float 张量提供。

3.2. DIGITS 中的其他 TensorFlow 工具

DIGITS 提供了一些有用的工具来帮助您使用 TensorFlow 进行开发。

3.2.1. 提供的有用函数

DIGITS 提供了一些有用的函数来帮助您创建模型。以下是我们 digits 类中提供的函数

函数名称 参数 描述
classification_loss pred - 要分类的图像 y - 标签 用于分类训练以计算图像分类的损失。
mse_loss lhs - 左手张量 rhs - 右手张量 用于计算 2 个张量之间的均方误差。
constrastive_loss lhs - 左手张量 rhs - 右手张量 y - 标签 根据 Caffe 定义计算对比损失。
classification_accuracy pred - 要分类的图像 y - 标签 用于衡量分类任务的准确性。
nhwc_to_nchw x - 要转置的张量 将最初为 NHWC 格式的张量转置为 NCHW。张量必须为 4 度。
nchw_to_nhwc x - 要转置的张量 将最初为 NCHW 格式的张量转置为 NHWC。张量必须为 4 度。
hwc_to_chw x - 要转置的张量 将最初为 HWC 格式的张量转置为 CHW。张量必须为 3 度。
chw_to_hwc x - 要转置的张量 将最初为 CHW 格式的张量转置为 HWC。张量必须为 3 度。
bgr_to_rgb x - 要转换的张量 将最初为 BGR 通道的张量转换为 RGB。
rgb_to_bgr x - 要转换的张量 将最初为 RGB 通道的张量转换为 BGR。

3.2.2. 使用 TensorBoard 进行可视化

TensorBoard 是 TensorFlow 提供的一种可视化工具,用于查看神经网络的图形。DIGITS 提供了在创建网络时轻松访问 TensorBoard 网络可视化的功能。可以通过单击“自定义网络”下的“可视化”按钮来访问此功能,如下图所示。

custom_network_tab.png

如果网络模型出现问题,DIGITS 将自动为您提供堆栈跟踪和错误消息,以帮助您定位问题。您还可以在模型训练时使用以下命令启动完整的 TensorBoard 服务器

复制
已复制!
            

$ tensorboard --logdir <job_dir>/tb/

其中 <job_dir> 是模型正在训练的目录,可以在此处找到:

image_classification_model.png

之后,转到 https://127.0.0.1:6006 打开 TensorBoard 页面,或单击“可视化”下的 TensorBoard

generic_image_model.png

有关使用 TensorBoard 的更多信息,请参阅:https://tensorflowcn.cn/guide/summaries_and_tensorboard

3.3. 示例

3.3.1. 简单自动编码器网络

以下网络是一个简单的自动编码器,用于演示如何在 DIGITS 中使用 TensorFlow 的结构。自动编码器是一个由两部分组成的网络,基本上充当压缩机制。第一部分将尝试将图像压缩到小于原始大小,而第二部分将尝试解压缩由压缩网络创建的压缩表示。

复制
已复制!
            

class UserModel(Tower): @model_property def inference(self): # the order for input shape is [0] -> H, [1] -> W, [2] -> C # this is because tensorflow's default order is NHWC model = tf.reshape(self.x, shape=[-1, self.input_shape[0], self.input_shape[1], self.input_shape[2]]) image_dim = self.input_shape[0] * self.input_shape[1] with slim.arg_scope([slim.fully_connected], weights_initializer=tf.contrib.layers.xavier_initializer(), weights_regularizer=slim.l2_regularizer(0.0005)): # first we reshape the images to something model = tf.reshape(_x, shape=[-1, image_dim]) # encode the image model = slim.fully_connected(model, 300, scope='fc1') model = slim.fully_connected(model, 50, scope='fc2') # decode the image model = slim.fully_connected(model, 300, scope='fc3') model = slim.fully_connected(model, image_dim, activation_fn=None, scope='fc4') # form it back to the original model = tf.reshape(model, shape=[-1, self.input_shape[0], self.input_shape[1], self.input_shape[2]]) return model @model_property def loss(self): # In an autoencoder, we compare the encoded and then decoded image with the original original = tf.reshape(self.x, shape=[-1, self.input_shape[0], self.input_shape[1], self.input_shape[2]]) # self.inference is called to get the processed image model = self.inference loss = digits.mse_loss(original, model) return loss

3.3.2. 通过重命名冻结预训练模型中的变量

以下是如何指定您要用于训练的权重的演示。如果您使用预训练模型,这将效果最佳。这适用于微调模型。

当您首次训练模型时,TensorFlow 将使用指定的名称保存变量。当您重新加载模型以重新训练它时,tensorflow 将同时重新加载所有这些变量,并在模型定义中指定它们时将它们标记为可重新训练。当您更改模型中变量的名称时,TensorFlow 将知道不要训练该变量,从而“冻结”它。

复制
已复制!
            

class UserModel(Tower): @model_property def inference(self): model = construct_model() """code to construct the network omitted""" # assuming the original model have weight2 and bias2 variables # in here, we renamed them by adding the suffix _not_in_use # this tells TensorFlow that these variables in the pre-trained model should # not be retrained and it should be frozen # If we would like to freeze a weight, all we have to do is just rename it self.weights = { 'weight1': tf.get_variable('weight1', [5, 5, self.input_shape[2], 20], initializer=tf.contrib.layers.xavier_initializer()), 'weight2': tf.get_variable('weight2_not_in_use', [5, 5, 20, 50], initializer=tf.contrib.layers.xavier_initializer()) } self.biases = { 'bias1': tf.get_variable('bias1', [20], initializer=tf.constant_initializer(0.0)), 'bias2': tf.get_variable('bias2_not_in_use', [50], initializer=tf.constant_initializer(0.0)) } return model @model_property def loss(self): loss = calculate_loss() """code to calculate loss omitted""" return loss


有关故障排除提示,请参阅 Nvidia DIGITS 故障排除和支持指南。

4.1. 支持

有关最新的发行说明,请参阅 DIGITS 发行说明文档网站。有关 DIGITS 的更多信息,请参阅:

注意

注意:nvidia-docker 镜像和此镜像之间可能存在细微差异。

声明

本文档仅供参考,不得视为对产品的特定功能、条件或质量的保证。NVIDIA Corporation(“NVIDIA”)对本文档中包含的信息的准确性或完整性不作任何明示或暗示的陈述或保证,并且对本文档中包含的任何错误不承担任何责任。NVIDIA 对使用此类信息或因使用此类信息而可能导致的侵犯专利或第三方其他权利的后果或使用不承担任何责任。本文档不承诺开发、发布或交付任何材料(定义如下)、代码或功能。

NVIDIA 保留随时对此文档进行更正、修改、增强、改进和任何其他更改的权利,恕不另行通知。

客户应在下订单前获取最新的相关信息,并应验证此类信息是否为最新且完整。

除非 NVIDIA 和客户的授权代表签署的单独销售协议(“销售条款”)另有约定,否则 NVIDIA 产品受订单确认时提供的 NVIDIA 标准销售条款和条件的约束。NVIDIA 在此明确反对将任何客户通用条款和条件应用于购买本文档中引用的 NVIDIA 产品。本文档不直接或间接地构成任何合同义务。

NVIDIA 产品并非设计、授权或保证适用于医疗、军事、航空、航天或生命支持设备,也不适用于 NVIDIA 产品的故障或失灵可能合理预期会导致人身伤害、死亡或财产或环境损害的应用。NVIDIA 对在上述设备或应用中包含和/或使用 NVIDIA 产品不承担任何责任,因此,此类包含和/或使用由客户自行承担风险。

NVIDIA 不保证基于本文档的产品适用于任何特定用途。NVIDIA 不一定会执行每个产品的所有参数的测试。客户全权负责评估和确定本文档中包含的任何信息的适用性,确保产品适合并满足客户计划的应用,并为该应用执行必要的测试,以避免应用或产品的默认设置。客户产品设计中的缺陷可能会影响 NVIDIA 产品的质量和可靠性,并可能导致超出本文档中包含的附加或不同条件和/或要求。对于可能基于或归因于以下原因的任何默认、损坏、成本或问题,NVIDIA 不承担任何责任:(i) 以任何违反本文档的方式使用 NVIDIA 产品;或 (ii) 客户产品设计。

本文档未授予 NVIDIA 专利权、版权或 NVIDIA 其他知识产权下的任何明示或暗示的许可。NVIDIA 发布的有关第三方产品或服务的信息不构成 NVIDIA 授予使用此类产品或服务的许可,也不构成对其的保证或认可。使用此类信息可能需要获得第三方专利或第三方其他知识产权下的许可,或获得 NVIDIA 专利或 NVIDIA 其他知识产权下的许可。

仅当事先获得 NVIDIA 书面批准、未经修改地复制且完全符合所有适用的出口法律和法规,并附带所有相关的条件、限制和声明时,才允许复制本文档中的信息。

本文档以及所有 NVIDIA 设计规范、参考板、文件、图纸、诊断程序、列表和其他文档(统称为“材料”)均“按原样”提供。NVIDIA 对材料不作任何明示、暗示、法定或其他方面的保证,并明确声明不承担对非侵权性、适销性和特定用途适用性的所有暗示保证。在法律未禁止的范围内,在任何情况下,NVIDIA 均不对因使用本文档而引起的任何损害(包括但不限于任何直接、间接、特殊、附带、惩罚性或后果性损害,无论如何引起,也无论责任理论如何)承担责任,即使 NVIDIA 已被告知可能发生此类损害。尽管客户可能因任何原因而遭受任何损害,但 NVIDIA 对本文所述产品的客户的总体和累积责任应根据产品的销售条款进行限制。

商标

NVIDIA、NVIDIA 徽标以及 cuBLAS、CUDA、cuDNN、DALI、DIGITS、DGX、DGX-1、DGX-2、DGX Station、DLProf、Jetson、Kepler、Maxwell、NCCL、Nsight Compute、Nsight Systems、NvCaffe、PerfWorks、Pascal、SDK Manager、Tegra、TensorRT、Triton Inference Server、Tesla、TF-TRT 和 Volta 是 NVIDIA Corporation 在美国和其他国家/地区的商标和/或注册商标。其他公司和产品名称可能是与其关联的各自公司的商标。

版权

© 2021 NVIDIA Corporation 和附属公司。保留所有权利。

上次更新时间:2021 年 9 月 27 日。