第1章,怎么样自学计算机编程

计算机 3
第1章 深度学习的发展介绍 一日清晨,朝阳未热,少年小飞未醒,接到了一个陌生的电话,电话中念到“双眸剪秋水,一手弹春风,歌尽琵琶怨,醉来入梦中。
”这首诗如何?电话中是一位声音甜美,自称小鱼的女生,听到这,昏沉朦胧的少年,突然振作了,既疑惑又激动,思考一会儿,紧张又兴奋地说道“虽然我不懂诗,但感觉剪和弹用得非常妙呀。
请问我认识你吗?”“哎呀,不好意思,我打错电话啦,我还以为你是我闺蜜”,电话那头娇羞地答到。
机智如小飞,肯定不会错过这美丽的错误,然后就立即回道……以上故事,是我将图灵在1950年《机器与智能》中关于“模仿游戏”[1]的一段改编,而上述诗句是来自于中科院院士张钹展示的机器人所做的诗。
随着现代技术的进步,特别是深度学习(DeepLearning)[2]的发展,完成上述任务并不再是天方夜谭。
我们不妨和图灵一起思考,如果机器能够完成上述的问答,那小飞怎么去判断是人或者是机器呢?那所谓的意识又是什么呢?带着这些令人头痛但又激动的思考,我们现在就开始深度学习的入门之旅。
在一百多年前,可编程计算机第一次被构想出时,人们就想象着机器是否可以变得智能。
如今,人工智能已是一个欣欣向荣的领域,拥有着许多实际应用及激动人心的研究主题。
我们期望智能软件能够应用到自动化家居、语音识别、图像理解、医疗诊断及辅助基本科学的研究中去。
人与计算机就像天平的两端,机器善于计算,只要问题能被一系列数学规则形式化描述出来,人们就可以编写程序让机器执行。
比如求解线性方程组,计算行星轨迹等,虽然这些 深度学习实战 任务很复杂,但对于机器而言却很简单。
但有些问题虽然看似简单,但人却难以描述,比如人如何识别口语,文字或脸部图像。
由于人难以描述这些本能就会的任务,虽然人处理很简单,但对于机器而言却难于上青天。
而人工智能的目标就是去解决人容易执行,但很难形式化描述的任务。
在早期的人工智能中,我们想要机器智能地完成某项任务,我们首先需要使用形式化语言,硬编码关于该任务的知识;然后计算机通过这些形式化语言,自动使用逻辑推理规则去推理状态。
但其中根本问题在于,我们要知道如何解决某项问题。
比如,我们想教机器人下棋,我们知道确定的规则,也知道某些下棋的技巧,然后我们将各种规则、各种技巧通过编程实现出来,那么机器就学会了下棋。
机器棋艺的高低,其实只是编程人员棋艺的高低,机器只是比人类运算快一些罢了。
但有些事情,我们是很难描述清楚的,我喜欢一朵花,一首诗,一个人,但问我为什么喜欢,我却不知道。
同样地,你想让机器去赏析一首诗,一朵花,一个人,那也是很难完成的任务。
深度学习便是这些更直觉问题的一种解决方案。
这种解决方案允许电脑从经验中学习并依靠层次化概念去理解世界。
通过从经验中收集知识,这种方法避免了人类手工地去形式化列举电脑所需的知识,层次化概念允许电脑从更简单的概念中学习更抽象的概念。
也许现在你已经有点晕眩了,那我们就先轻松地讲一个故事吧。
认识小鱼同学后,为了博取小鱼同学的欢心,小飞就想亲手做一道黄焖鸡给小鱼。
于是他就翻看了一下食谱,开始了“实验”:首先,准备各种食材;然后,将各种配菜预炒,再放入鸡块爆炒;爆炒入味后再放入一碗水,用锅盖焖10分钟,最终黄焖鸡就出锅了。
小飞尝了尝亲手做的黄焖鸡,如你所想,才将鸡块入口,就吐了出来,因为实在太难吃了。
但小飞并没有灰心,总结了一下,少放了点水,多加了点盐,再多炒了会儿鸡块,鼓起勇气一尝。
好咸啊!虽然又失败了,但总体还是挺开心的,因为至少可以吃了。
一鼓作气,再次总结,再次实验,忐忑地再次试尝,总算有了黄焖鸡该有的味儿了。
起锅打包,小飞开心地去找小鱼同学去了…… 从以上的故事中,我们发现了什么?发现小飞买了很多鸡肉,我们知道了,小飞一开始不会做黄焖鸡,但通过不断尝试,是可以做好黄焖鸡的。
在此期间,小飞做了什么事呢?其实只是在调整,放多少水,放多少盐,煮多久,炒多久等,而这个过程就是一个简单的学习行为。
同理,在机器学习中,我们并不是将做黄焖鸡的整个过程,每个细节都编程给机器,相反,我们把小飞的学习过程,复制给机器。
做一次黄焖鸡,我们可以将其称为一个数据,而放水,放盐,煮多久,我们可以称为数据的特征(Feature),对于学习最朴素的理解其实就是调整数据特征各自的重要性。
我们再仔细剖析一下上面的故事,有一个过程叫作食材准备阶段,我们可以简单地将该阶段作为“黄焖鸡”数据的一个特征,当然,我们也可以将这一特征再细分一下,多少姜、多少辣椒配多少鸡块呢?而酱油的多少和水的多少又如何调配呢?那这些又如何影响爆炒和黄焖的时间呢?数据的特征直接影响着学习的难度及最终结果的好坏。
如果我们先学习油盐酱醋的调配,将其组成配料特征,这样就简化了整个学习过程,而这种特征到特征的学习,我们就称为表征学习或表示学习(RepresentationLearning[3],“表征”是一个心理学词汇,翻译成表征更贴切些,但“表示”更常用些)。
如果我们将做黄焖鸡的过程,细分得非常细致,也就是特征维度(数量)很高,那么每一维度对最终学习任务好坏的影响就越小,如香菇的
2 第1章深度学习的发展介绍 量对黄焖鸡的好坏影响很小,我们很难通过调整香菇的量,去调整黄焖鸡的做法,而香菇特征也相互影响着其他特征的选择。
因此我们先学习配菜这一简单的概念或特征,然后再学习一些更抽象的概念,一层一层的抽象,最终仅仅去学习“选材”“黄焖”这些特别抽象的特征,这就是所谓的深度学习。
1.1如何阅读本书 本书是一本有关深度学习的入门实战教程,目的在于尽可能以一种轻松的方式,讲解一些深度学习核心的技术,关键的思想,以及常用的技巧方法。
需要注意的是,深度学习充斥着大量的数学公式,大多数人可能会望而生畏,看着公式就头痛欲裂。
但数学只是工具,数学公式只是简化我们的描述,我们更应该做的是深入理解这些公式背后的哲学内涵。
本书同样会列出很多的公式,但请读者们不要在意所谓的公式,应该多去看一些文字性描述,理顺公式的每一次演变,公式是帮助你快速的记忆,并不是你的负担。
也许,对于大多数读者,看懂各种算法,了解各种思想,但编写程序还是无从下手,本书将使用IPythonNotebook进行模块化编程练习,我们会一步一步地动手实践,希望能帮助你从理论走向实践,并从实践中加深对理论知识的进一步理解。
深度学习能够火爆的最主要原因是大数据的到来,以及运算能力的大大提高,针对GPU编程的Theano,TensorFlow,Torch等深度学习库,都是非常好的学习资源,如果你想从事深度学习研究,则应该至少掌握一种以上的深度学习库。
但本书的目的在于让你不那么头痛欲裂地跨入深度学习领域,本书并不是一本深度学习平台指导用书。
在本书的最后一章,我们会教你如何搭建TensorFlow深度学习库,帮助你铺垫更广阔的知识世界。
我们希望能给你一个小板凳,然后你可以站上去,希望你拥有瞭望远方的喜悦,希望你能享受在微风中的呼吸。
因此,如果你有些惧怕数学公式或编程能力相对较弱,这些都没关系。
最重要的是你憧憬着深度学习,相信集体的力量,渴望着人工智能,同时也不太在意一些稍显不严谨的语言,那或许这是一本属于你的书。
需要注意的是,本书作为入门书籍,只会重点介绍深度学习在实际应用中的技术及方法,深度学习的一些高级研究主题,如自动编码器(Autoencoder)[4],受限玻尔兹曼机(RBM)[5]等非监督学习研究主题并不涉及。
但这些主题是深度学习的研究重点,对于有志从事深度学习研究的专业人员而言,这些主题才是更广阔的世界。
每章我们都会分为两个部分,第一部分介绍该章节的深度学习技术,第二部分进行编程练习,在每章的末尾,我们给出了参考代码,希望在你想要放弃时给你点帮助。
本书的知识内容主要参考于IanGoodfellow,YoshuaBengio,AaronCourville所著的DeepLearning以及斯坦福大学的CS231公开课,你也可以将本书作为学习这些书的铺垫。
1.2深度学习沉浮史 喜欢一个人,就应该去了解她的过去,感受她的曾经。
想要学习深度学习,不妨也粗略地了解下它的过去,下面我们列出了一些深度学习的关键趋势。
•深度学习拥有悠久的历史,曾经几度“改嫁”,反映着不同的哲学观点,并且流行度也是几度兴衰。

