TensorFlow上手要点都总结在这儿了,你还有理由偷懒吗?

Steven Dufresne:在90年代我开始写神经网络软件。TensorFlow开源后,一直十分渴望用它搭建一些有趣的东西。 

谷歌的人工智能系统是现在的新热点。当TensorFlow可以被安装在树莓派上,操作变得非常容易。在上面我很快就搭建了一个二进制神经网络。这篇文章中,我将把经验分享给大家,帮助其他想要尝试、深入了解神经网络的人更快上手。 

TensorFlow是什么?

引用TensorFlow官网的话,TensorFlow是一个“采用数据流图进行数值计算的开源软件库”。其中“数据流图”是什么意思?这是个很酷的东西。在正式回答之前,我们先谈谈一个简单神经网络的结构。

神经网络基础

一个简单神经网络由输入层(input units)、隐层(hidden units)、阈值(bias unit)、输出层(output units)几部分构成。输入层负责接收数据。隐层之所以这么叫是因为从用户的角度来看,它们是隐藏的。输出层输出我们获得的结果。旁边的阈值是用来控制隐含层和输出层的值是否输出(即超过阈值的神经元才能输出)。两两不同神经元之间的连接是权重,只是一些数字,需要靠训练获得。

训练神经网络,就是为了给权重找到最佳的值,这让神经网络一步步变得“智能”。在下面这个例子中,输入神经元的值被设置为二进制数字0,0,0。接下来TensorFlow会完成这之间的所有事情,而输出神经元会神奇得包含数字0,0,1。即便你漏掉了,它也知道二进制中000下面一个数是001,001接下来是010,就这样一直到111.一旦权重被设定了合适的值,它将知道如何去计数。 

在运行神经网络中有一个步骤是将每一个权重乘以其对应的输入神经元,然后将乘积结果保存在相应的隐藏神经元。

我们可以将这些神经元和权重看作成数列(array),在Python中也被称为列表(list)。从数学的角度来看,它们都是矩阵。图中我们只绘制出了其中一部分,这里将输入层矩阵和权重矩阵相乘,得到五元素隐藏层矩阵(亦称为列表或数列)。

从矩阵到张量

在TensorFlow中,这些列表(lists)被称为张量(tensors)。矩阵相乘被称为操作(operation,也翻译作计算节点或运算),即程序员常说的op,阅读TensorFlow官方文件时会经常遇到。进一步讲,神经网络就是一堆张量、以及操作张量的 op 的集合,它们共同构成了神经网络图(graph)。

以下图片取自《TensorBoard, a tool for visualizing the graph》这篇文章,用于检测训练前后的张量值变化。张量是图中的连线,上面的数字代表张量的维度(dimensions)。连接张量的节点是各种操作(op),双击后可以看到更多的细节,比如后面一张图是双击后展现的第一层(layer 1)的细节。

最下面的X,是占位符操作,向输入张量赋值。沿着左边的线向上是输入张量(input tensor)。上面节点标着MatMul操作,使输入张量(input tensor)和权重张量(weight tensor,导向MatMul操作的另一条线)矩阵相乘。 

所有这些只是为了更直观的展示出图、张量和操作是什么,让大家更好的理解为什么TensorFlow被称为是“采用数据流图进行数值计算的开源软件库”。但是,我们为什么要创建这些图呢? 

为什么创建图?

当前,TensorFlow 只有 Python 的稳定 API,Python 是一门解释型语言。神经网络需要大量的运算,大型神经网络包含数千甚至数百万的权重,通过解释(interpret)每一步来计算的效率极低。

因此,我们通过创建一个由张量和 op 构成的图,包括所有的数学运算甚至变量的初始值,来描述神经网络的结构。只有在创建图之后,才能加载到TensorFlow里的Session。这被称为TensorFlow的“延迟执行”(deferred execution)。 Session通过高效代码来运行计算图。不仅如此,许多运算,例如矩阵相乘,都可以在GPU上完成。此外,TensorFlow也支持多台机器或者GPU同时运行。

创建二进制计数器图

