使用 TensorFlow 和 Python 进行深度学习(附视频中字)

TensorFlow是谷歌研发的开源框架。本讲座介绍了如何使用TensorFlow创建深度学习应用程序,以及与其他Python机器学习库进行比较。

我叫Ian Lewis,我是谷歌云平台团队的开发者大使(Developer Advocate)。来自日本东京,我在东京居住了大约10年。如果你们有任何问题,可以关注一下我的Twitter账号 @IanMLewis。

下面我将说明一下PyCon JP(PyCon大会:Python语言社群全球性的盛会)。PyCon JP是日本的PyCon大会。我们从2011年就开始做PyCon JP,有意思的是PyCon JP实际上始于2010年的PyCon新加坡。当时我和PyCon JP其他的创始人相遇在这个会议。之后我们聚在一起,觉得在日本也需要类似的会议,所以就有了PyCon JP。一开始还是一个小型的PyCon,六个月后在2011年我们做了一场真正像样的PyCon。所以如果你有兴趣的话,可以在PyCon JP注册报名,和我们一起交流。


关于机器学习

介绍一下今天的主题,深度学习。我将会介绍一下深度学习的背景,谈一谈深度学习是什么。你们当中有多少人了解机器学习科学家,以及数据科学家?好的,很多人都知道。如果不了解的话,可能会觉得这个讲座有点无聊。希望在我讲TensorFlow时,你们能够有所收获。

深度学习是特定的一种机器学习,特定的神经网络。当中的深度部分来自深度神经网络。神经网络指的是取输入到网络中,输入连接到节点,当中包括激活函数。这些将用于输入,之后输入被导出,作为神经网络的输出。

我们用一张猫的图片当例子。输入就是图片的像素,经过神经网络得到输出。比如分类,告诉我们这是猫还是狗等等。这些相互连接并传递内容的被称为张量(tensor)。

这里介绍一下背景,这些神经网络擅长什么?

神经网络擅长两类主要问题,一种是分类问题。比如这是我的输入属于哪个类别。这张照片是狗还是猫还是人类等等,因此它擅长添加标签或者分类等等。另一种是回归,回归是构建数学函数 描述你手里的数据。所以你得到很多类型的输出。

比起回归,我将多讲讲分类问题。想象你们有一些分类问题,假设你有一些数据。比如图中的蓝色和橘色的数据。可以认为这些是人的身高比上体重,蓝色和橘色的点分别是成人和小孩的分组。你想构建网络或程序,能够通过人的身高体重来判断是成人还是孩子。这是一个很容易解决的问题,你可以在两者之间画一条线就行了。

但是这是例子可以通过神经网络解决。假设你有更复杂的问题比如像这个,输入数据不够清晰。那你该使用哪种函数或者分类方法区分这些数据。在这个例子里如果你有一个非常简单的神经网络,没有办法收敛(converge)。无法解决区分这两类数据的问题。所以为了解决这个问题,你需要开发一个更复杂的神经网络 深度更深。你可以添加中间这些隐藏层,可以让你利用神经网络进行更复杂的识别和分类。根据我怎么构建,这个可能收敛或者不能。但为了解决这类问题,需要一个更复杂的神经网络。

那么神经网络的核心有什么?核心是一个大型函数,输入一个张量,输出另一个张量。中间步骤在张量进行操作,从而生成输出。这类问题就相当于,就像有多少人了解矩阵乘法,这个是高中数学知识。你会对这些张量进行这类操作,通过乘以权重和添加偏差等等。就像流水线一样,为了得到输出一遍一遍地重复。但进行乘法要用到的中间权重。实际上构成了你的神经网络。

介绍下TensorFlow名字的由来。TensorFlow指张量(tensor)如何流过(flow)神经网络。

但是张量是什么?你们都很熟悉矩阵乘法或矩阵,比如向量或者简单的数组。你将如何把它在编程语言中执行。因此你有许多值组成的数组。矩阵可能是向量的二维或三维版本,你可能在编程语言中有类似这样的三维矩阵。