3 深度学习实战 •深度学习随着可训练数据的不断增长变得更加有用。
•随着计算机硬件,软件基础设施的提高,深度学习模型尺寸正在变大。
•随着精确度不断地提高,深度学习已经开始应用于越来越复杂的领域。
“滚滚长江东逝水,浪花淘尽英雄,是非成败转头空,青山依旧在,几度夕阳红……”许多读者或许已经听说过深度学习作为一种令人激动的新技术,刺激着整个人工智能领域的发展,并且让整个社会前所未有地讨论着人工智能这一话题。
但事实上,深度学习最早可以追溯到二十世纪四十年代。
深度学习之所以似乎是新的,是因为其流行度几经沉浮,说得严重些,深度学习以前是遭到同行鄙视的。
深度学习历经多次“良妻改嫁”并跟随“夫君”改名多次,并且只是最近才称为“深度学习”。
其实这个领域已经更名了许多次,其也映射出不同学者,不同思想对该领域的影响。
泛泛地说,深度学习的发展有三段起伏:在1940—1960年,深度学习被称为控制论,随着生物学习理论的发展,以及感知机模型的实现,爆发了第一波热潮。
第二波浪潮为1980—1995年,开始于联结主义[6]方法,随着使用反向传播算法训练1~2个隐藏层的神经网络而迅速“膨胀”。
而当前以深度学习之名复苏是始于2006年,由于使用逐层贪婪非监督式预训练[4]方法初始化深层神经网络权重,使得网络在数据集较少时依然可以有效地训练深层的神经网络,而在2012年后深度学习彻底被工业界所接纳,大量的公司及科研人员开始关注了深度学习。
1.2.1模拟生物大脑的疯狂远古时代 大浪淘沙,如今洗尽铅华的一些算法是模拟生物学习的计算模型。
深度学习过去的名字也被称为人工神经网络(ANNs)[7]。
深度学习模型也可以说是受生物大脑(无论人类大脑还是动物大脑)启发的工程系统。
并且,用于机器学习的神经网络有时也用于帮助理解大脑的功能。
神经网络的思考方式主要基于两种观点,一种观点是,大脑证明了智能行为是可能的,那么去构建智能最直接的方式就是模拟大脑,复制其功能;另一种观点则相反,期望通过神经网络去理解人类智慧及其原则。
因此,神经网络模型除了解决工程问题外,还试图解释人类智慧等基本科学问题。
现代的术语“深度学习”已经超出了神经科学在当前机器学习模型上的观点,其引出了一个更通用的学习原则,即多层次组合的原则,这个原则能够应用于不拘泥于神经元启发的机器学习框架。
现代深度学习的鼻祖是受神经科学观点启发的简单线性模型。
该模型如上述的“黄焖鸡模型”一样,使用一组n维输入值x1,…,xn作为数据,然后将它们与输出y关联起来。
该模型能够学习一组权重w1,…,wn并且计算它们的输出。
神经网络研究的第一个高潮以控制论著称。
麦卡洛克–皮茨神经元[8]是一种早期的脑功能模型,该线性模型通过测试f(x,w)值的正负,能够识别两种不同的输入分类。
当然,为了该模型符合期望的分类定义,其权重需要正确设置,但这些权重需要通过人类操作设置。
在20世纪50年代,感知机[9]成为第一个从给定的输入样例中学习分类权重的模型。
大约在相同时期,自适应线性单元(ADALINE)[10]同样能够自动地学习预测数字数据。
这些成就虽然很简单,但给了当时的人工智能领域很大的冲击。
因为当时的主流思想是计算机能够做正
4 第1章深度学习的发展介绍 确的逻辑推理将本质上解决人工智能问题。
一时间神经网络受到了大量的关注与投资,但其中也有许多不切实际的想法,因此也受到了许多学者的“仇视”。
MIT人工智能实验室创始人MarvinMinsky和SeymourPapert就是持怀疑态度的两位学者。
1969年,他们在一本开创性著作中表达了这种质疑,书中严谨分析了感知机的局限性,书名很贴切,就叫《感知机》,其理论证明了感知机无法学习异或函数。
看到线性模型中这些缺陷的批评者们,掀起了强烈反对生物启发学习的浪潮,这也导致了神经网络的第一次主要衰败。
但这些简单的学习算法深远地影响了现代机器学习的格局。
用于学习自适应线性单元权重的训练算法是随机梯度下降算法的特例,而随机梯度下降算法的稍微修改版本仍然是如今深度学习领域统治级的训练算法。
如今,对于深度学习研究而言,神经科学被当作是一种重要的灵感源泉,但其不再是该领域主要的指导了。
而神经科学在深度学习领域中被削弱的主要原因在于我们对大脑还没有足够的认知,并使用其作为指导。
神经科学给了我们理由去期望,一个单独的深度学习算法能够解决许多不同的任务。
神经科学家已经发现,如果雪貂的大脑被重新连接,将视觉信号传送到听觉处理区域,雪貂就能通过它们大脑的听觉处理区域学习“看”。
我们也许可以假设,大多数哺乳动物大脑可能使用一个单独的算法去解决大脑中的大多数不同任务。
在这假设之前,机器学习研究是碎片化的,不同的研究社区研究自然语言处理、视觉、运动以及语音识别任务。
如今,这些应用领域仍然分离,但对于深度学习研究团体来说,同时研究许多甚至是全部应用领域是常见的。
我们能够从神经科学中获得一些粗糙的指导方针,如神经认知机[11]受到哺乳动物视觉系统的启发,引入了一种强大的图像处理模型结构,并在之后成为卷积神经网络[12]的基础。
虽然神经科学是深度学习重要的灵感来源,但并不需要将其作为一种刚性指南,真实神经元相比于神经元模型来说复杂得多,但使用更真实的神经元并没有提高机器学习的性能。
同时,虽然神经科学已经成功地启发了一些神经网络结构,但由于我们对于生物学习还没有足够多的了解,神经科学还无法给我们训练这些结构提供太多的指导。
各种宣传经常强调深度学习与大脑的相似性。
虽然深度学习研究相比于其他的机器学习研究,如核函数机或贝叶斯统计,确实更像去模拟大脑工作,但并不应该仅仅把深度学习作为模拟大脑的一种尝试。
现代深度学习灵感来源于许多领域,尤其是应用数学基础,像是线性代数,概率论,信息论及数值优化等。
虽然有一些深度学习研究以神经科学作为重要的灵感来源,但其他一些完全和神经科学无关。
需要注意的是,在算法级别努力理解大脑如何工作依然是盛行的,这种努力主要以“计算神经学”著称,并且是深度学习的一个单独的研究领域,研究人员反复地在这两个领域移动是很平常的。
深度学习领域主要关心怎样构建计算机系统,来成功地解决所需的智能任务;计算神经学领域主要关心构建更精确模型,模拟大脑如何真实工作。
1.2.2联结主义近代 在20世纪80年代,出现了第二波神经网络研究高潮,并被称为联结主义或并行分布处理[3]。
认知科学是以一种跨学科的方法组合多个不同水平的分析去理解思维,而联结主义就出现在认知科学的这一背景下。
在20世纪80年代早期,大多数认知科学家研究符号推理模
5 深度学习实战 型,尽管当时非常流行,但符号模型非常难于解释大脑如何能够真实地使用神经元执行这些符号。
因此联结主义开始研究能够依据神经元执行的认知模型[13]。
联结主义的核心思想是大量简单的计算单元连接在一起能够完成智能行为,这种观点同样适用于生物神经系统的神经元及计算模型的隐藏单元。
并且在20世纪80年代随着联结主义兴起的一些关键概念,仍然是如今深度学习的核心。
其中之一是分布式表征[14]。
这种观点是系统的高级或抽象特征由多个子特征组合而来,并且通过组合不同的子特征,系统可以构造不同的高级特征。
例如,假设需要有一个视觉系统能够识别汽车、卡车和鸟,并且这些对象可能是红色、绿色或蓝色。
一种表述方式是使用独立神经元:红卡车、红汽车、红鸟、绿卡车等。
这需要9个不同的神经元,并且每个神经元必须独立地学习颜色或对象概念。
另一种提高的方式是使用分布式表征,三个神经元描述颜色,三个神经元描述对象。
这仅仅需要6个神经元而不是9个,并且描述红色的神经元能够学习汽车,卡车以及鸟类图像中的红色,不仅仅局限于特定对象的分类图片。
联结主义的另一个成就是成功地使用反向传播算法[3]训练深度神经网络。
该算法的流行度也是跌宕起伏,但如今依然是训练深度模型统治级的方法。
神经网络研究的第二个高潮持续到20世纪90年代中期,当基于神经网络和其他AI技术的投资者寻找投资时,又开始表现不切实际的雄心壮志,当智能研究无法满足这些不合理的期望时,投资者非常的失望。
同时,其他机器学习模型也在飞速地发展,如核函数机[15],概率图模型[16]都在许多重要任务中取得了良好的结果。
这两个因素导致了神经网络流行度的衰退,这种衰退一直持续到了2007年。
虽然处于低迷期,但一些人仍然没有将其放弃。
加拿大高级研究所(CIFAR)通过其神经计算与自适应感知机(NCAP)研究计划保持神经网络研究的存活。
该项目联合了由多伦多大学的GeoffreyHinton,蒙特利尔大学的YoshuaBengio以及纽约大学的YannLeCun领导的机器学习研究团队,并且还囊括了一大批顶尖的神经科学,人类和计算机视觉方面专家。
1.2.3百花齐放,层次结构主导,模型巨大的当代 神经网络研究的第三波高潮开始于2006年的重大突破。
GeoffreyHinton展示了一种名叫深度置信网络(DeepBeliefNetworks,DBN)[17]的神经网络,它通过使用逐层贪婪预训练的方式能够高效地训练网络。
其他的CIFAR附属研究机构也迅速地展示了同样的策略可以应用在许多其他的深度网络中,并且系统地提高了测试样例的泛化能力。
这波神经网络的研究,通俗化地使用深度学习术语来强调深层概念的重要性。
相比之前,研究者能够训练更深的神经网络,并且关注深度理论。
这时,深度神经网络性能远远超过了基于其他机器学习技术的智能系统和手工设计的功能。
时间到了2012年,Hinton领导的深度学习小组使用ALexNet[18]网络,在ImageNet计算机视觉挑战赛上,将当时最佳图像识别性能提高了一倍。
从此引爆了学术界及工业界,并且ALexNet网络和传统的CNN网络并没有本质区别,其核心只是选用了更简单的ReLU神经元并使用GPU进行加速学习。
人们开始重新审视一大批以前遭到抛弃的深度学习模型,并且各大公司也开始了超大规模深度模型的研究,超大规模数据集的“军备竞赛”也正在上演。
如今,神经网络的第三个高潮依然持续着,但深度学习研究的焦点在这波高潮期间已经
6 第1章深度学习的发展介绍 戏剧化地改变了,第三波高潮开始关注新非监督学习技术以及深度模型在小数据集的泛化能力。
但这些高级主题还处在实验室研究之中,由于篇幅有限,本文仅介绍被成熟应用于工业界的监督式学习算法,有兴趣的读者可以参阅IanGoodfellow所著的DeepLearning的高级研究主题。
总之,深度学习是机器学习的一个重要分支,并且随着过去几十年的发展,已经吸收了大量神经科学,统计学以及应用数学的知识。
在最近几年中,由于计算机更强的能力,更大的数据集以及一些训练深度网络的新技术兴起,其流行度已经获得了极大的增长。
但正如这些年神经网络的跌宕起伏一样,目前深度学习虽然处于上升期,但有可能会来到一个梦想破碎的蛰伏期,没有人能说得准,甚至还有大量的科学家开始担忧起人工智能可能会是一个潘多拉魔盒。
但勇敢不是不畏惧,而是心怀恐惧,仍然向前。
我们使用图灵于1950年《机器与智能》论文中的最后一句话,作为我们的开始,接下来,我们就将正式进入本书的学习。
Wecanonlyseeashortdistanceahead,butwecanseeplentytherethatneedstobedone.——AlanMathisonTuring 1.3Python简易教程 Python是一种非常简单易学的解释性语言。
由于强大的开源库支持(NumPy、Scipy、Matplotlib),其广泛应用于科学计算中。
如果你励志成为一名数据科学家或数据“攻城狮”,那么Python就是你必须要学会的工具之
一。
接下来我们将简短地介绍下Python、NumPy、Matplotlib的使用,如果你已经十分熟悉这些内容,可以轻松地跳过该章节,直接进入下一章节的学习。
本章节教程内容主要参考于斯坦福大学cs228课程的Python教程,具体详情可以使用下列网址查看: /kuleshov/cs228-material/blob/master/tutorials/python/cs228-python-tutorial.ipynb。
1.3.1Anaconda搭建 Anaconda是开发Python最常用的开源平台之
一,已经为你安装了Python中最常用的工具库(NumPy、Matplotlib、Scipy、IPython等),使用起来非常方便,读者可以访问https://www.continuum.io/downloads/网址进行下载。
本书的教程将使用Python2.7+版本,因此确保你下载的版本符合我们的要求。
在本节中,将逐步学习以下内容。
•Python基本使用:基本数据类型(Containers、Lists、Dictionaries、Sets、Tuples),函数,类; •NumPy:数组,数组索引,数据类型,数组运算,广播;•Matplotlib:Plotting,Subplots,Images。
1.3.2IPythonNotebook使用 IPythonNotebook(现改名JupyterNotebook)是一种基于Web技术的交互式计算文档,
7 深度学习实战 使用浏览器作为客户端进行交互,其页面被保存为.ipynb的类JSON文件格式,是非常高效的教学演示工具。
本书的教学教程主要就使用IPythonNotebook进行分模块演示。
安装Anaconda时,默认就安装了IPythonNotebook,读者只需直接启动即可。
•启动IPythonNotebook首先启动Jupyter:如图1-1所示,启动dos窗口,将路径转换到文件:“第1章练习-numpy.ipynb”所在路径,然后输入jupyternotebook(或ipythonnotebook)命令,再按Enter键确认。
这时,浏览器会自动启动Jupyer。
图1-1启动JupyterNotebook命令行示意图 1.3.3Python基本用法 Python是一种面向对象的解释型高级编程语言。
很多时候,由于其代码具有高可读性,且只需要数行代码就可以表达复杂的功能,使Python看起来简直和伪代码一样。
如下列代码所示,为Python实现经典的快速排序算法例子。
defquicksort(arr):iflen(arr)<=1:returnarrpivot=arr[len(arr)/2]left=[xforxinarrifxpivot]returnquicksort(left)+middle+quicksort(right) printquicksort([3,6,8,10,1,2,1])[1,1,2,3,6,8,10] 1.3.3.1基本数据类型和大多数编程语言一样,Python拥有一系列的基本数据类型,比如整型、浮点型、布尔 型和字符串等。
这些基本数据类型的使用方式和其他语言的使用方式类似。

