2017年11月1日星期三

掌握地球?智能机器带来的真正风险


作者:Abhimanyu Dubey

翻译:吴蕾、霍静、任杰


当人们问我是做什么工作的时候,我总是非常困惑如何回答才好。"人工智能"这个答复吧,我觉得太宽泛了,而"图像识别"似乎又太专业了。不过呢,还是下面这个问题令我真正抓狂:


人工智能会掌控整个地球吗?


对于一名从事于机器智能研究的专业人士来说,这个问题太让我恼火了。我也不想去抱怨怀疑论者,事实上大部分人都觉得人工智能是一种神秘,而且有着无穷无尽阴谋诡计的玩意儿,最终它们会把人类灭绝,因为,它能够在我们狂看一晚Evan Goldberg编导的电影之后,就预测到下一部我们将观看的影片将会是《Sausage Party》(《香肠派对》)。


"然而,大多数人并没有意识到,无论我们认为自己多么有个性,多么特殊,从普遍意义上来看,人们还是遵循一些普遍行为模式的。只要经过足够多训练,计算机就可以轻松识别出人们的行为模式。"


因此,机器能推测你喜欢的音乐,或者给你一些手机APP应用的建议,这对机器来说很容易实现。不过,这并不代表所有的预测工作的难度和性质类似,我只是希望大家能理解,这相对于人类的能力来说是一种延伸和拓展。


要想了解时下人工智能领域中哪些技术很厉害,重点在于懂得机器学习做得不错的两个主要场景:


1.受控环境 2.监督


我们看到了Google的人工围棋选手AlphaGo打败了人类最厉害的围棋选手,计算机象棋的问题很早以前就已经解决了,而最近又有很多论文在探讨Doom游戏比赛中击败人类的话题。事实上,在游戏里面,你能够完全掌控操作环境、能够实施的行为以及可能产生的结果,这使得建模变得相当容易。而一旦我们能够将游戏环境进行建模,下一步任务就是模拟和学习。实际上,这些理论早就已经成熟了,正是近年来计算机硬件的发展使大规模机器学习得以实现,才能够令AlphaGo这类技术在实现层面上获得重大突破。


监督式受控环境表示对于每一个行为,你能够估计出可能受到的惩罚,从而能够有效地从错误中积累经验,而游戏正是这种监督式受控环境的完美表达。还有一个例子就是我们刚才提到的电影预测,可以理解为有一个很大的样本,里面存在"用户"和"影片"两类数据,还有一个给定的用户选择模型。通过这些,我们就能进行下一次看什么电影的预测。


在监督式受控环境中,我们知道会得到何种信息,并能够对类似的信息加以处理。我们可以对这类目标创建"表达法"(representation),在我们需要进行预测的时候,这些"表达法"能够帮助我们最终确定准确的计算模型。这是通用学习类型中的一个非常狭窄的子类,也是和我们人类差不多的一类智能方式。


图注:分类器概观


然而,大部分的人类行为并非监督式的,而是在与环境交互的基础上建立的逻辑和直觉。人类的基本活动,比如说识别物体,理解物理过程都是时常发生的事情。通常,我们通过与事物的互动能习得很多的新知。


在当前阶段,这对于计算机来说还是很难达到的水平。现在如果你要一台机器能认识所有你给的图片里面的汽车,你必须告诉机器先去看那些图片,还得告诉它你的汽车是什么样子的。当你给机器看了大量汽车图片时,它就能认出汽车了。这就是监督式学习,在它尚未理解看什么东西的时候,你得教它汽车是什么样子的。


现在,计算机科学家在努力使这种学习变成几乎无需监督的,即非监督式学习。最终,我们希望机器能够理解物体和景象的概念本身,而不需要特地去调教它。


当前大多数研究的重心在于非监督式学习,解决这个问题更加困难。诚然,我们的机器看上去更聪明了,不过大多数都是在监督式受控环境中的情况。首先我们必须能令机器人在非监督的环境下正常工作,然后再考虑系统在非受控的情形下运行,这样才更为接近人类的智能。


"尽管,现在探讨机器灭绝人类,或者是机器人的'不良企图'仍为时尚早。然而,人工智能更严峻的威胁正悄然逼近,这可能造成极其严重的后果"。

早先通过观察特定的特性的算法称为决策树分割数据,图源:维基百科


在这个会议的最初讨论时,我导师曾提到了一个问题,令我第一次真正质疑人工智能的可用性。早期传统的人工智能技术的算法很容易理解,比如说,我们要造一个机器来测量人的身高和体重,并告诉他们是不是超重了。这个很简单,我们只需要计算出这个人的体重指数(Body Mass Index, BMI),如果超过了特定阈限,那就是超重。这是人工智能的原型算法。如果我说某人肥胖,这是必须要有合理的判断的(而不是熊孩子骂人),这个人的BMI确实是落在超重人群的平均BMI范围里。


现在大多数的机器已经不是这么简单了,它们采用大量复杂的数据作为输入(比如高清晰度的图片),经过非常精细粒度的算法来完成输出。这样的话,简单的阈限或决策树的方法就不够用了。渐渐地,系统采用了一套广为人知的深度学习算法,去识别和学习大量数据,用类似于人类的方式去细化模板。


图注:典型的深度学习模型。它包含了若干个互相连通传播信息的神经元(圆圈),这与已发现的人脑运作模式十分相似


这些系统性能非常好,但是学习过程很慢,因为需要很多数据来学习。


"但是,有个问题:一旦它们给了我们结果,不管正确与否,我们并不知道机器是怎么得到这个结果的。"


这个听起来并不是那么要紧—在开始的时候,在机器学习系统里面,我们有两种类型的数据—特征和标签。特征是观察到的变量,标签是我们需要预测的。举个例子,在之前的肥胖症检测器中,我们的特征是人的身高和体重,标签是每个人的超重或者健康指标。为了从图片中检测癌症细胞,特征是若干张器官的图像,标签是图片有没有癌症细胞。


癌症检测算法会先扫描这组图片


机器学习算法一般会这样解决问题,先给每个特征配置权重,相加,最后基于所得的和来做决定。比如,如果你要预测一个苹果是不是坏了,你会先看苹果的气味、颜色,如果触摸一下那么就还有它的质感,最后大脑会配置给这些特征不同的权重。


假如苹果烂了,光凭颜色一个特征就可以解决问题了


计算机遵循类似的想法,只不过权重是通过不同的优化算法算出来的。但是,在深度学习中,我们并不确定我们想用哪些具体的特征,更不用说配置权重。所以我们怎么办?我们让计算机自己学习选出最好的特征群,把它们用最佳方式组合来做决定,从某种意义上模拟人类大脑的做法。


这个主意给我们带来惊人的结果—在计算机视觉领域(这个领域研究如何让计算机理解图像数据),尤其是随着高效GPU和新框架的出现,使学习基本的图像级别的概念变得小菜一碟。但是,要注意的是—我们讨论的这些机器通过学习选出的特征,物理意义并不像传统方法那么直观。


这些例子展示了计算机从图片中寻找的东西—看上去它们在检测形状,但是对于非图像数据,并不是这么直观。


