Py学习  »  Python

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

CDA数据分析师 • 6 年前 • 441 次点击  

CDA字幕组 翻译整理

本文为 CDA 数据分析师原创作品,转载需授权


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


CDA字幕组对该视频进行了汉化,附有中文字幕的视频如下:


使用TensorFlow和Python进行深度学习(一)




使用TensorFlow和Python进行深度学习(二)



针对不方面开视频的小伙伴,CDA字幕组也贴心的整理了文字版本,如下:


(文末有彩蛋! )




我叫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,构建机器学习的产品版本。如果你感兴趣的话 一定要看看,谢谢大家来听讲座。


CDA字幕组召集令


CDA数据分析师旗下的CDA字幕组开始招募啦


我们发掘了一批优质的数据分析视频只要你有责任心有时间有一定的英文翻译、听译能力最重要的是热爱数据分析那么就来加入我们吧


申请报名:


点击「阅读原文」或扫描下方二维码


往期精彩文章回顾

 
数据科学的十大常见误区 你中枪了吗?


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/76vAu8RgoO
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/4158
 
441 次点击