8 第1章深度学习的发展介绍 •整型和浮点型 输入:x=3printx,type(x)printx+1#加;printx-1#减;printx*2#乘;printx**2#幂乘;x+=1printx#打印"4"。
x*=2printx#打印"8"。
y=2.5printtype(y)#打印""。
printy,y+1,y*2,y**2#打印"2.53.55.06.25"。
#python不支持(x++)或(x--)运算。
printy++ 输出:3 42694
8 2.53.55.06.25 File"",line2printy++^ SyntaxError:invalidsyntax •布尔型 Python实现了所有的布尔逻辑,但使用的是英语单词(and、or、not和xor),而不是我们习惯的操作符(&&和||等)。
输入:t,f=True,Falseprinttype(t)#打印""。
printtandf#逻辑AND;printtorf#逻辑OR;printnott#逻辑NOT;printt!
=f#逻辑XOR; 输出: FalseTrueFalseTrue •字符串 输入:hello='hello'#字符串可以使用单引号。
world="world"#也可以使用双引号。
printhello,len(hello),world 输出:hello5world
9 深度学习实战 hw=hello+''+world#字符串拼接。
printhw#打印"helloworld"。
hw12='%s%s%d'%(hello,world,12)#按格式输出。
printhw12#打印"helloworld12"。
helloworldhelloworld12 也可以将字符串当作是一个对象,有很多的方法,如下列代码所示。
输入: s="hello"prints.capitalize()#将字符串首字母大写;打印"Hello"。
prints.upper()#将字符串转换成大写;打印"HELLO"。
prints.rjust
(7)#字符串向右对齐,使用空格进行占位;打印"hello"。
prints.center
(7)#字符串居中,使用空格对左右进行占位;打印"hello"。
prints.replace('l','(ell)')#使用子串代替规定处字符。
#打印"he(ell)(ell)o"。
print'world'.strip()#删除空白字符(开头或结尾);打印"wor ld"。
输出: HelloHELLOhellohellohe(ell)(ell)o world 如果想掌握更多关于字符串的应用与操作,有兴趣的读者可以访问以下网址来进行学习:#string-methods。
Python有4种容器类型:列表(Lists)、字典(Dictionaries)、集合(Sets)和元组(Tuples)。
1.3.3.2列表(Lists) 在Python中,列表相当于数组,但是列表长度可变,且能包含不同类型元素。
输入:xs=[3,1,2]#创建列表。
printxs,xs[2]printxs[-1]#负值索引相当于从列表的末端进行反向索引;打印"2"。
xs[2]='foo'#列表可以包含不同类型的元素。
printxsxs.append('bar')#添加新元素到列表末端。
printxsx=xs.pop()#移除列表末端元素。
printx,xs 输出:[3,1,2]22[3,
1,'foo'][3,
1,'foo','bar']bar[3,
1,'foo'] 如果想掌握更多关于列表的应用与操作,有兴趣的读者可以访问以下网址来进行学习:#more-on-lists。
•切片(Slicing)为了同时获取列表中的多个元素,Python提供了一种简洁的语法去访问子列表,这就 10 第1章深度学习的发展介绍 是切片。
输入:nums=range
(5)#range是内置的创建整型列表函数。
printnums#打印"[0,1,2,3,4]"。
printnums[2:4]#获取索引2-4(排除)的子列表;打印"[2,3]"。
printnums[2:]#获取索引2到末的子列表;打印"[2,3,4]"。
printnums[:2]#获取索引开始到2(排除)的子列表;打印"[0,1]"。
printnums[:]#获取整个列表;打印"[0,1,2,3,4]"。
printnums[:-1]#切片也可以使用负号索引;"打印[0,1,2,3]"。
nums[2:4]=['s','we']#用新子列表替换指定索引列表中的子列表。
printnums #打印"[0,1,s,we,4]"。
输出: [0,1,2,3,4][2,3][2,3,4][0,1][0,1,2,3,4][0,1,2,3][0,
1,'s','we',4] •循环(Loops) 可以按以下方式遍历列表中的每一个元素。
输入:animals=['cat','dog','monkey']foranimalinanimals: printanimal 输出:catdogmonkey 如果想要在循环体内访问每个元素的指针,可以使用内置的枚举(enumerate)函数,注意:起始ID为
0。
输入:animals=['cat','dog','monkey']foridx,animalinenumerate(animals): print'#%d:%s'%(idx+1,animal) 输出:#1:cat#2:dog#3:monkey •列表解析(ListComprehensions) 在编程的时候,我们常常要将列表中的每一元素使用特定的表达式进行转换。
下面是一个简单例子,将列表中的每个元素转换成它的平方。
输入:nums=[0,1,2,3,4]squares=[]forxinnums: squares.append(x**2)printsquares 输出:[0,1,4,9,16] 也可以使用更简单的列表解析(ListComprehension)。
11 深度学习实战 输入:nums=[0,1,2,3,4]squares=[x**2forxinnums]printsquares 列表解析也可以包含条件语句。
输入:nums=[0,1,2,3,4]even_squares=[x**2forxinnumsifx%2==0]printeven_squares 输出:[0,1,4,9,16] 输出:[0,4,16] 1.3.3.3字典(Dictionaries) 字典用来存储(键,值)对,其和Java中的Map差不多。
输入: d={'cat':'cute','dog':'furry'}#为数据创建字典。
printd['cat'] #从字典中获取词条(entry);打印"cute"。
print'cat'ind#检查字典中是否有给定键值(key);打印"True"。
d['fish']='wet'#给定键值,创建词条。
printd['fish'] #打印"wet"。
printd.get('monkey','N/A')#获取字典中元素默认值;打印"N/A"。
printd.get('fish','N/A')#获取字典中元素默认值;打印"wet"。
deld['fish'] #从字典中移除元素。
printd.get('fish','N/A')#"fish"不再是字典中的键值;打印"N/A"。
输出:cute Truewet N/AWetN/A 字典的详细用法可以访问#dict网址来进行学习。
•迭代字典 输入:d={'人':
2,'猫':
4,'蜘蛛':8}foranimalind: legs=d[animal]print'%s有%d腿'%(animal,legs) 输出:猫有4腿蜘蛛有8腿人有2腿 也可以使用iteritems方法进行迭代。
输入:d={'人':
2,'猫':
4,'蜘蛛':8}foranimal,legsind.iteritems(): print'%s有%d腿'%(animal,legs) 输出:猫有4腿蜘蛛有8腿人有2腿 12 第1章深度学习的发展介绍 •字典解析(DictionaryComprehensions) 和列表解析类似,字典解析允许你轻松地构造字典,如下列代码所示。
输入:nums=[0,1,2,3,4]even_num_to_square={x:x**2forxinnumsifx%2==0}printeven_num_to_square 输出:{0:0,2:4,4:16} 1.3.3.4集合(Sets) 集合存放着无序的不同元素,在Python中,集合使用花括号表示,如果将一个序列转换为集合,那么该序列的重复元素将会被剔除,并且原有的顺序也将被打散。
输入:animals={'cat','dog'}print'cat'inanimals#检查是否元素在集合中;打印"True"。
print'fish'inanimals#打印"False"。
animals.add('fish')print'fish'inanimalsprintlen(animals) #向集合中添加元素。
#集合中的元素个数; animals.add('cat')#添加一个存在的元素到集合中,其没有变化。
printlen(animals)animals.remove('cat')#从集合中移除一个元素。
printlen(animals) 输出:True FalseTrue 33
2 •集合循环 虽然集合中的循环语法和列表中的一样,但由于集合是无序的,因此访问集合元素的时候,不能做关于顺序的假设。
输入:animals={'cat','dog','fish'}foridx,animalinenumerate(animals): print'#%d:%s'%(idx+1,animal) 输出:#1:fish#2:dog#3:cat •集合解析(SetComprehensions) 和字典、列表一样,可以很方便地使用集合解析构建集合。
输入:frommathimportsqrtprint{int(sqrt(x))forxinrange(30)} 输出:set([0,1,2,3,4,5]) 13 深度学习实战 1.3.3.5元组(Tuples) 元组是一个(不可改变)有序列表。
元组和列表在很多方面都很相似,最大的区别在于元组可以像字典一样使用键/值对,并且还可以作为集合中的元素,而列表不行。
如下列代码所示。
输入:#通过元组键值创建字典。
d={(x,x+1):xforxinrange(10)}t=(5,6)#创建元组。
printtype(t)printd[t]printd[(1,2)] 输出: 51 1.3.3.6函数(Functions) Python使用关键词def来定义函数,如下列代码所示。
输入:defsign(x): ifx>0:return'正' elifx<0:return'负' else:return'零' forxin[-1,0,1]:printsign(x) 也经常使用可选参数来定义函数,如下列代码所示。
输入:defhello(name,loud=False): ifloud:print'HELLO,%s'%name.upper() else:print'Hello,%s!
'%name hello('Bob')hello('Fred',loud=True) 输出:负零正 输出:Hello,Bob!
HELLO,FRED 14 第1章深度学习的发展介绍 1.3.3.7类(Classes) 在Python中,定义类的语法很直接,如下列代码所示。
输入: classGreeter: #构造函数。
def__init__(self,name): self.name=name#创建一个变量实例。
#实例方法。
defgreet(self,loud=False): ifloud: print'HELLO,%s!
'%self.name.upper() else: print'Hello,%s'%self.name g=Greeter('Fred')#创建一个Greeter类实例。
g.greet() #调用实例方法;打印"Hello,Fred"。
g.greet(loud=True)#调用实例方法;打印"HELLO,FRED!
"。
输出:Hello,FredHELLO,FRED!
1.3.4NumPy NumPy是Python中用于科学计算的核心库,其提供了高性能的多维数组对象及相关工具,其用法和MATLAB比较相似,具体详情可以参考如下网址: /NumPy_for_Matlab_Users。
要使用NumPy,首先要导入numpy包:importnumpyasnp。
1.3.4.1数组(Arrays) NumPy中的数组是由相同数据类型组成的网格,可以通过非负整型的元组进行访问,数组维度数量也被称为数组的秩或阶(rank),数组的形状(shape)是一个由整数构成的元组,描述数组不同维度上的大小。
我们可以从Python内嵌的列表中创建数组,然后利用方括号访问其中的元素,如下列代码所示。
输入:a=np.array([1,2,3])#创建秩为1的数组。
printtype(a),a.shape,a[0],a[1],a[2]a[0]=5#改变数组元素。
printa#创建秩为2的数组。
b=np.array([[1,2,3],[4,5,6]])printb 输出:(3L,)123 [523] [[123][456]] 15 深度学习实战 printb.shapeprintb[0,0],b[0,1],b[1,0] (2L,3L)124 NumPy同样提供了大量的方法创建数组,如下列代码所示。
输入:#创建2*2的零矩阵。
a=np.zeros((2,2))printa#创建各元素值为1的1*2矩阵。
b=np.ones((1,2))printb#创建各元素值为7的2*2矩阵。
c=np.full((2,2),
7,)printc#创建3*3的单位矩阵。
d=np.eye(3)printd 输出:[[0.0.][0.0.]] [[1.1.]] [[7.7.][7.7.]] [[1.0.0.][0.1.0.][0.0.1.]] #使用随机数创建3*3的矩阵。
e=np.random.random((3,3))printe [[1.31744138e-01[6.38513903e-01[8.57136438e-02 5.75103263e-025.77462977e-012.80388443e-01 8.14373864e-01]5.26181855e-04]6.97968482e-01]] •数组索引 和Python列表类似,NumPy数组也可以使用切片语法,因为数组可以是多维的,所以必须为每个维度指定好切片,如下列代码所示。
输入:importnumpyasnp#创建秩为
2,形状为(3,4)的数组。
a=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])printa#取出第1行,2列开始的,形状为(2,2)的子数组。
#[[23]#[67]]b=a[:2,1:3]printb 输出:[[1234][5678][9101112]] [[23][67]] 切取的子数组实际上是原数组的一份浅备份,因此修改子数组,原始数组也将受到修改,如下列代码所示。
16 第1章深度学习的发展介绍 输入:print'原始a:',a[0,1] b[0,0]=77#b[0,0]和a[0,1]共享同一内存。
print'修改b后的a:',a[0,1] 输出:原始a:
2 修改b后的a:77 也可以混合整数索引以及切片索引访问数组,但是这会生成一个秩少于原始数组的子数组。
注意这和MATLAB处理的数组切片有些不同,NumPy有两种数组切片方式,一是混合整数索引和切片,生成低秩子数组;二是仅使用切片,生成与原始数组同秩的子数组。
输入:#创建形状(3,4)秩为2的numpy数组。
a=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])printarow_r1=a[
1,:]#秩为
1,数组a的第二行子数组。
row_r2=a[1:
2,:]#秩为
2,数组a的第二行子数组。
row_r3=a[[1],:]#秩为
2,数组a的第二行子数组。
print'秩为1:',row_r1,row_r1.shapeprint'秩为2:',row_r2,row_r2.shape print'秩为2:',row_r3,row_r3.shape#作用在列上同样适用:col_r1=a[:,1]#秩为
1,数组a的第二列子数组。
col_r2=a[:,1:2]#秩为
2,数组a的第二列子数组。
print'秩为1:',col_r1,col_r1.shapeprint'秩为2:'printcol_r2,col_r2.shape 输出:[[1234][5678][9101112]]秩为1:[5678](4L,) 秩为2:[[5678]](1L,4L)秩为2:[[5678]](1L,4L)秩为1:[2610](3L,) 秩为2:[[2] [6][10]](3L,1L) •整型数组索引 当我们使用切片索引数组时,得到的总是原数组的子数组,而整型数组索引允许我们利用其他数组中的数据构建一个新的数组。
如下列代码所示。
输入:a=np.array([[1,2],[3,4],[5,6]])#整型数组索引示例。
#返回的数组形状为(
3,)。
printa[[0,1,2],[0,1,0]]#上述整型数组索引与下列索引相等:printnp.array([a[0,0],a[1,1],a[2,0]]) 输出:[145] [145] 17 深度学习实战 #当使用整型数组索引时,可以重复索引同一个数组元素:printa[[0,0],[1,1]]#上述整型数组索引等于下列索引:printnp.array([a[0,1],a[0,1]]) [22][22] 整型数组索引的一个小技巧是从矩阵的每一行中选择或改变元素,如下列代码所示。
输入:#创建新数组用于选择元素。
a=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])printa #创建数组索引。
b=np.array([0,2,0,1])#使用数组b中的索引选择矩阵a每一行中的特定元素。
printa[np.arange
(4),b]#打印"[16711]"。
#使用数组b中的索引改变矩阵a每一行中的特定元素。
a[np.arange
(4),b]+=10printa 输出:[[123][456][789][101112]][16711] [[1123][4516][1789][102112]] •布尔型数组索引 布尔型索引可以任意挑选数组中的元素,这种类型索引频繁地用于条件语句下的元素选取。
如下列代码所示。
输入:importnumpyasnpa=np.array([[1,2],[3,4],[5,1]])printabool_idx=(a>2)#寻找大于2的数组元素,返回相同形状的布尔型数组,#其每个元素为a>2的布尔值。
printbool_idx#我们可以使用布尔数组索引去构造一个秩为1的数组,#其元素与布尔数组的真值相对应。
printa[bool_idx]#我们也可以将上述内容简洁地用一行语句表达:printa[a>2] 输出:[[12][34][51]][[FalseFalse][TrueTrue][TrueFalse]] [345] [345] •数据类型(DataTypes)NumPy提供了大量的数据类型去构造数组,NumPy会尝试猜测你创建的数组的数据类 18 第1章深度学习的发展介绍 型,但构造函数的数组通常也可选择显式指明其数据类型。
如下列代码所示。
输入:x=np.array([1,2])#让numpy自己选择数据类型。
y=np.array([1.0,2.0])#让numpy自己选择数据类型。
z=np.array([1,2],dtype=np.int64)#显式的规定数据类型。
printx.dtype,y.dtype,z.dtype 输出:int32float64int64 更多有关数据类型详细的说明及其用法,有兴趣的读者可以访问如下网址来进行学习:。
1.3.4.2数组运算 数组中基本的数学运算操作是按数组元素进行的,并且重载操作以及函数都可以使用,如下列代码所示。
输入:x=np.array([[1,2],[3,4]],dtype=np.float64)y=np.array([[5,6],[7,8]],dtype=np.float64)#按元素求和;以下两种方式都可以使用;printx+yprintnp.add(x,y) #按元素相减;printx-yprintnp.subtract(x,y) #按元素乘;printx*yprintnp.multiply(x,y) #按元素除;printx/yprintnp.divide(x,y) #按元素取平方根;printnp.sqrt(x) 输出:[[6.8.][10.12.]] [[6.8.][10.12.]][[-
4.-4.][-
4.-4.]] [[-
4.-4.][-
4.-4.]][[5.12.][21.32.]] [[5.12.][21.32.]][[0.2[0.42857143 [[0.2[0.42857143[[
1.[1.73205081 0.33333333] 0.5 ]] 0.33333333] 0.5 ]] 1.41421356]
2. ]] 注意:和MATLAB不同,*在NumPy中是按元素乘,而在MATLAB中是矩阵乘。
在NumPy中我们使用dot函数计算向量内积(点积)、矩阵乘矩阵及矩阵乘向量等操作。
dot可以当作函数在NumPy中使用,也可作为数组对象的实例方法,如下列代码所示。
19 深度学习实战 输入:x=np.array([[1,2],[3,4]])y=np.array([[5,6],[7,8]])v=np.array([9,10])w=np.array([11,12])#向量内积;都将生成219。
printv.dot(w)printnp.dot(v,w)#矩阵/向量乘积;都将生成秩为1的数组[2967]。
printx.dot(v)printnp.dot(x,v) #矩阵/矩阵乘积;都将生成秩为2的数组。
#[[1922]#[4350]]printx.dot(y)printnp.dot(x,y) 输出:219 219[2967][2967][[1922][4350]][[1922][4350]] NumPy还提供了许多有用的数组计算函数,其中最常用的是sum函数。
输入:x=np.array([[1,2],[3,4]])printnp.sum(x)#计算所有元素的累加和;打印"10"。
printnp.sum(x,axis=0)#计算每一列的累加和;打印"[46]"。
printnp.sum(x,axis=1)#计算每一行的累加和;打印"[37]"。
输出:10 [46][37] 更多有关NumPy的数学函数的使用,感兴趣的读者可以参考如下网址来进行学习:。
除了使用数组进行数学计算,我们还频繁地使用reshape或者其他方法操纵数组数据。
例如要转置一个矩阵,简单地使用数组对象的T属性即可,如下列代码所示。
输入:printx printx.T v=np.array([[1,2,3]])printvprintv.T 输出:[[12][34]][[13][24]][[123]] [[1][2][3]] 20 第1章深度学习的发展介绍 1.3.4.3广播(Broadcasting) 广播提供了强大的机制,允许NumPy在不同形状的数组中执行数学操作。
我们经常会遇到小数组和大数组相乘的情况,比如图片数据矩阵与权重矩阵。
使用广播机制可以提高代码质量及运算效率。
例如要在矩阵的每一行中都加上一个常数向量,可以按如下代码进行操作。
输入:#矩阵x的每一行加上向量v,将结果存储在矩阵y中。
x=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])v=np.array([1,0,1])y=np.empty_like(x)#创建一个和x形状相同的空矩阵。
#使用显式循环完成上述操作。
foriinrange
(4): y[i,:]=x[i,:]+vprinty 输出:[[224][557][8810][111113]] 这样操作是可行的,但当矩阵X特别大时,在Python中计算显式循环就将变得非常缓慢。
其实将向量v加到矩阵X的每一行就相当于将向量v拷贝多次垂直堆叠成矩阵VV,然后对矩阵X与矩阵VV进行按元素求和操作,也可以实现同样的结果,如下列代码所示。
输入: vv=np.tile(v,(4,1))#拷贝4次向量v,然后将其堆叠起来。
printvv #打印"[[101] # [101] # [101] # [101]]" y=x+vv#矩阵x和矩阵vv按元素相加。
printy 输出:[[101][101][101][101]] [[224][557][8810][111113]] NumPy广播机制允许我们在不创建多次向量v备份的情况下执行该计算,如下列代码所示。
输入:importnumpyasnp#矩阵x的每一行加上向量v,将结果存储在矩阵y中。
x=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])v=np.array([1,0,1])y=x+v#使用广播将v加到矩阵的每一行上。
printy 输出:[[224][557][8810][111113]] 由于广播机制的原因,即使X的形状为(4,3),v的形状为(
3,),表达式y=x+v依然可以 21 深度学习实战 执行;这就好像将v拷贝重塑为(4,3)的矩阵,然后进行按元素相加。
对两个数组使用广播机制要遵守下列规则。