大部分人不觉得这是个问题—从技术角度在现阶段这并不是一个大问题,因为现在人工智能解决的任务都是具体的,比如从图片中辨认人物和物体、脸部追踪以及合成声音信号。我们大致知道算法在学习什么样的物体(事实上,这个展示是这个方面的一个最近的发展)。但是,当我们使用深度学习来处理那些有更多风险的预测的时候,每个预测都需要合情合理,可以解释。


设想你是一家银行,你有所有客户详细的交易信息和信用历史。你使用一个复杂的深度学习算法来找出拖欠贷款者。既然你已经有了一个大型数据库囊括用户的各类行为模式信息,算法解决这个问题可能会给出很高的准确率,但是,一旦你怀疑未来的拖欠者,你并不确切的知道到底是什么引起了怀疑,对于预测的解释变得非常困难。


大部分的深度学习系统没有好的技术去理解它们的决策能力,这个也是研究的热点。对于某些与特定任务相关的深度网络,尤其在计算机视觉,我们在理解这些系统上已经有了很大的进步—对其较好的定位,理解是什么激发产生了一种算法以及算法是否确实(按照我们的理解)这么做了。但是总的来说,还是有很大的空间需要提高。


机器学习有个很严重的缺陷—为了把信号和噪声分开,需要很多人工处理。或者用专业的话说,过拟合。我说这个专业词的意思是,当一个模型要拟合一个特定的数据集,用以预测新的未知的数据,它可能对于已知数据拟合的过于完美。所以导致的结果是,当应用于现实世界的时候,它就不会那么准确。


具体来讲,模型不是学习在这个世界中确实存在的模式,而是学习已经采集数据集的模式。有几种方式可以理解过拟合,对于感兴趣的人现实中有很多的关于过拟合的例子。一个简单的例子就是在你居住的地方是夏天,所以你把自己的行李箱装满了夏天的衣服,结果在阿姆斯特丹只有11度,你在那里只能冷的瑟瑟发抖。

该图反映了过拟合的情况,即,最后一幅图显然对噪音也进行了拟合


关注过拟合问题的原因是想强调一下机器学习的可解释性的重要性。如果我们不能理解这些机器学习算法到底学习的是什么,我们并不能判断它们是不是过拟合了。举个例子说,某机器算法是根据上网浏览历史来预测可疑的上网行为。因为使用的大部分的训练数据是来自美国的19岁少年,那么用于预测美国的19岁少年以外的任何个体就会是有偏的,尽管他们的搜索历史都有PewDiePie (专注恐怖与动作游戏)的视频。


这个问题的反响会随着深度学习在推断任务中的应用增加而迅速加大。比如,我们看到很多研究关于医疗图像预测 – 这个应用需要更多的可解释性和可理解性。除此之外,假如预测任务的批量太大不可能去人工检查预测结果,我们就需要系统来帮我们理解和调整机器学习到底做了什么。


这个威胁刚刚出现,但是这个方面的研究需要更多的时间,来找到更好的解决办法。但是,我们必须意识到模型可解释性的重要性,尤其当我们建立模型是为了让生活变得更好。


我想用一个例子来结尾:如果一个人撞车了,我们可以找出原因,来理解事故是怎么发生的 – 也许司机喝醉了,也许路人正边端着热饮边发短信呢。


但是如果无人驾驶车撞到另外一辆车,致一名乘客死亡,我们去找谁呢?原因又是什么呢?你怎么保证它不会再发生呢?


这些事故最近发生过几次,随着更多的人工智能系统的出现,会有更多的失误发生。为了更好的改正,我们需要理解到底哪里出了问题:这是今天人工智能要面临的主要挑战之一。



]]> 原文: http://ift.tt/2lHOQ70
RSS Feed

机器知心

IFTTT

吴恩达CNN新课上线!deeplearning.ai 4/5解锁,6日开课

大数据文摘作品

作者:魏子敏 龙牧雪


文末有彩蛋!bazinga!


相隔近3个月,吴恩达及其创业公司deep learning ai系列课程的第四门课程终于上线,课程依然选择在coursera的平台,11月6日正式开课,持续四周。尽管课程还没有正式开始,但目前所有视频已经可以在coursera网站上观看了。


coursera课程链接:

http://ift.tt/2vLAXJh




文摘菌注意到,在deeplearning ai的官网尾部特别设置了一条给中国ai学习者的通道,直通网易云课堂的相关课程,本次课程网易云课堂也已经放出了英文版视频(网易云课堂表示中文版目前还在紧张的翻译中),无法科学上网看到coursera的同学也可以在国内观看流畅的视频啦(吴教主一定是听到了国内同学的呼声!)。




值得一提的是,在第一讲的课程中,当吴教主讲解计算机视觉照片风格转化时,放出的是自己太太Carol Reiley的照片,这一波炫妻也是毫无痕痕迹了。文摘菌也想给大家提个醒,Carol的照片在本次课程讲解中还会多次出现,保证大家狗粮吃到饱(微笑脸)。



图片来源:网易云课堂



图片来源:Drive.AI


Carol Reiley本身也是ai从业者。据Carol自己的领英介绍,她在机器人领域拥有15年学术和业界经验,被福布斯评为"20个AI杰出女性"(20 Incredible Women in AI),拥有6个专利并著有一本童书。Carol是硅谷的自动驾驶创业公司Drive.ai创始人之一,吴恩达同时是这家公司的董事会成员。


根据coursera和网易云课堂资料,这门课会教你如何搭建卷积神经网络并将其应用到图像数据上。这两年,在深度学习的基础上,计算机视觉也得到了迅猛的发展,从而产生了大量令人振奋的应用:安全无人驾驶、精确面部识别、自动阅读放射成像等等。建议已经学习了前两门专项课程的同学学习。




本次课程吴恩达依然作为导师亲自上阵授课,另外配备了两位课程助教。




通过这门课的学习,你将会:


理解如何搭建一个神经网络,包括最新的变体,例如残余网络。

知道如何将卷积网络应用到视觉检测和识别任务。

知道如何使用神经风格迁移生成艺术。

能够在图像、视频以及其他2D或3D数据上应用这些算法。


附上网易云和coursera列出的中英文授课大纲,感兴趣的同学们可以即日开始战斗啦!


第一周  卷积神经网络


1.1  计算机视觉


1.2  边缘检测示例


1.3  更多边缘检测内容


1.4  Padding


1.5  卷积步长


1.6  卷积的"卷"体现之处


1.7  单层卷积网络


1.8  简单卷积网络示例


1.9  池化层


1.10  卷积神经网络示例


1.11  为什么使用卷积?




第二周  深度卷积网络:实例探究


2.1  为什么要进行实例探究


2.2  经典网络


2.3  残差网络


2.4  残差网络为什么有用?


2.5  网络中的网络以及 1×1 卷积


2.6  谷歌 Inception 网络简介


2.7  Inception 网络


2.8  使用开源的实现方案


2.9  迁移学习


2.10  数据扩充


2.11  计算机视觉现状




第三周  目标检测


3.1  目标定位


3.2  特征点检测


3.3  目标检测


3.4  卷积的滑动窗口实现


3.5  Bounding Box预测


3.6  交并比


3.7  非极大值抑制


3.8  Anchor Boxes


3.9  YOLO 算法


3.10  RPN网络




第四周  特殊应用:人脸识别和神经风格转换