以下是创建二进制计数器神经网络(binary counter neural network)的脚本,完整的代码可以在我的GitHub 网页上找到。注意,在TensorBoard里还有其他的一些代码保存在其中。

下面我们将从这些代码开始创建张量和 op 组成的图。

首先导入 "tensorflow" 模块,创建一个 session 随后使用。同时,为了让脚本更容易理解,我们也创建了一些变量,包含了网络中的神经元个数。

然后,我们为输入和输出的神经元创建占位符(placeholders)。占位符是TensorFlow里一个操作,便于后续输入实际的数值。这里X和y_是图中的两个张量,每一个都有相关联的 placeholder 操作。

你可能会觉得奇怪,为什么我们要将占位符shape定义为二维列表[None,NUM_INPUTS]和[None,NUM_OUTPUTS],第一个维度都是”None”?从整体来看,神经网络有点像我们每次输入一个值,训练它生成一个特定输出值。但更有效率的方式是,一次提供多个输入\输出对(pair),这就是 batch 。上面shape中的第一维,是每个 batch 中有几组输入/输出对。创建一个 batch 之前我们并不知道里面有几组。实际上,后续我们将使用同一个图来进行训练、测试以及实际使用,所以 batch 的大小不会每次都相同。因此,我们将第一维的大小设置为 Python 占位符对象 ”None“。

接下来,我们创建神经网络图的第一层:将权重定义为W_fc1,阈值(或偏差)定义为b_fc1,隐层定义为h_fc1。这里”fc”意为“完全连接(fully connected)”的意思,因为权重把每一个输入神经元和每一个隐藏神经元连接起来。

tf.truncated_normal 导致了一系列操作和张量,将会把所有权重赋值为标准化的随机数字。

Variable 的操作会给出初始化的值,这里是随机数字,在后面可以多次引用。一旦训练完,也可以很方便的将神经网络保存至文件中。

你可以看到我们用 matmul 操作来执行矩阵乘法的位置。我们插入一个 add 操作来加入偏差权重(bias weights)。其中 relu 运算执行的就是“激活函数”(activation function)。矩阵乘法和加法都是线性运算。神经网络用线性运算能做的事非常少。激活方程提供了一些非线性。这里的relu激活函数,就是将所有小于0的值设置为0,其余值不变。不管你信不信,这为神经网络能够学习的东西打开了一扇全新的大门。

神经网络第二层中的权重和阈值与第一层设置的一样,只是输出层不同。我们再次进行矩阵相乘,这一回乘的是权重和隐层,随后加入偏差权重(bias weights),激活函数被留到下一组代码。

与上面的relu类似,Sigmoid是另一个激活函数,也是非线性的。这里我使用sigmoid函数,一定程度上是因为它能使最终输出值为一个0和1之间,对于二进制计数器而言是一个理想的选择。在我们的例子中,为了表示二进制111,所有的输出神经元都可以有一个很大的值。这和图像分类不同,后者会希望仅仅用一个输出单元来输出一个很大的值。举个例子,比如一张图像里有长颈鹿,我们会希望代表长颈鹿的输出单元输出相当大的值。这种情况下,用softmax函数作为激活函数反倒更适合。

仔细看下前面的代码,会发现似乎有些重复,我们插入了两次sigmoid。实际是我们创建了两次不同的、并行的输出。其中cross_entropy张量将被用来训练神经网络。而 results 张量则是后续用来执行训练过的神经网络,不管它被训练出来作何目的。这是目前我能想到的最好的方法。

最后一件事就是训练(training)。也就是基于训练数据调整所有的权重。记住,在这里我们仍然只是创建一个图。真正的“训练”发生在我们开始运行这个图的时候。

运行过程中供选择的优化器很多,这里我选取了 tf.train.RMSPropOptimizer。因为就像sigmoid一样,它比较适合所有输出值都可能较大的情况。而针对分类的情形,例如图像分类,用tf.train.GradientDescentOptimizer效果可能更好。

训练和使用二进制计数器

在完成创建图之后,就可以开始训练了。

