如何仅使用TensorFlow C+来训练深度神经网络

作者|Florian Courtial

译者|Debra

编辑|Emily

AI 前线导读:训练神经网络是一件十分复杂,难度非常大的工作,有没有可能让训练的过程简单便利一些呢?有人突发奇想,尝试仅仅使用 TensorFlow C ++ 来进行这项工作。这样做的效果如何呢?我们来看看 Florian Courtial 用 TensorFlow C ++ 构建 DNN 框架的示例来了解一下吧。

更多干货内容请关注微信公众号“AI 前线”,(ID:ai-front)

正如你所知,TensorFlow(TF)的核心由 C ++ 构建,但是如今还是 Python API 使用起来比较便利一些。

我写这篇博文的目标,是仅使用 TF C ++ API 来构建基础的深度神经网络(DNN),然后再尝试仅使用 CuDNN 实现这一功能。但从使用 TF C ++ 构建神经网络开始,我就意识到即使是在简单的 DNN 中,也有很多东西会丢失。

请记住这一点,进行外部操作训练网络肯定是不可行的,因为你很可能将丢失梯度运算。我目前正在尝试将梯度运算从 Python 改为 C ++。

在这篇文章中,我们将示例如何建立一个深度神经网络,并通过车龄、里程和燃料类型来预测一辆宝马 Serie 1 的价格。我们将仅使用 TensorFlow C ++,并描述缺失的训练细节。目前 C ++ 中没有优化器,所以现在训练的代码没有那么性感,但是将来我可能会添加。

所有代码可以在 Github 上找到。

重建 TensorFlow

我们将用 TensorFlow C ++ 代码进行编码,虽然可以使用现成编译的库,但是我相信有些人在这个过程中会由于库环境的特殊性而遇到麻烦。从头开始构建 TensorFlow 会避免这些问题,而且需要确保使用的是最新版本的 API。

接下来只需要安装 bazel构建工具就可以了,然后遵照你的操作系统指示进行操作。在 OSX上,使用 brew就足够了:(左右滑动可看到全部代码)

因为是从头构建 TF,我们还需要张量源:

然后进行配置安装,你可以选择 GPU,也可以不选择,要做到这一点需要运行配置脚本:

现在我们来创建将接收模型代码的文件,并开始首次构建 TF。请注意,第一次构建需要相当长的时间(10 - 15分钟)。

非核心的 C ++ TF代码在 / tensorflow / cc中,这是我们创建模型文件的位置,另外还需要一个 BUILD文件,以便 bazel可以建立 model.cc。

我们把 bazel指示添加到 BUILD文件中:

一般它会使用 model.cc建立一个二元模型。现在,我们已经做好为模型编写代码的所有准备。

读取数据

如果你还记得的话,这些数据是法国网站 leboncoin.fr报废的,而不是经过清理和规范化,并保存到 CSV文件中的数据。我们的目标是读取这些数据。用来规范化数据的元数据被保存在 CSV文件的第一行,我需要它们重新构建网络输出的价格。我创建了一个 data_set.h和 data_set.cc文件,防止代码被打乱。它们将从 CSV文件中生成一个二维数组,用来训练神经网络。

我把代码放在这里,但因为它与我们的目标没有多大相关性,所以无需在阅读代码上多花时间。

data_set.h

我们还需要将这两个文件添加到 BUILD 文件中。

建模

第一步是将 CSV 文件读取为两个张量,x 为输入,y 为预期结果。我们使用之前定义的 DataSet 类。您可以在这里下载 CSV 数据集。

我们需要类型和形状来定义一个张量。在 data_set 对象中,x 以扁平的方式保存,这就是为什么我们将尺寸缩减至 3(每辆车有 3个特征)。然后我们使用 std :: copy_n 将数据从 data_set 对象复制到 Tensor(Eigen :: TensorMap)的底层数据结构中。现在可以开始建模了。

使用以下方法,我们可以轻松地调试张量:

C ++ API 的独特之处在于,我们需要一个 Scope 对象来保存图构造的状态,这个对象将在运算中传递。

我们将得到两个占位符,x 包含汽车功能和每辆车的相应价格。

该网络有两个隐藏层,因此我们将得到三个权重矩阵和三个偏差矩阵。而 Python 是在 C ++ 下完成的,我们必须定义一个变量和一个 Assign 节点,以便为该变量分配一个默认值。通过使用 RandomNormal 来初始化变量,我们获得正态分布的随机值。

然后使用 Tanh 作为激活函数建立三个层。

添加一个 L2 正则化。

最后,我们计算一下损失,即预测和实际价格 y 之间的差异,再加上正则化。

至此,我们完成了正向传播,并准备好启动反向传播部分。第一步是使用一个函数调用,将正向操作的梯度添加到图形中。

我们将所有计算每个变量损失的梯度所需的运算都添加到图中,初始化一个空的 grad_outputs 向量,当在 TensorFlow session 中使用时,它将保存为生成变量梯度的节点,grad_outputs [0] 将生成梯度损失 wrt w1,grad_outputs [1]grad 损失 wrt w2,按照 的顺序,传递给 AddSymbolicGradients 。

现在,我们得到一个 grad_outputs 节点列表。在 TensorFlow session 中使用时,每个节点计算一个变量的损失梯度,之后被用来更新变量。每个变量设置为一行,使用最简单的梯度下降来进行更新。