4.1  什么是人脸识别?


4.2  One-Shot 学习


4.3  Siamese 网络


4.4  Triplet 损失


4.5  面部验证与二分类


4.6  什么是神经风格转换?


4.7  什么是深度卷积网络?


4.8  代价函数


4.9  内容代价函数


4.10  风格代价函数


4.11 一维到三维推广




最后的最后,除了吴教主的课程,在网易云课堂学习的各位同学也可以顺便关注文摘菌家的专栏,以及我们授权翻译的两门斯坦福和牛津的优质免费课程。


专栏链接:

http://ift.tt/2zpYrFL




李飞飞主讲的斯坦福CS231n深度学习与计算机视觉:

http://ift.tt/2uU73O7


牛津大学联合谷歌DeepMind深度学习与自然语言处理:

http://ift.tt/2zedD8d




]]> 原文: http://ift.tt/2zr6qT7
RSS Feed

机器知心

IFTTT

藏在声音和智能音箱中的秘密

上个月,谷歌和亚马逊分别公布了迷你智能扬声器 Google Home Mini Chalk 和 Amazon Echo Dot 2,价格都低于 50 美元。这些藏在智能语音设备中的虚拟小助手们能够管理你的日常生活。这些曾经只存在于科幻小说当中的技术,如今都是依靠着自然人机语音接口实现的。


1966年,麻省理工学院的 Joseph Weizenbaum 发明了第一个聊天机器人 Eliza,它可以做出适当的回答,比如「对于你感到沮丧,我非常抱歉」。但从功能上来说,它仅仅是检测了输入的关键字,然后触发了预编程的回答。


和 Eliza 相比,现在的智能音箱明显更接近人类,功能也更多样化。微软的智能语音助手 Cortana 以讽刺的幽默闻名;而 Google Home 可以管理简单的计划,比如点个披萨或者陪你玩些小游戏。虽然现在的智能音箱还没有达到科幻电影「Her」中人工智能系统 Samantha 的程度,但这也已足够有吸引力了——2500万的用户立即购买了 Echo,500万的用户购买了 Google Home 。而且,这仅仅是个开始。


智能音箱无需动手操作,这使得人机交互的用户体验更加友好,从而在功能上提供了更多可能性。实际上,这是未来的交互模式。不过,尽管人们知道这些虚拟助手能做更多新事情,极少数人真正了解它们是怎么做到的。


Synced 最近参与了由Innoworld在硅谷组织的一场线下活动,讨论了当今虚拟助手运用的科技。


胡峻玲博士是 Question.ai 的总裁及创始人,同时也是人工智能前沿会议的主席。她介绍了构造虚拟助手的六个关键要素:语音识别,语音合成,自然语言理解,对话系统,聊天机器人,以及音乐推荐系统。


语音识别和言语合成

智能音箱必须检测人类的声音,并且将其转换为机器可读的形式,这也被称为语音识别。数十年来,研究者们常常被噪声所困扰,深度学习带来了革命性的改变。2012年,基于深度学习的 AlexNet 在 ILSVRC 中胜出,它在图像识别方面大获成功。自 2013 年来,深度学习也已经被广泛地运用到了语音识别当中。


「深度学习让我们能够实现端到端的语音识别。」胡博士说。为了创造这样一个用户接口,智能音箱必须开发远场(far-field)语音识别功能。 Echo 采用了由七个麦克风组合的阵列技术,使它能从很远的地方、甚至是在嘈杂的房间里,辨别并处理声音指令。Echo 还对音箱做了调整,使它能辨别不同用户的声音。


锚定智能检测(Anchored Smart Detection)会唤起智能音箱的工作。这个关键步骤是由亚马逊团队首次引入的。它使用远距离循环神经网络(RNN)识别唤醒关键词以及随之而来的用户需求。



语音合成,是另一种虚拟助手运用的语音相关技术。一旦智能音箱决定了要说什么内容,语音合成便将词汇转换成声音。


虚拟助手首先通过词典将文本输入简化到词典当中。然后,词典会转化成一个音素串(phoneme string),也就是一个将单词分辨的单元。虚拟助手获得了一个音素后,会使用韵律建模、音高、音长、响度、语调、节奏等方式进行处理。最后,音素串和韵律注解会被整合到声音识别模型中,从而转换成流利的语言表达。


「Alexa 能说得非常流利,听上去不像一个机器人。这是因为我们研究了韵律建模。」胡博士说道。


核心要素——自然语言理解


在语音识别和语音合成之间,有一个关键步骤是自然语言理解(NLU),这是让虚拟助手具有阅读理解能力的关键。举例来说,当用户说「我在弹钢琴」的时候,系统并不知道什么是「我」或什么是「钢琴」。这种时候,自然语言理解的研究者们必须找到方法,将人类语言转换成一个标准的形式。



虚拟助手首先会挑出一些特有名词,比如城市名、公司名、乐曲名。下一个步骤是词类归纳,也就是将单词分到八个类别:动词、名词、限定词、形容词、副词、代词、同位语、感叹词。



最后一步是语法分析,也就是将一串自然语言或机器语言符号依照语法规则进行分析。但是,如果用户没有注意语法规则,语法分析可能没办法正确工作。现在,许多研究项目正在抛弃了语法分析,寻找其他替代方案解决端到端的自然语言处理问题。


对话系统


虚拟助手还需要两个步骤来启动一个对话:探测用户的意图,以及决定如何回复。


对话行为(dialogue act)将用户需求与对应的系统功能联系起来——比如,用户想听一个笑话、一首歌,或是想点一个披萨。在接受这个输入需求之后,虚拟助手会根据语调、首位单词和谓语动词来捕捉特征;然后,将这些特征归类到一个对话行为中去,比如需求、陈述、是非问题、或是确认问题。



对话行为步骤。

紧跟着对话行为步骤的,是对话决策(dialogue policy),它决定了系统接下来要做出怎样的动作。


如今,用户们希望能与虚拟助手们进行多重互动的自然对话,因此对话系统需要一个状态追踪器去维持现有的对话状态。这包含了用户最近的对话行为,以及当前用户表达的全部信息(entire set of slot-filler constraints)



现在,对话系统通过强化学习来搭建。这使得虚拟助手能更加机敏地响应用户的需求。


聊天与推荐服务


显然,一个智能音箱不仅仅是一个对话机器人,它还要适应不同用户的不同需求,提供聊天服务或音乐推荐服务。


聊天机器人在声音和内容两个方面都要与人类似,这是人机顺利交互的关键。亚马逊和谷歌等公司正鼓励开发嵌入式设备机器人。它们应基于开源聊天机器人接口,如 Amazon Lex Chatbot 或 Google的 API.ai。


音乐推荐功能是当今智能音箱的另一个核心功能。就像个人音乐电台一样,要凭借机器学习训练海量数据,为用户播放最适合的乐曲。这非常类似于亚马逊的产品推荐功能,或是 YouTube 的视频推荐功能。


音乐推荐算法要学会评估用户的偏好。这主要是利用收听特征(收听时长)、用户特征(收入、年龄、性别、地理位置等)和曲目特征(曲目、艺术家、流派、频道、关键词等)作为数据库进行学习的。


