机器学习导图系列(1):数据处理

机器学习导图系列教程旨在帮助引导开发者对机器学习知识网络有一个系统的概念,其中具体释义并未完善,需要开发者自己探索才能对具体知识有深入的掌握。本项目灵感来自Daniel Formoso的github开源项目。本文作者对其项目进行翻译、整理、批注等二次创作,其中不乏生僻的数学名词,对于没有留过学的作者来说费了很多功夫。我又将导图整理成了知识卡片,方便大家查看。由于机器学习的知识网络很大,导致完整的导图过大,文章中的图片可能经过压缩,如需完整图片可查看github项目machine-learning-mindmap-cn下载高清原图。本系列还在持续创作中,你的点赞、留言、star都会成为我持续创作的动力。Daniel Formoso: https://github.com/dformoso/m...machine-learning-mindmap-cn: https://github.com/caiyongji/…机器学习导图系列分为五大模块。机器学习数据处理机器学习概念机器学习过程机器学习算法机器学习模型及神经网络模型数据类型数据探索数据清洗特征插补特征工程特征选择特征编码特征归一化(Normalisation)或缩放(Scaling)构造数据集最后你随手就是一个赞。

April 7, 2019 · 1 min · jiezi

一文纵览自然语言生成的发展

摘要: 从马尔科夫链到Transformer,本文带您纵览自然语言生成的发展。人们对人工智能的兴趣随着科幻电影的诞生和发展变得愈发浓厚。每当我们听到“人工智能”这个词,便会联想到《终结者》、《黑客帝国》、《我,机器人》等电影。机器人具有独立思考的能力在目前看来还比较遥远,但机器学习和自然语言理解领域已经在过去几年取得了重大进展。个人助理(Siri/Alexa)、聊天机器人及问答机器人等应用程序正悄无声息地改变着人们的生活方式。人们需要理解大量有歧义且结构多变的语言并从中获取意义,这促使自然语言理解(Natural Language Understanding,NLU)和自然语言生成(Natural Language Generation, NLG)成为人工智能中发展最快的应用。Gartner预测,“到2019年,自然语言生成将是90%的现代BI和分析平台的标准特征”。本文将回顾NLG的历史,并展望其未来。什么是NLG?NLG通过预测句子中的下一个单词传达信息。使用语言模型能够预测下一个可能出现的单词,也就是找到单词在序列中的概率分布。举个例子,预测“I need to learn how to __”的下一个单词,语言模型会计算下一个单词,如“write”,“drive”可能出现的概率。RNNs及LSTMs等高级神经网络能够处理较长的句子,提高了语言模型预测的准确性。马尔可夫链(Markov Chains)马尔可夫链是最早用于语言生成的算法。它通过当前单词预测句子中的下一个单词。举个例子,模型通过下面两个句子进行训练,“I drink coffee in the morning”和“I eat sandwiches with tea”。“drink”后面出现“coffee”的概率是100%,“I”后面出现“eat”和“drink”的概率分别为50%。马尔可夫链在计算下一个单词出现概率的时候,会把每个单词之间的关系考虑进去。该模型最早用于为智能手机输入句子提供下一个单词生成建议。但由于仅注意当前单词,马尔可夫模型无法探测当前单词与句子中其它单词的关系以及句子的结构,使得预测结果不够准确,在许多应用场景中受限。循环神经网络(Recurrent Neural Network, RNN)神经网络启发于人类大脑的工作原理,通过对输入和输出数据之间的非线性关系进行建模,为计算提供了一种新的方法,用于语言建模即称为神经语言建模。RNN是神经网络的一种,它能够捕捉输入数据的序列特征。通过前馈网络处理序列中的每一个item,并将模型的输出作为序列的next item,此过程能够帮助存储前面每步的信息。这样的“记忆”使得RNN在语言生成中有着出色的表现,因为记住过去的信息能够帮助更好的预测未来。与马尔可夫链不同的是,在进行预测时,RNN不仅关注当前单词,还关注已经处理过的单词。利用RNN进行语言生成在RNN的每一次迭代中,模型都能在其“记忆”单元中存储出现过的单词,以及计算下一个单词出现的概率。举个例子,有“We need to rent a __”,此时要预测句子中的下一个单词。模型能够记住在词典中每个单词随前面单词出现的概率。在上述例子中,“house”或者“car”比“river”和“dinner”有着更高的出现概率。“记忆”单元选择概率更高的单词,并对其进行排序,然后进行下一次迭代。但RNN有一个很大的问题——梯度消失。随着序列长度的增加,RNNs不能存储那些很久前遇到的单词,便只能根据最近的单词进行预测。这使得RNNs无法应用于生成连贯的长句子。长短期记忆网络(Long Short-Term Memory, LSTM)长短期记忆网络是RNNs的变体,比vanilla RNNs更适合处理长序列。LSTM应用广泛,其与RNNs的结构类似。不同的是,RNNs只有一个简单的层结构,而LSTM内部有4个层结构。一个LSTM由4部分组成:cell,输入门,输出门以及遗忘门。利用LSTM进行语言生成示例,输入句子为“I am from Spain. I am fluent in ___”。为了正确预测出下一个单词“Spanish”,LSTM会更加关注上一句中的“Spain”并且利用cell对其进行记忆。在处理序列时cell会对获取的信息进行存储,这些信息会用于预测下一个单词。当遇到句号时,遗忘门会意识到句子中的上下文发生了改变,并忽略当前cell中存储的状态信息,换句话说,遗忘门的作用是让循环神经网络“忘记”之前没有用到的信息。LSTM及其变体能够解决梯度消失问题并生成连贯的句子。但是,LSTM也有其局限性:计算要求高,难以训练。TransformerTransformer在2017年,由Google团队在论文《Attention Is All You Need》中首次提出,并涉及到一种名为“self-attention mechanism”的新方法。Transformers目前广泛用于解决NLP问题,例如语言建模,机器翻译以及文本生成等。Transformer模型由一组编码器和一组解码器组成,前者负责处理任意长度的输入,后者负责输出生成的句子。在上述示例中,编码器处理输入句子,并为其生成表示。解码器利用表示生成用于输出的句子。每个单词最初的表示或嵌入由空心圆表示。接下来,Transformer模型利用self-attention机制获取所有其他单词之间的关系,生成每个单词的新表示,如图中的实心圆。对每个单词重复该步骤,连续生成新的表示,类似地,解码器从左往右依次生成单词。与LSTMs不同的是,Transformer需要的步骤少,应用self-attention机制能够在不考虑单词位置的情况下,直接捕捉句子中所有单词之间的关系。最近,许多研究学者对vanilla transformer模型进行了改进,提升了速度与精度。在2018年,谷歌提出BERT模型,此模型在各种NLP任务中均取得了最先进的结果。在2019年,OpenAI发布了一个基于transformer的语言模型,只需要输入几行文本就可以生成长篇文章。利用Transformers进行语言生成Transformer模型同样可以用于语言生成,最著名的要数OpenAI提出的GPT-2语言模型。该模型通过将注意力集中在与预测下一个单词相关的单词上,更好的学习并预测句子中的下一个单词。使用Transformer进行文本生成与机器翻译所遵循的结构类似。举个例子,“Her gown with the dots that are pink, white and ____”。通过利用self-attention机制对前面所出现的颜色(白色和粉色)进行分析,理解需要预测的单词也是一种颜色,此时模型的输出为“blue”。Self-attention能够帮助模型选择性地关注每一个单词在句子中担任的角色,而不仅仅是通过循坏记住些许特征。语言生成的未来本文带我们纵览了语言生成的发展,从利用马尔可夫链预测下一个单词,到使用self-attention生成连贯的文章。但是,我们仍处于生成语言建模的初期,今后还会往自主生成文本的方向迈进。生成模型也将用于图像、视频、音频等内容的开发。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 25, 2019 · 1 min · jiezi

100行Python代码理解深度学习关键概念:从头构建恶性肿瘤检测网络

摘要: 100行Python代码理解深度学习关键概念!在构建乳腺癌预测神经网络过程中,我们主要分为3大部分:1.用Python从零开始创建一个神经网络,并使用梯度下降算法训练模型。2.在该神经网络中使用威斯康星乳腺癌数据集,根据9种不同的特征,预测肿瘤是良性还是恶性的。3.探索反向传播和梯度下降算法的工作原理。在这个领域中,有很多大牛都通过视频和博文分享了自己掌握的专业知识,如fast.ai的Jeremy Howard、吴恩达、Andrej Karpathy、Yann Lecun等等。他们一致认为,深度学习的关键之一就是,尽快亲自动手编写一个深度学习的模型。当前,深度学习领域中有很多强大的库可供我们使用,如Tensorflow、 PyTorch、 Fast.ai、 Keras、 Mxnett、Nctk、DL4J 等。如果仅仅直接使用这些强大的库,我们可能会错过很多关键的东西,因此,我们需要进一步思考这些进程中最重要的那部分。如果能自己亲自动手编码创建一个神经网络,我们就不得不面对创建过程中出现的一些问题和障碍,挖掘深度学习背后隐藏的那些令人惊叹的知识。当前,深度学习领域中有各种各样的架构和开发:卷积神经网络、循环神经网络和生成对抗网络等等。在这些不同种类的网络背后,都包含了两个相同的算法:反向传播算法和梯度下降算法。探索神秘的函数宇宙中的很多事物都可以用函数表示。本质上来说,函数是一种数学结构,接受一个输入并产生一个输出,表示因果关系、输入输出关系。当我们审视周围的世界时,会接收到很多信息,我们将这些信息转化为数据,就可以从这些数据中学到很多知识。在利用这些数据进行学习的时候,会有很多不同的种类。通常来说,深度学习中有三种最常见的类型:1.监督学习:从一组有标签(已分类)的训练数据中学习函数,输入和输出是成对的数据集。2.非监督学习:从没有任何标签或分类的数据中学习到函数。3.强化学习:代理人会在特定环境中做出相应的动作,通过最大化代理人得到的奖励得到函数。监督学习本文中,我们主要关注监督学习。现在,我们有一个数据集,包含输入及对应的输出。下面,我们想了解这些输入和输出是如何通过一个神秘的函数联系起来的。当数据集达到一定的复杂度时,寻找这个函数的难度就相当大。因此,我们就需要使用神经网络和深度学习,来探索这个神秘的函数。本质上来说,神经网络通过一系列的中间“权重”连接我们的输入和期望输出数据。这些权重实际上就是一些数字。当我们使用正确的架构和参数,通过神经网络的结构和优化算法,我们可将神经网络近似成一个通用函数近似器,将输入和输出数据联系起来。创建一个神经网络一般来说,简单的神经网络包括两层(输入不计入层数):1.输入:神经网络的输入包含了我们的源数据。并且,神经元的数量与源数据的特征数量相匹配。下图中有4个输入,当我们使用威斯康星乳腺癌数据集创建神经网络的时候,就会使用9个输入。2.第一层:隐藏层,包含一些隐藏层神经元,这些神经元将会与周围层中的所有单元相连接。3.第二层:有一个单元,为神经网络的输出。在实际的神经网络构建过程中,我们可以使用更多的层,比如10个或20个层的网络。为了简单起见,在这里,我们使用2个层。千万不要小看这2个层,它能够实现很多功能。神经网络如何进行学习问题来了:在这个神经网络中,学习将在哪个部分进行?我们来回顾一下,我们在神经网络的输入层放置了一些数据,并向网络展示某个输入应该对应什么输出,也就是说,神经网络的输出(第2层)应该是什么结果。在神经网络中,每个神经元都有一个相关的权重以及一个偏差。这些权重只是神经网络在开始学习时候初始化的一些随机数字。神经网络根据输入数据和这些权重值进行计算,通过神经网络传播,直到输出产生最终的结果。这些计算的结果就是一个将输入映射到输出的函数。我们需要的就是,这些神经网络能够计算出一个最佳权重值。因为网络通过计算,不同的权重和不同的层结合起来,会近似出不同类型的函数。现在,我们来进一步探索正在探寻的函数。为了方便阅读,我们需要解释下这些变量的名称:1.X表示输入层,即提供给网络的数据集。2.Y表示与输入x对应的目标输出,由输入经过网络进行一系列的计算得到的输出。3.Yh(y hat)表示预测函数,即我们像网络提供输入数据集x后,经过神经网络一系列的计算产生的输出。因此,Y是理想的输出,Yh是神经网络接收到输入数据后产生的实际输出。4.W表示网络各层的权重。我们首先看第一层——隐藏层,它执行了一个运算WX(即W和X的乘积)。然后进行一个加权和:1.这一层中的每个单元都和前一层中的每个单元相连接。2.权重值存在于每个连接中。3.该层中每个单元的值都是由前一个层中每个单元的值权重的总和,而该权重则是1中所得到的权重。从某种程度上来说,权重表示连接的强度,即:不同层之间单元连接的强度。现在,我们要在这个架构中添加一个额外的量——偏差:WX+b。这个偏差能够给神经网络带来更多的灵活性,偏差允许网络“移动”单位的线性计算,加强网络学习这些函数的能力。b代表单位偏差项。我们看到,WX+b就是一个线性方程,通过乘积与和运算表示输入和输出的线性关系。现在,我们的神经网络只有2层,但是请记住,一个神经网络可以有很多层,比如20个甚至200个。因此,我们用数字表述这些变量属于哪一层。这样一来,定义隐藏层(第1层)的线性方程则为:W1X+b1,并为其输出命名为Z,表示某一层计算的输出。因此,我们得到如下方程:Z1=W1X+b1注意,这个计算应该针对每个层的每个单元进行。当我们为神经网络编写代码的时候,我们将使用向量化编程,也就是说,利用矩阵将某一层的所有计算放在一个单一的数学运算中。上面所讲述的是只有一个层的神经网络。现在,我们考虑一个有很多层的神经网络,每个层执都执行一个类似上面的线性运算,当所有的线性运算连接在一起时,这个神经网络就能够计算复杂的函数了。激活函数然而,现在就有一个问题:线性函数——太简单了吧。这个世界是复杂的,因此,线性函数远远满足不了实际需求。一般来说,复杂的函数往往都是非线性的。而且,如果神经网络的架构仅仅由线性函数计算,那么就很难计算非线性行为。这就是为什么我们要在神经网络的每一层末尾加上一个额外的量:激活函数。现在,我们介绍4个最典型的例子。为了方便我们后续对激活函数进行深入探索,首先需要介绍梯度这一概念。一个函数在某一点上的梯度也称为函数的导数,表示该函数在该点输出值的变化率。我们来思考这样一个问题:当特定输入发生变化时,函数的输出会发生怎样的变化?当梯度(导数)非常小,即函数的输出变化非常平坦时,我们称之为梯度消失。在后边的反向传播算法中,我们可以通过梯度了解网络中每个参数将会如何影响网络的输出,从而就能够决定如何调整网络的权值,也就是说了解这个参数的变化将会使网络的输出增加还是减少?梯度消失是我们所面临的一个问题,因为如果某一点的梯度变化很小或趋于0,我们就很难确定该神经网络在该点的输出方向。当然,我们也会遇到相反的情况——梯度爆炸。当梯度值非常大时,神经网络可能就会变得非常不稳定。不同的激活函数有各自的优点,但是都会面临梯度消失和梯度爆炸这两大问题。左上:Sigmoid激活函数;右上:Tanh激活函数;左下:Relu激活函数;右下:Leaky Relu激活函数(1)Sigmoid激活函数——1/(1+e-x)1.输出范围:[0,1]。2.非线性,输出为两个极端变量0和1。适用于二分类问题。3.曲线变化温和,因此,梯度(导数)比较容易控制。4.该激活函数的主要缺点为:在极端情况下,函数的输出曲线变得非常平坦,也就是说,函数的导数(变化率)将变得非常小,在这种情况下,Sigmoid激活函数的计算效率和速度将会非常低,甚至会完全没效率。5.当Sigmoid激活函数出现在神经网络的最后一层时,将会特别有用,因为Sigmoid激活函数有助于将输出变为0或1(即二分类问题)。如果将Sigmoid激活函数放在神经网络的其他层,就会出现梯度消失问题。(2)Tanh激活函数——(2/(1+e-2x))-11.输出范围:[-1,1]。2.曲线和Sigmoid激活函数的曲线类似,是Sigmoid激活函数曲线的缩小版。3.Tanh激活函数曲线较为陡峭,因此,该激活函数的导数(变化率)比较大。4.Tanh激活函数的缺点与Sigmoid激活函数类似。(3)Relu激活函数——max (0,x)1.如果输入大于0,那么,输出值等于输入值;否则,输出为0。2.Relu激活函数的范围是[0,+∞),这就意味着输出可能是+∞,可能会存在梯度爆炸问题。3.优点:使神经网络轻量化,因为一些神经元可能输出为0,防止所有的神经元被同时激活。4.Relu激活函数存在一个问题,即输入为0的时候,输出全部为0,这将会导致梯度为0,会让我们忽视某些神经元的一些有用的计算。5.Relu激活函数计算简单,成本低廉。6.当前,Relu激活函数是神经网络内层最经常使用的激活函数。(4)Leaky Relu激活函数——ex / Sum(ex)1.输出范围:[0,1]2.Leaky Relu激活函数将输入进行标准化处理为一个概率分布。3.通常用于多分类场景中的输出层。在这里,我们在输出层使用Sigmoid激活函数,在隐藏层使用Relu激活函数。好了,现在我们已经理解了激活函数,那么,就需要对其进行命名!A:表示激活函数的输出。因此,在神经网络的隐藏层中,将会进行如下计算:A1=Relu(Z1)Z1=W1X+b1在第二层的输出层中,将会进行如下计算:A2=Sigmoid(Z2)Z2=W2A1+b2请注意,第二层(输出层)的输入为第一层的输出,即A1。第二层的输出就是网络的最终输出。将上面的计算归纳一下,就得到2层神经网络所执行的全部计算:Yh = A2 = Sigmoid(W2ReLU (W1X+ b1) + b2 )因此,本质上来说,神经网络是一连串的函数,有些是线性函数,有些是非线性函数,它们共同组成了一个复杂的函数,将我们的输入数据和想要的输出数据连接了起来。现在,我们注意到,在这个方程的所有变量中,W和b是两个未知数,这就是神经网络需要学习的地方。也就是说,神经网络必须进行不断的学习,找到W和b的正确值,才能计算出正确的函数。因此,我们训练神经网络的目的也变得明了了,即寻找W1,b1,W2,b2的正确值。但是,在开始训练神经网络之前,我们必须首先对这些值进行初始化,即用随机函数对其进行初始化处理。初始化以后,我们就可以对神经网络进行编码,我们使用Python构建一个类,对这些主要的参数进行初始化处理。我们将如何进行实战编码呢?请继续阅读我们的第二部分:用Python构建一个神经网络。一站式开发者服务,海量学习资源0元起!阿里热门开源项目、机器学习干货、开发者课程/工具、小微项目、移动研发等海量资源;更有开发者福利Kindle、技术图书幸运抽奖,100%中–》https://www.aliyun.com/acts/product-section-2019/developer?utm_content=g_1000047140本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 19, 2019 · 1 min · jiezi

2019五个最棒的机器学习课程

摘要: 爱学习的朋友们,你们的福利来了!2019五个最棒的机器学习课程!!凭借强大的统计学基础,机器学习正在成为最有趣,节奏最快的计算机科学领域之一,目前已经有无穷无尽的行业和应用正在使用机器学习使它们更高效和智能。聊天机器人、垃圾邮件过滤、广告投放、搜索引擎和欺诈检测是机器学习模型正在实际应用于日常生活的几个例子。机器学习到底是什么呢?我认为机器学习是让我们找到模式并为人类无法做的事情创建数学模型。机器学习课程与包含探索性数据分析,统计,通信和可视化技术等主题的数据科学课程不同,它更侧重于教授机器学习算法,如何以数学方式工作,以及如何在编程语言中使用它们。以下是今年五大机器学习课程的简要回顾。最好的五个机器学习课程:1. 机器学习-Coursera2. 深度学习专项课程-Coursera3. 使用Python进行机器学习-Coursera4. 高级机器学习专项课程-Coursera5. 机器学习-EdX什么是一个非常好的机器学习课程?标准:上面的每门课程都遵循以下标准:严格关注机器学习;使用免费的开源编程语言,即Python,R或Octave;这些开源的语言都有很多免费的开源库;包含练习和实践经验的编程任务;解释算法如何以数学方式工作;有吸引力的讲师和有趣的讲座;有了这个标准,很多课程都会被淘汰,为了让自己沉浸其中并尽可能快速全面地学习ML,我相信除了在线学习之外,你还应该寻找各种书籍。以下是两本对我的学习经历产生重大影响的书籍。两本优秀的书籍伴侣除了参加下面的任何视频课程,如果你对机器学习还不熟悉,你应该考虑阅读以下书籍:统计学习简介,可在线免费获取。本书提供了令人难以置信的清晰直接的解释和示例,以提高你对许多基本机器学习技术的整体数学直觉。而去更多地是关于事物的理论方面,但它确实包含许多使用R编程语言的练习和例子。使用Scikit-Learn和TensorFlow进行动手机器学习,可通过Safari订阅获得。这是对前一本书的一个很好的补充,因为本文主要关注使用Python进行机器学习的应用。本书将强化你的编程技巧,并向你展示如何立即将机器学习应用于项目。现在,让我们来看看课程描述和评论。1:机器学习 - Coursera此课程的创作者是Andrew Ng,一个斯坦福大学教授,谷歌大脑、Coursera的创始人之一。本课程使用开源编程语言Octave而不是Python或R进行教学。对于某些人来说,这可能是不太友好,但如果你是一个完整的初学者,Octave实际上是一种最简单学习ML基础知识的方法。总的来说,课程材料非常全面,并且由Ng直观地表达,该课程完整地解释了理解每个算法所需的所有数学,包括一些微积分解释和线性代数的复习,课程相当独立,但事先对线性代数的一些了解肯定会有所帮助。提供者:Andrew Ng,斯坦福大学费用:免费审核,证书79美元课程结构:单变量的线性回归回顾线性代数多变量的线性回归Octave/Matlab教程Logistic回归正则化神经网络:表示神经网络:学习应用机器学习的建议机器学习系统设计支持向量机降维异常检测推荐系统大规模机器学习应用示例:Photo OCR如果你可以承诺完成整个课程,你将在大约四个月内掌握机器学习的基础知识。之后,你可以轻松地进入更高级或专业的主题,如深度学习,ML工程或任何其他引起你兴趣的话题。毫无疑问,这是新手开始的最佳课程。2:深度学习专项课程-Coursera同样由Andrew Ng教授,这是一个更高级的课程系列,适合任何有兴趣学习神经网络和深度学习的人。每门课程的作业和讲座都使用Python编程语言,并将TensorFlow库用于神经网络。这第一个机器学习课程的很好的后续,因为你现在将接触使用Python进行机器学习。提供者:Andrew Ng,deeplearning.ai费用:免费审核,证书每月49美元课程结构:1. 神经网络与深度学习深度学习简介神经网络基础知识浅层神经网络深度神经网络2. 改进神经网络:超参数调整,正则化和优化深度学习的实践方面优化算法超参数调整,批量标准化和编程框架3. 构建机器学习项目ML策略(1)ML策略(2)4. 卷积神经网络卷积神经网络的基础深度卷积模型:案例研究物体检测特殊应用:人脸识别和神经风格转移5. 序列模型递归神经网络自然语言处理和Word嵌入序列模型和注意机制为了理解本课程中介绍的算法,你应该熟悉线性代数和机器学习。如果你需要一些建议来获取所需的数学,请参阅本文末尾的学习指南。3:使用Python进行机器学习-Coursera这是另一个初学者课程,这个课程仅关注最基本的机器学习算法。本课程使用Python教学,并且对数学的要求不是很高。通过每个模块,你将有机会使用交互式Jupyter笔记本来完成你刚学过的新概念。每个笔记本都增强了你的知识,并为你提供了在实际数据上使用算法的具体说明。提供者:IBM价格:免费审核,证书每月39美元课程结构:机器学习简介回归分类聚类推荐系统项目本课程最好的一点是为每种算法提供实用的建议。当引入新算法时,老师会向你提供它的工作原理,它的优点和缺点,以及你应该使用它的哪种情况。这些点经常被排除在其他课程之外,这些信息对于新学员来说非常重要。4:高级机器学习专项课程-Coursera这是另一个高级系列课程,涉及了非常多的网络类型。如果你有兴趣尽可能多地使用机器学习技术,这个课程很关键。本课程的教学非常棒,由于其先进性,你需要学习更多的数学。本课程涵盖的大部分内容对许多机器学习项目至关重要。提供者:国立研究大学高等经济学院成本:免费审核,每月49美元的证书课程:1. 深度学习简介优化简介神经网络简介深度学习图像无监督表示学习Dee学习序列项目2. 如何赢得数据科学竞赛:向顶级Kagglers学习介绍和回顾关于模型的特征处理和生成最终项目描述探索性数据分析验证数据泄漏度量标准优化高级特征工程-1超参数优化高级特征工程-2Ensembling项目3. 机器学习的贝叶斯方法贝叶斯方法和共轭先验的介绍期望最大化算法变分推断和潜在Dirichlet分配(LDA)马尔可夫链蒙特卡洛变分自动编码器高斯过程和贝叶斯优化项目4. 实践强化学习简介:我为什么要关心?RL的核心:动态编程无模型方法基于近似值的方法基于政策的方法探索5. 计算机视觉中的深度学习图像处理和计算机视觉入门视觉识别的卷积特征物体检测对象跟踪和动作识别图像分割与合成6. 自然语言处理简介和文本分类语言建模和序列标记语义的向量空间模型序列到序列任务对话系统7. 通过机器学习解决大型强子对撞机挑战数据科学家的粒子物理入门粒子识别寻找稀有衰变中的新物理学在新的CERN实验中用机器学习搜索暗物质提示探测器优化完成这一系列课程大约需要8到10个月,所以如果你从今天开始,在不到一年的时间里,你将学到大量的机器学习算法,并能够开始处理更多尖端的应用程序。在这几个月中,你还将创建几个真正的项目,使计算机学习如何阅读,查看和播放。这些项目将成为你投资组合的理想选择,并将使你的GitHub对任何感兴趣的雇主都非常活跃。5:机器学习-EdX这是一个高级课程,具有文中任何其他课程的最高数学先决条件。你需要非常牢固地掌握线性代数、微积分、概率和编程。该课程在Python或Octave中都有编程作业,但该课程不教授任何一种语言。与其他课程的不同之处是对机器学习的概率方法的讲解。如果你有兴趣阅读教科书,例如机器学习:概率视角,这是硕士课程中最流行的数据科学书籍之一。提供者:哥伦比亚大学费用:免费审核,证书300美元课程结构:最大似然估计,线性回归,最小二乘法岭回归,偏差方差,贝叶斯规则,最大后验推断最近邻分类,贝叶斯分类器,线性分类器,感知器Logistic回归,Laplace逼近,核方法,高斯过程最大边距,支持向量机(SVM),树木,随机森林,提升聚类,K均值,EM算法,缺失数据高斯混合,矩阵分解非负矩阵分解,潜在因子模型,PCA和变化马尔可夫模型,隐马尔可夫模型连续状态空间模型,关联分析模型选择,后续步骤课程中的许多主题都包含在针对初学者的其他课程中,但数学并未在这里淡化。如果你已经学习了这些技术,有兴趣深入研究数学,并希望从事实际推导出某些算法的编程作业,那么请学习本课程。学习指南这里是你学习机器学习之旅的快速指南,首先,我们将介绍大多数机器学习课程的先决条件。课程先决条件高级的课程在开始之前需要以下知识:线性代数概率微积分程序设计这些是能够理解机器学习如何在幕后工作的简单组件。许多初级课程通常要求至少一些编程和熟悉线性代数基础知识,例如向量,矩阵。本文的第一个课程,Andrew Ng的机器学习,包含了你需要的大部分数学的复习,但是如果你以前没有学过线性代数,那么同时学习机器学习和线性代数可能会很困难。另外,我建议学习Python,因为大多数优秀的ML课程都使用Python。如果你学习使用Octave的Andrew Ng的机器学习课程,你应该在课程期间或之后学习Python,因为你最终需要它。另外,另一个很棒的Python资源是dataquest.io,它在他们的交互式浏览器环境中有一堆免费的Python课程。在学习了必备必需品之后,你就可以开始真正理解算法的工作原理了。基本算法在机器学习中有一套基本的算法,每个人都应该熟悉并具有使用经验。这些是:线性回归Logistic回归k-Means聚类k-最近邻居支持向量机(SVM)决策树随机森林朴素贝叶斯这些是必需品,上面列出的课程基本上包含所有这些。在开展新项目时,了解这些技术如何工作以及何时使用它们将非常重要。在基础知识之后,一些更先进的学习技巧将是:集成学习Boosting降维强化学习神经网络与深度学习这只是一个开始,但这些算法通常是你在最有趣的机器学习解决方案中看到的,它们是你工具箱的有效补充。就像基本技术一样,你学习的每一个新工具都应该养成一个习惯,立即将它应用到项目中,以巩固你的理解,并在需要复习时有所回头。解决一个项目在线学习机器学习具有挑战性并且非常有益。重要的是要记住,只是观看视频和参加测验并不意味着你真的在学习这些材料。如果你正在进行的项目使用不同的数据并且目标与课程本身不同,你将学到更多。一旦你开始学习基础知识,你应该寻找可以应用这些新技能的有趣数据。上面的课程将为你提供何时应用某些算法的直觉,因此立即将它们应用于你自己的项目中是一种很好的做法。通过反复试验,探索和反馈,你将发现如何尝试不同的技术,如何衡量结果,以及如何分类或预测。有关要采用何种ML项目的一些灵感,请参阅此示例列表。解决项目可以让你更好地理解机器学习环境,当你深入了解深度学习等更高级的概念时,实际上可以使用无限数量的技术和方法来理解和使用。阅读新研究机器学习是一个快速发展的领域,每天都有新的技术和应用出现。一旦你通过基础知识,你应该有能力通过一些关于你感兴趣的主题的研究论文。有几个网站可以获得符合你标准的新论文的通知。Google学术搜索始终是一个好的开始,输入“机器学习”和“深度学习”等关键词,或者你感兴趣的任何其他内容,点击左侧的“创建提醒”链接即可收到电子邮件。让它成为每周习惯,阅读这些警报,扫描文件,看看它们是否值得阅读,然后承诺了解正在发生的事情。如果它与你正在处理的项目有关,请查看你是否可以将这些技术应用于你自己的问题。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 15, 2019 · 1 min · jiezi

为拯救爸妈朋友圈,达摩院造了“谣言粉碎机”

生命不可能从谎言中开出灿烂的鲜花。前几天,母上大人给我发了条消息,再三叮嘱帮忙扩散,随手解救癌症患者。“速转!科学家发现:一味中药48小时可杀死60%癌细胞!”回复框里,我打了一段长长的反驳文字。在按下发送前沉思良久,为了保住每日的晚饭,我又默默删除了。母上大人的朋友圈,啥都不说了从那句熟悉的“狼来了”开始,谣言开始在我们生活无孔不入,一些不坏好意的人,把谎言变成一张漂亮的包装纸,裹挟着诈骗、虚荣、不怀好意,肆意横行:当全民疯抢板蓝根食盐白醋,终日人心惶惶;当“养生秘闻”“200%理财回报”充斥在朋友圈,无数养老钱血本无归;当“寒门状元之死”透支人们对世界的信任;……人们被迫练就了一身硬邦邦的铠甲,一边斜眉冷视周围的世界,一边草木皆兵地生存。宁可信其有,不可信其无。然而,总有人想改变这一切。达摩院的科学家们最近在用AI识别谣言的研究上,有了一些小突破。“谣言粉碎机”,也许离我们并不遥远?(1)在了解到这个信息后,我第一时间采访到了达摩院NLP团队的核心成员之一——李泉志,他本科毕业于清华大学,后在美国获得自然语言理解方向的博士学位,目前在达摩院的西雅图办公室工作。李泉志,达摩院智能实验室科学家在加入达摩院前,他曾是世界级通讯社——路透社重要的“情报官”:通过机器筛选成千上万的网络信息,为数千位一线记者提供可靠线索。借着这个难得的机会,我“假公济私”,请泉志使用算法鉴定我妈发来的新闻真假,还原“打假”现场。在泉志的详细说明下,一个令人惊叹的“打假”模型逐渐露出。事实上,这个运算逻辑远比我之前想得要复杂,甚至显得有点“老谋深算”。泉志告诉我,判断一个新闻真假,要分三个步骤。首先,在盘根错节的信息里,机器会找到最初的信源,分析其用户画像(专业领域,个人或机构,机构类型,影响力,过去发表的内容类型,是否可信,地域,注册时间,活跃规律等),进而判断此发布者的信誉度。如果这条新闻带有链接,我们可以再看看链接的域名,是否来自可信网站,比如新华社、政府医药管理局。接下来,我们拿起听诊器,细细揣摩正文的“心跳声”:“一味中药48小时可杀死60%癌细胞!”打开正文,我们看看究竟这味中药的成分是哪些?具体对哪些癌细胞起作用?机器会把这些关键的论证提炼为知识点,与知识图谱里的权威知识库做匹配验证。如果毫无联系、自相矛盾,减分。泉志表示,除了内容不实、上下文逻辑不连贯外,机器还能从行文风格里找到蛛丝马迹。比如:“多一次转发就多一次活命机会”“传疯了!晚上一定要关wifi,太吓人了”……是的,机器连“标题党”都不放过!假新闻经常会采用夸大性、空洞的说辞来危言耸听。真新闻往往行文严谨、一丝不苟。如果说前面两步,还算是常规操作。第三步,就是关键:对传播路径的深入分析。一条谣言在社交网络里引爆,必然有无数的人密集关注。在留言、转发等行为里,有人赞同,有反对,还有质疑,或者只是简单的路过,都是一种态度。机器统计不仅能统计所有用户的态度,更不可思议的是,它会“看人下菜”,区别对待每条发言的分量。比如,我弟转发了母上发来的新闻,冒着零用钱缩水的危险表示:“假的!昨天食品监督局已经公开辟谣了”——这条反对意见质疑得较为有力,权重提升。随后,ID为“小旺仔”的用户也在此条新闻下留言,只写了四个字:消息不实。虽然寥寥数字,但是机器一看,不得了,小旺仔的认证信息是该省第一附属医院的医学教授,权重也得提升。机器会对所有反馈用户进行画像分析:是否是认证用户、过去发表的内容类型、注册时间、活跃规律、是否和事件发生地在同一个地方等,以此来计算用户信誉度。最后根据不同态度的人群比例、各自的信誉度,以及处于传播路径中的位置等信息,计算出此新闻的可信度。“如果有人转发了小旺仔的留言,表示‘举双爪支持’,系统会不会认为这是对新闻的赞同?”我感觉自己抓到了系统漏洞,有点小激动。泉志表示这个问题提得非常好,接着干脆地做了否定:“我们的整个传播路径是个神经网络,环环相扣,不会断章取义的。”以上三步中计算出的信息会输入到神经网络模型中。基于这些信息,模型会综合判断出此新闻是否为谣言。(2)这个模型的魅力之处在于,你不必为它编写程序去学习人类的指令:它能完全自主学习训练,就像人脑一样“思考”。随着知识库的日益丰富,它的判断能力会越来越好。“简直是一位飞速成长的大编辑!”我感叹道。“这还不是全部”,泉志爽朗笑了,“我们还用了多任务学习,‘一心多用’,让机器在同一时间完成多个复杂任务,判断内容真假、观察传播路径、挖掘用户画像这些都能同时进行。”在有条不紊的运算机制里,机器就像一位冷峻的解剖师,切开浮夸的表象,梳理每一条新闻的经脉、肌理走向,抽丝剥茧,层层剥开,最终找到事实的内核。泉志接着又透露了一个重要信息——这项技术不仅能控制假新闻源头、防止谣言大规模扩散,它还有一个隐藏的“大招”。传谣容易,辟谣难。谣言的扩散速度犹如遇到林木的大火,一点即燃,但是当真相出来时,却往往无人问津。比如,网络曾谣传市面上的香蕉大多泡过药水,许多人从此再没买过香蕉。即使数年后风头过去,还有人表示吃香蕉总觉得有药水味。这项技术的隐藏”大招“,是可以针对性地为民众辟谣。根据传播路径索引,曾经支持“香蕉浸泡毒液”的人,都可以收到官方的辟谣信息:香蕉浸泡的白色液体不是甲醛,而是符合国家安全标准的保鲜剂,无毒无害;吃酱油不会变黑、开水重复烧也不会有事,交999元每月回报99的“好事”自然更是子虚乌有。有始有终,皆大欢喜!(3)达摩院所研发的“AI谣言粉碎机”,在刚刚结束的SemEval全球语义测试中,创造了假新闻识别准确率的新纪录,达到了前所未有的81%。SemEval 是自然语言处理领域的国际权威比赛,由国际计算语言学学会举办。假新闻识别是此次比赛的主要项目之一,吸引了哥伦比亚大学、华盛顿大学、艾伦·图灵研究所等20多路顶级高手参与。赛题是这样的:主办方向所有参赛者提供社交媒体上470余条新闻、以及一万多条相关的留言、转发等数据。参赛者需要根据这些有限的信息,判断这数百条新闻是真是假。这些似是而非的新闻涉及政治、娱乐、商业、科技等多个领域,比如——特朗普的差旅开支远远低于奥巴马;太阳报:英国女王支持英国脱欧;震惊了!台风过后,高速公路出现一条大鲨鱼;美国九成媒体被六家公司控制;吉萨金字塔能利用隐秘的房间集中电磁能能量;……此次比赛桂冠由达摩院NLP首席科学家司罗所属的团队斩获,真假新闻二分类上的准确率高达81%,刷新了本竞赛系列上macro F 、RMSE两项关键性指标的世界记录。在此之前,达摩院NLP团队曾在机器阅读理解顶级赛事SQuAD上,凭借82.440的精准率打破了历史纪录;在国际顶级机器翻译大赛WMT上,连夺英文-中文翻译、英文-俄语互译、英文-土耳其语互译5项第一。让机器读懂人类语言,并判断人类的表达意图,从而进一步帮助人类实现对信息真假的判断,达摩院的科学家们,从未放弃对技术难题的攻克。(4)隔着一万多千米的太平洋,与泉志说再见后,我突然想起了今年春晚的小品《“儿子”来了》:葛优饰演的保健品销售员,用夸张的“床垫”欺骗一对老夫妻。从“狼来了”到“儿子来了”,信任在不知不觉中成了世上最高的门槛。我们知道天下不会掉馅饼,但当周围人都在转发高额理财新闻时仍会忍不住动摇;我们本不会勤于研究饭菜的化学中和反应,但万一同时吃了螃蟹和香菇中毒呢;我们从不担心银行没收存款,但在接到短信“银行卡已被冻结需支付保证金”时虎躯一震……人类的原始本能告诉我们要相信彼此,然而世界正变得日益庞大和复杂,道德、名声的影响力已不如往昔,传统的信任出现了缝隙。“谣言粉碎机”技术的背后,是一次史无前例的信任重建。只有假新闻被扼杀在繁衍的温床里,破碎将倾的信任才会被重新扶起顶天立地。而信任,是爱的最好证明。AI = 爱。本文作者:孝杨阅读原文本文来自云栖社区合作伙伴“阿里技术,如需转载请联系原作者。

February 28, 2019 · 1 min · jiezi

将视觉深度学习模型应用于非视觉领域

摘要: 本文可以让你了解到,具有创造性的数据处理方法如何才能将深度学习视觉的功能应用于非视觉的领域。介绍近些年来,深度学习技术已经彻底改变了计算机视觉领域。由于迁移学习和各种各样的学习资源的出现,任何人都可以通过使用预训练的模型,将其应用到自己的工作当中,以此获得非常好的结果。随着深度学习越来越商业化,希望它的创造性能应用在不同的领域上。今天,计算机视觉领域中的深度学习在很大程度上解决了视觉对象的分类、目标检测和识别问题。在这些领域,深度神经网络(Deep Neural Network,DNN)的表现要胜过人类。即使数据不是可视化的,但你仍然可以利用这些视觉深度学习模型的力量,主要是卷积神经网络(Convolutional Neural Network,CNN)。要做到这一点,你必须将数据从非视觉领域迁移到视觉领域(图像)里,然后使用一个经过在图像和数据上训练过的模型。你将会感叹这种方法是多么的强大。在本文中,我将介绍3个案例,这是关于公司如何进行创造性地深度学习应用,将视觉深度学习模型应用于非视觉领域。在每一个案例中,都会对一个非计算机视觉的问题进行转换和描述,以便更好地利用适合图像分类的深度学习模型的能力。案例1:石油工业在石油工业中,游梁式抽油机(Beam pumps)常常用于从地下开采石油和天然气。它们由连接在移动梁上的发动机来提供动力。移动梁将发动机的旋转运动传递给抽油杆的垂直往复运动,抽油杆作为一个动力泵,再将油输送到地面上。游梁式抽油机作为一种复杂的机械系统,很容易发生故障。为了方便诊断排查,在抽油机上安装了一个测功机,用于测量杆上的负载。测量后,绘制出一张测功机的动力泵卡片,图上显示了发动机在旋转循环过程中每个部分的负载。当游梁式抽油机出故障的时候,测功机卡片上的形状会改变。这个时候,通常会邀请专业的技术人员过来检查卡片,并根据抽油机出现故障的部分来判断需要采取什么措施和方法来进行维修。这个过程不仅非常耗时,而且还需要非常深入的专业知识才能有效地解决问题。另一方面,这个过程看起来有可能是可以自动化完成的,这就是为什么尝试过典型的机器学习系统而并没有取得很好效果的原因,准确率大约为60%。将深度学习应用到这个领域的一个公司是Baker Hughes。在这种情况下,测功机卡片被转变为图像,然后作为输入到Imagenet的预训练模型中。这个结果非常令人印象深刻,精度从60%上升到93%,只需采用预训练的模型并用新的数据对其进行一下微调。经过模型训练的进一步优化,其精度达到了97%。上图是Baker Hughes部署的系统示例。在左侧,你可以看到输入图像,在右侧是故障模式的实时分类。它不仅击败了以前的基于机器学习的传统方法,而且公司不再需要抽油机的技术人员花费大量的时间来排查故障,他们过来就可以立即进行机械故障修复,从而大大提高了效率。案例2:在线欺诈检测计算机用户在使用计算机的时候有独特的模式和习惯。当你在浏览一个网站或在键盘上键入电子邮件内容的时候,你使用鼠标的习惯是独一无二的。在这种特殊的情况下,Splunk解决了一个问题,即通过使用计算机鼠标的方式来对用户进行分类。如果你的系统能够根据鼠标使用的方式来识别用户,那么这种方法可以用于欺诈检测。假设这样一个情况:某些人在窃取了别人的用户名和登录密码之后在网上消费。他们使用电脑鼠标的方式是独一无二的,系统将很容易检测到这种异常操作,并进一步防止发生欺诈交易,同时也会通知真正的账户所有者。使用特殊的Javascript代码,可以收集所有鼠标的行为活动。软件每5-10毫秒记录一次鼠标的行为。因此,每个用户在每个网页的行为数据可以是5000–10000个数据点。数据代表了两个挑战:第一个挑战是对于每个用户来说都是海量的数据,第二个挑战是每个用户的数据集都将包含不同多个数据点,这不太方便,因为,通常来说,不同长度的序列需要更复杂的深度学习架构。这个方案是将每个用户在每个网页上的鼠标活动转换为一个单个图像。在每幅图像中,鼠标的移动是一条由不同的颜色来表示鼠标移动速度的线来表示的,而点击左键和点击右键则是由绿色和红色的圆圈来表示的。这种处理初始数据的方法解决了上述的两个问题:首先,所有图像的大小都相同;其次,现在基于图像的深度学习模型可以用于此类数据了。Splunk使用TensorFlow和Keras为用户分类创建了一个深度学习的系统。他们做了2个实验:1. 当访问相类似的页面时,金融服务网站的用户组分类:正常客户与非客户用户。一个由2000张图片组成的相对较小的训练数据集。在对基于VGG16网络的一个已修改结构进行了2分钟的训练之后,系统能够以80%以上的准确度识别出这两个类;2. 用户的个人分类。该任务是为一个给定的用户预测出是真实用户还是一个模拟者。提供了一个只有360张图片的非常小的训练数据集。基于VGG16网络,但是由于考虑到小数据集和减少过度拟合(有可能放弃和批量标准化)而进行了修改。经过了3分钟的训练,准确率达到了78%左右,考虑到任务具有的挑战性,那么这一点很令人印象深刻;要了解更多相关内容,请参阅描述了系统和实验过程的完整内容。案例3:鲸鱼的声音检测在这个例子中,谷歌使用卷积神经网络来分析录音并检测出其中的座头鲸。这对于科学研究来说很有帮助,例如跟踪单个鲸鱼的活动、叫声的特性、鲸鱼的数量等等。有趣不是目的,而是如何通过需要利用图像的卷积神经网络来处理数据。将音频数据转换成图像的方法是通过使用光谱图来实现的。光谱图是音频数据基于频率特征的视觉来表示的。在将音频数据转换成光谱图之后,谷歌的研究人员使用了ResNet-50网络结构来训练这个模型。他们能够达到以下的性能表现:90%的准确度:90%的音频剪辑被归类为鲸鱼叫声的分类;90%的敏感度:如果给一个鲸鱼叫声的录音,那么就会有90%的机会被打上敏感度的标签;让我们把焦点从鲸鱼叫声转移到处理音频数据时可以做些什么。当你创建光谱图的时候,可以选择要使用的频率,这取决于你所拥有的音频数据的类型。你将需要给人类的说话声、座头鲸的叫声、或工业设备的录音设置不同的频率,因为在所有的这些情况下,最重要的信息是包含在了不同的频段里。你不得不使用自己的专业领域知识来选择相关的参数。例如,如果你使用的是人类声音数据,那么你的第一选择应该是梅尔频率倒谱图。目前有一些有比较好的软件包可用于音频。Librosa是一个免费的音频分析Python库,可以使用CPU生成光谱图。如果你在TensorFlow中开发并且想在GPU上做光谱计算,那也是支持的。请参考一下这篇文章,了解更多的关于谷歌如何处理座头鲸数据的内容。综上所述,本文所阐述的一般方法都遵循了两个步骤。首先,找到一种将数据转换成图像的方法;其次,使用一个经过预训练的卷积网络或者从头开始进行训练。第一步要比第二步更难,这是需要你必须有创造力的地方,要考虑到如果你的数据可以转换成图像。我希望提供的实例对解决你的问题有所帮助。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 30, 2019 · 1 min · jiezi

可应用于实际的14个NLP突破性研究成果(一)

摘要: 最好的论文是可以直接走出实验室!NLP年度最佳应用论文大集锦!语言理解对计算机来说是一个巨大的挑战。幼儿可以理解的微妙的细微差别仍然会使最强大的机器混淆。尽管深度学习等技术可以检测和复制复杂的语言模式,但机器学习模型仍然缺乏对我们的语言真正含义的基本概念性理解。但在2018年确实产生了许多具有里程碑意义的研究突破,这些突破推动了自然语言处理、理解和生成领域的发展。我们总结了14篇研究论文,涵盖了自然语言处理(NLP)的若干进展,包括高性能的迁移学习技术,更复杂的语言模型以及更新的内容理解方法。NLP,NLU和NLG中有数百篇论文,由于NLP对应用和企业AI的重要性和普遍性,所以我们从数百篇论文中寻找对NLP影响最大的论文。2018年最重要的自然语言处理(NLP)研究论文1.BERT:对语言理解的深度双向变换器的预训练,作者:JACOB DEVLIN,MING-WEI CHANG,KENTON LEE和KRISTINA TOUTANOVA论文摘要:我们引入了一种名为BERT的新语言表示模型,它是Transformer的双向编码器表示。与最近的语言表示模型不同,BERT旨在通过联合调节所有层中的左右上下文来预训练深度双向表示。因此,预训练的BERT表示可以通过一个额外的输出层进行微调,以创建适用于广泛任务的最先进模型,例如问答和语言推理,而无需实质性的具体的架构修改。BERT在概念上简单且经验丰富,它获得了11项自然语言处理任务的最新成果,包括将GLUE基准推至80.4%(提升了7.6%)、MultiNLI准确度达到86.7%(提升了5.6%)、SQuAD v1.1问题回答测试F1到93.2%(提升了1.5%)。总结谷歌AI团队提出了自然语言处理(NLP)的新前沿模型-BERT,它的设计允许模型从每个词的左侧和右侧考虑上下文。BERT在11个NLP任务上获得了新的最先进的结果,包括问题回答,命名实体识别和与一般语言理解相关的其他任务。论文的核心思想是什么?通过随机屏蔽一定比例的输入token来训练深度双向模型-从而避免单词间接“看到自己”的周期。通过构建简单的二进制分类任务来预训练句子关系模型,以预测句子B是否紧跟在句子A之后,从而允许BERT更好地理解句子之间的关系。训练一个非常大的模型(24个Transformer块,1024个隐藏层,340M参数)和大量数据(33亿字语料库)。什么是关键成就?刷新了11项NLP任务的记录,包括:获得80.4%的GLUE分数,这比之前最佳成绩提高了7.6%;在SQuAD 1.1上达到93.2%的准确率。预训练的模型不需要任何实质的体系结构修改来应用于特定的NLP任务。AI社区对其看法?BERT模型标志着NLP的新时代;两个无人监督的任务在一起为许多NLP任务提供了很好的性能;预训练语言模型成为一种新标准;未来的研究领域是什么?在更广泛的任务上测试该方法。收集BERT可能捕获或未捕获的语言现象。最可能的商业应用是什么?BERT可以帮助企业解决各种NLP问题,包括:提供更好的聊天机器人客服体验;客户评论分析;搜索相关信息;你在哪里可以代码?Google Research发布了一个官方Github存储库,其中包含Tensorflow代码和BERT预训练模型。BIT的PyTorch实现也可以在GitHub上获得。2.人类注意力的序列分类,作者:MARIA BARRETT,JOACHIM BINGEL,NORA HOLLENSTEIN,MAREK REI,ANDERSSØGAARD论文摘要学习注意力函数需要非常大规模的数据,不过有很多自然语言处理任务都是对人类行为的模拟,在这篇论文中作者们就表明人类的注意力确实可以为 NLP 中的许多注意力函数提供一个不错的归纳偏倚。具体来说,作者们根据人类阅读语料时的眼睛动作追踪数据估计出了「人类注意力」,然后用它对 RNN 网络中的注意力函数进行正则化。作者们的实验表明,人类注意力在大量不同的任务中都带来了显著的表现提升,包括情感分析、语法错误检测以及暴力语言检测。总结Maria Barrett和她的同事建议使用从眼动(eye-tracking)追踪语料库中获取的人类注意力来规范循环神经网络(RNN)中的注意力。通过利用公开可用的眼动追踪语料库,即通过眼睛跟踪测量(例如注视持续时间)增强的文本,它们能够在NLP任务中显着提高RNN的准确性,包括情绪分析、滥用语言检测和语法错误检测。论文的核心思想是什么?使用人的注意力,从眼动追踪语料库中估计,以规范机器注意力。模型的输入是一组标记序列和一组序列,其中每个标记与标量值相关联,该标量值表示人类读者平均专注于该标记的注意力。RNN联合学习循环参数和注意力功能,但可以在来自标记序列的监督信号和眼睛跟踪语料库中的注意力轨迹之间交替。建议的方法不要求目标任务数据带有眼睛跟踪信息。什么是关键成就?在注意力序列分类任务中引入循环神经结构。证明使用人眼注意力(从眼动追踪语料库中估计)来规范注意力功能可以在一系列NLP任务中实现显著改善,包括:§ 情绪分析,§ 检测语言检测,§ 语法错误检测。性能比基线平均误差减少4.5%。这些改进主要是由于召回率(recall)增加。AI社区对其看法?该论文获得了关于计算自然语言学习顶级会议的CoNLL 2018人类语言学习和处理启发的最佳研究论文特别奖。未来的研究领域是什么?在学习人类相关任务时,探索利用人类注意力作为机器注意力的归纳偏见的其他可能性。什么是可能的商业应用?RNN结合人类注意力信号,可应用于商业环境:§ 加强客户评论的自动分析;§ 过滤掉滥用的评论,回复。你在哪里可以得到实现代码?本研究论文的代码可在GitHub上获得。3.基于短语和神经元的无监督机器翻译,作者:GUILLAUME LAMPLE,MYLE OTT,ALEXIS CONNEAU,LUDOVIC DENOYER,MARC’AURELIO RANZATO论文摘要机器翻译系统在某些语言上实现了接近人类的性能,但其有效性强烈依赖于大量并行句子的可用性,这阻碍了它们适用于大多数语言。本文研究了如何在只能访问每种语言的大型单语语料库时学习翻译。我们提出了两种模型变体,一种神经模型,另一种基于短语的模型。两个版本都利用参数的初始化、语言模型的去噪效果以及通过迭代反向翻译自动生成并行数据。这些模型明显优于文献中的方法,同时更简单且具有更少的超参数。在广泛使用的WMT'14英语-法语和WMT'16德语-英语基准测试中,我们的模型不使用单个平行句的情况下分别获得28.1和25.2 BLEU分数,超过现有技术水平11 BLEU分。在英语-乌尔都语和英语-罗马尼亚语等低资源语言中,我们的方法比半监督和监督方法获得的效果都要好,我们的NMT和PBSMT代码是公开的。总结Facebook AI研究人员承认了缺乏用于训练机器翻译系统的大型并行语料库,并提出了一种更好的方法来利用单语数据进行机器翻译(MT)。特别是,他们认为通过适当的翻译模型初始化、语言建模和迭代反向翻译,可以成功地完成无监督的MT。研究人员提出了两种模型变体,一种是神经模型,另一种是基于短语的模型,它们的性能都极大地超越了目前最先进的模型。论文的核心思想是什么?无监督的MT可以通过以下方式完成:§ 合适的翻译模型初始化(即字节对编码);§ 在源语言和目标语言中训练语言模型,以提高翻译模型的质量(例如,进行本地替换,单词重新排序);§ 用于自动生成并行数据的迭代反向转换。有两种模型变体:神经和基于短语:§ 神经机器翻译一个重要的属性:跨语言共享内部表示。§ 基于短语的机器翻译在低资源语言对上优于神经模型,且易于解释和快速训练。什么是关键成就?基于神经和短语的机器翻译模型显著优于以前的无监督,例如:§ 对于英语-法语任务,基于短语的翻译模型获得的BLEU分数为28.1(比之前的最佳结果高出11 BLEU分);§ 对于德语-英语任务,基于神经和短语的翻译模型组合得到BLEU得分为25.2(高出基线10个BLEU点)。无监督的基于短语的翻译模型实现了超过使用10万个并行句子训练的监督模型对应的性能。AI社区的对其想法?该论文在自然语言处理领域的领先会议被评为EMNLP 2018评为最佳论文奖。未来的研究领域是什么?寻找更有效的原则实例或其他原则。扩展到半监督模型。什么是可能的商业应用?改进其中没有足够的并行语料库来训练受监督的机器翻译系统的机器翻译结果。你在哪里可以得到实现代码?Facebook团队在GitHub上提供了本研究论文的原始实现代码。未完待续……本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 29, 2019 · 1 min · jiezi

序列模型简介——RNN, Bidirectional RNN, LSTM, GRU

摘要: 序列模型大集合——RNN, Bidirectional RNN, LSTM, GRU既然我们已经有了前馈网络和CNN,为什么我们还需要序列模型呢?这些模型的问题在于,当给定一系列的数据时,它们表现的性能很差。序列数据的一个例子是音频的剪辑,其中包含一系列的人说过的话。另一个例子是英文句子,它包含一系列的单词。前馈网络和CNN采用一个固定长度作为输入,但是,当你看这些句子的时候,并非所有的句子都有相同的长度。你可以通过将所有的输入填充到一个固定的长度来解决这个问题。然而,它们的表现仍然比RNN要差,因为这些传统模型不了解给定输入的上下文环境。这就是序列模型和前馈模型的主要区别所在。对于一个句子,当看到一个词的时候,序列模型试图从在同一个句子中前面的词推导出关系。当我们读一个句子的时候,不会每次遇到一个新词都会再从头开始。我们会根据对所读过单词的理解来处理之后的每个单词。循环神经网络(Recurrent Neural Network,RNN)循环神经网络如上图所示。在一个时间步骤中的每个节点都接收来自上一个节点的输入,并且这可以用一个feedback循环来表示。我们可以深入这个feedback循环并以下图来表示。在每个时间步骤中,我们取一个输入x_i和前一个节点的输出a_i-1,对其进行计算,并生成一个输出h_i。这个输出被取出来之后再提供给下一个节点。此过程将一直继续,直到所有时间步骤都被评估完成。描述如何在每个时间步骤上计算输出的方程式,如下所示:在循环神经网络中的反向传播发生在图2中所示箭头的相反方向上。像所有其它的反向传播技术一样,我们评估一个损失函数,并获取梯度来更新权重参数。循环神经网络中有意思的部分是从右到左出现的反向传播。由于参数从最后的时间步骤更新到最初的时间步骤,这被称为通过时间的反向传播。长短期记忆(Long Short-Term Memory)— LSTM网络循环神经网络的缺点是,随着时间步骤长度的增大,它无法从差得很远的时间步骤中获得上下文环境。为了理解时间步骤t+1的上下文环境,我们有可能需要了解时间步骤0和1中的表示。但是,由于它们相差很远,因此它们所学的表示无法在时间步骤t+1上向前移动,进而对其起作用。“我在法国长大……我能说一口流利的法语”,要理解你说的法语,网络就必须远远地往后查找。但是,它不能这么做,这个问题可以归咎于梯度消失的原因。因此,循环神经网络只能记住短期存储序列。为了解决这个问题,Hochreiter & Schmidhuber提出了一种称为长短期记忆网络。LSTM网络的结构与循环神经网络保持一致,而重复模块会进行更多的操作。增强重复模块使LSTM网络能够记住长期依赖关系。让我们试着分解每个操作,来帮助网络更好地记忆。1、忘记门操作我们从当前时间步骤获取输入,并从前一时间步骤获取学习的表示,之后将它们连接起来。我们将连接后的值传递给一个sigmoid函数,该函数输出一个介于0和1之间的值(f_t)。我们在f_t和c_t-1之间做元素的乘积。如果一个值为0,那么从c_t-1中去掉,如果这个值为1,则完全通过。因此,这种操作也被称为“忘记门操作”。2、更新门操作上图表示的是“更新门操作”。我们将来自当前时间步骤中的值和前一时间步骤中已学习的表示连接起来。将连接的值通过一个tanh函数进行传递,我们生成一些候选值,并通过一个sigmoid函数传递,从候选值中选择一些值,所选的候选值将会被更新到c_t-1。3、输出门操作我们将当前时间步骤的值和前一时间步骤已学习的表示连接起来,并经由一个sigmoid函数传递来选择将要用作输出的值。我们获取单元状态并请求一个tanh函数,然后执行元素方式操作,其只允许选定的输出通过。现在,在一个单一单元中要完成很多的操作。当使用更大的网络时,与循环神经网络相比,训练时间将显著地增加。如果想要减少你的训练时间,但同时也使用一个能记住长期依赖关系的网络,那么还有另一个替代LSTM网络的方法,它被称为门控循环单元。门控循环单元(Gated Recurrent Unit ,GRU Network)与LSTM网络不同的是,门控循环单元没有单元状态,并且有2个门而不是3个(忘记、更新和输出)。门控循环单元使用一个更新门和一个重置门。更新门决定了应该让多少之前的信息通过,而重置门则决定了应该丢弃多少之前的信息。 在上面的图中,z_t表示更新门操作,通过使用一个sigmoid函数,我们决定让哪些之前的信息通过。h_t表示重置门操作,我们将前一时间步骤和当前时间步骤的连接值与r_t相乘。这将产生我们希望从前一时间步骤中所放弃的值。尽管门控循环单元在计算效率上比LSTM网络要高,但由于门的数量减少,它在表现方面仍然排在LSTM网络之后。因此,当我们需要更快地训练并且手头没有太多计算资源的情况下,还是可以选择使用门控循环单元的。双向循环神经网络所有上述双向RNN网络的一个主要问题是,它们从之前的时间步骤中学习表示。有时,你有可能需要从未来的时间步骤中学习表示,以便更好地理解上下文环境并消除歧义。通过接下来的列子,“He said, Teddy bears are on sale” and “He said, Teddy Roosevelt was a great President。在上面的两句话中,当我们看到“Teddy”和前两个词“He said”的时候,我们有可能无法理解这个句子是指President还是Teddy bears。因此,为了解决这种歧义性,我们需要往前查找。这就是双向RNN所能实现的。双向RNN中的重复模块可以是常规RNN、LSTM或是GRU。双向RNN的结构和连接如图10所示。有两种类型的连接,一种是向前的,这有助于我们从之前的表示中进行学习,另一种是向后的,这有助于我们从未来的表示中进行学习。正向传播分两步完成:我们从左向右移动,从初始时间步骤开始计算值,一直持续到到达最终时间步骤为止;我们从右向左移动,从最后一个时间步骤开始计算值,一直持续到到达最终时间步骤为止;结论将双向循环神经网络与LSTM模块相结合可以显著地提高性能,当将它们与监控机制相结合的时候,你可以在机器翻译、情感化分析等实例中获得最高水品的性能表现。希望本文对大家有帮助。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 28, 2019 · 1 min · jiezi

Auto-Keras与AutoML:入门指南

摘要: 不会机器学习?不会人工智能?没关系!自动化程序来了!在本教程中,你将学习如何使用Auto-Keras(Google的AutoML的开源替代品)来实现自动化机器学习和深度学习。目前来说,深度学习从业者在数据集上训练神经网络时,主要正在尝试优化和平衡两个目标:1.定义适合数据集性质的神经网络体系结构;2.在许多实验中调整一组超参数,这将导致模型具有高精度并能够推广到训练和测试集之外的数据。需要调整的典型超参数包括优化算法(SGD,Adam等),学习速率和学习速率调度以及正则化等。根据数据集和具体问题,深度学习专家可以进行数十到数百次实验,以找到神经网络架构和超参数之间的平衡,这些实验通常需要计算数百到数千小时。刚刚提到的这种模式仅适用于专家,那非深度学习专家呢?这就需要Auto-Keras和AutoML:Auto-Keras和AutoML的最终目标是通过使用自动神经架构搜索(NAS)算法降低进入机器学习和深度学习的门槛。Auto-Keras和AutoML使非深度学习专家能够以最小的深度学习领域知识或实际数据来训练他们自己的模型。具有最小机器学习专业知识的程序员可以使用AutoML和Auto-Keras并应用这些算法,只需很少的努力即可实现最先进的性能。听起来好得令人难以置信?也许你需要好好阅读这篇文章的其余部分以找出原因。Auto-Keras和AutoML:入门指南在本博文的第一部分中,我们将讨论自动机器学习(AutoML)和神经架构搜索(NAS),这种算法使得AutoML在应用于神经网络和深度学习时成为可能。我们还将简要讨论Google的AutoML,这是一套工具和库,允许具有有限机器学习专业知识的程序员在自己的数据上训练高精度模型。当然,谷歌的AutoML是一种专有算法,AutoML的另一种选择是开源Auto-Keras、它是围绕Keras和PyTorch而构建。然后,我将向你展示如何使用Auto-Keras自动训练网络以及评估它。什么是自动机器学习(AutoML)?Auto-Keras是Google AutoML的替代品。它可以帮助你自动训练模型,几乎不需要干预。对于新手深度学习从业者来说,它们是很好的选择。在无监督学习之外,非专家的自动机器学习被认为是机器学习的“圣杯”。想象一下通过以下方式自动创建机器学习模型的能力:1.安装库/使用Web界面;2.将库/接口指向你的数据;3.自动训练数据模型而无需调整参数/需要深入了解为其提供动力的算法;一些公司正试图创建这样的解决方案,其中一个就是谷歌的AutoML。Google AutoML使非常有限的机器学习经验的开发人员和工程师能够自动在他们自己的数据集上训练神经网络。谷歌的底层AutoML算法是迭代的:1.在训练集上训练网络;2.在测试集上评估网络;3.修改神经网络架构;4.调整超参数;5.重复上述过程;使用AutoML的程序员或工程师不需要定义他们自己的神经网络架构或调整超参数,AutoML会自动为他们做这件事。神经架构搜索(NAS)使AutoML成为可能神经架构搜索(NAS)在搜索CIFAR-10的最佳CNN架构时,通过这些图表生成了一个模型。Google的AutoML和Auto-Keras都采用了一种称为神经架构搜索(NAS)的算法。根据你的输入数据集,神经架构搜索算法将自动搜索最佳架构和相应参数。神经架构搜索基本上是用一组自动调整模型的算法取代深度学习工程师/从业者!在计算机视觉和图像识别的背景下,神经架构搜索算法将:1.接受输入训练数据集;2.优化并找到称为“单元”的架构构建块,然后让这些单元自动学习,这可能看起来类似于初始化,残留或激活微架构;3.不断训练和搜索“NAS搜索空间”以获得更优化的单元;如果AutoML系统的用户是经验丰富的深度学习从业者,那么他们可能会决定:1.在训练数据集的一个非常小的子集上运行NAS;2.找到一组最佳的架构构建块/单元;3.获取这些单元并手动定义在体系结构搜索期间找到的更深层次的网络版本;4.使用自己的专业知识和最佳实践,在完整的培训集上训练网络;这种方法是全自动机器学习解决方案与需要专家深度学习实践者的解决方案之间的混合体,通常这种方法比NAS自己训练的模型性能更好。Auto-Keras:谷歌AutoML的开源替代品在Auto-Keras包是由在德克萨斯州A&M大学数据实验室团队开发。Auto-Keras是Google AutoML的开源替代品。Auto-Keras依然是利用神经架构搜索,但应用“网络态射”(在更改架构时保持网络功能)以及贝叶斯优化,以指导网络态射以实现更高效的神经网络搜索。你可以在Jin等人的2018年出版物Auto-Keras:Efficient Neural Architecture Search with Network Morphism中找到Auto-Keras框架的全部细节。安装Auto-Keras:正如Auto-Keras GitHub存储库所述,Auto-Keras处于“预发布”状态-它现在还不是正式版本。其次,Auto-Keras需要Python 3.6并且只与Python 3.6兼容。如果你使用的*是3.6以外的任何其他版本的Python,你将无法使用Auto-Keras软件包。如果你想要检查Python版本,只需使用以下命令:python –version如果你有Python 3.6,你可以使用pip安装Auto-Keras:pip install tensorflow # or tensorflow-gpupip install keraspip install autokeras使用Auto-Keras实现我们的训练脚本:让我们继续使用Auto-Keras实现我们的训练脚本,打开train_auto_keras.py文件并插入以下代码:# import the necessary packagesfrom sklearn.metrics import classification_reportfrom keras.datasets import cifar10import autokeras as akimport osdef main(): # initialize the output directory OUTPUT_PATH = “output"首先,我们在第2-5行导入必要的包:如前所述,我们将使用scikit-learn的classification_report来计算我们将在输出文件中保存的统计信息。我们将使用CIFAR-10数据集,因为它已经被内置到keras.datasets。然后是导入import依赖项-autokeras,我已经将它用AK的简写代替。该os模块是必需的,因为我们会在建立输出文件的路径时,在各种操作系统上容纳路径分隔符。我们在第7行定义脚本的主要功能,由于Auto-Keras和TensorFlow处理线程的方式,我们需要将代码包装在main函数中。有关更多详细信息,请参阅此GitHub问题线程。现在让我们初始化Auto-Keras的训练时间列表:# initialize the list of training times that we’ll allow # Auto-Keras to train for TRAINING_TIMES = [ 60 * 60, # 1 hour 60 * 60 * 2, # 2 hours 60 * 60 * 4, # 4 hours 60 * 60 * 8, # 8 hours 60 * 60 * 12, # 12 hours 60 * 60 * 24, # 24 hours ]上述代码是限定了一组训练-TIMES,包括[1,2,4,8,12,24]小时。我们将使用Auto-Keras来探索更长的训练时间对精确度的影响。让我们加载CIFAR-10数据集并初始化类名:# load the training and testing data, then scale it into the # range [0, 1] print("[INFO] loading CIFAR-10 data…”) ((trainX, trainY), (testX, testY)) = cifar10.load_data() trainX = trainX.astype(“float”) / 255.0 testX = testX.astype(“float”) / 255.0 # initialize the label names for the CIFAR-10 dataset labelNames = [“airplane”, “automobile”, “bird”, “cat”, “deer”, “dog”, “frog”, “horse”, “ship”, “truck”]我们的CIFAR-10数据被加载并存储在第25行的训练/测试分组中。随后,我们将这个数据缩放到[0,1]的范围。接着我们会初始化我们的类labelNames,这10个类包含在CIFAR-10中。请注意,标签在这里很重要。现在让我们开始循环遍历我们的TRAINING_TIMES,每次都使用Auto-Keras:# loop over the number of seconds to allow the current Auto-Keras # model to train for for seconds in TRAINING_TIMES: # train our Auto-Keras model print("[INFO] training model for {} seconds max…".format( seconds)) model = ak.ImageClassifier(verbose=True) model.fit(trainX, trainY, time_limit=seconds) model.final_fit(trainX, trainY, testX, testY, retrain=True) # evaluate the Auto-Keras model score = model.evaluate(testX, testY) predictions = model.predict(testX) report = classification_report(testY, predictions, target_names=labelNames) # write the report to disk p = os.path.sep.join(OUTPUT_PATH, “{}.txt”.format(seconds)) f = open(p, “w”) f.write(report) f.write("\nscore: {}".format(score)) f.close()上面的代码块是今天脚本的核心。在第35行,我们在每个TRAINING_TIMES上定义了一个循环,我们在其中做以下操作:初始化我们的模型(AK.ImageClassifier),并让训练开始。请注意,我们并没有实例化一个特定对象的CNN类,我们也没有调整超参数。因为Auto-Keras会为我们处理所有这些。一旦达到时间限制,请采用Auto-Keras找到的最佳模型和参数+重新训练模型。评估和构建分类报告。将分类报告与准确度分数一起写入磁盘,以便我们评估更长训练时间的影响。我们将为每个TRAINING_TIMES重复此过程。最后,我们将检查并启动执行的主线程:# if this is the main thread of execution then start the process (our# code must be wrapped like this to avoid threading issues with# TensorFlow)if name == “main”: main()这里我们检查确保这是执行的主线程,然后是主函数。仅仅60行代码,我们就完成了使用CIFAR-10示例脚本编写Auto-Keras,但是我们还没有完成……使用Auto-Keras训练神经网络让我们继续使用Auto-Keras训练我们的神经网络。请确保使用本教程的“下载”部分下载源代码。从那里打开终端,导航到下载源代码的位置,然后执行以下命令:$ python train_auto_keras.py[INFO] training model for 3600 seconds max… Preprocessing the images.Preprocessing finished.Initializing search.Initialization finished.+———————————————-+| Training model 0 |+———————————————-+Using TensorFlow backend.No loss decrease after 5 epochs.Saving model.+————————————————————————–+| Model ID | Loss | Metric Value |+————————————————————————–+| 0 | 4.816269397735596 | 0.5852 |+————————————————————————–++———————————————-+| Training model 1 |+———————————————-+Using TensorFlow backend.Epoch-14, Current Metric - 0.83: 28%|██████▊ | 110/387 [01:02<02:46, 1.67 batch/s]Time is out.[INFO] training model for 86400 seconds max… Preprocessing the images.Preprocessing finished.Initializing search.Initialization finished.+———————————————-+| Training model 0 |+———————————————-+Using TensorFlow backend.No loss decrease after 5 epochs….+———————————————-+| Training model 21 |+———————————————-+Using TensorFlow backend.No loss decrease after 5 epochs.+————————————————————————–+| Father Model ID | Added Operation |+————————————————————————–+| | to_deeper_model 16 ReLU || 16 | to_wider_model 16 64 |+————————————————————————–+Saving model.+————————————————————————–+| Model ID | Loss | Metric Value |+————————————————————————–+| 21 | 0.8843476831912994 | 0.9316000000000001 |+————————————————————————–++———————————————-+| Training model 22 |+———————————————-+Using TensorFlow backend.Epoch-3, Current Metric - 0.9: 80%|████████████████████▊ | 310/387 [03:50<00:58, 1.31 batch/s]Time is out.No loss decrease after 30 epochs.在这里你可以看到我们的脚本正在指示Auto-Keras执行六组实验。在NVIDIA K80 GPU上,总训练时间为3天多一点。Auto-Keras的结果:使用Auto-Keras通常是一个非常耗时的过程。使用Auto-Keras进行训练可在8-12小时范围内为CIFAR-10生成最佳型号。在上图中,你可以看到训练时间(x轴)对使用Auto-Keras的总体准确度(y轴)的影响。较短的训练时间,即1小时和2小时,大约可以达到73%的准确性。一旦我们训练4小时,我们就能达到高达93%的准确率。训练8-12小时,我们就能获得95%的精确度了。超过8-12小时的训练不会提高我们的准确度,这意味着我们已达到饱和点并且Auto-Keras无法进一步优化。Auto-Keras和AutoML值得吗?Auto-Keras值得吗?这无疑是行业向前迈出的一大步,对那些没有深入学习领域知识的人尤其有用。在无监督学习之外(从未标记数据自动学习模式),非专家的自动机器学习被认为是机器学习的“圣杯”。Google的AutoML和开源Auto-Keras软件包都试图将机器学习带给大众,即使是没有关键性技术的经验的程序员。虽然Auto-Keras在CIFAR-10上工作得相当好,但是我使用我之前关于深度学习,医学图像和疟疾检测的文章进行了第二组实验。我使用简化的ResNet架构获得了97.1%的准确率,该架构花费了不到一小时的时间进行训练。然后我让Auto-Keras在相同的数据集上运行24小时-结果只有96%的准确度,低于我自己定义的架构。但不管怎样,谷歌的AutoML和Auto-Keras都是向前迈出的一大步。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

January 28, 2019 · 2 min · jiezi

Euler 今日问世!国内首个工业级的图深度学习开源框架,阿里妈妈造

阿里妹导读:千呼万唤始出来!阿里妈妈正式公布重磅开源项目——图深度学习框架Euler。这是国内首个在核心业务大规模应用后开源的图深度学习框架。此次开源,Euler内置了大量的算法供用户直接使用,相关代码已经可在GitHub上进行下载。图学习和深度学习都是人工智能的一个分支,作为阿里巴巴旗下的大数据营销平台,阿里妈妈创新性地将图学习与深度学习进行结合,推出了Euler,可帮助大幅度提升营销效率。Euler已在阿里妈妈核心业务场景进行了锤炼和验证,同时,在金融、电信、医疗等涉及到复杂网络分析的场景中也具有很高的应用价值。例如,用户可以利用Euler对基于用户交易等金融数据构建的复杂异构图进行学习与推理,进而应用于金融反欺诈等场景。下面让我们一起走进Euler的世界。Euler 开源地址 : https://github.com/alibaba/euler1. 概述过去几年随着数据规模和硬件计算力的迅速增长,深度学习技术在工业界被广泛应用并产生了巨大的技术红利。当前应用已经相对成熟,下一步的技术红利在哪里还在积极探索之中。图神经网络将端到端学习与归纳推理相结合,有望解决深度学习无法处理的关系推理、可解释性等一系列问题。对结构知识的表达、计算和组合泛化是实现具备human-like AI的关键,图神经网络有希望在这些方面形成突破,使得机器能力进一步提升,因此对图神经网络的深入应用有希望形成下一波技术红利。图作为表达能力很强的通用的数据结构,可以用来刻画现实世界中的很多问题,例如社交场景的用户网络、电商场景的用户和商品网络、电信场景的通信网络、金融场景的交易网络和医疗场景的药物分子网络等等。相比文本、语音和图像领域的数据比较容易处理成欧式空间的Grid-like类型,适合现有的深度学习模型处理,图是一种非欧空间下的数据,并不能直接应用现有方法,需要专门设计的图神经网络系统。1.1Euler的核心能力1)大规模图的分布式学习工业界的图往往具有数十亿节点和数百亿边,有些场景甚至可以到数百亿节点和数千亿边,在这样规模的图上单机训练是不可行的。Euler支持图分割和高效稳定的分布式训练,可以轻松支撑数十亿点、数百亿边的计算规模。2)支持复杂异构图的表征工业界的图关系大都错综复杂,体现在节点异构、边关系异构,另外节点和边上可能有非常丰富的属性,这使得一些常见的图神经网络很难学到有效的表达。Euler在图结构存储和图计算的抽象上均良好的支持异构点、异构边类型的操作,并支持丰富的异构属性,可以很容易的在图学习算法中进行异构图的表征学习。3)图学习与深度学习的结合工业界有很多经典场景,例如搜索/推荐/广告场景,传统的深度学习方法有不错效果,如何把图学习和传统方法结合起来,进一步提升模型能力是很值得探索的。Euler支持基于深度学习样本的mini-batch训练,把图表征直接输入到深度学习网络中联合训练。4)分层抽象与灵活扩展Euler系统抽象为图引擎层、图操作算子层、算法实现层三个层次,可以快速地在高层扩展一个图学习算法。实际上,Euler也内置了大量的算法实现供大家直接使用。1.2 Euler内置的算法实现考虑到框架的易用性,我们内置了多种知名算法以及几种我们内部的创新算法。所有实现,我们仔细进行了测试,保证了算法运行效率,且算法效果与原论文对齐。用户无需进行开发,注入数据到平台后,可以直接使用。我们内置的算法列表见下表。有关我们内部算法的详细信息请见2.3节。2. 系统设计Euler系统整体可以分为三层:最底层的分布式图引擎,中间层图语义的算子,高层的图表示学习算法。下边我们分开描述各个层次的核心功能。2.1分布式图引擎为了支持我们的业务,我们不仅面临超大规模图存储与计算的挑战,还需要处理由多种不同类型的点,边及其属性构成异构图的复杂性。我们的分布式图引擎针对海量图存储,分布式并行图计算及异构图进行了优化设计,确保了工业场景下的有效应用。首先为了存储超大规模图(数十亿点,数百亿边),Euler必须突破单机的限制,从而采用了分布式的存储架构。在图加载时,整张图在引擎内部被切分为多个子图,每个计算节点被分配1个或几个子图进行加载。为了充分利用各个计算节点的能力,在进行图的操作时,顶层操作被分解为多个对子图的操作由各个节点并行执行。这样随着更多节点的加入,我们可以得到更好的服务能力。其次,我们引入了多replica的支持。从而用户可以灵活平衡shard与replica的数量,取得更佳的服务能力。最后,我们针对图表示学习优化了底层的图存储数据结构与操作算法,单机的图操作性能获得了数倍的提升。多种不同类型的边,点与属性所组成的异构图,对很多复杂的业务场景必不可少。为了支持异构图计算能力,底层存储按照不同的节点与边的类型分别组织。这样我们可以高效支持异构的图操作。2.2中间图操作算子由于图学习算法的多样性以及业务的复杂性,固定的某几种甚至几十种算法实现无法满足客户的所有需求。所以在Euler设计中,我们围绕底层系统的核心能力着重设计了灵活强大的图操作算子,且所有算子均支持异构图操作语义。用户可以利用它来快速搭建自己的算法变体,满足独特的业务需求。首先,Euler分布式图引擎提供了C++的API来提供所有图操作。基于这个API,我们可以方便的基于某个深度学习框架添加图操作的算子,从而利用Euler C++接口访问底层图引擎的能力。我们支持广泛使用的深度学习框架,比如阿里巴巴的X-DeepLearning与流行的TensorFlow。后继我们也会考虑支持其它的深度学习框架,比如PyTorch。利用灵活的图操作算子,机器学习框架可以在每个mini-batch与Euler交互,动态扩充与组织训练样本。这样,Euler不仅支持传统的以图为中心的学习模式,且可以把图学习的能力注入传统的学习任务,实现端到端训练。按照功能分类,我们的核心系统提供的API可以分类如下:全局带权采样点和边的能力。主要用于mini-batch样本的随机生成以及Negative Sampling。基于给定节点的邻居操作。这个是图计算的核心能力包括邻居带权采样,取Top权重的邻居等。点/边的属性查找。这个能力使得算法可以使用更丰富的特征,而不仅限于点/边的ID特征。2.3高层算法实现如1.2节所述,除了LINE算法以外,我们实现的算法可以分为随机游走与邻居汇聚两大类算法。有关外部算法的详细信息,请参见1.2节提供的论文链接。下面我们详细介绍内部的三个创新算法,相关论文的链接我们会在github上给出。Scalable-GCN它是一种高效的GCN训练算法。GCN以及更一般的Graph Neural Network (GNN)类的方法由于能有效的提取图结构信息,在许多任务上均取得了超过以往方法的效果。但是GCN的模型会引入巨大的计算量,导致模型的训练时间不可接受。Scalable-GCN在保证优秀效果的前提下,把mini-batch GCN的计算复杂度从层数的指数函数压到线性。这使得在阿里妈妈的海量数据下应用三层GCN成为可能,广告匹配的效果获得了显著提升。LsHNELsHNE是我们结合阿里妈妈搜索广告场景创新地提出一种无监督的大规模异构网络embedding学习方法。区别于DeepWalk类算法,LsHNE的特点包括:a) 采用深度神经网络学习表达,可以有效融合Attribute信息;b)考虑embedding表示的距离敏感需求,提出两个负采样原则:分布一致性原则和弱相关性原则;c)支持异构网络。LasGNNLasGNN是一种半监督的大规模异构图卷积神经网络学习方法, 它有效融合了图结构知识信息和海量用户行为信息,大幅提升了模型精度,是工业界广告场景下首次应用半监督图方法。该方法有多处创新,例如将metapath的思想应用于图卷积网络中,并提出了metapathGCN模型,有效解决了异构网络的卷积问题;提出了metapathSAGE模型,在模型中我们设计高效的邻居采样的方法,使得大规模的多层邻居卷积成为可能。3. 应用实例Euler平台已经在阿里妈妈搜索广告的多个场景下广泛实用,并取得了出色的业务效果,例如检索匹配场景、CTR预估场景、营销工具场景和反作弊场景等。我们以匹配场景的为例来看下Euler的应用。广告匹配的任务是给定用户搜索请求,匹配模块通过理解用户意图,快速准确地从海量广告中找到高质量的小规模候选广告集,输送给下游的排序模块进行排序。我们首先使用一些传统的挖掘算法,从用户行为日志、内容属性等维度挖掘出Query(查询词), Item(商品)和Ad(广告)的多种关系,然后利用Euler平台的LsHNE方法学习图中节点的embedding,这里节点embedding后的空间距离刻画了原来图中的关系,对于在线过来的请求通过计算用户查询词向量、前置行为中节点向量和广告节点向量之间的距离进行高效的向量化最近邻检索,可以快速匹配到符合用户意图的广告。图2展示了LsHNE方法的离线和在线流程。具体图3展示了样本构造和网络结构示意。本文作者:让你久等了阅读原文本文来自云栖社区合作伙伴“阿里技术”,如需转载请联系原作者。

January 21, 2019 · 1 min · jiezi

PyTorch可视化理解卷积神经网络

摘要: 神经网络工具像一个黑匣子,无法知道它的中间是如何处理的。本文使用图片加代码的形式讲解CNN网络,并对每层的输出进行可视化,便于初学者理解,可以动手实践下哦!如今,机器已经能够在理解、识别图像中的特征和对象等领域实现99%级别的准确率。生活中,我们每天都会运用到这一点,比如,智能手机拍照的时候能够识别脸部、在类似于谷歌搜图中搜索特定照片、从条形码扫描文本或扫描书籍等。造就机器能够获得在这些视觉方面取得优异性能可能是源于一种特定类型的神经网络——卷积神经网络(CNN)。如果你是一个深度学习爱好者,你可能早已听说过这种神经网络,并且可能已经使用一些深度学习框架比如caffe、TensorFlow、pytorch实现了一些图像分类器。然而,这仍然存在一个问题:数据是如何在人工神经网络传送以及计算机是如何从中学习的。为了从头开始获得清晰的视角,本文将通过对每一层进行可视化以深入理解卷积神经网络。卷积神经网络在学习卷积神经网络之前,首先要了解神经网络的工作原理。神经网络是模仿人类大脑来解决复杂问题并在给定数据中找到模式的一种方法。在过去几年中,这些神经网络算法已经超越了许多传统的机器学习和计算机视觉算法。“神经网络”是由几层或多层组成,不同层中具有多个神经元。每个神经网络都有一个输入和输出层,根据问题的复杂性增加隐藏层的个数。一旦将数据送入网络中,神经元就会学习并进行模式识别。一旦神经网络模型被训练好后,模型就能够预测测试数据。另一方面,CNN是一种特殊类型的神经网络,它在图像领域中表现得非常好。该网络是由YanLeCunn在1998年提出的,被应用于数字手写体识别任务中。其它应用领域包括语音识别、图像分割和文本处理等。在CNN被发明之前,多层感知机(MLP)被用于构建图像分类器。图像分类任务是指从多波段(彩色、黑白)光栅图像中提取信息类的任务。MLP需要更多的时间和空间来查找图片中的信息,因为每个输入元素都与下一层中的每个神经元连接。而CNN通过使用称为局部连接的概念避免这些,将每个神经元连接到输入矩阵的局部区域。这通过允许网络的不同部分专门处理诸如纹理或重复模式的高级特征来最小化参数的数量。下面通过比较说明上述这一点。比较MLP和CNN因为输入图像的大小为28x28=784(MNIST数据集),MLP的输入层神经元总数将为784。网络预测给定输入图像中的数字,输出数字范围是0-9。在输出层,一般返回的是类别分数,比如说给定输入是数字“3”的图像,那么在输出层中,相应的神经元“3”与其它神经元相比具有更高的类别分数。这里又会出现一个问题,模型需要包含多少个隐藏层,每层应该包含多少神经元?这些都是需要人为设置的,下面是一个构建MLP模型的例子:Num_classes = 10Model = Sequntial()Model.add(Dense(512, activation=’relu’, input_shape=(784, )))Model.add(Dropout(0.2))Model.add(Dense(512, activation=’relu’))Model.add(Dropout(0.2))Model.add(Dense(num_classes, activation=’softmax’))上面的代码片段是使用Keras框架实现(暂时忽略语法错误),该代码表明第一个隐藏层中有512个神经元,连接到维度为784的输入层。隐藏层后面加一个dropout层,丢弃比例设置为0.2,该操作在一定程度上克服过拟合的问题。之后再次添加第二个隐藏层,也具有512谷歌神经元,然后再添加一个dropout层。最后,使用包含10个类的输出层完成模型构建。其输出的向量中具有最大值的该类将是模型的预测结果。这种多层感知器的一个缺点是层与层之间完全连接,这导致模型需要花费更多的训练时间和参数空间。并且,MLP只接受向量作为输入。卷积使用稀疏连接的层,并且其输入可以是矩阵,优于MLP。输入特征连接到局部编码节点。在MLP中,每个节点都有能力影响整个网络。而CNN将图像分解为区域(像素的小局部区域),每个隐藏节点与输出层相关,输出层将接收的数据进行组合以查找相应的模式。计算机如何查看输入的图像?看着图片并解释其含义,这对于人类来说很简单的一件事情。我们生活在世界上,我们使用自己的主要感觉器官(即眼睛)拍摄环境快照,然后将其传递到视网膜。这一切看起来都很有趣。现在让我们想象一台计算机也在做同样的事情。在计算机中,使用一组位于0到255范围内的像素值来解释图像。计算机查看这些像素值并理解它们。乍一看,它并不知道图像中有什么物体,也不知道其颜色。它只能识别出像素值,图像对于计算机来说就相当于一组像素值。之后,通过分析像素值,它会慢慢了解图像是灰度图还是彩色图。灰度图只有一个通道,因为每个像素代表一种颜色的强度。0表示黑色,255表示白色,二者之间的值表明其它的不同等级的灰灰色。彩色图像有三个通道,红色、绿色和蓝色,它们分别代表3种颜色(三维矩阵)的强度,当三者的值同时变化时,它会产生大量颜色,类似于一个调色板。之后,计算机识别图像中物体的曲线和轮廓。。下面使用PyTorch加载数据集并在图像上应用过滤器:# Load the librariesimport torchimport numpy as npfrom torchvision import datasetsimport torchvision.transforms as transforms# Set the parametersnum_workers = 0batch_size = 20# Converting the Images to tensors using Transformstransform = transforms.ToTensor()train_data = datasets.MNIST(root=‘data’, train=True, download=True, transform=transform)test_data = datasets.MNIST(root=‘data’, train=False, download=True, transform=transform)# Loading the Datatrain_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, num_workers=num_workers)test_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, num_workers=num_workers)import matplotlib.pyplot as plt%matplotlib inlinedataiter = iter(train_loader)images, labels = dataiter.next()images = images.numpy()# Peeking into datasetfig = plt.figure(figsize=(25, 4))for image in np.arange(20): ax = fig.add_subplot(2, 20/2, image+1, xticks=[], yticks=[]) ax.imshow(np.squeeze(images[image]), cmap=‘gray’) ax.set_title(str(labels[image].item()))下面看看如何将单个图像输入神经网络中:img = np.squeeze(images[7])fig = plt.figure(figsize = (12,12)) ax = fig.add_subplot(111)ax.imshow(img, cmap=‘gray’)width, height = img.shapethresh = img.max()/2.5for x in range(width): for y in range(height): val = round(img[x][y],2) if img[x][y] !=0 else 0 ax.annotate(str(val), xy=(y,x), color=‘white’ if img[x][y]<thresh else ‘black’)上述代码将数字'3’图像分解为像素。在一组手写数字中,随机选择“3”。并且将实际像素值(0-255 )标准化,并将它们限制在0到1的范围内。归一化的操作能够加快模型训练收敛速度。构建过滤器过滤器,顾名思义,就是过滤信息。在使用CNN处理图像时,过滤像素信息。为什么需要过滤呢,计算机应该经历理解图像的学习过程,这与孩子学习过程非常相似,但学习时间会少的多。简而言之,它通过从头学习,然后从输入层传到输出层。因此,网络必须首先知道图像中的所有原始部分,即边缘、轮廓和其它低级特征。检测到这些低级特征之后,传递给后面更深的隐藏层,提取更高级、更抽象的特征。过滤器提供了一种提取用户需要的信息的方式,而不是盲目地传递数据,因为计算机不会理解图像的结构。在初始情况下,可以通过考虑特定过滤器来提取低级特征,这里的滤波器也是一组像素值,类似于图像。可以理解为连接卷积神经网络中的权重。这些权重或滤波器与输入相乘以得到中间图像,描绘了计算机对图像的部分理解。之后,这些中间层输出将与多个过滤器相乘以扩展其视图。然后提取到一些抽象的信息,比如人脸等。就“过滤”而言,我们有很多类型的过滤器。比如模糊滤镜、锐化滤镜、变亮、变暗、边缘检测等滤镜。下面用一些代码片段来理解过滤器的特征:Import matplotlib.pyplot as pltImport matplotib.image as mpimgImport cv2Import numpy as npImage = mpimg.imread(‘dog.jpg’)Plt.imshow(image)# 转换为灰度图gray = cv2.cvtColor(image, cv2.COLOR_RB2GRAY)# 定义sobel过滤器sobel = np.array([-1, -2, -1],[0, 0, 0],[1, 2, 1]))# 应用sobel过滤器Filtered_image = cv2.filter2D(gray, -1, sobel_y)# 画图Plt.imshow(filtered_image, cmp=’gray’)以上是应用sobel边缘检测滤镜后图像的样子, 可以看到检测出轮廓信息。完整的CNN结构到目前为止,已经看到了如何使用滤镜从图像中提取特征。现在要完成整个卷积神经网络,cnn使用的层是:1.卷积层(Convolutional layer)2.池层(Pooling layer)3.全连接层(fully connected layer)典型的cnn网络结构是由上述三类层构成:下面让我们看看每个图层起到的的作用:* 卷积层(CONV)——使用过滤器执行卷积操作。因为它扫描输入图像的尺寸。它的超参数包括滤波器大小,可以是2x2、3x3、4x4、5x5(或其它)和步长S。结果输出O称为特征映射或激活映射,具有使用输入层计算的所有特征和过滤器。下面描绘了应用卷积的工作过程:池化层(POOL)——用于特征的下采样,通常在卷积层之后应用。池化处理方式有多种类型,常见的是最大池化(max pooling)和平均池化(ave pooling),分别采用特征的最大值和平均值。下面描述了池化的工作过程: 全连接层(FC)——在展开的特征上进行操作,其中每个输入连接到所有的神经元,通常在网络末端用于将隐藏层连接到输出层,下图展示全连接层的工作过程:在PyTorch中可视化CNN在了解了CNN网络的全部构件后,现在让我们使用PyTorch框架实现CNN。步骤1:加载输入图像:import cv2import matplotlib.pyplot as plt%matplotlib inlineimg_path = ‘dog.jpg’bgr_img = cv2.imread(img_path)gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)# Normalisegray_img = gray_img.astype(“float32”)/255plt.imshow(gray_img, cmap=‘gray’)plt.show()步骤2:可视化过滤器对过滤器进行可视化,以更好地了解将使用哪些过滤器:import numpy as npfilter_vals = np.array([ [-1, -1, 1, 1], [-1, -1, 1, 1], [-1, -1, 1, 1], [-1, -1, 1, 1]])print(‘Filter shape: ‘, filter_vals.shape)# Defining the Filtersfilter_1 = filter_valsfilter_2 = -filter_1filter_3 = filter_1.Tfilter_4 = -filter_3filters = np.array([filter_1, filter_2, filter_3, filter_4])# Check the Filtersfig = plt.figure(figsize=(10, 5))for i in range(4): ax = fig.add_subplot(1, 4, i+1, xticks=[], yticks=[]) ax.imshow(filters[i], cmap=‘gray’) ax.set_title(‘Filter %s’ % str(i+1)) width, height = filters[i].shape for x in range(width): for y in range(height): ax.annotate(str(filters[i][x][y]), xy=(y,x), color=‘white’ if filters[i][x][y]<0 else ‘black’)步骤3:定义CNN模型本文构建的CNN模型具有卷积层和最大池层,并且使用上述过滤器初始化权重:import torchimport torch.nn as nnimport torch.nn.functional as Fclass Net(nn.Module): def init(self, weight): super(Net, self).init() # initializes the weights of the convolutional layer to be the weights of the 4 defined filters k_height, k_width = weight.shape[2:] # assumes there are 4 grayscale filters self.conv = nn.Conv2d(1, 4, kernel_size=(k_height, k_width), bias=False) # initializes the weights of the convolutional layer self.conv.weight = torch.nn.Parameter(weight) # define a pooling layer self.pool = nn.MaxPool2d(2, 2) def forward(self, x): # calculates the output of a convolutional layer # pre- and post-activation conv_x = self.conv(x) activated_x = F.relu(conv_x) # applies pooling layer pooled_x = self.pool(activated_x) # returns all layers return conv_x, activated_x, pooled_x# instantiate the model and set the weightsweight = torch.from_numpy(filters).unsqueeze(1).type(torch.FloatTensor)model = Net(weight)# print out the layer in the networkprint(model)Net((conv): Conv2d(1, 4, kernel_size=(4, 4), stride=(1, 1), bias=False)(pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))步骤4:可视化过滤器快速浏览一下所使用的过滤器def viz_layer(layer, n_filters= 4): fig = plt.figure(figsize=(20, 20)) for i in range(n_filters): ax = fig.add_subplot(1, n_filters, i+1) ax.imshow(np.squeeze(layer[0,i].data.numpy()), cmap=‘gray’) ax.set_title(‘Output %s’ % str(i+1))fig = plt.figure(figsize=(12, 6))fig.subplots_adjust(left=0, right=1.5, bottom=0.8, top=1, hspace=0.05, wspace=0.05)for i in range(4): ax = fig.add_subplot(1, 4, i+1, xticks=[], yticks=[]) ax.imshow(filters[i], cmap=‘gray’) ax.set_title(‘Filter %s’ % str(i+1))gray_img_tensor = torch.from_numpy(gray_img).unsqueeze(0).unsqueeze(1)步骤5:每层过滤器的输出在卷积层和池化层输出的图像如下所示:卷积层:池化层:可以看到不同层结构得到的效果会有所差别,正是由于不同层提取到的特征不同,在输出层集合到的特征才能很好地抽象出图像信息。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

January 21, 2019 · 3 min · jiezi

一幅GAN网络创造的肖像图卖了40万美金,但那又怎样?

摘要: 价值不菲的艺术创造到底是否能被科技代替?在2018年一场著名的拍卖会上,一部AI制作的肖像以432,500美元的价格成交!这篇新闻在科技媒体上被广泛讨论,有些人认为这一事件对人类艺术家构成了威胁。其实,这只是深度学习快速发展中众多不可思议的案例中的一个,这些故事创造了关于人工智能的耸人听闻的头条新闻,或者是说人工智能表现出与人类同等的艺术创造力。一些言论:“人工智能写作已经到来”,“人工智能很快就能写出比人类更好的小说”等等在网络上大量出现。事实上,与任何其他技术创新一样,人工智能或者更具体地说机器学习和深度学习将影响我们创造音乐,艺术和文学的方式。但是在过去的一年里,我研究了这个领域并与参与开发和使用产生艺术作品的人工智能技术的艺术家和工程师进行了交谈,了解到了关于人工智能在艺术创造发明的应用及艺术家对它的看法。发现深度学习并不是人类创造力的替代!即使一个AI创意成功售价数十万美元。人与机器艺术的区别要理解深度学习对人类创造力的影响,我们必须首先理解人工智能与人类在产生艺术之间的差异。尽管人类思维,其技术较旧,处理能力较慢且存储不稳定,但在创建艺术作品时,人类思维过程比最先进的AI算法要复杂得多。当你画一幅画,创作一首歌,写一部小说(甚至是这篇博文)时,你的生活经历、文化、宗教、政治和社会倾向都会混合成一堆混乱的情绪和化学反应,影响到你的工作。因为我们对我们的大脑知之甚少,所以我们无法真正理解人类的创造过程,人类艺术的每一项工作本身都是独一无二的。试图重现它实际上就像一个人能两次踏进同一条河流。相反,我们非常清楚AI算法如何生成视觉、音频和文本数据,即使它们的内部工作机制有时会困扰我们。最近人工智能创新的核心是神经网络,这种复杂结构特别擅长检查和匹配模式以及对信息进行分类。各种艺术和音乐生成工具中使用的深度学习技术也各不相同,但是已经变得非常流行的一种特定技术是生成性对抗网络(GAN)。GAN涉及两个神经网络,一个用于生成新数据,另一个用于评估第一个输出,以查看它是否通过了特定类别的数据。例如,如果分类器网络已经学习了足够的爱尔兰民间音乐样本,它将能够告诉你一个新的音乐音符序列是否属于爱尔兰民俗类。因此,爱尔兰音乐GAN将有一个生成器网络创建音乐样本并通过分类器运行它们以查看它是否作为爱尔兰音乐传递。如果结果不令人满意,则生成器修改数据,通过分类器重新运行并重复该过程,直到后者将其评定为可接受的爱尔兰音乐样本。我们可以应用相同的方法来创建各种数据。去年,图形芯片巨头Nvidia使用GAN为不存在的人创造逼真的图像。最近,一个开发团队使用GAN创建了一幅画,售价超过40万美元。一些不法分子则使用GAN创造出名人和政治家的假色情片。但是我们要清楚,神经网络和分类器都不知道他们正在创造的数据内容,以及它的艺术价值或它可能对其他人造成的潜在伤害。这些内容是没有情感,没有灵感和想象力的火花。GAN和其他所有表现创造力的深度学习或人工智能技术都是使用数学和统计学来创建数据并将它们与之前看到的其他样本进行比较。深度学习将自动完成一些创造性任务我们不得不承认深度学习和神经网络在创作艺术、音乐和文学作品方面的局限性,但是如果说艺术创造力肯定不会自动化是不对的。像人工智能影响的其他行业一样,人类的创造力必然会受到一些破坏。至少,我们必须重新思考我们对创造力的定义。我在与不同专家的谈话中得出的结论是,深度学习将使某些形式的艺术自动化。例如“功能音乐”:我们在演示广告和一些更简单的视频游戏的背景中播放的音频类型,可以通过神经网络自动化,神经网络根据用户提供的输入参数生成新的音乐序列,这些输入可以是风格,节奏和心情等。目前有几家公司已经开发或正在开发类似的AI应用程序,他们的产品市场非常丰富。很容易看到类似的发展在视觉艺术领域发生,其中AI算法可以为视频和演示的背景创建独特的功能视觉效果。但功能艺术可能并不完全被视为创意内容。它们旨在帮助用户专注于其他内容,例如演示文稿或视频的内容。“我们认为功能性音乐是一种因其用例而受到重视的音乐,而不是制作它的创造力。”纽约人工智能创业公司Amper Music的首席执行官兼联合创始人Drew Silverstein说。但西尔弗斯坦解释说:艺术音乐“更多的是关于这个过程而不是用例。”然而,有些人正在以创造功能性音乐和艺术为生。他们的工作自动化会发生什么?深度学习将增强人类的创造力功能艺术仅占整个行业的一小部分,更广泛的AI行业深度学习进步的真正发展是人类能力的提升。事实上是神经网络和深度学习将使更多人更容易变得富有创造力。现在已经有不同的深度学习工具有助于提高业余爱好者和专业艺术家的创造性技能。例如,神经网络可以绘制并修改一幅画以使其具有梵高或毕加索风格。另一个例子是Google开发的一种工具,它使用机器学习来检查粗略的草图并将其转换为清晰的图纸。在更专业的层面上,深度学习可以帮助艺术家找到新的想法并加快他们的创作过程。去年,我写了一篇关于folk-rnn的文章,这是一个创造爱尔兰凯尔特音乐的深度学习应用程序。我与爱尔兰音乐家兼作曲家达伦巴纳尔斯进行了交谈,他告诉我,虽然他对一些作品有好感并且感到惊讶,但显然它们仍需要添加一些人性才能完成。他并不担心神经网络可以取代他的工作,有趣的是中间会出现一些他想不到的新想法。巴纳尔斯希望像folk-rnn这样的工具可以帮助他完成工作。“当我不得不开始大规模的作曲时,我总觉得这很令人生畏。也许我可以给计算机一些参数:玩家的数量、心情、甚至我最喜欢的作曲家的名字,它可以为我生成一个基本结构。我不希望它开箱即用,但这将是一个起点!”巴纳尔斯说。在文学领域,即使人工智能对人类语言的理解有限,但深度学习也会在帮助专业作家方面找到一些有趣的用例。本月“纽约时报”刊登了一个故事,描述了作家如何使用机器学习来寻找他的写作思路和完成句子的建议。软件背后的技术细节并不多,并且使用的技术是自然语言处理和生成(NLP/NLG)人工智能的一个分支,帮助计算机分析和创建人类文本。同样,这里没有涉及创造力,只有统计模式匹配和预测。但就像民谣一样,NLP/NLG有时会提出作者不会想到的有趣想法。在某些方面,比如说作为独立业务模型的出现应用程序编程接口(API)。API并没有让程序员的失业,但他们使更多没有任何编程背景的人能够开发应用程序。我在去年12月采访过的Spotify创造者技术研究实验室主任弗朗索瓦·帕切特(Francois Pachet),他将创造性人工智能工具与80年代的数字合成器进行了比较,当时人们担心计算机会导致音乐家失去工作,但恰恰相反,数字合成器在某种意义上说,使每个人都带上量这些新的机器和硬件且学会了如何有效地使用它们,音乐界也因此得到了快速发展。为什么AI不会取代人类的创造力人工智能技术将继续改进并更好地模仿人类的创造力。在某些时候,它甚至可能创造出与人类艺术家无法区分的音乐和艺术。但是,使艺术品有价值的东西不一定是输出。大多数时候,了解人类成就的过程和劳动与最终结果同样重要和珍贵。一台机器人可以在很短时间内被训练为投篮大师,同样一个职业篮球运动员需要花费几十年才会成为投篮大师。此外,如果你做了一些更新,教给机器人一个新的技能,你可以迅速将其推广到所有类型,这是人类无法做到的。但我们对人类运动员的欣赏不仅仅是他们在场上的统计数据和表现,我们应该更欣赏他们的坚持和努力。同样,我们应该欣赏音乐家、艺术家、作家以及每个创造性人类的故事,因为他们的个人努力,他们克服生活的挑战,并从他们所经历的一切中寻找灵感。这是人类艺术的真正本质,即使我们实现了始终难以捉摸的一般人工智能,这也是无法自动化的。让我写这篇文章的原因是关于在拍卖会上出售的GAN画作的故事。但有趣的是,创造GAN开发者对这件事的评价(生成式对抗网络的发明者Goodfellow称这是一个有趣的转折)。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 21, 2019 · 1 min · jiezi

计算机如何在图像识别领域取得惊人突破

原文 How computers got shockingly good at recognizing images作者 Timothy B. Lee译者 李平海图片如无标示亦出自原文文末附有专业词汇对照表囿于专业知识水平,译文如有不达之处,望留言斧正。如今,我可以在GooglePhotos里输入“沙滩”,就可以看到过去一段时间里我去过的各个沙滩。我并没有管理过我的照片,给它们打标签。实际上是Google根据照片内容识别出沙滩。这个看似普通的功能基于深度卷积神经网络技术,此技术允许软件以一种复杂的方式理解图像,这是以前的技术做不到的。这些年来研究人员发现,随着他们建立更深层的网络,积累更大的数据集来训练它们,软件的准确性越来越高。这导致了对算力的需求几乎无法满足,让英伟达(Nvidia)和AMD等GPU制造商大赚一笔。Google几年前开发了自己定制的神经网络芯片,其他公司争相效仿。例如在特斯拉,深度学习专家Andrej Karpathy被任命为负责自动驾驶项目。这家汽车制造商在开发定制的芯片,以加速未来的自动驾驶版本中的神经网络操作。又例如苹果公司,最近几款的iPhone中的A11/A12芯片就包含“神经引擎”,可以加速神经网络运行,以提供更好的图像识别/语音识别应用。那些我为了写本文而采访的专家们认为,如今深度学习的热潮可以追溯到一篇专业论文——AlexNet(以该文首要作者Alex Krizhevsky的昵称命名)。“在我看来,AlexNet论文发表的2012年可谓里程碑。”机器学习专家、《智能机器如何思考》(How Smart Machines Think)作者Sean Gerrish如是说。2012年之前,深度神经网络只是机器学习领域中的死水泥潭。但随即Krizhevsky和他的多伦多大学团队向一个备受瞩目的图像识别竞赛提交了作品,准确率突破性地超越了以往任何技术。一夜之间,深度神经网络成为了图像识别的领衔技术。其他研究人员很快地利用这项技术使图像识别精度飞跃发展。在这篇文章中,我们将深入探讨深度学习。我会解释神经网络究竟是什么,它如何被训练,以及它为什么需要那么大的算力。然后我将解释一种特殊神经网络——深层卷积网络——为什么它特别擅长理解图像。别担心,我们会有很多配图。简单的单神经元的例子“神经网络”这个词可能比较含糊,让我们从一个简单例子开始吧。假设你想要一个根据红绿黄交通灯决定车子是否能走的神经网络。此神经网络可以用一个神经元来完成这项任务。这个神经元接收每个输入(1代表打开,0代表关闭),乘以各自权重(weight),并且把加权值(weighted value)相加。然后此神经元会加上偏置(bias),这决定了神经元“激活(activate)”的阈值。此情况下如果输出值为正,我们认为此神经元“激活”了,否则没“激活”。这个神经元相当于不等式“green - red - 0.5 > 0”。如果计算结果为true,就意味着绿灯亮了,红灯灭了,车子可以通过。在真正的神经网络中,虚拟神经元会有额外的一步。在加权值加上偏置求和后,神经元会调用非线性激活函数(Non-linear activation function)。一种流行的做法是sigmoid函数,一个S型函数,它总是产生一个0~1间的值。在我们简单的交通灯模型中,使用激活函数并不会改变结果(但不能用0,例子中我们用0.5)。但激活函数的非线性是让神经网络模拟更复杂函数的关键。没有了激活函数,无论多复杂的神经网络都可以简化为它的输入的线性组合。而且线性函数不可能模拟复杂的真实现象。非线性激活函数可以让神经网络更接近任何数学函数。一个神经网络样例当然,有很多办法可以近似函数。神经网络之所以特别,是因为我们知道如何用一些算式,一堆数据,以及海量算力来“训练”它们。我们可以建造一个合适的通用神经网络来替代用人类程序员专门写来执行特定任务的神经网络。刷过一堆打过标签的数据后,它会修改神经网络本身,让自己能尽可能打出正确的标签。我们希望得出的神经网络具有通用性,能为不在训练数据中的样本也正确地打标签。在AlexNet发表之前,这个努力已经开始了。1986年,三位研究人员发表了一篇关于反向传播(backpropagation)的里程碑式论文。该技术是一种有助于训练复杂神经网络的数学方法。为了直观地了解反向传播如何工作,让我们来看看Michael Nielsen在他杰出的在线深度学习教程中描述的一个简单神经网络。目标是让神经网络从28X28像素的图片上正确地识别一个手写的数字(例如0,1,2)。每个图片有28x28=784个输入值,每个都用0或1代表这个像素是深色还是浅色。Nielsen 构建了一个这样的神经网络:插图里中层和右层每个圆圈代表我们上一段说的那种神经元。每个神经元为输入值加权求平均,然后加上偏置,然后调用一个激活函数。值得注意的是左层的圆圈不是神经元,它们代表的是输入值。虽然只画了8个输入圈,但实际上有784个输入——每个代表一个像素。右层的10个神经元代表“亮灯”猜测不同的数字:假如是0,首个神经元应该被激活(其他神经元不激活),假如是1则是第二个神经元被激活(其余的不激活),如此类推。每个神经元接收上一层所有神经元的输入。所以中层的15个神经元都是收784个输入值。它们每个都为784个输入值设置权重。这意味着在此层有15X784=11760个权重参数。同理,输出层有10个神经元,每个都从中层的15个神经元接收输入值,所以又多了1510个权重参数。与此同时,整个网络25个神经元共有25个偏置。训练神经网络我们目标是调整这11935个参数,尽可能正确地得让代表对应手写数字的输出神经元亮灯。我们可以用一个叫MNIST的著名数据集来训练,它提供了60000个已经正确标注的28X28像素图像:此图是 MNIST 数据集里60000个图像种的160个Nielsen 示范了如何不依赖任何机器学习库,仅用74行正常Python代码来训练这个神经网络。训练从选取11935个随机的权重/偏置参数开始。软件将遍历每张图片样本,完成两步过程:根据输入图像和网络的当前参数,前馈步骤计算网络的输出值。反向传播步骤将计算结果与正确输出值的偏差,然后修改网络种的参数,以略微提高其在特定输入图像上的性能。下例中,假设网络收到了这张图片:如果网络经过良好调校,网络中“7”的输出值应该接近1,其他9个输出值应该都接近0。但假如收到此图时“0”值是0.8。那就太离谱了!训练算法会改变输入“0”输出神经元的各个权重,好让下次输入这张图片时,输出值会更接近0。为此,反向传播算法会为各个权重参数算出一个误差梯度。这是一个衡量输出错误有多大程度被输入权重所被改变的维度。算法会依照这个梯度决定多大程度改变每个输入值的权重——梯度越大,这个参数修改越多。换句话说,这个训练过程“教会”输出神经元更少地注意导向错误的输入方(即中层的神经元),更多地注意正确方向的输入方。算法一直为每个输出神经元重复此步骤。它将降低 “1,” “2,” “3,” “4,” “5,” “6," “8,” 和 “9” 神经元(除了神经元“7”)的输入方的权重,使输出神经元的值降低。输入值越大,反映此输入值的权重参数的误差梯度就越大,因此这个权重会减少越多。同理,训练算法会增加输出神经元“7”的输入值的权重。令下次遇到这个图像时,此神经元会产生更大的输出值。同样的,输入值越大,加权后的增加值也越大,这使得输出神经元“7”在以后的几轮学习中更加关注这些输入。接下来,算法需要对中层执行相同的计算:改变每个输入值的权重以减少网络的错误——同样,使“7”输出更接近1,其他输出更接近0。但每个中层神经元都会对向全部10个输出层神经元进行输出,这会导致两个方向的矛盾。首先,中层的误差梯度,不仅仅取决于输入值,也同时取决于下一层的误差梯度。这个算法之所以被称为反向传播,是因为网络里后层的误差梯度会反向传到前面层级(沿着算式中的关系链)并用来计算梯度。同时,每个中层神经元也是全部10个输出层神经元的输入源。因此,训练算法计算的误差梯度,必须反映输入权重的变化如何影响所有输出的平均误差。反向传播是一种爬坡算法:该算法的每一轮都会使输出结果更接近训练图像的正确结果,但只会更接近一点。随着算法经历越来越多的样本,它会“爬坡”到一个最优参数集,该参数集能够正确地分类尽可能多的训练样本。要获得较高的准确率,需要成千上万的训练样本,算法可能需要对训练集中的每个图像进行数十次循环,才能达到最优。Nielsen展示了如何用74行Python代码实现上述所言。值得注意的是,使用这个简单程序训练的神经网络能够识别MNIST数据库中95%以上的手写数字。通过一些额外的改进,像这样一个简单的两层神经网络能够识别98%以上的数字。AlexNet的突破你可能以为,上世纪80年代反向传播的发展会开启一段基于神经网络的机器学习的快速发展时期,但事实并非如此。在90年代和21世纪初,有一些人在研究这项技术。但对神经网络的热潮直到2010年代初才真正兴起。我们可以在由斯坦福大学计算机科学家李飞飞组织的年度机器学习竞赛《ImageNet》的结果中看到这一点。在每年的比赛中,参赛者都会得到一组由100多万张训练图片组成的通用图片,每张图片上都手工标注着1000种可能的分类,比如“消防车”、“蘑菇”或“猎豹”。参赛者的软件根据其对未被纳入训练集的其他图像进行分类的能力进行评判。程序可以进行多次猜测,如果前五次对图像的猜测中有一次与人类选择的标签相匹配,则该软件被认为是成功的。比赛从2010年开始举办,在前两届比赛中,深度神经网络并没有发挥主要作用。顶级团队使用了各种其他机器学习技术,但结果平平无奇。2010年获胜的那支球队,top5错误率(即五轮皆猜错)为28%。2011年度则是25%。然后就到了2012年。这个来自多伦多大学的团队提交了一份参赛作品,不啻于将选手们从死水泥潭中拖出。该参赛作品即后来以主要作者Alex krizhevsky名字命名的AlexNet。通过使用深度神经网络,该研究小组获得了16%的top5错误率。当年最接近的竞对手错误率达到26%。前文所说的手写识别网络有两层,25个神经元,以及将近12000个参数。AlexNet更大更复杂:8个可训练的层、65万个神经元和6000万个参数。训练这样规模的网络需要大量的算力,而AlexNet的设计就是利用现代GPU提供的大量并行算力。研究人员想出了如何在两个GPU之间分配网络训练的工作,从而使他们的算力提高了一倍。尽管进行了积极的优化,使用2012年水平的硬件(两个Nvidia GTX 580 GPU,每个有3GB内存)对网络训练依然耗费了5到6天。看看AlexNet结果的一些例子,对我们理解这是一个多么引人瞩目的突破很有帮助。以下是那篇论文的插图,展示了一些图片样本和AlexNet对应的top5分类猜测:AlexNet能够识别出第一张图片中包含了一只螨虫,尽管这只螨虫只是图片边缘的一小块。该软件不仅能正确识别美洲豹,它的其他先行猜测——美洲虎、猎豹、雪豹和埃及猫——都长得很像。AlexNet将蘑菇的图片标注为“伞菌”——蘑菇的一种。官方正确的标签“蘑菇”是AlexNet的第二选择。AlexNet的“错误结果”同样令人惊讶。照片上,一只斑点狗站在樱桃后面,旁边写着“斑点狗”,而官方的标签是“樱桃”。AlexNet意识到这张照片上有某种水果——“葡萄”和“接骨木果”是它的前五种选择——但它没有完全意识到它们是樱桃。给AlexNet展示一张马达加斯加猫在树上的照片,它会猜一系列的小型爬树哺乳动物。很多人(包括我)都会同样地猜错。这确实是一个引人瞩目的表现,表明软件可以识别各种方向和排布中的常见对象。深度神经网络迅速成为图像识别任务中最受欢迎的技术,机器学习的世界从此迈上快车道不回头。ImageNet的发起人写道:“随着基于深度学习的方法在2012年取得成功,2013年的绝大多数参赛作品都使用了深度卷积神经网络。”这种模式持续了好几年,后来的优胜者都是建立在AlexNet团队开创的基本技术之上。到2017年,使用深度神经网络的参赛者将top5错误率降至3%以下。考虑到这项任务的复杂度,可以说这使得计算机比许多人更擅长这项任务。这张来自ImageNet团队的条形图显示了每年top-5分类比赛中获胜团队的错误率。从2010年到2017年,错误率稳步下降。卷积网络的概念从技术上讲,AlexNet是一个卷积神经网络。在本节中,我将解释卷积网络的作用,以及为什么这项技术对现代图像识别算法至关重要。我们之前研究的简单手写识别网络是全连接的:第一层的每个神经元都是第二层神经元的输入源。此结构比较适合相对简单的任务,例如识别28×28像素图像中数字。但进一步扩展就很难了。在MNIST手写数字数据集中,字符总是居中的。这大大简化了训练,因为这意味7在图像的顶部和右侧总是有一些黑色像素,而左下方总是白色的。0总是中间白块,四周的像素则较暗。一个简单的、全连接的网络可以相当容易地检测这些类型的模式。但是假如你想建立一个神经网络来识别可能位于大图中的任何位置的数字。一个全连接的网络不擅长于此,因为它没有一种有效的方法来识别位于图像不同部分的形状之间的相似性。如果你的训练集的左上角恰好有大部分的7,那么你会得到一个网络,它比图像中其他地方更善于识别左上角的7。从理论上讲,你可以通过确保你的训练集在每个可能的像素位置上都有很多数字的样本来解决这个问题。但在实践中,这将是巨大的浪费。随着图像的大小和网络的深度的增加,连接的数量——也就是输入权重参数的数量——将会激增。你需要更多的训练图像和算力来达到足够的准确性。当神经网络学习识别图像中某个位置的形状时,它应该能够将这种学习应用于识别图像中其他位置的类似形状。卷积神经网络为这个问题提供了一个优雅的解决方案。“这就像拿一个模板或模式,然后将其与图像上的每一个点进行匹配,”人工智能研究员唐杰(音)说。“你有一个狗的模板轮廓,然后发现右上角和你的模板基本匹配——那里有条狗吧?”如果没有,可以稍微移动一下模板,遍历整张图片。狗出现在在图像哪个位置并不重要。模板会匹配到它。你不会想让网络的每个子部分都学习自己单独的狗识别器。试想一下,如果我们把一幅大图像分成2828像素的小块。然后,我们可以将每个小块输入到之前所述的全连接的手写识别网络中。如果这些小块中的“7”输出至少有一个被点亮,就意味着整个大图中可能有7的存在。这就是卷积网络的本质。卷积网络在AlexNet中如何工作?在卷积网络中,这些“模板”被称为特征检测器(feature detector),它们所观察的区域被称为接受域(receptive field)。真正的特征检测器的接受域往往比边长28像素小得多。在AlexNet中,第一个卷积层具有接受域为11×11像素的特征检测器。它随后的卷积层有3到5个单位宽的接受域。当特征检测器扫过输入图像时,它会生成一个特征图(feature map):一个二维网格,表示该检测器被图像的不同部分激活的强度。卷积层通常有多个特征检测器,每个检测器扫描输入图像以寻找不同的模式。在AlexNet中,第一层有96个特征检测器,生成了96个特征图。为了更具体地说明这一点,以下是经过网络训练的AlexNet第一层中的96个特征检测器所学习的视觉模式的可视化表示。特征检测器可以寻找水平或垂直的线条、从亮到暗的渐变、棋盘图形和其他形状。彩色图像用像素分布格式表示,每个像素有三个值:红值、绿值和蓝值。AlexNet的第一层会将红绿蓝三位表示的像素归纳为96个类型值之一。图像中的每个“像素”(指第一层分割的单元)有96种可能的值,对应96种特征检测器。在本例中,这96个值中的第一个值指示图像中的某个特定点是否与此模式匹配:第二个值指示某个特定点是否与此模式匹配:第三个值表示某个特定点是否与此模式匹配:如此类推,在AlexNet的第一层中,其他93个特征检测器也是如此。第一层将图像的每个“像素”用一种新表现形式输出——表示为96个值(类似96进制?)的向量(我稍后将解释,这个新表示形式也被按比例缩小四倍)。这是AlexNet的第一层。接下来是另外四个卷积层,每个层的输入都是前一层的输出。正如我们所看到的,第一层检测基本的模式,如水平和垂直的线,光到暗的变化,以及曲线。然后,第二层使用第一层的结果作为构建块来检测稍微复杂一些的形状。例如,第二层可能有一个特征检测器,它通过组合第一层特征检测器的输出来查找曲线,从而查找圆。第三层通过结合第二层的特征找到更复杂的形状。第4层和第5层可以找到更复杂的模式。研究人员Matthew Zeiler和Rob Fergus在2014年发表了一篇出色的论文,为可视化类似ImageNet的五层神经网络所识别的模式提供了一些有用的方法。在下列插图中,每张图片(第一张除外)都有两个部分。在右边,你将看到一些缩略图图像,它们高度匹配了特定的特征检测器。它们9个分为一组,每组对应一个不同的特征检测器。在左边是一个地图,它显示了缩略图图像中的哪些特定像素产生了高度匹配。你可以在第5层中最显著地看到这一点,因为有一些特性检测器可以高度匹配为狗、企业标识、独轮车轮子等。浏览这些图像,你可以看到每一层都能够识别比前一层更复杂的模式。第一层识别简单的像素模式,看起来也并不十分相像。第二层识别纹理和简单的形状。在第三层,我们可以看到可识别的形状,如汽车轮子和红橙色的球体(可能是西红柿、瓢虫或其他东西)。第一层的感受域为11X11单位大小,而后面的层的感受域大小则为3X3单位到5X5单位不等。但是请记住,后面的这些层接收的是前面的层生成的特征图,这些特征图中的每个“像素”表示原始图像中的n个像素。所以每一层的感受域都包含了原始图像中比前一层更大的部分。这就是为什么后期图层的缩略图看起来比早期图层更复杂的原因之一。感受域示意图,from深度神经网络中的感受野网络的第五层也是最后一层能够识别这些图像中最显眼的大尺度元素。例如这张图片,我从上面第5层图片的右上角截取的:右边的9张图片看起来可能不太相似。但是如果你看一下左边的9张热图,你会发现这个特定的特征检测器并没有聚焦于每张图像前景中的物体。相反,它关注的是每个图像背景中的绿色部分!显然,如果你要识别的类别之一是“草”,那么用“草检测器”就合适了,但是它同时也可能检测其他东西。在五个卷积层之后,AlexNet有三个层是全连接的,就像我们手写识别网络中的层一样。这些层会利用第五卷积层生成的每个特征图,尝试将图像分类为1000个类别中的一个。所以如果一幅画的背景是草,那么它更有可能是野生动物。另一方面,如果这幅画的背景是草,那么它不太可能是一幅室内家具的画。其他位于第五层的特征探测器提供了丰富的信息可用于猜测照片内容。网络的最后几层将这些信息综合起来,对整个图片所描绘的内容进行有理据的猜测。卷积层的独到之处:共享输入权重我们已经看到卷积层中的特征检测器执行了牛逼的模式识别,但是到目前为止,我还没有解释卷积网络实际上是如何工作的。卷积层是一层神经元。像任何神经元一样,这些神经元取其输入的加权平均值,然后应用一个激活函数。用我们讨论过的反向传播技术来训练当中的参数。但与上面的神经网络不同,卷积层没有全连接。每个神经元只接受前一层神经元的一小部分输入。更重要的是,卷积网络中的神经元共享输入权重。让我们放大AlexNet的第一个卷积层中的第一个神经元。这一层的接受域大小是11×11像素,所以第一个神经元接收某角落的11×11像素。这个神经元接受这121个像素的输入,每个像素有三个值——红、绿、蓝。神经元总共有363个输入。和任何神经元一样,这个神经元取363个输入值的加权平均值,然后应用一个激活函数。因为它有363个输入值,它也需要363个输入权重参数。AlexNet第一层中的第二个神经元与第一个神经元非常相似。它同样接收11×11像素,但它的接受域是从第一个神经元的接受域平移4个像素开始。这就在两个接受域之间产生了7个像素的重叠,这就避免了遗漏两个神经元之间的有趣模式。第二个神经元同样接收描述11×11像素的363个值,每个值乘以权重参数,求和,并调用一个激活函数。特殊的是,第二个神经元没有自己的一组363个输入权重,而是使用与第一个神经元相同的输入权重。第一个神经元的左上角像素使用与第二个神经元的左上角像素相同的输入权重。所以这两个神经元在寻找完全相同的模式。它们的接受域之间有4个像素的偏移。当然实际远不止两个神经元——图片分为55×55格共3025个神经元。这3025个神经元中的每一个都使用与开始两个神经元相同的363个输入权重。所有这些神经元共同“扫描”图像中可能存在的特定模式,组成一个特征检测器。请记住,AlexNet的第一层有96个特性检测器。我刚才提到的3025个神经元组成了96个特征探测器中的一个。其他95个特征探测器则是由各自的一组3025个神经元组成。每组3025个神经元与组内其他神经元共享其363个输入权重,但不是和其他95个特征检测器的神经元共享。卷积网络的训练使用与训练全连接网络相同的基础反向传播算法,但是卷积结构使得训练过程更加高效。“使用卷积非常有用,因为可以重用参数,”机器学习专家和作家Sean Gerrish告诉Ars(本文原作者机构)。这大大减少了网络需要学习的输入权重的数量,这使得网络可以用更少的训练样本产生更好的结果。从图像的一个部分学到的识别模式,可以转化用于识别其他图像的其他位置的相同模式。这使得网络可以通过更少的训练实例来实现高性能。深度卷积网络威名远扬AlexNet的论文在学术机器学习社区引起了轰动,它的重要性也很快得到了业界的认可。谷歌对这项技术特别感兴趣。2013年,谷歌收购了AlexNet论文作者创办的一家初创公司。他们利用这项技术为谷歌照片添加了一个新的图像搜索功能。谷歌的Chuck Rosenberg写道:“我们直接从一个学术研究实验室进行了前沿研究,并在短短6个多月的时间里启动了它。”与此同时,谷歌2013年的一篇论文描述了它如何使用深度卷积网络从谷歌街景(Google Street View )的照片中读取地址码。“我们的系统帮助我们从街景图像中提取了近1亿个实体街道编号,”作者写道。研究人员发现,随着神经网络的发展,其性能不断提高。谷歌街景团队写道:“我们发现这种方法的性能随着卷积网络的深度而提高,在我们训练层级最多的架构中,性能最好。我们的实验表明,更深层次的架构可能获得更好的准确性,但效率会逐渐降低。”所以在AlexNet之后,神经网络变得越来越深。一个谷歌的团队在2014年ImageNet竞赛中提交的作品获得了优胜——就在2012年AlexNet获胜的两年后。和AlexNet一样,它也是基于一个深度卷积神经网络,但是谷歌使用了一个更深层的22层网络,从而获得了6.7 %的top5错误率——这比AlexNet的16%错误率有了很大的提高。不过,更深层的网络只对大型训练集有用。基于这个原因,Gerrish认为ImageNet数据集和竞争对深度卷积网络的成功起到了关键作用。大家还记得吗?ImageNet竞赛给了参赛者一百万张图片,要求他们从1000个不同的类别中选择一个。Gerrish说:“拥有100万张图片来训练你的神经网络,意味着每个类别有1000张图片(1m/1000 = 1000)。”他说,如果没有这么大的数据集,“你训练网络的参数就多得多。”近年来,人们聚焦于收集更大的数据,以便训练更深入、更准确的网络。这是自动驾驶汽车公司如此专注于在公共道路上积累里程的一大原因——来自测试的图像和视频被送回总部,用于培训公司的图像识别网络。深度学习计算的繁荣更深层次的网络和更大的训练集可以提供更好的性能,这一发现对更多的算力产生了无法满足的需求。AlexNet成功的一个重要原因是意识到,神经网络训练涉及矩阵运算,可以使用显卡高度并行的算力高效地执行这些运算。“神经网络是可并行的,”机器学习研究员唐杰说。显卡本来是为视频游戏提供大规模并行算力的,结果非常适合神经网络使用。“GPU的核心运算是极快的矩阵乘法,最终成为神经网络的核心运算,”唐说。这为英伟达(Nvidia)和AMD这两家行业领先的GPU制造商带来了滚滚财源。这两家公司都致力于开发适应机器学习应用程序独特需求的新芯片,而人工智能应用程序目前在这些公司的GPU销售中占据了相当大的比例。2016年,谷歌公开了一个定制芯片,称为张量处理单元(TPU),专门用于神经网络操作。谷歌2017年写道,虽然他们早在2006年就考虑过为神经网络构建专用集成电路(ASIC),但2013年这种情况变得紧迫起来。“就在那时,我们意识到神经网络快速增长的计算需求可能要求我们将运营的数据中心数量增加一倍。”最初,TPU仅允许谷歌自己的专有服务使用,但后来,谷歌开始允许任何人通过它的云计算平台使用这项技术。当然,谷歌并不是唯一一家致力于人工智能芯片的公司。一个小例子是,iPhone最新版本的芯片就包括一个为神经网络操作优化的“神经引擎”。英特尔正在开发自己的针对深度学习的优化芯片系列。特斯拉最近宣布放弃英伟达的芯片,转而采用自制神经网络芯片。亚马逊据说也在开发自己的AI芯片。为何深层神经网络难以理解我已经解释了深度神经网络是如何工作的,但我还没有真正解释它们的工作何以那么出色。大量的矩阵运算可以让计算机区分美洲虎和猎豹,接骨木和醋栗,这真令人惊讶。但也许神经网络最值得注意的地方是它们做不到的事。卷积使神经网络能够理解平移——它们可以判断一幅图像的右上角的模式是否与另一幅图像的左上角的模式相似。但除此之外,卷积网络并没有真正的理解几何图形。如果图像旋转45度或放大2倍,他们就无法识别出这两幅图像是否相似。卷积网络并没有尝试去理解三维物体的结构,而且它们也不能识别不同的光照条件。然而,深度神经网络能够识别狗的图片,无论它们是正面还是侧面拍摄的,无论它们是占据了图片的一小部分还是很大一部分。神经网络是怎么做到的?事实证明,有了足够的数据,暴力统计方法就足以完成这项工作。卷积网络的设计初衷并不是“想象”如果从不同的角度或在不同的环境下,一张特定的图像会是什么样子,但是有了足够多的标记样本,它可以通过纯粹的重复来学习所有可能的排列。有证据表明,人类的视觉系统实际上是以类似的方式工作的。我们来看这两张图片(在看第二张图片之前,确保你仔细看了第一幅图片):显然,这张照片的创作者把人像的眼睛和嘴巴颠倒过来,再把整张照片翻过来。当你把图像倒过来看时,它看起来相对正常,因为人类的视觉系统已经习惯了在这个方向上看眼睛和嘴。但是当你看后者时,就会发现人像面容变得畸形。这表明人类视觉系统依赖于一些与神经网络相同的粗糙模式匹配技术。如果我们看到的东西几乎都是同一个方向的——就如人类的眼睛——我们就能更好地识别出它们通常的方向。神经网络善于利用图片中的所有环境来理解它所显示的内容。例如,汽车通常出现在道路上。裙子通常要么出现在女性的身体上,要么挂在衣橱里。飞机要么在蓝天的衬托下出现,要么在跑道上滑行。没有人明确地教神经网络这些相关性,但有足够多的标记样本,网络可以自动学习它们。2015年,谷歌的一些研究人员试图通过“反向操作”来更好地理解神经网络。他们不是用图像来训练神经网络,而是用训练过的神经网络来修改图像。比如,他们从一幅包含随机噪声的图像开始,然后逐渐修改它,使其强烈地“点亮”神经网络的输出之一——要求神经网络高效地“绘制”一个它被训练识别的类别。在一个有趣的例子中,他们用一个被训练用来识别哑铃的神经网络来画图。研究人员在研究报告中写道:“这些是哑铃没错,但似乎都画出了肌肉发达的举重运动员来举哑铃。”乍一看,这似乎很奇怪,但实际上这与人类的行为并没有太大的不同。如果我们在一幅图像中看到一个小的或模糊的物体,我们就会观察周围的环境,寻找图片中可能发生的事情的线索。很明显,人类通过不同的方式对图像进行推理,利用我们对周围世界复杂的概念理解。总而言之,深层神经网络擅长于图像识别,是因为它们充分利用了图片中显示的所有环境,这与人类的识别方式并没有太大的不同。(完)专业词汇对照表neural network 神经网络computing power 算力convolutional network 卷积网络neuron 神经元weight 权重bias 偏置activation function 激活函数Non-linear activation function 非线性激活函数light up 亮灯(即匹配)layer 层receptive field 感受域backpropagation 反向传播top-five error rate top5错误率error gradient 误差梯度matrix 矩阵fully connected layer 全连接层pattern 模式feature detector 特征检测器brute-force statistical 暴力统计 ...

January 16, 2019 · 1 min · jiezi

重磅公开!阿里语音识别模型端核心技术,让你“听”见未来

阿里妹导读:语音识别技术作为人工智能技术中的重要组成部分,成为影响人机交互的核心组件之一,从各种智能家用IoT设备的语音交互能力,到公共服务、智慧政务等场合的应用,语音识别技术正在影响着人们生活的方方面面。本文将全面介绍阿里云语音识别技术中的重要模型端技术,希望和业界同仁交流探讨。声学模型、语言模型和解码器可以看作是现代语音识别系统最核心的三个组成部分。虽然最近有一些研究者尝试构建End2end的语音识别系统,但包含声学模型、语言模型和解码器的现代语音识别系统依然是当前最主流和使用最广泛的系统。在这其中,声学模型主要用来构建输入语音和输出声学单元之间的概率映射关系;语言模型用来描述不同字词之间的概率搭配关系,使得识别出的句子更像自然文本;解码器负责结合声学单元概率数值和语言模型在不同搭配上的打分进行筛选,最终得到最可能的识别结果。随着近几年深度学习的火热,语音识别领域也纷纷投入深度学习的大潮之中。将传统HMM-GMM声学模型替换成HMM-DNN声学模型后,可以获得超过20%的相对提升,在传统N-Gram语言模型基础上叠加NN-LM语言模型也可以获得进一步的提高。在这过程中,声学模型由于更适合采用深度神经网络模型,从而受到研究者更多的关注。本文主要介绍阿里云语音识别技术中采用的声学模型技术和语言模型技术,包括LC-BLSTM声学模型、LFR-DFSMN声学模型和NN-LM语言模型,其中LC-BLSTM是对传统BLSTM模型的一种改进,在保持了高准确率的同时,提供了低延时的特性;而DFSMN是一种新颖的非递归结构的神经网络却可以像RNN一样对信号的长时相关进行建模,同时可以获得更稳定的训练效果和更好的识别准确。NN-LM语言模型是近年来在传统N-Gram语言模型基础上获得的进一步改进。Latency-Controlled BLSTM模型DNN(即fully connected DNN)模型的优点在于通过增加神经网络的层数和节点数,扩展了网络对于复杂数据的抽象和建模能力,但同时DNN模型也存在一些不足,例如DNN中一般采用拼帧来考虑上下文相关信息对于当前语音帧的影响,这并不是反映语音序列之间相关性的最佳方法。自回归神经网络(RNN)在一定程度上解决了这个问题,它通过网络节点的自连接达到利用序列数据间相关性的目的。进一步有研究人员提出一种长短时记忆网络(LSTM-RNN),它可以有效减轻简单RNN容易出现的梯度爆炸和梯度消散问题,而后研究人员又对LSTM进行了扩展,使用双向长短时记忆网络(BLSTM-RNN)进行声学模型建模,以充分考虑上下文信息的影响。BLSTM模型可以有效地提升语音识别的准确率,相比于DNN模型,相对性能提升可以达到15%-20%。但同时BLSTM模型也存在两个非常重要的问题:1、句子级进行更新,模型的收敛速度通常较慢,并且由于存在大量的逐帧计算,无法有效发挥GPU等并行计算工具的计算能力,训练会非常耗时;2、由于需要用到整句递归计算每一帧的后验概率,解码延迟和实时率无法得到有效保证,很难应用于实际服务。对于这两个问题,学术界首先提出Context-Sensitive-Chunk BLSTM(CSC-BLSTM)的方法加以解决,而此后又提出了Latency Controlled BLSTM(LC-BLSTM)这一改进版本,更好、更高效地减轻了这两个问题。我们在此基础上采用LC-BLSTM-DNN混合结构配合多机多卡、16bit量化等训练和优化方法进行声学模型建模,取得了相比于DNN模型约17-24%的相对识别错误率下降。典型的LSTM节点结构由3个gate组成:input gate、forget gate、output gate和一个cell组成,输入、输出节点以及cell同各个门之间都存在连接;inputgate、forget gate同cell之间也存在连接,cell内部还有自连接。这样通过控制不同门的状态,可以实现更好的长短时信息保存和误差传播。LSTM可以像DNN一样逐层堆积成为DeepLSTM,为了更好地利用上下文信息,还可以使用BLSTM逐层堆积构造Deep BLSTM,其结构如下图所示,网络中沿时间轴存在正向和反向两个信息传递过程,每一个时间帧的计算都依赖于前面所有时间帧和后面所有时间帧的计算结果,对于语音信号这种时序序列,该模型充分考虑了上下文对于当前语音帧的影响,能够极大提高音素状态的分类准确率。然而由于标准的BLSTM是对整句语音数据进行建模,训练和解码过程存在收敛慢、延迟高、实时率低等问题,针对这些弊端我们采用了Latency Controlled BLSTM进行解决,与标准的BLSTM使用整句语音进行训练和解码不同,Latency Control BLSTM使用类似truncated BPTT的更新方式,并在cell中间状态处理和数据使用上有着自己的特点,如下图所示,训练时每次使用一小段数据进行更新,数据由中心chunk和右向附加chunk构成,其中右向附加chunk只用于cell中间状态的计算,误差只在中心chunk上进行传播。时间轴上正向移动的网络,前一个数据段在中心chunk结束时的cell中间状态被用于下一个数据段的初始状态,时间轴上反向移动的网络,每一个数据段开始时都将cell中间状态置为0。该方法可以很大程度上加快网络的收敛速度,并有助于得到更好的性能。解码阶段的数据处理与训练时基本相同,不同之处在于中心chunk和右向附加chunk的维度可以根据需求进行调节,并不必须与训练采用相同配置。LFR-DFSMN模型FSMN是近期被提出的一种网络结构,通过在前馈全连接神经网络(Feedforward Fully-connectedNeural Networks,FNN)的隐层添加一些可学习的记忆模块,从而可以有效地对信号的长时相关性进行建模。FSMN相比于LCBLSTM不仅可以更加方便的控制时延,而且往往也能获得更好的性能,需要的计算资源也更少。但是标准的FSMN很难训练非常深层的结构,由于梯度消失问题导致训练效果不好。而深层结构的模型目前在很多领域被证明具有更强的建模能力。因而针对此我们提出了一种改进的FSMN模型,称之为深层的FSMN(Deep FSMN, DFSMN)。进一步的我们结合低帧率(Low Frame Rate,LFR)技术构建了一种高效的实时语音识别声学模型,相比于去年我们上线的LFR-LCBLSTM声学模型可以获得超过20%的相对性能提升,同时可以获得2-3倍的训练以及解码的加速,可以显著的减少我们的系统实际应用时所需要的计算资源。最早提出的FSMN的模型结构如上图(a)所示,其本质上是一个前馈全连接神经网络,通过在网络的某些隐层旁添加一些记忆模块(memory block)来对当前时刻周边的上下文信息进行建模,从而使得模型可以对时序信号的长时相关性进行建模。记忆模块采用如上图(b)所示的抽头延迟结构将当前时刻以及之前 N 个时刻的隐层输出通过一组系数编码得到一个固定的表达。FSMN的提出是受到数字信号处理中滤波器设计理论的启发:任何无限响应冲击(Infinite Impulse Response, IIR)滤波器可以采用高阶的有限冲击响应(FiniteImpulseResponse, FIR)滤波器进行近似。从滤波器的角度出发,如上图(c)所示的RNN模型的循环层就可以看作如上图(d)的一阶IIR滤波器。而FSMN采用的采用如上图(b)所示的记忆模块可以看作是一个高阶的FIR滤波器。从而FSMN也可以像RNN一样有效的对信号的长时相关性进行建模,同时由于FIR滤波器相比于IIR滤波器更加稳定,因而FSMN相比于RNN训练上会更加简单和稳定。根据记忆模块编码系数的选择,可以分为:标量FSMN(sFSMN)矢量FSMN(vFSMN)sFSMN 和 vFSMN 顾名思义就是分别使用标量和矢量作为记忆模块的编码系数。以上的FSMN只考虑了历史信息对当前时刻的影响,我们可以称之为单向的FSMN。当我们同时考虑历史信息以及未来信息对当前时刻的影响时,我们可以将单向的FSMN进行扩展得到双向的FSMN。FSMN相比于FNN,需要将记忆模块的输出作为下一个隐层的额外输入,这样就会引入额外的模型参数。隐层包含的节点越多,则引入的参数越多。研究结合矩阵低秩分解(Low-rank matrix factorization)的思路,提出了一种改进的FSMN结构,称之为简洁的FSMN(Compact FSMN,cFSMN)。下图是一个第l个隐层包含记忆模块的cFSMN的结构框图。对于cFSMN,通过在网络的隐层后添加一个低维度的线性投影层,并且将记忆模块添加在这些线性投影层上。进一步的,cFSMN对记忆模块的编码公式进行了一些改变,通过将当前时刻的输出显式的添加到记忆模块的表达中,从而只需要将记忆模块的表达作为下一层的输入。这样可以有效的减少模型的参数量,加快网络的训练。上图是我们进一步提出的Deep-FSMN(DFSMN)的网络结构框图,其中左边第一个方框代表输入层,右边最后一个方框代表输出层。我们通过在cFSMN的记忆模块(红色框框表示)之间添加跳转连接(skip connection),从而使得低层记忆模块的输出会被直接累加到高层记忆模块里。这样在训练过程中,高层记忆模块的梯度会直接赋值给低层的记忆模块,从而可以克服由于网络的深度造成的梯度消失问题,使得可以稳定的训练深层的网络。相比于之前的cFSMN,DFSMN优势在于,通过跳转连接可以训练很深的网络。对于原来的cFSMN,由于每个隐层已经通过矩阵的低秩分解拆分成了两层的结构,这样对于一个包含4层cFSMN层以及两个DNN层的网络,总共包含的层数将达到13层,从而采用更多的cFSMN层,会使得层数更多而使得训练出现梯度消失问题,导致训练的不稳定性。我们提出的DFSMN通过跳转连接避免了深层网络的梯度消失问题,使得训练深层的网络变得稳定。需要说明的是,这里的跳转连接不仅可以加到相邻层之间,也可以加到不相邻层之间。跳转连接本身可以是线性变换,也可以是非线性变换。具体的实验我们可以实现训练包含数十层的DFSMN网络,并且相比于cFSMN可以获得显著的性能提升。从最初的FSMN到cFSMN不仅可以有效的减少模型的参数,而且可以获得更好的性能。进一步的在cFSMN的基础上,我们提出的DFSMN,可以更加显著的提升模型的性能。如下表是在一个2000小时的英文任务上基于BLSTM,cFSMN,DFSMN的声学模型性能对比。从上表中可以看到,在2000小时这样的任务上,DFSMN模型可以获得比BLSTM声学模型相对14%的错误率降低,显著提高了声学模型的性能。传统的声学模型,输入的是每帧语音信号提取的声学特征,每帧语音的时长通常为10ms,对于每个输入的语音帧信号会有相对应的一个输出目标。最近有研究提出一种低帧率(Low Frame Rate,LFR)建模方案:通过将相邻时刻的语音帧进行绑定作为输入,去预测这些语音帧的目标输出得到的一个平均输出目标。具体实验中可以实现三帧(或更多帧)拼接而不损失模型的性能。从而可以将输入和输出减少到原来的三分之一甚至更多,可以极大的提升语音识别系统服务时声学得分的计算以及解码的效率。我们结合LFR和以上提出的DFSMN,构建了基于LFR-DFSMN的语音识别声学模型,经过多组实验我们最终确定了采用一个包含10层cFSMN层+2层DNN的DFSMN作为声学模型,输入输出则采用LFR,将帧率降低到原来的三分之一。识别结果和去年我们上线的最好的LCBLSTM基线比较如下表所示。通过结合LFR技术,我们可以获得三倍的识别加速。从上表中可以看到,在实际工业规模应用上,LFR-DFSMN模型比LFR-LCBLSTM模型可以获得20%的错误率下降,展示了对大规模数据更好的建模特性。NN-LM语言模型语言模型,顾名思义,对语言进行建模的模型。语言表达可以看作一串字符序列,不同的字符序列组合代表不同的含义,字符的单位可以是字或者词。语言模型的任务,可以看作是给定字符序列,如何估计该序列的概率,或者说,如何估计该序列的合理性。P(上海 的 工人 师傅 有 力量)>P(上海 的 工人 食腐 有 力量)拿这句话做个例子。比如到底应该是“工人师傅有力量”,还是“工人食腐有力量”,哪句话更“合适”。我们容易判断左边这句的概率大一点。于是我们希望通过语言模型的建模,可以给出符合人类预期的概率分配。就像这句,“工人师傅”的概率,大于“工人食腐”的概率。基于统计词频的传统N元文法模型,通过马尔可夫假设简化了模型结构和计算,通过计数的方式计算,通过查找的方式使用。拥有估计简单、性能稳定、计算快捷的优势,有超过三十年的使用历史。然而其马尔科夫假设强制截断建模长度,使得模型无法对较长的历史建模;基于词频的估计方式也使得模型不够平滑,对于低词频词汇估计不足。随着神经网络(Neural Networks,NNs)的第三次崛起,人们开始尝试通过NN来进行语言模型建模。一个典型的建模结构是递归神经网络(recurrentneural networks,RNNs),其递归的结构理论上可以对无穷长序列进行建模,弥补了N元文法对于序列长度建模的不足;同时其各层间的全向连接也保证了建模的平滑。此外为了提升模型的性能,研究者们还尝试了通过长短时记忆(Long Short-Term Memory,LSTM)结构来提升基本RNN本身建模能力的不足,进一步提升模型性能。NN用于大规模语言建模的系统中,需要面对一些问题,例如大词表带来的存储和计算增加。实际线上系统的词表往往比较大,而随着词表的增加,基本RNN结构的存储和计算量都会几何级数爆炸式增长。为此,研究者们进行了一些尝试,压缩词典尺寸成了一个最直接的解决方案,一个经典的方法是词表聚类。该方法可以大幅压缩词表尺寸,但往往也会带来一定的性能衰减。更直接的一个想法是直接过滤掉低频词汇,这样依然会带来一定的性能衰减,据此有一个改进策略,我们发现真正制约速度性能的主要是输出层节点,输入层节点大,借助projection层可以很好解决,于是输入层采用大辞典,而仅对输出层词表进行抑制,这样不仅尽可能地降低了损失,同时过滤掉过低的词频,也有利于模型节点的充分训练,性能往往还会略有提升。词表的压缩可以提升建模性能,降低计算量和存储量,但仅限于一定的量级,不可以无限制压缩,如何继续降低计算量依然是一个问题。一些方法被提了出来。例如LightRNN,通过类似聚类的方式,利用embedding的思想,把词表映射到一个实值矩阵上,实际输出只需要矩阵的行加矩阵的列,计算量大概也能开个方。和节点数多一起造成计算量大的一个原因就是softmax输出,需要计算所有的节点求个和,然后得到分母。若是这个分母能保持一个常数,实际计算的时候就只算需要的节点,在测试环节就快的多了。于是就有了正则项相关的方法,Variance Regularization,如果训练速度可以接受的话,这种方法在基本不损失模型正确性的情况下可以大幅提升前向计算速度;如果训练的时候也想提速,还可以考虑基于采样,sampling的方法,比如NCE、Importance Sampling、Black Sampling等,本质上就是说,在训练的时候不计算全部节点,只计算正样本(也就是标签为1的节点),以及部分通过某种分布采样的到的负样本,避免高输出造成的计算缓慢。速度上提升还是很明显的。从阿里云获得开发者模型定制能力想象一个做智能电话客服或是智能会议系统的开发者,需要为他的系统接入语音识别(将语音转写为文字)的能力。摆在他面前的会是这样一个尴尬的局面:一个选择是自己从零开始学做语音识别,这可能要花费大量的时间和金钱。毕竟人工智能这种事情,各大互联网巨头投入大量的人力、物力、财力,也要花较长的时间才能积累下技术;第二个选择是用上述巨头们在互联网上提供的开箱即用的、one size fits all的语音识别接口,时间是省下了,但语音转文字的准确率嘛,只能碰碰运气,毕竟巨头们也很忙,没有精力为你关注的场景进行优化。那么问题来了:有没有一种手段能够以最小的投入获得业务上最佳的语音识别效果呢?答案是肯定的。阿里云依托达摩院业界领先的语音交互智能,打破传统语音技术提供商的供给模式,在云计算时代让普通开发者也能够通过阿里云提供的语音识别云端自学习技术,获得定制优化自己所关心的业务场景的成套手段。阿里云让广大的开发者站在巨头的肩膀上,通过自主可控的自学习,在短时间内实现对语音识别系统应用从入门到精通,并在开发者关心的场景下轻松拥有业界顶尖的语音识别准确率。这就是云计算时代的语音识别技术全新的供给模式。与其它人工智能技术一样,语音识别技术的关键在于算法、算力和数据三个方面。阿里云依托达摩院语音交互智能,近年来持续在世界前沿进行“算法”演进,近期还将最新的研究成果DFSMN声学模型开源,供全世界的研究者复现目前最佳的结果并进行持续提升。在“算力”方面自不用说,这本身就是云计算的天然强项。基于阿里云ODPS-PAI平台,我们构建了专为语音识别应用优化的CPU/GPU/FPGA/NPU训练和服务混布平台,每天服务于阿里云上巨量的语音识别请求。在“数据”方面,我们提供通过海量数据训练的、开箱即用的场景模型,包括电商、客服、政务、手机输入等等。同时应该看到,在具体的落地场景下往往会有一些非常特殊、领域相关的“说法”需要被识别,很多时候类似于“碎屑岩岩性地层”、“海相碳酸盐岩”这种特定说法对于通用场景模型的识别率提出了挑战。要获得开发者关心的具体场景下最佳的准确率,开箱即用的模型一般还需要一定的定制优化工作才可以达到。传统上,这样的定制是通过语音技术服务提供商来完成的,在成本、周期、可控性等方面都存在明显不足。阿里云提供的语音定制“自学习”平台服务,可以提供多种手段,在很短的时间内、以较低的成本,让开发者完全掌控模型定制优化及上线的工作。阿里云创新工具平台及服务技术,依托强大的基础设施,使得在云计算的大背景下进行大规模定制化语音服务成为可能。而开发者完全无需关心后台的技术和服务,只需要使用阿里云提供的简单易用的“自学习”工具,利用场景知识和数据,就可以获得该特定场景下最优的效果,并按需要持续迭代提升。阿里云的智能语音自学习平台具备以下优势:易:智能语音自学习平台颠覆性地提供一键式自助语音优化方案,极大地降低进行语音智能优化所需要的门槛,让不懂技术的业务人员也可以来显著提高自身业务识别准确率。快:自学习平台能够在数分钟之内完成业务专属定制模型的优化测试上线,更能支持业务相关热词的实时优化,一改传统定制优化长达数周甚至数月的漫长交付弊端。准:自学习平台优化效果在很多内外部合作伙伴和项目上得到了充分验证,很多项目最终通过自学习平台不光解决了效果可用性问题,还在项目中超过了竞争对手使用传统优化方式所取得的优化效果。举例来说,开发者可以使用下述多种“自学习”手段来定制自己关心领域的模型:a)业务热词定制在许多特定场所,要求快速对特定词的识别能力进行加强(注:包括两种模式,模式一为其他词易被识别成特定词;模式二为特定词易被识别成其他词),采用实时热词加载技术,可以在实时场景下,通过设置不同的档位,能够实现热词识别能力的加强。b)类热词定制很多时候,相同的发音相同的属性在不同上下文上会需要不同的识别效果。联系人和地名就是典型的案例,对于不同人的好友,“张阳”和“章扬”我们就必须能准确地识别出相应的名字。同样,相隔千里的安溪跟安西如果识别错误会给导航带来大麻烦。智能语音自学习平台相信“每个人都值得被尊重”,提供联系人类和地名类的定制能力,“让天下没有难识的路”。c)业务专属模型定制用户通过输入对应领域的相关文本,如行业或公司的基本介绍、客服聊天记录、领域常用词汇和专有名词等,即可快速自行生成该行业下的定制模型,整个定制过程无需用户人工干预。通过这些手段,阿里云使得开发者不必关心语音技术的算法和工程服务细节,专注于他们擅长的垂直领域的知识和数据收集,实现全新的语音技术云端供给模式,造福于广大的开发者及其业务结果。本文作者:鄢志杰、薛少飞、张仕良、郑昊、雷鸣阅读原文本文来自云栖社区合作伙伴“阿里技术”,如需转载请联系原作者。

January 15, 2019 · 1 min · jiezi

2018最佳GAN论文回顾(上)

摘要: 受Reddit网站上讨论区的启发,我决定快速地浏览一下2018年关于GAN最有趣的文章。我很高兴今年参加了一个研究项目,这要求我必须熟悉大量用于计算机视觉方面的深度学习领域的资料。我对过去两、三年内取得的进展感到惊讶,这真的非常令人兴奋和鼓舞,所有不同的子领域,如图像修复、对抗性样本、超分辨率或是三维重建,都大大得益于近期的发展。然而,有一种神经网络,它受到了大量的宣传和炒作 — 生成性对抗网络(Generative Adversarial Networks,GANs)。我也认为这种模型是非常吸引人的,并且我也一直在寻找一些GAN的新思路。受Reddit网站上讨论区的启发,我决定快速地浏览一下2018年关于GAN最有趣的文章。这份名单非常的主观 — 我选择的研究论文不仅是最高水平的,而且也都非常的有趣。在第一章中,我将讨论其中的三篇。顺便说一下,如果你对以前的GAN论文感兴趣,这一篇文章可能会有所帮助,作者在文中提到的一篇论文排在了我的名单上的第一位。1.GAN解析:可视化和理解生成性对抗网络 — 考虑到GAN的大肆宣传,很明显这项技术迟早会被商业化应用。然而,因为我们对其内部机制了解的不多,所以我认为要生产一个可靠的产品仍然很困难。不过这项工作仍然向未来迈出了巨大的一步,在未来我们能够真正控制GAN。因此,一定要看看他们伟大的交互演示,结果是令人震惊的;2.一种用于生成性对抗网络的基于生成器体系结构 – NVIDIA(英伟达)的研究团队会定期地提出一些具有开创性的概念(2018年的关于图像修复的论文,近期的用神经网络进行图形绘制的演示)。这篇论文也不例外,加上显示结果的视频就更有吸引力了;3.进化生成性对抗网络 — 这是一个真正简单易懂的文章。进化算法和GAN一起 — 这肯定很有趣;GAN解析: 可视化和理解生成性对抗网络(GAN Dissection: Visualizing and Understanding Generative Adversarial Networks)详解该论文已于2018年11月26日提交。作者以交互式演示的方式创建了一个非常不错的项目网站。主要思想:GAN无疑证明了深度神经网络的强大。机器学习生成令人震惊的、高分辨率图像的方式是非常美妙的,就仿佛它像我们一样了解这个世界。但是,和其它的那些出色的统计模型一样,GAN最大的缺陷是缺乏可解释性。这项研究为理解GAN迈出了非常重要的一步。它允许我们在生成器中找到“负责”生成某些属于class c的对象单元。作者们声称,我们可以检查生成器的一个层,并找到导致在生成图像中形成c对象的单元子集。作者们通过两个步骤:解剖和干预,为每个类寻找一组“因果”单元。另外,这可能是第一项工作,为了解GAN的内部机制提供了系统的分析。方法:生成器G可以被看作是从潜在的向量z到一个生成的图像x=G(z)的映射。我们的目标是理解参数r,一种内部的表示,它是生成器G的特定层的输出。x=G(z)=f(r)关于c类的对象,我们想仔细看下参数r。我们知道参数r包含关于一个这些特定对象生成的编码信息。我们的目标是了解这个信息是如何在内部编码的。作者们声称有一种方法可以从参数r中提取这些单元,而r负责生成类c的对象。这里,是特定层中所有单元的集合,参数U是目标单元,参数P是像素位置。问题来了,如何进行这种分离?作者们提出了两个步骤,这两个步骤是理解GAN黑盒子的工具。就是解析和干预。解析 — 我们要识别那些有趣的类,它们在r中有一个明确的表示方法。这基本上是通过比较两个图像来完成的。首先通过计算x获得第一个图像,然后通过语义分割网络来运行。这将返回与目标类别(例如:树木)相对应的像素位置。第二个图像是通过用ru,p进行上采样,因此它与sc(x)的维度相匹配,然后再对其进行阈值处理,以便对被这个特定单元所“发亮”的像素做出艰难的决定。最后,我们计算了两个输出之间的空间一致性。值越高,单元u对类c的因果效应就越大。通过对每个单元执行这个操作,我们最终应该找出哪些类在r的结构中有一个明确的表示方法。干预 — 在这一点上,我们已经确定了相关的类。现在,我们试图为每个类找到最好的分离方式。这意味着,一方面我们抑制非受迫单元,希望目标类将从生成的图像上消失。另一方面,我们扩大了因果单元对生成图像的影响。这样我们就可以了解到他们对目标类c的存在有多大的贡献。最后,我们从两个图像中分割出类c并进行对比。语义图之间的一致性越小越好。这意味着在一个图像上,我们完全“排除”了树木的影响,而第二个图像只包含一片树林。结果:a)Progressive GAN生成的教堂图像 b)根据所给的预训练的Progressive GAN,我们确定了负责生成“树”类的单元 c)我们可以阻止那些单元“删除”图像中的树 d)扩大图像中树的密度。上述结果表明,我们对网络内部的机制有了很好的理解。这些见解可以帮助我们改善网络行为。了解图像的哪些特征来自于神经网络的哪个部分,对于理解说明、商业应用和进一步的研究都是非常有价值的。a)出于调试的目的,我们可以确定那些有伪影的单元……,b)和c)把它们去掉了,以“修复”GAN。一个可以解决的问题是在生成的图像中有看得见的伪影。即使是一个训练很好的GAN有时也能产生一个极其不现实的图像,而这些错误的原因以前是未知的。现在我们可以将这些错误与导致视觉伪影的神经元联系起来。通过识别和阻止这些单元,可以提高生成的图像质量。通过将某些单元设置为固定的平均值(例如,门),我们可以确保门将出现在图像中的某个位置。当然,这不会违反学过的分布统计(我们不能强迫门出现在空中)。另一个限制来自于这样一个事实,即一些对象与某些位置之间的联系是非常的紧密,以至于无法将它们从图像中消除。举个例子:不能简单地把椅子从会议室里删除掉,那样只会降低它们像素的密度或尺寸。一种用于生成性对抗网络的基于生成器体系结构(A Style-Based Generator Architecture for Generative Adversarial Networks详述该论文已于2018年12月12日提交,代码很快就将会发布。另外,对于那些想更多了解这种方法但并不想阅读论文的人来说,博客上发表了一篇很好的总结文章。主要思想:这项工作提出了关于GAN框架的另一个观点。更具体地说,它从样式转换设计中吸取灵感,创建了一个生成器架构,在生成的图像中可以学习高级属性(如年龄、在人脸或背景上训练时的身份、相机视角)和随机变化(雀斑、头发细节)。它不仅学习自动分离这些属性,而且还允许我们以非常直观的方式控制合成。方法:传统的GAN架构(左)与基于样式的生成器(右)。在新的框架中,我们有两个网络组件:映射网络f与综合网络g。前者将一个潜在的代码映射到一个中间的潜在空间W,W对样式的信息进行编码。后者利用生成的样式和高斯噪声来创建新的图像。块“A”是一个训练过的仿射转换,而块“B”将训练过的每个通道的比例因子应用于噪声的输入。在经典的GAN方法中,生成器以一些潜在的代码作为输入,并输出一个图像,这属于它在训练阶段所学习到的分布。作者们通过创建一个基于样式的、由两个元素组成的生成器来背离这种设计:1.一个全连接的网络,代表着非线性映射 f:Z→W;2.一个综合网络g;全连接的网络 — 通过变换一个标准化的潜在向量z∈Z,我们得到了一个中间的潜在向量w=f(z)。中间的潜在空间W有效地控制了生成器的样式。作为旁注,作者确保避免从W的低密度区域采样。虽然这可能造成w的变化损失,但据说最终会导致更好的平均的图像质量。现在,一个从中间的潜在空间采样的潜在向量w被输入到块“A”(训练的仿射变换)中,并转换成样式y=(ys,yb)。最后通过每个卷积层的自适应实例标准化(adaptive instance normalization,AdaIN)将该风格添加到合成网络中。AdaIN操作是这样定义的:合成网络 — AdaIN的操作通过对其进行标准化来改变每个特征图xi,然后使用来自样式y的分量进行比例缩放和移位。最后,生成器的特征映射也被提供了一个直接的方式来生成随机细节 — 显式的噪声输入 — 以包含不相关高斯噪声的单通道图像的形式。综上所述,虽然显式的噪声输入可以被视为在合成网络中生成过程的“种子”,但从W抽取的潜在代码试图向图像添加某种样式。结果:作者们从2017年的Progressive GAN开始重新审视NVIDIA的架构。虽然他们掌握了大部分的架构和超参数,但是生成器正在根据新的设计进行“升级”。论文内容最令人印象深刻的特点是样式的混合。上图是可视化样式混合的效果。通过让一个潜在的代码(来源)生成一个图像,我们可以覆盖另一个图像(目标)的特征子集。这里,我们覆盖对应于粗糙空间分辨率(低分辨率特征图)的层。这样我们就可以影响目标图像的高级特征了。这种新奇的生成器结构使其有能力在合成网络的不同层向同一图像添加不同的样式。在训练过程中,我们通过映射网络运行两个潜在代码z1和z2,并接收相应的w1和w2两个向量。完全由z1生成的图像被称为目标。这是一个生成的高分辨率图像,几乎与实际的分布区区分不出来。仅通过添加z2而生成的图像被称为来源。现在,在使用z1生成目标图像的过程中,在某些层,我们可以添加z2的代码了。此操作将用那些来源来覆盖目标中存在的样式子集。来源对目标的影响是由层的位置来控制的,这些层正被来源的潜在代码进行“培育”。与特定层对应的分辨率越低,来源对目标的影响越大。这样,我们就可以决定要在多大程度上影响目标图像:粗糙空间分辨率(分辨率42−82) — 高级方面,如:发型、眼镜或年龄;中间样式分辨率(分辨率162−322) — 较小比例的面部特征,如:发型样式的细节、眼睛;精细分辨率(分辨率642−10242)—只需修改一些小细节,如:头发颜色、肤色色调或皮肤结构;作者们将他们的方法进一步应用到汽车、卧室甚至是猫的图像中,得到了令人震惊的结果。我仍然困惑为什么网络的决定会影响到猫的图像中爪子的位置,而不会关心汽车图像中车轮的转动……我发现真正令人惊奇的是,这个框架可以进一步应用于不同的数据集,比如汽车和卧室的图像。进化生成性对抗网络(Evolutionary Generative Adversarial Networks)细节该论文已于2018年3月1日提交。主要思想:在传统设置中,GAN通过交替更新生成器和使用反向传播的识别器进行训练。利用在目标函数中的交叉熵机制,实现了双人minmax 游戏。E-GAN的作者们提出了一种基于进化算法的可替代GAN框架。他们以进化问题的形式重新声明了损失函数。生成器的任务是在识别器的影响下承受不断地突变。根据“适者生存”的原则,我们希望最新一代生成器以这样的方式“进化”,从而学会正确的训练样本分布。方法:原始的GAN框架(左)与E-GAN框架(右)。在E-GAN框架中,全部的G生成器在一个动态环境中进化 — 即识别器D。该算法涉及三个阶段:变化、评估和筛选。最好的子版本被保留下来以供下一次迭代的时候使用。进化算法试图在一个给定的环境(这里是指识别器)中进化全部的生成器。生成器中的每个个体都代表了生成网络参数空间中的一个可能的解决方案。进化过程归结为三个步骤:1.变化:通过根据一些突变属性而自我修改,生成器的单个G生成其子级[图片上传失败…(image-5fce9b-1547434233756)] …;2.评估:每个子级都将使用一个适应函数进行评估,该函数取决于识别器的当前状态;3.筛选:我们对每个子级进行评估,并决定它在适应函数的方面是否足够好,如果是,它将被保留,否则就会被丢弃;上述这些步骤涉及到两个应该被详细讨论的概念:突变和适应函数:突变 — 这些是在“变化”步骤中给子级引入的改变。最初的GAN训练目标激发了他们的灵感。作者们区分了三种最有效的突变类型。它们是minmax突变(鼓励将Jensen-Shannon分歧最小化)、启发式突变(添加了反向Kullback-Leibler分歧项)和最小二乘突变(受LSGAN的启发);适应函数— 在进化算法中,一个适应函数告诉我们一个给定的子级离达到设定的目标有多接近。这里,适应函数包括两个要素:质量适应得分和多样性适应得分。前者确保了生成器能够提供欺骗识别器的输出,而后者则关注生成样本的多样性。因此,一方面,培育子版本不仅要很好地接近原始分布,而且还要保持多样性,并且避免模式崩溃的陷阱。作者们声称他们的方法解决了多个众所周知的问题。E-GAN不仅在稳定性和抑制模式崩溃方面做得更好,还减轻了选择超参数和架构(对收敛至关重要)的压力。最后,作者们声称E-GAN比传统的GAN框架收敛得更快。结果:该算法不仅对合成数据进行了测试,而且还对CIFAR-10的数据集和Inception进行了测试。作者们修改了流行的GAN方法,如DCGAN,并在实际的数据集上对其进行了测试。结果表明,通过训练E-GAN,可以从目标数据分布中生成各种高质量的图像。根据作者们的想法,在每一个筛选步骤中只保留一个子级就足以成功地将参数空间遍历到最优的解决方案。我发现E-GAN的这个属性非常有趣。另外,通过对空间连续性的仔细检查,我们可以发现,E-GAN的确从潜在的噪声空间到图像空间学习了一种有意义的预测。通过在潜在向量之间进行插值,我们可以获得平稳地改变有语义意义的人脸属性的生成图像。在潜在空间中线性地插值。生成器已经从CelebA数据集中学习了图像的分布。=0.0对应着从向量z1生成一个图像,而=1.0则意味着图像来自向量z2。通过改变alpha的取值,我们可以在潜在的空间内进行插值,效果非常好。本文中所有的数据都来自于我的博客上面发布的文章。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 14, 2019 · 1 min · jiezi

揭秘人工智能(系列):深度学习是否过分夸大?

摘要: 深度学习可能不是过分夸大,也许它只是没有很好地被理解!2012年左右,多伦多大学的研究人员首次使用深度学习来赢下了ImageNet,它是一项非常受欢迎的计算机图像识别竞赛。对于那些参与AI行业的人来说,这是一个大问题,因为计算机视觉是使计算机能够理解图像背景的学科,也是人工智能中最具挑战性的领域之一。当然,与任何其他产生巨大影响的技术一样,深度学习成为炒作的焦点。不同的公司和组织开始应用它来解决不同的问题(或假装应用它)。许多公司开始使用深度学习和先进的人工智能技术重塑其产品和服务。与此同时,媒体也经常撰写有关人工智能和深度学习的故事,这些故事充满误导性,并且大多是由那些对技术运作方式没有正确理解的人撰写。他们大多使用关于人工智能的耸人听闻的头条来博眼球,这些也促成了围绕深度学习的炒作。经过媒体的炒作后,许多专家认为深度学习被夸大了,它最终会消退并可能导致另一个人工智能冬季,从而使人们对人工智能的兴趣和资金投入大幅下降。其中一些著名专家也承认,深度学习已经触底,其中包括一些深入学习的先驱者。但根据著名数据科学家和深度学习研究员杰里米·霍华德的说法,“深度学习过度夸大”的论点有点夸张。霍华德是fast.ai的创始人,<u style=“box-sizing: border-box;">fast.ai</u>是一个非营利性的在线深度学习课程。今年,霍华德在USENIX Enigma会议上发表的演讲中发表了许多反对深度学习的论点。整个视频非常清楚地说明了深度学习究竟做了什么和不做什么,这个演讲可以帮助你清楚地了解该领域。以下是霍华德演讲主要反驳的几个论点:深度学习只是一种时尚-明年它将是另一回事(NO!)许多人认为深度学习是突然冒出来,最终也会突然消失。霍华德反驳解释到:“你今天在深度学习中实际看到的是几十年研究的结果,而这几十年的研究终于达到了实际上给出最先进成果的程度。”人工神经网络的概念是深度学习算法的主要组成部分,它已存在数十年,第一个神经网络可以追溯到20世纪50年代。但是,由于数十年的研究以及数据和计算资源的可用性,深度学习的概念已经从实验室走出并进入实际领域。霍华德说:“利用深度学习,人们可以减少很多复杂的繁琐的事务,我们应该期待看到[深度学习]继续发展下去而不是消失。”深度学习和机器学习是一回事(NO!)滥用人工智能词汇很容易导致了从业人员对行业的混淆和怀疑。有人说深度学习只是机器学习的另一个别称,而其他人则认为它与其他AI技术(如支持向量机(SVM),随机森林和逻辑回归)属于同一水平。但深度学习和机器学习并不相同,深度学习是机器学习的一个子集。通常,机器学习适用于基于训练数据的数学模型和行为规则的所有技术。ML技术已经投入生产使用了很长时间。在深度学习之前,科学家们必须在编写“功能”或模块方面投入大量精力,这些功能可以执行模型想要执行的任务的一小部分。例如,如果你想创建一个可以检测猫的图像的AI模型,你将不得不编写较小的程序来检测猫的特征,如耳朵、尾巴、鼻子、皮毛。而且你必须使这些程序足够强大,以便从不同角度和不同光照条件下检测这些特征,并告诉不同猫种之间的差异。最后你才能在这些功能之上进行机器学习。如果你想解决更复杂的问题,如通过MRI扫描检测乳腺癌,那么创建特征将变得更具挑战性。霍华德说:“你将需要数十名领域专家与数十名计算机程序员和数学家合作,提出这些功能概念并对其进行编程。最后使用一个经典的机器学习模型,如逻辑回归。”这项工作大概需要数年的工作。![经典的机器学习方法涉及许多复杂的步骤,需要数十名领域专家、数学家和程序员的合作](https://upload-images.jianshu…深度学习用神经网络取代了艰苦的经典机器学习过程。霍华德将神经网络描述为“无限灵活的函数”。这意味着神经网络可以应用于机器学习解决的大多数问题,而无需通过以前必须执行的所有特定于域的特征工程。要想神经网络解决特定问题,你需要调整其参数。为此,深度学习使用“梯度下降”,这是一种通用优化算法,可以将神经网络的参数与其想要解决的问题相匹配。最后,深度学习利用了近年来可用的GPU和专用硬件的强大功能,以合理快速和可扩展的方式执行这些任务。霍华德说:“只有在过去的几年里,这三件事情才能让我们真正使用神经网络来获得最先进的结果。”因此,深度学习不是通过以前机器学习方法所涉及的专业知识密集型和容易出错的过程,而是提供样本数据(例如标记为猫图片,标记为癌症或非癌症的MRI扫描…)并训练神经元使用梯度下降的网络。神经网络比较并找到这些数据样本中的常见模式,并学习应用相同的知识来分类以前从未见过的新数据样本。这种方法在过去几年中深入学习了最流行的人工智能技术,并引发了使用深度学习的应用程序的爆炸式增长。深度学习只对图像识别有益(NO!)很多人都承认深度学习是一种非常有用的人工智能技术,但很多批评者都抱怨它的使用仅限于解决涉及图像分类的问题!“图像识别非常重要!”霍华德说。几年前,霍华德和一组研究人员在肺部CT扫描上训练了一个深度神经网络,并创建了一种算法,可以检测恶性癌症肿瘤,这个算法的结果诊断的结果与四名人类放射科医师相比,假阳性和阴性率更低。霍华德还指出,许多问题可以重新理解为图像识别问题。例如,在中国古代游戏围棋中击败世界冠军的深度学习算法AlphaGo实际上是一个图像识别的卷积神经网络(CNN)。“具体来说,AlphaGo所做的是看了很多在真人玩过的围棋的例子”霍华德解释道。“基本上,他们最终做了一个图像识别神经网络,他们试图学习的东西不是这张照片是猫还是狗,而是这是一张白子赢或黑赢的围棋照片。”这种方法一直是AlphaGo和许多掌握不同棋盘和视频游戏的AI算法成功的关键因素。关键是,许多问题可以转化为图像识别问题,并通过深度学习解决。例如,霍华德深度学习课程的学生创建了一个神经网络,该网络在鼠标移动和点击的图像行为上进行训练。在这种情况下,他创建了一个卷积神经网络,试图根据这些图片预测欺诈行为。也就是说,深度学习也证明了其超越计算机视觉和图像识别领域的价值。霍华德指出,深度学习现在也适用于大多数自然语言处理(NLP)问题,这包括机器翻译和文本摘要等领域。NLP是一个关键组件,它可以使Siri,Alexa和Cortana等AI助手理解你的命令。(有一点要知道:深度学习对人类语言的掌握有限)深度学习还可以解决涉及结构化数据的问题,例如电子表格中的行和列。例如,你可以为神经网络提供一组代表金融交易及结果(欺诈或正常)的行,并对其进行训练以预测欺诈性交易。霍华德指出,深度学习也可以应用于时间序列和信号问题,例如连接到网络的不同IP地址的事件顺序或随时间收集的传感器数据。深度学习的痛点霍华德还指出了一些深度学习成效有限的领域,这些领域包括强化学习,对抗模型和异常检测。一些专家认为强化学习是当前人工智能的圣杯。强化学习涉及开发AI模型而不向他们提供大量标记数据。在强化学习中,你为模型提供问题域的约束,并让它开发自己的行为规则。AlphaGo的高级版AlphaGo Zero就是使用强化学习从头开始训练自己,然后超过了AlphaGo。虽然深度强化学习是人工智能研究中比较有趣的领域之一,但它在解决现实问题方面没有明显的进展。Google Brain AI研究员Alex Irpan在深度强化学习的极限上有一篇引人深思的文章。对抗模型是霍华德提及的另一个深度学习痛点。对抗性示例是操纵输入可能导致神经网络以非理性方式运行的实例。有很多研究人员展示了对抗性<u style=“box-sizing: border-box;">示例</u>如何能够成为对AI模型的攻击<u style=“box-sizing: border-box;">者</u>。虽然已经做了一些努力来加强深层学习模式以对抗对抗性攻击,但到目前为止,成功有限。部分挑战源于神经网络非常复杂且难以解释的事实。异常检测,霍华德谈到的第三个深度学习痛点也非常具有挑战性。一般概念是在基线数据上训练神经网络,并让它确定偏离基线的行为。这是在网络安全中使用AI的主要方法之一,一些公司正在探索这一概念。但是,它仍然无法将自己确立为对抗安全威胁的非常可靠的方法。深度学习是一个黑盒子这是一个真正令人担忧的问题,尤其是在人工智能模型被赋予关键决策的领域,例如医疗保健、自动驾驶汽车和刑事司法。那些愿意让深度学习代表他们做出决定的人需要知道推动这些决策的因素是什么?不幸的是,当你在训练神经网络时获得的性能优势会降低你在决策过程中获得的可见性。这就是深度学习通常被称为“黑匣子”的原因。但是,现在已经有了很多有趣的研究来解释AI决策,并帮助工程师和最终用户理解影响神经网络输出的元素。深度学习需要大量数据一般认为,要创建一个新的深度学习模型,需要访问数百万和数十亿个带标签的示例,这就是为什么只有大型科技公司才能创建它。“需要大量数据的说法通常不正确,因为大多数人在实践中使用迁移学习”霍华德说。迁移学习是机器学习中的一门学科,其中一个模型获得的知识被转移到执行类似任务的另一个模型。与人类如何将知识从一个领域转移到另一个领域相比,它非常原始。但是,迁移学习在深度学习领域是一个非常有用的工具,因为它使开发人员能够用更少的数据创建新模型。霍华德解释说:“你从一个预先训练好的[神经]网络开始,然后为你的特定任务微调权重。一般来说,如果你有大约1,000个示例,你应该能够建立一个良好的神经网络。”你需要博士学位才能进行核心深度学习深度学习是一个非常复杂的计算机科学领域,它涉及许多高级数学概念。但是在过去几年中,学术界已经创建了大量的工具和库来抽象出潜在的复杂性,并使你能够无须解决过多的数学问题来开发深度学习模型。Fast.ai和Keras就是两个现成的库,可用于快速开发深度学习应用程序。还有很多在线课程,包括霍华德的fast.ai,Coursera和其他课程,使你能够开始深入学习编程,只需要很少的编程知识。许多具有计算机科学以外背景的人已经能够将这些课程应用于现实世界的问题。需要明确的是,深度学习研究仍然是一个非常先进和复杂的领域,人才既稀缺又昂贵。开发新的深度学习技术的人是一些最令人垂涎和收入极高的研究人员。但这并不意味着其他人需要拥有相同水平的知识才能在他们的应用程序中使用这些研究项目的结果。深度学习需要大量的计算能力“你可能会担心你需要一个充满GPU的大房间,总的来说这并不是真的,我现在看到的绝大部分成功结果都是用一个GPU完成的。” 霍华德说大型公司和组织进行的大型研究项目需要大量的GPU,例如一款机器人手用6144 CPU和8个GPU进行训练出来的。另一个例子是OpenAI Five,一个训练有素的AI模型,可以玩著名的Dota 2在线战斗竞技游戏,OpenAI Five是用了128,000个CPU内核和256个GPU的训练的结果。但是,大多数实际问题都可以通过单个GPU解决。例如,你可以通过一个GPU来完成霍华德的Fast.ai课程。总结:我建议你观看整个视频,其中,霍华德深入研究了一些更专业的主题,例如你是否可以将深度学习应用于信息安全。重要的是我们要了解深度学习的范围和限制以及机会和优势,因为它是我们这个时代最有影响力的技术之一。深度学习不是过分夸大,也许它只是没有很好地被理解。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 14, 2019 · 1 min · jiezi

揭秘人工智能(系列):人工智能带来的网络安全威胁

摘要: 人工智能给网络安全带来了哪些挑战?了解下!历史表明,网络安全威胁随着新的技术进步而增加。关系数据库带来了SQL注入攻击,Web脚本编程语言助长了跨站点脚本攻击,物联网设备开辟了创建僵尸网络的新方法。而互联网打开了潘多拉盒子的数字安全弊病,社交媒体创造了通过微目标内容分发来操纵人们的新方法,并且更容易收到网络钓鱼攻击的信息,比特币使得加密ransowmare攻击成为可能。类似的威胁网络安全的方法还在不断产生。关键是,每项新技术都会带来以前难以想象的新安全威胁。最近,深度学习和神经网络在支持各种行业的技术方面变得非常突出。从内容推荐到疾病诊断和治疗以及自动驾驶,深度学习在做出关键决策方面发挥着非常重要的作用。现在我们所面临的问题是,知道神经网络和深度学习算法所特有的安全威胁是什么?在过去几年中,我们已经看到了恶意行为者开始使用深度学习算法的特征和功能来进行网络攻击的示例。虽然我们仍然不知道何时会出现大规模的深度学习攻击,但这些例子可以说成是将要发生事情的序幕。你应该知道深度学习和神经网络可用于放大或增强已存在的某些类型的网络攻击。例如,你可以使用神经网络在网络钓鱼诈骗中复制目标的写作风格。正如DARPA网络大挑战在2016年所展示的那样,神经网络也可能有助于自动发现和利用系统漏洞。但是,如上所述,我们专注于深度学习所特有的网络安全威胁,这意味着在深度学习算法进入我们的软件之前,它们不可能存在。我们也不会涵盖算法偏见和神经网络的其他社会和政治含义,如操纵选举。要研究深度学习算法的独特安全威胁,首先必须了解神经网络的独特特征。什么使深度学习算法独一无二?深度学习是机器学习的一个子集,机器学习是一个人工智能领域,其中软件通过检查和比较大量数据来创建自己的逻辑。机器学习已存在很长时间,但深度学习在过去几年才开始流行。人工神经网络是深度学习算法的基础结构,大致模仿人类大脑的物理结构。与传统的软件开发方法相反,传统的程序员精心编写定义应用程序行为的规则,而神经网络通过阅读大量示例创建自己的行为规则。当你为神经网络提供训练样例时,它会通过人工神经元层运行它,然后调整它们的内部参数,以便能够对具有相似属性的未来数据进行分类。这对于手动编码软件来说是非常困难的,但神经网络却非常有用。例如,如果你使用猫和狗的样本图像训练神经网络,它将能够告诉你新图像是否包含猫或狗。使用经典机器学习或较旧的AI技术执行此类任务非常困难,一般很缓慢且容易出错。计算机视觉、语音识别、语音转文本和面部识别都是由于深度学习而取得巨大进步的。但神经网络在保证准确性的同时,失去的却是透明度和控制力。神经网络可以很好地执行特定任务,但很难理解数十亿的神经元和参数是如何进行网络决策的。这被称为“AI黑匣子”问题。在许多情况下,即使是创建深度学习算法的人也很难解释他们的内部工作原理。总结深度学习算法和神经网络两个与网络安全相关的特征:他们过分依赖数据,这意味着他们与他们训练的数据一样好(或坏)。它们是不透明的,这意味着我们不知道它们如何起作用。接下来,我们看看恶意行为者如何利用深度学习算法的独特特征来进行网络攻击。对抗性攻击神经网络经常会犯错,这对人类来说似乎是完全不合逻辑甚至是愚蠢的。例如,去年,英国大都会警察局用来检测和标记虐待儿童图片的人工智能软件错误地将沙丘图片标记为裸体。在另一个案例中,麻省理工学院的学生表示,对玩具龟进行微小改动会导致神经网络将其归类为步枪。这些错误一直伴随着神经网络而存在。虽然神经网络通常会输出与人类产生的结果非常相似的结果,但它们并不一定经历相同的决策过程。例如,如果你只用白猫和黑狗的图像训练一个神经网络,它可能会优化其参数,根据动物的颜色而不是它们的物理特征对动物进行分类。对抗性的例子,导致神经网络产生非理性错误的输入,强调了AI算法和人类思维的功能之间的差异。在大多数情况下,可以通过提供更多训练数据并允许神经网络重新调整其内部参数来修复对抗性示例。但由于神经网络的不透明性,找到并修复深度学习算法的对抗性示例可能非常困难。恶意行为者可以利用这些错误对依赖深度学习算法的系统进行对抗性攻击。例如,在2017年,密歇根州华盛顿大学以及加州大学伯克利分校的研究人员表示,通过进行小幅调整来停止标志,他们可以使自动驾驶汽车的计算机视觉算法不可见。这意味着黑客可以强迫自动驾驶汽车以危险的方式行事并可能导致事故。如下面的例子所示,没有人类驾驶员不会注意到“被黑”的停车标志,但神经网络可能完全失明。在另一个例子中,卡内基梅隆大学的研究人员表示,他们可以欺骗面部识别系统背后的神经网络,通过佩戴一副特殊的眼镜将一个人误认为另一个人。这意味着攻击者可以使用对抗攻击来绕过面部识别身份验证系统。对抗性攻击不仅限于计算机视觉,它们还可以应用于依赖神经网络和深度学习的语音识别系统。加州大学伯克利分校的研究人员涉及了一种概念验证,在这种概念验证中,他们操纵音频文件的方式会让人耳不被注意,但会导致AI转录系统产生不同的输出。例如,这种对抗性攻击可用于以在播放时向智能扬声器发送命令的方式来改变音乐文件,播放文件的人不会注意到文件包含的隐藏命令。目前,只在实验室和研究中心探索对抗性攻击。暂时还没有证据表明发生过对抗性攻击的真实案例。发展对抗性攻击与发现和修复它们一样困难,因为对抗性攻击也非常不稳定,它们只能在特定情况下工作。例如,视角或照明条件的微小变化可以破坏对计算机视觉系统的对抗性攻击。但它们仍然是一个真正的威胁,对抗性攻击将变得商业化只是时间问题,正如我们在深度学习的其他不良用途中看到的那样。但我们也看到人工智能行业也正在努力帮助减轻对抗深度学习算法的对抗性攻击的威胁。在这方面可以提供帮助的方法之一是使用生成对抗网络(GAN)。GAN是一种深度学习技术,它使两个神经网络相互对抗以产生新数据。第一个网络即生成器创建输入数据,第二个网络,即分类器,评估由生成器创建的数据,并确定它是否可以作为特定类别传递。如果它没有通过测试,则生成器修改其数据并再次将其提交给分类器。两个神经网络重复该过程,直到生成器可以欺骗分类器认为它创建的数据是真实的。GAN可以帮助自动化查找和修补对抗性示例的过程。另一个可以帮助强化神经网络抵御对抗性攻击的趋势是创建可解释的人工智能。可解释的AI技术有助于揭示神经网络的决策过程,并有助于调查和发现对抗性攻击的可能漏洞。一个例子是RISE,一种由波士顿大学研究人员开发的可解释的人工智能技术。RISE生成热图,表示输入的哪些部分对神经网络产生的输出有贡献。诸如RISE之类的技术可以帮助在神经网络中找到可能存在问题的参数,这些参数可能使它们容易受到对抗性攻击。数据中毒(Data poisoning)虽然对抗性攻击在神经网络中可以发现并解决相关问题,但数据中毒通过利用其过度依赖数据在深度学习算法中产生问题行为。深度学习算法没有道德、常识和人类思维所具有的歧视的概念。它们只反映了他们训练的数据隐藏的偏见和趋势。2016年,推特用户向微软部署的人工智能聊天机器人提供仇恨言论和种族主义言论,在24小时内,聊天机器人变成了纳粹支持者和大屠杀否认者,然后毫不犹豫地发出了恶意评论。由于深度学习算法仅与其数据质量保持一致,因此为神经网络提供精心定制的训练数据的恶意行为者可能会导致其表现出有害行为。这种数据中毒攻击对于深度学习算法特别有效,这些算法从公开可用或由外部参与者生成的数据中提取训练。已经有几个例子说明刑事司法、面部识别和招募中的自动化系统由于其训练数据中的偏差或缺点而犯了错误。虽然这些例子中的大多数是由于困扰我们社会的其他问题而在我们的公共数据中已经存在的无意错误,但没有什么能阻止恶意行为者故意毒害训练神经网络的数据。例如,考虑一种深度学习算法,该算法监视网络流量并对安全和恶意活动进行分类。这是一个无监督学习的系统。与依赖于人类标记的示例来训练其网络的计算机视觉应用相反,无监督的机器学习系统通过未标记的数据来仔细查找共同的模式,而无需接收关于数据所代表的具体指令。例如,AI网络安全系统将使用机器学习为每个用户建立基线网络活动模式。如果用户突然开始下载比正常基线显示的数据多得多的数据,系统会将其归类为潜在的恶意意图人员。但,具有恶意意图的用户可以通过以小增量增加他们的下载习惯来欺骗系统以慢慢地“训练”神经网络以认为这是他们的正常行为。数据中毒的其他示例可能包括训练面部识别认证系统以验证未授权人员的身份。去年,在Apple推出新的基于神经网络的Face ID身份验证技术之后,许多用户开始测试其功能范围。正如苹果已经警告的那样,在某些情况下,该技术未能说出同卵双胞胎之间的区别。但其中一个有趣的失败是两兄弟的情况,他们不是双胞胎,看起来不一样,年龄相差多年。这对兄弟最初发布了一段视频,展示了如何用Face ID解锁iPhone X.但后来他们发布了一个更新,其中他们表明他们实际上通过用他们的面部训练其神经网络来欺骗Face ID。其实这是一个无害的例子,但很容易看出同一模式如何为恶意目的服务。由于神经网络不透明且开发人员不创建规则,因此很难调查并发现用户可能故意对深度学习算法造成的有害行为。基于深度学习的恶意软件今年早些时候,IBM的研究人员引入了一种新的恶意软件,它利用神经网络的特性针对特定用户隐藏恶意负载,有针对性的攻击以前是拥有大量计算和情报资源的国家和组织。但是,由IBM开发的概念验证恶意软件DeepLocker表明,此类攻击可能很快成为恶意黑客的正常操作方式。DeepLocker已将其恶意行为和有效负载嵌入到神经网络中,以将其隐藏在端点安全工具之外,后者通常会在应用程序的二进制文件中查找签名和预定义模式。DeepLocker的另一个特点是使用神经网络为其有效载荷指定特定目标。为了显示基于深度学习的恶意软件的破坏性功能,IBM研究人员为DeepLocker提供了勒索软件病毒,并将其嵌入到视频会议应用程序中。同时,恶意软件的开发人员在通过网络摄像头看到特定用户的面部时,可以训练神经网络来激活有效负载。由于恶意软件嵌入在视频会议应用程序中,因此它可以合法访问网络摄像头的视频源,并能够监控应用程序的用户。一旦目标在摄像机前显示他们的脸,DeepLocker就会释放勒索软件并开始加密用户计算机上的所有文件。黑客将能够使用DeepLocker等恶意软件根据他们的性别和种族,用特定深度学习算法来定位特定用户或群体。我们尚未了解深度学习算法和神经网络的网络安全威胁的规模。创建DeepLocker的研究人员表示,他们并不确定此类恶意软件是否已经在黑客放弃。未来在神经网络领域面临的网络安全问题,还存在诸多不确定性!本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 11, 2019 · 1 min · jiezi

菜鸟数据科学家五大误区

你准备好要成为一名数据科学家,积极的参加Kaggle比赛和Coursera的讲座。虽然这一切都准备好了,但是一名数据科学家的实际工作与你所期望的却是大相径庭的。本文研究了作为数据科学家新手的5个常见错误。这是由我在塞巴斯蒂安·福卡德(<u style=“box-sizing: border-box;">Dr. Sébastien Foucaud</u>)博士的帮助下一起完成的,他在指导和领导学术界与行业领域的年轻数据科学家方面拥有20多年的经验。本文旨在帮助你更好地为今后的实际工作做准备。1、Kaggle成才论你通过参加Kaggle比赛,练习了数据科学领域的各项技能。如果你能把决策树和神经网络结合起来那就再好不过了。说实话,作为一个数据科学家,你不需要做那么多的模型融合。请记住,通常情况下,你将花80%的时间进行数据预处理,剩下的20%的时间用于构建模型。作为Kaggle的一份子对你在很多方面都有帮助。所用到的数据一般都是彻底处理过的,因此你可以花更多的时间来调整模型。但在实际工作中,则很少会出现这种情况。一旦出现这种情况,你必须用不同的格式和命名规则来收集组装不同来源的数据。做数据预处理这项艰苦的工作以及练习相关的技能,你将会花费80%的时间。抓取图像或从API中收集图像,收集Genius上的歌词,准备解决特定问题所需的数据,然后将其提供给笔记本电脑并执行机器学习生命周期的过程。精通数据预处理无疑会使你成为一名数据科学家,并对你的公司产生立竿见影的影响。2、神经网络(Neural Networks)无所不能在计算机视觉或自然语言处理的领域,深度学习模型优于其它机器学习模型,但它们也有很明显的不足。神经网络需要依赖大量的数据。如果样本很少,那么使用决策树或逻辑回归模型的效果会更好。神经网络也是一个黑匣子,众所周知,它们很难被解释和说明。如果产品负责人或主管经理对模型的输出产生了质疑,那么你必须能够对模型进行解释。这对于传统模型来说要容易得多。正如詹姆斯·勒(James Le)在一个伟大的邮件中所阐述的那样,有许多优秀的统计学习模型,自己可以学习一下,了解一些它们的优缺点,并根据用例的约束来进行模型的实际应用。除非你正在计算机视觉或自然语言识别的专业领域工作,否则最成功的模型很可能就是传统的机器学习算法。你很快就会发现,最简单的模型,如逻辑回归,通常是最好的模型。3、机器学习是产品在过去的十年里,机器学习既受到了极大的吹捧,也受到了很大的冲击。大多数的初创公司都宣称机器学习可以解决现实中遇到的任何问题。机器学习永远都不应该是产品。它是一个强大的工具,用于生产满足用户需求的产品。机器学习可以用于让用户收到精准的商品推荐,也可以帮助用户准确地识别图像中的对象,还可以帮助企业向用户展示有价值的广告。作为一名数据科学家,你需要以客户作为目标来制定项目计划。只有这样,才能充分地评估机器学习是否对你有帮助。4、混淆因果和相关有90%的数据大约是在过去的几年中形成的。随着大数据的出现,数据对机器学习从业者来说已经变得越来越重要。由于有非常多的数据需要评估,学习模型也更容易发现随机的相关性。上图显示的是美国小姐的年龄和被蒸汽、热气和发热物体导致的命案总人数。考虑到这些数据,一个学习算法会学习美国小姐的年龄影响特定对象命案数量的模式。然而,这两个数据点实际上是不相关的,并且这两个变量对其它的变量没有任何的预测能力。当发现数据中的关系模式时,就要应用你的领域知识。这可能是一种相关性还是因果关系呢?回答这些问题是要从数据中得出分析结果的关键点。5、优化错误的指标机器学习模型通常遵循敏捷的生命周期。首先,定义思想和关键指标。之后,要原型化一个结果。下一步,不断进行迭代改进,直到得到让你满意的关键指标。构建一个机器学习模型时,请记住一定要进行手动错误分析。虽然这个过程很繁琐并且比较费时费力,但是它可以帮助你在接下来的迭代中有效地改进模型。参考下面的文章,可以从Andrew Ng的Deep Learning Specialization一文中获得更多关于改进模型的技巧。注意以下几个关键点:实践数据处理研究不同模型的优缺点尽可能简化模型根据因果关系和相关性检查你的结论优化最有希望的指标本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 8, 2019 · 1 min · jiezi

到底什么成就了今天的人工智能?(下)

摘要: 人工智能发展迅速,可是到底什么成就了今天的人工智能呢?跟随我们一起来探索吧。人工智能大多数个人电脑、智能手机和其他设备的硬件性能非常相似,由操作系统定义,通过下载其他软件“学习”。早期计算机的学习完全依赖于与人类的交互,而现在则通过互联网接收更新。随着越来越多的数据存储到云端,服务器代理的作用不断增强。这些代理负责计算密集型任务,类似于中枢神经系统。相反,面向消费者的电子产品正在改善它们的输入/输出能力,变得有点像外围神经。由此也衍生出了物联网。在物联网中,拥有数十台高度专业化的微型设备,每台只执行一项或几项功能。基于云计算的中央“大脑”负责协调所有设备来控制房屋、工厂甚至整个区域。相比之下,机器人技术专注于更加自主的主体。机器人必须实时处理复杂的现实情况。自动驾驶汽车就是典例:图中简化了结构,真实的系统有超过100个传感器,具有恒定的输入流。自动驾驶汽车的设计是当今人工智能研究中最困难的领域之一。面向消费者的机器人只是人工智能研究中的微小分支,是一个相对较新的趋势,而大多数机器人是为工业和军事需求设计的。与武装无人机或核电站控制员的失误相比,自动驾驶出租车的不当行为更像一场小型事故。此类系统的策略编程不依赖于黑盒算法,但其工作的每个方面均需要严格的数学规范。量子世界(Quantum world)量子力学是人工智能和生物智能的共同基础。量子力学的出现,为以半导体为核心的计算机技术奠定了基础。300多年前发展起来的计算行星运动的数学方法作为了反向传播和梯度下降的基础。概率论、统计力学和矩阵力学成为了量子力学的基础,是现代人工智能的近亲。目前,深度学习就像炼金术,物理学则可以帮助我们更好地理解它。虽然量子计算机还处于起步阶段,但目前的实验表明它能有效地加速处理某些优化问题。例如,玻尔兹曼机器是一种人工神经网络,但难以在大多实际场景中进行应用,所以研究学者提出了一种受限的变体,成为最早的深度神经网络之一。量子计算机则有可能结合玻尔兹曼机器和其它概率模型的全部计算能力。理解量子力学非常难,概率振幅只是冰山一角。尽管许多人批评人工神经网络的解释性很差,但他们也无法直观地描述量子力学。生物智能(Biological Agents)生物智能存在了约30亿年。地球上数百万种生物都有一个共同点:DNA。DNA是细胞的“中枢神经系统”。人们认为,在基于DNA的生命出现之前就有基于RNA的生物体,它们在功能和结构上非常相似。生物学家们在很长一段时间里都认为,约98%不编码蛋白质的DNA是无用的。但后来的研究发现,它们在控制编码DNA以适应动态环境中起着关键作用。DNA自身的某些部分可能会被甲基化失活,但这是可逆的,且在整个生命周期中发生多次。现代科技已能合成和编辑我们想要的DNA,人工和生物智能已无太大区别。细胞(Cells)具有基本功能的细胞称为原细胞:它们代表了最初生命有机体的样子。大约30亿年前的地球环境模型表明,在足够多的核苷酸中能够捕获脂类气泡,从而产生第一个基因组,而基因组又能通过从周围环境中捕获营养物质实现复制。在积累了足够数量的基因和其他化学物质后,这些气泡在内部压力的作用下分裂。另一个简单的例子是病毒。两者的主要区别在于病毒不维持内部代谢,需要利用其他生物体进行自我复制。病毒的基因组通常很短,只编码1到2个蛋白质。然而,病毒可以通过DNA交换与宿主进行“交流”,这一过程称为水平基因转移。许多单细胞生物都有这种能力,它在整个进化过程中扮演着重要的角色。相比之下,细菌可以对不同的化学物质,光,压力,温度等进行感应。许多细菌在分子水平上具有类似于普通内燃机的运动机制。此外,它们有相当强的沟通能力,可以成群结队地聚集在一起,能借助自身基因组和周围的蛋白质消化大量的营养物质,并执行相当复杂的行为。它们的结构与原细胞和古细菌非常相似。真核细胞与此相反,它们有许多细胞器。其中,像线粒体和叶绿体都有自己的DNA片段,在过去可能是独立的生物体。此外,线粒体在克雷布斯循环中发挥着至关重要的作用,能够促进新陈代谢。真核细胞内部结构虽然复杂,但缺乏自行移动的能力。动物细胞也缺乏叶绿体和细胞壁,使其失去自主性。生物细胞虽然逐渐失去了独立生存的能力,但却获得了更为复杂的“社会”能力。细胞通过动作电位对环境变化做出快速反应。当传感器检测到化学物质、压力或其他刺激时,细胞膜电势迅速变化。但动作电位信号仅限于源细胞和与其有直接膜-膜连接的细胞。它可以通过信号分子传递给其他细胞,但过程耗时长。大多数动物进化出了专门的细胞——神经元克服该问题。神经元形状各异,可以长出新的突触或移除旧的突触。外围神经元通常只有几百个连接,而中间神经元的连接可能超过10000个。这些机制使它们能够快速移动信号,并通过调整突触强度进行转换。此外,脊椎动物的许多轴突都有髓鞘,可以使电位移动得更快,同时激活更少的膜通道,节省能量。下面介绍到目前为止研究得最好的神经系统之一,线虫:研究人员对其进行了长达50年的剖析,了解其全部302个神经元的详细结构,其中包含5000多个突触:即使只有302个神经元,研究人员也很难判断它们在做什么。它们持续地“学习”,且功能可能会实时变化,而人类大脑拥有数十亿个细胞。考虑到复杂性,神经科学的大多数研究都集中在特定的区域、通路或细胞类型上。大多数进化的旧结构负责呼吸、心跳、睡眠/苏醒周期、饥饿和其他重要功能。大脑皮层是最受研究人员关注的。大脑皮层是一层折叠的层状薄片,厚度约为2-3毫米,大脑的其他部分被一块类似于餐巾纸的结构所覆盖。大脑皮层涉及一些高级认知功能,如语言、意识、计划等。新皮层约占大脑皮层的90%。另一研究充分的区域是海马体:所有的脊椎动物都有一个类似的结构叫做苍白球,但哺乳动物有一个更进化的版本,海马体。它在空间记忆和情景记忆中起着至关重要的作用,其功能类似一个时空地图。有了这张地图,大脑就可以把复杂的记忆储存在专门用于视觉、听觉和其他表现形式的区域。最初对大脑的研究集中在损伤外伤和内部损害上。在大脑皮层中,大脑区域缺失和认知功能缺失之间的相关性较弱。研究结果表明,记忆分布在整个大脑皮层,甚至在手术切除邻近神经元的某些部分后,还可以重新学习缺失的功能。研究人员提供了如下区域图:但上图在实际和理论两方面都缺乏精确性。在实验环境中,你可以刺激大脑的某一部分,观察其反应。但是,除了主要的感觉和运动区域外,得到的结果并不准确。另一方面,功能性磁共振成像可以跟踪受试者,判断在执行某些任务时大脑的活跃部分,但这些区域并非专门处理特定任务,结果也不准确。同时,功能性磁共振成像实际上是在测量氧气的供应水平,所以仅仅测量单个神经元的活动水平是不够的,就像这样:大脑活动的另一个有趣的特征是它以波的形式进行:以上研究能够帮助理解和治疗神经系统疾病,却并不能描述人类的行为。但是,这种自下而上的思维研究方法仍然取得了重大发现,比如基于神经活动来预测一个人的选择,以及大脑没有“中心”部分。从心理学角度分析,人类行为在很大程度上受到遗传、文化和环境因素的影响。智商及智商测试方法是其中最著名的研究成果。虽然有理论试图对智力做出解释,如多元智能理论,智力的三位一体理论等,但并未被广泛接受。这些理论的主要问题在于没有提供一种定量证明的方法。即使是像走路或说“嗨”这样简单的行为,涉及到的神经结构也极其复杂,再加上考虑到每个细胞内DNA和其他生物机制的复杂性,对神经科学研究的做出心理学解释往往比实验本身还要复杂。什么是智能?答案虽然多样,但到目前为止都没有一个被广泛接受的统一理论。也许AIXI和IIT的结合会推动其产生。要把两者结合起来,需要一个奖励的概念,这个概念可能来自医学和经济学,适用于每一种人工和生物智能。当前几乎所有的智能衡量都基于某些任务的性能,这在瞬息万变的现实环境中不够灵活。或许,将意识定义为“任何可能的经验”,以及与AIXI背后的智能框架相关联的IIT框架,可以提供一幅更广阔的认知图景。任何主体工作都可以被描述为量子系统的波函数,但这不仅难以计算,还对习得的中间表征以及生物智能和人工智能的解释提出了巨大的挑战。虽然人工智能的进步和对人类智能的深层次理解有着巨大的应用前景,但仍存在一些挑战: 隐私(Privacy)偏差(Bias) 一致性(Alignment):大多数人工智能训练都是基于效用最大化或误差最小化,而这些目标函数并不能代表所有的人类价值和道德。 替代(Displacement):科技取代人类完成特定任务已经有一段时间了,但人类的进化比人工智能要慢得多。 网络攻击(Cyberattacks)心理工程(Psycho-engineering):大量的心理实验和历史教训表明,即使没有任何暴力倾向的人,如果被适当地操纵,也会对别人造成伤害。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 8, 2019 · 1 min · jiezi

到底什么成就了今天的人工智能?(上)

摘要: 人工智能发展迅速,可是到底什么成就了今天的人工智能呢?跟随我们一起来探索吧。维基百科对智能有如下定义:智能是一种能够感知或推断信息,并将其作为知识留存下来,自适应地用于某种环境或上下文的能力。*人工智能(Artificial Intelligence)虽然我们很难对人工智能做一个确切的解释,但可以从查尔斯巴贝奇的分析机讲起。它虽然没有任何特殊的“自适应”能力,但却非常灵活。遗憾的是,理论上虽然完美,但却没有得以实现。巴贝奇分析机早图灵机50年左右出现。从理论上讲,它能够将任何可计算的函数作为输入,并在完全机械的情况下产生输出。复杂性理论(complexity theory)由此得以发展,同时人们也意识到构建通用计算机其实相对简单。此外,算法的实现也越发多样。尽管还存在一些技术上的挑战,但在过去的70年中,相同价格可购买到的计算量大约每两年翻一番。也就是说,构建计算力强大的人工智能系统越发容易。然而,这受到了所提供或输入的数据,以及处理时间的限制。可以做如下思考:如果每台计算机的能力都受到数据和时间的限制,我们还能称之为智能计算机么?下面我们简单回顾一下人工智能的发展史。人类的智能主要包括归纳总结和逻辑演绎,对应着人工智能中的联结主义(如人工神经网络)和符号主义(如吴文俊方法)。符号主义认为智能是基于逻辑规则的符号操作;联结主义认为智能是由神经元构成的信息处理系统。其发展轨迹如下图所示:联结主义,即“橙色阵营”在一开始处于领先地位,得益于其与神经科学和人类大脑之间的关系。人类大脑被视为“强AI(Strong Artificial Intelligence)”和“通用人工智能(Artificial General Intelligence,AGI)”唯一的成功应用。然而,第一代神经网络在处理实际问题时屡屡受挫。因为神经网络多数是线性的,并且能力十分有限,深受外界质疑。与此同时,符号主义,即“蓝色阵营”利用严谨的数学理论创造出了更多有用的东西。随着手工知识的积累,输入或输出数据量急速增长,系统的性能无法适应需求,联结主义逐渐衰败。就好比法律,专家制定出再完备的规则都有可能相互冲突,此时便需要越来越多的“法官”来解决这些问题。这减缓了联结主义的发展。后来,“橙色阵营”获取了足够的标签数据和计算资源,能够在可接受的时间内对网络进行“训练”,世界各地的研究学者开始进行大量试验。尽管如此,联结主义仍花费了大量的时间使大众重新信任神经网络,开发人员也花了较长才适应了模糊逻辑和统计的概念。在对人工神经网络进行详细讨论前,本文将先介绍一些其它方法:决策树、概率模型、进化算法。决策树(Decision Tree)是最简单有效的算法之一。其“学习”是通过顺序地遍历数据的每个属性并找到对特定输出具有最大预测能力的属性来执行的。像随机森林这样的高级变体使用了更复杂的学习技术,并在同一个模型中组合多个树,它们的输出是通过“投票”得到的,这与人类的“直觉”类似。概率模型(Probabilistic models)是统计方法的代表。概率模型与神经网络常共享架构、学习/优化过程甚至符号。但是概率模型大多受概率逻辑(通常是贝叶斯)的约束,而神经网络则无此约束。进化算法(Evolutionary computation)最初是受到生物进化的启发,且以随机突变和适应度为主。由于修改通常是随机的,其限制噪声的效果突出。进化算法是一种引导式搜索,许多方面与退火过程类似。上述方法有一个共同点:它们从较差的策略开始,逐渐对其改善,以期在某种性能评估方法中取得更好的分数。如今,机器学习技术,尤其是深度学习正在主导人工智能的发展。与大多数使用1到2个中间抽象层(所谓的浅模型)机器学习方法不同,深度学习可能包含数百甚至数千个堆叠的可训练层。研究学者认为对这样的深度网络进行训练,需要全新的优化程序。事实证明,使用梯度下降的逆向传播(即链式法则)即可很好的进行训练,也可使用Adam或RMSProp。神经网络训练流程如下:1、 获取输入2、 计算输出3、 评估性能4、 调节参数5、 重复训练,至性能最优梯度下降法只需调整参数使误差最小。但该方法容易使网络陷入局部最优,而没有获得最优性能。然而,最新研究表明许多神经网络已经能够获取全局最优解。深度学习实现了训练的并行化,即分布式学习。能在同一时间跨多台机器训练相同的体系结构,同时实现梯度交换,加速超过1000倍。此外,经过训练的网络可以处理相似的任务,即迁移学习,这也是人工神经网络广泛流行的重要原因。例如,经过图像分类训练的网络可以用于其他计算机视觉任务,自然语言处理和其他领域。更重要的是,同一个网络还可以用来解决不同模式的问题。强化学习(Reinforcement Learning,RL)则将它们结合在了一起。RL的最初想法来自行为心理学,科研人员探究了在行为心理学中奖励如何影响学习和塑造动物的行为。RL并不需要出现正确的输入/输出对,也不需要精确校正次优化的行为。举个例子,我们并不需要教会机器人如何精确移动,只需根据它走多远或多快对其进行奖励,它会自己找出正确的路线。然而,这种训练模式在实践中也是最具挑战性的,即使是相对简单的任务,通常也需要付出大量的努力才能正确设置。在实际问题中,通常很难在环境中指定奖励,研究人员目前更多地关注内部奖励模型。与RL并行的是逆向强化学习(Inverse Reinforcement Learning):当完成复杂的任务时,强化学习的回报函数很难指定,我们希望有一种方法能够找到高效且可靠的回报函数,这种方法就是逆向强化学习。通用人工智能中一些框架来自于严格的数学理论,一些受神经元回路的启发,还有一些基于心理模型。本文将以HTM、AIXI、ACT-R和SOAR为例进行介绍。层级实时记忆算法 (Hierarchical Temporal Memory,HTM),HTM算法旨在模拟新大脑皮层的工作原理,将复杂的问题转化为模式匹配与预测。它强调对“神经元”进行分层级,以及信息模式的空间特性与时间特性。稀疏分布表示(Sparse Distributed Representation, SDR)是HTM算法中的一个重要概念。实际上,它只是拥有几千个元素的位数组。就像大脑中的信息总是通过亿万神经细胞中的小部分活跃细胞来表示一样,HTM使用稀疏分布表示语义相关的输入。HTM算法中的抑制(Inhibition)类似于批规范化和其他一些正则化技术,提升(Boosting)在机器学习中已经是一个相对较老的概念,层次结构(Hierarchical Structure)并没有真正的大脑皮层的结构灵活。HTM对物体间关系的重视程度低,甚至连稀疏分布表示也可以用普通神经网络构建。总体来说,HTM需要进行大量调整才能获取与其它机器学习算法相当的性能。接下来介绍AIXI,它是一个对通用人工智能的理论上的数学形式化表示。然而,它有一个显著的缺点——无法计算。事实上,许多机器学习算法均不能精确计算,只能做近似处理。AIXI表示如下:AIXI的核心是一个强化学习智能体,在诸多方面与Schmidhuber开发的Godel Machine类似。然而,它们都是AGI的描述性模型,复杂程度高,无法执行,但不可否认,它们都是人工智能研究人员的灵感源泉。相反,ACT-R,即理性思维的自适应控制系统 (AdaptiveControl of Thought—Rational),它不仅是一种理论,而且是一种用LISP编写的软件框架。ACT-R主要关注不同类型的内存,较少关注其中数据的转换。该理论试图理解人类如何获得和组织知识以及如何产生智力活动,其研究进展基于神经生物学研究成果并从中得以验证,且已成功地为许多不同认知现象建立起合理的模型。然而,它在实际应用中并未取得成功,最终只作为研究人员的工具。SOAR与ACT-R有着相似的根源和基本假设,但它更关注于实现AGI,而不是建立人类认知的模型。ACT-R和SOAR是人工智能符号主义的经典代表,在认知科学的发展中起到了重要作用,但是应用它们相比现代联结主义需要更多的配置和先验知识。此外,神经影像和其他用于心智研究的工具越发详细和准确,而且ACT-R和SOAR在某一定程度上过于僵化,无法保持相关性。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 7, 2019 · 1 min · jiezi

2018最有用的六个机器学习项目

摘要: 用了这六个机器学习开源项目,你的项目一定进行的666!2018年又是人工智能和机器学习快速发展的一年。许多新的机器学习的项目正在以非常高的影响力影响着诸多领域,特别是医疗保健、金融、语音识别、增强现实和更复杂3D视频渲染。这一年,我们看到了更多的应用驱动研究,而不是理论研究。虽然这可能有其缺点,但它在短时间内产生了一些巨大的积极影响,产生了可以迅速转化为业务和客户创造价值的新研发,这一趋势在ML开源项目中得到了强烈反映。让我们来看看过去一年中最实用的6个ML项目。这些项目都公开发布了代码和数据集,允许个别开发人员和小型团队学习并创造价值。它们可能不是理论上最具开创性的作品,但它们很实用!Fast.aiFast.ai库的编写是为了使用现代最佳实践方法以简化且快速准确进行神经网络训练,它抽象了在实践中实施深度神经网络可能带来的所有细节工作。而且它非常易于使用,并且设计它的人有应用程序构建思维。它最初是为Fast.ai课程的学生创建的,该库以简洁易懂的方式编写在易于使用的Pytorch库之上。DetectronDetectron是Facebook AI用于物体检测和实例分割研究的研究平台,系统是用Caffe2编写。它包含各种对象检测算法的实现,包括:Mask R-CNN:使用更快的R-CNN结构的对象检测和实例分割;RetinaNet:一个基于(Feature Pyramid Network)算法的网络,具有独特的Focal Loss来处理难题;Faster R-CNN:对象检测网络最常见的结构;所有网络都可以使用以下几种可选的分类主干之一:ResNeXt {50101152};RESNET {50101152};Feature Pyramid Network(使用ResNet/ResNeXt);VGG16;更重要的是,所有上述这些模型都是带有COCO数据集上的预训练模型,因此你可以立即使用它们!他们已经在Detectron模型动物园中使用标准评估指标进行了测试。FastText这是另一个来自Facebook的研究,fastText库专为文本表示和分类而设计。它配备了预先训练的150多种语言的词向量模型,这些单词向量可用于许多任务,包括文本分类,摘要和翻译等。Auto-KerasAuto-Keras是一个用于自动机器学习(AutoML)的开源软件库。它由Texas A&M大学的DATA实验室和社区贡献者开发。AutoML的最终目标是为具有有限数据科学或机器学习背景的开发工程师提供易于访问的深度学习工具。Auto-Keras提供自动搜索深度学习模型的最佳架构和超参数的功能。DopamineDopamine是由Google基于强化学习创建的快速原型设计的研究框架,它旨在灵活且易于使用,实现标准RL算法,指标和基准。根据Dopamine的文档,他们的设计原则是:简单的测试:帮助新用户运行基准测试;灵活的开发:为新用户提供新的创新想法;可靠:为一些较旧和更流行的算法提供实现;可重复性:确保结果是可重复;vid2vidvid2vid项目是在Pytorch上实现的Nvidia最先进的视频到视频合成的模型。视频到视频合成的目标是学习从输入源视频(例如,一系列语义分割掩模)到精确描绘源视频内容的输出照片拟真视频的映射函数。这个库的好处在于它的选择:它提供了几种不同的vid2vid应用程序,包括自动驾驶/城市场景,人脸和人体姿势。它还附带了丰富的指令和功能,包括数据集加载、任务评估、训练功能和多GPU!其他一些有价值的项目:ChatterBot:用于对话引擎和创建聊天机器人的机器学习模型;Kubeflow:Kubernetes的机器学习工具包;imgaug:用于深度学习的图像增强;imbalanced-learn:scikit下的python包,专门用于修复不平衡数据集;mlflow:用于管理ML生命周期的开源平台:包括测试,可重复性和部署;AirSim:基于虚幻引擎/Unity的自动驾驶汽车模拟器,来自Microsoft AI和Research;本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 7, 2019 · 1 min · jiezi

GIF动画解析RNN,LSTM,GRU

摘要: 本文主要研究了维尼拉循环神经(RNN)、长短期记忆(LSTM)和门控循环单元(GRU)这三个网络,介绍的比较简短,适用于已经了解过这几个网络的读者阅读。循环神经网络是一类常用在序列数据上的人工神经网络。三种最常见的循环神经网络分别是:1.维尼拉循环神经网络(vanilla RNN)2.长短期记忆网络(LSTM),由Hochreiter和Schmidhuber于1997年提出3.门控循环单元网络(GRU),由Cho等人于2014年提出现在可以查到许多解释循环神经网络这一概念的图示。不过我个人比较推荐的是Michael Nguyen在《迈向数据科学》上发表的这篇文章,因为这篇文章撰写了关于这些模型的很多知识,而且提供了清楚易懂的插图,易于读者理解。这篇文章目的是启发大家思考如何更好地可视化这些单元中发生的情况,节点是如何共享的,以及它们怎么转换为输出节点这些问题。Michael 的精彩动画也给了我很大的启发,从中受益匪浅。本文主要研究了维尼拉循环神经(RNN)、长短期记忆(LSTM)和门控循环单元(GRU)这三个网络,介绍的比较简短,适用于已经了解过这几个网络的读者(并且建议在阅读本文之前阅读Michael的文章)。请读者注意,下面的动画是按顺序排列的,读者请依序查看。如下图所示,是我用来做插图的图例。在所演示的动画中,我使用了3(绿色)和2个隐藏单元(红色)的输入大小,批处理大小为1。演示如下:Vanilla RNN* t — time step 时间步长* X — input 输入* h — hidden state 隐藏状态* length of X — size/dimension of input X的长度表示输入的大小,尺寸* length of h — no. of hidden units. h的长度表示不属于隐蔽的单位注意,不同的库可以用不同的方式调用它们,但它们的含义都是相同的。Keras — state_size ,unitsPyTorch — hidden_sizeTensorFlow — num_unitsLSTM* C — cell state注意,单元格状态的维度与隐藏状态的维度相同。GRU希望这些动画片对你有所帮助!以下是静态图像中的单元格的概述:非常感谢德里克和任杰对本文的想法、建议和纠正。如果您想继续了解人工智能和深度学习,可以在Twitter@remykarem上阅读我写的关于这些的摘要文章和演示。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 7, 2019 · 1 min · jiezi

即将取代RNN结构的Transformer

Transformer之前上图是经典的双向RNN模型,我们知道该模型是通过递归的方式运行,虽然适合对序列数据建模,但是缺点也很明显“它无法并行执行”也就无法利用GPU强大的并行能力(这里插句题外话,正因为GPU强大的并行能力,所以batch_size等于1和等于200运算时间基本差不多),再加上各种门控机制,运行速度很慢。一般而言,编码器输出编码向量C作为解码器输入,但是由于编码向量C中所有的编码器输入值贡献相同,导致序列数据越长信息丢失越多。CNN网络相比RNN网络,它虽然可以并行执行,但是无法一次捕获全局信息,通过上图可得我们需要多次遍历,多个卷积层叠加增大感受野。谷歌的做法是Attention is All You Need !Transformer如图所示是Transformer的整体结构,我们将详细介绍每一部分,先从左边的编码器开始。A: 这一步,我想大家已经非常熟悉了,将词汇表转为embedding维度的向量(onehot和embedding区别)。B: 仅仅使用attention有一个致命短板,它对序列数据的顺序免疫,即:无法捕获序列的顺序。比如对翻译任务,我们知道顺序非常重要,单词顺序变动甚至会产生完全不同的意思。因此增加Position Embedding给每个位置编号,每个编号对应一个向量,这样每个词向量都会有一个位置向量,以此来定位。如图所示,Position Embedding计算公式,将id为p的位置映射为一个dpos维的位置向量,这个向量的第i个元素的数值就是PEi(p),位置编码算法当然不止一种,但是不同算法必须要解决的的问题就是能够处理未知长度的序列。假设位置向量有4维,实际位置向量可能如下所示:结合位置向量和词向量我们有两种方式,一种是将两者拼接成一个新向量,另一种是使两者维度相同然后相加得到新向量。C:残差连接,随后是D: layer-normalization。随着网络层数的加深,会带来梯度消失,梯度爆炸以及过拟合问题。针对此问题,我们一般采用权重正则化,批标准化,更换激活函数等等措施,但是当网络层数进一步增加,会出现网络退化问题,即:训练集精度开始下降。使用残差可以解决此问题,目前使用残差的网络可以达到几百层。E:Multi-head注意力机制上图是attention计算过程,我们分解步骤,依次来看。生成“q”,“k”,“v”向量,由输入embedding向量与图示右侧对应权重矩阵相乘。需要注意的是,此处的三个权重矩阵为所有输入共享。如果每个词独享一个权重矩阵,个人认为并不会提升性能,有可能还会降低。计算attention score,计算方式如图所示:使用softmax归一化数值,softmax上面的相除操作主要是调解内积不要太大。将softmax归一化后的值与“v”向量矩阵相乘,将所有加权向量加和,产生该位置的self-attention的输出结果。multi-headed attention:就是有多组上面那样的attention,最后将结果拼接起来,其中,每组attention权重不共享。计算公式如下:整体计算过程如下图所示:F:全连接网络,两个线性函数,一个非线性函数(Relu):解码器:A:解码器attention计算的内部向量和编码器的输出向量,计算源句和目标句之间的关系,在Transformer之前,attention机制就应用在这里。B:线性层是一个全连接层,神经元数量和词表长度相等,然后添加softmax层,将概率最高值对应的词作为输出。总结Transformer现在大有取代RNN之势,但依然存在一些缺点。首先,Transformer虽然使用到了位置向量,但是对序列位置要求很高的项目做的并不好。Transformer可以一步到位获取全局信息,但如果你的项目只是需要局部信息呢?虽然也可以做到,但是增加了多余计算量。本文内容部分参考The Illustrated Transformer

January 5, 2019 · 1 min · jiezi

神经网络基础

要想入门以及往下理解深度学习,其中一些概念可能是无法避免地需要你理解一番,比如:什么是感知器什么是神经网络张量以及运算微分梯度下降带着问题出发在开始之前希望你有一点机器学习方面的知识,解决问题的前提是提出问题,我们提出这样一个问题,对MNIST数据集进行分析,然后在解决问题的过程中一步一步地来捋清楚其中涉及到的概念MNIST数据集是一份手写字训练集,出自MNIST,相信你对它不会陌生,它是机器学习领域的一个经典数据集,感觉任意一个教程都拿它来说事,不过这也侧面证明了这个数据集的经典,这里简单介绍一下:拥有60,000个示例的训练集,以及10,000个示例的测试集图片都由一个28 ×28 的矩阵表示,每张图片都由一个784 维的向量表示图片分为10类, 分别对应从0~9,共10个阿拉伯数字压缩包内容如下:train-images-idx3-ubyte.gz: training set images (9912422 bytes)train-labels-idx1-ubyte.gz: training set labels (28881 bytes)t10k-images-idx3-ubyte.gz: test set images (1648877 bytes)t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes)上图:图片生成代码如下:%matplotlib inlineimport matplotlibimport matplotlib.pyplot as pltimport numpy as npfrom keras.datasets import mnist(train_images, train_labels), (test_images, test_labels) = mnist.load_data()def plot_digits(instances, images_per_row=10, **options): size = 28 images_per_row = min(len(instances), images_per_row) images = instances n_rows = (len(instances) - 1) // images_per_row + 1 row_images = [] n_empty = n_rows * images_per_row - len(instances) images.append(np.zeros((size, size * n_empty))) for row in range(n_rows): rimages = images[row * images_per_row : (row + 1) * images_per_row] row_images.append(np.concatenate(rimages, axis=1)) image = np.concatenate(row_images, axis=0) plt.imshow(image, cmap = matplotlib.cm.binary, **options) plt.axis(“off”)plt.figure(figsize=(9,9))plot_digits(train_images[:100], images_per_row=10)plt.show()不过你不用急着尝试,接下来我们可以一步一步慢慢来分析手写字训练集看这一行代码:(train_images, train_labels), (test_images, test_labels) = mnist.load_data()MNIST数据集通过keras.datasets加载,其中train_images和train_labels构成了训练集,另外两个则是测试集:train_images.shape: (60000, 28, 28)train_labels.shape: (60000,)我们要做的事情很简单,将训练集丢到神经网络里面去,训练后生成了我们期望的神经网络模型,然后模型再对测试集进行预测,我们只需要判断预测的数字是不是正确的即可在用代码构建一个神经网络之前,我先简单介绍一下到底什么是神经网络,让我们从感知器开始感知器感知器是Frank Rosenblatt提出的一个由两层神经元组成的人工神经网络,它的出现在当时可是引起了轰动,因为感知器是首个可以学习的神经网络感知器的工作方式如下所示:左侧三个变量分别表示三个不同的二进制输入,output则是一个二进制输出,对于多种输入,可能有的输入成立有的不成立,在这么多输入的影响下,该如何判断输出output呢?Rosenblatt引入了权重来表示相应输入的重要性此时,output可以表示为:上面右侧的式子是一个阶跃函数,就是和Sigmoid、Relu一样作用的激活函数,然后我们就可以自己实现一个感知器:import numpy as npclass Perceptron: """ 代码实现 Frank Rosenblatt 提出的感知器的与非门,加深对感知器的理解 blog: https://www.howie6879.cn/post/33/ """ def init(self, act_func, input_nums=2): """ 实例化一些基本参数 :param act_func: 激活函数 """ # 激活函数 self.act_func = act_func # 权重 已经确定只会有两个二进制输入 self.w = np.zeros(input_nums) # 偏置项 self.b = 0.0 def fit(self, input_vectors, labels, learn_nums=10, rate=0.1): """ 训练出合适的 w 和 b :param input_vectors: 样本训练数据集 :param labels: 标记值 :param learn_nums: 学习多少次 :param rate: 学习率 """ for i in range(learn_nums): for index, input_vector in enumerate(input_vectors): label = labels[index] output = self.predict(input_vector) delta = label - output self.w += input_vector * rate * delta self.b += rate * delta print(“此时感知器权重为{0},偏置项为{1}".format(self.w, self.b)) return self def predict(self, input_vector): if isinstance(input_vector, list): input_vector = np.array(input_vector) return self.act_func(sum(self.w * input_vector) + self.b)def f(z): "”" 激活函数 :param z: (w1x1+w2x2+…+wj*xj) + b :return: 1 or 0 """ return 1 if z > 0 else 0def get_and_gate_training_data(): ’’’ AND 训练数据集 ’’’ input_vectors = np.array([[1, 1], [1, 0], [0, 1], [0, 0]]) labels = np.array([1, 0, 0, 0]) return input_vectors, labelsif name == ‘main’: """ 输出如下: 此时感知器权重为[ 0.1 0.2],偏置项为-0.2 与门 1 and 1 = 1 1 and 0 = 0 0 and 1 = 0 0 and 0 = 0 """ # 获取样本数据 and_input_vectors, and_labels = get_and_gate_training_data() # 实例化感知器模型 p = Perceptron(f) # 开始学习 AND p_and = p.fit(and_input_vectors, and_labels) # 开始预测 AND print(‘1 and 1 = %d’ % p_and.predict([1, 1])) print(‘1 and 0 = %d’ % p_and.predict([1, 0])) print(‘0 and 1 = %d’ % p_and.predict([0, 1])) print(‘0 and 0 = %d’ % p_and.predict([0, 0]))S型神经元神经元和感知器本质上是一样的,他们的区别在于激活函数不同,比如跃迁函数改为Sigmoid函数神经网络可以通过样本的学习来调整人工神经元的权重和偏置,从而使输出的结果更加准确,那么怎样给⼀个神经⽹络设计这样的算法呢?以数字识别为例,假设⽹络错误地把⼀个9的图像分类为8,我们可以让权重和偏置做些⼩的改动,从而达到我们需要的结果9,这就是学习。对于感知器,我们知道,其返还的结果不是0就是1,很可能出现这样一个情况,我们好不容易将一个目标,比如把9的图像分类为8调整回原来正确的分类,可此时的阈值和偏置会造成其他样本的判断失误,这样的调整不是一个好的方案所以,我们需要S型神经元,因为S型神经元返回的是[0,1]之间的任何实数,这样的话权重和偏置的微⼩改动只会引起输出的微⼩变化,此时的output可以表示为(w⋅x+b),而就是S型函数,S型函数中S指的是Sigmoid函数,定义如下:神经网络神经网络其实就是按照一定规则连接起来的多个神经元,一个神经网络由以下组件构成:输入层:接受传递数据,这里应该是 784 个神经元隐藏层:发掘出特征各层之间的权重:自动学习出来每个隐藏层都会有一个精心设计的激活函数,比如Sigmoid、Relu激活函数输出层,10个输出上⼀层的输出作为下⼀层的输⼊,信息总是向前传播,从不反向回馈:前馈神经网络有回路,其中反馈环路是可⾏的:递归神经网络从输入层传入手写字训练集,然后通过隐藏层向前传递训练集数据,最后输出层会输出10个概率值,总和为1。现在,我们可以看看Keras代码:第一步,对数据进行预处理,我们知道,原本数据形状是(60000, 28, 28),取值区间为[0, 255],现在改为[0, 1]:train_images = train_images.reshape((60000, 28 * 28)) train_images = train_images.astype(‘float32’) / 255test_images = test_images.reshape((10000, 28 * 28)) test_images = test_images.astype(‘float32’) / 255然后对标签进行分类编码:from keras.utils import to_categoricaltrain_labels = to_categorical(train_labels) test_labels = to_categorical(test_labels)第二步,编写模型:from keras import models from keras import layersnetwork = models.Sequential() network.add(layers.Dense(512, activation=‘relu’, input_shape=(28 * 28,))) network.add(layers.Dense(10, activation=‘softmax’) network.compile(optimizer=‘rmsprop’,loss=‘categorical_crossentropy’, metrics=[‘accuracy’])network.fit(train_images, train_labels, epochs=5, batch_size=128)一个隐藏层,激活函数选用relu,输出层使用softmax返回一个由10个概率值(总和为 1)组成的数组训练过程中显示了两个数字:一个是网络在训练数据上的损失loss,另一个是网络在 训练数据上的精度acc很简单,我们构建和训练一个神经网络,就这么几行代码,之所以写的这么剪短,是因为keras接接口封装地比较好用,但是里面的理论知识我们还是需要好好研究下神经网络的数据表示TensorFlow里面的Tensor是张量的意思,上面例子里面存储在多维Numpy数组中的数据就是张量:张量是数据容器,矩阵就是二维张量,张量是矩阵向任意维度的推广,张量的维度称为轴标量包含一个数字的张量叫做标量(0D张量),如下:x = np.array(12)print(x, x.ndim)# 12, 0张量轴的个数也叫做阶(rank)向量数字组成的数组叫做向量(1D张量),如下:x = np.array([12, 3, 6, 14, 7])print(x, x.ndim)# [12 3 6 14 7] 1矩阵向量组成的数组叫做矩阵(2D张量),如下:x = np.array([[5, 78, 2, 34, 0], [6, 79, 3, 35, 1], [7, 80, 4, 36, 2]])print(x, x.ndim)# [[ 5 78 2 34 0]# [ 6 79 3 35 1]# [ 7 80 4 36 2]] 23D张量与更高维张量将多个矩阵组合成一个新的数组就是一个3D张量,如下:x = np.array([[[5, 78, 2, 34, 0], [6, 79, 3, 35, 1]], [[5, 78, 2, 34, 0], [6, 79, 3, 35, 1]], [[5, 78, 2, 34, 0], [6, 79, 3, 35, 1]]])print(x, x.ndim)# (array([[[ 5, 78, 2, 34, 0],# [ 6, 79, 3, 35, 1]],# # [[ 5, 78, 2, 34, 0],# [ 6, 79, 3, 35, 1]],# # [[ 5, 78, 2, 34, 0],# [ 6, 79, 3, 35, 1]]]), 3)将多个3D张量组合成一个数组,可以创建一个4D张量关键属性张量是由以下三个关键属性来定义:轴的个数:3D张量三个轴,矩阵两个轴形状:是一个整数元祖,比如前面矩阵为(3, 5),向量(5,),3D张量为(3, 2, 5)数据类型在Numpy中操作张量以前面加载的train_images为:(train_images, train_labels), (test_images, test_labels) = mnist.load_data()比如进行切片选择10~100个数字:train_images[10:100].shape# (90, 28, 28)数据批量的概念深度学习模型会将数据集随机分割成小批量进行处理,比如:batch = train_images[:128]batch.shape# (128, 28, 28)现实世界的数据张量下面将介绍下现实世界中数据的形状:向量数据:2D张量,(samples, features)时间序列数据或者序列数据:3D张量,(samples, timesteps, features)图像:4D张量,(samples, height, width, channels) 或 (samples, channels, height, width)视频:5D张量,(samples, frames, height, width, channels) 或 (samples, frames, channels, height, width)张量运算类似于计算机程序的计算可以转化为二进制计算,深度学习计算可以转化为数值数据张量上的一些张量运算(tensor operation)上面模型的隐藏层代码如下:keras.layers.Dense(512, activation=‘relu’)这一层可以理解为一个函数,输入一个2D张量,输出一个2D张量,就如同上面感知机那一节最后输出的计算函数:output = relu(dot(W, input) + b)逐元素计算Relu 和加法运算都是逐元素的运算,比如:# 输入示例input_x = np.array([[2], [3], [1]])# 权重W = np.array([[5, 6, 1], [7, 8, 1]])# 计算输出 zz = np.dot(W, input_x)# 实现激活函数def naive_relu(x): assert len(x.shape) == 2 x = x.copy() for i in range(x.shape[0]): for j in range(x.shape[1]): x[i, j] = max(x[i, j], 0) return x# 激活函数对应的输出output = naive_relu(z)output广播张量运算那节中,有这样一段代码:output = relu(dot(W, input) + b)dot(W, input)是2D张量,b是向量,两个形状不同的张量相加,会发生什么?如果没有歧义的话,较小的张量会被广播,用来匹配较大张量的形状:input_x = np.array([[1], [3]])# 权重W = np.array([[5, 6], [7, 8]])b = np.array([1])# 计算输出 zz = np.dot(W, input_x) + b# array([[24],# [32]])张量点积点积运算,也叫张量积,如:import numpy as np# 输入示例input_x = np.array([[2], [3], [1]])# 权重W = np.array([[5, 6, 1], [7, 8, 1]])np.dot(W, input_x)两个向量之间的点积是一个标量:def naive_vector_dot(x, y): assert len(x.shape) == 1 assert len(y.shape) == 1 assert x.shape[0] == y.shape[0] z = 0. for i in range(x.shape[0]): z += x[i] * y[i] return zx = np.array([1,2])y = np.array([1,2])naive_vector_dot(x, y)# 5.0矩阵和向量点积后是一个向量:np.dot(W, [1, 2, 3])# array([20, 26])张量变形前面对数据进行预处理的时候:train_images = train_images.reshape((60000, 28 * 28)) train_images = train_images.astype(‘float32’) / 255上面的例子将输入数据的shape变成了(60000, 784),张量变形指的就是改变张量的行和列,得到想要的形状,前后数据集个数不变,经常遇到一个特殊的张量变形是转置(transposition),如下:x = np.zeros((300, 20))x = np.transpose(x)x.shape# (20, 300)梯度优化针对每个输入,神经网络都会通过下面的函数对输入数据进行变换:output = relu(dot(W, input_x) + b)其中:relu:激活函数W:是一个张量,表示权重,第一步可以取较小的随机值进行随机初始化b:是一个张量,表示偏置现在我们需要一个算法来让我们找到权重和偏置,从而使得y=y(x)可以拟合样本输入的x再回到感知器感知器学习的过程就是其中权重和偏置不断调优更新的过程,其中的偏置可以理解成输入为1的权重值,那么权重是怎么更新的呢?首先,介绍一个概念,损失函数,引用李航老师统计学习方法书中的一个解释:监督学习问题是在假设空间中选取模型f作为决策函数,对于给定的输入X,由f(X)给出相应的输出Y,这个输出的预测值f(X)与真实值Y可能一致也可能不一致,用一个损失函数(loss function)或代价函数(cost function)来度量预测错误的程度,损失函数是f(X)和Y的非负实值函数,记作L(Y,f(X))其中模型f(X)关于训练数据集的平均损失,我们称之为:经验风险(empirical risk),上述的权重调整,就是在不断地让经验风险最小,求出最好的模型f(X),我们暂时不考虑正则化,此时我们经验风险的最优化的目标函数就是:求解出此目标函数最小时对应的权重值,就是我们感知器里面对应的权重值,在推导之前,我们还得明白两个概念:什么是导数什么是梯度什么是导数假设有一个连续的光滑函数f(x) = y,什么是函数连续性?指的是x的微小变化只能导致y的微小变化。假设f(x)上的两点a,b足够接近,那么a,b可以近似为一个线性函数,此时他们斜率为k,那么可以说斜率k是f在b点的导数总之,导数描述了改变x后f(x)会如何变化,如果你希望减小f(x)的值,只需要将x沿着导数的反方向移动一小步即可,反之亦然什么是梯度梯度是张量运算的导数,是导数这一概念向多元函数导数的推广,它指向函数值上升最快的方向,函数值下降最快的方向自然就是梯度的反方向随机梯度下降推导过程如下:感知器代码里面的这段:self.w += input_vector * rate * delta就对应上面式子里面推导出来的规则总结再来看看全部的手写字识别模型代码:from keras import models from keras import layersfrom keras.utils import to_categorical(train_images, train_labels), (test_images, test_labels) = mnist.load_data()train_images = train_images.reshape((60000, 28 * 28)) train_images = train_images.astype(‘float32’) / 255test_images = test_images.reshape((10000, 28 * 28)) test_images = test_images.astype(‘float32’) / 255train_labels = to_categorical(train_labels) test_labels = to_categorical(test_labels)network = models.Sequential() network.add(layers.Dense(512, activation=‘relu’, input_shape=(28 * 28,))) network.add(layers.Dense(10, activation=‘softmax’))network.compile(optimizer=‘rmsprop’,loss=‘categorical_crossentropy’, metrics=[‘accuracy’])network.fit(train_images, train_labels, epochs=5, batch_size=128)test_loss, test_acc = network.evaluate(test_images, test_labels)print(’test_acc:’, test_acc)输入数据保存在float32格式的Numpy张量中,形状分别是(60000, 784)和(10000, 784)神经网络结构为:1个输入层、一个隐藏层、一个输出层categorical_crossentropy是针对分类模型的损失函数每批128个样本,共迭代5次,一共更新(469 * 5) = 2345次说明对本文有影响的书籍文章如下,感谢他们的付出:[统计学习方法] 第一章Neural Networks and Deep Learning 第一章Deep Learning with Python 第二章hands_on_Ml_with_Sklearn_and_TFhanbt零基础入门深度学习系列 ...

January 4, 2019 · 4 min · jiezi

2018年度机器学习50大热门网文

摘要: 本文总结了2018年期间机器学习博客top50篇,在这个寒冬中给大家带来一点干粮。新的一年新气象,总结过去一年,展望新的一年。站在巨人的肩膀上前行,肯定会事半功倍。因此,本文从2018年1月至12月期间挑选出近22,000篇机器学习文章,并进行比较,以挑选出能够提升2019年数据科学技能的前50名文章。从概率上讲,这是一个极具竞争力的列表,概率仅为50 / 22,000(0.23%),且需要经过仔细挑选并与过去一年发布的机器学习文章进行对比。Mybridge AI通过考虑受欢迎程度、参与度和新近度以及其他人为因素来评估这些文章的质量。本教程将50篇文章划分为16个相关组:寒冬已至,请花些大量时间阅读过去一年中可能错过的顶级机器学习教程。如果想查看去年最好的机器学习系列文章,请点击这里。深度视频No. 1Deepfakes与家庭乐趣,如何让自己妻子参加今夜秀——由Sven Charleer提供;No. 2深度视频肖像:一种新颖的方法,只使用输入视频即可实现肖像视频的照片般逼真的重新动画——由Christian Theobalt提供;人脸识别No. 3如何使用Python中的深度学习实现iPhone X的FaceID功能——Nouman Di PaloCourtesy;No. 4使用OpenCV、Python和深度学习进行人脸识别——由Adrian Rosebrock提供;No. 5前沿人脸识别很复杂,这些电子表格让它变得更容易——由 Dave Smith提供;对象检测No. 6在Airbnb上分类列表照片:大规模深度学习模型正在改变我们在平台上思考家庭图像的方式——由Shijing Yao提供;No. 7使用OpenCV进行YOLO对象检测——由Adrian Rosebrock提供;No. 8使用10行代码实现对象检测——由Moses Olafenwa提供;游戏AINo. 9游戏AI的初学者指南——由Kylotan提供;No. 10基于预测奖励的强化学习——由Harri Edwards提供;No. 11Montezuma的复仇之路通过Go-Explore解决,这是一种新的解决困难探索问题的算法——由优步工程师提供;No. 12抢旗:代理如何在复杂的第一人称多人游戏中实现人类级别的表现,甚至可以与人类队友合作——由DeepMind提供;No. 13OpenAI Five:在Dota 2游戏中击败业余人类玩家——由OpenAI提供;象棋No. 14AlphaZero:在国际象棋、将棋和围棋的盛大游戏中崭露头角——由DeepMind提供;No. 15如何使用Python和Keras构建自己的AlphaZero AI——由David Foster提供;No. 16简单解释:人工智能程序如何掌握围棋游戏的古老游戏——由Aman Agarwal提供;医疗No. 17深度学习在医学图像数据集中的不合理用处——由Luke Oakden-Rayner提供;No. 18利用基于DNA的胜者通吃神经网络扩大分子模式识别——由Kevin M. Cherry、Lulu Qian提供;No. 19针对脑核磁共振图像的深度学习方法——由Henrik Marklund提供;运动No. 20每个人都跳舞:一个简单的方法“跟我做”动作迁移——由Caroline Chan等人提供;No. 21走向虚拟替身演员——由Xue Bin peng提供;No. 22学习敏捷:一个真正的机器人手,使用与OpenAI Five相同的学习算法和代码进行训练,已经学习了类似于旋转物体的动作——由OpenAI提供;No. 23在人工代理中使用类似网格的表示进行导航——由Andrea Banino等人提供;Web&AppNo. 24如何使用CoreML、PyTorch和React Native在iOS上发布神经网络——由 Stefano等人提供;No. 25如何训练AI将设计模型转换为HTML和CSS——由Emil Wallner提供;翻译No. 26通过更快的训练和推理将神经机器翻译成更大的数据集——由Michael Auli等人提供;No. 27在翻译中找到:通过深入学习从头开始构建语言翻译——由Samuel Lynn-Evans等人提供;No. 28无监督机器翻译:为更多语言提供快速,准确翻译的新方法。由Facebook Research提供NLPNo. 29有关BERT、ELMo和co(如何NLP破解转移学习)的说明——由Jay Alammar提供No. 30注释迁移学习——由哈佛NLP组提供;No. 31自然语言处理很有趣——由Adam Geitgey提供;神经网络No. 32如何在Python中从头开始构建自己的神经网络——由James Loy提供;No. 33使用简单的NumPy编写一个神经网络——由Piotr Skalski提供;CNNNo. 34可区分的图像参数化:一种功能强大、探索不足的神经网络可视化和艺术工具——由distillpub提供;No. 35特征转换——由distillpub提供;No. 36Keras和卷积神经网络(CNN——由Adrian Rosebrock提供;No. 37可解释性的组成部分——由Distill提供;No. 38Rosetta:通过机器学习理解图像和视频中的文本——由Facebook Research提供;No. 39一个有趣的卷积神经网络失败案例和协同解决方案——由优步提供;RNNNo. 40Google Duplex:用于通过电话完成真实世界任务的AI系统——由Yaniv Leviathan提供;No. 41世界模型:代理人可以在自己的梦中学习吗?——由maru提供;强化学习No. 42经验教训再现深度强化学习论文——由Matthew Rahtz提供;No. 43具有强化学习的灵巧操作:高效、通用和低成本——由Henry Zhu等人提供;No. 44深度强化学习不起作用——由Sorta Insightful提供;TensorFlowNo. 45TensorFlow中的三元组损失和在线挖掘——由Olivier Moindrot提供;No. 46Tensorflow:令人困惑的部件(1)——由Jacob Buckman提供;No. 47Tensorflow-Project-Template:TensorFlow项目模板架构的最佳实践(Github上已有2579颗星)——由Mahmoud Gemy提供;No. 48使用TensorFlow.js在浏览器中进行实时人体姿态估计——由TensorFlow提供;指南No. 49机器学习规则:| ML通用指南|谷歌开发者——由Martin Zinkevich提供;No. 50基于模型的机器学习——由John Winn和Christopher M. Bishop提供以上就是2018年度top50机器学习教程。如果你有更好的文章,请留言。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

January 2, 2019 · 1 min · jiezi

各类监督方法流行趋势分析

摘要: 想知道目前最流行的监督学习方法是哪一类吗?本文统计每种类型的出版物数量的历史数据回答了该问题,一睹为快吧!又到一年的年末了,到了进行总结并展望来年的时候了,在这里预祝各位新的一年顺利。闲话少叙,本文将对有监督学习方法进行总结。机器学习领域在过去几十年中经历了巨大的变化,不可否认的是,虽然有些方法已经存在了很长时间,但仍然是该领域的主要内容。例如,最小二乘法( least squares)的概念在19世纪早期由勒让德和高斯提出,最基本的形式的神经网络( neural networks)早在1958年就引入的,并在过去的几十年中大幅提升、支持向量机(SVM)等方法则更是较新的方法,这些方法仍然占据了机器学习领域应用中的半壁江山。 随着科研的进行,有大量可用的监督学习方法被发明。使用者通常会提出以下问题:什么是最好的模型?众所周知,这个问题没有标准答案,因为模型的有用性取决于手头的数据以及具体处理的问题,合适的就是最好的。那么,可以转换下思路,换成这个问题:最受欢迎的模型是什么?这将是本文的关注点。衡量机器学习模型的流行程度出于本文的目的,使用频率论方法定义流行度。更确切地说,将使用提及个人监督学习模型的科学出版物的数量表示受欢迎的程度。当然,这种方法有一些限制:可能有比出版物数量更准确的表示方法;分析受所使用的搜索术语的影响;文献数据库并不完美;因此,对于这篇文章进行了两次分析。第一个分析是对出版频率的纵向分析,而第二个分析则比较了不同领域与机器学习模型相关的出版物总数。在第一次分析中,通过从谷歌学术搜索中搜索数据来确定出版物的数量,该数据考虑出版物的标题和摘要。为了确定与个人监督学习方法相关的出版物数量,统计1950年至2017年期间谷歌学术搜索的点击次数。由于抓取谷歌学术的数据非常困难,所以本文参考ScrapeHero提供的有用建议来收集数据。在分析中包含了13种监督方法:神经网络、深度学习、SVM、随机森林、决策树、线性回归、逻辑回归、泊松回归、岭回归、套索回归( lasso regression)、k-最近邻、线性判别分析、以及对数线性模型。其中,对于套索回归,搜索时考虑了 lasso regression和套lasso model ;对于最近邻方法,搜索时术语有k-nearest neighbor和k-nearest neighbour,得到的数据集表示从1950年到现在,每个监督模型相关的出版物的数量。从1950年到现在使用的监督模型为了分析纵向数据,将时间段划分为两个时期:机器学习的早期阶段(1950年至1980年),几乎没有可用模型;以及形成时期(1980年至今),开发了许多新模型。早期:线性回归占优势从图1中可以看出,线性回归是1950年至1980年间的主导方法。相比之下,科学文献中极少提及其他机器学习模型。然而,从20世纪60年代开始,可以看到神经网络和决策树的普及开始增长。此外,还可以看到逻辑回归尚未广泛应用,在20世纪70年代末的数量仅略有增加。形成年代:神经网络的多样化和兴起图2表明,从20世纪80年代后期开始,出版物中提到的监督模型变得更加多样化。重要的是,文献中提到的机器学习模型的比率一直稳步增加,直到2013年。该图具体显示了线性回归、逻辑回归和神经网络的普及。正如之前所见,线性回归在1980年之前已经流行。然而,从1980年开始,神经网络和逻辑回归的普及开始迅速增长。虽然逻辑回归的流行度在2010年达到顶峰,该方法几乎变得像线性回归一样受欢迎,但近年来,神经网络和深度学习的流行程度甚至超过了2015年线性回归的流行程度。神经网络已经变得非常受欢迎,因为它们已经在机器学习应用方面取得了突破,例如图像识别(ImageNet,2012)、人脸识别(DeepFace,2014)和游戏(AlphaGo,2016)等。来自谷歌学术的数据表明,文章中提到神经网络的频率在过去几年中略有下降(图2中未显示)。这可能是因为术语深度学习(多层神经网络)在某种程度上取代了术语神经网络的使用。另外可以看到,稍微不那么受欢迎的监督方法是决策树和SVM。与前三种方法相比,提到这些方法的频率明显较小。另一方面,文献中提到这些方法的频率似乎也有较小的波动。值得注意的是,决策树和SVM的流行度都没有下降。在决策树和SVM之间,SVM似乎表现出更有利的增长趋势,因为SVM在发明后仅仅15年就成功超越了决策树。不同领域的监督学习模型的受欢迎程度在第二个分析中,想调查不同的领域是否依赖于不同的机器学习技术。为此,查询了三个科学出版物库:谷歌学术出版物、计算机科学出版物的dblp和生物医学科学出版物的PubMed。在三个库中统计了13个机器学习模型的命中频率。结果如图3所示。图3表明,许多方法对各个领域都非常具体,下面分析每个领域中最流行的模型。整体使用监督学习模型根据谷歌学术搜索表明,最常用的五种监督模型如下所示:线性回归: 3,580,000(34.3%)篇论文;逻辑回归:2,330,000(22.3%)篇论文;神经网络: 1,750,000(16.8%)篇论文;决策树: 875,000(8.4%)份论文;支持向量机:684,000(6.6%)篇论文;总体而言,线性模型显然占主导地位,占监督模型的统计率的50%以上。单非线性方法并不落后:神经网络占所有论文的16.8%,其次是决策树(8.4%的论文)和SVM(6.6%的论文)。在生物医学科学中使用模型根据PubMed,在生物医学科学中,最受欢迎的五种机器学习模型如下所示:逻辑回归: 229,956(54.5%)篇论文;线性回归: 84,850(20.1%)篇论文;Cox回归: 38,801(9.2%)篇论文;神经网络: 23,883(5.7%)篇论文;泊松回归: 12,978(3.1%)篇论文;在生物医学科学中,可以看到与线性模型相关的提及次数偏多:五种最流行的方法中有四种是线性的,这可能是由于两个原因造成的。首先,在医疗环境中,样本数量通常太小,无法拟合复杂的非线性模型。其次,模型解释结果的能力对医疗应用至关重要。由于非线性方法通常难以解释,因此它们不太适合医疗应用。逻辑回归在PubMed数据库中的流行可能是由于大量出版物的临床研究。在这些研究中,通常使用逻辑回归分析分类结果(即治疗成功),因为它非常适合于解释特征对结果的影响。Cox回归在PubMed数据库中也非常流行,因为它常用于分析Kaplan-Meier生存数据。在计算机科学中使用的模型从dblp中检索到,计算机科学书目中最受欢迎的五个模型是:神经网络: 63,695(68.3%)篇论文;深度学习: 10,157(10.9%)篇论文;支持向量机: 7,750(8.1%)篇论文;决策树: 4,074(4.4%)篇论文;最近邻居: 3,839(2.1%)篇论文;计算机科学出版物中提到的机器学习模型的分布是截然不同的:大多数出版物似乎都涉及最近的非线性方法(例如神经网络、深度学习和支持向量机),如果将深度学习算作神经网络的一种,则超过四分之三的检索计算机科学出版物都涉及神经网络。行业之间的差别图4总结了文献中提到的参数和非参数模型的百分比。柱形图表明,在机器学习研究中调查的模型(计算机科学出版物)和应用的模型类型(生物医学和整体出版物)之间存在很大差异。虽然超过90%的计算机科学出版物涉及非参数模型,但大约90%的生物医学出版物涉及参数模型,这表明机器学习研究主要集中在最先进的方法,如深度神经网络,而机器学习的用户往往依赖于更多可解释的参数模型,如逻辑回归等。总结对科学文献中有监督学习模型的流行度分析表明了人工神经网络的受欢迎程度。但是,也看到不同的领域使用不同类型的机器学习模型。特别是生物医学科学的研究人员仍然严重依赖参数模型,但这种情况逐渐在发生改变,随着可解释模型的研究更加深入,更复杂的模型一定会在生物医学领域得到广泛应用。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 2, 2019 · 1 min · jiezi

2018年深度学习的主要进步

摘要: 一文了解2018深度学习取得了哪些突破性进展!在过去几年中,深度学习改变了整个人工智能的发展。深度学习技术已经开始在医疗保健,金融,人力资源,零售,地震检测和自动驾驶汽车等领域的应用程序中出现。至于现有的成果表现也一直在稳步提高。在学术层面,机器学习领域已经变得非常重要了,以至于每20分钟就会出现一篇新的科学文章。在本文中,我将介绍2018年深度学习的一些主要进展,与2017年深度学习进展版本一样,我没有办法进行详尽的审查。我只想分享一些给我留下最深刻印象的领域成就。语言模型:Google的BERT在自然语言处理(NLP)中,语言模型是可以估计一组语言单元(通常是单词序列)的概率分布的模型。在该领域有很多有趣的模型,因为它们可以以很低的成本构建,并且显着改进了几个NLP任务,例如机器翻译,语音识别和内容解析。历史上,最著名的方法之一是基于马尔可夫模型和n-gram。随着深度学习的出现,出现了基于长短期记忆网络(LSTM)更强大的模型。虽然高效,但现有模型通常是单向的,这意味着只有单词的上下文才会被考虑。去年10月,Google AI语言团队发表了一篇引起社区轰动的论文。BERT是一种新的双向语言模型,它已经实现了11项复杂NLP任务的最新结果,包括情感分析、问答和复述检测#Paraphrase_recognition)。预训练BERT的策略不同于传统的从左到右或从右到左的选项。新颖性包括:随机屏蔽一定比例的输入词,然后预测那些被屏蔽的词;这可以在多层次的背景下保持间接“看到自己”的词语。构建二元分类任务以预测句子B之后是否紧跟句子A,这允许模型确定句子之间的关系,这种现象不是由经典语言建模直接捕获的。至于实施,Google AI开源了他们的论文代码,该代码基于TensorFlow。其中一些在PyTorch也能实现,例如Thomas Wolf和Junseong Kim的实现。BERT对业务应用程序的影响很大,因为这种改进会影响NLP的各个方面。这可以在机器翻译,聊天机器人行为,自动电子邮件响应和客户审查分析中获得更准确的结果。视频到视频合成我们通常习惯由图形引擎创建的模拟器和视频游戏进行环境交互。虽然令人印象深刻,但经典方法的成本很高,因为必须精心指定场景几何、材料、照明和其他参数。一个很好的问题是:是否可以使用例如深度学习技术自动构建这些环境。在他们的视频到视频合成论文中,NVIDIA的研究人员解决了这个问题。他们的目标是在源视频和输出视频之间提供映射功能,精确描绘输入内容。作者将其建模为分布匹配问题,其目标是使自动创建视频的条件分布尽可能接近实际视频的条件分布。为实现这一目标,他们建立了一个基于生成对抗网络(GAN)的模型。在GAN框架内的关键思想是,生成器试图产生真实的合成数据,使得鉴别器无法区分真实数据和合成数据。他们定义了一个时空学习目标,旨在实现暂时连贯的视频。结果非常惊人,如下面的图片所示:输入视频位于左上象限,它是来自Cityscapes数据集的街道场景视频的分段图。作者将他们的结果(右下)与两个基线进行比较:pix2pixHD(右上)和COVST(左下)。这种方法甚至可以用于执行未来的视频预测。由于NVIDIA开源vid2vid代码(基于PyTorch),你可以尝试执行它。改进词嵌入去年,我写了关于字嵌入在NLP中的重要性,并且相信这是一个在不久的将来会得到更多关注的研究课题。任何使用过词嵌入的人都知道,一旦通过组合性检查的兴奋(即King-Man+Woman=Queen)已经过去,因为在实践中仍有一些限制。也许最重要的是对多义不敏感,无法表征词之间确切建立的关系。到底同义词Hyperonyms?另一个限制涉及形态关系:词嵌入模型通常无法确定诸如驾驶员和驾驶之类的单词在形态上是相关的。在题为“深度语境化词语表示”(被认为是NAACL 2018年的优秀论文)的论文中,来自艾伦人工智能研究所和Paul G. Allen计算机科学与工程学院的研究人员提出了一种新的深层语境化词汇表示方法。同时模拟单词使用的复杂特征(例如语法和语义)以及这些用途如何在语言环境(即多义词)中变化。他们的提议的中心主题,称为语言模型嵌入(ELMo),是使用它的整个上下文或整个句子来对每个单词进行矢量化。为了实现这一目标,作者使用了深度双向语言模型(biLM),该模型在大量文本上进行了预训练。另外,由于表示基于字符,因此可以捕获单词之间的形态句法关系。因此,当处理训练中未见的单词(即词汇外单词)时,该模型表现得相当好。作者表明,通过简单地将ELMo添加到现有的最先进解决方案中,结果可以显著改善难以处理的NLK任务,例如文本解释,共指解析和问答,与Google的BERT表示一样,ELMo是该领域的重要贡献,也有望对业务应用程序产生重大影响。视觉任务空间结构的建模视觉任务是否相关?这是斯坦福大学和加州大学伯克利分校的研究人员在题为“Taskonomy:Disentangling Task Transfer Learning”的论文中提出的问题,该论文获得了2018年CVPR的最佳论文奖。可以合理地认为某些视觉任务之间存在某种联系。例如,知道表面法线可以帮助估计图像的深度。在这种情况下,迁移学习技术-或重用监督学习结果的可能性将极大的提高。作者提出了一种计算方法,通过在26个常见的视觉任务中找到转移学习依赖关系来对该结构进行建模,包括对象识别、边缘检测和深度估计。输出是用于任务转移学习的计算分类图。上图显示了计算分类法任务发现的示例任务结构。在该示例中,该方法告知我们如果组合了表面法线估计器和遮挡边缘检测器的学习特征,则可以用很少的标记数据快速训练用于重新整形和点匹配的模型。减少对标签数据的需求是这项工作的主要关注点之一。作者表明,可以通过粗略地减小求解一组10个任务所需的标记的数据点的总数2/3(具有独立训练相比),同时保持几乎相同的性能。这是对实际用例的重要发现,因此有望对业务应用程序产生重大影响。微调通用语言模型以进行文本分类深度学习模型为NLP领域做出了重大贡献,为一些常见任务提供了最先进的结果。但是,模型通常从头开始训练,这需要大量数据并且需要相当长的时间。Howard和Ruder提出了一种归纳迁移学习方法,称为通用语言模型微调(ULMFiT)。主要思想是微调预训练的语言模型,以使其适应特定的NLP任务。这是一种精明的方法,使我们能够处理我们没有大量数据的特定任务。他们的方法优于六个文本分类任务的最新结果,将错误率降低了18-24%。关于训练数据的数量,结果也非常惊人:只有100个标记样本和50K未标记样本,该方法实现了与10K标记样本从头开始训练的模型相同的性能。同样,这些结果证明迁移学习是该领域的关键概念。你可以在这里查看他们的代码和预训练模型。最后的想法与去年的情况一样,2018年深度学习技术的使用持续增加。特别是,今年的特点是迁移学习技术越来越受到关注。从战略角度来看,这可能是我认为今年最好的结果,我希望这种趋势在将来可以继续下去。我在这篇文章中没有探讨的其他一些进展同样引人注目。例如,强化学习的进步,例如能够击败Dota 2的职业玩家的惊人的OpenAI Five机器人。另外,我认为现在球CNN,特别有效的分析球面图像,以及PatternNet和PatternAttribution,这两种技术所面临的神经网络的一个主要缺点:解释深层网络的能力。上述所有技术发展对业务应用程序的影响是巨大的,因为它们影响了NLP和计算机视觉的许多领域。我们可能会在机器翻译、医疗诊断、聊天机器人、仓库库存管理、自动电子邮件响应、面部识别和客户审查分析等方面观察到改进的结果。从科学的角度来看,我喜欢Gary Marcus撰写的深度学习评论。他清楚地指出了当前深度学习方法的局限性,并表明如果深度学习方法得到其他学科和技术的见解(如认知和发展心理学、符号操作和混合建模)的补充,人工智能领域将获得相当大的收益。无论你是否同意他,我认为值得阅读他的论文。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 2, 2019 · 1 min · jiezi

CNN 模型压缩与加速算法综述

本文由云+社区发表导语:卷积神经网络日益增长的深度和尺寸为深度学习在移动端的部署带来了巨大的挑战,CNN模型压缩与加速成为了学术界和工业界都重点关注的研究领域之一。前言自从AlexNet一举夺得ILSVRC 2012 ImageNet图像分类竞赛的冠军后,卷积神经网络(CNN)的热潮便席卷了整个计算机视觉领域。CNN模型火速替代了传统人工设计(hand-crafted)特征和分类器,不仅提供了一种端到端的处理方法,还大幅度地刷新了各个图像竞赛任务的精度,更甚者超越了人眼的精度(LFW人脸识别任务)。CNN模型在不断逼近计算机视觉任务的精度极限的同时,其深度和尺寸也在成倍增长。自从AlexNet一举夺得ILSVRC 2012 ImageNet图像分类竞赛的冠军后,卷积神经网络(CNN)的热潮便席卷了整个计算机视觉领域。CNN模型火速替代了传统人工设计(hand-crafted)特征和分类器,不仅提供了一种端到端的处理方法,还大幅度地刷新了各个图像竞赛任务的精度,更甚者超越了人眼的精度(LFW人脸识别任务)。CNN模型在不断逼近计算机视觉任务的精度极限的同时,其深度和尺寸也在成倍增长。表1 几种经典模型的尺寸,计算量和参数数量对比ModelModel Size(MB)MillionMult-AddsMillionParametersAlexNet[1]>20072060VGG16[2]>50015300138GoogleNet[3]5015506.8Inception-v3[4]90-100500023.2随之而来的是一个很尴尬的场景:如此巨大的模型只能在有限的平台下使用,根本无法移植到移动端和嵌入式芯片当中。就算想通过网络传输,但较高的带宽占用也让很多用户望而生畏。另一方面,大尺寸的模型也对设备功耗和运行速度带来了巨大的挑战。因此这样的模型距离实用还有一段距离。在这样的情形下,模型小型化与加速成了亟待解决的问题。其实早期就有学者提出了一系列CNN模型压缩方法,包括权值剪值(prunning)和矩阵SVD分解等,但压缩率和效率还远不能令人满意。近年来,关于模型小型化的算法从压缩角度上可以大致分为两类:从模型权重数值角度压缩和从网络架构角度压缩。另一方面,从兼顾计算速度方面,又可以划分为:仅压缩尺寸和压缩尺寸的同时提升速度。本文主要讨论如下几篇代表性的文章和方法,包括SqueezeNet[5]、Deep Compression[6]、XNorNet[7]、Distilling[8]、MobileNet[9]和ShuffleNet[10],也可按照上述方法进行大致分类:表2 几种经典压缩方法及对比MethodCompression ApproachSpeed ConsiderationSqueezeNetarchitectureNoDeep CompressionweightsNoXNorNetweightsYesDistillingarchitectureNoMobileNetarchitectureYesShuffleNetarchitectureYes一、SqueezeNet1.1 设计思想SqueezeNet是F. N. Iandola,S.Han等人于2016年的论文《SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and < 0.5MB model size》中提出的一个小型化的网络模型结构,该网络能在保证不损失精度的同时,将原始AlexNet压缩至原来的510倍左右(< 0.5MB)。SqueezeNet的核心指导思想是——在保证精度的同时使用最少的参数。而这也是所有模型压缩方法的一个终极目标。基于这个思想,SqueezeNet提出了3点网络结构设计策略:策略 1.将3x3卷积核替换为1x1卷积核。这一策略很好理解,因为1个1x1卷积核的参数是3x3卷积核参数的1/9,这一改动理论上可以将模型尺寸压缩9倍。策略 2.减小输入到3x3卷积核的输入通道数。我们知道,对于一个采用3x3卷积核的卷积层,该层所有卷积参数的数量(不考虑偏置)为:式中,N是卷积核的数量,也即输出通道数,C是输入通道数。因此,为了保证减小网络参数,不仅仅需要减少3x3卷积核的数量,还需减少输入到3x3卷积核的输入通道数量,即式中C的数量。策略 3.尽可能的将降采样放在网络后面的层中。在卷积神经网络中,每层输出的特征图(feature map)是否下采样是由卷积层的步长或者池化层决定的。而一个重要的观点是:分辨率越大的特征图(延迟降采样)可以带来更高的分类精度,而这一观点从直觉上也可以很好理解,因为分辨率越大的输入能够提供的信息就越多。上述三个策略中,前两个策略都是针对如何降低参数数量而设计的,最后一个旨在最大化网络精度。1.2 网络架构基于以上三个策略,作者提出了一个类似inception的网络单元结构,取名为fire module。一个fire module 包含一个squeeze 卷积层(只包含1x1卷积核)和一个expand卷积层(包含1x1和3x3卷积核)。其中,squeeze层借鉴了inception的思想,利用1x1卷积核来降低输入到expand层中3x3卷积核的输入通道数。如图1所示。图1 Fire module结构示意图[5]其中,定义squeeze层中1x1卷积核的数量是s1x1,类似的,expand层中1x1卷积核的数量是e1x1, 3x3卷积核的数量是e3x3。令s1x1 < e1x1+ e3x3从而保证输入到3x3的输入通道数减小。SqueezeNet的网络结构由若干个 fire module 组成,另外文章还给出了一些架构设计上的细节:为了保证1x1卷积核和3x3卷积核具有相同大小的输出,3x3卷积核采用1像素的zero-padding和步长squeeze层和expand层均采用RELU作为激活函数在fire9后采用50%的dropout由于全连接层的参数数量巨大,因此借鉴NIN[11]的思想,去除了全连接层而改用global average pooling。1.3 实验结果表3 不同压缩方法在ImageNet上的对比实验结果[5]上表显示,相比传统的压缩方法,SqueezeNet能在保证精度不损(甚至略有提升)的情况下,达到最大的压缩率,将原始AlexNet从240MB压缩至4.8MB,而结合Deep Compression后更能达到0.47MB,完全满足了移动端的部署和低带宽网络的传输。此外,作者还借鉴ResNet思想,对原始网络结构做了修改,增加了旁路分支,将分类精度提升了约3%。1.4 速度考量尽管文章主要以压缩模型尺寸为目标,但毋庸置疑的一点是,SqueezeNet在网络结构中大量采用1x1和3x3卷积核是有利于速度的提升的,对于类似caffe这样的深度学习框架,在卷积层的前向计算中,采用1x1卷积核可避免额外的im2col操作,而直接利用gemm进行矩阵加速运算,因此对速度的优化是有一定的作用的。然而,这种提速的作用仍然是有限的,另外,SqueezeNet采用了9个fire module和两个卷积层,因此仍需要进行大量常规卷积操作,这也是影响速度进一步提升的瓶颈。二、Deep CompressionDeep Compression出自S.Han 2016 ICLR的一篇论文《Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding》。该文章获得了ICLR 2016的最佳论文奖,同时也具有里程碑式的意义,引领了CNN模型小型化与加速研究方向的新狂潮,使得这一领域近两年来涌现出了大量的优秀工作与文章。2.1 算法流程与前面的“架构压缩派”的SqueezeNet不同,Deep Compression是属于“权值压缩派”的。而两篇文章均出自S.Han团队,因此两种方法结合,双剑合璧,更是能达到登峰造极的压缩效果。这一实验结果也在上表中得到验证。Deep Compression的算法流程包含三步,如图2所示:图2 Deep Compression Pipeline[6]1、Pruning(权值剪枝)剪枝的思想其实早已在早期论文中可以窥见,LeCun等人曾经就利用剪枝来稀疏网络,减小过拟合的风险,提升网络泛化性。图3是MNIST上训练得到的LeNet conv1卷积层中的参数分布,可以看出,大部分权值集中在0处附近,对网络的贡献较小,在剪值中,将0值附近的较小的权值置0,使这些权值不被激活,从而着重训练剩下的非零权值,最终在保证网络精度不变的情况下达到压缩尺寸的目的。实验发现模型对剪枝更敏感,因此在剪值时建议逐层迭代修剪,另外每层的剪枝比例如何自动选取仍然是一个值得深入研究的课题。图3 LeNet conv1层权值分布图2、Quantization (权值量化)此处的权值量化基于权值聚类,将连续分布的权值离散化,从而减小需要存储的权值数量。初始化聚类中心,实验证明线性初始化效果最好;利用k-means算法进行聚类,将权值划分到不同的cluster中;在前向计算时,每个权值由其聚类中心表示;在后向计算时,统计每个cluster中的梯度和将其反传。图4 权值量化前向和后向计算过程[6]3、Huffman encoding(霍夫曼编码)霍夫曼编码采用变长编码将平均编码长度减小,进一步压缩模型尺寸。2.2 模型存储前述的剪枝和量化都是为了实现模型的更紧致的压缩,以实现减小模型尺寸的目的。对于剪枝后的模型,由于每层大量参数为0,后续只需将非零值及其下标进行存储,文章中采用CSR(Compressed Sparse Row)来进行存储,这一步可以实现9x13x的压缩率。对于量化后的模型,每个权值都由其聚类中心表示(对于卷积层,聚类中心设为256个,对于全连接层,聚类中心设为32个),因此可以构造对应的码书和下标,大大减少了需要存储的数据量,此步能实现约3x的压缩率。最后对上述压缩后的模型进一步采用变长霍夫曼编码,实现约1x的压缩率。2.3 实验结果表4 不同网络采用Deep Compression后的压缩率[6]通过SqueezeNet+Deep Compression,可以将原始240M的AlexNet压缩至0.47M,实现约510x的压缩率。2.4 速度考量可以看出,Deep Compression的主要设计是针对网络存储尺寸的压缩,但在前向时,如果将存储模型读入展开后,并没有带来更大的速度提升。因此Song H.等人专门针对压缩后的模型设计了一套基于FPGA的硬件前向加速框架EIE[12],有兴趣的可以研究一下。三、XNorNet二值网络一直是模型压缩和加速领域经久不衰的研究课题之一。将原始32位浮点型的权值压缩到1比特,如何最大程度地减小性能损失就成为了研究的关键。此篇论文主要有以下几个贡献:提出了一个BWN(Binary-Weight-Network)和XNOR-Network,前者只对网络参数做二值化,带来约32x的存储压缩和2x的速度提升,而后者对网络输入和参数都做了二值化,在实现32x存储压缩的同时带了58x的速度提升;提出了一个新型二值化权值的算法;第一个在大规模数据集如ImageNet上提交二值化网络结果的工作;无需预训练,可实现training from scratch。3.1 BWN为了训练二值化权值网络,令,其中,即二值滤波器,是是尺度因子。通过最小化目标函数,得到其最优解:即最优的二值化滤波器张量B即为原始参数的符号函数,最优的尺度因子为每个滤波器权值的绝对值的均值。训练算法如图5所示,值得注意的是,只有在前向计算和后向传播时使用二值化后的权值,在更新参数时依然使用原始参数,这是因为如果使用二值化后的参数会导致很小的梯度下降,从而使得训练无法收敛。3.2 XNOR-Net在XNOR网络中,优化的目标是将两个实数向量的点乘近似到两个二值向量的点乘,即式中,,类似的,有最优解如下式在卷积计算中,输入和权值均量化成了二值,因此传统的乘法计算变成了异或操作,而非二值化数据的计算只占了很小一部分。XNOR-Net中一个典型的卷积单元如图6所示,与传统单元不同,各模块的顺序有了调整。为了减少二值化带来的精度损失,对输入数据首先进行BN归一化处理,BinActiv层用于对输入做二值化,接着进行二值化的卷积操作,最后进行pooling。图5 BWN训练过程[7]图6 传统卷积单元与XNOR-Net卷积单元对比[7]3.3 实验结果表5 ImageNet上二值网络与AlexNet结果对比[7]与ALexNet相比,BWN网络能够达到精度基本不变甚至略好,XNOR-Net由于对输入也做了二值化,性能稍降。四、DistillingDistilling算法是Hinton等人在论文Distilling the Knowledge in a Neural Network中提出的一种类似网络迁移的学习算法。4.1 基本思想Distilling直译过来即蒸馏,其基本思想是通过一个性能好的大网络来教小网络学习,从而使得小网络能够具备跟大网络一样的性能,但蒸馏后的小网络参数规模远远小于原始大网络,从而达到压缩网络的目的。其中,训练小模型(distilled model)的目标函数由两部分组成1) 与大模型(cumbersome model)的softmax输出的交叉熵(cross entropy),称为软目标(soft target)。其中,softmax的计算加入了超参数温度T,用以控制输出,计算公式变为温度T越大,输出的分布越缓和,概率zi/T越小,熵越大,但若T过大,会导致较大熵引起的不确定性增加,增加了不可区分性。至于为何要以soft target来计算损失,作者认为,在分类问题中,真值(groundtruth)是一个确定性的,即one-hot vector。以手写数字分类来说,对于一个数字3,它的label是3的概率是1,而是其他数值的概率是0,而对于soft target,它能表征label是3的概率,假如这个数字写的像5,还可以给出label是5的一定概率,从而提供更多信息,如数字0123456789真值0001000000软目标0000.9500.0480.0020002)与真值(groundtruth)的交叉熵(T=1)训练的损失为上述两项损失的加权和,通常第二项要小很多。4.2 实验结果作者给出了在语音识别上的实验结果对比,如下表表6 蒸馏模型与原始模型精度对比[8]上表显示,蒸馏后的模型的精确度和单字错误率和用于产生软目标的10个模型的性能相当,小模型成功地学到了大模型的识别能力。4.3 速度考量Distilling的提出原先并非针对网络加速,而最终计算的效率仍然取决于蒸馏模型的计算规模,但理论上蒸馏后的小模型相对原始大模型的计算速度在一定程度上会有提升,但速度提升的比例和性能维持的权衡是一个值得研究的方向。五、MobileNetMobileNet是由Google提出的针对移动端部署的轻量级网络架构。考虑到移动端计算资源受限以及速度要求严苛,MobileNet引入了传统网络中原先采用的group思想,即限制滤波器的卷积计算只针对特定的group中的输入,从而大大降低了卷积计算量,提升了移动端前向计算的速度。5.1 卷积分解MobileNet借鉴factorized convolution的思想,将普通卷积操作分成两部分:Depthwise Convolution 每个卷积核滤波器只针对特定的输入通道进行卷积操作,如下图所示,其中M是输入通道数,DK是卷积核尺寸:图7 Depthwise Convolution[9]Depthwise convolution的计算复杂度为 DKDKMDFDF,其中DF是卷积层输出的特征图的大小。Pointwise Convolution采用1x1大小的卷积核将depthwise convolution层的多通道输出进行结合,如下图,其中N是输出通道数:图8 Pointwise Convolution[9]Pointwise Convolution的计算复杂度为 MNDFDF上面两步合称depthwise separable convolution标准卷积操作的计算复杂度为DKDKMNDFDF因此,通过将标准卷积分解成两层卷积操作,可以计算出理论上的计算效率提升比例:对于3x3尺寸的卷积核来说,depthwise separable convolution在理论上能带来约8~9倍的效率提升。5.2 模型架构图9 普通卷积单元与MobileNet 卷积单元对比[9]MobileNet的卷积单元如上图所示,每个卷积操作后都接着一个BN操作和ReLU操作。在MobileNet中,由于3x3卷积核只应用在depthwise convolution中,因此95%的计算量都集中在pointwise convolution 中的1x1卷积中。而对于caffe等采用矩阵运算GEMM实现卷积的深度学习框架,1x1卷积无需进行im2col操作,因此可以直接利用矩阵运算加速库进行快速计算,从而提升了计算效率。5.3 实验结果表7 MobileNet与主流大模型在ImageNet上精度对比[9]上表显示,MobileNet在保证精度不变的同时,能够有效地减少计算操作次数和参数量,使得在移动端实时前向计算成为可能。六、ShuffleNetShuffleNet是Face++今年提出了一篇用于移动端前向部署的网络架构。ShuffleNet基于MobileNet的group思想,将卷积操作限制到特定的输入通道。而与之不同的是,ShuffleNet将输入的group进行打散,从而保证每个卷积核的感受野能够分散到不同group的输入中,增加了模型的学习能力。6.1 设计思想我们知道,卷积中的group操作能够大大减少卷积操作的计算次数,而这一改动带来了速度增益和性能维持在MobileNet等文章中也得到了验证。然而group操作所带来的另一个问题是:特定的滤波器仅对特定通道的输入进行作用,这就阻碍了通道之间的信息流传递,group数量越多,可以编码的信息就越丰富,但每个group的输入通道数量减少,因此可能造成单个卷积滤波器的退化,在一定程度上削弱了网络了表达能力。6.2 网络架构在此篇工作中,网络架构的设计主要有以下几个创新点:提出了一个类似于ResNet的BottleNeck单元借鉴ResNet的旁路分支思想,ShuffleNet也引入了类似的网络单元。不同的是,在stride=2的单元中,用concat操作代替了add操作,用average pooling代替了1x1stride=2的卷积操作,有效地减少了计算量和参数。单元结构如图10所示。提出将1x1卷积采用group操作会得到更好的分类性能在MobileNet中提过,1x1卷积的操作占据了约95%的计算量,所以作者将1x1也更改为group卷积,使得相比MobileNet的计算量大大减少。提出了核心的shuffle操作将不同group中的通道进行打散,从而保证不同输入通道之间的信息传递。ShuffleNet的shuffle操作如图11所示。图10 ShuffleNet网络单元[10]图11 不同group间的shuffle操作[10]6.3 实验结果表8 ShuffleNet与MobileNet在ImageNet上精度对比 [10]上表显示,相对于MobileNet,ShuffleNet的前向计算量不仅有效地得到了减少,而且分类错误率也有明显提升,验证了网络的可行性。6.4 速度考量作者在ARM平台上对网络效率进行了验证,鉴于内存读取和线程调度等因素,作者发现理论上4x的速度提升对应实际部署中约2.6x。作者给出了与原始AlexNet的速度对比,如下表。表9 ShuffleNet与AlexNet在ARM平台上速度对比 [10]结束语近几年来,除了学术界涌现的诸多CNN模型加速工作,工业界各大公司也推出了自己的移动端前向计算框架,如Google的Tensorflow、Facebook的caffe2以及苹果今年刚推出的CoreML。相信结合不断迭代优化的网络架构和不断发展的硬件计算加速技术,未来深度学习在移动端的部署将不会是一个难题。参考文献[1] ImageNet Classification with Deep Convolutional Neural Networks[2] Very Deep Convolutional Networks for Large-Scale Image Recognition[3] Going Deeper with Convolutions[4] Rethinking the Inception Architecture for Computer Vision[5] SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and < 0.5MB model size[6] Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding[7] Distilling the Knowledge in a Neural Network[8] XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks[9] MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications[10] ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices[11] Network in Network[12] EIE: Efficient Inference Engine on Compressed Deep Neural Network此文已由作者授权腾讯云+社区在各渠道发布获取更多新鲜技术干货,可以关注我们腾讯云技术社区-云加社区官方号 ...

January 2, 2019 · 2 min · jiezi

Facebook开源语音识别系统wav2letter++简介

语音识别系统是深度学习生态中发展最成熟的领域之一。当前这一代的语音识别模型基本都是基于递归神经网络(Recurrent Neural Network)对声学和语言模型进行建模,以及用于知识构建的计算密集的特征提取流水线。虽然基于RNN的技术已经在语音识别任务中得到验证,但训练RNN网络所需要的大量数据和计算能力已经超出了大多数机构的能力范围。最近,Facebook的AI研究中心(FAIR)发表的一个研究论文,提出了一种新的单纯基于卷积神经网络(Convolutional Neural Network)的语音识别技术,而且提供了开源的实现wav2letter++,一个完全基于卷积模型的高性能的语音识别工具箱。在深度学习领域,在语音识别系统中使用CNN并不新鲜,但是大部分应用都局限于特定的任务,而且通常与RNN结合起来构成完整的系统。但是当前CNN领域的研究表明只使用卷积神经网络也有潜力在语音识别的所有领域达到最高水平,例如机器翻译、存在长程依赖的语言模型的语音合成等。CNN模型与其他技术的最大优势在于它不需要额外而且昂贵的特征提取计算就可以天然地对诸如MFCC之类的标准特征计算进行建模。因此长久以来,深度学习社区一直都期待着在语音识别工作流中完全使用CNN,因为这要比目前的基于RNN的模型更高效也更富有竞争力。全卷积语音识别架构经过很多次实验,FAIR团队决定依赖于一个整合多个不同CNN层的架构来实现端对端的语音识别流水线,从音频波形处理到语言转录。该架构基于下图所示的散射模型:模型的第一层CNN用来处理原始音频并提取一些关键特征;接下来的卷积声学模型是一个具有门限单元的CNN,可通过训练从音频流中预测字母;卷积语言模型层则根据来自声学模型的输入生成候选转录文本;最后环节的集束搜索(Beam-Search)编码器则完成最终的转录单词序列。FAIR团队将其全卷积语音识别模型与最先进的模型进行了对比,它可以用少的多的训练数据达到基本一致的性能,测试结果令人满意因此FAIR团队决定开源该算法的初始实现。Wav2letter++虽然深度学习技术近期的进步促进了自动语音识别(Automatic Speech Recognition)框架和工具箱的增加。然而,全卷机语音识别模型的进步,激励了FAIR团队创建wav2letter++,一个完全使用C++实现的深度语音识别工具箱。wav2letter++的核心设计基于以下三个关键原则:实现在包含成千上万小时语音数据集上的高效模型训练简单可扩展模型,可以接入新的网络架构、损失函数以及其他语音识别系统中的核心操作平滑语音识别模型从研究到生产部署的过渡基于以上原则,wav2letter++实现了如下图所示的非常直白的架构:为了更好地理解wav2letter++的架构,有以下几点值得着重指出:ArrayFire张量库:wav2letter++使用ArrayFire作为张量操作的基础库。ArrayFire支持硬件无关的高性能并行建模,可以运行在多种后端上,例如CUDA GPU后端或CPU后端数据预备和特征提取:wav2letter++支持多种音频格式的特征提取。框架可以在每次网络评估之前即时计算特征,并且通过异步并行计算来实现模型训练的效率最大化模型:wav2letter++包含一组丰富的端对端序列模型,也包含众多网络架构以及激活函数。可扩展的训练:wav2letter++支持三种主要的训练模式:train :从零开始训练continue :从检查点状态继续训练(continuing with a checkpoint state),fork :可用于迁移学习。训练流水线使用并行数据、同步随机梯度下降以及基于NVIDIA的集群通信库,可以无缝伸缩。解码:wav2letter++解码器是基于前面提到的全卷积架构中的集束搜索解码器,它负责输出最终的音频转录文本Wav2letter++实战FAIR团队将wav2letter++与其他语音识别进行了对比测试,例如ESPNet、Kaldi和OpenSeq2Seq。实验基于著名的华尔街日报CSR数据集。初始结果表明wav2letter++在训练周期中的任一方面都完胜其他方案。完全基于CNN的语音识别系统当然是一个有意思的实现途径,它可以优化对计算能力和训练数据的需求。Facebook的wav2letter++实现已经被视为当前最快的语音识别框架之一。我们将在不久的未来看到该领域越来越多的进步。汇智网翻译整理,转载请标明出处:Introducing Wav2letter++

December 27, 2018 · 1 min · jiezi

机器学习与数据科学决策树指南

摘要: 一份关于决策树的基本介绍,用实例说明详细讲解。还在为如何抉择而感到纠结吗?快采用决策树(Decision Tree)算法帮你做出决定吧。决策树是一类非常强大的机器学习模型,具有高度可解释的同时,在许多任务中也有很高的精度。决策树在机器学习模型领域的特殊之处在于其信息表示的很清楚,而不像一些机器学习方法是个黑匣子,这是因为决策树通过训练学到的“知识”直接形成层次结构,该结构以这样的方式保存和显示学到的知识,即使是非专业人士也可以容易地弄明白。现实生活中的决策树在现实生活中,我们常常用过类似于决策树的方式来决定自己的生活。例如,决定周末安排什么样的活动。采取怎样的活动可能取决于一些因素,比如是否愿意和朋友一起出去或独自度过周末、周末的天气如何等。假设就这两个因素影响你做出决定的话,如果天气晴朗,并且你的朋友可以一起参与,那么你可能想踢足球。如果是下雨天,可能会一起去看电影。如果朋友有事无法参加,那么无论天气如何,可能会去看会书、玩会电子游戏。这就是现实中的一个明显的决策树例子,上述已经构建了一个树来模拟一组顺序的、层次化的决策,最终得到一个结果。这里,为了保持树的小巧,还选择了相当“高级”的决策。例如,如果为天气设置了许多可能的选项,例如晴天(25度)、下雨(25度)、晴天(26度)、下雨(26度)、晴天(27度)…… 等等,这样会使得树尺寸会很大,这种精确的温度对于最后做出的决策没有太相关的关系,因为只是想知道是外界是否下雨,根据下雨的情况决定是否外出,而温度的高低对其影响很小。当然,极寒极热天气还是在家比较舒服。 机器学习中的决策树的概念和上面的思想是相同的,需要构建一个具有一组分层决策的树,最终给出决策结果,即分类或回归预测。尽可能使得决策树尺寸较小,同时要实现高分类/回归准确性。机器学习中的决策树决策树模型的构建一般分为两个步骤:归纳(induction)和修剪(pruning)。归纳是实际构建树的步骤,即根据我们的数据设置所有的分层决策边界。但由于训练决策树的性质,树模型可能容易出现严重的过拟合现象。这个时候就需要采用修剪处理,修剪就是从决策树中删除不必要的分支结构的过程,有效地降低了对抗过拟合的复杂性,并使其更容易解释。归纳|Induction从高层次来看,决策树归纳需要经过4个主要步骤:训练数据集应具有一些特征变量、分类或回归输出;确定数据集中的“最佳特征”以分割数据;将数据拆分为包含此最佳特征的可能值的子集,这种分裂基本上定义了树上的节点,即每个节点是基于数据中的某个特征的分裂点;使用从步骤3创建的数据子集递归地生成新的树节点,保持分裂直到达到一个优化点,在该点已经通过某种度量优化了最大精度,同时最小化了分裂/节点的数量。第1步很简单,只需好好分析数据集。对于步骤2,通常使用贪婪算法来选择要使用的特征和特定分割,以最小化代价函数。构建决策树时执行的拆分相当于划分特征空间。我们将迭代地尝试不同的分割点,最后选择成本最低的分割点。也可以只在数据集中的值范围内进行拆分,这将使得我们免于浪费计算来测试那些表现差的分裂点。对于回归树,可以使用简单的平方误差作为模型的代价函数:其中,Y是期望输出,Y-hat是预测值,对数据集中的所有样本求和以获得总误差。对于分类,使用的是基尼指数函数(Gini Index Function):其中pk是特定预测节点中第k类的训练实例样本的比例。理想情况下, 节点的错误值应为零,这意味着每个拆分输出的类正是我们想要的,一旦到达那个特定的决策节点,无论处于决策边界的这一边还是另一边,其输出也确定好了。在数据集中具有单个分类的概念被称为信息增益。以下是举例:如果选择了某种划分,其中每个输出根据输入数据混合类别,这种情况实际上根本没有获得任何信息; 另一方面,如果采取的分割对于每个输出的类的正确率都很高,那么已经获得 了在具体特征变量上以特定方式分割的信息。之后是对树模型进行分裂,直到树有数千个分支,但这不是一个好主意!这样得到的决策树将是巨大的、缓慢的,并且会过拟合训练数据集。因此,需要设置一些预定义的停止标准来停止树的构造。最常见的停止方法是对分配给每个叶节点的训练样本的数量使用最小数量。如果计数小于某个最小值,则不接受拆分,并将该节点作为最终叶节点。如果所有的叶子节点都成为最终节点,则训练停止。较小的最小数量将提供更精细的分割和信息,但也容易过拟合训练数据。因此,最小数量的取值通常基于数据集设置,具体取决于每个类中预计有多少个示例样本。修剪|Pruning由于训练决策树的性质,可能容易会出现严重的过拟合现象。为每个节点设置最小实例数的正确值可能具有挑战性。大多数情况下,可能只是希望做出合适的决定,而无需最优的决定。因此,无需使得最小值非常小获得非常复杂的树,且有很多分裂是多余的,并没有提高模型的准确性。树修剪是一种利用修剪树中不必要的分裂的技术。从上层开始,修剪将树的一部分从严格的决策边界压缩为更平滑、更通用的树,从而有效地降低树的复杂性。决策树的复杂性定义为树中的分裂数。一种简单而高效的修剪方法是遍历树中的每个节点,并评估将其移除后其代价函数上的效果。如果移除后,代价函数变化不大,那就修剪掉该节点。实例实践使用Scikit Lear中内置的函数来实现分类和回归的决策树是非常容易的。首先加载数据集并初始化决策树以进行分类。from sklearn.datasets import load_irisfrom sklearn import tree# Load in our datasetiris_data = load_iris()# Initialize our decision tree objectclassification_tree = tree.DecisionTreeClassifier()# Train our decision tree (tree induction + pruning)classification_tree = classification_tree.fit(iris_data.data, iris_data.target)Scikit.还允许使用graphviz库可视化构建的树,它附带了一些选项,这些选项将有助于可视化决策节点,并将模型学到的内容进行分割,下面根据特征名称对节点进行着色,并显示每个节点的类和特征信息:import graphviz dot_data = tree.export_graphviz(classification_tree, out_file=None, feature_names=iris.feature_names, class_names=iris.target_names, filled=True, rounded=True, special_characters=True) graph = graphviz.Source(dot_data) graph.render(“iris”) 也可以在Scikit Learn中为决策树模型设置几个参数。以下是一些有趣的尝试以获得更好的结果:max_depth:树的最大深度,类似于深度神经网络中的最大层数。较浅会使得模型更快但不准确;更深的模型可能会使得准确性更高,但过拟合的风险也增大,且运行很慢;min_samples_split: 拆分节点所需的最小样本数, 将其设置为合适的值将有助于减轻过拟合;max_features:查找最佳拆分时要考虑的特征数,更高可能意味着更好的结果,但训练也需要更长的时间;min_impurity_split:树生长早期停止的阈值,如果节点的杂质高于阈值,则该节点将分裂,可用于权衡对抗过拟合(高值、小树)与高精度(低值、大树);presort:是否预先分配数据以加快拟合中最佳分割的发现。如果事先对每个特征的数据进行排序,训练算法将更容易找到合适的分裂值;实际中应用决策树的技巧以下是决策树的优缺点总结,可以帮助读者确定它是否适合各自的问题,以及有关如何有效应用它们的一些提示:优点| Pros易于理解和解释:在每个节点都能够确切地看到模型做出了什么决定。在实践中,能够完全理解准确度和误差来自何处,模型可以很好地处理哪种类型的数据,以及输出如何受到特征值的影响。Scikit learn的可视化工具是可视化和理解决策树的绝佳选择;需要准备很少的数据:许多机器学习模型可能需要大量的数据预处理,例如归一化,并且可能需要复杂的正则化方案。另一方面,在调整了一些参数后,决策树可以很好地做到开箱即用;使用树进行推理的计算成本与训练树的数据集呈对数关系,这是一个巨大的优势,意味着输入更多的数据不一定会对推理速度产生巨大的影响;缺点|Cons由于训练的性质,过拟合在决策树中很常见。通常建议执行某种类型的降维,例如PCA, 以便树不必学习如此多的特征上的拆分;出于与过拟合情况类似的原因,决策树也容易变得偏向于在数据集中占多数的类别,对不平衡数据进行某种类平衡(例如类权重、采样或专门的损失函数)操作是一个不错的主意。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 26, 2018 · 1 min · jiezi

YOLO目标检测模型原理介绍

YOLO-v1介绍YOLO是一个端到端的目标检测算法,不需要预先提取region proposal(RCNN目标检测系列),通过一个网络就可以输出:类别,置信度,坐标位置,检测速度很快,不过,定位精度相对低些,特别是密集型小目标。YOLO将图像resize到448x448作为输入,输出7x7x30,即:将图片划分为7x7,每个单元格独立检测。这里需要注意,不是那种滑动窗口将每个单元格都输入到网络中进行预测,这里的划分只是物体中心点位置的划分之用(划分越多越准确),物体的中心落在哪个单元格,就由那个单元格负责预测。说完7x7我们再说下另一个维度30,30=(2*5=20),其中“2:每个单元格预测数量(box数量)”,“5:(x,y,w,h,score)”,“20:模型可以预测20个种类”。YOLO-v1训练模型首先会将ImageNet作为训练集预训练模型,最终达到88%精度,然后使用迁移学习将预训练的模型应用到当前标注的训练集进行训练。模型输出5维信息(x,y,w,h,score),使用Leaky Relu作为激活函数,全连接层后添加Dropout层防止过拟合。在得到输出值之后,我们需要计算每个box与ground true的Iou值,然后通过非极大值抑制筛选box。YOLO-v1损失函数损失函数包含三部分分别是:坐标损失,置信度损失(7x7x2),类别损失(7x7x20)。坐标损失:我们使用SSE损失函数(就是MSE损失函数的累加版本),如图所示我们在“w,h”中加了根号,加根号的原因是,“w,h”的损失在大框和小框之间“权重”应该不同。因为,对应图像中较大的物体而言,box有些偏移一般并不会影响预测结果。但是对应小物体而言,同样的偏移可能会脱离预测目标。置信度损失:如图所示,损失函数分为两部分:有物体,没有物体,其中没有物体损失部分还增加了权重系数。添加权重系数的原因是,对于一幅图像,一般而言大部分内容是不包含待检测物体的,这样会导致没有物体的计算部分贡献会大于有物体的计算部分,这会导致网络倾向于预测单元格不含有物体。因此,我们要减少没有物体计算部分的贡献权重,比如取值为:0.5。类别损失:当有物体的中心点落在单元格中,此单元格就负责预测该物体。YOLO-v2改进使用批标准化:随着神经网络的训练,网络层的输入分布会发生变动,逐渐向激活函数取值两端靠拢,如:sigmoid激活函数,此时会进入饱和状态,梯度更新缓慢,对输入变动不敏感,甚至梯度消失导致模型难以训练。BN,在网络层输入激活函数输入值之前加入,可以将分布拉到均值为0,标准差为1的正态分布,从而使激活函数处于对输入值敏感的区域,从而加快模型训练。此外,BN还能起到类似dropout的正则化作用,由于我们会有‘强拉’操作,所以对初始化要求没有那么高,可以使用较大的学习率。High Resolution Classifier:在介绍YOLO-v1的时候我们说到,模型需要先在ImageNet上预训练模型,因此,此时图像输入为224x224,使用迁移学习训练后我们的图像输入是448x448,因此模型需要适应图像分辨率的改变。在YOLO-v2中,我们在预训练模型中先224x224训练160个epoch,然后将输入调整到448x448,再跑10个epoch,也就是在ImageNet数据集中两种分辨率跑两次。YOLO大神作者实现表明,这样操作可以提高4%的map。Convolutional With Anchor Boxes: 1,加入anchor boxes,提高box数量。 2,删除全连接层和最后一个池化层,保留更高分辨率特征。 3,用416x416代替448x448输入大小,使特征图有奇数大小的高和宽。Dimension Clusters:使用k-means的方式对训练集的bounding boxes做聚类,但是该方法存在不同尺寸的box误差权重不同,我们希望误差与尺寸没有关系,因此通过IOU定义如下函数:Multi-Scale Training:训练阶段,采用32的倍数作为图像尺寸动态输入,如【320,352。。。608】。这种网络训练方式使得相同网络可以对不同分辨率的图像做detection。使用Darknet-19作为后端网络:YOLO-v3YOLO-v3结构图以来自木盏,表示感谢,也欢迎关注他的博客。DBL:指Darknetconv2d_BN_Leaky。resn:指:n代表数字,有res1,res2, … ,res8等等,表示这个res_block里含有多少个res_unit,使用残差结构可以让网络更深。concat:张量拼接。将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变。后端网络使用darknet-53:我们发现,在YOLO-v3网络中没有池化层和全连接层,那么张量尺寸的变化是通过改变卷积核步长来实现。同YOLO-v2一样,输出尺寸为输入尺寸的1/32,即:一般要求输入图像尺寸是32的倍数。类别预测由softmax改为logistic(使用sigmoid):用于处理预测物体之间存在包含关系问题,解决多标签对象支持。比如woman和person,softmax输出:person,logistic输出两者。使用多尺度特征预测物体:上图是YOLO-v3在COCO数据集上使用聚类得到的9种先验框,一个代表宽度一个代表高度。在不同的感受野中使用不同的先验框。如果先验框不是最佳的,即使超过预设定的阈值,也不会进行预测。logistic回归用来从9个先验框中找到最佳的那个。补充:Iou计算总结YOLO好不好,我们就以一张图作为总结吧:祝大家2018年圣诞节快乐!

December 25, 2018 · 1 min · jiezi

(Python)零起步数学+神经网络入门

摘要: 手把手教你用(Python)零起步数学+神经网络入门!在这篇文章中,我们将在Python中从头开始了解用于构建具有各种层神经网络(完全连接,卷积等)的小型库中的机器学习和代码。最终,我们将能够写出如下内容:假设你对神经网络已经有一定的了解,这篇文章的目的不是解释为什么构建这些模型,而是要说明如何正确实现。逐层我们这里需要牢记整个框架:1. 将数据输入神经网络2. 在得出输出之前,数据从一层流向下一层3. 一旦得到输出,就可以计算出一个标量误差。4. 最后,可以通过相对于参数本身减去误差的导数来调整给定参数(权重或偏差)。5. 遍历整个过程。最重要的一步是第四步。 我们希望能够拥有任意数量的层,以及任何类型的层。 但是如果修改/添加/删除网络中的一个层,网络的输出将会改变,误差也将改变,误差相对于参数的导数也将改变。无论网络架构如何、激活函数如何、损失如何,都必须要能够计算导数。为了实现这一点,我们必须分别实现每一层。每个层应该实现什么我们可能构建的每一层(完全连接,卷积,最大化,丢失等)至少有两个共同点:输入和输出数据。现在重要的一部分假设给出一个层相对于其输出(∂E/∂Y)误差的导数,那么它必须能够提供相对于其输入(∂E/∂X)误差的导数。è®°ä½ï¼Eæ¯æ éï¼ä¸ä¸ªæ°å­ï¼ï¼XåYæ¯ç©éµã 我们可以使用链规则轻松计算∂E/∂X的元素:为什么是∂E/∂X?对于每一层,我们需要相对于其输入的误差导数,因为它将是相对于前一层输出的误差导数。这非常重要,这是理解反向传播的关键!在这之后,我们将能够立即从头开始编写深度卷积神经网络!花样图解基本上,对于前向传播,我们将输入数据提供给第一层,然后每层的输出成为下一层的输入,直到到达网络的末端。对于反向传播,我们只是简单使用链规则来获得需要的导数。这就是为什么每一层必须提供其输出相对于其输入的导数。这可能看起来很抽象,但是当我们将其应用于特定类型的层时,它将变得非常清楚。现在是编写第一个python类的好时机。抽象基类:Layer所有其它层将继承的抽象类Layer会处理简单属性,这些属性是输入,输出以及前向和反向方法。from abc import abstractmethod# Base classclass Layer: def init(self): self.input = None; self.output = None; self.input_shape = None; self.output_shape = None; # computes the output Y of a layer for a given input X @abstractmethod def forward_propagation(self, input): raise NotImplementedError # computes dE/dX for a given dE/dY (and update parameters if any) @abstractmethod def backward_propagation(self, output_error, learning_rate): raise NotImplementedError正如你所看到的,在back_propagation函数中,有一个我没有提到的参数,它是learning_rate。 此参数应该类似于更新策略或者在Keras中调用它的优化器,为了简单起见,我们只是通过学习率并使用梯度下降更新我们的参数。全连接层现在先定义并实现第一种类型的网络层:全连接层或FC层。FC层是最基本的网络层,因为每个输入神经元都连接到每个输出神经元。前向传播每个输出神经元的值由下式计算:使用矩阵,可以使用点积来计算每一个输出神经元的值:当完成前向传播之后,现在开始做反向传播。反向传播正如我们所说,假设我们有一个矩阵,其中包含与该层输出相关的误差导数(∂E/∂Y)。 我们需要:1.关于参数的误差导数(∂E/∂W,∂E/∂B)2.关于输入的误差导数(∂E/∂X)首先计算∂E/∂W,该矩阵应与W本身的大小相同:对于ixj,其中i是输入神经元的数量,j是输出神经元的数量。每个权重都需要一个梯度:使用前面提到的链规则,可以写出:那么:这就是更新权重的第一个公式!现在开始计算∂E/∂B:同样,∂E/∂B需要与B本身具有相同的大小,每个偏差一个梯度。 我们可以再次使用链规则:得出结论:现在已经得到∂E/∂W和∂E/∂B,我们留下∂E/∂X这是非常重要的,因为它将“作用”为之前层的∂E/∂Y。再次使用链规则:最后,我们可以写出整个矩阵:æä»¬å·²ç»å¾å°FC屿éçä¸ä¸ªå ¬å¼ï¼ 编码全连接层现在我们可以用Python编写实现:from layer import Layerimport numpy as np# inherit from base class Layerclass FCLayer(Layer): # input_shape = (1,i) i the number of input neurons # output_shape = (1,j) j the number of output neurons def init(self, input_shape, output_shape): self.input_shape = input_shape; self.output_shape = output_shape; self.weights = np.random.rand(input_shape[1], output_shape[1]) - 0.5; self.bias = np.random.rand(1, output_shape[1]) - 0.5; # returns output for a given input def forward_propagation(self, input): self.input = input; self.output = np.dot(self.input, self.weights) + self.bias; return self.output; # computes dE/dW, dE/dB for a given output_error=dE/dY. Returns input_error=dE/dX. def backward_propagation(self, output_error, learning_rate): input_error = np.dot(output_error, self.weights.T); dWeights = np.dot(self.input.T, output_error); # dBias = output_error # update parameters self.weights -= learning_rate * dWeights; self.bias -= learning_rate * output_error; return input_error;激活层到目前为止所做的计算都完全是线性的。用这种模型学习是没有希望的,需要通过将非线性函数应用于某些层的输出来为模型添加非线性。现在我们需要为这种新类型的层(激活层)重做整个过程!不用担心,因为此时没有可学习的参数,过程会快点,只需要计算∂E/∂X。我们将f和f’分别称为激活函数及其导数。前向传播正如将看到的,它非常简单。对于给定的输入X,输出是关于每个X元素的激活函数,这意味着输入和输出具有相同的大小。反向传播给出∂E/∂Y,需要计算∂E/∂X注意,这里我们使用两个矩阵之间的每个元素乘法(而在上面的公式中,它是一个点积)编码实现激活层激活层的代码非常简单:from layer import Layer# inherit from base class Layerclass ActivationLayer(Layer): # input_shape = (1,i) i the number of input neurons def init(self, input_shape, activation, activation_prime): self.input_shape = input_shape; self.output_shape = input_shape; self.activation = activation; self.activation_prime = activation_prime; # returns the activated input def forward_propagation(self, input): self.input = input; self.output = self.activation(self.input); return self.output; # Returns input_error=dE/dX for a given output_error=dE/dY. # learning_rate is not used because there is no “learnable” parameters. def backward_propagation(self, output_error, learning_rate): return self.activation_prime(self.input) * output_error;可以在单独的文件中编写一些激活函数以及它们的导数,稍后将使用它们构建ActivationLayer:import numpy as np# activation function and its derivativedef tanh(x): return np.tanh(x);def tanh_prime(x): return 1-np.tanh(x)*2;损失函数到目前为止,对于给定的层,我们假设给出了∂E/∂Y(由下一层给出)。但是最后一层怎么得到∂E/∂Y?我们通过简单地手动给出最后一层的∂E/∂Y,它取决于我们如何定义误差。网络的误差由自己定义,该误差衡量网络对给定输入数据的好坏程度。有许多方法可以定义误差,其中一种最常见的叫做MSE - Mean Squared Error:其中y 和y分别表示期望的输出和实际输出。你可以将损失视为最后一层,它将所有输出神经元吸收并将它们压成一个神经元。与其他每一层一样,需要定义∂E/∂Y。除了现在,我们终于得到E!以下是两个python函数,可以将它们放在一个单独的文件中,将在构建网络时使用。import numpy as np# loss function and its derivativedef mse(y_true, y_pred): return np.mean(np.power(y_true-y_pred, 2));def mse_prime(y_true, y_pred): return 2(y_pred-y_true)/y_true.size;网络类到现在几乎完成了!我们将构建一个Network类来创建神经网络,非常容易,类似于第一张图片!我注释了代码的每一部分,如果你掌握了前面的步骤,那么理解它应该不会太复杂。from layer import Layerclass Network: def init(self): self.layers = []; self.loss = None; self.loss_prime = None; # add layer to network def add(self, layer): self.layers.append(layer); # set loss to use def use(self, loss, loss_prime): self.loss = loss; self.loss_prime = loss_prime; # predict output for given input def predict(self, input): # sample dimension first samples = len(input); result = []; # run network over all samples for i in range(samples): # forward propagation output = input[i]; for layer in self.layers: # output of layer l is input of layer l+1 output = layer.forward_propagation(output); result.append(output); return result; # train the network def fit(self, x_train, y_train, epochs, learning_rate): # sample dimension first samples = len(x_train); # training loop for i in range(epochs): err = 0; for j in range(samples): # forward propagation output = x_train[j]; for layer in self.layers: output = layer.forward_propagation(output); # compute loss (for display purpose only) err += self.loss(y_train[j], output); # backward propagation error = self.loss_prime(y_train[j], output); # loop from end of network to beginning for layer in reversed(self.layers): # backpropagate dE error = layer.backward_propagation(error, learning_rate); # calculate average error on all samples err /= samples; print(’epoch %d/%d error=%f’ % (i+1,epochs,err));构建一个神经网络最后!我们可以使用我们的类来创建一个包含任意数量层的神经网络!为了简单起见,我将向你展示如何构建……一个XOR。from network import Networkfrom fc_layer import FCLayerfrom activation_layer import ActivationLayerfrom losses import from activations import import numpy as np# training datax_train = np.array([[[0,0]], [[0,1]], [[1,0]], [[1,1]]]);y_train = np.array([[[0]], [[1]], [[1]], [[0]]]);# networknet = Network();net.add(FCLayer((1,2), (1,3)));net.add(ActivationLayer((1,3), tanh, tanh_prime));net.add(FCLayer((1,3), (1,1)));net.add(ActivationLayer((1,1), tanh, tanh_prime));# trainnet.use(mse, mse_prime);net.fit(x_train, y_train, epochs=1000, learning_rate=0.1);# testout = net.predict(x_train);print(out);同样,我认为不需要强调很多事情,只需要仔细训练数据,应该能够先获得样本维度。例如,对于xor问题,样式应为(4,1,2)。结果$ python xor.py epoch 1/1000 error=0.322980 epoch 2/1000 error=0.311174 epoch 3/1000 error=0.307195 … epoch 998/1000 error=0.000243 epoch 999/1000 error=0.000242 epoch 1000/1000 error=0.000242 [array([[ 0.00077435]]), array([[ 0.97760742]]), array([[ 0.97847793]]), array([[-0.00131305]])]卷积层这篇文章开始很长,所以我不会描述实现卷积层的所有步骤。但是,这是我做的一个实现:from layer import Layerfrom scipy import signalimport numpy as np# inherit from base class Layer# This convolutional layer is always with stride 1class ConvLayer(Layer): # input_shape = (i,j,d) # kernel_shape = (m,n) # layer_depth = output depth def init(self, input_shape, kernel_shape, layer_depth): self.input_shape = input_shape; self.input_depth = input_shape[2]; self.kernel_shape = kernel_shape; self.layer_depth = layer_depth; self.output_shape = (input_shape[0]-kernel_shape[0]+1, input_shape[1]-kernel_shape[1]+1, layer_depth); self.weights = np.random.rand(kernel_shape[0], kernel_shape[1], self.input_depth, layer_depth) - 0.5; self.bias = np.random.rand(layer_depth) - 0.5; # returns output for a given input def forward_propagation(self, input): self.input = input; self.output = np.zeros(self.output_shape); for k in range(self.layer_depth): for d in range(self.input_depth): self.output[:,:,k] += signal.correlate2d(self.input[:,:,d], self.weights[:,:,d,k], ‘valid’) + self.bias[k]; return self.output; # computes dE/dW, dE/dB for a given output_error=dE/dY. Returns input_error=dE/dX. def backward_propagation(self, output_error, learning_rate): in_error = np.zeros(self.input_shape); dWeights = np.zeros((self.kernel_shape[0], self.kernel_shape[1], self.input_depth, self.layer_depth)); dBias = np.zeros(self.layer_depth); for k in range(self.layer_depth): for d in range(self.input_depth): in_error[:,:,d] += signal.convolve2d(output_error[:,:,k], self.weights[:,:,d,k], ‘full’); dWeights[:,:,d,k] = signal.correlate2d(self.input[:,:,d], output_error[:,:,k], ‘valid’); dBias[k] = self.layer_depth * np.sum(output_error[:,:,k]); self.weights -= learning_ratedWeights; self.bias -= learning_ratedBias; return in_error;它背后的数学实际上并不复杂!这是一篇很好的文章,你可以找到∂E/∂W,∂E/∂B和∂E/∂X的解释和计算。如果你想验证你的理解是否正确,请尝试自己实现一些网络层,如MaxPooling,Flatten或DropoutGitHub库你可以在GitHub库中找到用于该文章的完整代码。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

December 21, 2018 · 4 min · jiezi

GAN是一种特殊的损失函数?

摘要: 从本质上来说,生成对抗网络(GAN)是一种特殊的损失函数,我们来深入探索下这句话的含义。数据科学家Jeremy Howard在fast.ai的《生成对抗网络(GAN)》课程中曾经讲过这样一句话:“从本质上来说,生成对抗网络(GAN)是一种特殊的损失函数。”你是否能够理解这句话的意思?读完本文,你会更好的理解这句话的含义。神经网络的函数逼近理论在数学中,我们可以将函数看做一个“机器”或“黑匣子”,我们为这个“机器”或“黑匣子”提供了一个或多个数字作为输入,则会输出一个或多个数字,如下图所示:一般来说,我们可以用一个数学表达式来表示我们想要的函数。但是,在一些特殊的情况下,我们就没办法将函数写成一堆加法和乘法的明确组合,比如:我们希望拥有这样一个函数,即能够判断输入图像的类别是猫还是狗。如果不能用明确的用数学表达式来表达这个函数,那么,我们可以用某种方法近似表示吗?这个近似方法就是神经网络。通用近似定理表明,如果一个前馈神经网络具有线性输出层和至少一层隐藏层,只要给予网络足够数量的神经元,便可以表示任何一个函数。作为损失函数的神经网络现在,我们希望设计一个猫和狗的分类器。但我们没办法设计一个特别明确的分类函数,所以我们另辟蹊径,构建一个神经网络,然后一步一步逐渐实现这一目标。为了更好的逼近,神经网络需要知道距离目标到底还有多远。我们使用损失函数表示误差。现在,存在很多种类型的损失函数,使用哪种损失函数则取决于手头上的任务。并且,他们有一个共同的属性,即这些损失函数必须能够用精确的数学表达式来表示,如:1.L1损失函数(绝对误差):用于回归任务。2.L2损失函数(均方误差):和L1损失函数类似,但对异常值更加敏感。3.交叉熵损失函数:通常用于分类任务。4.Dice系数损失函数:用于分割任务。5.相对熵:又称KL散度,用于测量两个分布之间的差异。在构建一个性能良好的神经网络时,损失函数非常有用。正确深入的理解损失函数,并适时使用损失函数实现目标,是开发人员必备的技能之一。如何设计一个好的损失函数,也是一个异常活跃的研究领域。比如:《密度对象检测的焦点损失函数(Focal Loss)》中就设计了一种新的损失函数,称为焦点损失函数,可以处理人脸检测模型中的差异。可明确表示损失函数的一些限制上文提到的损失函数适用于分类、回归、分割等任务,但是如果模型的输出具有多模态分布,这些损失函数就派不上用场了。比如,对黑白图像进行着色处理。如上图所示:1.输入图像是个黑白鸟类图像,真实图像的颜色是蓝色。2.使用L2损失函数计算模型输出的彩色图像和蓝色真实图像之间的差异。3.接下来,我们有一张非常类似的黑白鸟类图像,其真实图像的颜色是红色。4.L2损失函数现在尝试着将模型输出的颜色和红色的差异最小化。5.根据L2损失函数的反馈,模型学习到:对于类似的鸟类,其输出可以接近红色,也可以接近蓝色,那么,到底应该怎么做呢?6.最后,模型输出鸟类的颜色为黄色,这就是处于红色和蓝色中间的颜色,并且是差异最小化的安全选择,即便是模型以前从未见过黄色的鸟,它也会这样做。7.但是,自然界中没有黄色的鸟类,所以模型的输出并不真实。在很多情况下,这种平均效果并不理想。举个例子来说,如果需要模型预测视频中下一个帧图像,下一个帧有很多种可能,你肯定希望模型输出其中一种可能,然如果使用L1或L2损失函数,模型会将所有可能性平均化,输出一个特别模型的平均图像,这就和我们的目标相悖。生成对抗网络——一种新的损失函数如果我们没办法用明确的数学表达式来表示这个损失函数,那么,我们就可以使用神经网络进行逼近,比如,函数接收一组数字,并输出狗的真实图像。神经网络需要使用损失函数来反馈当前结果如何,但是并没有哪个损失函数可以很好的实现这一目标。会不会有这样一种方法?能够直接逼近神经网络的损失函数,但是我们没必要知道其数学表达式是什么,这就像一个“机器”或“黑匣子”,就跟神经网络一样。也就是说,如果使用一个神经网络模型替换这个损失函数,这样可以吗?对,这就是生成对抗网络(GAN)。我们来看上面两个图,就可以更好的理解损失函数。在上图中,白色框表示输入,粉色和绿色框表示我们要构建的神经网络,蓝色表示损失函数。在vanilla GAN中,只有一个损失函数,即判别器D,这本身就是一个特殊的神经网络。而在Alpha-GAN中,有3个损失函数,即输入数据的判别器D,编码潜在变量的潜在判别器C和传统的像素级L1损失函数。其中,D和C不是明确的损失函数,而是一种逼近,即一个神经网络。梯度如果使用损失函数训练生成网络(和Alpha-GAN网络中的编码器),那么,应该使用哪种损失函数来训练判别器呢?判别器的任务是区分实际数据分布和生成数据分布,使用监督的方式训练判别器比较容易,如二元交叉熵。由于判别器是生成器的损失韩式,这就意味着,判别器的二进制交叉熵损失函数产生的梯度也可以用来更新生成器。结论考虑到神经网络可以代替传统的损失函数,生成对抗网络就实现了这一目标。两个网络之间的相互作用,可以让神经网络执行一些以前无法实现的任务,比如生成逼真的图像等任务。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 21, 2018 · 1 min · jiezi

用PyTorch创建一个图像分类器?So easy!(Part 2)

摘要: 学习完了如何加载预训练神经网络,下面就让我们来看看如何训练分类器吧!在第一部分中,我们知道了为什么以及如何加载预先训练好的神经网络,我们可以用自己的分类器代替已有神经网络的分类器。那么,在这篇文章中,我们将学习如何训练分类器。训练分类器首先,我们需要为分类器提供待分类的图像。本文使用ImageFolder加载图像,预训练神经网络的输入有特定的格式,因此,我们需要用一些变换来调整图像的大小,即在将图像输入到神经网络之前,对其进行裁剪和标准化处理。具体来说,将图像大小调整为224*224,并对图像进行标准化处理,即均值为 [0.485,0.456,0.406],标准差为[0.229,0.224,0.225],颜色管道的均值设为0,标准差缩放为1。然后,使用DataLoader批量传递图像,由于有三个数据集:训练数据集、验证数据集和测试数据集,因此需要为每个数据集创建一个加载器。一切准备就绪后,就可以训练分类器了。在这里,最重要的挑战就是——正确率(accuracy)。让模型识别一个已经知道的图像,这不算啥事,但是我们现在的要求是:能够概括、确定以前从未见过的图像中花的类型。在实现这一目标过程中,我们一定要避免过拟合,即“分析的结果与特定数据集的联系过于紧密或完全对应,因此可能无法对其他数据集进行可靠的预测或分析”。隐藏层实现适当拟合的方法有很多种,其中一种很简单的方法就是:隐藏层。我们很容易陷入这样一种误区:拥有更多或更大的隐藏层,能够提高分类器的正确率,但事实并非如此。增加隐藏层的数量或大小以后,我们的分类器就需要考虑更多不必要的参数。举个例子来说,将噪音看做是花朵的一部分,这会导致过拟合,也会降低精度,不仅如此,分类器还需要更长的时间来训练和预测。因此,我建议你从数量较少的隐藏层开始,然后根据需要增加隐藏层的数量或大小,而不是一开始就使用特别多或特别大的隐藏层。在第一部分介绍的《AI Programming with Python Nanodegree》课程中的花卉分类器项目中,我只需要一个小的隐藏层,在第一个完整训练周期内,就得到了70%以上的正确率。数据增强我们有很多图像可供模型训练,这非常不错。如果拥有更多的图像,数据增强就可以发挥作用了。每个图像在每个训练周期都会作为神经网络的输入,对神经网络训练一次。在这之前,我们可以对输入图像做一些随机变化,比如旋转、平移或缩放。这样,在每个训练周期内,输入图像都会有差异。增加训练数据的种类有利于减少过拟合,同样也提高了分类器的概括能力,从而提高模型分类的整体准确度。Shuffle在训练分类器时,我们需要提供一系列随机的图像,以免引入任何误差。举个例子来说,我们刚开始训练分类器时,我们使用“牵牛花”图像对模型进行训练,这样一来,分类器在后续训练过程中将会偏向“牵牛花”,因为它只知道“牵牛花”。因此,在我们使用其他类型的花进行训练时,分类器最初的偏好也将持续一段时间。为了避免这一现象,我们就需要在数据加载器中使用不同的图像,这很简单,只需要在加载器中添加shuffle=true,代码如下:trainloader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)Dropout有的时候,分类器中的节点可能会导致其他节点不能进行适当的训练,此外,节点可能会产生共同依赖,这就会导致过拟合。Dropout技术通过在每个训练步骤中使一些节点处于不活跃状态,来避免这一问题。这样一来,在每个训练阶段都使用不同的节点子集,从而减少过拟合。除了过拟合,我们一定要记住,学习率( learning rate )是最关键的超参数。如果学习率过大,模型的误差永远都不会降到最小;如果学习率过小,分类器将会训练的特别慢,因此,学习率不能过大也不能过小。一般来说,学习率可以是0.01,0.001,0.0001……,依此类推。最后,在最后一层选择正确的激活函数会对模型的正确率会产生特别大的影响。举个例子来说,如果我们使用 negative log likelihood loss(NLLLoss),那么,在最后一层中,建议使用LogSoftmax激活函数。结论理解模型的训练过程,将有助于创建能够概括的模型,在预测新图像类型时的准确度更高。在本文中,我们讨论了过拟合将会如何降低模型的概括能力,并学习了降低过拟合的方法。另外,我们也强调了学习率的重要性及其常用值。最后,我们知道,为最后一层选择正确的激活函数非常关键。现在,我们已经知道应该如何训练分类器,那么,我们就可以用它来预测以前从未见过的花型了!本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 20, 2018 · 1 min · jiezi

YOLO目标检测快速上手

介绍YOLO是基于深度学习端到端的实时目标检测系统,YOLO将目标区域预测和目标类别预测整合于单个神经网络模型中,实现在准确率较高的情况下快速目标检测与识别,更加适合现场应用环境。本案例,我们快速实现一个视频目标检测功能,实现的具体原理我们将在单独的文章中详细介绍。下载编译我们首先下载Darknet开发框架,Darknet开发框架是YOLO大神级作者自己用C语言编写的开发框架,支持GPU加速,有两种下载方式:下载Darknet压缩包git clone https://github.com/pjreddie/darknet下载后,完整的文件内容,如下图所示:编译:cd darknet# 编译make编译后的文件内容,如下图所示:下载权重文件我们这里下载的是“yolov3”版本,大小是200多M,“yolov3-tiny”比较小,30多M。wget https://pjreddie.com/media/files/yolov3.weights下载权重文件后,文件内容如下图所示:上图中的“yolov3-tiny.weights”,“yolov2-tiny.weights"是我单独另下载的。C语言预测./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg如图所示,我们已经预测出三种类别以及对应的概率值。模型输出的照片位于darknet根目录,名字是“predictions.jpg”,如下图所示:让我们打开模型输出照片看下:Python语言预测我们首先需要将“darknet”文件夹内的“libdarknet.so”文件移动到“darknet/python”内,完成后如下图所示:我们将使用Darknet内置的“darknet.py”,进行预测。预测之前,我们需要对文件进行修改:默认py文件基于python2.0,所以对于python3.0及以上需要修改print由于涉及到python和C之间的传值,所以字符串内容需要转码使用绝对路径修改完成后,如下图所示:打开“darknet/cfg/coco.data”文件,将“names”也改为绝对路径(截图内没有修改,读者根据自己的实际路径修改):我们可以开始预测了,首先进入“darknet/python”然后执行“darknet.py”文件即可:结果如下图所示:对模型输出的结果做个简单的说明,如:# 分别是:类别,识别概率,识别物体的X坐标,识别物体的Y坐标,识别物体的长度,识别物体的高度(b’dog’, 0.999338686466217, (224.18377685546875, 378.4237060546875, 178.60214233398438, 328.1665954589844)视频检测from ctypes import import randomimport cv2import numpy as npdef sample(probs): s = sum(probs) probs = [a/s for a in probs] r = random.uniform(0, 1) for i in range(len(probs)): r = r - probs[i] if r <= 0: return i return len(probs)-1def c_array(ctype, values): arr = (ctypelen(values))() arr[:] = values return arrclass BOX(Structure): fields = [(“x”, c_float), (“y”, c_float), (“w”, c_float), (“h”, c_float)]class DETECTION(Structure): fields = [(“bbox”, BOX), (“classes”, c_int), (“prob”, POINTER(c_float)), (“mask”, POINTER(c_float)), (“objectness”, c_float), (“sort_class”, c_int)]class IMAGE(Structure): fields = [(“w”, c_int), (“h”, c_int), (“c”, c_int), (“data”, POINTER(c_float))]class METADATA(Structure): fields = [(“classes”, c_int), (“names”, POINTER(c_char_p))]lib = CDLL(”../python/libdarknet.so", RTLD_GLOBAL)lib.network_width.argtypes = [c_void_p]lib.network_width.restype = c_intlib.network_height.argtypes = [c_void_p]lib.network_height.restype = c_intpredict = lib.network_predictpredict.argtypes = [c_void_p, POINTER(c_float)]predict.restype = POINTER(c_float)set_gpu = lib.cuda_set_deviceset_gpu.argtypes = [c_int]make_image = lib.make_imagemake_image.argtypes = [c_int, c_int, c_int]make_image.restype = IMAGEget_network_boxes = lib.get_network_boxesget_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int)]get_network_boxes.restype = POINTER(DETECTION)make_network_boxes = lib.make_network_boxesmake_network_boxes.argtypes = [c_void_p]make_network_boxes.restype = POINTER(DETECTION)free_detections = lib.free_detectionsfree_detections.argtypes = [POINTER(DETECTION), c_int]free_ptrs = lib.free_ptrsfree_ptrs.argtypes = [POINTER(c_void_p), c_int]network_predict = lib.network_predictnetwork_predict.argtypes = [c_void_p, POINTER(c_float)]reset_rnn = lib.reset_rnnreset_rnn.argtypes = [c_void_p]load_net = lib.load_networkload_net.argtypes = [c_char_p, c_char_p, c_int]load_net.restype = c_void_pdo_nms_obj = lib.do_nms_objdo_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]do_nms_sort = lib.do_nms_sortdo_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]free_image = lib.free_imagefree_image.argtypes = [IMAGE]letterbox_image = lib.letterbox_imageletterbox_image.argtypes = [IMAGE, c_int, c_int]letterbox_image.restype = IMAGEload_meta = lib.get_metadatalib.get_metadata.argtypes = [c_char_p]lib.get_metadata.restype = METADATAload_image = lib.load_image_colorload_image.argtypes = [c_char_p, c_int, c_int]load_image.restype = IMAGErgbgr_image = lib.rgbgr_imagergbgr_image.argtypes = [IMAGE]predict_image = lib.network_predict_imagepredict_image.argtypes = [c_void_p, IMAGE]predict_image.restype = POINTER(c_float)def convertBack(x, y, w, h): xmin = int(round(x - (w / 2))) xmax = int(round(x + (w / 2))) ymin = int(round(y - (h / 2))) ymax = int(round(y + (h / 2))) return xmin, ymin, xmax, ymaxdef array_to_image(arr): # need to return old values to avoid python freeing memory arr = arr.transpose(2,0,1) c, h, w = arr.shape[0:3] arr = np.ascontiguousarray(arr.flat, dtype=np.float32) / 255.0 data = arr.ctypes.data_as(POINTER(c_float)) im = IMAGE(w,h,c,data) return im, arrdef detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45): im, image = array_to_image(image) rgbgr_image(im) num = c_int(0) pnum = pointer(num) predict_image(net, im) dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum) num = pnum[0] if nms: do_nms_obj(dets, num, meta.classes, nms) res = [] for j in range(num): a = dets[j].prob[0:meta.classes] if any(a): ai = np.array(a).nonzero()[0] for i in ai: b = dets[j].bbox res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h))) res = sorted(res, key=lambda x: -x[1]) if isinstance(image, bytes): free_image(im) free_detections(dets, num) return resif name == “main”: cap = cv2.VideoCapture(0) ret, img = cap.read() fps = cap.get(cv2.CAP_PROP_FPS) net = load_net(b"/Users/xiaomingtai/darknet/cfg/yolov2-tiny.cfg", b"/Users/xiaomingtai/darknet/yolov2-tiny.weights", 0) meta = load_meta(b"/Users/xiaomingtai/darknet/cfg/coco.data") cv2.namedWindow(“img”, cv2.WINDOW_NORMAL) while(True): ret, img = cap.read() if ret: r = detect(net, meta, img) for i in r: x, y, w, h = i[2][0], i[2][17], i[2][18], i[2][19] xmin, ymin, xmax, ymax = convertBack(float(x), float(y), float(w), float(h)) pt1 = (xmin, ymin) pt2 = (xmax, ymax) cv2.rectangle(img, pt1, pt2, (0, 255, 0), 2) cv2.putText(img, i[0].decode() + " [" + str(round(i[1] * 100, 2)) + “]”, (pt1[0], pt1[1] + 20), cv2.FONT_HERSHEY_SIMPLEX, 1, [0, 255, 0], 4) cv2.imshow(“img”, img) if cv2.waitKey(1) & 0xFF == ord(‘q’): break模型输出结果:模型视频检测结果:没有GPU的条件下还是不要选择yolov3了,很慢。总结本篇文章主要是YOLO快速上手,我们通过很少的代码就能实现不错的目标检测。当然,想熟练掌握YOLO,理解背后的原理是十分必要的,下篇文章将会重点介绍YOLO原理。 ...

December 19, 2018 · 3 min · jiezi

用PyTorch创建一个图像分类器?So easy!(Part 1)

摘要: 本文将为你介绍为何要重用神经网络?哪部分可以重用,哪部分不可以重用。了解完这些基础概念,你就可以自行创建一个图像分类器了。经过了几个月的学习和实践,我完成了优达学城网站上《Python Programming with Python Nanodegree》课程的学习,该课程的终极项目就是使用Pytorch为102种不同类型的花创建一个图像分类器。在完成这个项目的过程中,我和其他学员一样,都碰到了各种问题和挑战,因此写下了这篇文章。希望你读完这篇文章以后,会对你的机器学习有所裨益。本文介绍了如何实现图像分类的基础概念,即理解图像内容的算法。本文并不会详细分步说明构建模型的具体步骤,而是从宏观上介绍整个过程,如果你正在学习机器学习或人工智能,相信这篇文章将会对你很有帮助。在第一部分中,我们将介绍加载预训练的神经网络,为什么要“重用”网络(即使用预训练神经网络),指明哪些部分可以重用,哪些部分不可以重用,以及如何自定义预训练网络。加载一个预训练网络“重用”是一个非常合理的策略,特别是当某些工具是大家都认可为标准的时候,“重用”更显得尤为重要。在这个例子中,我们的出发点是torchvision提供的一个模型框架。现在,我们要做的是加载一个预先训练好的网络,并用自己的网络替换它的分类器,然后,我们就可以训练自己的分类器了。虽然这个想法很合理,但是也比较麻烦,因为加载一个预先训练好的网络,并不会节省我们训练分类器的工作量。所以,使用预训练网络到底有什么好处呢?当我们人类在看图像的时候,我们会识别线条和形状,鉴于此,我们才可以将图像内容与之前看到的内容联系起来。现在,我们希望分类器也能做到这点,但是,图像并不是一个简单的数据,而是由数千个独立的像素组成,每个像素又由3个不同的值组合起来,形成颜色,即红色、绿色和蓝色。 如果我们希望分类器能够处理这些数据,我们要做的就是将每个待处理图像所包含的信息,以分类器可以理解的格式传给分类器,这就是预训练网络发挥作用的地方。这些预训练网络主要由一组特征检测器和分类器组成,其中,特征检测器被训练成可以从每个图像中提取信息,分类器被训练成理解特征层提供的输入。在这里,特征检测器已经在ImageNet中接受过训练,并且性能良好,我们希望这点能够继续保持。在训练分类器时,为了防止特征层被篡改,我们得对特征层进行“冻结”,下面这些代码可以很轻松的解决这一问题:for param in model.parameters(): param.requires_grad = False那么,问题又来了,既然我们可以“重用”特征检测器,我们为什么不能“重用”分类器?要回答这个问题,我们先来看看VGG16架构的默认分类器:(classifier): Sequential( (0): Linear(in_features=25088, out_features=4096, bias=True) (1): ReLU(inplace) (2): Dropout(p=0.5) (3): Linear(in_features=4096, out_features=4096, bias=True) (4): ReLU(inplace) (5): Dropout(p=0.5) (6): Linear(in_features=4096, out_features=1000, bias=True))首先,我们没办法保证这些代码能够起作用,在我们特定的环境中,这些默认层、元素、激活函数以及Dropout值并不一定是最佳的。尤其是最后一层的输出是1000个元素,这就容易理解了。在我们的例子中,我们要对102种不同类型的花进行分类,因此,我们的分类器输出必须是102,而不是1000。从上面VGG16架构的默认分类器中,我们还可以注意到,分类器的输入层有25088个元素,这是特定预训练模型中特征检测器的输出大小,因此,我们的分类器大小也必须要与要特征层的输出相匹配。结论从上面的分析,本文能够得到以下结论:1.预先训练好的网络非常有用。使用预训练模型,可以让我们更加专注于我们自己用例的具体细节,还可以重用众所周知的工具,对用例中的图像进行预处理。2.分类器的输出大小必须与我们希望识别的图像数量相同。3.特征层的输出和自定义分类器的输入大小必须相匹配。在下一篇文章中,我们将深入探讨,在训练分类器过程中,如何避免一些常见的陷阱,并学习如何调整超参数,来提高模型的准确性。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 19, 2018 · 1 min · jiezi

数据不足,如何进行迁移学习?

摘要: 在没有足够的训练数据时,本文详细介绍了如何使用FloydHub、fast.ai和PyTorch进行迁移学习。现在,人工智能的发展处于跳跃式阶段,我们也对AI在大型数据集的应用进展感到吃惊。更重要的是,那些我们没有跟踪的数十亿张照片或餐厅的评论并没有被遗漏掉:迁移学习技术让收集数据变得更加“容易”。另外,得益于PyTorch框架、fast.ai应用程序库以及FloydHub公司,小团队或者是个别开发人员也能轻松的应用这些方法。本文要讲的例子就是ULMFiT:Jeremy Howard和Sebastian Ruder在fast.ai展示了如何用几百个标记准确的对电影评论进行分类。除此之外,还有一个在通用英语文本语料库中训练的模型。除了英语文本资料库和标记对评论进行分类外,fast.ai还有一个小技巧,它拥有大量特定领域的文本:10万多个样本评论,来展示普通英语和电影评论之间的区别。这引发了我们的思考:至少得需要多少数据,才足以弥合训练示例和通用语言模型之间的差距?这并不是一个特别愚蠢的问题。Frame可以帮助Zendesk,Intercom和Slack等规模性公司标记、评价和理解与客户的对话。也就是说, “只要有足够的对话,我们就可以手动评价”和“我们有足够的数据从头训练一个模型”,这二者之间有很大的差距。仅仅几十个标签和几千条相关对话,这能够做什么?事实证明,这非常有用。在本文中,我们将使用相同的电影评论数据集来证明:即便是只有少部分的数据,数据迁移依然可以有效。更加详细的代码请参考ULMFiT。迁移什么?深度神经网络是当前最新人工智能背后的关键技术,比如理解图像、音频或文本。深度神经网络的核心是它由层(“深度”)组成,每个层都将输入转换为更接近网络训练答案的新的表示。我们通常会抱怨,不了解神经网络的中间层到底发生了什么……其实,它们通常被设计为更加清晰、可解释的角色!比如:很多语言模型利用嵌入层将单个单词或短语进行分类,将具有相似含义的单词或短语放在一起。举个例子来说,这将有助于翻译AI在需要使用“杰出”(illustrious)这个词的时候,会根据经验选择使用“伟大”(great)。现在变得更有趣了:一个“知道”“illustrious = great”的层不仅有利于翻译,还可以学习情绪估计,将不同的观点聚集起来。这就是迁移学习,也就是说模型在一个任务中学习到的东西可以对另外一个学习任务有帮助。事实上,这个特殊的例子特别受欢迎,以至于改进的通用语言模型已经成为一个全新的领域! 迁移学习不仅有利于任务之间的转移:它可以帮助一般模型在特定环境中更好的工作。例如:一个通用的英语情绪模型或许可以预测电影评论,但是可能不知道“紧张、紧张的惊悚”是件好事。这就是Jeremy和Sebastian Rudder的通用语言模型微调文本分类(ULMFiT)的用武之地。他们对一个包含100,000个IMDB评论的通用语言模型做了改进。即便是只标记几百个单词,其余的单词也能够帮助AI学习审稿人经常用“杰出”或“很好”代替“紧张、紧绷”等,这很好的弥补了数据不足的缺陷。结果的准确度令我们感到惊讶:仅仅有500个标记示例,分类的准确度却高达94%。未被标记的数据最少需要多少?ULMFiT为NLP提供了一个有力的依据,使模型能够更有效的利用较小的数据集。在这项研究中,我们专注于回答以下问题:如果我们对标记示例的预算特别少,那么,得需要收集多少未标记的数据才能有效的使用迁移学习?为了解决这个问题,我们使用了大量固定的域数据池,并改变了标记示例的数量,来看看模型应该如何改进。将标记示例的数量保持不变,并改变未标记的其他域示例的数量。也就是说,我们的实验包括:1.语言建模(变量)2.语言任务(不变量)我们的语言任务、情感分类和原始的ULMFiT论文中的任务相同,另外,也使用了IMDB电影评论数据集。在实验中,标记情绪训练样本的数量保持在500个,500个样本可以用于很多小领域的研究,并且,有助于强调不同语言模型的差异提升能力。对于语言建模,我们改变了可用于语言任务的三种语言模型的域数据量:仅限ULM:这是使用Wikitext103预训练英语语言模型仅限域(domain):仅在IMDB数据上的基于域训练的模型。ULM +域(domain):ULMFiT模型训练这些模型的计算量特别大,最大的域训练可能需要几天的时间才能完成。为了加快训练速度和有效的执行网格搜索,我们使用了FloydHub。结果经过大约50个小时GPU处理,结果如下:从实验结果,我们可得知:使用33%的域数据,就可以获得75%数据的UMLFiT性能。令人惊讶的是,ULM + 2,000域示例的语言任务预测准确率约为85%。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 18, 2018 · 1 min · jiezi

生物智能与AI——关乎创造、关乎理解(下)

摘要: 原来人工智能跟人类智能有那么深的联系!无监督学习,迁移学习和工程设计AI系统与人类学习之间的另一个主要差异在于AI系统所需的大量标记数据才可以达到人类级别的性能。例如,最近的语音识别系统在11940小时的语音训练后才能对齐转录。如果我们每天大声地听到另一个人类阅读文本两个小时,那么我们需要16年才能获取到这个数据集。AlphaGozero练习了490万场才击败人类围棋大师。如果一个人每天玩围棋30年,那么他每天必须玩450场比赛才能达到AlphaGozero的练习量。此外,最近关于视觉问答的数据集包含了0.25M图像,0.76M问题和10M答案。如果我们每天收到关于图像的100个问题的答案,我们需要274年的时间来吸收这种规模的数据集。很明显人类接受的标记训练数据量要少得多,但他们可以识别语音,玩围棋并很好地回答有关图像的问题。 其中,人工智能和生物智能之间差距的几个关键在于人类从未标记数据中学习的能力(无监督学习),以及在解决先前任务时获得的强大先验知识,并将这些知识转移到新任务中(迁移学习)。最后,人类社会建立了教育系统,精心挑选一些学习任务进行教学,以促进知识获取。为了在人工系统中有效地实例化这些概念,我们需要更深入地理解和数学形式化人类和其他动物如何进行无监督学习及知识如何在任务之间转移,这需要计算机科学家、心理学家和教育工作者的参与。因为这对于在标记数据稀缺的领域中训练AI是至关重要。建立理解,规划和主动因果学习的世界模型当前AI在商业环境中的成功很多是通过监督方法实现的,其中AI系统被动地接收输入,被告知正确的输出,并且它调整其参数以匹配每个输入-输出组合。相比之下,婴儿就像活跃的科学家一样探索他们的环境。例如:利用魔术,婴儿会看到两个“魔法”物体:物体A,它似乎穿过墙壁,而物体B,它在掉落时不会掉落。给婴儿A,B,婴儿将尝试将物体A穿过墙壁,然后放下物体B以查看它是否会掉落。这项非凡的实验表明,婴儿就像科学家一样,积极地探索他们的世界。因此,与当前大多数的商业AI系统不同,婴儿具有学习和利用世界模型的卓越能力。我们需要在神经科学和人工智能方面进一步研究从经验中学习世界模型,使用这些世界模型进行规划(即,根据当前行动想象不同的未来),并使用这些未来的计划来做出决策。这种基于模型的规划和决策可能是当前无模型强化学习系统的有力支持,该系统简单地将世界状态映射到值或预期的未来奖励。人工智能中的这项工作可以与神经科学的工作携手并进,揭示动物的神经活动如何与想象的和未来相关。像好奇心这样的基本驱动可以形式化为强化学习系统,以此来促进学习和探索。更一般地,深入理解多个系统和促进动物和人类学习的内在生物驱动可能对加速人工系统的学习非常有益。在后摩尔定律时代实现节能计算生物系统和AI系统之间的另一个数量级差异在于它们的能量消耗。人脑仅消耗20瓦的功率,而超级计算机则以兆瓦的功率运行。造成这种差异的一个关键原因可能是过度依赖数字计算本身,虽然数字革命推动了现代信息技术的兴起,但现在我们对实现人工智能的追求被认为是次优遗留技术。原因是数字计算需要在计算的中间阶段以极高的可靠性翻转每一位。然而,热力学定律则为每个快速可靠的位翻转确定了相当大的能量成本。相比之下,生物的细胞内的分子以及脑内神经元的计算看起来令人惊讶地嘈杂和不精确。然而,生物计算的每个中间步骤都足够可靠,以使最终答案足够好。此外,大脑智能地向上或向下调节能量成本根据所需的通信速度。例如,考虑大脑中通过目标神经元的单位的成本。它开始于囊泡的随机释放,其以1毫米/秒的速度扩散到源神经元和目标神经元之间的空间,仅燃烧2.3毫微微焦耳(fj)。速度刚刚好,因为神经元连接之间的空间只有20纳米。该化学信号被转换为无源电信号,其以1米/秒的速度流过神经元细胞体,燃烧23fj横穿约10微米。最后,它到达轴突终端并转换为长轴,沿着轴突每秒行进100米,燃烧6000 fJ行进1厘米。因此,在从化学信号传递到被动电信号时,大脑动态地将通信速度上调1000倍,以跨越增加1000倍的距离,从而导致能量消耗增加10倍。因此,只有在需要更高速度且仅需要更高可靠性时,大脑才会消耗更多能量。相比之下,数字计算机在刚性同步时钟上运行,并且在每个时钟周期,许多晶体管必须可靠地翻转状态。总之,生物计算的明显混乱不一定是不可避免的混乱,而是可能反映出高能效设计的理想原则。为了在我们的AI硬件中实现这样的效率,遵循生物计算的这些原则可能是必要的。用于AI的神经科学和神经科学的AI:一种良性的科学螺旋最近神经科学和AI之间相互作用促进了深度和递归神经网络模型的发展。在许多情况下,当训练深度或递归网络来解决任务时,其内部表现看起来与训练为解决相同任务的动物中测量的内部神经活动模式非常相似。因此,我们通常会在不同的任务中获得不同大脑区域操作的高度复杂但令人惊讶的真实模型,从而提出了一个基本问题:我们如何理解这些模型正在做什么以及它们如何工作?更确切地说,学习网络连接和神经动态如何产生高性能?AI目前在理解它的神经模型正在做什么时面临同样的问题,虽然一些工程师认为没有必要了解神经网络是如何工作的。然而,对于当前网络的成功和失败如何因其连通性和动态性而产生的更深入的科学理解将导致网络的优化。然而,科学与技术之间的相互作用历史上几乎没有更深入的科学认识,也不会导致更好的技术。但是,在AI的某些应用中,特别是在医学诊断或法律中,可解释的AI是必不可少的。例如,如果医生和法官无法理解为什么这些系统做出了他们做出的决定,他们就不会在他们的案件中使用人工智能系统的建议。因此,神经科学需要共享理解网络性能和决策如何作为网络连接和动态的新兴属性。因此,理论神经科学,应用物理学和数学的思想和理论的发展可以帮助分析AI系统。此外,AI系统的行为可能会改变神经科学中实验设计的本质,将实验工作集中在AI中难以理解的网络功能方面。总体而言,神经科学,人工智能和许多其他理论学科之间的紧密联系可以获得很多灵感,这可能会为生物和人工系统中的智能的出现带来统一的规律。寻求管理生物和人工智能的普遍规律在人工智能系统设计中,一种经常被引用的无视生物学的争论常涉及到飞机与鸟类的比较。然而,仔细观察这个想法会发现更多的细微差别。飞行的一般问题涉及解决两个基本问题:(1)为了前进而产生推力,(2)升力的大小使我们不会脱离天空。鸟类和飞机用不同方法解决了推力问题:鸟儿拍翅膀和飞机使用喷气发动机。但是,它们以完全相同的方式解决升力问题,通过使用弯曲的翼形,在低于和低于上方的气压下产生更高的气压。因此,滑翔的鸟类和飞机的运作非常相似。实际上,我们知道空气动力学的一般物理定律:不同形状通过空气时,都可以用计算的方法来预测产生的力,如升力和推力。而且,任何解决飞行问题的方法,无论是生物还是人工,都必须遵守空气动力学定律。更一般地说,在我们对物理世界的研究中,我们习惯于存在管理其行为的原则或规律。例如,正如空气动力学控制飞行物体的运动一样,广义相对论控制着空间和时间的曲率,量子力学控制着纳米世界的演化。我们认为,可能存在普世原则或法律来管理智能行为如何从大型互连神经元网络的合作活动中产生。这些法律可以连接和统一神经科学、心理学、认知科学和人工智能的相关学科,他们的阐述也需要帮助分析和计算领域,如物理,数学和统计学。事实上,这篇文章的作者使用了动力系统理论、统计力学、黎曼几何、随机矩阵理论和自由概率理论等技术,获得了对生物和人工网络运作的概念性见解。然而,为了阐明管理非线性分布式网络中出现智能的一般规律和设计原则,还需要进一步的工作,包括开发新概念,分析方法和工程能力。最终,就像鸟类,飞机和空气动力学的故事一样,创造智能机器的问题可能存在多种解决方案,其中一些组件在生物解决方案和人工解决方案之间共享,而其他组件则可能不同。通过寻求一般的智力法则,发现适用于生物和人工系统的新兴智能的潜在法则,以及建立受神经科学和心理学启发的新型AI,需要许多研究人员共同努力:计算机科学家追求更好的AI系统,神经科学家,心理学家和认知科学家探索大脑和思想的属性,数学家,物理学家,统计学家和其他理论家寻求形式化我们的综合知识并发现一般的法律和原则。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 18, 2018 · 1 min · jiezi

深度学习常见激活函数介绍及代码实现

作用深度神经网络引入非线性单元,使训练问题不再是一个凸优化问题,虽然我们很难得到最优解,但是可以通过梯度下降去寻找局部最小值。增强模型的拟合能力,理论上只要有足够的神经元,一层隐藏层就可以表达任意函数。性质可微(多元函数):函数可微保证使用梯度下降优化的可计算性。单调性:保证梯度方向相对稳定。输出值范围:当输出有限,由于特征表示受有限权值影响,基于梯度的优化方法会更加稳定;当输出无限,特征表示不受影响,但由于高梯度需要小学习率。非饱和性:当激活函数满足如下要求,称为右饱和:当激活函数满足如下要求,称为左饱和:激活函数饱和会造成梯度值接近0,导致梯度消失使模型无法收敛。sigmoidsigmoid函数,导函数图像:sigmoid激活函数具有“连续可微”,“单调性”,“输出值有限”。通过查看导函数图像,sigmoid激活函数最大的问题就是两端饱和,造成梯度消失(解决办法:使用relu激活函数,BN等),此外输出不以0中心(以0中心的好处是可以加快模型收敛)。目前sigmoid激活函数多使用在二分类问题(对于大于二分类问题,如果类别之间存在相互关系使用sigmoid,反之使用softmax),门控机制的判断等。import tensorflow as tftf.enable_eager_execution()sigmoid_test=tf.nn.sigmoid([-3.,-2.,-1.,0.0,1.,2.,3.],name=‘sigmoid_op’)print(sigmoid_test)输出:tf.Tensor([0.04742587 0.11920292 0.26894143 0.5 0.7310586 0.880797 0.95257413], shape=(7,), dtype=float32)tanh tanh函数,导函数图像:tanh激活函数输出区间[-1,1],输出值以0为中心,与sigmoid激活函数相比具有更大的梯度值,再加上输出值以0为中心,模型收敛更快。不过它依然存在两端饱和,梯度消失问题还是存在,tanh激活函数在RNN模型中应用较多。import tensorflow as tftf.enable_eager_execution()tanh_test=tf.nn.tanh([-3.,-2.,-1.,0.0,1.,2.,3.],name=‘tanh_op’)print(tanh_test)输出:tf.Tensor([-0.9950547 -0.9640276 -0.7615942 0. 0.7615942 0.9640276 0.9950547], shape=(7,), dtype=float32)relurelu函数,导函数图像:relu与线性单元的区别是在其一半的定义域上输出为0,这使得它易于优化,计算。通过图像可得,relu激活函数的梯度不仅大,而且一致,更重要的是它没有sigmoid,tanh激活函数的饱和性,有效缓解了梯度消失问题。目前,relu激活函数是神经网络隐藏层的首选。但是,它最大的问题是当输入小于0时,输出值为0,此时神经元将无法学习。import tensorflow as tftf.enable_eager_execution()relu_test=tf.nn.relu([-3.,-2.,-1.,0.0,1.,2.,3.],name=‘relu_op’)tf.nn.reluprint(relu_test)输出:tf.Tensor([0. 0. 0. 0. 1. 2. 3.], shape=(7,), dtype=float32)leakyreluleakyrelu函数,导函数图像:leakyrelu激活函数是relu的衍变版本,主要就是为了解决relu输出为0的问题。如图所示,在输入小于0时,虽然输出值很小但是值不为0。leakyrelu激活函数一个缺点就是它有些近似线性,导致在复杂分类中效果不好。import tensorflow as tftf.enable_eager_execution()# alpha: Slope of the activation function at x < 0leaky_relu_test=tf.nn.leaky_relu([-3.,-2.,-1.,0.0,1.,2.,3.],alpha=0.2,name=‘leaky_relu_op’)print(leaky_relu_test)输出:tf.Tensor([-0.6 -0.4 -0.2 0. 1. 2. 3. ], shape=(7,), dtype=float32)eluelu函数,导函数图像:elu和relu的区别在负区间,relu输出为0,而elu输出会逐渐接近-,更具鲁棒性。elu激活函数另一优点是它将输出值的均值控制为0(这一点确实和BN很像,BN将分布控制到均值为0,标准差为1)。import tensorflow as tftf.enable_eager_execution()elu_relu_test=tf.nn.elu([-10000,-100.,-3.,-2.,-1.,0.0,1.,2.,3.],name=‘elu_relu_op’)print(elu_relu_test)输出:tf.Tensor([-1. -1. -0.95021296 -0.86466473 -0.63212055 0. 1. 2. 3. ], shape=(9,), dtype=float32)softmaxsoftmax单元常作为网络的输出层,它很自然地表示了具有 k 个可能值的离散型随机变量的概率分布。softmax将向量等比例压缩到[0,1]之间,且保证所有元素之和为1。import tensorflow as tftf.enable_eager_execution()softmax_test=tf.nn.softmax([-3.,-2.,-1.,0.0,1.,2.,3.],name=‘softmax_op’)print(softmax_test)softmax_test_sum=tf.reduce_sum(softmax_test)print(softmax_test_sum)输出:tf.Tensor([0.0015683 0.00426308 0.01158826 0.03150015 0.0856263 0.23275642 0.6326975 ], shape=(7,), dtype=float32)tf.Tensor(1.0, shape=(), dtype=float32)总结激活函数的选择还要根据项目实际情况,考虑不同激活函数的优缺点。 ...

December 17, 2018 · 1 min · jiezi

年度大盘点:机器学习开源项目及框架

摘要: 2018年马上就要结束了,我们来回顾一下过去的这一年中,机器学习领域有哪些有趣的事情吧!我们先来看看Mybridge AI 中排名靠前的顶级开源项目,再聊聊机器学习今年都有哪些发展,最后探寻下新的一年中会有哪些有值得我们期待的事情。顶级的开源项目BERTBERT,全称为Bidirectional Encoder Representations from Transformers,是一种基于TensorFlow解决自然语言处理的新方法,且性能更好。我们可以使用BERT中的 预训练模型解决问题,该模型在性能上具有很大优势,比如可以识别句子中的上下文。在Github中非常受欢迎,有8848个星,完整学术论文请访问这里。DeepCreamPyDeepCreamPy是一个深度学习工具,可以像Photoshop一样重建图像中被删除的区域。我们使用图像编辑工具(比如PS)将删减的区域填充为绿色,神经网络可以对其进行复原。该项目在Github中有6365颗星。TRFLTRFL项目可用于编写TensorFlow中的强化学习代理,具体的操作文档在这里。HorizonHorizon是一个基于PyTorch构建的强化学习平台,并使用Caffe2为模型提供服务。Horizon的主要优势在于,设计者在设计这一平台的时候,考虑了生产用例。想要了解更多详细内容,请查看Facebook Research官方文档。另外,如果你想使用Horizon,可查看该使用文档。DeOldifyDeOldify是一个用于着色和恢复旧图像的深度学习库。开发者结合了几种不同的方法,来实现这一目标,其中的几种方法包括:带自注意力机制的生成对抗网络(Self-Attention Generative Adversarial Networks),Progressive Growing of GANs,以及TTUR( Two Time-Scale Update Rule)。AdaNetAdaNet是一个基于TensorFlow的库,它可以自动学习模型,且不需要很多的技术人员参与,该项目基于AdaNet算法。访问AdaNet的官方文档,请点击这里。Graph NetsGraph Nets是用于构建Sonnet和TensorFlow的DeepMind库。Graph 网络输入一个图形,输出也是一个图形。Maskrcnn-benchmarkMaskrcnn-benchmark项目可以帮助我们在Pytorch中构建对象检测和分割工具。这个库的优势在于速度快、内存效率高,可以进行多个GPU训练和推断,且为推断提供CPU支持。PocketFlowPocketFlow项目是一个加速和压缩深度学习模型的框架。它解决了大多数深度学习模型的计算费用问题。该项目最初由腾讯AI实验室的研究人员开发,了解其实现及官方文档请点击这里。MAMEToolkitMAMEToolKit是一个训练街机游戏强化学习算法的库,使用该工具可以跟踪游戏状态,同时也可以接收游戏帧数据。机器学习框架的主要发展PyTorch 1.0在今年10月份举办的PyTorch会议期间,Facebook发布了PyTorch 1.0预览版。PyTorch 1.0解决了以下问题:训练耗时长、联网问题、缓慢的可扩展性以及Python编程语言带来的一些不灵活性。PyTorch 1.0引入了一组编译工具Torch.jit,这将弥补生产和研究之间的差距。Torch.jit中包含Python中的Torch Script语言,在PyTorch 1.0中,我们可以使用图形模式构建模型,这在开发高性能和低延迟的应用程序中非常有用。Auto-Keras你或许听过自动化机器学习(automated machine learning),即自动化搜索机器学习模型的最佳参数。除Auto-Keras之外,还有其他的自动化机器学习模型,比如Google的AutoML。Auto-Keras是基于Keras和ENAS编写的,其中,ENAS是神经网络结构搜索的最新版本。TensorFlow Serving使用TensorFlow Serving系统,我们能更加轻松的将TensorFlow模型部署到生产环境中。虽然TensorFlow Serving在2017年就已经发布,但是今年更加注重将模型应用到生产环境环节。Machine Learning Javascript现在已经有一些可以允许开发人员在浏览器上运行模型的Javascript框架,比如TensorFlow.js和Keras.js。其模型实现与使用的方法,与Keras或TensorFlow等常规框架非常相似。展望未来2019年马上就要到了,随着Auto-Keras等自动化工具的发展,开发人员的工作有望变得更加轻松。除此以外,我们还拥有先进的研究以及优秀的社区,各类机器学习框架的性能还会更上一层楼。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 17, 2018 · 1 min · jiezi

生物智能与AI——关乎创造、关乎理解(上)

摘要: 原来人工智能跟人类智能有那么深的联系!几百万年前,第一次人类智能的星火出现在非洲大陆,并且持续发展,最终在大约10万年前在智人的大脑中达到顶峰。作为现代人类,我们只能想象我们的古代祖先在窥视夜空时所经历的事情,以思考物理现实的本质,以及从内心窥视自己心理现实的本质。在过去的几百年里,我们的物种通过发现控制空间、时间、物质和能量的基本数学定律。在发展对物理现实的精确理解方面取得了巨大的智力进步,现在已经在量子力学的大框架中被编纂。然而,我们正处于探索心理现实本质的最初阶段。尤其是人类智能是如何从100亿个突触连接的1000亿个神经元的生物湿件中产生的?神经科学,心理学和认知科学等现代学科在过去100年中取得了重要进展,为解决这一重大问题奠定了基础。但是,当涉及到我们的心智能力时,对于现代人来说,仅仅理解它们是不够的,我们非常希望在无生命系统中重现这些功能。本质上,人类作为进化的产物,有时也渴望扮演创造者的角色。这种向往渗透在人类文学的作品,事实上,人工智能(AI)这个新兴领域,通常与神经科学,心理学和认知科学领域合作,在创造具有类似人类能力的机器方面取得了巨大进步。在这篇文章中,我将进一步探讨人工智能,神经科学,心理学和认知科学以及数学,物理和社会科学中的联合学科在过去和未来将继续如何共同努力追求交织在一起的理解和创造智能系统的过程。生物学与人工智能之间的富有成效的合作在过去的60多年中,AI的发展受到了神经科学和心理学的深刻影响,其中也受到了神经科学和心理学的启发。在早期的几十年中,许多AI从业者在神经科学和心理学方面进行了很好的研究。在这里,我提供了神经科学,心理学和AI之间过去的相互作用:这种相对简单的元素(神经元)的分布式网络能够实现源于神经科学的人类智能的显着计算,并且现在以神经网络的形式渗透到AI系统中。这个想法并不总是显而易见的,在大约一百年前,在高尔基和卡哈尔之间的著名辩论之后,它才变得坚定。包括多维尺度和因子分析在内的各种降维技术最初是在心理测量学研究的背景下开发的。著名的神经科学家霍勒斯·巴洛(Horace Barlow)发明了分解代码的概念,这反过来启发了独立成分分析(ICA)和当前的AI研究,旨在解开数据变异的独立因素。托尔曼在认知图上的工作提供了方向,使得我们可以使用这些模型进行规划和导航。这巩固了内部模型形成作为动物智能的关键组成部分的思想,这部分目前处于人工智能研究的前沿。Hopfield网络是理论神经科学的一个模型,为思考分布式、可寻址的存储器和检索提供了一个统一的框架,也启发了Boltzmann机器,这反过来又为证明深度神经网络模型的成功提供了关键的第一步。它还启发了许多弱约束的分布式以满足作为AI计算模型的想法。目前主导机器视觉的深层卷积网络的关键核心直接受到大脑的启发。其中包括腹侧流中的分层视觉处理,它表明深度的重要性;视网膜的发现是整个视觉皮层的组织原理,导致卷积的出现;发现简单和复杂的细胞激发了最大池化等操作。关于稀疏编码的研究工作是为了理解初级视觉皮层中定向边缘检测器,导致稀疏编码成为现代AI系统中的基本构建块。时序差分学习等算法现在是强化学习领域的基础,它受到经典条件反射的动物实验的启发。反过来,强化学习对基底神经节功能的解释具有显着影响,其中多巴胺能为基底神经节提供了非常重要的奖励预测误差信号,该信号也驱动许多强化学习算法。大脑中存储系统的模块化启发了现代记忆神经网络,其在一定程度上将存储器存储和执行控制电路的操作分开,其决定何时从存储器读取和写入。人类注意力系统激发了注意力机制和神经网络的结合,这些神经网络可以被训练以动态地注意力或忽略其状态和输入的不同方面以进行未来的计算决策。语言学和认知科学中正式生成语法的发展导致概率语法的发展和CS的解析。Dropout等现代正则化技术的灵感来自于神经动力学的内在随机性。人工智能未来的生物学启示尽管当前人工智能系统在监督模式识别任务方面取得了显著的商业成功,但仿真人类智能仍然有很长的路要走。在这里,我将概述一些个人观点,其中我认为生物学和人工智能领域可以携手前进。1、生物学上可信的信用分配(plausible credit assignment)信用分配问题可能是神经科学和人工智能领域最大的开放性问题之一。很明显,假设你正在打网球而且你没有击中球。你的100万亿个突触中有哪一个应该受到指责?大脑如何在你的运动系统中专门找到并纠正突触组,尤其是在错误发生后几百毫秒内通过视觉系统传递错误时?在AI中,这种信用分配问题在许多情况下通过多层计算的反向传播来解决。然而,目前尚不清楚大脑如何解决这个问题。真实的情况是,大脑使用本地学习规则解决它:即每个突触仅使用物理上可用的信息来调整其强度,例如,由突触连接的两个神经元的电活动来奖励和惩罚的任何神经调节输入。解释这些本地突触规则是什么以及它们如何工作可能会对AI产生巨大影响,这可以一定程度上减少反向传播的通信开销。但更一般地说,解决困扰神经科学和人工智能的常见未解决问题应该通过将突触生理学家,计算神经科学家和AI从业者聚集在一起来集体解决生物学上可信的信用分配问题来推动进步。2、融合突触复杂性生物和人工神经模型之间的主要区别在于我们模拟连接神经元的突触的方式。在人工网络中,突触由单个标量值建模,反映乘法增益因子,转换神经元的输入如何影响神经元的输出。相反,每个生物突触都隐藏在极其复杂的分子信号通路中。例如,我们对最近事件记忆的海马突触各自包含数百种不同类型分子的化学反应网络,同时它具有整个复杂时间处理能力的动力系统。在看到这种复杂性后,理论家或工程师可能会试图简单地将其视为生物学上的混乱,而这种混乱就是一种进化的偶然事件。然而,理论研究表明,这种突触复杂性可能确实对学习和记忆至关重要。事实上,在突触具有有限动态范围的记忆网络模型中,这样的突触本身就要求是具有复杂时间滤波特性的动态系统,以实现合理的网络存储容量。此外,最近在AI中正在利用更智能的突触作为解决灾难性遗忘问题的一种方法,其中训练学习两个任务的网络只能学习第二个任务,因为学习第二个任务会改变突触权重以这种方式消除从学习第一项任务中获得的知识。一般地说,我们的人工智能系统很可能通过忽略生物突触的动态复杂性而取得重大的性能提升。正如我们为我们的网络添加空间深度以实现复杂的层次表示一样,我们可能还需要为突触添加动态深度以实现复杂的时间学习功能。从系统级模块化大脑架构中获取灵感通常,当前的商业AI系统涉及具有相对均匀的分层或循环架构的训练网络,其从随机权重开始。但是,对于更复杂的任务来说,这可能是一个难以解决的问题。事实上,生物进化的道路却截然不同。所有脊椎动物的最后共同祖先生活在5亿年前。从那以后,它的基本大脑一直在发展,导致大约1亿年前出现哺乳动物大脑,以及几百万年前的人类大脑。这种不间断的进化链导致了一个错综复杂的大脑结构,具有高度保守的计算元素和巨大的系统级模块化。事实上,我们目前缺乏工程设计原则,来解释像大脑一样复杂的传感,通信,控制和记忆网络可以在5亿年的时间内不断扩大规模和复杂性,同时永远不会失去在动态环境中自适应运行的能力。因此,AI从大脑的系统级结构中获取灵感可能非常有趣。一个关键的系统属性是功能和结构的模块化。大脑不像我们目前的AI架构是同质的,而是有不同的模块,如海马(保留情节记忆和导航),基底神经节(潜在的强化学习和动作选择)和小脑(自动化的运动控制和通过监督学习获得更高层次的认知)。此外,人脑中的记忆系统(习惯记忆,运动技能,短期记忆,长期记忆,情景记忆,语义记忆)也是功能模块化的。此外,在运动系统中,嵌套反馈环架构占主导地位,通过简单的快速循环在20毫秒内实现自动运动校正,稍慢的智能循环通过运动皮层在50毫秒内实现更复杂的运动校正,最后经过整个大脑的视觉反馈实现对运动错误的有意识的校正。最后,所有哺乳动物大脑的一个主要特征是由大量相似的6层皮质柱组成的新皮层,所有这些都被认为是在单个规范计算模块上实现的变异。总体而言,现代哺乳动物大脑具有显著的模块性,通过1亿年的进化保存下来,表明这种系统级模块化可能有利于在AI系统中实施。目前从白板上训练神经网络的方法是不可能走向更普遍的人类智能的途径。实际上,系统级模块化的组合带来的不同类型的纠错嵌套循环和动态复杂的突触可能都是解决生物学上可信的信用分配的关键因素。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 17, 2018 · 1 min · jiezi

目标检测算法图解:一文看懂RCNN系列算法

摘要: 本文简要介绍图像检测中常用的深度学习方法——RCNN家族系列算法,以图像讲解形式,便于理解。在生活中,经常会遇到这样的一种情况,上班要出门的时候,突然找不到一件东西了,比如钥匙、手机或者手表等。这个时候一般在房间翻一遍各个角落来寻找不见的物品,最后突然一拍大脑,想到在某一个地方,在整个过程中有时候是很着急的,并且越着急越找不到,真是令人沮丧。但是,如果一个简单的计算机算法可以在几毫秒内就找到你要找的物品,你的感受如何?是不是很惊奇!这就是对象检测算法(object detection)的力量。虽然上述举的生活例子只是一个很简单的例子,但对象检测的应用范围很广,跨越多个不同的行业,从全天候监控到智能城市的实时车辆检测等。简而言之,物体检测是强大的深度学习算法中的一个分支。在本文中,我们将深入探讨可以用于对象检测的各种算法。首先从属于RCNN系列算法开始,即RCNN、 Fast RCNN和 Faster RCNN。在之后的文章中,将介绍更多高级算法,如YOLO、SSD等。1.解决对象检测任务的简单方法(使用深度学习)下图说明了对象检测算法是如何工作。图像中的每个对象,从人到风筝都以一定的精度进行了定位和识别。下面从最简单的深度学习方法开始,一种广泛用于检测图像中的方法——卷积神经网络(CNN)。如果读者对CNN算法有点生疏,建议阅读此文。这里仅简要总结一下CNN的内部运作方式:首先将图像作为输入传递到网络,然后通过各种卷积和池化层处理,最后以对象类别的形式获得输出。对于每个输入图像,会得到一个相应的类别作为输出。因此可以使用这种技术来检测图像中的各种对象。1.首先,将图像作为输入;2.然后,将图像分成不同的区域;3.然后,将每个区域视为单独的图像;4.将所有这些区域传递给CNN并将它们分类为各种类别;5.一旦将每个区域划分为相应的类后,就可以组合所有这些区域来获取具有检测到的对象的原始图像:使用这种方法会面临的问题在于,图像中的对象可以具有不同的宽高比和空间位置。例如,在某些情况下,对象可能覆盖了大部分图像,而在其他情况下,对象可能只覆盖图像的一小部分,并且对象的形状也可能不同。基于此,需要划分大量的区域,这会花费大量的计算时间。因此,为了解决这个问题并减少区域数量,可以使用基于区域的CNN,它使用提议方法选择区域。2.基于区域的卷积神经网络2.1 RCNN的思想RCNN算法不是在大量区域上工作,而是在图像中提出了一堆方框,并检查这些方框中是否包含任何对象。RCNN 使用选择性搜索从图像中提取这些框。下面介绍选择性搜索以及它如何识别不同的区域。基本上四个区域形成一个对象:不同的比例、颜色、纹理和形状。选择性搜索在图像中识别这些模式,并基于此提出各种区域。以下是选择性搜索如何工作的简要概述:首先, 将图像作为输入:然后,它生成初始子分段,以便获得多个区域:之后,该技术组合相似区域以形成更大的区域(基于颜色相似性、纹理相似性、尺寸相似性和形状兼容性):最后,这些区域产生最终的对象位置(感兴趣的区域);下面是RCNN检测对象所遵循的步骤的简要总结:1.首先采用预先训练的卷积神经网络;2.重新训练该模型模型——根据需要检测的类别数量来训练网络的最后一层(迁移学习);3.第三步是获取每个图像的感兴趣区域。然后,对这些区域调整尺寸,以便其可以匹配CNN输入大小;4.获取区域后,使用SVM算法对对象和背景进行分类。对于每个类,都训练一个二分类SVM;最后,训练线性回归模型,为图像中每个识别出的对象生成更严格的边界框;[对上述步骤进行图解分析](http://www.robots.ox.ac.uk/~tvg/publications/talks/Fast-rcnn-slides.pdf):首先,将图像作为输入:然后,使用一些提议方法获得感兴趣区域(ROI)(例如,选择性搜索):之后,对所有这些区域调整尺寸,并将每个区域传递给卷积神经网络:然后,CNN为每个区域提取特征,SVM用于将这些区域划分为不同的类别:最后,边界框回归(Bbox reg)用于预测每个已识别区域的边界框:以上就是RCNN检测物体的全部流程。2.2 RCNN的问题从上节内容可以了解到RCNN是如何进行对象检测的,但这种技术有其自身的局限性。以下原因使得训练RCNN模型既昂贵又缓慢:基于选择性搜索算法为每个图像提取2,000个候选区域;使用CNN为每个图像区域提取特征;RCNN整个物体检测过程用到三种模型:CNN模型用于特征提取;线性svm分类器用于识别对象的的类别;回归模型用于收紧边界框;这些过程相结合使得RCNN非常慢,对每个新图像进行预测需要大约40-50秒,这实际上使得模型在面对巨大的数据集时变得复杂且几乎不可能应用。好消息是存在另一种物体检测技术,它解决了RCNN中大部分问题。3.了解Fast RCNN3.1Fast RCNN的思想RCNN的提出者Ross Girshick提出了这样的想法,即每个图像只运行一次CNN,然后找到一种在2,000个区域内共享该计算的方法。在Fast RCNN中,将输入图像馈送到CNN,CNN生成卷积特征映射。使用这些特征图提取候选区域。然后,使用RoI池化层将所有建议的区域重新整形为固定大小,以便将其馈送到全连接网络中。下面将其分解为简化概念的步骤:1.首先将图像作为输入;2.将图像传递给卷积神经网络,生成感兴趣的区域;3.在所有的感兴趣的区域上应用RoI池化层,并调整区域的尺寸。然后,每个区域被传递到全连接层的网络中;4.softmax层用于全连接网以输出类别。与softmax层一起,也并行使用线性回归层,以输出预测类的边界框坐标。因此,Fast RCNN算法中没有使用三个不同的模型,而使用单个模型从区域中提取特征,将它们分成不同的类,并同时返回所标识类的边界框。对上述过程进行可视化讲解:将图像作为输入:将图像传递给卷积神经网络t,后者相应地返回感兴趣的区域:然后,在提取的感兴趣区域上应用RoI池层,以确保所有区域具有相同的大小:最后,这些区域被传递到一个全连接网络,对其进行分类,并同时使用softmax和线性回归层返回边界框:上述过程说明了Fast RCNN是如何解决RCNN的两个主要问题,即将每个图像中的1个而不是2,000个区域传递给卷积神经网络,并使用一个模型来实现提取特征、分类和生成边界框。3.2Fast RCNN的问题Fast RCNN也存在一定的问题,它仍然使用选择性搜索作为查找感兴趣区域的提议方法,这是一个缓慢且耗时的过程,每个图像检测对象大约需要2秒钟。因此,又开发了另一种物体检测算法——Faster RCNN。4.了解Faster RCNN4.1. Faster RCNN的思想Faster RCNN是Fast RCNN的修改版本,二者之间的主要区别在于,Fast RCNN使用选择性搜索来生成感兴趣区域,而Faster RCNN使用“区域提议网络”,即RPN。RPN将图像特征映射作为输入,并生成一组提议对象,每个对象提议都以对象分数作为输出。以下步骤通常采用Faster RCNN方法:1.将图像作为输入并将其传递给卷积神经网络,后者返回该图像的特征图;2.在这些特征图上应用RPN,返回提议对象及其分数;3.在这些提议对象上应用RoI池层,以将所有提案降低到相同的大小;4.最后,将提议传递到全连接层,该层在其顶部具有softmax层和线性回归层,以对对象的边界框进行分类和输出;这里简要解释一下RPN是如何运作的:首先,Faster RCNN从CNN获取特征图并将它们传递到区域提议网络。RPN在这些特征图上使用滑动窗口,每个窗口生成不同形状和大小的k个方框( Anchor boxe):方框是固定尺寸的边界箱,具有不同的形状和尺寸。对于每个方框,RPN预测两件事:预测锚是对象的概率;用于边界框回归器调整锚点以更好地适合物体的形状;在有了不同形状和大小的边界框后,将其传递到RoI池层。对每个提案并对其进行裁剪,以便每个提案都包含一个对象。这就是RoI池层所做的事情,它为每个方框提取固定大小的特征图:然后将这些特征图传递到全连接层,该层具有softmax和线性回归层,最终对对象进行分类并预测已识别对象的边界框。4.2Faster RCNN的问题上述讨论过的所有对象检测算法都使用区域来识别对象,且网络不会一次查看完整图像,而是按顺序关注图像的某些部分,这样会带来两个复杂性的问题:该算法需要多次通过单个图像来提取到所有对象;由于不是端到端的算法,不同的系统一个接一个地工作,整体系统的性能进一步取决于先前系统的表现效果。5.总结下表是总结了本文中介绍的所有算法算法特征预测时间限制CNN将图像分成多个区域,将每个区域分类为不同的类别-需要很多区域来准确预测,因此计算时间长RCNN使用选择性搜索生成区域,从每个图像中提取大约2000个区域40-50秒每个区域分别传递给CNN的计算时间也很长,且使用三种不同的模型进行预测Fast RCNN每个图像只传递一次到CNN,并提取特征图。在这些地图上使用选择性搜索来生成预测。将RCNN中使用的所有三种模型组合在一起2秒选择性搜索很慢,因此计算时间仍然很长Faster RCNN用区域提议网络替换选择性搜索方法,使算法更快0.2秒对象提议需要时间,并且由于不同的系统一个接一个地工作,系统的性能取决于先前系统的表现效果本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 14, 2018 · 1 min · jiezi

对象检测(object detection)算法图解

摘要: 本文简要介绍图像检测中常用的深度学习方法——RCNN家族系列算法,以图像讲解形式,便于理解。在生活中,经常会遇到这样的一种情况,上班要出门的时候,突然找不到一件东西了,比如钥匙、手机或者手表等。这个时候一般在房间翻一遍各个角落来寻找不见的物品,最后突然一拍大脑,想到在某一个地方,在整个过程中有时候是很着急的,并且越着急越找不到,真是令人沮丧。但是,如果一个简单的计算机算法可以在几毫秒内就找到你要找的物品,你的感受如何?是不是很惊奇!这就是对象检测算法(object detection)的力量。虽然上述举的生活例子只是一个很简单的例子,但对象检测的应用范围很广,跨越多个不同的行业,从全天候监控到智能城市的实时车辆检测等。简而言之,物体检测是强大的深度学习算法中的一个分支。在本文中,我们将深入探讨可以用于对象检测的各种算法。首先从属于RCNN系列算法开始,即RCNN、 Fast RCNN和 Faster RCNN。在之后的文章中,将介绍更多高级算法,如YOLO、SSD等。1.解决对象检测任务的简单方法(使用深度学习)下图说明了对象检测算法是如何工作。图像中的每个对象,从人到风筝都以一定的精度进行了定位和识别。下面从最简单的深度学习方法开始,一种广泛用于检测图像中的方法——卷积神经网络(CNN)。如果读者对CNN算法有点生疏,建议阅读此文。这里仅简要总结一下CNN的内部运作方式:首先将图像作为输入传递到网络,然后通过各种卷积和池化层处理,最后以对象类别的形式获得输出。对于每个输入图像,会得到一个相应的类别作为输出。因此可以使用这种技术来检测图像中的各种对象。1.首先,将图像作为输入;2.然后,将图像分成不同的区域;3.然后,将每个区域视为单独的图像;4.将所有这些区域传递给CNN并将它们分类为各种类别;5.一旦将每个区域划分为相应的类后,就可以组合所有这些区域来获取具有检测到的对象的原始图像:使用这种方法会面临的问题在于,图像中的对象可以具有不同的宽高比和空间位置。例如,在某些情况下,对象可能覆盖了大部分图像,而在其他情况下,对象可能只覆盖图像的一小部分,并且对象的形状也可能不同。基于此,需要划分大量的区域,这会花费大量的计算时间。因此,为了解决这个问题并减少区域数量,可以使用基于区域的CNN,它使用提议方法选择区域。2.基于区域的卷积神经网络2.1 RCNN的思想RCNN算法不是在大量区域上工作,而是在图像中提出了一堆方框,并检查这些方框中是否包含任何对象。RCNN 使用选择性搜索从图像中提取这些框。下面介绍选择性搜索以及它如何识别不同的区域。基本上四个区域形成一个对象:不同的比例、颜色、纹理和形状。选择性搜索在图像中识别这些模式,并基于此提出各种区域。以下是选择性搜索如何工作的简要概述:首先, 将图像作为输入:然后,它生成初始子分段,以便获得多个区域:之后,该技术组合相似区域以形成更大的区域(基于颜色相似性、纹理相似性、尺寸相似性和形状兼容性):最后,这些区域产生最终的对象位置(感兴趣的区域);下面是RCNN检测对象所遵循的步骤的简要总结:1.首先采用预先训练的卷积神经网络;2.重新训练该模型模型——根据需要检测的类别数量来训练网络的最后一层(迁移学习);3.第三步是获取每个图像的感兴趣区域。然后,对这些区域调整尺寸,以便其可以匹配CNN输入大小;4.获取区域后,使用SVM算法对对象和背景进行分类。对于每个类,都训练一个二分类SVM;最后,训练线性回归模型,为图像中每个识别出的对象生成更严格的边界框;[对上述步骤进行图解分析](http://www.robots.ox.ac.uk/~tvg/publications/talks/Fast-rcnn-slides.pdf):首先,将图像作为输入:然后,使用一些提议方法获得感兴趣区域(ROI)(例如,选择性搜索):之后,对所有这些区域调整尺寸,并将每个区域传递给卷积神经网络:然后,CNN为每个区域提取特征,SVM用于将这些区域划分为不同的类别:最后,边界框回归(Bbox reg)用于预测每个已识别区域的边界框:以上就是RCNN检测物体的全部流程。2.2 RCNN的问题从上节内容可以了解到RCNN是如何进行对象检测的,但这种技术有其自身的局限性。以下原因使得训练RCNN模型既昂贵又缓慢:基于选择性搜索算法为每个图像提取2,000个候选区域;使用CNN为每个图像区域提取特征;RCNN整个物体检测过程用到三种模型:CNN模型用于特征提取;线性svm分类器用于识别对象的的类别;回归模型用于收紧边界框;这些过程相结合使得RCNN非常慢,对每个新图像进行预测需要大约40-50秒,这实际上使得模型在面对巨大的数据集时变得复杂且几乎不可能应用。好消息是存在另一种物体检测技术,它解决了RCNN中大部分问题。3.了解Fast RCNN3.1Fast RCNN的思想RCNN的提出者Ross Girshick提出了这样的想法,即每个图像只运行一次CNN,然后找到一种在2,000个区域内共享该计算的方法。在Fast RCNN中,将输入图像馈送到CNN,CNN生成卷积特征映射。使用这些特征图提取候选区域。然后,使用RoI池化层将所有建议的区域重新整形为固定大小,以便将其馈送到全连接网络中。下面将其分解为简化概念的步骤:1.首先将图像作为输入;2.将图像传递给卷积神经网络,生成感兴趣的区域;3.在所有的感兴趣的区域上应用RoI池化层,并调整区域的尺寸。然后,每个区域被传递到全连接层的网络中;4.softmax层用于全连接网以输出类别。与softmax层一起,也并行使用线性回归层,以输出预测类的边界框坐标。因此,Fast RCNN算法中没有使用三个不同的模型,而使用单个模型从区域中提取特征,将它们分成不同的类,并同时返回所标识类的边界框。对上述过程进行可视化讲解:将图像作为输入:将图像传递给卷积神经网络t,后者相应地返回感兴趣的区域:然后,在提取的感兴趣区域上应用RoI池层,以确保所有区域具有相同的大小:最后,这些区域被传递到一个全连接网络,对其进行分类,并同时使用softmax和线性回归层返回边界框:上述过程说明了Fast RCNN是如何解决RCNN的两个主要问题,即将每个图像中的1个而不是2,000个区域传递给卷积神经网络,并使用一个模型来实现提取特征、分类和生成边界框。3.2Fast RCNN的问题Fast RCNN也存在一定的问题,它仍然使用选择性搜索作为查找感兴趣区域的提议方法,这是一个缓慢且耗时的过程,每个图像检测对象大约需要2秒钟。因此,又开发了另一种物体检测算法——Faster RCNN。4.了解Faster RCNN4.1. Faster RCNN的思想Faster RCNN是Fast RCNN的修改版本,二者之间的主要区别在于,Fast RCNN使用选择性搜索来生成感兴趣区域,而Faster RCNN使用“区域提议网络”,即RPN。RPN将图像特征映射作为输入,并生成一组提议对象,每个对象提议都以对象分数作为输出。以下步骤通常采用Faster RCNN方法:1.将图像作为输入并将其传递给卷积神经网络,后者返回该图像的特征图;2.在这些特征图上应用RPN,返回提议对象及其分数;3.在这些提议对象上应用RoI池层,以将所有提案降低到相同的大小;4.最后,将提议传递到全连接层,该层在其顶部具有softmax层和线性回归层,以对对象的边界框进行分类和输出;这里简要解释一下RPN是如何运作的:首先,Faster RCNN从CNN获取特征图并将它们传递到区域提议网络。RPN在这些特征图上使用滑动窗口,每个窗口生成不同形状和大小的k个方框( Anchor boxe):方框是固定尺寸的边界箱,具有不同的形状和尺寸。对于每个方框,RPN预测两件事:预测锚是对象的概率;用于边界框回归器调整锚点以更好地适合物体的形状;在有了不同形状和大小的边界框后,将其传递到RoI池层。对每个提案并对其进行裁剪,以便每个提案都包含一个对象。这就是RoI池层所做的事情,它为每个方框提取固定大小的特征图:然后将这些特征图传递到全连接层,该层具有softmax和线性回归层,最终对对象进行分类并预测已识别对象的边界框。4.2Faster RCNN的问题上述讨论过的所有对象检测算法都使用区域来识别对象,且网络不会一次查看完整图像,而是按顺序关注图像的某些部分,这样会带来两个复杂性的问题:该算法需要多次通过单个图像来提取到所有对象;由于不是端到端的算法,不同的系统一个接一个地工作,整体系统的性能进一步取决于先前系统的表现效果。5.总结下表是总结了本文中介绍的所有算法算法特征预测时间限制CNN将图像分成多个区域,将每个区域分类为不同的类别-需要很多区域来准确预测,因此计算时间长RCNN使用选择性搜索生成区域,从每个图像中提取大约2000个区域40-50秒每个区域分别传递给CNN的计算时间也很长,且使用三种不同的模型进行预测Fast RCNN每个图像只传递一次到CNN,并提取特征图。在这些地图上使用选择性搜索来生成预测。将RCNN中使用的所有三种模型组合在一起2秒选择性搜索很慢,因此计算时间仍然很长Faster RCNN用区域提议网络替换选择性搜索方法,使算法更快0.2秒对象提议需要时间,并且由于不同的系统一个接一个地工作,系统的性能取决于先前系统的表现效果本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 12, 2018 · 1 min · jiezi

深度学习实现自动生成图片字幕

介绍本次项目使用深度学习自动生成图像字幕。如上图,模型自动生成“The person is riding a surfboard in the ocean”字幕。我们具体该如何实现呢?如图所示,我们需要分别使用CNN和RNN模型来实现。CNN模型:利用卷积网络对图像特征提取的强大能力,来提取特征信息。我们的CNN模型需要有强大的识别能力,因此该模型需要使用过大量,多类别的训练集进行训练,并且识别准确率较高。本次,我们利用迁移学习使用Inception模型实现此功能。通过迁移学习实现OCT图像识别 文章中有迁移学习的相关介绍。RNN模型:对于文本序列数据,目前我们最好的选择依然是RNN模型。为了提升模型预测能力,我们使用注意力机制实现文本预测。注意力机制实现机器翻译 文章中有注意力机制的相关介绍。对模型的细节要求我们将在对应代码实现里进行介绍。数据集介绍我们使用MS-COCO数据集进行训练,为方便理解,简单介绍下数据格式。COCO数据有5种类型,分别是: object detection, keypoint detection, stuff segmentation, panoptic segmentation,image captioning。基础数据结构如下图所示:具体样例(部分):本次项目使用的是Image Captioning其中,每张照片不少于5个字幕:数据下载处理import tensorflow as tf# 开启eager模式tf.enable_eager_execution()import matplotlib.pyplot as pltfrom sklearn.model_selection import train_test_splitfrom sklearn.utils import shuffleimport reimport numpy as npimport osimport timeimport jsonfrom glob import globfrom PIL import Imageimport pickleannotation_zip=tf.keras.utils.get_file( # cache_dir(默认值): ~/.keras # cache_subdir: datasets, # /.keras/datasets/captions.zip fname=‘captions.zip’, cache_subdir=os.path.abspath(’.’), origin=‘http://images.cocodataset.org/annotations/annotations_trainval2014.zip', # 解压 extract=True)# 返回文件夹名,实现:split(file)[0]annotation_file = os.path.dirname(annotation_zip)+’/annotations/captions_train2014.json’name_of_zip=‘train2014.zip’if not os.path.exists(os.path.abspath(’.’)+"/"+name_of_zip): image_zip=tf.keras.utils.get_file( fname=name_of_zip, cache_subdir=os.path.abspath(’.’), origin=‘http://images.cocodataset.org/zips/train2014.zip', extract=True ) PATH=os.path.dirname(image_zip)+‘train2014/’else: PATH=os.path.abspath(’.’)+’/train2014/‘读取字幕和图片:# 读取注释json文件with open(annotation_file,‘r’) as f: annotations=json.load(f)# 保存全部字幕all_captions=[]# 保存全部图片all_img_name_vecotr=[]# json格式参考COCO数据集官网for annot in annotations[‘annotations’]: # 添加开始和结束标记 caption=’<start>’+annot[‘caption’]+’<end>’ # 获取图片名字 image_id=annot[‘image_id’] # 参考文章开始给出的“具体样例” full_coco_image_path=PATH+‘COCO_train2014_’+’%012d.jpg’%(image_id) all_img_name_vecotr.append(full_coco_image_path) all_captions.append(caption)# random_state 随机种子,确保每次数据一致train_captions,img_name_vector=shuffle( all_captions, all_img_name_vecotr, random_state=1 ) # 使用训练集前30000样本 num_examples=30000 train_captions=train_captions[:num_examples] img_name_vector=img_name_vector[:num_examples]重训练InceptionV3:简单介绍下InceptionV3模型:Inception模型结构中最重要的思想就是卷积核分解。通过上图可知,5x5的卷积可由2个3x3的卷积代替,3x3卷积可由一个3x1卷积和一个1x3卷积代替,代替的好处是减少了权重参数量,增加了网络非线性(层增多)。比如,一个5x5卷积的权重参数量和2个3x3卷积的权重参数量分别是(5x5):(3x3)x2。InceptionV3中就将7x7的卷积分解成7x1卷积和1x7卷积。批标准化(BN)正式提出是在InceptionV2,BN通过将输入分布转变成均值为0,标准差为1的正态分布,将值域处于激活函数敏感范围从而防止梯度消失问题。正因为梯度消失问题的解决,我们可以使用更大的学习率进行训练从而加快模型收敛。由于BN有类似Dropout的正则化作用,因此在训练的时候不使用或少使用Dropout,并减轻L2正则。使用非对称卷积,如:1x3卷积,3x1卷积(论文作者指出在feature map的大小12x1220x20之间效果最好)。使用Label Smoothing对损失修正。下图是新损失函数:网络各层信息如下图所示:# 使用inception V3 要求图片分辨率:299,299# 输入值范围[-1,1]def load_image(image_path): img=tf.image.decode_jpeg(tf.read_file(image_path)) img_reshape=tf.image.resize_images(img,(299,299)) # 像素范围[-1,1] # (-255)/255 img_range=tf.keras.applications.inception_v3.preprocess_input(img_reshape) return img_range,image_path使用迁移学习构建新模型:# 最后一层卷积输入shape(882048),并将结果向量保存为dictimage_model=tf.keras.applications.InceptionV3( # 不使用最后全连接层 include_top=False, # inception模型的训练集是imagenet weigths=‘imagenet’)# shape:(batch_size,299,299,3)new_input=image_model.input# hidden_layer shape:(batch_size,8,8,2048)hidden_layer=image_model.layers[-1].output# 创建新模型image_features_extract_model=tf.keras.Model( new_input, hidden_layer)保存通过使用InceptionV3获得的特征:encode_train=sorted(set(img_name_vector))# map:可以并行处理数据,默认读取的文件具有确定性顺序# 取消顺序可以加快数据读取# 通过设置参数num_parallel_calls实现image_dataset=tf.data.Dataset.from_tensor_slices(encode_train).map(load_image).batch(16)for img,path in image_dataset: # inception v3得到的feature batch_features=image_features_extract_model(img) batch_features=tf.reshape( # shape:(batch_size,8,8,2048) reshape:(batch_size,64,2048) batch_features,shape=(batch_features.shape[0],-1,batch_features[3]) )# 保存for bf,p in zip(batch_features,path): path_of_feature=p.numpy().decode(‘utf-8’) # 文件后缀.npy np.save(path_of_feature,bf.numpy())文本处理文本处理方式还是老规矩,先将文本转成字典表示然后创建字符转ID,ID转字符,最后补长到预设长度。# 计算最大长度def calc_max_length(tensor): return max(len(t)for t in tensor)top_k=5000tokenizer=tf.keras.preprocessing.text.Tokenizer( num_words=top_k, # 字典中没有的字符用<unk>代替 oov_token=’<unk>’, # 需要过滤掉的特殊字符 filters=’!"#$%&()+.,-/:;=?@[]^_`{|}~’)# 要用以训练的文本列表tokenizer.fit_on_texts(train_captions)# 转为序列列表向量train_seqs=tokenizer.texts_to_sequences((train_captions))tokenizer.word_index[’<pad>’]=0# 如果没有指定最大长度,pad_sequences会自动计算最大长度cap_vector=tf.keras.preprocessing.sequence.pad_sequences( sequences=train_seqs, # 后置补长 padding=‘post’)max_length=calc_max_length(train_seqs)模型训练参数拆分训练集,验证集:img_name_train,img_name_val,cap_trian,cap_val=train_test_split( img_name_vector, cap_vector, # 验证数据集占20% test_size=0.2, # 确保每次数据一致 random_state=0# 最好是2的次幂,更适合GPU运算(加快二进制运算)BATCH_SIZE=64# shuffle 缓冲区大小BUFFER_SIZE=1000# 词嵌入维度embedding_dim=256units=512vocab_size=len(tokenizer.word_index)# 后面会将(8,8,2048)转为(64,2048)# 维度一定要一致feature_shape=2048attention_features_shape=64# 加载保存的之前feature文件def map_func(img_name,cap): img_tensor=np.load(img_name.decode(‘utf-8’)+’.npy’) return img_tensor,capdataset=tf.data.Dataset.from_tensor_slices((img_name_train,cap_trian))# num_parallel_calls 根据自己的CPU而定dataset=dataset.map(lambda item1,item2:tf.py_func( map_func,[item1,item2],[tf.float32,tf.int32]),num_parallel_calls=4)# prefetch 可以合理利用CPU准备数据,GPU计算数据之间的空闲时间,加快数据读取dataset=dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(1)创建模型编码器模型:# 一层使用relu的全连接层class CNN_Encoder(tf.keras.Model): def init(self,embedding_dim): super(CNN_Encoder, self).init() # fc shape:(batch_size,64,embedding_dim) self.fc=tf.keras.layers.Dense(embedding_dim) def call(self,x): x=self.fc(x) x=tf.nn.relu(x) return x注意力层:详细介绍可以查看文章开始给出的链接,这里给出计算方程式:class BahdanauAttention(tf.keras.Model): def init(self,units): super(BahdanauAttention, self).init() self.W1=tf.keras.layers.Dense(units) self.W2=tf.keras.layers.Dense(units) self.V=tf.keras.layers.Dense(1) def call(self, features,hidden): # 参考注意力机制计算的方程 # feature shape:(batch_size,64,embedding_dim) # hidden_state shape:(batch_size,hidden_size) hidden_with_time_axis=tf.expand_dims(hidden,1) # score shape:(batch_size,64,hidden_size) score=tf.nn.tanh(self.W1(features)+self.W2(hidden_with_time_axis)) # attention_weights shape:(batch_size,64,1) attention_weights=tf.nn.softmax(self.V(score),axis=1) context_vector=tf.reduce_sum(attention_weightsfeatures,axis=1) return context_vector,attention_weights解码器中的GRU:# 相比LSTM因为减少了一个门,参数少,收敛快def gru(units): if tf.test.is_gpu_available(): # 使用GPU加速计算 return tf.keras.layers.CuDNNGRU( units=units, return_state=True, return_sequences=True, # 循环核的初始化方法 # glorot_uniform是sqrt(2 / (fan_in + fan_out))的正态分布产生 # 其中fan_in和fan_out是权重张量的扇入扇出(即输入和输出单元数目) recurrent_initializer=‘glorot_uniform’ ) else: return tf.keras.layers.GRU( return_sequences=True, return_state=True, # 默认:hard_sigmoid <= -1 输出0,>=1 输出1 ,中间为线性 recurrent_activation=‘sigmoid’, recurrent_initializer=‘glorot_uniform’ )解码器模型:# 使用注意力模型class RNN_Decoder(tf.keras.Model): def init(self,embedding_dim,units,vocab_size): super(RNN_Decoder, self).init() self.units=units # 词嵌入将高维离散数据转为低维连续数据,并表现出数据之间的相似性(向量空间) self.embedding=tf.keras.layers.Embedding(input_shape=vocab_size,output_dim=embedding_dim) self.gru=gru(units) self.fc1=tf.keras.layers.Dense(self.units) self.fc2=tf.keras.layers.Dense(vocab_size) self.attention=BahdanauAttention(self.units) def call(self,x,features,hidden): # 获取注意力模型输出 context_vector,attention_weights=self.attention(features,hidden) # x shape:(batch_size,1,embedding_dim) x=self.embedding(x) # 注意力,当前输入合并 # 注意力shape:(batch_size,1,hidden) x shape:(batch_size,1,embedding_size) # x shape:(batch_size, 1, embedding_dim + hidden_size) x=tf.concat([tf.expand_dims(context_vector,1),x],axis=-1) output,state=self.gru(x) # x shape:(batch_size,max_length,hidden_size) x=self.fc1(output) # x shape:(batch_sizemax_length,hidden_size) x=tf.reshape(x,shape=(-1,x.shape[2])) # x shape:(batch_sizemax_length,vocab_size) x=self.fc2(x) return x,state,attention_weights def reset_state(self, batch_size): return tf.zeros((batch_size, self.units))模型训练实例化模型:encoder = CNN_Encoder(embedding_dim)decoder = RNN_Decoder(embedding_dim, units, vocab_size)损失函数,优化器设置:# InceptionV3模型使用的不是Adam优化器# 各种优化器以后放到一篇单独的文章详细介绍optimizer=tf.train.AdamOptimizer(learning_rate=0.0001)def loss_function(real,pred): mask=1-np.equal(real,0) # 带mask的交叉熵损失 loss_=tf.nn.sparse_softmax_cross_entropy_with_logits( labels=real, logits=pred )*mask return tf.reduce_mean(loss_)训练:将使用InceptionV3模型提取的特征作为编码器输入编码器输出,hidden_state,字幕文本作为解码器输入解码器hidden_state作为下一次输入,预测值用于计算模型损失使用标签文本作为解码器输入(teacher-forcing模式)梯度计算及应用loss_plot=[]EPOCHS=20for epoch in range(EPOCHS): start=time.time() total_loss=0 for (batch,(img_tensor,target)) in enumerate(dataset): loss=0 # 每迭代一次batch后重置 hidden_state hidden=decoder.reset_states(batch_size=target.shape[0]) # input维度是3维 dec_input=tf.expand_dims([tokenizer.word_index[’<start>’]*BATCH_SIZE],1) # eager模式下记录梯度 with tf.GradientTape() as tape: # inception模式提取的特征 features=encoder(img_tensor) # 每张照片不止一个captions for i in range(1,target.shape[1]): # attention_weights此处暂不需要 predictions,hidden,_=decoder(dec_input,features,hidden) loss+=loss_function(target[:,i],predictions) # teacher forcing 使用标签数据作为输入替代hidden-output dec_input=tf.expand_dims(target[:,i],1) total_loss+=(loss/int(target.shape[1])) # 总训练参数 variables=encoder.variables+decoder.variables # 梯度计算及应用 gradients=tape.gradient(loss,variables) optimizer.apply_gradients(zip(gradients,variables)) if batch%100 == 0: print(’epoch{},batch{},loss{:.4}’.format( epoch+1, batch, loss.numpy()/int(target.shape[1]) )) loss_plot.append(total_loss/len(cap_vector))plt.plot(loss_plot)plt.xlabel(’epochs’)plt.ylabel(’loss’)plt.show()模型预测模型预测不使用Teacher forcing模式,当遇到预设的结束标记“<end>”时模型结束训练。def evaluate(image): attention_plot = np.zeros((max_length, attention_features_shape)) # 初始化hidden-state hidden = decoder.reset_state(batch_size=1) # shape:(1,299,299,3) temp_input = tf.expand_dims(load_image(image)[0], 0) # 特征提取 img_tensor_val = image_features_extract_model(temp_input) # shape:(1,8,8,2048) reshape:(1,64,2048) img_tensor_val = tf.reshape(img_tensor_val, (img_tensor_val.shape[0], -1, img_tensor_val.shape[3])) # shape:(1,64,256) features = encoder(img_tensor_val) # 增加batchsize维度 dec_input = tf.expand_dims([tokenizer.word_index[’<start>’]], 0) result = [] for i in range(max_length): predictions, hidden, attention_weights = decoder(dec_input, features, hidden) attention_plot[i] = tf.reshape(attention_weights, (-1, )).numpy() # 我们使用softmax归一化结果,使用argmax查询最大值 # 对于分类数量大于2,softmax和sigmoid的区别是 # 类别之间有相互关系的使用sigmoid,反之使用softmax predicted_id = tf.argmax(predictions[0]).numpy() # ID转字符,获取文本结果 result.append(tokenizer.index_word[predicted_id]) # 判断是否是预设的结束标记 if tokenizer.index_word[predicted_id] == ‘<end>’: return result, attention_plot # 将预测值作为输入,预测下一个结果(teacher-forcing在这里使用数据标签作为输入) dec_input = tf.expand_dims([predicted_id], 0) attention_plot = attention_plot[:len(result), :] return result, attention_plot以下用于可视化注意力机制训练过程:此处代码主要是图像展示就不做过多介绍了。def plot_attention(image, result, attention_plot): temp_image = np.array(Image.open(image)) fig = plt.figure(figsize=(10, 10)) len_result = len(result) for l in range(len_result): temp_att = np.resize(attention_plot[l], (8, 8)) ax = fig.add_subplot(len_result//2, len_result//2, l+1) ax.set_title(result[l]) img = ax.imshow(temp_image) ax.imshow(temp_att, cmap=‘gray’, alpha=0.6, extent=img.get_extent()) plt.tight_layout() plt.show()rid = np.random.randint(0, len(img_name_val))image = img_name_val[rid]real_caption = ’ ‘.join([tokenizer.index_word[i] for i in cap_val[rid] if i not in [0]])result, attention_plot = evaluate(image)print (‘Real Caption:’, real_caption)print (‘Prediction Caption:’, ’ ‘.join(result))plot_attention(image, result, attention_plot)Image.open(img_name_val[rid])总结想要对图像生成字幕,首先需要提取图像特征,本文我们利用迁移学习使用Inception模型来提取特征,对于Inception模型,我们重点理解卷积核分解。至于文本预测部分与使用注意力机制实现机器翻译大体一致。有一点想说的是,类似这样的项目维度转换会比较多,也是很容易出错的地方,这一点需要格外留意。本文代码内容来自 Yash Katariya在此表示感谢。 ...

December 11, 2018 · 3 min · jiezi

将神经网络训练成一个“放大镜”

摘要: 想不想将神经网络训练成一个“放大镜”?我们就训练了一个这样炫酷的神经网络,点击文章一起看下吧!当我们网购时,我们肯定希望有一个贴近现实的购物体验,也就是说能够全方位的看清楚产品的细节。而分辨率高的大图像能够对商品进行更加详细的介绍,这真的可以改变顾客的购物体验,让顾客有个特别棒的购物之旅。idealo.de是欧洲领先的比价网站,也是德国电子商务市场最大的门户网站之一,在此基础上,我们希望能够在此基础上为用户提供一个用户友好、有吸引力的购物平台。在这里,我们利用深度学习来评估数百万酒店图像的美学层次和技术质量,另外,那些没有任何信息的、特别难看的小的产品图像对我们来说是无效的,因此需要想办法解决。购物网站上并不是所有的商店都能为顾客提供高质量的图像,相反,商家提供的图像特别小、分辨率特别低、质量也很低。为了向用户展示高质量的高分辨率图像,我们基于2018年的论文《图像超分辨率的RDN网络》,训练了一个特别先进的卷积神经网络。我们的目标很简单:拍摄一些特别小的图像,然后就像使用放大镜一样,对图像进行放大,并且还要保持高分辨率。本文对实现这一目标做了详细介绍,另外,具体实现的细节,请查看GitHub。总概与大多数深度学习项目一样,我们的深度学习项目主要有四个步骤:1.回顾前人对该项目所做的贡献。2.实施一个或多个解决方案,然后比较预先训练的版本。3.获取数据,训练并测试模型。4.针对训练和验证结果对模型进行改进和优化。具体来说,本文主要有以下几方面的内容:1.介绍模型训练的配置,如何评估模型的性能2. 查看早期训练和测试结果,了解从哪方面进行改进。3.指出后续需要探索的方向。训练与以往“标准”的监督深度学习任务不同,我们这个“放大镜”深度学习模型输出的不仅仅是类标签或一个分数,而是一整幅图像。这就意味着训练过程以及评估会跟以往略有不同,我们要输出的是原始高分辨率图像,为了更好的对模型进行评估,我们需要一种测量缩放输出图像“质量”的方法,该方法更详细的优缺点将在后面进一步做详细阐释。损失函数损失函数是用来评估神经网络的性能究竟如何,这个有很多方法可以评估。这个问题的本质为大家留下了创造力空间,如有些聪明的人会用高级特征和对抗网络。对于第一次迭代,我们使用标准方法:网络的超分辨率(SR)输出和高分辨率输出(HR)之间的像素均方差(MSE)。评估我们用峰值信噪比(PSNR)来评估输出图像的质量,峰值信噪比是基于两个图像之间的像素均方差(MSE)。由于峰值信噪比是最常用的评估输出图像质量的方法,因此我们也使用这一评估标准,以便将本文模型与其他模型作比较。开始我们在p2.xlarge AWS EC2实例上进行训练,直到验证损失函数收敛,训练结束,这大概需要90个周期(一个周期24小时),然后使用Tensorboard跟踪训练数据集及验证数据集的损失函数和PSNR值。如上图所示,左上角为在每个周期结束时,反向传播到神经网络上的训练损失函数。右上角为跟踪泛化性能的非训练数据及的损失。左下角为训练数据集的PSNR值。右下角为验证数据集的PSNR值。结果输出的结果如下所示,我们先看看模型的输出结果,再考虑如何对该模型进行改进。左侧是验证数据集中的整个图像,中间是卷积神经网络的输出提取图像块,右侧是使用标准过程将中间输出提取图像块按比例放大后的输出,这里使用了GIMP的图像缩放功能![LR图像(左),重建SR(中),GIMP基线缩放(右)。](https://upload-images.jianshu…这个结果肯定不是特别完美:蝴蝶的天线周围有些没必要的噪声,蝴蝶的颈部和背部的毛发及翅膀上有些斑点轮廓,神经网络的输出图像(中)看起来要比GIMP基线输出图像(右)更加清晰。结果分析为了进一步理解模型有哪些优缺点,我们需要从验证数据集中提取具有高PSNR值的图像块和具有低能量度值的图像块。不出所料,性能最佳的图像块是具有较多平坦区域的图像块,而较为复杂的图像块难以准确再现。因此,我们重点关注这些较复杂的图像块,以便对结果进行训练和评估。同样的,我们也可以使用热图(heatmap)突出显示原始HR图像和神经网络输出SR图像之间的误差,颜色较暗的部分对应于较高的像素均方误差(较差的结果),颜色较浅的部分对应于较低的像素均方误差(或较好的结果)我们可以看到,具有多种模式的区域的误差会更大,但是看起来“更简单”的过渡区域则是相当黑暗的(例如云、天空),这是可以改进的,因为它与idealo的目录用例相关。浅谈深度学习任务中的非真实数据与常见的分类问题或输出为一个分值的监督式深度学习任务不同,我们用于评估神经网络输出的真实数据是原始HR图像。这既有好处,也有坏处。坏处:像Keras这样的当前较为流行的深度学习框架没有预先制定训练解决方案,比如生成器。实际上,它们通常依赖于从一维数组中获取训练和验证标签或文件,或者是直接从文件结构中派生出来的,这会涉及到一些额外的编码算法。好处:没有必要花太多时间来获得标签,给出一个HR图像池,我们可以对其进行简单的缩小,获得我们所需要的LR训练数据,并使用原始HR图像来评估损失函数通常来说,使用图像数据对神经网络进行训练时,需要从训练数据集中随机的选择多个图像来创建训练批次。然后将这些尺寸重新缩小到一个较小的尺寸,一般来说,大小约为100×100像素。我们随时使用随机变换对图像进行增强,并反馈到神经网络中。在这种情况下,没有必要向神经网络反馈整张图像,并且这也非常不可取。这是因为,我们不能将图像重新缩放到100×100的小像素点。毕竟,我们想要对图像进行放大。同时,我们也无法用较大尺寸的图像进行训练,比如大小为500×600像素的图像,因为处理这种大图像需要很长的时间。相反,我们可以从整个图像中提取一个非常小的随机色块,比如大小为16×16像素块,这样一来,我们就有了更多的数据点,因为每个图像都可以提供数百个不同的色块。我们之所以能够处理这种小色块,是因为我们不需要将一堆图像进行分类,比如:腿+尾巴+胡须+死老鼠=猫。因此,模型的末端就没有全连接层。我们只需要使用神经网络来构建这些模式的抽象表示,然后学习如何对其进行放大,除此以外,还要对块进行重新组合,使组合后的图像变得有意义。这种抽象表示由卷积层和放大层来完成,其中,卷积层是该网络中唯一的一种层类型。我们还要说明的是,全卷积结构使该网络的输入大小相互独立。也就是说,这意味着它与普通的分类卷积神经网络有所不同,你可以向完全卷积神经网络中输入任何大小的图像:无论输入图像原始大小是什么,网络都会输入一个输入图像大小2倍的图像。有关图像超分辨率的RDN网络更加详细的介绍,请查看文末链接。另一方面,我们还需要思考如何从图像中提取这些块。思路如下:从数据集中提取出n个随机图像,然后从每个图像中提取p个随机快。我们尝试了几种方法,如下图所示:首先,从一个均匀的网格中提出块,并创建一个完整的块数据集。在训练的时候,我们随机的提取其batch_size,并对其进行放大,反馈给网络。这种方法的缺点是需要静态的存储非常大的数据集,如果要用云服务器进行训练,这种方法其实并不理想:移动和提取数据集是一项相当耗时的操作,并且具有确定性定义的数据集可能并不是最佳数据集。另一种方法是随机选择batch_size大小的图像,并从中提取单个块。这种方法需要从磁盘中读取数据,这就大大降低了训练时间(我们设置的每个训练时间为15min-1h)。最后,我们将原始数据集中随机提取的单个图像块进行融合,并从中提取动态的batch_size块,这不仅能存储原始数据集,同时,也能保持较快的训练速度。拓展这是放大idealo网站产品目录的第一步,我们已经完成了。下面是我们将产品图像中低质量、低分辨率的图像进行放大,并输出。从上图中,我们可以看到,图像中较为平坦的地方会产生较为明显的噪声,文本也会略有失真。这就是我们计划要改进的地方。在下一步的探索中,我们将在自己的产品图像数据集上对神经网络进行训练。相关链接Github: Image Super ResolutionPaper: Residual Dense Network for Image Super-Resolution (Zhang et al. 2018)Dataset: DIVerse 2K resolution high quality images本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 10, 2018 · 1 min · jiezi

【Keras】减少过拟合的秘诀——Dropout正则化

摘要: Dropout正则化是最简单的神经网络正则化方法。阅读完本文,你就学会了在Keras框架中,如何将深度学习神经网络Dropout正则化添加到深度学习神经网络模型里。 Dropout正则化是最简单的神经网络正则化方法。其原理非常简单粗暴:任意丢弃神经网络层中的输入,该层可以是数据样本中的输入变量或来自先前层的激活。它能够模拟具有大量不同网络结构的神经网络,并且反过来使网络中的节点更具有鲁棒性。阅读完本文,你就学会了在Keras框架中,如何将深度学习神经网络Dropout正则化添加到深度学习神经网络模型里,具体内容如下:如何使用Keras API创建Dropout层;如何使用Keras API将Dropout正则化添加到MLP、CNN和RNN层;在现有模型中,如何使用Dropout正则化减少过拟合。Keras中的Dopout正则化在Keras深度学习框架中,我们可以使用Dopout正则化,其最简单的Dopout形式是Dropout核心层。在创建Dopout正则化时,可以将 dropout rate的设为某一固定值,当dropout rate=0.8时,实际上,保留概率为0.2。下面的例子中,dropout rate=0.5。layer = Dropout(0.5)Dropout层将Dropout层添加到模型的现有层和之前的输出层之间,神经网络将这些输出反馈到后续层中。用dense()方法指定两个全连接网络层:…model.append(Dense(32))model.append(Dense(32))…在这两层中间插入一个dropout层,这样一来,第一层的输出将对第二层实现Dropout正则化,后续层与此类似。现在,我们对第二层实现了Dropout正则化。…model.append(Dense(32))model.append(Dropout(0.5))model.append(Dense(32))…Dropout也可用于可见层,如神经网络的输入。在这种情况下,就要把Dropout层作为网络的第一层,并将input_shape参数添加到层中,来制定预期输入。…model.add(Dropout(0.5, input_shape=(2,)))…下面,我们来看看Dropout正则化如何与常见的网络类型一起使用。MLP Dropout正则化在两个全连接层之间添加Dropout正则化,代码如下所示:# example of dropout between fully connected layersfrom keras.layers import Densefrom keras.layers import Dropout…model.add(Dense(32))model.add(Dropout(0.5))model.add(Dense(1))…CNN Dropout正则化我们可以在卷积层和池化层后使用Dropout正则化。一般来说,Dropout仅在池化层后使用。# example of dropout for a CNNfrom keras.layers import Densefrom keras.layers import Conv2Dfrom keras.layers import MaxPooling2Dfrom keras.layers import Dropout…model.add(Conv2D(32, (3,3)))model.add(Conv2D(32, (3,3)))model.add(MaxPooling2D())model.add(Dropout(0.5))model.add(Dense(1))…在这种情况下,我们要将Dropout应用于特征图的每个单元中。在卷积神经网络中使用Dropout正则化的另一个方法是,将卷积层中的整个特征图都丢弃,然后在池化期间也不再使用。这种方法称为空间丢弃,即Spatial Dropout。“我们创建了一个新的Dropout正则化方法,我们将其称为Spatial Dropout。在这个方法中,我们将Dropout值扩展到整个特征映射中。”——《使用卷积神经网络有效的进行对象本地化,2015》在Keras中,通过SpatialDropout2D层提供Spatial Dropout正则化。# example of spatial dropout for a CNNfrom keras.layers import Densefrom keras.layers import Conv2Dfrom keras.layers import MaxPooling2Dfrom keras.layers import SpatialDropout2D…model.add(Conv2D(32, (3,3)))model.add(Conv2D(32, (3,3)))model.add(SpatialDropout2D(0.5))model.add(MaxPooling2D())model.add(Dense(1))…RNN Dropout正则化我们在LSTM循环层和全连接层之间使用Dropout正则化,代码如下所示:# example of dropout between LSTM and fully connected layersfrom keras.layers import Densefrom keras.layers import LSTMfrom keras.layers import Dropout…model.add(LSTM(32))model.add(Dropout(0.5))model.add(Dense(1))…在这里,将Dropout应用于LSTM层的32个输出中,这样,LSTM层就作为全连接层的输入。还有一种方法可以将Dropout与LSTM之类的循环层一起使用。LSTM可以将相同的Dropout掩码用于所有的输入中。这个方法也可用于跨样本时间步长的循环输入连接。这种使用递归模型进行Dropout正则化则称为变分循环神经网络(Variational RNN)。“变分循环神经网络在每个时间步长使用相同的Dropout掩码,包括循环层。这与在RNN中实现Dropout正则化一样,在每个时间步长丢弃相同的神经网络单元,并且随意的丢弃输入、输出和循环连接。这和现有的技术形成对比,在现有的技术中,不同的神经网络单元将在不同的时间步长被丢弃,并且不会对全连接层进行丢弃。”——《循环神经网络中Dropout的基础应用,2016》Keras通过循环层上的两个参数来支持变分神经网络(输入和循环输入样本时间步长的一致性丢弃),这称为 输入“Dropout”和循环输入的“recurrent_dropout”。# example of dropout between LSTM and fully connected layersfrom keras.layers import Densefrom keras.layers import LSTMfrom keras.layers import Dropout…model.add(LSTM(32))model.add(Dropout(0.5))model.add(Dense(1))…Dropout正则化案例在本节中,我们将演示如何使用Dropout正则化来减少MLP在简单二元分类问题上的过拟合。在这里,我们提供了一个在神经网络上应用Dropout正则化的模板,你也可以将其用于分类和回归问题。二元分类问题在这里,我们使用一个标准的二元分类问题,即定义两个二维同心圆,每个类为一个圆。每个观测值都有两个输入变量,它们具有相同的比例,类输出值为0或1。这个数据集就是 “圆”数据集。我们可以使用make_circles()方法生成观测结果。我们为数据添加噪声和随机数生成器,以防每次运行代码时使用相同的样本。# generate 2d classification datasetX, y = make_circles(n_samples=100, noise=0.1, random_state=1)我们可以用x和y坐标绘制一个数据集,并将观察到的颜色定义为类值。生成和绘制数据集的代码如下:# generate two circles datasetfrom sklearn.datasets import make_circlesfrom matplotlib import pyplotfrom pandas import DataFrame# generate 2d classification datasetX, y = make_circles(n_samples=100, noise=0.1, random_state=1)# scatter plot, dots colored by class valuedf = DataFrame(dict(x=X[:,0], y=X[:,1], label=y))colors = {0:‘red’, 1:‘blue’}fig, ax = pyplot.subplots()grouped = df.groupby(’label’)for key, group in grouped: group.plot(ax=ax, kind=‘scatter’, x=‘x’, y=‘y’, label=key, color=colors[key])pyplot.show()运行以上代码,会创建一个散点图,散点图展示每个类中观察到的同心圆形状。我们可以看到,因为噪声,圆圈并不明显。这是一个特别好的测试问题,因为类不可能用一条直线表示,比如它不是线性可微分的,在这种情况下,就需要使用非线性方法来解决,比如神经网络。在这里,我们只生成了100个样本,这对于神经网络来说,样本是相当少了。但是它提供了训练数据集的过拟合现象,并且在测试数据及上的误差更大:这是使用正则化的一个特别好的例子。除此之外,这个样本集中有噪声,这就使神经网络模型有机会学习不一致样本的各个方面。多层感知器的过拟合我们可以创建一个MLP模型来解决这个二元分类问题。该模型将具有一个隐藏层,它的节点比解决该问题所需节点要多得多,从而产生过拟合。另外,我们训练模型的时间也大大超过正常训练模型所需要的时间。在定义模型之前,我们将数据集拆分为训练集和测试集:30个训练数据来训练模型和70个测试数据来评估拟合模型性能。# generate 2d classification datasetX, y = make_circles(n_samples=100, noise=0.1, random_state=1)# split into train and testn_train = 30trainX, testX = X[:n_train, :], X[n_train:, :]trainy, testy = y[:n_train], y[n_train:]接下来,我们可以定义模型。在隐藏层中使用500个节点和矫正过得线性激活函数;在输出层中使用S型激活函数预测类的值(0或1)。该模型使用二元交叉熵损失函数进行优化,这个函数适用于二元分类问题和梯度下降到有效Adam问题。# define modelmodel = Sequential()model.add(Dense(500, input_dim=2, activation=‘relu’))model.add(Dense(1, activation=‘sigmoid’))model.compile(loss=‘binary_crossentropy’, optimizer=‘adam’, metrics=[‘accuracy’])将训练数据训练4000次,默认每次训练次数为32。 然后用测试数据集验证该模型性能,代码如下。# fit modelhistory = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)测试的方法如下。# evaluate the model_, train_acc = model.evaluate(trainX, trainy, verbose=0), test_acc = model.evaluate(testX, testy, verbose=0)print(‘Train: %.3f, Test: %.3f’ % (train_acc, test_acc))最后,在每次训练的时候绘制模型的性能。如果模型在训练数据集时的确是过拟合,那么我们训练集上的准确度线图更加准确,并且准确度随着模型学习训练数据集中的统计噪声而再次下降。# plot historypyplot.plot(history.history[‘acc’], label=‘train’)pyplot.plot(history.history[‘val_acc’], label=‘test’)pyplot.legend()pyplot.show()将以上所有代码组合起来,如下所示。# mlp overfit on the two circles datasetfrom sklearn.datasets import make_circlesfrom keras.layers import Densefrom keras.models import Sequentialfrom matplotlib import pyplot# generate 2d classification datasetX, y = make_circles(n_samples=100, noise=0.1, random_state=1)# split into train and testn_train = 30trainX, testX = X[:n_train, :], X[n_train:, :]trainy, testy = y[:n_train], y[n_train:]# define modelmodel = Sequential()model.add(Dense(500, input_dim=2, activation=‘relu’))model.add(Dense(1, activation=‘sigmoid’))model.compile(loss=‘binary_crossentropy’, optimizer=‘adam’, metrics=[‘accuracy’])# fit modelhistory = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)# evaluate the model, train_acc = model.evaluate(trainX, trainy, verbose=0), test_acc = model.evaluate(testX, testy, verbose=0)print(‘Train: %.3f, Test: %.3f’ % (train_acc, test_acc))# plot historypyplot.plot(history.history[‘acc’], label=‘train’)pyplot.plot(history.history[‘val_acc’], label=‘test’)pyplot.legend()pyplot.show()运行以上代码,我们可以看到模型在训练和测试数据集上的性能:模型在训练数据集上的性能优于测试数据集,这是过度拟合的一个可能标志。鉴于神经网络和训练算法的随机性,模型的测试结果可能会有所不同。由于该模型严重过拟合,该模型在同一数据集上运行的结果差异并不会很大。Train: 1.000, Test: 0.757下图为模型在训练和测试集上的精度图,我们可以看到过拟合模型的预期性能,其中测试精度增加到一定值以后,再次开始减小。使用Dropout正则化减少MLP过拟合我们使用Dropout正则化更新这个示例,即在隐藏层和输出层之间插入一个新的Dropout层来实现。在这里,指定Dropout rate=0.4。# define modelmodel = Sequential()model.add(Dense(500, input_dim=2, activation=‘relu’))model.add(Dropout(0.4))model.add(Dense(1, activation=‘sigmoid’))model.compile(loss=‘binary_crossentropy’, optimizer=‘adam’, metrics=[‘accuracy’])下面列出了隐藏层后添加了dropout层的完整更新示例。# mlp with dropout on the two circles datasetfrom sklearn.datasets import make_circlesfrom keras.models import Sequentialfrom keras.layers import Densefrom keras.layers import Dropoutfrom matplotlib import pyplot# generate 2d classification datasetX, y = make_circles(n_samples=100, noise=0.1, random_state=1)# split into train and testn_train = 30trainX, testX = X[:n_train, :], X[n_train:, :]trainy, testy = y[:n_train], y[n_train:]# define modelmodel = Sequential()model.add(Dense(500, input_dim=2, activation=‘relu’))model.add(Dropout(0.4))model.add(Dense(1, activation=‘sigmoid’))model.compile(loss=‘binary_crossentropy’, optimizer=‘adam’, metrics=[‘accuracy’])# fit modelhistory = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)# evaluate the model, train_acc = model.evaluate(trainX, trainy, verbose=0)_, test_acc = model.evaluate(testX, testy, verbose=0)print(‘Train: %.3f, Test: %.3f’ % (train_acc, test_acc))# plot historypyplot.plot(history.history[‘acc’], label=‘train’)pyplot.plot(history.history[‘val_acc’], label=‘test’)pyplot.legend()pyplot.show()运行以上代码,查看模型在训练和测试集上的性能。你所得到的结果可能会有所不同,在这种情况下,该模型具有较高的方差。在这里,我们可以看到,Dropout导致训练集的准确度有所下降,从100%降至96%,而测试集的准确度从75%提高到81%。Train: 0.967, Test: 0.814从这里我们可以看出,该模型已经不再适合训练数据集了。尽管使用Dropout正则化时会产生很多噪音,训练数据集和测试数据集的模型精度持续增加。在后续学习中,你可以进一步探索以下这些问题:1.输入Dropout。在输入变量上使用Dropout正则化,更新示例,并比较结果。2.权重约束。在隐藏层添加max-norm权重约束,更新示例,并比较结果。3.反复评估。更新示例,重复评估过拟合和Dropout模型,总结并比较平均结果。4.网格搜索率。创建Dropout概率的网格搜索,并报告Dropout rate和测试数据集准确度二者之间的关系。拓展阅读论文1.《使用卷积神经网络进行高效的对象本地化,2015》2.《递归神经网络中的理论Dropout应用,2016》博文1.基于Keras深度学习模型中的Dropout正则化2.如何使用LSTM网络的Dropout进行时间序列预测API1.Keras Regularizers API2.Keras Core Layers API3.Keras Convolutional Layers API4.Keras Recurrent Layers API5.sklearn.datasets.make_circles API总结阅读完本文,你已经了解了如何将深度学习正则化添加到深度学习神经网络模型的API中。具体来说,有以下几个内容:1.如何使用Keras API创建Dropout层。2.如何使用Keras API将Dropout正则化添加到MLP、CNN和RNN层。3.如何向现有模型中添加Dropout正则化,以此减少过拟合。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

December 10, 2018 · 3 min · jiezi

注意力机制实现机器翻译

介绍Attention模型形象的比喻就是“图像对焦”。上图是Encoder-Decoder模型,Decoder中每个单词生成过程如下:其中C是“语义编码C”,f是Decoder的非线性变换函数。由此,我们可以看出生成目标句子的每个单词都使用同一个语义编码C,即:源句子中的每个单词的影响力都是一样的,这如同图像没有对焦的情况,现实项目中也存在明显的不合理。比如一个机器翻译模型,输入是“Tom chase Jerry”,模型输出:“汤姆”,“追逐”,“杰瑞”。在翻译“杰瑞”的时候显然“Jerry”的贡献值最大,如果每个单词的贡献值相同明显不合理。这个问题在输入句子长度较短时问题不大,但是当输入句子较长时会丢失很多细节信息(个人觉得此处类似平均池化和最大值池化)。正因为如此,我们引入了Attention思想。Soft Attention模型使用Attention模型翻译“杰瑞”的时候,我们可以得到输入句子中的每个单词对输出当前单词的贡献值大小如:(Tom,0.3)(Chase,0.2) (Jerry,0.5)。这意味着生成每个单词yi时不再使用同一个语义编码C,而是根据yi使用不同的Ci。在引入Attention模型后yi的计算过程改变如下所示:每个Ci对应源句子中每个单词的注意力分配概率,示例如下:f2是Encoder对每个单词的变换函数,g函数代表整个源句子的中间语义表示的变换函数,一般形式是加权求和:aji代表注意力分配系数,hj代表源句子中某个单词的语义编码,Lx代表源句子中单词数量。g函数的计算过程如下图所示:Attention模型概率计算如果所示,当我们要生成yi单词,此时我们用i-1时刻的隐藏节点输出值Hi-1去和源句子中的每个单词对应RNN隐藏节点状态hj依次进行对比,即:通过函数F(hj,Hi-1)来获得yi对源句子中每个单词对应的对齐可能性,函数F常见方法如下图所示:然后使用Softmax函数进行数值归一化处理。如对“对齐概率”不理解的朋友,可以查看下图英语-德语翻译系统中加入Attention机制后,Encoder和Decoder两个句子中每个单词对应注意力分配概率分布。Self Attention模型在Soft Attention模型中,Attention机制发生在Decoder中Yi和Encoder中的所有元素之间。Self Attention模型不是在两者之间,而是Decoder内部元素之间或者Encoder内部元素之间发生的Attention机制,计算方法和Soft Attention模型一致。那么Self Attention模型有什么好处?我们依然以机器翻译为例:如图所示,Self Attention模型在内部可以捕获一些句法特征或语义特征。Self Attention模型相比传统RNN模型需要依次序序列计算,它的感受野更大,可以直接将句子中的任意两个单词的联系通过一个计算步骤联系起来,可以捕获远距离的相互依赖特征(就像列表和数组的区别)。此外,Self Attention模型对于增加计算的并行性也有帮助。案例我们使用的语言数据集是“英语-西班牙语”,数据集样本如下图所示:数据导入# 数据下载path_to_zip=tf.keras.utils.get_file( fname=‘spa-eng.zip’, origin=‘http://download.tensorflow.org/data/spa-eng.zip', # 解压tar zip文件 extract=True)path_to_file=os.path.dirname(path_to_zip)+’/spa-eng/spa.txt’转码:def unicode_to_ascii(sen): return ‘’.join( char for char in unicodedata.normalize(‘NFD’,sen) if unicodedata.category(char) != ‘Mn’ )数据预处理每条训练语句添加开始和结束标记移除句子中的特殊字符字符转ID,ID转字符并排序将句子补长到预设的最大长度def preprocess_sentence(w): w = unicode_to_ascii(w.lower().strip()) # 在单词和标点之间创建空格 # 如: “he is a boy.” => “he is a boy .” w = re.sub(r"([?.!,¿])", r" \1 “, w) w = re.sub(r’[” “]+’, " “, w) # 特殊字符以空格代替 w = re.sub(r”[^a-zA-Z?.!,¿]+”, " “, w) w = w.rstrip().strip() # 添加开始和结束标记 w = ‘<start> ’ + w + ’ <end>’ return w创建数据集:def create_dataset(path, num_examples): lines = open(path, encoding=‘UTF-8’).read().strip().split(’\n’) word_pairs = [[preprocess_sentence(w) for w in l.split(’\t’)] for l in lines[:num_examples]] # 返回格式:[ENGLISH, SPANISH] return word_pairs字符转ID,ID转字符,并排序:class LanguageIndex(): def init(self,lang): self.lang=lang self.wrod2idx={} self.id2word={} self.vacab=set() self.create_index() def create_index(self): for phrase in self.lang: # 添加到集合中,重复内容不添加 self.vacab.update(phrase.split(’ ‘)) self.vacab=sorted(self.vacab) self.wrod2idx[’<pad>’]=0 #字符-ID转换 for index,word in enumerate(self.vacab): self.wrod2idx[word]=index+1 for word,index in self.wrod2idx.items(): self.id2word[index]=word加载数据集:# 计算最大长度def max_length(tensor): return max(len(t) for t in tensor)def load_dataset(path,num_example): #get inputs outputs pairs=create_dataset(path,num_example) # 获取ID表示 inp_lang=LanguageIndex(sp for en,sp in pairs) targ_lang=LanguageIndex(en for en,sp in pairs) # LanguageIndex 不包含重复值,以下包含重复值 input_tensor=[[inp_lang.wrod2idx[s]for s in sp.split(’ ‘)]for en,sp in pairs] target_tensor=[[targ_lang.wrod2idx[s]for s in en.split(’ ‘)]for en,sp in pairs] max_length_inp,max_length_tar=max_length(input_tensor),max_length(target_tensor) # 将句子补长到预设的最大长度 # padding: post:后补长,pre:前补长 input_tensor=tf.keras.preprocessing.sequence.pad_sequences( sequences=input_tensor, maxlen=max_length_inp, padding=‘post’ ) target_tensor=tf.keras.preprocessing.sequence.pad_sequences( sequences=target_tensor, maxlen=max_length_tar, padding=‘post’ ) return input_tensor,target_tensor,inp_lang,targ_lang,max_length_inp,max_length_tar创建训练集验证集:# 本次项目只使用前30000条数据num_examples = 30000input_tensor, target_tensor, inp_lang, targ_lang, max_length_inp, max_length_targ = load_dataset(path_to_file, num_examples)# 训练集80%,验证集20%input_tensor_train, input_tensor_val, target_tensor_train, target_tensor_val = train_test_split(input_tensor, target_tensor, test_size=0.2)模型训练配置# 打乱数据集BUFFER_SIZE=len(input_tensor_train)BATCH_SIZE=64# 每个epoch迭代次数N_BATCH=BUFFER_SIZE // BATCH_SIZE# 词嵌入维度embedding_dim=256# 隐藏神经元数量units=1024vocab_inp_size=len(inp_lang.wrod2idx)vocab_tar_size=len(targ_lang.wrod2idx)dataset=tf.data.Dataset.from_tensor_slices((input_tensor_train,target_tensor_train)).shuffle(BUFFER_SIZE)# drop_remainder 当剩余数据量小于batch_size时候,是否丢弃dataset=dataset.batch(BATCH_SIZE,drop_remainder=‘True’)案例Attention模型计算文章开始我们介绍了Attention模型的计算过程,相信你会很容易理解上图的内容。对每个节点具体方程实现如下:FC=全连接层,EO=编码器输出,H=隐藏层状态,X=解码器输入,模型计算过程如下表示:score = FC(tanh(FC(EO) + FC(H)))attention weights = softmax(score, axis = 1)context vector = sum(attention weights * EO, axis = 1)embedding output=解码器输入X,输入词嵌入层merged vector=concat(embedding output, context vector)将merged vector输入到GRU创建模型GRU配置:def gru(units): # 使用GPU加速运算 if tf.test.is_gpu_available(): return tf.keras.layers.CuDNNGRU(units, return_sequences=True, return_state=True, # 循环核的初始化方法 # glorot_uniform是sqrt(2 / (fan_in + fan_out))的正态分布产生 # 其中fan_in和fan_out是权重张量的扇入扇出(即输入和输出单元数目) recurrent_initializer=‘glorot_uniform’) else: return tf.keras.layers.GRU(units, return_sequences=True, return_state=True, # hard_sigmoid <= -1 输出0,>=1 输出1 ,中间为线性 recurrent_activation=‘sigmoid’, recurrent_initializer=‘glorot_uniform’)编码器:class Encoder(tf.keras.Model): def init(self, vocab_size, embedding_dim, enc_units, batch_sz): super(Encoder, self).init() self.batch_sz = batch_sz self.enc_units = enc_units self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim) self.gru = gru(self.enc_units) def call(self, x, hidden): x = self.embedding(x) output, state = self.gru(x, initial_state = hidden) return output, state def initialize_hidden_state(self): return tf.zeros((self.batch_sz, self.enc_units))解码器:class Decoder(tf.keras.Model): def init(self,vocab_size,embedding_dim,dec_units,batch_sz): super(Decoder, self).init() self.batch_sz=batch_sz self.dec_units=dec_units self.embedding=tf.keras.layers.Embedding( input_shape=vocab_size, output_dim=embedding_dim ) self.gru=gru(self.dec_units) self.fc=tf.keras.layers.Dense(units=vocab_size) # 用于计算score,即:注意力权重系数 self.W1=tf.keras.layers.Dense(self.dec_units) self.W2=tf.keras.layers.Dense(self.dec_units) self.V=tf.keras.layers.Dense(units=1) def call(self,x,hidden,ec_output): # tf.expand_dims:在指定索引出增加一维度,值为1,从索引0开始 # axis: 取值范围是[-阶数,阶数],二维的时候0指的是列,1指的是行, # 更高维度的时候,数值是由外向里增加,如:3维向量,外向内依次是:0,1,2 # 通过计算score公式可得,需要将hidden维度扩展至:[batch_size,1,hidden_size] hidden_with_time_axis=tf.expand_dims(hidden,axis=1) # score=[batch_size, max_length, 1] score=self.V(tf.nn.tanh(self.W1(ec_output)+self.W2(hidden_with_time_axis))) # 数值归一化和为1的概率分布值 attention_weight=tf.nn.softmax(score,axis=1) context_vetor=attention_weightec_output # 求和平均 context_vetor=tf.reduce_sum(context_vetor,axis=1) X=self.embedding(x) # 合并解码器embedding输出和context vector x = tf.concat([tf.expand_dims(context_vector, 1), x], axis=-1) # output shape=(batch_size,time_step,hidden_size) # state shape=(batch_size,hidden_size) output,state=self.gru(x) # output[batch_size1,hidden_size] output=tf.reshape(output,shape=(-1,output.shape[2])) x-self.fc(output) return x,state,attention_weight def initilize_hidden_size(self): return tf.zeros((self.batch_sz,self.dec_units))实例化模型:encoder = Encoder(vocab_inp_size, embedding_dim, units, BATCH_SIZE)decoder = Decoder(vocab_tar_size, embedding_dim, units, BATCH_SIZE)损失函数,优化器:optimizer = tf.train.AdamOptimizer()def loss_function(real, pred): mask = 1 - np.equal(real, 0) loss_ = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=real, logits=pred) * mask return tf.reduce_mean(loss_)模型保存:checkpoint_dir = ‘./training_checkpoints’checkpoint_prefix = os.path.join(checkpoint_dir, “ckpt”)checkpoint = tf.train.Checkpoint(optimizer=optimizer, encoder=encoder, decoder=decoder)训练由于我们使用Teacher Forcing进行训练,所以我们简单介绍下。如图所示Teacher Forcing与Free-running不同,在训练过程中不再是前一时刻的hidden-state作为当前输入,而是在Ground Truth中找到对应的上一项作为当前输入。早期的RNN很弱,如果生成了非常差的结果Free-running的运行方式会导致后面的hidden-state都受到影响。Teacher Forcing运行方式就可以避免这种问题,缺点也很明显它严重依赖标签数据。# 迭代10次训练集EPOCHS = 10for epoch in range(EPOCHS): start = time.time() hidden = encoder.initialize_hidden_state() total_loss = 0 for (batch, (inp, targ)) in enumerate(dataset): loss = 0 # 先记录梯度 with tf.GradientTape() as tape: # 编码器输出 enc_output, enc_hidden = encoder(inp, hidden) dec_hidden = enc_hidden dec_input = tf.expand_dims([targ_lang.word2idx[’<start>’]] * BATCH_SIZE, 1) # 使用Teacher forcing运行方式 for t in range(1, targ.shape[1]): # 解码器输出 predictions, dec_hidden, _ = decoder(dec_input, dec_hidden, enc_output) loss += loss_function(targ[:, t], predictions) # 样本标签作为输入 dec_input = tf.expand_dims(targ[:, t], 1) batch_loss = (loss / int(targ.shape[1])) # one_loss++;batch_loss++ total_loss += batch_loss variables = encoder.variables + decoder.variables gradients = tape.gradient(loss, variables) optimizer.apply_gradients(zip(gradients, variables)) if batch % 100 == 0: print(‘Epoch {} Batch {} Loss {:.4f}’.format(epoch + 1, batch, batch_loss.numpy())) # 每迭代2次训练集保存一次模型 if (epoch + 1) % 2 == 0: checkpoint.save(file_prefix = checkpoint_prefix)翻译评估函数我们不使用teacher-forcing模式,解码器的每步输入是它前一时刻的hidden-state和编码器输出,当模型遇到 <end>标记停止运行。# 和训练模型函数代码基本一致def evaluate(sentence, encoder, decoder, inp_lang, targ_lang, max_length_inp, max_length_targ): attention_plot = np.zeros((max_length_targ, max_length_inp)) # 数据预处理 sentence = preprocess_sentence(sentence) # 向量化表示输入数据 inputs = [inp_lang.word2idx[i] for i in sentence.split(’ ‘)] # 后置补长 inputs = tf.keras.preprocessing.sequence.pad_sequences([inputs], maxlen=max_length_inp, padding=‘post’) inputs = tf.convert_to_tensor(inputs) result = ’’ hidden = [tf.zeros((1, units))] enc_out, enc_hidden = encoder(inputs, hidden) dec_hidden = enc_hidden # 维度扩展batch_size dec_input = tf.expand_dims([targ_lang.word2idx[’<start>’]], 0) for t in range(max_length_targ): predictions, dec_hidden, attention_weights = decoder(dec_input, dec_hidden, enc_out) # 保存权重用于稍后可视化展示 attention_weights = tf.reshape(attention_weights, (-1, )) attention_plot[t] = attention_weights.numpy() predicted_id = tf.argmax(predictions[0]).numpy() # 获取文本翻译结果 result += targ_lang.idx2word[predicted_id] + ’ ’ # 预设的结束标记 if targ_lang.idx2word[predicted_id] == ‘<end>’: return result, sentence, attention_plot # 预测值作为输入,以此输出下一时刻单词 dec_input = tf.expand_dims([predicted_id], 0) return result, sentence, attention_plot可视化权重值: fig = plt.figure(figsize=(10,10)) ax = fig.add_subplot(1, 1, 1) ax.matshow(attention, cmap=‘viridis’) fontdict = {‘fontsize’: 14} ax.set_xticklabels([’’] + sentence, fontdict=fontdict, rotation=90) ax.set_yticklabels([’’] + predicted_sentence, fontdict=fontdict) plt.show()总结本篇文章篇幅较多,不过项目的重点是Attention思想的理解,Self Attention模型具有更长的感受野,更容易捕获长距离的相互依赖特征,目前Google机器翻译模型就大量使用到Self Attention。Attention模型目前在机器翻译,图片描述任务,语音识别都有大量应用,熟练使用Attention对于解决实际问题会有很大的帮助。文章部分内容参考 Yash Katariya 和 张俊林,在此表示感谢。 ...

December 8, 2018 · 4 min · jiezi

傻瓜神经网络入门指南

摘要: 现在网络上充斥着大量关于神经网络的消息,但是,什么是神经网络?其本质到底是什么?用几分钟阅读完这篇文章,我不能保证你能够成为这个领域的专家,不过你已经入门了。现在网络上充斥着大量关于神经网络的消息,但是,什么是神经网络?其本质到底是什么?你是不是对这个熟悉又陌生的词感到困惑?用几分钟阅读完这篇文章,我不能保证你能够成为这个领域的专家,但可以保证的是,你已经入门了。什么是神经网络?想要透彻的了解神经网络,我们首先要知道什么是机器学习。为了更好的理解机器学习,我们首先谈谈人的学习,或者说什么是“经典程序设计”。在经典的程序设计中,作为一名开发人员,我需要了解所要解决的问题的各个方面,以及我要以什么规则为基础。举个例子来说,假设我要设计一个能够区别正方形和圆形的程序。处理方法则是编写一个可以检测到角的程序,然后计算角的数量。如果程序能检测到4个角,那么图形为正方形;如果角的个人为0,则为圆形。那么这个机器学习有何关系?一般来说,机器学习=从示例中学习。在机器学习中,该如何区别正方形和圆形呢?这时候,我们就要设计一个学习系统,将许多形状及类别不同的图形作为输入,然后我们希望机器能够自己学习形状及类别,然后识别出不同图形的不同特性。一旦机器学会了这些属性,我们就可以输入一个新的图形(机器以前没见过的图形),然后机器对这些图形进行分类。什么是神经网络?在神经网络中,神经元是一个很奇特的名字,比较类似于函数。在数学和计算机领域,函数可以接受某个输入,经过一系列的逻辑运算,输出结果。更重要的是,我们可以将神经元看做一个学习单元。因此,我们需要理解什么是学习单元,然后再了解神经网络的基本构建块,即神经元。为了更好的理解,假设我们试图理解博客文章中单词数量与人们实际从博客中读取单词数量之间的关系。请记住一点,在机器学习领域,我们从示例中学习。因此,我们用x表示机器收集到文章的单词数量,用y表示人们实际读到的单词数,它们之间的关系用f表示。然后,我只需要告诉机器(程序)我希望看到的关系(比如直线关系),机器再将会理解它所需要绘制的线。我在这里得到了什么?下次我想写一篇包含x个单词的文章时,机器可以根据对应关系f找到人们真正能阅读到的单词数y。那么,神经网络到底是什么?如果一个神经元是一个函数,那么神经网络就是一个函数网络,也就是说,我们有很多个这样的功能(比如学习单元),这些学习单元的输入和输出相互交织,相互之间也有反馈。作为一名神经网络的设计人员,我的主要工作就是:1.如何建模输入和输出?例如,如果输入是文本,我可以用什么建模?数字?还是向量?2.每个神经元有哪些功能?(它们是线性?还是指数?…)3.神经网络的架构是什么?(即哪个函数的输出是哪个函数的输入?)4.我可以用哪些通俗易懂的词来描述我的网络?一旦我回答了以上这些问题,我就可以向网络“展示”大量具有正确输入和输出的例子,神经网络学习后,当我再次输入一个新的输入时,神经网路就会有个正确的输出。神经网络的学习原理超出了本文索要描述的范围,想要了解更多内容,请点击这里。另外你可以去神经网络专题,来更透彻的了解神经网络。神经网络的学习是件永无止境时,这个领域的知识呈爆炸性增长,每时每刻都会有新的知识和内容更新。最后,我贴出来一些个人认为比较好的帖子供你学习:1.Gal Yona ——我最喜欢的博主之一。她的文章涵盖了核心技术解释到半哲学评论。2.Siraj Raval——拥有大量视频的YouTuber,从理论解释到动手实践教程,应有俱有!3.Christopher Olah ——一位充满激情和洞察力的研究员,他的博客涵盖了神经网络的基础到深入探索。4.Towards Data Science 是神经网络领域中最大的Medium出版物,建议你每天抽出几分钟的时间来阅读,你会获得意想不到的收获。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 6, 2018 · 1 min · jiezi

卷积神经网络导览

摘要: 关于卷积神经网络最重要的概念都在这里!介绍这篇文章旨在以全面和简洁的方式介绍卷积神经网络(CNN),目标是建立对这些算法的内部工作的直观理解。因此,这项工作对于刚从这个主题开始的非数学、非计算机科学背景的读者来说意味着特别有价值。我写这篇文章的灵感来自于我正在参加的Fast.ai课程’Code Deeprs For Coders v3’,导师Jeremy Howard鼓励我们在博客上讲述我们学到的东西。我在这里分享的知识来自于阅读各种材料和参加不同的课程的成果,目的是在以医学影像的学生研究项目。这些帖子的主要部分取自我最近完成的这篇论文。在旅程开始之前,必须采取一些预防措施来对卷积神经网络进行透视。机器学习(ML)是计算机科学的子领域,通过具有学习能力的算法解决问题。“学习”通过内部组件的自动优化一个称为参数的权重。适用于ML的问题是两种形式的预测:回归-连续值的预测以及分类-通过类成员预测将对象细分为不同的组。深度学习(DL)又是ML的子域,通过将具有特定架构的算法(称为神经网络)应用于机器学习问题来区分。这种架构的灵感来自于自然界中的神经网络,并且包括-稍微简化-表示连接不同神经元的计算单元和边缘以及确保信息流动的神经元。其中存在多种不同类型的神经网络:人工神经网络(ANN),专门用于处理表格数据;用于时间序列数据的递归神经网络(RNN),如语音和卷积神经网络(CNN),特别适用于图像数据。有了这些基础知识,我们就可以开始研究后一种类型了。“解剖”CNN图1是网络的循环示例图,它的灵感来自LeNet(LeCun等,1998)第一个CNN架构。虽然CNN之间的特定架构不同,但它们的特征在于都有该示例网络所涵盖的规定元素。该算法旨在解决二元分类问题,例如猫与狗之间的区别。在这一点上,重要的是该图和紧接着的用于为演练创建框架。因此,不需要完全理解和熟悉所有术语。这些更深入的理解在即将到来的部分中逐渐形成,图1将作为便于读者大致的参考。从图1中可以看出,网络被细分为前向和后向传递。在前向传递期间,数据通过不同的层(图1:彩色箭头)。由二维阵列表示的输入图像(图1:左空矩形)被提供给给出名称的卷积层。该层识别输入数据上的轮廓和形状,并输出一组特征图(图1:垂直条纹矩形)。最大池层成为卷积层的成功之处,它成功的消除了无关紧要的部分,从而缩小了数据。此后,数据通过平均池化操作,将图像数据转换为矢量,进入完全连接的层(图1:水平条纹矩形)。这些图层在此向量中标识特定于类的模式,并在此基础上预测输入数据的类成员资格。到目前为止,还没有学习过,因为这是在向后传递中完成的。首先,通过损失函数量化分类误差,基于损失函数的结果,通过反向传播和梯度下降来优化前述层中的参数。很明显更高的迭代次数,即输入更多训练样本图像,是实现正确分类结果所必需的。完整训练数据集通过模型的点称为epoch。卷积,线性整流函数和最大池化术语“卷积”描述了特定类型的矩阵计算,其中称为滤波器的特殊目的矩阵应用于输入图像,如图2所示。滤波器(3x3矩阵)通常是较小的矩阵,在卷积运算中,它被放置在图像的子部分上:(图2中的3x3青色图像子集)。每对相应值的元素乘法和随后对所有乘积的进行求和,产生单个输出值。换句话说,图像子集的左上角值与滤波器的左上角值相乘,顶部中间值与相应的顶部中间值相乘,最后所有乘积都相加。之后,滤波器以滑动窗口的方式在输入图像的每个拟合子集上执行上述计算的图像上移动。得到的输出值被收集在称为特征图的输出矩阵中,其中特征图中的输出值的位置(图2:青色顶部中间值)对应于计算中涉及的输入图像子集的位置。过滤器在图像上的移动方式取决于步幅和填充。一个步骤描述了每个卷积运算将滤波器移动一个像素,从而产生更小的特征图(图2:步幅s=1)。通过向图像的外边界添加零像素来抵消特征图的尺寸减小,称为填充(图2:填充=0)。在卷积操作期间,大多数单独的滤波器应用于输入图像,从而产生每个滤波器的特征图(图2:滤波器和特征图后面的多个silhouttes)。换句话说,卷积层输出与其滤波器计数对应的一叠特征映射。可以将滤波器视为专用轮廓检测器,并且得到的特征图报告检测位置。如果过滤器放置在包含边缘的图像子部件上,它会将其转换为特征图中的高值。换句话说,高特征映射值表示特定位置处的输入图像中的轮廓检测。该过程如图3所示:如果过滤器到达由黄色和绿色框标记的子部分,则识别基础轮廓。因此,特征图也可以被视为图像并相应地可视化。图4显示出了对输入图像应用滤波器(图4:底行)以进行垂直或水平边缘检测的结果。过滤器值是权重、是学习的参数。它们在后向传递期间不断优化,同时更多的数据通过网络。通过这种方式,实现了调整过程:过滤器学习识别输入图像中可用的特定元素,并且可以将其可视化为图片本身。而早期图层中的过滤器(图5:左)将学习基本像素,如轮廓,后期图层中的过滤器(图5:右)将连接上游特征,并学习更复杂的构造,例如眼睛甚至脸部( Zeiler和Fergus,2014)。因此,可以小心地将滤波器与视觉皮层神经元的感受野进行比较。这个被称为线性整流单元(ReLU)的函数应用于输出特征图(图6)。在令人生畏的名称下隐藏了一个简单的阈值步骤:零以下的所有值都归零。阈值化的特征图被移交给最大池化层(图7)。这里,虽然类似于卷积,但实际上发生了更简单的矩阵计算。过滤器再次以滑动窗口方式放置在要素图子集上,并提取子集的最高值,将它们保留在精简输出要素图中。目的是丢弃多余的数据:没有表示任何轮廓检测的值被划掉,而空间信息大致保留,这导致较低的计算成本。灵感和参考Jeremy Howard和Fast.ai深入学习编码器;Andrew Ng和deeplearning.ai的神经网络和深度学习;LeCun,Y.,Bottou,L.,Bengio,Y.,Haffner,P.,1998。基于梯度的学习应用于文档识别;Zeiler,MD,Fergus,R.,2014。可视化和理解卷积网络;本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 5, 2018 · 1 min · jiezi

用简单代码看卷积组块发展

摘要: 在本文中,我想带领大家看一看最近在Keras中实现的体系结构中一系列重要的卷积组块。作为一名计算机科学家,我经常在翻阅科学技术资料或者公式的数学符号时碰壁。我发现通过简单的代码来理解要容易得多。因此,在本文中,我想带领大家看一看最近在Keras中实现的体系结构中一系列重要的卷积组块。当你在GitHub网站上寻找常用架构实现时,一定会对它们里面的代码量感到惊讶。如果标有足够多的注释并使用额外的参数来改善模型,将会是一个非常好的做法,但与此同时这也会分散体系结构的本质。为了进一步简化和缩短代码,我将使用一些别名函数:defconv(x, f, k=3, s=1, p=‘same’, d=1, a=‘relu’): return Conv2D(filters=f, kernel_size=k, strides=s, padding=p, dilation_rate=d, activation=a)(x)def dense(x, f, a=‘relu’): return Dense(f, activation=a)(x)defmaxpool(x, k=2, s=2, p=‘same’): return MaxPooling2D(pool_size=k, strides=s, padding=p)(x)defavgpool(x, k=2, s=2, p=‘same’): return AveragePooling2D(pool_size=k, strides=s, padding=p)(x)defgavgpool(x): return GlobalAveragePooling2D()(x)defsepconv(x, f, k=3, s=1, p=‘same’, d=1, a=‘relu’): return SeparableConv2D(filters=f, kernel_size=k, strides=s, padding=p, dilation_rate=d, activation=a)(x)在删除模板代码之后的代码更易读。当然,这只有在你理解我的首字母缩写后才有效。defconv(x, f, k=3, s=1, p=‘same’, d=1, a=‘relu’): return Conv2D(filters=f, kernel_size=k, strides=s, padding=p, dilation_rate=d, activation=a)(x)def dense(x, f, a=‘relu’): return Dense(f, activation=a)(x)defmaxpool(x, k=2, s=2, p=‘same’): return MaxPooling2D(pool_size=k, strides=s, padding=p)(x)defavgpool(x, k=2, s=2, p=‘same’): return AveragePooling2D(pool_size=k, strides=s, padding=p)(x)defgavgpool(x): return GlobalAveragePooling2D()(x)defsepconv(x, f, k=3, s=1, p=‘same’, d=1, a=‘relu’): return SeparableConv2D(filters=f, kernel_size=k, strides=s, padding=p, dilation_rate=d, activation=a)(x)瓶颈(Bottleneck)组块一个卷积层的参数数量取决于卷积核的大小、输入过滤器的数量和输出过滤器的数量。你的网络越宽,3x3卷积耗费的成本就越大。def bottleneck(x, f=32, r=4): x = conv(x, f//r, k=1) x = conv(x, f//r, k=3) return conv(x, f, k=1)瓶颈组块背后的思想是,使用一个低成本的1x1卷积,按照一定比率r将通道的数量降低,以便随后的3x3卷积具有更少的参数。最后,我们用另外一个1x1的卷积来拓宽网络。Inception模块模块提出了通过并行的方式使用不同的操作并且合并结果的思想。通过这种方式网络可以学习不同类型的过滤器。defnaive_inception_module(x, f=32): a = conv(x, f, k=1) b = conv(x, f, k=3) c = conv(x, f, k=5) d = maxpool(x, k=3, s=1) return concatenate([a, b, c, d])在这里,我们将使用卷积核大小分别为1、3和5的卷积层与一个MaxPooling层进行合并。这段代码显示了Inception模块的原始实现。实际的实现结合了上述的瓶颈组块思想,这使它稍微的复杂了一些。definception_module(x, f=32, r=4): a = conv(x, f, k=1) b = conv(x, f//3, k=1) b = conv(b, f, k=3) c = conv(x, f//r, k=1) c = conv(c, f, k=5) d = maxpool(x, k=3, s=1) d = conv(d, f, k=1) return concatenate([a, b, c, d])剩余组块(ResNet)ResNet是由微软的研究人员提出的一种体系结构,它允许神经网络具有任意多的层数,同时还提高了模型的准确度。现在你可能已经习惯使用它了,但在ResNet之前,情况并非如此。defresidual_block(x, f=32, r=4): m = conv(x, f//r, k=1) m = conv(m, f//r, k=3) m = conv(m, f, k=1) return add([x, m])ResNet的思路是将初始的激活添加到卷积组块的输出结果中。利用这种方式,网络可以通过学习过程决定用于输出的新卷积的数量。值得注意的是,Inception模块连接这些输出,而剩余组块是用于求和。ResNeXt组块根据它的名称,你可以猜到ResNeXt与ResNet是密切相关的。作者们将术语“基数(cardinality)”引入到卷积组块中,作为另一个维度,如宽度(通道数量)和深度(网络层数)。基数是指在组块中出现的并行路径的数量。这听起来类似于以并行的方式出现的4个操作为特征的Inception模块。然而,基数4不是指的是并行使用不同类型的操作,而是简单地使用相同的操作4次。它们做的是同样的事情,那么为什么你还要把它们并行放在一起呢?这个问题问得好。这个概念也被称为分组卷积,可以追溯到最早的AlexNet论文。尽管当时它主要用于将训练过程划分到多个GPU上,而ResNeXt则使用ResNeXt来提高参数的效率。defresnext_block(x, f=32, r=2, c=4): l = [] for i in range(c): m = conv(x, f//(cr), k=1) m = conv(m, f//(cr), k=3) m = conv(m, f, k=1)l.append(m) m = add(l) return add([x, m])这个想法是把所有的输入通道分成一些组。卷积将只会在其专用的通道组内进行操作,而不会影响其它的。结果发现,每组在提高权重效率的同时,将会学习不同类型的特征。想象一个瓶颈组块,它首先使用一个为4的压缩率将256个输入通道减少到64个,然后将它们再恢复到256个通道作为输出。如果想引入为32的基数和2的压缩率,那么我们将使用并行的32个1x1的卷积层,并且每个卷积层的输出通道是4(256/(322))个。随后,我们将使用32个具有4个输出通道的3x3的卷积层,然后是32个1x1的卷积层,每个层则有256个输出通道。最后一步包括添加这32条并行路径,在为了创建剩余连接而添加初始输入之前,这些路径会为我们提供一个输出。这有不少的东西需要消化。用上图可以非常直观地了解都发生了什么,并且可以通过复制这些代码在Keras中自己创建一个小型网络。利用上面9行简单的代码可以概括出这些复杂的描述,这难道不是很好吗?顺便提一下,如果基数与通道的数量相同,我们就会得到一个叫做深度可分卷积(depthwise separable convolution)的东西。自从引入了Xception体系结构以来,这些技术得到了广泛的应用。密集(Dense)组块密集组块是剩余组块的极端版本,其中每个卷积层获得组块中之前所有卷积层的输出。我们将输入激活添加到一个列表中,然后输入一个可以遍历块深度的循环。每个卷积输出还会连接到这个列表,以便后续迭代获得越来越多的输入特征映射。这个方案直到达到了所需要的深度才会停止。defdense_block(x, f=32, d=5): l = x for i in range(d): x = conv(l, f) l = concatenate([l, x]) return l尽管需要数月的研究才能得到一个像DenseNet这样出色的体系结构,但是实际的构建组块其实就这么简单。SENet(Squeeze-and-Excitation)组块SENet曾经在短期内代表着ImageNet的较高水平。它是建立在ResNext的基础之上的,主要针对网络通道信息的建模。在常规的卷积层中,每个通道对于点积计算中的加法操作具有相同的权重。SENet引入了一个非常简单的模块,可以添加到任何现有的体系结构中。它创建了一个微型神经网络,学习如何根据输入对每个过滤器进行加权。正如你看到的那样,SENet本身不是一个卷积组块,但是因为它可以被添加到任何卷积组块中,并且可能会提高它的性能,因此我想将它添加到混合体中。defse_block(x, f, rate=16): m = gavgpool(x) m = dense(m, f // rate) m = dense(m, f, a=‘sigmoid’) return multiply([x, m])每个通道被压缩为一个单值,并被馈送到一个两层的神经网络里。根据通道的分布情况,这个网络将根据通道的重要性来学习对其进行加权。最后,再用这个权重跟卷积激活相乘。SENets只用了很小的计算开销,同时还可能会改进卷积模型。在我看来,这个组块并没有得到应有的重视。NASNet标准单元这就是事情变得丑陋的地方。我们正在远离人们提出的简捷而有效的设计决策的空间,并进入了一个设计神经网络体系结构的算法世界。NASNet在设计理念上是令人难以置信的,但实际的体系结构是比较复杂的。我们所了解的是,它在ImageNet上表现的很优秀。通过人工操作,作者们定义了一个不同类型的卷积层和池化层的搜索空间,每个层都具有不同的可能性设置。他们还定义了如何以并行的方式、顺序地排列这些层,以及这些层是如何被添加的或连接的。一旦定义完成,他们会建立一个基于递归神经网络的强化学习(Reinforcement Learning,RL)算法,如果一个特定的设计方案在CIFAR-10数据集上表现良好,就会得到相应的奖励。最终的体系结构不仅在CIFAR-10上表现良好,而且在ImageNet上也获得了相当不错的结果。NASNet是由一个标准单元(Normal Cell)和一个依次重复的还原单元(Reduction Cell)组成。defnormal_cell(x1, x2, f=32): a1 = sepconv(x1, f, k=3) a2 = sepconv(x1, f, k=5) a = add([a1, a2]) b1 = avgpool(x1, k=3, s=1) b2 = avgpool(x1, k=3, s=1) b = add([b1, b2]) c2 = avgpool(x2, k=3, s=1) c = add([x1, c2]) d1 = sepconv(x2, f, k=5) d2 = sepconv(x1, f, k=3) d = add([d1, d2]) e2 = sepconv(x2, f, k=3) e = add([x2, e2]) return concatenate([a, b, c, d, e])这就是如何在Keras中实现一个标准单元的方法。除了这些层和设置结合的非常有效之外,就没有什么新的东西了。倒置剩余(Inverted Residual)组块到现在为止,你已经了解了瓶颈组块和可分离卷积。现在就把它们放在一起。如果你做一些测试,就会注意到,因为可分离卷积已经减少了参数的数量,因此进行压缩可能会损害性能,而不是提高性能。作者们提出了与瓶颈组块和剩余组块相反的想法。他们使用低成本的1x1卷积来增加通道的数量,因为随后的可分离卷积层已经大大减少了参数的数量。在把通道添加到初始激活之前,降低了通道的数量。definv_residual_block(x, f=32, r=4): m = conv(x, fr, k=1) m = sepconv(m, f, a=‘linear’) return add([m, x])问题的最后一部分是在可分离卷积之后没有激活函数。相反,它直接被添加到了输入中。这个组块被证明当被放到一个体系结构中的时候是非常有效的。AmoebaNet标准单元利用AmoebaNet,我们在ImageNet上达到了当前的最高水平,并且有可能在一般的图像识别中也是如此。与NASNet类似,AmoebaNet是通过使用与前面相同的搜索空间的算法设计的。唯一的纠结是,他们放弃了强化学习算法,而是采用了通常被称为“进化”的遗传算法。但是,深入了解其工作方式的细节超出了本文的范畴。故事的结局是,通过进化,作者们能够找到一个比NASNet的计算成本更低的更好的解决方案。这在ImageNet-A上获得了名列前五的97.87%的准确率,也是第一次针对单个体系结构的。结论我希望本文能让你对这些比较重要的卷积组块有一个深刻的理解,并且能够认识到实现起来可能比想象的要容易。要进一步了解这些体系结构,请查看相关的论文。你会发现,一旦掌握了一篇论文的核心思想,就会更容易理解其余的部分了。另外,在实际的实现过程中通常将批量规范化添加到混合层中,并且随着激活函数应用的的地方会有所变化。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

December 4, 2018 · 2 min · jiezi

在数据采集器中用TensorFlow进行实时机器学习

摘要: 本文学习如何通过发布的最新TensorFlow Evaluator版本使用TensorFlow(TF)模型进行预测和分类。最新DataOps平台的真正价值,只有在业务用户和应用程序能够从各种数据源来访问原始数据和聚合数据,并且及时地产生数据驱动的认识时,才能够实现。利用机器学习(Machine Learning),分析师和数据科学家可以利用历史数据,以及实时地使用类似TensorFlow(TF)这样的技术,以做出更好的数据驱动业务的线下决策。在本文中,你将学习如何利用TensorFlow模型在StreamSets Data Collector3.5.0和StreamSets Data Collector Edge中最新发布的TensorFlow Evaluator进行预测和分类。在深入讨论细节之前,我们来看一些基本概念。机器学习(Machine Learning)亚瑟·塞缪尔把它描述为:“不需要明确地编写程序而使计算机有能力学习的研究领域。”随着机器学习领域的最新发展,计算机现在有能力做出预测,甚至比人类做的还要好,并且感觉可以解决任何问题。让我们先回顾一下机器学习都解决了什么样的问题吧。通常来说,机器学习被分为两大类:监督学习(Supervised Learning)“监督学习是学习一个函数的机器学习任务,该函数基于输入-输出的实例,将输入映射到输出。”—维基百科(Wikipedia)。它涉及到构建一个精准的模型,当历史数据被标记为一些结果的时候,模型就可以预测出结果了。用监督学习解决的常见业务问题:二元分类(学习预测一个分类值)顾客会购买一个特定产品吗?癌症是恶性的还是良性的?多级分类(学习预测一个分类值)给定的一段文本是否带有病毒、恐吓或淫秽内容?这是山鸢尾、蓝旗鸢尾还是北美鸢尾的物种?回归(学习预测一个连续值)一个代售房子的预测价格是多少?明天旧金山的气温是多少?无监督学习无监督学习允许我们在知道很少,或是完全不知道输出应该是什么样子的情况下处理问题。它涉及在之前数据上的标签是不可用的情况下创建模型。在这类的问题中,通过对基于数据中变量之间的关系进行数据聚类来导出结构。无监督学习的两种常见方法是K-均值聚类(K-means clustering)和DBSCAN。注意:Data Collector和Data Collector Edge中的TensorFlow Evaluator目前仅支持监督学习模型。神经网络与深度学习神经网络是机器学习算法的一种,可以学习和使用受人脑结构启发而来的计算模型。与其它机器学习算法,如决策树、逻辑回归等相比,神经网络具有较高的准确性。Andrew Ng在传统人工神经网络的背景下对深度学习进行了描述。在题为“深度学习、自我学习与无监督特征学习”的演讲中,他把深度学习的思想描述为:“利用了大脑结构的模仿, 希望:让学习算法更好地、更容易地使用;在机器学习和人工智能领域取得革命性的进展;我相信这是我们朝着真正的人工智能前进的最好办法。”常见的神经网络和深度学习应用包括:计算机视觉/图像识别/目标检测语言识别/自然语言处理(NLP)推荐系统(产品、婚介等)异常检测(网络安全等)TensorFlowTensorFlow是为深度神经网络设计的开源机器学习框架,由Google Brain Team开发的。TensorFlow支持在Windows和Mac操作系统上的可伸缩和便携式的训练,包括CPU、GPU和TPU。迄今为止,它是GitHub上最流行的和最活跃的机器学习项目。Data Collector中的TensorFlow随着TensorFlow Evaluator的引入,你现在能够创建管道(pipelines),以获取数据或特征,并在一个可控的环境中生成预测结果或分类,而不必发起对作为Web服务而提供和公布的机器学习模型的HTTP或REST API的调用。例如,Data Collector管道现在可以实时地检测欺诈交易或在文本上执行自然语言处理,因为数据在被存储到最终目的地之前,为了进一步的处理或做决策,正在经过各个阶段。另外,使用Data Collector Edge,你可以在Raspberry Pi和其它运行在所支持的平台上的设备上运行已经启用了的TensorFlow机器学习管道。例如,在高风险地区检测洪水等自然灾害发生的概率,以防止对人们财产的破坏。乳腺癌分类让我们考虑将乳腺癌肿瘤分类成恶性还是良性的例子。乳腺癌是一个经典的数据集,可以作为scikit-learn的一部分。要了解如何在Python中使用该数据集训练和导出一个简单的TensorFlow模型,请查看我在GitHub上的代码。正如你将要看到的那样,模型创建和训练被保持在最小范围,并且非常简单,只有几个隐藏层。最需要注意的重要方面是如何使用TensorFlow SavedModelBuilder来导出和保存模型。注意:要在Data Collector或Data Collector Edge中使用TensorFlow模型,首先应该在你选择支持的开发语言里,如Python,和交互式环境中,如Jupiter Notebook,使用TensorFlow的SavedModelBuilder导出和保存模型。一旦使用TensorFlow的SavedModelBuilder训练并导出了模型,那么在数据流管道中使用它进行预测或分类就非常简单了 — 只要模型保存在Data Collector或Data Collector Edge可访问的位置上即可。管道概述在深入了解细节之前,可以看下管道是什么样的:管道细节目录源:这将从.csv文件中加载乳腺癌的记录数据(注意:这个输入数据源可以非常简单地替换为其它的来源,包括Kafka、AWS S3、MySQL等等);字段转换器:这个处理器将转换供模型所使用的所有输入的乳腺癌记录特征数据,从String类型转换到Float类型(mean_radius,mean_texture,mean_perimeter,mean_area,mean_smoothness,mean_compactness,mean_concavity,mean_concave_points,mean_symmetry,mean_fractal_dimension,radius_error,texture_error,perimeter_error,area_error,smoothness_error,compactness_error,concavity_error,concave_points_error,symmetry_error,fractal_dimension_error,worst_radius,worst_texture,worst_perimeter,worst_area,worst_smoothness,worst_compactness,worst_concavity,worst_concave_points,worst_symmetry,worst_fractal_dimension) ;TensorFlow Evaluator:模型的保存路径:指定要使用的预训练的TensorFlow模型的位置;模型标签:设置为“serve”,因为元图(在我们导出的模型中)要用于服务中。有关详细信息,请参见tag_constants.py和相关的TensorFlow API documentation;输入配置:指定在训练和导出模型期间配置的输入张量信息(请见Train model and save/export it using TensorFlow SavedModelBuilder部分);输出配置:指定在训练和导出模型期间配置的输出张量信息(请见Train model and save/export it using TensorFlow SavedModelBuilder部分);输出字段:我们想保存分类值的输出记录字段;Expression Evaluator:-该处理器评估模型输出或分类值为0或1(存储在输出的字段TF_Model_Classification之中) ,并用Benign或Malignantrespectively这两个值创建一个新的记录字段“Condition”;Stream Selector:该处理器评估癌症状况(良性或恶性)并发送记录到各自的Kafka生产者;Kafka Producers:输入记录以及模型的输出或者分类值被有条件地发送给两个Kafka生产者以获得进一步地处理和分析;*TensorFlow Evaluator配置注意:一旦TensorFlow Evaluator产生了模型输出结果,本实例中采用的管道阶段是可选的,并且可以根据用例的需要与其它处理器和目标进行互换。管道执行在预览管道上,乳腺癌数据记录的输入通过了上面所述的数据流管道过程,包括服务于我们的TensorFlow模型。发送给Kafka生产者的最终输出记录数据(如上所示)包括用于分类的模型所使用的乳腺癌特征,在用户定义的字段TF_Model_Classification中模型输出值为0或1,以及由Expression Evaluator创建的Condition字段中表示相应的癌症状况是良性或恶性。总结本文说明了在Data Collector 3.5.0中使用最新发布的TensorFlow Evaluator。一般来说,这个评估器将允许你提供预训练的TensorFlow模型,用于生成预测结果和分类结果,而无需编写任何自己的代码。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 3, 2018 · 1 min · jiezi

深度学习Trick——用权重约束减轻深层网络过拟合|附(Keras)实现代码

摘要: 深度学习小技巧,约束权重以降低模型过拟合的可能,附keras实现代码。在深度学习中,批量归一化(batch normalization)以及对损失函数加一些正则项这两类方法,一般可以提升模型的性能。这两类方法基本上都属于权重约束,用于减少深度学习神经网络模型对训练数据的过拟合,并改善模型对新数据的性能。目前,存在多种类型的权重约束方法,例如最大化或单位向量归一化,有些方法也必须需要配置超参数。在本教程中,使用Keras API,用于向深度学习神经网络模型添加权重约束以减少过拟合。完成本教程后,您将了解:如何使用Keras API创建向量范数约束;如何使用Keras API为MLP、CNN和RNN层添加权重约束;如何通过向现有模型添加权重约束来减少过度拟合;下面,让我们开始吧。本教程分为三个部分:Keras中的权重约束;图层上的权重约束;权重约束案例研究;Keras中权重约束Keras API支持权重约束,且约束可以按每层指定。使用约束通常涉及在图层上为输入权重设置kernel_constraint参数,偏差权重设置为bias_constraint。通常,权重约束方法不涉及偏差权重。一组不同的向量规范在keras.constraints模块可以用作约束:最大范数(max_norm):强制权重等于或低于给定限制;非负规范(non_neg):强制权重为正数;单位范数(unit_norm):强制权重为1.0;Min-Max范数(min_max_norm):强制权重在一个范围之间;例如,可以导入和实例化约束:# import normfrom keras.constraints import max_norm# instantiate normnorm = max_norm(3.0)图层上的权重约束权重规范可用于Keras的大多数层,下面介绍一些常见的例子:MLP权重约束下面的示例是在全连接层上设置最大范数权重约束:# example of max norm on a dense layerfrom keras.layers import Densefrom keras.constraints import max_norm…model.add(Dense(32, kernel_constraint=max_norm(3), bias_constraint==max_norm(3)))…CNN权重约束下面的示例是在卷积层上设置最大范数权重约束:# example of max norm on a cnn layerfrom keras.layers import Conv2Dfrom keras.constraints import max_norm…model.add(Conv2D(32, (3,3), kernel_constraint=max_norm(3), bias_constraint==max_norm(3)))…RNN权重约束与其他图层类型不同,递归神经网络允许我们对输入权重和偏差以及循环输入权重设置权重约束。通过图层的recurrent_constraint参数设置递归权重的约束。下面的示例是在LSTM图层上设置最大范数权重约束:# example of max norm on an lstm layerfrom keras.layers import LSTMfrom keras.constraints import max_norm…model.add(LSTM(32, kernel_constraint=max_norm(3), recurrent_constraint=max_norm(3), bias_constraint==max_norm(3)))…基于以上的基本知识,下面进行实例实践。权重约束案例研究在本节中,将演示如何使用权重约束来减少MLP对简单二元分类问题的过拟合问题。此示例只是提供了一个模板,读者可以举一反三,将权重约束应用于自己的神经网络以进行分类和回归问题。二分类问题使用标准二进制分类问题来定义两个半圆观察,每个类一个半圆。其中,每个观测值都有两个输入变量,它们具有相同的比例,输出值分别为0或1,该数据集也被称为“ 月亮”数据集,这是由于绘制时,每个类中出现组成的形状类似于月亮。可以使用make_moons()函数生成观察结果,设置参数为添加噪声、随机关闭,以便每次运行代码时生成相同的样本。# generate 2d classification datasetX, y = make_moons(n_samples=100, noise=0.2, random_state=1)可以在图表上绘制两个变量x和y坐标,并将数据点所属的类别的颜色作为观察的颜色。下面列出生成数据集并绘制数据集的完整示例:# generate two moons datasetfrom sklearn.datasets import make_moonsfrom matplotlib import pyplotfrom pandas import DataFrame# generate 2d classification datasetX, y = make_moons(n_samples=100, noise=0.2, random_state=1)# scatter plot, dots colored by class valuedf = DataFrame(dict(x=X[:,0], y=X[:,1], label=y))colors = {0:‘red’, 1:‘blue’}fig, ax = pyplot.subplots()grouped = df.groupby(’label’)for key, group in grouped: group.plot(ax=ax, kind=‘scatter’, x=‘x’, y=‘y’, label=key, color=colors[key])pyplot.show()运行该示例会创建一个散点图,可以从图中看到,对应类别显示的图像类似于半圆形或月亮形状。上图的数据集表明它是一个很好的测试问题,因为不能用直线划分,需要非线性方法,比如神经网络来解决。只生成了100个样本,这对于神经网络而言较小,也提供了过拟合训练数据集的概率,并且在测试数据集上具有更高的误差。因此,也是应用正则化的一个好例子。此外,样本具有噪声,使模型有机会学习不一致的样本的各个方面。多层感知器过拟合在机器学习力,MLP模型可以解决这类二进制分类问题。MLP模型只具有一个隐藏层,但具有比解决该问题所需的节点更多的节点,从而提供过拟合的可能。在定义模型之前,需要将数据集拆分为训练集和测试集,按照3:7的比例将数据集划分为训练集和测试集。# generate 2d classification datasetX, y = make_moons(n_samples=100, noise=0.2, random_state=1)# split into train and testn_train = 30trainX, testX = X[:n_train, :], X[n_train:, :]trainy, testy = y[:n_train], y[n_train:]接下来,定义模型。隐藏层的节点数设置为500、激活函数为RELU,但在输出层中使用Sigmoid激活函数以预测输出类别为0或1。该模型使用二元交叉熵损失函数进行优化,这类激活函数适用于二元分类问题和Adam版本梯度下降方法。# define modelmodel = Sequential()model.add(Dense(500, input_dim=2, activation=‘relu’))model.add(Dense(1, activation=‘sigmoid’))model.compile(loss=‘binary_crossentropy’, optimizer=‘adam’, metrics=[‘accuracy’])然后,设置迭代次数为4,000次,默认批量训练样本数量为32。# fit modelhistory = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)这里将测试数据集作为验证数据集验证算法的性能:# evaluate the model_, train_acc = model.evaluate(trainX, trainy, verbose=0), test_acc = model.evaluate(testX, testy, verbose=0)print(‘Train: %.3f, Test: %.3f’ % (train_acc, test_acc))最后,绘制出模型每个时期在训练和测试集上性能。如果模型确实对训练数据集过拟合了,对应绘制的曲线将会看到,模型在训练集上的准确度继续增加,而测试集上的性能是先上升,之后下降。# plot historypyplot.plot(history.history[‘acc’], label=‘train’)pyplot.plot(history.history[‘val_acc’], label=‘test’)pyplot.legend()pyplot.show()将以上过程组合在一起,列出完整示例:# mlp overfit on the moons datasetfrom sklearn.datasets import make_moonsfrom keras.layers import Densefrom keras.models import Sequentialfrom matplotlib import pyplot# generate 2d classification datasetX, y = make_moons(n_samples=100, noise=0.2, random_state=1)# split into train and testn_train = 30trainX, testX = X[:n_train, :], X[n_train:, :]trainy, testy = y[:n_train], y[n_train:]# define modelmodel = Sequential()model.add(Dense(500, input_dim=2, activation=‘relu’))model.add(Dense(1, activation=‘sigmoid’))model.compile(loss=‘binary_crossentropy’, optimizer=‘adam’, metrics=[‘accuracy’])# fit modelhistory = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)# evaluate the model, train_acc = model.evaluate(trainX, trainy, verbose=0), test_acc = model.evaluate(testX, testy, verbose=0)print(‘Train: %.3f, Test: %.3f’ % (train_acc, test_acc))# plot historypyplot.plot(history.history[‘acc’], label=‘train’)pyplot.plot(history.history[‘val_acc’], label=‘test’)pyplot.legend()pyplot.show()运行该示例,给出模型在训练数据集和测试数据集上的性能。可以看到模型在训练数据集上的性能优于测试数据集,这是发生过拟合的标志。鉴于神经网络和训练算法的随机性,每次仿真的具体结果可能会有所不同。因为模型是过拟合的,所以通常不会期望在相同数据集上能够重复运行得到相同的精度。Train: 1.000, Test: 0.914创建一个图,显示训练和测试集上模型精度的线图。从图中可以看到模型过拟合时的预期形状,其中测试精度达到一个临界点后再次开始减小。具有权重约束的多层感知器过拟合为了和上面做对比,现在对MLP使用权重约束。目前,有一些不同的权重约束方法可供选择。本文选用一个简单且好用的约束——简单地标准化权重,使得其范数等于1.0,此约束具有强制所有传入权重变小的效果。在Keras中可以通过使用unit_norm来实现,并且将此约束添加到第一个隐藏层,如下所示:model.add(Dense(500, input_dim=2, activation=‘relu’, kernel_constraint=unit_norm()))此外,也可以通过使用min_max_norm并将min和maximum设置为1.0 来实现相同的结果,例如:model.add(Dense(500, input_dim=2, activation=‘relu’, kernel_constraint=min_max_norm(min_value=1.0, max_value=1.0)))但是无法通过最大范数约束获得相同的结果,因为它允许规范等于或低于指定的限制; 例如:model.add(Dense(500, input_dim=2, activation=‘relu’, kernel_constraint=max_norm(1.0)))下面列出具有单位规范约束的完整代码:# mlp overfit on the moons dataset with a unit norm constraintfrom sklearn.datasets import make_moonsfrom keras.layers import Densefrom keras.models import Sequentialfrom keras.constraints import unit_normfrom matplotlib import pyplot# generate 2d classification datasetX, y = make_moons(n_samples=100, noise=0.2, random_state=1)# split into train and testn_train = 30trainX, testX = X[:n_train, :], X[n_train:, :]trainy, testy = y[:n_train], y[n_train:]# define modelmodel = Sequential()model.add(Dense(500, input_dim=2, activation=‘relu’, kernel_constraint=unit_norm()))model.add(Dense(1, activation=‘sigmoid’))model.compile(loss=‘binary_crossentropy’, optimizer=‘adam’, metrics=[‘accuracy’])# fit modelhistory = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)# evaluate the model, train_acc = model.evaluate(trainX, trainy, verbose=0)_, test_acc = model.evaluate(testX, testy, verbose=0)print(‘Train: %.3f, Test: %.3f’ % (train_acc, test_acc))# plot historypyplot.plot(history.history[‘acc’], label=‘train’)pyplot.plot(history.history[‘val_acc’], label=‘test’)pyplot.legend()pyplot.show()运行该示例,给出模型在训练数据集和测试数据集上的性能。从下图可以看到,对权重进行严格约束确实提高了模型在验证集上的性能,并且不会影响训练集的性能。Train: 1.000, Test: 0.943从训练和测试精度曲线图来看,模型已经在训练数据集上不再过拟合了,且模型在训练和测试数据集的精度保持在一个稳定的水平。扩展本节列出了一些读者可能希望探索扩展的教程:报告权重标准:更新示例以计算网络权重的大小,并证明使用约束后,确实使得幅度更小;约束输出层:更新示例以将约束添加到模型的输出层并比较结果;约束偏置:更新示例以向偏差权重添加约束并比较结果;反复评估:更新示例以多次拟合和评估模型,并报告模型性能的均值和标准差;进一步阅读如果想进一步深入了解,下面提供一些有关该主题的其它资源:博客机器学习中矢量规范简介(Gentle Introduction to Vector Norms in Machine Learning)APIKeras Constraints APIKeras constraints.pyKerasCore Layers APIKeras Convolutional Layers APIKeras Recurrent Layers APIsklearn.datasets.make_moons API本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

November 30, 2018 · 2 min · jiezi

理解五个基本概念,让你更像机器学习专家

摘要: 这篇文章主要讲述了机器学习的相关内容,阐述了机器学习的主要意义和形成过程。区别了机器学习与AI、深度学习、神经网络等专业词汇。大多数人可能对机器学习有点恐惧或困惑。 脑子中会有它到底是什么,它有什么发展方向,我现在可以通过它挣钱吗等等这样的问题。这些问题的提出都是有依据的。事实上,你可能没有意识到自己其实多年来一直在训练机器学习模型。你看过苹果手机或者是Facebook上的照片吧? 你知道它如何向你展示一组面孔并要求你识别它们吗?其实,通过标记这些照片,你正在训练面部识别模型去识别新面孔。恭喜你,现在可以说你有训练机器学习模型的经验了!但在此之前,请阅读这些机器学习基础知识,以便你可以准确回答任何后续问题。1)机器学习可以预测如果你只是在图片中标记朋友的面孔,那就不是在用机器学习模型。如果你上传了一张新照片系统马上告诉你每个人是谁,那你就是应用了机器学习模型。机器学习的主要意义在于根据图案模型和经过训练的其他因素来预测事物。它可以预测任何事物,如要基于地理位置和卧室数量预测房价,基于一年中的时间和天气的变化预测航班是否会延误,依据图片中的人物特点进行人像识别等等。2)机器学习需要训练你必须告诉机器学习模型它试图预测的是什么。想想一个孩子是如何学习的,他们第一次看到香蕉,他们不知道它是什么。然后你告诉他们这是一个香蕉。下次他们看到另一个,他们会把它识别为香蕉,机器学习就是以类似的方式工作。你可以尽可能多地展示香蕉的照片,告诉它这是香蕉,然后用未经训练的香蕉图片进行测试。但这是一个过度的简化的方法,因为整个过程遗漏了告诉它什么不是香蕉的部分,除此之外还要给它展示不同种类不同颜色、不同角度的香蕉图片等等。3)达到80%的准确度就可以认为是成功的我们还没有达到通过机器学习平台识别图片中的香蕉达到100%的准确率技术的地步,但也没关系,事实证明,人类去识别也不是100%准确。业界的潜规则是达到80%准确度的模型就是成功的。大家可以思考一下,在你收藏的图片中正确识别800,000张是非常有用的,虽然可能还有错误的200,000张,但这已经节省了80%的时间。毋庸置疑,这是非常有价值的。假如我可以用它使你的生产力提高如此之多,你肯定会付我很多钱。而事实证明我可以用机器学习提高你的生产力。(2018年更新:80%规则改为90%规则。)4)机器学习不同于AI,深度学习或神经网络人们经常随意抛出以上这些术语,听起来像专家,但其中有很大差异。AI-人工智能是指在完成特定任务时与人类一样好(或优于人类)的计算机。它也可以指一个可以根据大量输入做出决策的机器人,与终结者或C3PO不同。它是一个非常广泛的术语,不是很有特指性。ML-机器学习是实现AI的一种方法。就是通过解析数据集对某事做出预测。ML平台可以通过许多不同的方式运行训练集来预测事物。NL-神经网络是实现机器学习模型预测事物的方式之一。神经网络的工作有点像人的大脑,通过大量的训练来调整自己,以了解香蕉应该是什么样子。这个过程创建了非常深的节点层。5)在AI变得有自我意识之前,我们还有很长的路要走我并不担心机器学习接管地球。主要是因为如果你曾构建过一个机器学习模型,就会明白它需要依赖你来告诉它究竟该做什么。即使你给出明确的指示,它通常也会出错。你必须对这些体系非常清晰明确,让它突然变化的可能性降到最低。即使是一个显示带有单词的框的简单网页,也需要你准确地告诉它该框出现的位置,形状,颜色,如何在不同的浏览器上工作,如何在不同的设备上正确显示等等。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

November 30, 2018 · 1 min · jiezi

一文了解自然语言处理神经史(下)

摘要: 越来越火的NLP到底经历了什么?2014年-序列到序列模型2014年,Sutskever等人提出序列到序列学习,一种通过神经网络将一个序列映射到另一个序列的通用框架。在该框架中,编码器神经网络逐个符号地处理句子并将其压缩成矢量表示; 然后,解码器神经网络基于编码器状态逐个符号地预测输出符号,在每个步骤中将先前预测的符号作为输入,如下面的图8所示。机器翻译成了这个框架的杀手级应用。2016年,谷歌宣布开始用NMT模型替换其基于单片短语的MT模型(Wu et al.,2016)。根据Jeff Dean的说法,这意味着用500线性神经网络模型替换500,000行基于短语的MT代码。由于其灵活性,该框架现在是自然语言生成任务的首选框架,不同的模型承担编码器和解码器的角色。重要的是,解码器模型不仅可以以序列为条件,而且可以以任意表示为条件。这使得例如基于图像生成标题(Vinyals等人,2015)(如下面的图9中可见),基于表格的文本(Lebret等人,2016),以及基于源代码更改的描述(Loyola等,2017),以及许多其他应用程序。序列到序列学习甚至可以应用于NLP中常见的结构化预测任务,其中NLP输出具有特定结构。简单地说,输出是线性化的,如下面图10中的consituency解析所示。神经网络已经证明了在给予consituency解析的足够数量的训练数据(Vinyals等,2015)和命名实体识别(Gillick等,2016)等的情况下,能够直接学习产生这种线性化输出的能力。用于序列和解码器的编码器通常基于RNN,但是也可以使用其他模型类型,最新的架构主要来自作为序列到序列架构的培养皿MT的工作。最近的模型是卷积编码器(Kalchbrenner等,2016; Gehring等,2017),变换器(Vaswani等,2017),将在下一个部分讨论,以及LSTM和变压器的组合(Chen等,2018)。2015-注意力注意力(Bahdanau等,2015)NMT)的核心创新之一,也是使NMT模型优于基于经典短语的MT系统的关键思想。序列到序列学习的主要瓶颈是它需要将源序列的整个内容压缩成固定大小的矢量。注意力通过允许解码器回顾源序列隐藏状态来减轻这种情况,然后将其作为加权平均值提供给解码器的附加输入,如下面的图11所示。注意力有不同的形式(Luong等,2015)在这里查看简要概述。 注意力广泛适用并且可能对任何需要根据输入的某些部分做出决策的任务有用。它已被应用于consituency解析(Vinyals等,2015),阅读理解(Hermann等,2015)和一次性学习(Vinyals等,2016)等。甚至输入不需要是序列,但可以包括其他表示,如图像字幕的情况(Xu et al.,2015),可以在下面的图12中看到。注意力的一个有用的副作用是,通过根据注意力量检查输入的哪些部分与特定输出相关。注意力也不仅限于查看输入序列;自-注意力可用于查看句子或文档中的周围单词以获得更多上下文敏感的单词表示。多层自-注意力是Transformer架构的核心(Vaswani等,2017),这是目前最先进的NMT模型。2015-基于记忆的网络注意力可以看作是模糊记忆的一种形式,其中记忆由模型的过去隐藏状态组成,模型选择从记忆中所检索的内容。有关注意事项及其与记忆关联的更详细概述,请查看此文章。许多具有更明确记忆的模型已经被提出,它们有不同的变体,例如神经网络图灵机(Graves et al,2014),记忆网络(Weston et al.,2015)[70]和端到端的记忆网络(Sukhbaatar et al.,2015),动态记忆网络( Kumar等,2015),可微神经计算机(Graves等,2016)和递归实体网络(Henaff等,2017)。通常基于与当前状态的相似性来访问内存,类似于注意力,并且通常可以写入和读取存储器,模型在实现和利用内存方面有所不同。例如,端到端记忆网络多次处理输入并更新内存以启用多个推理步骤。神经图灵机还具有基于位置的寻址,允许它们学习简单的计算机程序,如排序。基于记忆的模型通常应用于其中保留较长时间跨度信息的有用任务,例如语言建模和阅读理解。存储器的概念非常通用:知识库或表可以用作存储器,而存储器也可以基于整个输入或其特定部分来填充。2018年 - 预训练语言模型预训练的词嵌入与上下文无关,而且仅用于初始化模型中的第一层。最近几个月,一系列监督任务被用于预训练神经网络(Conneau等,2017; McCann等,2017; Subramanian等,2018)。相比之下,语言模型只需要未标记的文本; 因此,训练可以扩展到数十亿个tokens,新领域和新语言。 2015年首次提出了预训练语言模型(Dai&Le,2015); 直到最近,它们才被证明对各种各样的任务都有益。 语言模型嵌入可以用作目标模型中的特征(Peters等,2018),或者可以对目标任务数据微调语言模型(Ramachandran等,2017; Howard&Ruder,2018)。添加语言模型嵌入比许多任务的最新技术有了很大的改进,如下面的图13所示。预训练语言模型可以用更少的数据进行学习,由于语言模型仅需要未标记的数据,因此对于标记数据稀缺的低资源语言尤其有用。有关预训练语言模型的更多信息,请参阅本文。其他里程碑基于字符的表示:在字符上使用CNN或LSTM来获得基于字符的词表示是相当普遍的,特别是对于形态学丰富的语言和形态信息很重要或具有许多未知单词的任务。据我所知,基于字符的表示首先用于序列标记(Lample等,2016; Plank等,2016)。基于字符的表示减少了必须以增加计算成本处理固定词汇表的需要,并且能够实现诸如完全基于字符的NMT之类的应用(Ling等人,2016; Lee等人,2017)。对抗性学习:对抗性方法已经在风暴中占据了ML的领域,并且在NLP中也以不同的形式使用。对抗性示例越来越广泛地被广泛使用,不仅作为探测模型和理解其失败案例的工具,而且还使它们更加具有鲁棒性(Jia&Liang,2017)。对抗性训练:域对抗性损失(Ganin等,2016; Kim等,2017)是可以同样使模型更加健壮的有用的正规化形式。生成对抗网络(GAN)对于自然语言生成来说还不是太有效(Semeniuta等,2018),但是例如在匹配分布时是有用的(Conneau等,2018)。强化学习:强化学习已经被证明对于具有时间依赖性的任务是有用的,例如在训练期间选择数据(Fang等,2017; Wu等,2018)和建模对话(Liu等,2018)。RL对于直接优化诸如ROUGE或BLEU之类的非可微结束度量而不是优化替代损失(例如摘要中的交叉熵(Paulus等,2018; Celikyilmaz等,2018)和机器翻译也是有效的。(Ranzato等人,2016),反向强化学习在犒赏太复杂而无法指定的环境中可能是有用的,例如视觉叙事(Wang et al。,2018)。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

November 29, 2018 · 1 min · jiezi

一文了解自然语言处理神经史(上)

摘要: 越来越火的NLP到底经历了什么?本文扩展了Herman Kamper和我在2018年深度学习Indaba组织的自然语言处理前沿课程。整个课程的幻灯片都可以在这里找到,这篇文章将主要讨论NLP中基于神经网络方法的近期进展。免责声明:本文尝试将大约15年NLP的发展历程浓缩为今天最相关的八个里程碑,因此遗漏了许多相关和重要的发展。特别是,它严重偏向于当前的神经方法,这可能给人留下此期间没有其他有影响力方法的错误影响。2001年-神经语言模型语言建模是在给定前面的单词的情况下预测文本中的下一个单词的任务。 它可能是最简单的语言处理任务,具有实际应用,如智能键盘和电子邮件响应建议(Kannan et al.,2016)。语言建模有着丰富的历史。基于n-gram的经典方法采用平滑处理看不见的n-gram(Kneser&Ney,1995)。Bengio等人于2001年提出了第一种神经语言模型,一种前馈神经网络,如下图1所示。该模型把n个可以在表C中查找的先前单词向量表示作为输入。现在,这种向量被称为词嵌入。这些词嵌入被连接并送入隐藏层,然后将其输出提供给softmax层。想要了解更多该模型的信息,请查看此文章。最近,前馈神经网络已被用于语言建模的递归神经网络(RNN; Mikolov等人,2010)和长短期记忆网络(LSTM; Graves,2013)所取代。近年来已经提出了许多经典LSTM的新语言扩展模型(请参阅此页面以获得概述)。尽管有这些发展,但经典的LSTM仍然是一个强大的基线(Melis等,2018)。即使Bengio等人的经典前馈神经网络在某些环境中也与更复杂的模型竞争,但这些通常只学会考虑最近的词(Daniluk等,2017)。如何理解这些语言模型捕获的信息是一个活跃的研究领域(Kuncoro等,2018; Blevins等,2018)。语言建模通常是应用RNN时的首选训练场,并成功捕捉到了想象力,许多人通过Andrej的博客文章开始了解。语言建模是无监督学习的一种形式,Yann LeCun也将预测性学习作为获取常识的先决条件(参见NIPS 2016的Cake幻灯片)。 关于语言建模最显著的方面可能是,尽管它很简单,但它是本文讨论的许多后期进展的核心:词嵌入:word2vec的目标是简化语言建模;序列到序列模型:这种模型通过一次预测一个词来生成输出序列;预训练语言模型:这些方法使用语言模型中的表示来进行迁移学习;这反过来意味着NLP中许多最重要的最新进展减少为一种语言建模形式。 为了做“真正的”自然语言理解,仅仅从原始形式的文本中学习可能是不够的,我们将需要新的方法和模型。2008-多任务学习多任务学习是在多个任务上训练的模型之间共享参数的一般方法。在神经网络中,这可以通过绑定不同层的权重来轻松实现。多任务学习的想法在1993年由Rich Caruana首次提出,并应用于道路跟踪和肺炎预测(Caruana,1998)。直观地说,多任务学习鼓励模型学习对许多任务有用的表示。特别对于学习一般的低级表示,集中模型的注意力或在有限量的训练数据的设置中特别有用。有关多任务学习的更全面概述,请查看此文章。Collobert和Weston于2008年首次将多任务学习应用于NLP的神经网络。 在他们的模型中,查找表(或词嵌入矩阵)在两个在不同任务上训练的模型之间共享,如下面的图2所示。共享词嵌入使模型能够在词嵌入矩阵中协作和共享一般的低级信息,这通常构成模型中最大数量的参数。Collobert和Weston在2008年的论文中证明了它在多任务学习中的应用,它引领了诸如预训练词嵌入和使用卷积神经网络(CNN)之类的思想,这些思想仅在过去几年中被广泛采用。它赢得了ICML 2018的时间考验奖(参见此时的时间考验奖论文)。多任务学习现在用于各种NLP任务,并且利用现有或“人工”任务已成为NLP指令集中的有用工具。有关不同附加任务的概述,请查看此文章。虽然通常预先定义参数的共享,但是在优化过程期间也可以学习不同的共享模式(Ruder等,2017)。随着模型越来越多地在多项任务中被评估来评估其泛化能力,多任务学习越来越重要,最近提出了多任务学习的专用基准(Wang et al,2018; McCann et al,2018)。2013-词嵌入文本的稀疏向量表示,即所谓的词袋模型,在NLP中具有悠久的历史。正如我们在上面所看到的,早在2001年就已经使用了词或词嵌入的密集向量表示。 Mikolov等人在2013年提出的主要创新,是通过移动隐藏层和近似目标来使这些词嵌入的训练更有效率。虽然这些变化本质上很简单,但它们与高效的word2vec一起实现了大规模的词嵌入训练。Word2vec有两种模式,可以在下面的图3中看到:连续的词袋(CBOW)和skip-gram。它们的目标不同:一个基于周围的词预测中心词,而另一个则相反。虽然这些嵌入在概念上与使用前馈神经网络学习的嵌入技术没有什么不同,但是对非常大的语料库的训练使它们能够捕获诸如性别,动词时态和国家–首都关系之类的词之间的某些关系,由图4可知:这些关系及其背后的意义引发了对嵌入词的初步兴趣,许多研究调查了这些线性关系的起源(Arora等,2016; Mimno&Thompson,2017; Antoniak&Mimno,2018; Wendlandt等,2018))。然而,使用预训练嵌入作为初始化的固定词嵌入,把它作为当前NLP的主要内容被证明可以提高各种下游任务的性能。虽然捕获的关系word2vec具有直观且几乎神奇的性能,但后来的研究表明word2vec没有任何固有的特殊性:通过矩阵分解也可以学习词嵌入(Pennington等,2014; Levy&Goldberg,2014)和通过适当的调整,经典的矩阵分解方法(如SVD和LSA)可以获得类似的结果(Levy等,2015)。从那时起,许多工作已经开始探索词嵌入的不同方面,可以通过这篇文章了解一些趋势和未来方向。尽管有许多发展,但word2ve仍然是如今被广泛使用的一种流行的选择。Word2vec的范围甚至超出了词级别:带有负抽样的skip-gram,一个基于本地环境学习嵌入的方便目标,已被应用于学习句子的表示(Mikolov&Le,2014; Kiros et al.,2015)-甚至超越NLP,应用到网络(Grover&Leskovec,2016)和生物序列(Asgari&Mofrad,2015)等。一个特别令人兴奋的方向是将不同语言的词嵌入投影到同一空间中以实现(零射击)跨语言转移。越来越有可能以完全无监督的方式(至少对于类似语言)学习良好的投影,这开启了低资源语言和无监督机器翻译的应用(Lample等,2018; Artetxe等,2018)。请查看(Ruder等,2018)的概述。2013年-NLP的神经网络2013年和2014年是神经网络模型开始应用于NLP的标志年份。三种主要类型的神经网络被广泛使用:递归神经网络、卷积神经网络、循环神经网络。递归神经网络(RNN)是处理NLP中普遍存在的动态输入序列问题的明显选择。 Vanilla RNNs(Elman,1990)很快被经典的长短期记忆网络(Hochreiter&Schmidhuber,1997)所取代,后者证明其对消失和爆炸梯度问题更具弹性。在2013年之前,RNN仍然被认为很难训练,Ilya Sutskever的博士论文是改变这种现状的一个关键例子。LSTM细胞可视化可以在下面的图5中看到。双向LSTM(Graves等,2013)通常用于处理左右上下文。随着卷积神经网络(CNN)被广泛用于计算机视觉,它们也开始应用于文本(Kalchbrenner等,2014; Kim等,2014)。用于文本的卷积神经网络仅在两个维度上操作,其中滤波器仅需要沿时间维度移动。下面的图6显示了NLP中使用的典型CNN。卷积神经网络的一个优点是它们比RNN更可并行化,因为每个时间步的状态仅取决于本地环境(通过卷积运算)而不是像RNN取决过去所有状态。CNN可以使用扩张卷积扩展到更宽的感受野,以捕捉更广泛的背景(Kalchbrenner等2016)。 CNN和LSTM也可以组合和堆叠,并且可以使用卷积来加速LSTM。RNN和CNN都将语言视为一个序列。然而,从语言学的角度来看,语言本质上是等级的:单词被组成高阶短语和子句它们本身可以根据一组生产规则递归地组合。将句子视为树而不是序列的语言启发思想产生了递归神经网络,这可以在下面的图7中看到:与从左到右或从右到左处理句子的RNN相比,递归神经网络从下到上构建序列的表示。在树的每个节点处,通过组合子节点的表示来计算新表示。由于树也可以被视为在RNN上施加不同的处理顺序,因此LSTM自然地扩展到树。RNN和LSTM不仅仅可以被扩展来使用分层结构,而且不仅可以根据本地语言学习词嵌入,而且可以基于语法背景来学习词嵌入(Levy&Goldberg,2014);语言模型可以基于句法堆栈生成单词(Dyer et al。,2016); 图形卷积神经网络可以在树上运行(Bastings等,2017)。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

November 29, 2018 · 1 min · jiezi

用深度学习预测专业棋手走法

摘要: 相信很多朋友都会玩国际象棋,那么有尝试过构建一个国际象棋引擎吗,一起来玩玩看吧!我不擅长国际象棋。我父亲在我年幼的时候教过我,但我猜他是那些一直让他们的孩子获胜的爸爸之一。为了弥补世界上最受欢迎的游戏之一的技能的缺乏,我做了任何数据科学爱好者会做的事情:建立一个人工智能来击败我无法击败的人。遗憾的是,它不如AlphaZero(甚至普通玩家)好。但我想看看国际象棋引擎在没有强化学习的情况下如何做,以及学习如何将深度学习模型部署到网络上。比赛在这里!获取数据FICS拥有一个包含3亿场比赛,个人走法,结果以及所涉玩家评级的数据库。我下载了所有在2012年的比赛,其中至少有一名玩家超过2000 ELO。这总计约97000场比赛,有730万个走子。胜利分配是:43000次白方胜利,40000次黑方胜利和14000次平局。极小极大算法了解如何做一个深度学习象棋AI,我必须首先了解传统象棋AI程序。来自于极小极大算法。Minimax是“最小化最大损失”的缩写,是博弈论中决定零和博弈应如何进行的概念。Minimax通常用于两个玩家,其中一个玩家是最大化者,另一个玩家是最小化者。机器人或使用此算法获胜的人假设他们是最大化者,而对手是最小化者。该算法还要求有一个棋盘评估函数,来衡量谁赢谁输。该数字介于-∞和∞之间。最大化者希望最大化此值,而最小化者希望最小化此值。这意味着当你,最大化者,有两个走法可以选择的时候,你将选择一个给你更高评估的那个,而最小化者将做相反的选择。这个游戏假设两个玩家都发挥最佳状态并且没有人犯任何错误。以上面的GIF为例。你,最大化者(圆圈)有三个你可以选择的走法(从顶部开始)。你直接选择的走法取决于你的对手(方块)在走子后将选择的走法。但是你的对手直接选择的走法取决于你走子后选择的走法,依此类推,直到游戏结束。玩到游戏结束会占用大量的计算资源和时间,所以在上面的例子中,选择一个深度,2。如果最小化者(最左边的方块)选择左移,你有1和-1可供选择。你选择1,因为它会给你最高分。如果最小化者选择正确的走法,则选择0,因为它更高。现在是最小化者的回合,他们选择0因为这更低。这个游戏继续进行,一直进行到所有的走子都完成或你的思维时间耗尽。对于我的国际象棋引擎来说,假设白方是最大化者,而黑方是最小化者。如果引擎是白方,则算法决定哪个分支将给出最高的最低分数,假设人们在每次走子时选择最低分数,反之亦然。为了获得更好的性能,该算法还可以与另一种算法结合使用:alpha-beta剪枝。 Alpha-beta剪枝截止系统适用于决定是否应该搜索下一个分支。深度学习架构我的研究始于Erik Bernhardsson关于国际象棋深度学习的优秀文章。他讲述了他如何采用传统方法制作AI下棋并将其转换为使用神经网络作为引擎。第一步是将棋盘转换为输入层的数字形式。我借用了Erik Bernhardsson的编码策略,其中棋盘是一个热编码,每一个方块中都有一个棋子。这总计为768个元素数组(8 x 8 x 12,因为有12种棋子)。Bernhardsson选择将输出图层设为1表示白方胜利,-1表示黑方胜利,0表示平局。他认为游戏中的每个板位置都与结果有关。如果黑方赢了,每个棋的位置都被训练成“支持黑方”,如果白方赢了,则“支持白方棋”。这允许网络返回介于-1和1之间的值,这将告诉你该位置是否更有可能导致白赢或黑赢。我想用稍微不同的评估函数来解决这个问题。网络是否能够看到不是白方还是黑方获胜,而是能够看到哪个走子将导致胜利?首先,我尝试将768元素的棋盘表示放入输出,其中一个位置是输入,下一个位置是输出。当然,这没有用,因为这把它变成了一个多分类问题。这导致引擎适当地选择合法走子时出现太多的错误,因为输出层中的所有768个元素可以是1或0。因此,我查阅了Barak Oshri和Nishith Khandwala的斯坦福大学论文《利用卷积神经网络预测国际象棋中的运动》,了解他们如何解决这个问题。他们训练了7个神经网络,其中1个网络是棋子选择器网络。这个网络决定哪一个方格最有可能被移动。其他六个网络专门针对每一个棋子类型,并决定将一个特定的棋子移动到哪里。如果棋子选择器选择了一个带有兵的方格,那么只有棋子神经网络会响应最有可能移动到的方格。我从他们的想法中借鉴了两个卷积神经网络。第一个,从网络移动,将被训练成采用768元素数组表示并输出专业棋手移动的方格(在方块0和方块63之间)。 第二个网络:移动到网络,将做同样的事情,除了输出层将是专业棋手移动到的地方。我没有考虑谁赢了,因为我认为训练数据中的所有移动都是相对最优的,无论最终结果如何。我选择的架构是两个128卷积层,带有2x2滤波器,后面是两个1024神经元完全连接层。我没有应用任何池,因为池提供位置不变性。图片左上角的猫就像图片右下角的猫一样。然而,对于国际象棋,,棋子国王的值是完全不同于车兵。隐藏图层的激活功能是RELU,而我将softmax应用到最后一层,因此我基本上得到一个概率分布,其中所有方格的概率总和加起来达到100%。我的训练数据是训练集的600万个位置,其余130万个位置用于验证集。在训练结束时,我从网络上获得了34.8%的验证准确率,并且在转移到网络时获得了27.7%的验证准确率。这并不意味着70%的时间它没有学习合法的走子,这只意味着AI没有像验证数据中的专业玩家那样做出相同的举动。相比之下,Oshri和Khandwala的网络平均验证准确率为37%。将深度学习与Minimax结合起来因为现在这是一个分类问题,其中输出可以是64个类之一,这就留下了很大的错误空间。关于训练数据(来自高级别玩家的比赛)的一个警告是,优秀的棋手很少会玩到“将军”。他们知道什么时候输了,通常没有必要跟进整场比赛。这种缺乏平衡的数据使得网络在最终游戏结束时非常混乱。它会选择车来移动,并试图沿对角线移动。如果失败,网络甚至会试图指挥对手的棋子(厚颜无耻!)。为了解决这个问题,我命令输出的概率。然后,我使用python-chess库获取给定位置的所有合法走子的列表,并选择具有最高结果概率的合法走子。最后,我应用了一个带有惩罚的预测分数方程式,用于选择较不可能的走子:400(选择的走子指数之和)。名单上的合法走子越远,其预测得分就越低。例如,如果从网络移动的第一个索引(索引0)与移动到网络的第一个索引相结合是合法的,那么预测分数是400(0 + 0),这是最高可能分数:400。在与材料分数结合使用数字后,我选择了400作为最大预测分数。材料分数是一个数字,可以判断所做的走子是否会捕获一个棋子。根据捕获的棋子,走子的整体得分将得到提升。我选择的材料价值如下:兵:10,马:500,象:500,车:900,后:5000,王:50000。这特别有助于残局。在将杀走子将是第二个最可能的合法行动且预测得分较低的情况下,国王的物质价值将超过它。兵的分数如此之低,因为网络在早期比赛中考虑得足够充分,所以如果它是战略举措,它将会采用兵。然后我将这些分数结合起来,以返回给定任何潜在走子的棋盘的评估。我通过深度为3的minimax算法(使用alpha-beta修剪)提供了这个,并得到了一个可以将杀的可运行国际象棋引擎!使用Flask和Heroku进行部署我在Youtube上使用了Bluefever Software的指南,展示了如何通过向flask服务器发出AJAX请求来制作javascript国际象棋UI并通过它来路由我的引擎。 我使用Heroku将python脚本部署到Web并将其连接到我的自定义域:Sayonb.com。结论虽然引擎的性能没有我希望的那么好,但是我学到了很多关于AI的基础知识,将机器学习模型部署到web上,以及为什么AlphaZero不使用卷积神经网络来玩游戏!可以通过以下方式进行改进:通过使用bigram模型LSTM将从网络移动和移动到网络中的时间序列组合在一起。 这可能有助于将移出和移动到决策中,因为每个目前都是独立接近的。通过添加夺取的棋子的位置来改进棋子的赋值(夺取棋盘中心的兵比它在边缘时夺取更有利)。在使用神经网络预测分数和子力分值之间切换,而不是在每个节点使用两者。这可以允许更高的极小极大算法搜索深度。考虑边缘情况,例如:减少孤立自己的兵的可能性,增加马靠近棋盘中心的可能性。查看代码,或者在GitHub repo用自己的训练数据自己训练一个新网络!本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

November 26, 2018 · 1 min · jiezi

由浅入深:CNN中卷积层与转置卷积层的关系

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~本文由forrestlin发表于云+社区专栏导语:转置卷积层(Transpose Convolution Layer)又称反卷积层或分数卷积层,在最近提出的卷积神经网络中越来越常见了,特别是在对抗生成神经网络(GAN)中,生成器网络中上采样部分就出现了转置卷积层,用于恢复减少的维数。那么,转置卷积层和正卷积层的关系和区别是什么呢,转置卷积层实现过程又是什么样的呢,笔者根据最近的预研项目总结出本文。1. 卷积层和全连接层在CNN提出之前,我们所提到的人工神经网络应该多数情况下都是前馈神经网络,两者区别主要在于CNN使用了卷积层,而前馈神经网络用的都是全连接层,而这两个layer的区别又在于全连接层认为上一层的所有节点下一层都是需要的,通过与权重矩阵相乘层层传递,而卷积层则认为上一层的有些节点下一层其实是不需要的,所以提出了卷积核矩阵的概念,如果卷积核的大小是nm,那么意味着该卷积核认为上一层节点每次映射到下一层节点都只有nm个节点是有意义的,具体的映射方式下一节会讲到。到这里,有些初学者会认为全连接层也可以做到,只要让权重矩阵某些权重赋值为0就可以实现了,例如假设在计算当前层第2个节点时认为上一层的第1个节点我不需要,那么设置w01=0就可以了。其实没错,卷积层是可以看做全连接层的一种特例,卷积核矩阵是可以展开为一个稀疏的包含很多0的全连接层的权重矩阵,下图就是一个由44图片经过33卷积核生成一个大小为22output时,卷积核所展开的全连接层的权重矩阵。卷积核对应的全连接层权重矩阵可以看到,上面的矩阵大小为416,比卷积核33大了不少,因此使用卷积层而不用全连接层第一个原因就是可以极大的减少参数的个数,第二个原因就是卷积核关注的是某几个相邻的节点之间的关系,学习了图片的局部特征,可以说是带有目的性的学习,例如33的卷积核学习的就是相互距离为2的节点之间的关系。这与全连接层无区别的对待所有节点进行学习有极大的差别,这样一来就解决了前馈神经网络不能学习位移不变性的缺点。举个栗子,当我们在前馈神经网络中学习一个44的图片中是否有横折图案时,使用下图中4个训练数据进行训练,那么最终只会对5,6,9,a这四个节点的权重有所调节,然后如果出现如下图最后一张图片作为测试时,就会导致网络无法识别,而由于卷积核在不同节点间权重是共享的,所以就自然而然克服了这个问题。卷积克服平移不变性2. 卷积层的运算过程2.1 最简单的卷积卷积层的运算其实就是将多个卷积核作用于输入上,如下图所示,是最简单的一个卷积核所做的运算,no padding,no stride,底下蓝色方块看做是输入的图片,阴影部分就是33的卷积核(一般卷积核是个正方形,且边长为奇数),卷积核扫过时便与输入相乘再相加,最终得到22的输出,对应青色区域。no padding, no stride的卷积通常一层卷积层会包含多个卷积核,代表着卷积层的输出深度,例如下图就是我们经常在论文中看到的深度网络的架构,其中第一层就是卷积层+最大池化层,先不管最大池化层,至少我们可以明确卷积核的大小是55,卷积核个数是16,该层输出的size是1818。论文常见的卷积层2.2 带padding的卷积从最简单的卷积动图中我们可以看到,经过卷积操作,输出会比输入要小,但是有时候我们希望输出的size要与输入保持一致,而padding就是为了这个而引入的,而这种为了让输入和输出size保持一样的padding,我们会称之为"same padding",可参考下面的动图,卷积核大小是33,padding是1,padding实际的表现就是在输入的四周补0,padding是多少就补多少层,且上限是卷积核大小-1,正如下图中虚线区域,一般来说,论文中是不会给出padding的大小,需要我们自己推导,推导公式可见下文。padding=1的卷积根据padding大小不同,我们可以分为三种padding:same padding: 为了让输出和输入的size一样而补上的padding,例如33的核,same padding = 1,55的核,same padding = 2。full padding: padding = kernel size - 1valid padding: padding = 02.3 stride大于1的卷积stride就是步长,表示卷积核两次卷积操作的距离,默认是1,上述讲的两个例子步长都是1,而下面两个动图展示的是stride为2的情况,分别是无padding和有padding的情况。通常stride大于1时我们称为等距下采样,因为这样输出肯定会丢失信息,size比输入的小。no padding, stride=2的卷积padding=1, stride=2的卷积2.4 卷积核输入输出size与卷积核的关系上文中我们提到padding通常需要我们自己算出来,那么我们该怎么算呢,其实就是根据输入输出size和卷积核大小的关系算出来的,上面提到的几种卷积,其实就是卷积操作的三个参数,核大小(F)、padding(P)和stride(S),如果细心的读者在看动图时就会发现输出size是可以根据输入size和那三个参数计算出来的,公式如下,这里只给出宽度的计算,高度也是一样的。W2=(W1−F+2P)÷S+1这里我们注意到上面的公式是有除法的,所以就会存在除不尽的情况,这时候我们需要向下取整,这种情况我们称为odd卷积,其过程可参考下面动图。odd卷积3. 转置卷积层讲完卷积层后,我们来看CNN中另一个进行卷积操作的层次转置卷积层,有时我们也会称做反卷积层,因为他的过程就是正常卷积的逆向,但是也只是size上的逆向,内容上不一定,所以有些人会拒绝将两者混为一谈。转置卷积层最大的用途就是上采样了,刚刚我们说到在正常卷积中stride大于1时我们进行的是等距下采样,会让输出的size比输入小,而转置卷积层我们就会用stride小于1的卷积进行上采样,使输出的size变大,所以转置卷积层还有个别称就是分数卷积层。上采样最常见的场景可以说就是GAN中的生成器网络,如下图所示,虽然论文作者使用的是conv,但由于它的步长为1/2,所以代表的就是转置卷积层。转置卷积例子为了理解转置卷积层,我们需要明白什么叫做正常卷积的逆向,这通常也是新手难以理解的地方,下面笔者通过两个图来更好的解释,第一个图是正常卷积的过程,第二个图就是其对应的转置卷积,在第一个图中,大的正方形中数字1只参与小正方形中数字1的计算,那么在转置卷积中,大正方形的1也只能由小正方形的1生成,这就是逆向的过程。no padding, no stride的卷积转置卷积.png和讲述正常卷积的过程一样,笔者下面也会一一给出相对应的转置卷积。3.1 no padding no stride的卷积对应的转置卷积上面用作解释转置卷积的逆向过程时用到的图其实就是最简单(no padding, no stride)卷积以及其对应的转置卷积,这里给出它的动图。no padding, no stride的卷积转置3.2 带padding的卷积的转置卷积在正卷积中如果是有padding,那么在转置卷积中不一定会有padding,其计算公式下文会给出,这里先给出2.2对应的转置卷积动图。padding为1的卷积转置3.3 stride大于1的卷积的转置卷积在本节一开始就讲到,stride大于1的卷积是下采样,那么其对应的转置卷积便是stride小于1的上采样,但是不管是在pyTorch还是TensorFlow中,convTranspose函数的参数都是整数,不可能将stride设置为小于1的浮点数,那么我们会依然给convTranspose函数传入正卷积的stride,而convTranspose是怎么做的呢,可见下面的动图,它是2.3中无padding卷积对应的转置卷积,我们先不看转置卷积中的转置padding,也就是动图中外部的虚线区域,然后会发现每两个蓝色块之间都插入了白色块,也就是0,这样一来,卷积核每移动一步不就相当于是只移动了1/2步嘛,所以我们可以得出每两个蓝色块之间需要插入stride -1个0。stride为2的卷积转置3.4 正卷积和转置卷积的换算关系3.4.1 转置卷积的padding从上面3个例子的转置卷积中我们可以发现,如果用正卷积实现转置卷积时,卷积核的大小是保持不变的,而stride是为正卷积stride的倒数(只是我们插入0来模拟分数移动),最后,转置卷积的padding要怎么算呢,虽然如果我们调用pyTorch或TensorFlow时不需要管,传入正卷积的padding即可,但是理解convTranspose是怎么做的也有助于我们理解转置卷积。说了这么多,其实在我们为了让转置卷积保证是正卷积的逆向时,我们就不得不补充转置padding,我们用PT表示,其计算公式为:PT=F−P−1,其中F为正卷积的核大小,P为正卷积的padding。3.4.2 转置卷积的输出size这个其实很好算,因为我们都说转置卷积的逆向,所以我们只需在2.4给出公式中转换下求出W1即可,公式如下:W1=(W2−1)×S−2P+F其中S是正卷积的stride,P是正卷积的padding,F是正卷积的核边长。3.4.3 odd卷积的转置卷积这个可以说是转置卷积中最难理解的一种情况,在2.4中我们提到在除以stride时可能会除不尽要向下取整,那么我们在求W1时就会有不确定性,举个栗子,还是第3节一开始给出的图,我们是希望将W/4的图放大到W/2的程度,这是一个转置卷积的过程,我们先算一遍正卷积,从W/2下采样到W/4,k代表核边长为3,s是stride为1/2的倒数,即2,padding根据2.4的公式推导为1,所以正卷积的计算公式是:(W2−3+2)÷2+1=W4+12,然后向下取整就是W4,和图上显示的是一样,但是如果我们通过3.4.2的公式反过来计算,就是(W4−1)×2−2+3=W2−1,这就是odd转置卷积的不确定性,我们再回头看2.4给出的动图,会发现右边和下边的填充区域我们并没有进行卷积运算,因为向下取整而忽略了,所以我们在转置卷积时需要将这部分加回来,因此,在PyTorch中convTranspose函数还有一个参数output_padding就是负责处理这个的,TensorFlow应该也有相应的参数,笔者不太熟悉,下面就是PyTorch对该参数的描述,和我们遇到的情形一模一样。PyTorch中转置卷积的output_padding参数至于output_padding的值,应该为(W1−F+2P)%S,在上面提到的例子中就应该是1。4. 总结本文先是介绍了卷积神经网络和传统的前馈神经网络的联系和区别,然后再通过不同参数的卷积过程阐述卷积运算,最后再介绍刚入门深度学习时晦涩难懂的转置卷积,给出不同参数下正卷积所对应的转置卷积,最后总结出在卷积运算中所用到的公式。希望笔者上述的分析和解释能对刚入门CNN的同学有所帮助,而且笔者是从事iOS开发的,对于CNN和深度学习也是刚刚入门,希望各位AI大牛们不吝指教。5. 参考文档知乎上对CNN的直观解释,平移不变性笔者是从这里了解到的《A guide to convolution arithmetic for deep learning》的github,本文的动图都来自于此关于转置卷积和卷积的联系和区别相关阅读【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识

November 22, 2018 · 1 min · jiezi

用“活着的”CNN进行验证码识别

1 验证码验证码( CAPTCHA )是一种区分用户是计算机或人的公共全自动程序。在 CAPTCHA 测试中,作为服务器的计算机会自动生成一个问题由用户来解答。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答 CAPTCHA 的问题,所以回答出问题的用户就可以被认为是人类。2 CNN 验证码识别传统的方法是通过两个不相关的步骤来进行文字识别:1)将图片中的文字的位置进行定位,然后通过“小框”来切分,将图片中的文字剪切下来 2)再进行识别。但是在现今的验证码识别中,当要识别的图片中的文字变成手写体互相重叠,这种“切分”法就难以排上用场。因此卷积神经网络(CNN)就被用来识别这些无从下手的手写体。这种CNN 是通过一个或多个卷积层和顶端的全连通层(对应经典的神经网络)组成来对图像识别。CNN 训练模型需要大量的人工标注的图片来训练,但是本文方法就是自主产生随机的字符并产生相应的图片来在运行过程中调整参数。本文关注具有 4 个字符的的验证码图片。每个字符在输出层被表现为 62 个神经元。我们可以假设一个映射函数即:将前 62 个神经元分配给序列中的第一个字符,第二批 62 个神经元分配给序列中的第二个字符。因此,对于字符xi所对应的神经元的索引为输出层一共有 462=128 个。如果第一个预测字符的索引为 c0=52,因此可以反推预测的字符为3 实现步骤1 验证码生成1 验证码中的字符number = [‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’]ALPHABET = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’]alphabet = [‘a’, ‘b’, ‘c’, ’d’, ’e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ’l’, ’m’, ’n’, ‘o’, ‘p’, ‘q’, ‘r’, ’s’, ’t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’]gen_char_set = number + ALPHABET # 用于生成验证码的数据集2 生成验证码的字符 # char_set=number + alphabet + ALPHABET, char_set=gen_char_set, # char_set=number, captcha_size=4): """ 生成随机字符串,4位 :param char_set: :param captcha_size: :return: """ captcha_text = [] for i in range(captcha_size): c = random.choice(char_set) captcha_text.append(c) return captcha_text3 按照字符生成对应的验证码def gen_captcha_text_and_image(): """ 生成字符对应的验证码 :return: """ image = ImageCaptcha() captcha_text = random_captcha_text() captcha_text = ‘’.join(captcha_text) captcha = image.generate(captcha_text) captcha_image = Image.open(captcha) captcha_image = np.array(captcha_image) return captcha_text, captcha_image4 训练def crack_captcha_cnn(w_alpha=0.01, b_alpha=0.1): “““1 定义CNN cnn在图像大小是2的倍数时性能最高, 如果你用的图像大小不是2的倍数,可以在图像边缘补无用像素。 np.pad(image,((2,3),(2,2)), ‘constant’, constant_values=(255,)) # 在图像上补2行,下补3行,左补2行,右补2行 "”” x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1]) # w_c1_alpha = np.sqrt(2.0/(IMAGE_HEIGHTIMAGE_WIDTH)) # # w_c2_alpha = np.sqrt(2.0/(3332)) # w_c3_alpha = np.sqrt(2.0/(3364)) # w_d1_alpha = np.sqrt(2.0/(83264)) # out_alpha = np.sqrt(2.0/1024) # 3 conv layer w_c1 = tf.Variable(w_alpha * tf.random_normal([3, 3, 1, 32])) b_c1 = tf.Variable(b_alpha * tf.random_normal([32])) conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding=‘SAME’), b_c1)) conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding=‘SAME’) conv1 = tf.nn.dropout(conv1, keep_prob) w_c2 = tf.Variable(w_alpha * tf.random_normal([3, 3, 32, 64])) b_c2 = tf.Variable(b_alpha * tf.random_normal([64])) conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, w_c2, strides=[1, 1, 1, 1], padding=‘SAME’), b_c2)) conv2 = tf.nn.max_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding=‘SAME’) conv2 = tf.nn.dropout(conv2, keep_prob) w_c3 = tf.Variable(w_alpha * tf.random_normal([3, 3, 64, 64])) b_c3 = tf.Variable(b_alpha * tf.random_normal([64])) conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, w_c3, strides=[1, 1, 1, 1], padding=‘SAME’), b_c3)) conv3 = tf.nn.max_pool(conv3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding=‘SAME’) conv3 = tf.nn.dropout(conv3, keep_prob) # Fully connected layer w_d = tf.Variable(w_alpha * tf.random_normal([8 * 20 * 64, 1024])) b_d = tf.Variable(b_alpha * tf.random_normal([1024])) dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]]) dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d)) dense = tf.nn.dropout(dense, keep_prob) w_out = tf.Variable(w_alpha * tf.random_normal([1024, MAX_CAPTCHA * CHAR_SET_LEN])) b_out = tf.Variable(b_alpha * tf.random_normal([MAX_CAPTCHA * CHAR_SET_LEN])) out = tf.add(tf.matmul(dense, w_out), b_out) # 36*4 # out = tf.reshape(out, (CHAR_SET_LEN, MAX_CAPTCHA)) # 重新变成4,36的形状 # out = tf.nn.softmax(out) return out由于时间和设备的限制,我在验证码生成字符串中删去了英文字母只剩下了数字进行训练。要不然可以算到地老天荒也还是3%的准确率。下图是gen_char_set = number + ALPHABET的训练1万多步的结果的训练截图5 总结本文采用了“活着的 CNN”进行验证码识别,可以免去大量进行人工标注的步骤,对工作效率有不小的提升。文 / JoeCDC数学爱好者编 / 荧声本文已由作者授权发布,版权属于创宇前端。欢迎注明出处转载本文。本文链接:https://knownsec-fed.com/2018…想要订阅更多来自知道创宇开发一线的分享,请搜索关注我们的微信公众号:乐趣区。欢迎留言讨论,我们会尽可能回复。欢迎点赞、收藏、留言评论、转发分享和打赏支持我们。打赏将被完全转交给文章作者。感谢您的阅读。 ...

November 1, 2018 · 2 min · jiezi

当深度学习遇见自动文本摘要

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~本文由columneditor发表于云+社区专栏作者:姚均霖导语 :随着近几年文本信息的爆发式增长,人们每天能接触到海量的文本信息,如新闻、博客、聊天、报告、论文、微博等。从大量文本信息中提取重要的内容,已成为我们的一个迫切需求,而自动文本摘要(automatic text summarization)则提供了一个高效的解决方案。介绍随着近几年文本信息的爆发式增长,人们每天能接触到海量的文本信息,如新闻、博客、聊天、报告、论文、微博等。从大量文本信息中提取重要的内容,已成为我们的一个迫切需求,而自动文本摘要(automatic text summarization)则提供了一个高效的解决方案。根据Radev的定义[3],摘要是“一段从一份或多份文本中提取出来的文字,它包含了原文本中的重要信息,其长度不超过或远少于原文本的一半”。自动文本摘要旨在通过机器自动输出简洁、流畅、保留关键信息的摘要。自动文本摘要有非常多的应用场景,如自动报告生成、新闻标题生成、搜索结果预览等。此外,自动文本摘要也可以为下游任务提供支持。尽管对自动文本摘要有庞大的需求,这个领域的发展却比较缓慢。对计算机而言,生成摘要是一件很有挑战性的任务。从一份或多份文本生成一份合格摘要,要求计算机在阅读原文本后理解其内容,并根据轻重缓急对内容进行取舍,裁剪和拼接内容,最后生成流畅的短文本。因此,自动文本摘要需要依靠自然语言处理/理解的相关理论,是近几年来的重要研究方向之一。自动文本摘要通常可分为两类,分别是抽取式(extractive)和生成式(abstractive)。抽取式摘要判断原文本中重要的句子,抽取这些句子成为一篇摘要。而生成式方法则应用先进的自然语言处理的算法,通过转述、同义替换、句子缩写等技术,生成更凝练简洁的摘要。比起抽取式,生成式更接近人进行摘要的过程。历史上,抽取式的效果通常优于生成式。伴随深度神经网络的兴起和研究,基于神经网络的生成式文本摘要得到快速发展,并取得了不错的成绩。本文主要介绍基于深度神经网络的生成式自动文本摘要,着重讨论典型的摘要模型,并介绍如何评价自动生成的摘要。对抽取式和不基于深度神经网络的生成式自动文本摘要感兴趣的同学可以参考1。生成式文本摘要生成式文本摘要以一种更接近于人的方式生成摘要,这就要求生成式模型有更强的表征、理解、生成文本的能力。传统方法很难实现这些能力,而近几年来快速发展的深度神经网络因其强大的表征(representation)能力,提供了更多的可能性,在图像分类、机器翻译等领域不断推进机器智能的极限。借助深度神经网络,生成式自动文本摘要也有了令人瞩目的发展,不少生成式神经网络模型(neural-network-based abstractive summarization model)在DUC-2004测试集上已经超越了最好的抽取式模型[4]。这部分文章主要介绍生成式神经网络模型的基本结构及最新成果。基本模型结构生成式神经网络模型的基本结构主要由编码器(encoder)和解码器(decoder)组成,编码和解码都由神经网络实现。编码器负责将输入的原文本编码成一个向量(context),该向量是原文本的一个表征,包含了文本背景。而解码器负责从这个向量提取重要信息、加工剪辑,生成文本摘要。这套架构被称作Sequence-to-Sequence(以下简称Seq2Seq),被广泛应用于存在输入序列和输出序列的场景,比如机器翻译(一种语言序列到另一种语言序列)、image captioning(图片像素序列到语言序列)、对话机器人(如问题到回答)等。Seq2Seq架构中的编码器和解码器通常由递归神经网络(RNN)或卷积神经网络(CNN)实现。基于递归神经网络的模型RNN被称为递归神经网络,是因为它的输出不仅依赖于输入,还依赖上一时刻输出。如上图所示,t时刻的输出h不仅依赖t时刻的输入x,还依赖t-1时刻的输出,而t-1的输出又依赖t-1的输入和t-2输出,如此递归,时序上的依赖使RNN在理论上能在某时刻输出时,考虑到所有过去时刻的输入信息,特别适合时序数据,如文本、语音、金融数据等。因此,基于RNN实现Seq2Seq架构处理文本任务是一个自然的想法。典型的基于RNN的Seq2Seq架构如下图所示:图中展示的是一个用于自动回复邮件的模型,它的编码器和解码器分别由四层RNN的变种LSTM[5]组成。图中的向量thought vector编码了输入文本信息(Are you free tomorrow?),解码器获得这个向量依次解码生成目标文本(Yes, what’s up?)。上述模型也可以自然地用于自动文本摘要任务,这时的输入为原文本(如新闻),输出为摘要(如新闻标题)。目前最好的基于RNN的Seq2Seq生成式文本摘要模型之一来自Salesforce,在基本的模型架构上,使用了注意力机制(attention mechanism)和强化学习(reinforcement learning)。这个模型将在下文中详细介绍。基于卷积神经网络的模型 Seq2Seq同样也可以通过CNN实现。不同于递归神经网络可以直观地应用到时序数据,CNN最初只被用于图像任务[6]。CNN通过卷积核(上图的A和B)从图像中提取特征(features),间隔地对特征作用max pooling,得到不同阶层的、由简单到复杂的特征,如线、面、复杂图形模式等,如下图所示。CNN的优势是能提取出hierarchical的特征,并且能并行高效地进行卷积操作,那么是否能将CNN应用到文本任务中呢?原生的字符串文本并不能提供这种可能性,然而,一旦将文本表现成分布式向量(distributed representation/word embedding)[7],我们就可以用一个实数矩阵/向量表示一句话/一个词。这样的分布式向量使我们能够在文本任务中应用CNN。如上图所示,原文本(wait for the video and do n’t rent it)由一个实数矩阵表示,这个矩阵可以类比成一张图像的像素矩阵,CNN可以像“阅读”图像一样“阅读”文本,学习并提取特征。虽然CNN提取的文本特征并不像图像特征有显然的可解释性并能够被可视化,CNN抽取的文本特征可以类比自然语言处理中的分析树(syntactic parsing tree),代表一句话的语法层级结构。基于卷积神经网络的自动文本摘要模型中最具代表性的是由Facebook提出的ConvS2S模型[9],它的编码器和解码器都由CNN实现,同时也加入了注意力机制,下文将详细介绍。当然,我们不仅可以用同一种神经网络实现编码器和解码器,也可以用不同的网络,如编码器基于CNN,解码器基于RNN。前沿A Deep Reinforced Model for Abstractive Summarization这是由Salesforce研究发表的基于RNN的生成式自动文本摘要模型,通过架构创新和若干tricks提升模型概括长文本的能力,在CNN/Daily Mail、New York Times数据集上达到了新的state-of-the-art(最佳性能)。针对长文本生成摘要在文本摘要领域是一项比较困难的任务,即使是过去最好的深度神经网络模型,在处理这项任务时,也会出现生成不通顺、重复词句等问题。为了解决上述问题,模型作者提出了内注意力机制(intra-attention mechanism)和新的训练方法,有效地提升了文本摘要的生成质量。模型里应用了两套注意力机制,分别是1)经典的解码器-编码器注意力机制,和2)解码器内部的注意力机制。前者使解码器在生成结果时,能动态地、按需求地获得输入端的信息,后者则使模型能关注到已生成的词,帮助解决生成长句子时容易重复同一词句的问题。模型的另一创新,是提出了混合式学习目标,融合了监督式学习(teacher forcing)和强化学习(reinforcement learning)。首先,该学习目标包含了传统的最大似然。最大似然(MLE)在语言建模等任务中是一个经典的训练目标,旨在最大化句子中单词的联合概率分布,从而使模型学习到语言的概率分布。但对于文本摘要,仅仅考虑最大似然并不够。主要有两个原因,一是监督式训练有参考“答案”,但投入应用、生成摘要时却没有。比如t时刻生成的词是"tech",而参考摘要中是"science",那么在监督式训练中生成t+1时刻的词时,输入是"science",因此错误并没有积累。但在实际应用中,由于没有ground truth,t+1时刻的输入是错误的"tech"。这样引起的后果是因为没有纠正,错误会积累,这个问题被称为exposure bias。另一个原因是,往往在监督式训练中,对一篇文本一般只提供一个参考摘要,基于MLE的监督式训练只鼓励模型生成一模一样的摘要,然而正如在介绍中提到的,对于一篇文本,往往可以有不同的摘要,因此监督式学习的要求太过绝对。与此相反,用于评价生成摘要的ROUGE指标却能考虑到这一灵活性,通过比较参考摘要和生成的摘要,给出摘要的评价(见下文评估摘要部分)。所以希望在训练时引入ROUGE指标。但由于ROUGE并不可导的,传统的求梯度+backpropagation并不能直接应用到ROUGE。因此,一个很自然的想法是,利用强化学习将ROUGE指标加入训练目标。那么我们是怎么通过强化学习使模型针对ROUGE进行优化呢?简单说来,模型先以前向模式(inference)生成摘要样本,用ROUGE指标测评打分,得到了对这个样本的评价/回报(reward)后,再根据回报更新模型参数:如果模型生成的样本reward较高,那么鼓励模型;如果生成的样本评价较低,那么抑制模型输出此类样本。最终的训练目标是最大似然和基于ROUGE指标的函数的加权平均,这两个子目标各司其职:最大似然承担了建立好的语言模型的责任,使模型生成语法正确、文字流畅的文本;而ROUGE指标则降低exposure bias,允许摘要拥有更多的灵活性,同时针对ROUGE的优化也直接提升了模型的ROUGE评分。构建一个好的模型,除了在架构上需要有创新,也需要一些小技巧,这个模型也不例外。在论文中,作者使用了下列技巧:使用指针处理未知词(OOV)问题;共享解码器权重,加快训练时模型的收敛;人工规则,规定不能重复出现连续的三个词。综上所述,深度学习+强化学习是一个很好的思路,这个模型第一次将强化学习应用到文本摘要任务中,取得了不错的表现。相信同样的思路还可以用在其他任务中。Convolutional Sequence to Sequence LearningConvS2S模型由Facebook的AI实验室提出,它的编码器和解码器都是基于卷积神经网络搭建的。这个模型主要用于机器翻译任务,在论文发表的时候,在英-德、英-法两个翻译任务上都达到了state-of-the-art。同时,作者也尝试将该模型用于自动文本摘要,实验结果显示,基于CNN的Seq2Seq模型也能在文本摘要任务中达到接近state-of-the-art的表现。模型架构如下图所示。乍看之下,模型很复杂,但实际上,它的每个部分都比较直观,下面通过分解成子模块,详细介绍ConvS2S。首先来看embedding部分。这个模型的embedding比较新颖,除了传统的semantic embedding/word embedding,还加入了position embedding,将词序表示成分布式向量,使模型获得词序和位置信息,模拟RNN对词序的感知。最后的embedding是语义和词序embedding的简单求和。之后,词语的embedding作为输入进入到模型的卷积模块。这个卷积模块可以视作是经典的卷积加上非线性变换。虽然图中只画出一层的情况,实际上可以像经典的卷积层一样,层层叠加。这里着重介绍非线性变换。该非线性变换被称为Gated Linear Unit (GLU)[10]。它将卷积后的结果分成两部分,对其中一部分作用sigmoid变换,即映射到0到1的区间之后,和另一部分向量进行element-wise乘积。这个设计让人联想到LSTM中的门结构。GLU从某种程度上说,是在模仿LSTM和GRU中的门结构,使网络有能力控制信息流的传递,GLU在language modeling被证明是非常有效的[10]。除了将门架构和卷积层结合,作者还使用了残差连接(residual connection)[11]。residual connection能帮助构建更深的网络,缓解梯度消失/爆炸等问题。除了使用加强版的卷积网络,模型还引入了带多跳结构的注意力机制(multi-step attention)。不同于以往的注意力机制,多跳式注意力不仅要求解码器的最后一层卷积块关注输入和输出信息,而且还要求每一层卷积块都执行同样的注意力机制。如此复杂的注意力机制使模型能获得更多的历史信息,如哪些输入已经被关注过。像A Deep Reinforced Model for Abstractive Summarization一样,ConvS2S的成功之处不仅在于创新的结构,还在于细致入微的小技巧。在ConvS2S中,作者对参数使用了非常仔细的初始化和规范化(normalization),稳定了方差和训练过程。这个模型的成功证明了CNN同样能应用到文本任务中,通过层级表征长程依赖(long-range dependency)。同时,由于CNN具有可高度并行化的特点,所以CNN的训练比RNN更高效。比起RNN,CNN的不足是有更多的参数需要调节。评估摘要评估一篇摘要的质量是一件比较困难的任务。对于一篇摘要而言,很难说有标准答案。不同于很多拥有客观评判标准的任务,摘要的评判一定程度上依赖主观判断。即使在摘要任务中,有关于语法正确性、语言流畅性、关键信息完整度等标准,摘要的评价还是如同”一千个人眼里有一千个哈姆雷特“一样,每个人对摘要的优劣都有自己的准绳。自上世纪九十年代末开始,一些会议或组织开始致力于制定摘要评价的标准,他们也会参与评价一些自动文本摘要。比较著名的会议或组织包括SUMMAC,DUC(Document Understanding Conference),TAC(Text Analysis Conference)等。其中DUC的摘要任务被广泛研究,大多数abstractive摘要模型在DUC-2004数据集上进行测试。目前,评估自动文本摘要质量主要有两种方法:人工评价方法和自动评价方法。这两类评价方法都需要完成以下三点:决定原始文本最重要的、需要保留的部分;在自动文本摘要中识别出1中的部分;基于语法和连贯性(coherence)评价摘要的可读性(readability)。人工评价方法评估一篇摘要的好坏,最简单的方法就是邀请若干专家根据标准进行人工评定。这种方法比较接近人的阅读感受,但是耗时耗力,无法用于对大规模自动文本摘要数据的评价,和自动文本摘要的应用场景并不符合。因此,文本摘要研究团队积极地研究自动评价方法。自动评价方法为了更高效地评估自动文本摘要,可以选定一个或若干指标(metrics),基于这些指标比较生成的摘要和参考摘要(人工撰写,被认为是正确的摘要)进行自动评价。目前最常用、也最受到认可的指标是ROUGE(Recall-Oriented Understudy for Gisting Evaluation)。ROUGE是Lin提出的一个指标集合,包括一些衍生的指标,最常用的有ROUGE-n,ROUGE-L,ROUGE-SU:ROUGE-n:该指标旨在通过比较生成的摘要和参考摘要的n-grams(连续的n个词)评价摘要的质量。常用的有ROUGE-1,ROUGE-2,ROUGE-3。ROUGE-L:不同于ROUGE-n,该指标基于最长公共子序列(LCS)评价摘要。如果生成的摘要和参考摘要的LCS越长,那么认为生成的摘要质量越高。该指标的不足之处在于,它要求n-grams一定是连续的。ROUGE-SU:该指标综合考虑uni-grams(n = 1)和bi-grams(n = 2),允许bi-grams的第一个字和第二个字之间插入其他词,因此比ROUGE-L更灵活。 作为自动评价指标,ROUGE和人工评定的相关度较高,在自动评价摘要中能给出有效的参考。但另一方面,从以上对ROUGE指标的描述可以看出,ROUGE基于字的对应而非语义的对应,生成的摘要在字词上与参考摘要越接近,那么它的ROUGE值将越高。但是,如果字词有区别,即使语义上类似,得到的ROUGE值就会变低。换句话说,如果一篇生成的摘要恰好是在参考摘要的基础上进行同义词替换,改写成字词完全不同的摘要,虽然这仍是一篇质量较高的摘要,但ROUGE值会呈现相反的结论。从这个极端但可能发生的例子可以看出,自动评价方法所需的指标仍然存在一些不足。目前,为了避免上述情况的发生,在evaluation时,通常会使用几篇摘要作为参考和基准,这有效地增加了ROUGE的可信度,也考虑到了摘要的不唯一性。对自动评价摘要方法的研究和探索也是目前自动文本摘要领域一个热门的研究方向。总结本文主要介绍了基于深度神经网络的生成式文本摘要,包括基本模型和最新进展,同时也介绍了如何评价自动生成的摘要。自动文本摘要是目前NLP的热门研究方向之一,从研究落地到实际业务,还有一段路要走,未来可能的发展方向有:1)模仿人撰写摘要的模式,融合抽取式和生成式模型;2)研究更好的摘要评估指标。希望本文能帮助大家更好地了解深度神经网络在自动文本摘要任务中的应用。Reference[1] Text Summarization Techniques: A Brief Survey[2] A Survey on Automatic Text Summarization[3] Introduction to the Special Issue on Summarization[4] A Deep Reinforced Model for Abstractive Summarization[5] Understanding LSTM Networks[6] LeNet5, convolutional neural networks[7] What is word embedding in deep learning[8] A Deep Reinforced Model for Abstractive Summarization[9] Convolutional Sequence to Sequence Learning[10] Language Modeling with Gated Convolutional Networks[11]Deep Residual Learning for Image Recognition问答深度学习的原理和具体实现是什么?相关阅读深度学习角度 | 图像识别将何去何从?基于深度学习的文本分类?10分钟上手,OpenCV自然场景文本检测(Python代码+实现) 【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识 ...

October 30, 2018 · 1 min · jiezi