张量实质上是任意类型的矩阵,所以它是任意维数的。因此你有由任意数量组成的数组在你的应用中作为数组执行,这就是张量。只要维数匹配,你就可以在张量上进行矩阵乘法。当实际执行时,神经网络时完全连接的。在输出张量上,每个输入值连接输出值。这意味着,每个连接都有相应的权重。你所做的就是进行加法或乘法。把输入带入神经网络,后面加上一些偏差。

这个例子很简单。加上偏差,得到输出向量。比如这里有三个输出值,分别代表三个不同类别。比如对于输入图像,分为猫 、狗 、人。输出则是百分比或者输出值。显示输入图像与特定分类的匹配度。这个特定值的数值不会太友好,它只是一个数字,代表一个特定的值。反映你手上的图片多大程度上是人 狗,还是猫。

对这类神经网络,最后你通常会需要增加softmax函数。softmax的作用是选出最大值,或者对所有数据进行标准化。从而得到的输出值在0到1之间。给出一个百分比,说明图像是猫、狗还是人。假设得出一张我的图片是人的可能性为85%,似乎有点低。但你能懂当中的意思。

人工神经网络很厉害的一点是,一开始你不需要太了解数据。你可以开始用数据训练模型,然后使用反向传播来继续训练模型。更新权重和偏差,从而提高模型的性能。这正是由我刚才提到的反向传播来完成的,只需为神经网络提供损失函数(loss function)或者代价函数(cost function)。计算期望值和神经网络的实际值之间的差值。

我的图片应该是人,那么期望值应该是百分之百,表示这个图片上是人。而人工神经网络可能得出图片是人的概率为85%,使用代价函数得到15%的差值。用这个值更新神经网络的权重和偏差,尽可能让实际值接近期望值。反复迭代,该过程最终会得出最优的权重和偏差。整个过程需要使用一些输入数据。比如这是一张图片,这是对应的标签,或者模型应该得到的正确输出值。以上是关于神经网络的一些背景知识。

突破性进展

我花了一半时间为大家介绍这些内容。为什么要讲这些内容?无外乎是机器学习领域取得的众多突破性进展。

接下来的问题是如何训练模型,如何确定哪些值是预期得到的。因此你需要一些已经匹配的训练数据,期望值和数据相匹配。

我们为什么要讨论机器学习? 机器学习为什么成了最近的热词?

因为机器学习领域出现了众多的突破性进展,让我们能利用它解决实际问题。直到最近,我们能够用机器学习解决一些特定领域的问题,以辅助我们人类完成一些事情。然而我们很难把它做成产品,让它变得容易上手、便于使用。

这是我们在谷歌使用的Inception模型,用于训练图像以及给图像匹配标签。接下来我详细介绍一下它的背景。

这是深度神经网络。我之前提到的神经网络具有矩阵乘法,但类似这样的深度神经网络,加上"深度(deep)"的关键字或者深度方面。设想每个网络,采用诸如此类的矩阵乘法对输入数据进行操作。

比如输入是一张1M大小的图片,设想其中每个都有一个转换为张量的图片。一张1M大小的图片可能包含成千上万个像素点。它们构成张量中数以千计的维度。接下来你需要反复迭代,即对张量值进行数千次乘法运算。不断迭代,整个运行一遍。能够想象这是一个庞大的组合问题。为了训练模型需要完成多少计算,假设一张图片跑一次,而你现在有数以百万计的训练图像。你需要对这些图片进行训练,需要成千上万甚至上百万次,不难想象这是一个超大规模的问题。

我们研究发现对这类深度神经网络而言,结构越复杂,层数越多,模型预测性能越好。因此对于大量的输入,如果采用一个大型的深度神经网络,那么同样的训练集可以获得更多的值。但问题是深度神经网络需要大量的计算。为此人们通常构建大型的矩阵,或者有大量GPU的机器用来训练模型。通常需要数小时数天或数周来训练一个模型。仅为了运行一个测试,确保特定的模型或者特定的神经网络能够发挥性能。