在不久的将来,就机能和性能而言,不同的智能扬声器间不会有太大区别。差别将主要在于功能的多样性。Echo 和 Google Home 正不断竞争,尽可能地发展和集成更多功能。


未来的虚拟助手可以将我们的生活掌管到什么程度呢?只要拥有足够的数据和合适的模型,它们将有无限的可能:


「罗马餐厅随时都有莫纳迪啤酒吗?」
「他们的莫纳迪啤酒在晚上七点之前有特价活动,卖五美元一品脱。不过记得你晚上九点要接 Leslie,得限制酒量啊。如果你喝了超过两品脱,我就要把你的车给锁了……而且你已经胖了两公斤了,你真的确定要吃意大利菜吗?……对了,猫还抓了只老鼠回家……」

硅谷顶级人工智能大会将在本周五盛大召开,请抓紧报名

www.aifrontiers.com

code AI4JQZX


原文链接:http://ift.tt/2ykaUdV


]]> 原文: http://ift.tt/2A7U1k6
RSS Feed

机器知心

IFTTT

增强学习入门6——蒙特卡罗方法

这个系列是我和InfoQ合作的《无痛的增强学习入门》系列,现转载到知乎专栏中。首发地址在:无痛的增强学习入门:蒙特卡罗方法 ,欢迎围观。

6 蒙特卡罗方法

6.1 真正的增强学习

本节我们来看看无模型的一种简单解决方法——蒙特卡罗法。从名字可以看出,当我们无法得到模型内容时,就需要通过不断模拟的方式得到大量相关的样本,并通过样本得到我们预期得到的结果。通过这样的方式,我们似乎又可以前进了。

在前面的策略迭代中,我们曾经总结了一轮迭代过程中的几个主要步骤:

  1. 策略评估
  2. 策略改进

其中与模型相关的是策略评估部分,既然没有了模型,我们就需要使用蒙特卡罗的方法得到。因为在之前的策略迭代法有模型信息,所以它只需要评估状态价值函数——也就是v(s),然后根据Bellman公式:

q(s,a)=\sum_{s′}p(s′|s,a)(R+v(s′))q(s,a)=\sum_{s′}p(s′|s,a)(R+v(s′))

求出状态-行动价值函数,并进行策略改进。现在我们没有了模型,不知道状态转移的情况,于是就需要对状态-行动价值函数进行估计。我们将

q(s,a)=E_π[R1+R2+R3+...]q(s,a)=E_π[R1+R2+R3+...]

变换为:

q(s,a)=\frac{1}{N}\sum^N_{i=1}[R^i_1+R^i_2+…]

也就是说,只要这个MDP是有终点的,我们就可以计算出每一个状态下的Return,然后利用大数据的力量求出估计值,然后得出策略评估的结果。

听上去是不是挺简单的?没错,精彩的还在后面。

6.2 蒙特卡罗法

接下来我们就实现一个简单的蒙特卡罗法的代码,更重要的是,我们最终还要拿这个算法的结果和策略迭代法进行比较,看看在不知道环境模型的情况下,蒙特卡罗法能否做到和策略迭代一样的效果。

前面对算法的流程已经有了介绍,我们的整理算法如下所示:

def monte_carlo_opt(self):     while True:         self.monte_carlo_eval()         ret = self.policy_improve()         if not ret:             break

其中包含了两个子算法。其中policy_improve和前面的算法类似,都是完成:

π(s)=argmaxaq(s,a)

所以这里不再赘述,下面来看看monte_carlo_eval,这个方法又分成几个部分,首先要用当前的策略玩游戏,产生一系列的episode:

env.start() state = env.pos episode = [] prev_state = env.pos while True:     reward, state = env.action(self.policy_act(state))     episode.append((reward, prev_state))     prev_state = state     if state == -1:         break

产生episode之后,我们再来计算每一个状态的长期回报:

value = [] return_val = 0 for item in reversed(episode):     return_val = return_val * self.gamma + item[0]     value.append((return_val, item[1]))

最后,我们将每一个状态-行动对应的return记录在状态-行动价值函数上:

# every visit for item in reversed(value):     act = self.policy_act(item[1])     self.value_n[item[1]][act] += 1     self.value_q[item[1]][act] += (item[0] -  \         self.value_q[item[1]][act]) /  \         self.value_n[item[1]][act]

这里涉及到一个小的改变,因为我们要计算期望价值价值,将所有观测到的return进行平均,那么假设价值为V,数量为N,那么有

V_t = \frac{1}{N}\sum_{i=1}^t [R_1 + R_2 + … + R_t]

= \frac{1}{N} \sum_{i=1}^t [R_1+…R_{t-1}]+\frac{1}{N}R_t

=\frac{1}{N} * (N-1)V_{t-1} +\frac{1}{N}R_t

=V_{t-1}+\frac{1}{N}(R_t-V_{t-1})

这样每一时刻我们都可以求出当前所有观测值的平均数,而且这个公式和我们常见的梯度下降法也十分类似,其中的 \frac{1}{N} 像学习率,而 R_t−V_{t−1} 像目标函数的梯度。那么是不是真的可以这么考虑呢?当然是的。

以上就是我们进行一轮游戏的运算过程,实际上我们会有多轮游戏,我们先将游戏轮数设置为100,也就是说,每一次策略评估,我们都来玩100轮游戏,并根据这一百轮游戏的结果完成估计。这样,蒙特卡罗算法的基本框架就搭起来了。大家一定非常想看看它的效果,于是我们就来和策略迭代进行一次对比,:

def monte_carlo_demo():     np.random.seed(0)     env = Snake(10, [3,6])     agent = MonteCarloAgent(100, 2, env)     with timer('Timer Monte Carlo Iter'):         agent.monte_carlo_opt()     print 'return_pi={}'.format(eval(env,agent))     print agent.policy     agent2 = TableAgent(env.state_transition_table(), env.reward_table())     with timer('Timer PolicyIter'):         agent2.policy_iteration()     print 'return_pi={}'.format(eval(env,agent2))     print agent2.policy

最终的结果为:

Timer Monte Carlo Iter COST:0.128234863281 return_pi=81 [0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0  0 0 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1  1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] policy evaluation proceed 94 iters. policy evaluation proceed 62 iters. policy evaluation proceed 46 iters. Iter 3 rounds converge Timer PolicyIter COST:0.329040050507 return_pi=84 [0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0  0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 1 1  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0]

可以看出,蒙特卡罗的结果比策略迭代还是要差一些,下面我们就来看看它们差距的原因。

6.3 探索与利用

一直以来我们没有花大篇幅做增强学习原理方面的讨论,是因为前面的算法虽然漂亮,但它们并不能帮我们直接解决实际问题,我们遇到的实际问题大多数都是不知道环境模型,或者环境模型太过于复杂的。所以这涉及到增强学习的一个思路,用英文讲就是"try and error"。

由于不知道完整的环境信息,我们只能通过不断地尝试去增加对环境和问题的理解,并通过这些理解帮助我们做出更好的决策。这里面肯定会走不少弯路,而且有一些弯路甚至不易发觉。所以增强学习遇到的一个问题是,如何找到更好的解决问题的路径,并确认这样路径应该就是最优的路径。