1.如果数组的秩不同,将秩较小的数组进行扩展,直到两个数组的尺寸长度都一样。

2.如果两个数组在某个维度上的长度是相同的,或者其中一个数组在该维度上的长度为
1,那么我们就说这两个数组在该维度上是相容的。

3.如果两个数组在所有维度上都是相容的,它们就能使用广播。

4.广播之后,两个数组的尺寸将和较大的数组尺寸一样。

5.在任何一个维度上,如果一个数组的长度为
1,另一个数组长度大于
1,那么在该维度上,就好像是对第一个数组进行了复制。
如果感觉没有解释清楚,更多关于广播的详细说明文档可以参考以下网址:或者更具体的解释可以访问/EricsBroadcastingDoc网址。
支持广播机制的函数也被称为通用函数(UniversalFunctions),可以访问#available-ufuncs网址来查看所有的通用函数。
以下是广播的一些应用。
输入:#计算向量外积。
v=np.array([1,2,3])#v形状(
3,)。
w=np.array([4,5])#w形状(
2,)。
#要计算外积,我们首先要重塑v为一列(3,1),然后将其与w(
2,)相乘,#输出一个形状为(3,2)的矩阵,其就是v与w的外积。
printnp.reshape(v,(3,1))*w#将向量加到矩阵中的每一行。
x=np.array([[1,2,3],[4,5,6]])#x形状(2,3),v形状(
3,),广播之后的形状(2,3),printx+v#将向量加到矩阵的每一列。
x形状(2,3),w形状(
2,),#如果我们将x进行转置,其形状就被重塑为(3,2),#然后将其与w进行广播,就可以生成形状为(3,2)的矩阵;#最后再将结果进行转置,就可以得到形状为(2,3)的矩阵;#这个矩阵就是将向量w加到矩阵x的每一列所得到的结果。
print(x.T+w).T#另一种更简单的方法是将w重塑为形状为(2,1)的行向量;#然后直接与x进行广播就可产生相同的结果,#注意(
2,)表示的是秩为1的向量,(2,1)表示的是秩为2的矩阵。
printx+np.reshape(w,(2,1))#矩阵各元素乘以一个常数,#x形状(2,3),Numpy将标量作为形状为()的数组进行处理;printx*
2 输出:[[45][810][1215]] [[246][579]] [[567][91011]] [[567][91011]] [[246][81012]] 22 第1章深度学习的发展介绍 通过上面内容的介绍,发现广播可以使代码简洁而高效,因此应该尽可能地使用广播操作。
以上仅仅是NumPy一些重要的用法,但其功能远不只这些。
详细的文档请参考网址:/doc/numpy/reference/。
1.3.5Matplotlib Matplotlib是一个绘图工具库。
下面我们简单地介绍下matplotlib.pyplot模块,其用法和MATLAB相似。
importmatplotlib.pyplotasplt#使用以下IPython命令行,可以使得绘图结果嵌入到notebook中。
%matplotlibinline •绘制(Plotting) Matplotlib最重要的函数就是绘制函数plot,使用plot函数可以绘制2D数据,如下列代码所示,绘制好的图形如图1-2所示。
#使用sin三角函数计算x与y的坐标点。
x=np.arange(0,3*np.pi,0.1)y=np.sin(x)#使用plot函数绘制坐标点。
plt.plot(x,y) 图1-2使用plot函数绘制图形 添加标题、说明及坐标轴标记到图表中,如下列代码所示,绘制好的图形如图1-3所示。
x=np.arange(0,3*np.pi,0.1)y_sin=np.sin(x)y_cos=np.cos(x)#使用plot函数绘制坐标点。
plt.plot(x,y_sin)plt.plot(x,y_cos)plt.xlabel('xaxislabel') 23 深度学习实战 plt.ylabel('yaxislabel')plt.title('SineandCosine')plt.legend(['Sine','Cosine']) 图1-3添加标题、说明与坐标轴标记 •子图(Subplots) 还可以使用subplot函数在一幅图中绘制不同的子图,如下列代码所示,绘制的子图如图1-4所示。
#使用sin以及cos函数计算x与y的坐标点。
x=np.arange(0,3*np.pi,0.1)y_sin=np.sin(x)y_cos=np.cos(x)#设置子图网格,其高为
2,宽为
1。
#设置使用第一张子图。
plt.subplot(2,1,1)#绘制第一张子图。
plt.plot(x,y_sin)plt.title('Sine')#设置使用第二张子图,并绘制。
plt.subplot(2,1,2)plt.plot(x,y_cos)plt.title('Cosine')#显示图表。
plt.show() 24 第1章深度学习的发展介绍 图1-4绘制子图 更多关于Matplotlib的内容及其使用,感兴趣的读者可以访问以下网址:/api/pyplot_api.html#matplotlib.pyplot.subplot来进行学习。
1.4参考文献 [1]Feigenbaum,
E.A.,&Feldman,
J.(1950).Computingmachineryandintelligence.Mind,6(137),44-53. [2]Lecun,
Y.,Bengio,
Y.,&Hinton,
G.(2015).Deeplearning.Nature,521(7553),436-444.[3]Rumelhart,
D.E.,Hinton,
G.E.,&Williams,
R.J.(1986).Learningrep-resentationbyback-propagatingerrors.Nature,323
(3),533-536.[4]Hinton,
G.E.,&Salakhutdinov,
R.R.(2006).Reducingthedimensionalityofdatawithworks.Science,313(5786),504-507.[5]Bengio,
Y.(2009).LearningDeepArchitecturesforAI:NowPublishers.[6]Fodor,
J.A.,&Pylyshyn,
Z.W.(1988).Connectionismandcognitivearchitecture:acriticalanalysis.Cognition,28(1–2),3-71.[7]Jain,
A.K.,Mao,
J.,&Mohiuddin,
K.M.(1996).ArtificialNeuralNetworks:ATutorial.Computer,29
(3),31-44.[8]ulloch,
W.S.,&Pitts,
W.H.(1943).Alogicalcalculusofideasimminentinnervousactivity.[9]Rosenblatt,
F.(1958).Theperceptron:aprobabilisticmodelforinformationstorageanizationinthebrain:MITPress.[10]Widrow,
B.(1960).Hoff:Adaptiveswitchingcircuits.[11]Fukushima,
K.(1980).Neocognitron:Aanizingworkmodelforamechanismofpatternrecognitionunaffectedbyshiftinposition.Biologicalics,36
(4),193-202.[12]Lecun,
Y.,&Bengio,
Y.(1998).worksforimages,speech,andtime 25 深度学习实战 series:MITPress.[13]Touretzky,
D.S.,&Hinton,
G.E.(1988).ADistributedConnectionistProductionSystem. CognitiveScience,12
(3),423-466.[14]Rumelhart,
D.E.,Hinton,
G.E.,&Williams,
R.J.(1988).Learninginternal representationsbyerrorpropagation:MITPress.[15]Hofmann,
T.,Schölkopf,
B.,&Smola,
A.J.(2008).KernelMethodsinMachineLearning. AnnalsofStatistics,36
(3),1171-1220.[16]Heckerman,
D.(1992).Atutorialonlearningwithworks:MITPress.[17]Bengio,
Y.,Lamblin,
P.,Popovici,
D.,&Larochelle,
H.(2006).Greedylayer-wise trainingofworks.PaperpresentedattheInternationalConferenceonNeuralInformationProcessingSystems. [18]Krizhevsky,
A.,Sutskever,
I.,&Hinton,
G.E.(2012).ImageNetclassificationwithdeepconvolutionalworks.PaperpresentedattheInternationalConferenceonNeuralInformationProcessingSystems. 26

标签: #怎么安装python3 #语言 #c4d #转换成 #容量 #web #培训机构 #后缀名