首先,要准备一些训练数据:包括输入变量 inputvals  和目标变量 targetvals 。其中 inputvals 包含输入值,后者的每一个都有对应的 targetvals 目标值。例如,inputvals[0]即[0, 0, 0] ,对应的输出或目标值为targetvals[0] ,也就是 [0, 0, 1] 。

do_training和save_trained都可以硬编码,每次都可以进行更改,或者使用命令行参数进行设置。

首先使所有 Variable 操作对张量初始化;然后,将之前创建的图从底部到 train_step执行最多不超过 10001 遍;这是最后一个添加到图中的东西。我们将 inputvals和targetvals通过RMSPropOptimizer导入train_step操作。这就是通过调整权重,在给定输入值的情况下,让输出值不断接近目标值的步骤。只要输出值和目标值之间的误差足够小,小到某个能承受的范围,这个循环就会停止。

如果你有成百上千的输入/输出组,你可以一次训练一个子集,也就是前面提到的一批(batch)。但这里我们一共只有8组,所以每次都全放进去。

我们也可以将训练好的神经网络保存在一个文件(file)中,下次就不用再训练了。下次可以直接导入一个已经训练过的神经网络文件,文件中只包含进行过变量运算后的张量的值,而不包含整个图的结构。所以即便是执行已经训练好的图,我们仍然需要脚本来创建图形。MetaGraphs可以进行文件保存和导入图,但这里我们不这么做。

请注意,我们是从图形底部运行至结果张量(results tensor),在训练网络中不断重复的创建结果。

我们输入000,希望它返回一个接近001的值。然后将返回的值重复输入再次执行。这样总共运行9次,保证从000数到111有足够的次数,之后再次回到000。

以下就是成功训练后的输出结果。在循环中被训练了200次(steps)。在实际中,训练了10001次仍没有有效降低训练误差的情况非常罕见。一旦训练成功,训练多少次并不重要。

运行二进制计数器

下一步

前面说过,这里讲的二进制计数神经网络代码可以在我的Github主页上找到。你可以根据这些代码开始学习,或者观看TensorFlow官网上的其他入门教程。下一步,根据机器人识别物体上获取的灵感,我想通过它做一些硬件方面的研究。

====================================分割线================================

本文作者:姜泱

本文转自雷锋网禁止二次转载,原文链接

时间: 2024-09-07 14:11:38

TensorFlow上手要点都总结在这儿了,你还有理由偷懒吗?的相关文章

手把手教你由TensorFlow上手PyTorch(附代码)

当我第一次尝试学习 PyTorch 时,没几天就放弃了.和 TensorFlow 相比,我很难弄清 PyTorch 的核心要领.但是随后不久,PyTorch 发布了一个新版本,我决定重新来过.在第二次的学习中,我开始了解这个框架的易用性.在本文中,我会简要解释 PyTorch 的核心概念,为你转入这个框架提供一些必要的动力.其中包含了一些基础概念,以及先进的功能如学习速率调整.自定义层等等.   PyTorch 的易用性如何?Andrej Karpathy 是这样评价的 资源 首先要知道的是:P

谷歌开源TensorFlow系统 背后都有什么门道

 7月19日消息,据国外媒体报道,作为谷歌旗下最重要的人工智能系统,TensorFlow功能强大.其中包含的一些工具可以自动识别声音和图像,而另一些工具则可以根据上下文关系理解词语含义.同时,这也是一个开源系统,允许任何人下载源码.通过将所有工具开源,TensorFlow能够让开发人员打造出高度智能化的产品. 深度学习算法 人工智能并不是什么新奇的概念.在1956年的一次大会上,信息论之父克劳德·艾尔伍德·香农(Claude Elwood Shannon)就提出了关于机器人工智能的相关概念,并预

外链的价值要点 都体现在哪几个方面?

外链的价值性都有哪些呢?就是每天要"苦逼"式的去做的,没有什么限制性.但做了那么多,你是否了解到做的作用了?一般的外链者,只是单一的把它当做人物去完成.反之呢,去关注 效果的人,要弄懂自己做的怎样.这样,会成为一名出色者.同时,也能够更佳的深入了解到外链的价值性,体现在哪些方面.当然,这与行业之间,是具有很大的差异化的.例如,商品的,需要图于字的结合.而咨询类的,更佳的趋向于严谨的文字.做的多了,就能从不同的角度认识到.今简单的阐述一下外链的价值性,分为两个层面叙述. 一.外链的传统价