回到蛇棋的问题上来,在前面的问题中,我们可以看到棋盘,所以我们可以精确求出每一个状态-行动的价值函数。但是对于无模型的问题,我们能不能保证遍历所有的状态行动呢?

对于这个问题,我们可以想象,一开始所有的价值函数都初始化为0,所有的策略均使用第一种投掷手法,如果我们固定这种手法不变,那么我们只能得到这种手法的return,那么除非这种手法估计得到的价值函数为负,不然新的手法将不会被选中,也不会进行任何的模拟尝试,这就为我们带来了麻烦。

所以,为了"雨露均沾",我们必须让其他没有被选为最优策略的行动也参与到模拟游戏的过程中来,这样才能让每一个q(s,a)都有值,这样做策略改进菜有意义。

基于这个想法,我们改进了我们的策略模块,我们采用一种叫ϵ−greedyϵ−greedy的方法,首先用一个0到1的随机数进行判断,如果随机数小于某个ϵϵ,那么我们将采用完全随机的方式产生行动,而在其他情况下将选择当前的最优策略。代码如下:

def policy_act(self, state):     if np.random.rand() < 0.05:         return np.random.randint(self.act_num)     else:         return self.policy[state]

在这里,我们设定的ϵϵ是0.05,完成了这一步的修改,我们结果将会如何呢?

Timer Monte Carlo Iter COST:0.486936807632 return_pi=84 [0 1 1 1 0 1 1 1 1 0 0 1 1 0 0 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 0 1 1 0 0  0 0 1 0 0 1 1 0 0 0 0 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 0 0 1 1  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 0 0 0 0] policy evaluation proceed 94 iters. policy evaluation proceed 62 iters. policy evaluation proceed 46 iters. Iter 3 rounds converge Timer PolicyIter COST:0.325078964233 return_pi=84 [0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0  0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 1 1  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0]

可以看出,虽然两种方法的最终策略不同,但是模拟得到的分数几乎相同。说明在增加了对不同方法的尝试后,算法真的会有大幅的提高。

这个问题在增强学习中也被称为是"探索与利用"的对立问题。所谓的探索是指不拘泥于当前的表现,选择一些其他的策略完成行动;利用就是持续使用当前的最优策略,尽可能地获得更多的回报。我们假设总的资源是有限的,比方说时间有限,可以进行模拟游戏的轮数有限,我们不能无止尽地探索,也不能短视地一直利用,那么就需要尝试在两者之间寻找一个平衡。

前面我们提到,蒙特卡罗方法需要模型有明确的终止状态,那么总有一些问题是没有终止状态的,或者说有些任务需要在线学习,也就是说边尝试边学习,这些场景并不是很适合蒙特卡罗方法。而且蒙特卡罗方法也有自己的小问题,那么下一节我们就来看看另一种解决无模型问题的方法。

私货时间

我的书《深度学习轻松学:核心算法与视觉实践》,终于等到双十一,半价赔本促销,感谢支持!



via 无痛的机器学习 - 知乎专栏 http://ift.tt/2h1JRwF
RSS Feed

RSS4

IFTTT

昆仑数据首席科学家田春华:人工智能降低了工业大数据分析的门槛

在刚刚结束的国际 PHM 数据竞赛中,昆仑数据的 K2 代表队以绝对优势一举夺冠,成为 PHM Data Challenge 十年竞赛史上首个完全由中国本土成员组成的冠军团队。团队由昆仑数据首席数据科学家田春华博士带领四名成员组成,在业余时间完成了本次竞赛的任务。


PHM(Prognostics & Health Management,即故障诊断与健康管理)学会从 2008 年成立一直专注于工业设备故障诊断领域,其每年举办的「PHM 数据竞赛」是国际上高水平的同类赛事之一。首届竞赛由国际 PHM 学会和 NASA 共同举办,此后赛事成为一项传统,受到来自欧美工业界乃至军工界的追捧,至今已经有 10 届。往年的竞赛题目包括「涡轮发动机的剩余寿命预测」、「齿轮箱异常检测」、「晶圆化学机械平坦化异常分类」等,今年则聚焦于「城轨车辆悬挂系统异常检测」。


本次竞赛包括两个问题:


1)健康诊断:判断城轨车辆悬挂系统是否处于故障状态

2)故障定位:从故障车辆的 22 个部件中识别出 1~2 个故障部件


这个题目具有重要的现实意义,可以延伸至高铁、地铁以及汽车等应用领域。


图为悬挂系统模型,分为一级减震和二级减震,由 22 个部件组成(弹簧/阻尼),共安装 18 个振动传感器(红色标识)


本次竞赛分两个阶段,阶段一为模型的训练与测试,训练集为 200 个健康车辆轨道运行数据,测试集为 200 个待判轨道车辆运行数据;阶段二是模型的验证,验证集为 200 个待判轨道车辆运行数据。


「这里的难点在于,训练数据集中都是健康样本,没有异常。」田春华说,「可是往往有价值的则是异常数据,这是工业场景中普遍存在的现象。」实际工业场景中的异常数据较少,而且工业系统进行过多次调优,所以绝大部分工业数据均为正常数据,这与研究人员进行大数据分析的过程中希望具备全模态样本的期望相背。「比如近万台风机中,三年内可能只有个位数的风机出现过重大故障。想想样本得有多么不均衡吧。」他补充道。


解决这个问题有两种思路,一是用数据模型精确刻画所有的正常情形,只要脱离正常情形就判定为异常,这需要进行细致入微的建模,但会存在误判的情况;二是让模型具备通用性,考虑轨道、速度、负载等外生变量对系统产生的影响,同时考虑系统运行是一个动态的过程,要寻找到不变量。



K2 团队在 PHM 竞赛中的解题思路


「好在我们拿到了 18 个传感器的数据,系统内部的相关性非常强,所以可通过信号上下前后的一致性来增加一些判断。」田春华表示,团队为此加工了减振比等特征。「我们过去在这个问题上积累了很多经验,所以一开始就抓住了问题的基本面。在选择了正确的特征加工路径之后,精度可以达到 80% 以上,接下来再进行算法的调整和优化。」此外,团队还使用了基于相似度的轨道位置匹配减弱轨道不平整的影响。


在判断出系统处于正常还是异常状态后,团队面临着第二个考验,即指出到底是哪些弹簧或阻尼发生了故障。据田春华介绍,由于训练集全部为正常样本,所以这里需要结合自动控制理论中频域分析的知识:弹簧可以控制振幅,阻尼会使振幅衰减。在这个机理的基础上,数据驱动才能实现。


「其实当初在第二个问题上,我们也只是有一个大概的想法,没有必胜的把握。后来使用了多模型才有了一点突破,这都是我们意料之外的。而且跟往年的题目相比,今年的题目机理较强。虽然过去我们有很多经验,但是为了进行佐证,团队仍然查阅了大量的文献。」田春华回忆道。


K2 团队在 PHM 竞赛中的调优曲线图


事实上,竞赛的两个问题原本的分值比重各占 50%。各领先团队在第一个问题上的分数相差不多,但由于第二个问题难度较大,K2 团队占据了绝对领先优势。组委会出于竞赛趣味性的考量,更改了规则,把两个问题的分值比重改为 3:1。