研究人员需要反复操作,只为获得一个可用的模型。一些研究人员开始利用超级计算机进行训练,目的是加快速度。然而这对大多数人是不可能的。你需要提前租用超级计算机。对于没有超级计算机来处理这类机器学习模型的人,他们实际上利用深度神经网络。

在谷歌,我们拥有大量的计算机设备。虽然我们没有超级计算机,但我们有许多计算机。我们另辟蹊径,但是我们通过在谷歌利用机器学习取得了众多重大突破。

这些是我们研发的产品。你如果熟悉谷歌图片,可以在你的相册簿批量添加一组图片,然后通过关键词搜索你想要的图片。例如"雕像" "婚礼" 任何关键词,系统将搜索到与你输入的关键词或标签相匹配的图片。你不需要提前标记这些图片,也不需要教它这些图片是什么。根据之前训练过的模型它已经知道了。这很擅长开发产品和现实中的应用。

另外一件我们正在做的是识别图片里的文字。我们有很多街景数据或街景图片。我们想要获得现实中商铺的名字等。因此我们需要通过图片,从图片中得出文本。从而得到索引,弄清楚这些商铺的位置。我们在致力于解决这类问题。

你可能听过AlphaGo,这是一个运用机器学习神经网络的项目。它会下围棋,而且听说下得很不错。

在Google中机器学习的应用越来越多。这是最近的现象,可以注意到这张图里。在2014年之前 Google中应用机器学习项目的数量有着轻微的增长,但是2014年之后就出现了飞速的增长。说明了机器学习近年来发展有多迅速。

这是谷歌中的一个项目,称为谷歌大脑。用于构建这类神经网络。我们的方式是,通过将神经网络的问题分配到很多机器上,并同时在很多机器上进行训练和预测。这让我们能够利用Inception模型,在使用ImageNet时能够提升40倍的速度。正如之前展示的图,ImageNet是非常著名的数据集,用于机器学习和训练。同时我们还用RankBrain对搜索结果进行排序的机器学习模型。我们用约50到500个机器节点,来训练这类模型。

TensorFlow

接下来我们来讲TensorFlow。TensorFlow是谷歌研发的库,用于构建这类机器学习模型。TensorFlow是开源的库,使用Python。同时是用来构建神经网络的通用机器学习库。去年11月我们对它进行了开源。现在已经被用于许多机器学习项目。

TensorFlow的名字源于我之前提过的,即让张量(tensor)在管道中流动(flow)。从而有张量的数据流通过神经网络。这个思路来自于为这些张量绘制的流程图。它有一些很酷的特征,比如说能够灵活直观地构建图像框架,支持线程、队列和异步运算。可以在CPU GPU或任何支持TensorFlow的设备上运行。它会在图中进行操作 并对其进行分解,分配到许多的CPU和GPU上。

TensorFlow的核心数据结构在于图(graph)。操作就是图中的节点,值的张量在操作间传递。包括其他内容比如常量(constants)即在训练时不改变的量。这些可以在训练时或者更新模型时改变,但在单次训练中是不会改变的。还有占位符(placeholders)和变量(variables)。占位符类似于神经网络中的输入,而变量则是在训练神经网络时不断更新的。一般来说,有作为神经网络输入的占位符,以及变量类似在训练中进行更新的权重或者偏差。会话(session)则用于封装运行所在的环境,它的作用类似于把操作映射到设备上。这张幻灯片是非排他性列表,包括TensorFlow所支持的操作。我们有一些TensorFlow中所支持的操作。

这是在Jupiter notebook上运行TensorFlow的例子。我将用非常基础的MNIST例子进行讲解,MNIST是用于机器学习的经典数据集,包括许多手写数字的图片。你要做的就是,用这些数字进行光学字符识别(OCR)或者字符识别,从而确定每个图片代表什么数字。

如果是1,那么你希望输出文本是1。现在我要加载测试数据,在训练数据集中进行测试。训练图片共有55000张,每张图片都被表述或映射到张量中,大小为784个维度,每一张图片都有784个像素,即28乘28。