我们的网络已做好在 Session 中启动的准备,Python 优化器 API 的最小化功能基本上包含了在函数调用中的计算和应用梯度。

我们对一个 ClientSession 和一个命名为 output 的 Tensor 进行初始化,使之接收网络的输出。

然后初始化变量,在 Python 中,调用 tf.global_variables_initializer()就足够了,因为在构建图的过程中,我们保留了所有变量的列表。使用 C ++,我们必须保留变量列表。每个 RandomNormal 输出将被分配给 Assign 节点中定义的变量。

现在,我们可以循环训练步骤。在示例中,我们将做 5000 步训练。第一步是使用损失节点进行正向传播,输出为网络损失。每隔 100 步,我们记录下损失值,网络的强制性属性会导致损失值减小。之后计算梯度节点并更新变量。如果你还记得,我们的梯度节点已被用作 ApplyGradientDescent 节点的输入,所以为了运行 apply_ 节点,我们需要首先计算梯度,然后将其应用于正确的变量。

到这一步,该网络经过训练,已经可以尝试预测一辆车的价格,也就是所谓的推理。我们来预测一下一台柴油发动机,车龄为 7 年,里程 11 万公里的宝马 Seria 1 的价格。要做到这一点,我们需要使用 layer_3 节点,以汽车数据作为输入 x(基本上是一个正向传播)。因为我们此前曾经对网络进行过 5000步 的训练,所以权重会有一个学习值,产生的结果是非随机的。

我们不能直接使用汽车的属性,因为我们的网络从规范化的属性中学习,同样还必须经过相同的规范化过程。鉴于此,DataSet 使用 CSV 读取期间加载的数据集元数据来处理该步骤。

该网络生成一个介于 0和 1 之间的值,data_set 输出还负责使用数据集元数据,将该值转换回可读的价格。这个模型可以使用命令 bazel run -c opt // tensorflow / cc / models:model 运行,如果 TensorFlow 是重建的,很快就可以得到以下输出:

该模型预测的汽车价格为 13377.7 欧元。多次运行模型可能会得到不同的结果,有时差距非常大,如 8000€ 与 17000€。这是由于我们只用了三个属性来描述汽车,而且网络架构也非常简单。

正如我之前所说,C ++ API 还在不断改进,我们在将来可以找到更简单的方法。如果你知道能改善此方案的解决方法,欢迎留下评论。

https://matrices.io/training-a-deep-neural-network-using-only-tensorflow-c/

本文来自企鹅号 - AI漫游媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏深度学习入门与实践

【深度学习系列】PaddlePaddle可视化之VisualDL

  上篇文章我们讲了如何对模型进行可视化,用的keras手动绘图输出CNN训练的中途结果,本篇文章将讲述如何用PaddlePaddle新开源的VisualDL来...

4089
来自专栏AI黑科技工具箱

1.试水:可定制的数据预处理与如此简单的数据增强(下)

上一部分我们讲了MXNet中NDArray模块实际上有很多可以继续玩的地方,不限于卷积,包括循环神经网络RNN、线性上采样、池化操作等,都可以直接用NDArra...

4403
来自专栏FreeBuf

用机器学习玩转恶意URL检测

前段时间漏洞之王Struts2日常新爆了一批漏洞,安全厂商们忙着配合甲方公司做资产扫描,漏洞排查,规则大牛迅速的给出”专杀”规则强化自家产品的规则库。这种基于规...

8469
来自专栏贾志刚-OpenCV学堂

使用Tensorflow Object Detection API实现对象检测

Tensorflow Object Detection API自从发布以来,其提供预训练模型也是不断更新发布,功能越来越强大,对常见的物体几乎都可以做到实时准确...

1403
来自专栏素质云笔记

图像增强︱window7+opencv3.2+keras/theano简单应用(函数解读)

在服务器上安装opencv遇到跟CUDA8.0不适配的问题,于是不得不看看其他机器是否可以预装并使用。 . 一、python+opencv3.2安装 ope...

40610
来自专栏机器之心

资源 | 微软发布可变形卷积网络代码:可用于多种复杂视觉任务

选自Github 机器之心编译 编辑:吴攀 上个月,微软代季峰等研究者发布的一篇论文提出了一种可变形卷积网络,该研究「引入了两种新的模块来提高卷积神经网络(CN...

3506
来自专栏玉树芝兰

如何用 Python 和循环神经网络(RNN)做中文文本分类?

本文为你展示,如何使用 fasttext 词嵌入预训练模型和循环神经网络(RNN), 在 Keras 深度学习框架上对中文评论信息进行情感分类。

1544
来自专栏ATYUN订阅号

使用Python完成你的第一个学习项目

你是否想使用python进行机器学习但却难以入门? 在这篇教程中,你将用Python完成你的第一个机器学习项目。 在以下的教程中,你将学到: 下载并安装P...

72511
来自专栏专知

【资源】Python实现多种模型(Naive Bayes, SVM, CNN, LSTM, etc)用于推文情感分析

【导读】近日,Abdul Fatir 在自己的CS5228课程报告使用不同的方法进行Tweets情感分析(作为二分类问题),并对这些方法的性能进行比较,主要是基...

45310
来自专栏Python中文社区

基于RNN自动生成古诗

專 欄 ❈ 作者:yonggege,Python中文社区专栏作者 GitHub地址:https://github.com/wzyonggege ❈ 0. ch...

2635

扫码关注云+社区