「我们还是处于领先,只是优势没有那么大了。」田春华说道。最终,K2 团队的模型在第一个问题上的准确率达到 82.5%,在第二个问题上的灵敏度达到 53.5%,以 0.762 的总成绩摘得桂冠。

在谈到团队夺冠经验时,田春华表示,在短时间内把数据和机理有效结合,这对选手的专业性要求极高。K2 团队成员来自不同的领域,如自动化、统计、计算机,实现了优势互补。特征加工为后续研究奠定了基础,机理确定则帮助团队瞄准了方向。


在工业领域,企业希望最大程度地挖掘工业大数据的潜在价值并将其高效延伸至实际的细分场景,进而实现对工业业务理解的加深、降低实际决策所带来的不确定性。换言之,这些企业需要一个「医生」,这位「医生」需要通过「望闻问切」掌握工业机器的健康状况,不仅要能诊断出机器是否「生病」以及「病因」,并且对症下药,还要具备预测机器什么时候将会「生病」的能力。

举例来说,风机叶片受到低温环境因素的影响,可能会面临结冰的问题,这不仅存在安全隐患,也会对风机的效率与健康带来不良的后果。由于许多风机部署于较为偏远的地区,单纯依靠人力难以实现对风机状况的监测。如果可以使用传感器采集风机的数据指标,然后传输回机控中心加以分析,那么企业员工就能够远程掌控每一个风机的状态信息。因此,一个能够适应复杂地形、复杂气象条件的数据分析模型就十分必要了。


在人工智能技术兴起之后,工业大数据领域的研究人员就开始尝试使用新技术处理问题,并将其应用于一些数据量较大的工业应用案例。田春华介绍,公司在风机结冰问题上就曾使用过深度学习技术进行自动识别,而且表现不错。「在做风机结冰项目的时候,利用深度学习上来就取得 70% 的精度,这样我们对模型精度有了一个基准。然后我们加工特征后,通过白箱模型让精度提升至 80% 以上。」他解释道,「在处理实际工业问题时,我们通常先用深度学习快速得到一个基准,然后再做一个白箱模型,因为工业界的一线操作人员还是希望模型具有可解释性。某种程度上,人工智能技术降低了加工特征的工作量和数据分析的门槛。」


「当前人工智能存在一定的封闭性,虽然具有巨大的发展空间。在工业大数据领域,基于统计的数据分析方法并不是唯一的技术手段。」昆仑数据 CTO 王晨解释道,「我们认为,工业领域人工智能突破的方向在于,如何把统计模型与领域内的知识与机理模型深度融合。这也是我们研究的一个重要方向。」


「具体到工业领域中的实际问题,远比竞赛复杂和有趣得多,从大数据分析应用领域来说,除了 PHM 之外,大数据还可以在生产效率提升、产业互联网等方面发挥相当大的价值。」


在 SMT(印刷电路板)产线,SPI 机台利用光学检测自动研判锡膏涂抹质量,但往往过于严格,导致很多符合工程设计要求的产品被判定不合格。对于高价值产品,SPI 研判为不合格的板子还需要大量的人工复判。使用机器学习方法自动识别,部分筛选出合格品,这将大大降低人的工作量。 


但在石油管道泄漏检测中,机器学习的重点就是降低虚假预警。利用负压波检测是否存在泄漏相对容易,但造成压力下降的因素较多,除了泄漏,还有不同油品输送压力不同、油罐更换等正常工况变化的影响。幸运的是,我们发现不同原因造成的压力下降曲线形状存在细微差别,有的曾现底部震荡,有的曲线光滑但间杂毛刺。利用模式识别技术可自动匹配出识别出的压力下降的真正故障原因,降低了虚假预警给实际运维带来的困扰。


工业大数据的三大典型方向


「一个完整的工业大数据分析要整个流程打通,从开始的接入管理、规划、数据整合、深度分析,到后来的应用、业务流程,以及谁是工业产品的目标用户、选择工业产品的原因及利好等等,这些问题都是工业大数据平台要给出的答案。」田春华说道。


昆仑数据专注于做工业企业的大数据合伙人,成立于 2014 年底,创始团队来自 IBM、华为、西门子等科技企业,公司于 2015 年 1 月完成天使轮融资,同年 9 月获得来自达晨创投的数千万人民币 A 轮融资,2016 年 8 月完成 1 亿人民币 B 轮融资,如今团队有 100 余人。目前,昆仑数据已推出工业大数据平台产品 KMX,着眼于管理分析海量机器数据,挖掘展现数据价值,帮助企业为数据赋能、实现业务洞察、形成行动闭环。


以风机的运维场景为例,KMX 平台可以把风机附近的气象信息、地理信息、包含历史养护信息的设备日志等关联起来,为接下来的数据分析提供有力支持。在没有大数据平台的情况下,这些数据是散落在各个系统中的,无法为数据分析提供上下文信息,可能导致数据挖掘和分析结果较为片面。


目前,昆仑数据主要聚焦于能源行业、装备制造以及电子制造这三个领域。王晨介绍,为了保障企业的数据安全,昆仑数据会施行事前及事后的权限管理策略,设定了严格的访问权限及痕迹追踪管理。王晨表示:「工业大数据领域正处于方兴未艾阶段,市场空间较大,我们也正在积极探索的过程中。」


今年,昆仑数据参与举办了首届中国工业大数据创新竞赛,该赛事由工信部指导、信通院主办,吸引了来自海内外 1000 多支参赛团队。昆仑数据受邀承担出题任务并担任决赛评审专家。此次竞赛的两道竞赛题目分别为「风机叶片结冰检测」和「风机齿形带断裂预警」。谈及投入不少精力来推动中国自己的工业大数据竞赛,「也是希望大家能多关注这个领域,这里面的确有许多有意思的问题。」田春华笑道。


至于未来,人工智能是否能在工业大数据领域有所突破?迁移学习是否能在强机理的现实世界中找到落点?工业大数据还隐藏着哪些未被挖掘出的潜力?

想必随着时间的推移,这些专攻工业大数据的科学家们一定会在实践中找到令人惊喜的答案。



]]> 原文: http://ift.tt/2htg4Kj
RSS Feed

机器知心

IFTTT

终于!TensorFlow引入了动态图机制Eager Execution


PyTorch 的动态图一直是 TensorFlow 用户求之不得的功能,谷歌也一直试图在 TensorFlow 中实现类似的功能。最近,Google Brain 团队发布了 Eager Execution,一个由运行定义的新接口,让 TensorFlow 开发变得简单许多。在工具推出后,谷歌开发人员 Yaroslav Bulatov 对它的性能与 PyTorch 做了横向对比。


今天,我们为 TensorFlow 引入了「Eager Execution」,它是一个命令式、由运行定义的接口,一旦从 Python 被调用,其操作立即被执行。这使得入门 TensorFlow 变的更简单,也使研发更直观。


Eager Execution 的优点如下:


  • 快速调试即刻的运行错误并通过 Python 工具进行整合
  • 借助易于使用的 Python 控制流支持动态模型
  • 为自定义和高阶梯度提供强大支持
  • 适用于几乎所有可用的 TensorFlow 运算


Eager Execution 现在处于试用阶段,因此我们希望得到来自社区的反馈,指导我们的方向。