我调出一张图,这是训练数据集中的第6张图。实际输出是这样。这是数字8的图片,如果看到原始的输入图像,输入图像中的值都代表图像中的一个特定像素。从0到1,代表这个图像多暗。如果是0,像素则为白色。如果是1或者接近1,像素则比较暗。

然后看到这里,这些是训练数据。这是训练数据输出的形状。是10维的,大小为10的数组。输出为0、1。训练数据是0或1,或是任何一个值。这说明了训练数据代表什么。这是输入图像的实际训练标签,这里为8。在第8个位置有个1,说明这个图片为8。我们将用它训练神经网络。

这是我之前展示的图片。就像你训练神经网络一样会看到每个像素,并为特定像素分配一个权重。因为我将会做一个相当浅的神经网络,只有一个隐藏层。这会要给每个像素分配权重,表示这个像素或者图片是否代表特定数字。这里的蓝色表示正权重值(positive weight),红色表示负权重值(negative weight)。所以蓝色区域的像素表示为0。1、2也是同理。具体看到这个,这个类似实际数字的权重。你可以看到,这里的8看起来很像8。

一旦完成这一步,你可以设置神经网络。要如何实际训练它。这实际定义神经网络。我创建了X作为占位符,这是神经网络的输入。所以X是输入,形状为784维度。这意味着大小不一定为55000,它可以是任意大小。接着分配这些变量,因此权重和偏差将在训练中更新。

然后我要定义在值上进行的操作。这里要进行矩阵乘法,这是我要进行的预定义操作之一。用X乘以W 并且乘以所有的权重,即进行这个矩阵乘法。最后加上B,加上偏差。接着在上面运行softmax。这能够让我在神经网络中进行训练。

现在要定义训练步骤,这定义了我将在神经网络上进行的反向传播。在这里我定义一个占位符,这是为了损失函数。在这个例子中我将用到交叉熵(cross-entropy)。这是损失函数的一种,你可以尝试其他几个。但这是一个非常简单的例子。

我将使用梯度下降优化器,这是用来更新权重和偏差的方法。当出现差异时你可以使用梯度下降,从而明确该如何更新权重和偏见,应该更新多少。你将使用这个优化器,尝试找出输出的差异,然后映射到需要更新的权重和偏差的差异上。这将告诉我如何将交叉熵函数最小化,进行可视化后是这样。有初始值,接着使用梯度下降优化器。从而明确该如何改变这些值,以获得更好的输出。为了得到更好的值需要反复重复该过程。这里存在找到本地最小值的问题,这是调整值的不错方式。

接下来我将在神经网络中,使用优化器或者反向传播从而进行训练。这将对会话进行初始化,即对TensorFlow的训练会话进行初始化。然后它会循环,对数据进行数千次的小批量处理。我将取训练集,选出100个值。有意思的是,我不必对整个55000张图像的训练集进行循环,也不必每次训练。我可以随机选取一百个值,并且仅在每个小批次中进行训练。

这很有意思,如果你喜欢统计你在做的是选出整个训练集,然后选出当中的随机样本进行训练,这将得到训练集的代表性样本。从统计上来说,最终得到的结果近似于对整个训练集进行训练。这类似于你想知道比起其他总统候选人,人们是否喜欢这个候选人。你不需要问每一个美国人或者每个州的人。你可以对随机人群进行询问,得到的结果与实际结果很相近。这样可以节省很多的时间,只需运行实际数据的百分之五,从而节省大量时间。

接下来可以对神经网络进行测试,看其效果如何。这是在TensorFlow中使用的另一种操作,使用argmax函数。这个Y值是从神经网络得出的值,这个质数Y是训练集中得出的实际值,是正确的值。我将对两者都运行argmax函数,这将在输出的每个向量中得出0或者1。最后得出我的神经网络正确率为91%,这实际上很糟糕。十个图像中有一个是不正确的,但这是一个非常简单的例子。

你可以开始做更复杂的例子 使用MNIST,MNIST当中最好的正确率可以达到99.997%。如果用神经网络做的更多,可以得到更正确的数值。