LoadRunner常用的分析要点都有哪些

提供了生产负载的虚拟用户运行状态的相关信息,可以帮助我们了解负载生成的结果. Rendezvous(负载过程中集合点下的虚拟用户): 当设置集合点后会生成相关数据,反映了随着时间的推移各个时间点上并发用户的数目,方便我们了解并发用户的变化情况. Errors(错误统计): 通过错误信息可以了解错误产生的时间和错误类型,方便定位产生错误的原因. Errors per Second(每秒错误): 了解在每个时间点上错误产生的数目,数值越小越好.通过统计数据可以了解错误随负载的变化情况,定为何时系统在

每个程序员都需要学习 JavaScript 的7个理由

最近在和招聘经理交流现在找一个好的程序员有多难的时候,我渐渐意识到了现在编程语言越来越倾重于JavaScript.Web开发人员尤其如此.所以,如果你是一个程序员,那么你应该去学习JavaScript. 需求 我之所以这样说的主要原因是,随着JavaScript的日渐成熟,以及Node.js方案变得越来越可行,我们对JavaScript程序员的需 求正在持续增长. JavaScript在需求比例上已经超过了C#,仅屈居于Java之下.如果你看看GitHub上可行的项目,你会发现JavaScrip

每个程序员都需要学习 JavaScript 的7个理由小结_基础知识

最近在和招聘经理交流现在找一个好的程序员有多难的时候,我渐渐意识到了现在编程语言越来越倾重于JavaScript.Web开发人员尤其如此.所以,如果你是一个程序员,那么你应该去学习JavaScript. 需求 我之所以这样说的主要原因是,随着JavaScript的日渐成熟,以及Node.js方案变得越来越可行,我们对JavaScript程序员的需求正在持续增长. JavaScript在需求比例上已经超过了C#,仅屈居于Java之下.如果你看看GitHub上可行的项目,你会发现JavaScript

网站外部连接建设的四大核心要点和注意事项

很多电子商务人员都将seo做为实现网络营销的一个重要手段之一,前期虽然比较辛苦,后期的话只要关键词一旦获得排名后续的工作往往变的轻松和简单,只要在网站内容和连接建设方面考虑下,注意服务器空间因素,一般稳定排名不是一件非常困难的事情,不管在网站优化初期还是在网站取得良好的排名之后,网站外部连接建设必须遵循一下几个核心要点才能使我们网站获得很好的搜索引擎信任,进而提高网站权重获得稳定排名.下面笔者就外联在建设过程中的几个核心要点和大家一一分享一下. 第一,网站外部链接相关性.相关性的外联无疑会对网站

学习笔记TF064:TensorFlow Kubernetes

AlphaGo,每个实验1000个节点,每个节点4个GPU,4000 GPU.Siri,每个实验2个节点,8个GPU.AI研究,依赖海量数据计算,离性能计算资源.更大集群运行模型,把周级训练时间缩短到天级小时级.Kubernetes,应用最广泛容器集群管理工具,分布式TensorFlow监控.调度生命周期管理.容器集群自动化部署.扩容.运维开源平台,提供任务调度.监控.失败重启.TensorFlow.Kubernetes都是谷歌公司开源.https://kubernetes.io/ .谷歌云平台

PyTorch vs TensorFlow,哪个更适合你

本文将探讨PyTorch和TensorFlow这两种流行深度学习框架之间的关键相似点和不同点.为什么选择这两个框架,而不是其他的呢?目前有很多的深度学习框架,而且很多都可用于实际的生产,我之所以选择这两个只是因为我对它们特别感兴趣. 起源 TensorFlow由谷歌大脑开发,并且在谷歌公司中广泛地应用于研究和生产需求.它的前身是闭源的DistBelief. PyTorch是Torch框架的表亲,Torch是基于lua开发的,在Facebook公司里被广泛使用.然而,PyTorch的出现并不是为了