为了更好地理解 Eager Execution,下面让我们看一些代码。它很技术,熟悉 TensorFlow 会有所帮助。


使用 Eager Execution


当你启动 Eager Execution 时,运算会即刻执行,无需 Session.run() 就可以把它们的值返回到 Python。比如,要想使两个矩阵相乘,我们这样写代码:


import tensorflow as tf import tensorflow.contrib.eager as tfe tfe.enable_eager_execution() x = [[2.]] m = tf.matmul(x, x)


使用 print 或者 Python 调试器检查中间结果非常直接。


print(m) # The 1x1 matrix [[4.]]


动态模型的构建可使用 Python 控制流。下面是使用 TensorFlow 算术操作的考拉兹猜想(Collatz conjecture)的一个示例:


a = tf.constant(12) counter = 0 while not tf.equal(a, 1):  if tf.equal(a % 2, 0):    a = a / 2  else:    a = 3 * a + 1  print(a)


这里,tf.constant(12) 张量对象的使用将把所有数学运算提升为张量运算,从而所有的返回值将是张量。


梯度


多数 TensorFlow 用户对自动微分(automatic differentiation)很感兴趣。因为每次调用都有可能出现不同的运算,可以理解为我们把所有的正向运算录到「磁带」上,然后在计算梯度时进行「倒放」。梯度计算完成后,「磁带」就没用了。

如果你熟悉 autograd 包,我们提供的 API 与之非常类似。例如:


def square(x):  return tf.multiply(x, x) grad = tfe.gradients_function(square) print(square(3.))    # [9.] print(grad(3.))      # [6.]


gradients_function 的调用使用一个 Python 函数 square() 作为参数,然后返回 Python callable,用于计算输入的 square() 偏导数。因此,为了得到输入为 3.0 时的 square() 导数,激活 grad(3.0),也就是 6。

同样的 gradient_function 调用可用于计算 square() 的二阶导数。


gradgrad = tfe.gradients_function(lambda x: grad(x)[0]) print(gradgrad(3.))  # [2.]


如前所述,控制流(control flow)会引起不同的运算,下面是一个示例:


def abs(x):  return x if x > 0. else -x grad = tfe.gradients_function(abs) print(grad(2.0))  # [1.] print(grad(-2.0)) # [-1.]


自定义梯度


用户或许想为运算或函数自定义梯度。这可能有用,原因之一是它为一系列运算提供了更高效、数值更稳定的梯度。

下面的示例使用了自定义梯度。我们先来看函数 log(1 + e^x),它通常用于计算交叉熵和 log 似然。


def log1pexp(x):  return tf.log(1 + tf.exp(x)) grad_log1pexp = tfe.gradients_function(log1pexp) # The gradient computation works fine at x = 0. print(grad_log1pexp(0.)) # [0.5] # However it returns a `nan` at x = 100 due to numerical instability. print(grad_log1pexp(100.)) # [nan]


我们可以将自定义梯度应用于上述函数,简化梯度表达式。注意下面的梯度函数实现重用了前向传导中计算的 (tf.exp(x)),避免冗余计算,从而提高梯度计算的效率。


@tfe.custom_gradient def log1pexp(x):  e = tf.exp(x)  def grad(dy):    return dy * (1 - 1 / (1 + e))  return tf.log(1 + e), grad grad_log1pexp = tfe.gradients_function(log1pexp) # Gradient at x = 0 works as before. print(grad_log1pexp(0.)) # [0.5] # And now gradient computation at x=100 works as well. print(grad_log1pexp(100.)) # [1.0]


建立模型


模型可以分成几类。此处我们要提的模型可以通过创建一个简单的两层网络对标准的 MNIST 手写数字进行分类。


class MNISTModel(tfe.Network):  def __init__(self):    super(MNISTModel, self).__init__()    self.layer1 = self.track_layer(tf.layers.Dense(units=10))    self.layer2 = self.track_layer(tf.layers.Dense(units=10))  def call(self, input):    """Actually runs the model."""    result = self.layer1(input)    result = self.layer2(result)    return result


我们推荐使用 tf.layers 中的类别(而非函数),这是因为它们创建并包含了模型参数(变量,variables)。变量的有效期和层对象的有效期紧密相关,因此需要对它们进行追踪。

为什么要使用 tfe.Network?一个网络包含了多个层,是 tf.layer.Layer 本身,允许将 Network 的对象嵌入到其它 Network 的对象中。它还包含能够协助检查、保存和修复的工具。

即使没有训练模型,我们也可以命令式地调用它并检查输出:


# Let's make up a blank input image model = MNISTModel() batch = tf.zeros([1, 1, 784]) print(batch.shape) # (1, 1, 784) result = model(batch) print(result) # tf.Tensor([[[ 0.  0., ...., 0.]]], shape=(1, 1, 10), dtype=float32)


注意我们在这里不需要任何的占位符或会话(session)。一旦数据被输入,层的参数就被设定好了。


训练任何模型都需要定义一个损失函数,计算梯度,并使用一个优化器更新参数。首先定义一个损失函数:


 def loss_function(model, x, y):  y_ = model(x)  return tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=y_)


然后是训练的循环过程:


optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001) for (x, y) in tfe.Iterator(dataset):  grads = tfe.implicit_gradients(loss_function)(model, x, y)  optimizer.apply_gradients(grads)


implicit_gradients() 计算损失函数关于计算使用的所有 TensorFlow 变量的导数。


我们可以按往常使用 TensorFlow 的方式将计算转移到 GPU 上:


with tf.device("/gpu:0"):  for (x, y) in tfe.Iterator(dataset):    optimizer.minimize(lambda: loss_function(model, x, y))

(注意:我们简化然后保存损失损失函数并直接调用 optimizer.minimize,但你也可以使用上面的 apply_gradients() 方法,它们是等价的。)


使用 Eager 和 Graphs


Eager execution 使开发和调试互动性更强,但是 TensorFlow graph 在分布式训练、性能优化和生产部署中也有很多优势。


启用 eager execution 时,执行运算的代码还可以构建一个描述 eager execution 未启用时的计算图。为了将模型转换成图,只需要在 eager execution 未启用的 Python session 中运行同样的代码。示例:http://ift.tt/2zX45eK eager(命令式)和 graph(声明式)编程之间轻松转换。这样,启用 eager execution 开发出的模型可以轻松导出到生产部署中。


在不久的将来,我们将提供工具,可以选择性地将模型的某些部分转换成 graph。用这种方式,你就可以融合部分计算(如自定义 RNN 细胞的内部)实现高性能,同时还能保持 eager execution 的灵活性和可读性。


如何改写我的代码?


Eager execution 的使用方法对现有 TensorFlow 用户来说应是直观的。目前只有少量针对 eager 的 API;大多数现有的 API 和运算需要和启用的 eager 一起工作。请记住以下内容:


一般对于 TensorFlow,我们建议如果你还没有从排队切换到使用 tf.data 进行输入处理,请抓紧做。它更容易使用,也更快。查看这篇博文(http://ift.tt/2htRc51


使用目标导向的层(比如 tf.layer.Conv2D() 或者 Keras 层),它们可以直接存储变量。你可以为大多数模型写代码,这对 eager execution 和图构建同样有效。也有一些例外,比如动态模型使用 Python 控制流改变基于输入的计算。一旦调用 tfe.enable_eager_execution(),它不可被关掉。为了获得图行为,需要建立一个新的 Python session。


开始使用


这只是预发布,还不完善。如果你想现在就开始使用,那么:


  • 安装 TensorFlow 的 nightly 版本(http://ift.tt/2zX3Lg4
  • 查看 README(包括 known issues),地址:http://ift.tt/2z1h6qH
  • 从 eager execution 用户指南(http://ift.tt/2huNd8z
  • 在 GitHub 中查看 eager 示例(http://ift.tt/2zVASRs
  • 及时查看变更日志(http://ift.tt/2hue4l0


性能测试


Eager Execution 目前仅处于开发的前期,它的性能究竟如何?Google Brain 的工程师 Yaroslav Bulatov 对这一新工具做出了评测。TensorFlow 此前最令人诟病的问题就是它必须将计算定义为静态图。


我们在谷歌大脑的工作之一就是解决这类需求,并最终以命令式版本开源。但是这依赖于私有/不稳定的 API,而且这些 API 的维护成本会越来越高昂。幸运的是,PyTorch 满足了研究员的需求,并且如今的 TensorFlow 也官方支持执行模式而不需要定义图。


目前,Eager Execution 仍在积极开发中,但在最近发布的可用版本非常有用,我们可以试用一下:


pip install tf-nightly-gpu python from tensorflow.contrib.eager.python import tfe tfe.enable_eager_execution() a = tf.random_uniform((10,)) b = tf.random_uniform((10,)) for i in range(100):  a = a*a  if a[0]>b[0]:  break print(i)


请注意,此操作并不需要处理图,Session 就可以立即执行。若想应用 GPU 加速,请先将 tensor 拷贝至指定设备。


a = a.gpu() # copies tensor to default GPU (GPU0) a = a.gpu(0) # copies tensor to GPU0 a = a.gpu(1) # copies tensor to GPU1 a = a.cpu() # copies tensor back to CPU


端口命令代码


你可以将一个已有的 numpy/pytorch/matlab 的命令式代码重写成正确的 API 调用。例如,


torch.sum -> tf.reduce_sum」 array.T -> tf.transpose(array) 等


我已使用 PyTorch 实现的 l-BFGS 作为练习,第一次在 GPU 上并行跑两个实验时(PyTorch & Eager),我得到前 8 位小数相同的结果。这使我大吃一惊,前所未闻。



使用已有的基于图的代码


如果你的代码不依赖于特定的 API,例如 graph_editor,你可以使用现有的代码并在 eager execution 模式下运行。


还有一个实验性的函数「graph_callable」,可以将任意 tensorflow 子图作为一个可以调用的函数。它仍然处于开发阶段,但我能得到一个有效的例子来说明,该例子将 tensorflow /models 中的 resnet_model 包装成一个 graph_callable。下面是一个随机批大小训练这个模型的例子。

一旦该功能上线,它应该有助于提高程序性能,具体可参考下文的性能部分。


拓展了梯度


原始 tf.gradients_function 的新衍生版本反映了autograd 的梯度。你可以调用在一个已有函数内调用「gradients_function」N 次获得 N 阶导数,即


# expensive way to compute factorial of n def factorial(n):  def f(x):    return tf.pow(x, n)  for i in range(n):    f = tfe.gradients_function(f)  return f(1.)


还有一个原始「custom_gradient」函数,这使得创建自定义梯度更容易。例如,假设我们想要平方函数,但在后向传播时增加了噪声。


@tfe.custom_gradient def noisy_square(x):   def grad(b):       true_grad = 2*b*x       return true_grad+tf.random_uniform(())    return (x*x), grad grad = tfe.gradients_function(noisy_square) x = 2. points = [] for i in range(20):   x -= .9*grad(x)[0]   print(x, loss(x))


效果如下:



你会看到版本二收敛更慢,但是一旦收敛,它的泛化能力更好。


这种梯度修正对于实现如 KFAC 的高级优化算法时十分有用。想想我早期所讲,KFAC 在简单网络中相当于激活函数和反向传播值白化的梯度下降。


这就可以理解为梯度在其两边乘上了白化的矩阵


假设你已经将这些矩阵保存为 m1,m2,那么你自定义的乘操作可以是这样的:


@tfe.custom_gradient def kfac_matmul(W, A):   def grad(B):       true_grad1 = B @ tf.transpose(A)       true_grad2 = tf.transpose(W) @ B    return [m1 @ true_grad1 @ m2, true_grad2] return W @ A, grad


注意,true_grad1, true_grad2 函数是乘法操作的反向传播实现,请参考 Mike Giles 的第 4 页「An extended collection of matrix derivative results for forward and reverse mode algorithmic differentiation」(http://ift.tt/2huYbL7)

你可以通过使用 kfac_matmul 替代采用梯度下降算法恢复原来的 kfac,或者你可以尝试新的变种方法,利用动量和 Adam。


这里(http://ift.tt/2zX3MAE Eager execution 模式下的 KFAC 样例。


性能


Eager Execution 模式使你的程序执行慢一点或慢很多的程度取决于你的计算高运算强度的卷积还是矩阵相乘。


做纯矩阵乘法(超过 1 毫秒的时间)是没有太大的差别,无论你用 tensorflow 快速模式,pytorch 或 tensorflow 经典模式。



另一方面,端到端的例子更易受影响。


在测试中,当运行环境设置为 O(n^(1.5)) 操作,如 matmul/conv 时,Eager Execution 的速度要比 PyTorch 慢 20%,或者在大量 O(n) 操作如矢量添加的例子中,比 PyTorch 慢 2-5 倍。


作为一个简单的例子,我们使用吴恩达提出的 UFLDL 来训练 MNIST 自编码器。在批尺寸=60k,I-BFGS 的 history=5 时,大量的计算效能都被花在了自编码器正向传播上,Eager 的版本要比 PyTorch 慢 1.4 倍。


在批尺寸为 60k,I-BFGS 的 history=100 的设置下,两个回环在每一步 I-BFGS(点积和向量增加)中执行「两步递归」,Eager 版本的模型速度降低了 2.5 倍,而 PyTorch 仅受轻微影响。


最后,如果我们将批尺寸减少到 10k,我们可以看到每次迭代的速度都要慢 5 倍,偶尔甚至会慢 10 倍,这可能是因为垃圾回收策略造成的。


结论


虽然目前 Eager Execution 的表现还不够强大,但这种执行模式可以让原型设计变得容易很多。对于在 TensorFlow 中构建新计算任务的开发者而言,这种方式必将很快成为主流。


原文地址:

http://ift.tt/2yj8gFu

http://ift.tt/2ihiECC



]]> 原文: http://ift.tt/2huDsXE
RSS Feed

机器知心

IFTTT

入职仅一年,套现5000多万后背刺马斯克搬走 Grok 核心代码库!-InfoQ 每周精要894期

「每周精要」 NO. 894 2025/09/06 头条 HEADLINE 入职仅一年,套现 5000 多万搬走 Grok 核心代码库! 业内专家:拥有菜谱不等于能做出同样的菜 精选 SELECTED AI 公司创始人现跑路迪拜! 80% 收入烧广告、假账骗投资人,微...