TensorFlow的官网也是很不错的,当中有很多教程。比如这个针对初学者的MNIST例子,关于在TensorFlow上使用MNIST训练集。如果想通过更复杂的操作得到更好的结果,可以试试下一个教程,针对专家的MNIST教程。给原来的神经网络增加了些复杂性,从而提高5%或6%的正确率。还有一些其他教程,比如使用卷积神经网络 递归神经网络等等。有很多例子,都是简单易懂的。这让TensorFlow成为机器学习中非常出色的库。

在这里出于趣味性,我使用MNIST和Theano库,运行了相同的训练数据。Theano库与TensorFlow的方式很类似,使用方法也类似。在这里我会使用TensorFlow例子中,这里你所做的非常类似。在Theano中存在共享对象(shared object),这会用于权重和偏差,而不是用变量。接着你可以对神经网络进行定义,使用相同的softmax 再加上偏差。然后对损失函数和训练步骤定义相同的交叉熵。有点不同的是需要进行反向传播。这里是反向传播,这是梯度下降函数。可以给出代价函数的交叉熵,以及权重和偏差。但需要自己进行更新。

之后就可以用Theano建立训练模型,然后做数千次批次训练 。接着测试,在这里我得到89%正确率。会得到相同的正确率,因为操作类型是相同的。Theano和TensorFlow的区别在于库核心部分的构成。

TensorFlow能够让你更容易分解操作,并且映射到特定的设备中。然而 Theano是核心库,这让它很难或几乎不可能映射到多个GPU或多个设备进行训练。

TensorFlow的与众不同在于分布式训练,这能够对各个GPU和CUP进行映射。并且支持许多不同类型的分布式训练。比如数据并行(data parallelism),以及模型并行(model parallelism)等等。数据并行和模型并行中存在一些取舍,两者得到的结果不同。模型并行会分解模型的不同部分,然后在不同设备不同机器上训练相同的数据。数据并行则是在多台机器上运行相同的模型,并拆分数据。两者都有不同的优缺点。

在谷歌,我们倾向于使用数据并行。但是模型并行性适用于许多不同类型的任务。TensorFlow两者都支持。我不会介绍过多的细节,比如数据并行、同步模型、异步模型。如果你感兴趣的话,可以之后和我聊聊。

当你对这类机器学习模型或训练进行分配时,会存在一些问题。你需要在各个机器之间传输大量的数据,取决于如何分解或分配训练。因此你需要一个快速的神经网络,因为操作在单个GPU上需要花费几纳秒,但是通过网络传输数据需要几毫秒。分布数据的能力上存在数量级的差异。问题的瓶颈在于机器之间的网络。

在谷歌我们致力于这类问题。为了使机器间的连接尽可能快,因此我们计划建立一个云版本,称为Cloud ML。支持在谷歌数据中心运行TensorFlow,能够充分利用谷歌数据中心的硬件,从而进行分布式训练。这可以帮助你减少时间。原来需要8小时如今在20个节点上只需32分钟,快了近15倍。

除了能够利用GPU以及这类硬件,我们也在开发自己的硬件用于机器学习和矩阵乘法。这称为Tensor Processing Unit(TPU)。这是我们在谷歌开发的一种ASIC,为了获得更好的性能。GPU是非常耗能的,所以我们开发了一些耗电少的产品。但是这些是专门针对机器学习的。我们也计划把这些作为云计算学习的一部分。

如果你们对TensorFlow感兴趣,可以看看这些网站。上面有很多例子和教程。这也是TensorFlow很不错的地方。这些教程真的很棒,编写的很好,简单易懂。

还可以看看bit.ly/tensorflow-workshop,很适合构建TensorFlow模型。包括基础和进阶的MNITS例子,还包括如何使用kubernetes,以及使用TensorFlow Serving,构建机器学习的产品版本。如果你感兴趣的话 一定要看看,谢谢大家来听讲座。

共同关注 数据分析,是技术,也是艺术。

加关注
喜欢 | 1

登陆后发表文章

  • 0条回应给“使用 TensorFlow 和 Python 进行深度学习(附视频中字)”的评论