精华内容
下载资源
问答
  • Deep Learning(深度学习)学习笔记整理系列之(一)

    万次阅读 多人点赞 2013-04-08 23:35:33
    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04-08   声明: 1)该Deep Learning的学习系列是整理自网上很大牛和机器学习专家...

    Deep Learning(深度学习)学习笔记整理系列

    zouxy09@qq.com

    http://blog.csdn.net/zouxy09

    作者:Zouxy

    version 1.0  2013-04-08

     

    声明:

    1)该Deep Learning的学习系列是整理自网上很大牛和机器学习专家所无私奉献的资料的。具体引用的资料请看参考文献。具体的版本声明也参考原文献。

    2)本文仅供学术交流,非商用。所以每一部分具体的参考资料并没有详细对应。如果某部分不小心侵犯了大家的利益,还望海涵,并联系博主删除。

    3)本人才疏学浅,整理总结的时候难免出错,还望各位前辈不吝指正,谢谢。

    4)阅读本文需要机器学习、计算机视觉、神经网络等等基础(如果没有也没关系了,没有就看看,能不能看懂,呵呵)。

    5)此属于第一版本,若有错误,还需继续修正与增删。还望大家多多指点。大家都共享一点点,一起为祖国科研的推进添砖加瓦(呵呵,好高尚的目标啊)。请联系:zouxy09@qq.com

     

    目录:

    一、概述

    二、背景

    三、人脑视觉机理

    四、关于特征

           4.1、特征表示的粒度

           4.2、初级(浅层)特征表示

           4.3、结构性特征表示

           4.4、需要有多少个特征?

    五、Deep Learning的基本思想

    六、浅层学习(Shallow Learning)和深度学习(Deep Learning)

    七、Deep learning与Neural Network

    八、Deep learning训练过程

           8.1、传统神经网络的训练方法

           8.2、deep learning训练过程

    九、Deep Learning的常用模型或者方法

           9.1、AutoEncoder自动编码器

           9.2、Sparse Coding稀疏编码

           9.3、Restricted Boltzmann Machine(RBM)限制波尔兹曼机

           9.4、Deep BeliefNetworks深信度网络

           9.5、Convolutional Neural Networks卷积神经网络

    十、总结与展望

    十一、参考文献和Deep Learning学习资源

     

    一、概述

           Artificial Intelligence,也就是人工智能,就像长生不老和星际漫游一样,是人类最美好的梦想之一。虽然计算机技术已经取得了长足的进步,但是到目前为止,还没有一台电脑能产生“自我”的意识。是的,在人类和大量现成数据的帮助下,电脑可以表现的十分强大,但是离开了这两者,它甚至都不能分辨一个喵星人和一个汪星人。

           图灵(图灵,大家都知道吧。计算机和人工智能的鼻祖,分别对应于其著名的“图灵机”和“图灵测试”)在 1950 年的论文里,提出图灵试验的设想,即,隔墙对话,你将不知道与你谈话的,是人还是电脑。这无疑给计算机,尤其是人工智能,预设了一个很高的期望值。但是半个世纪过去了,人工智能的进展,远远没有达到图灵试验的标准。这不仅让多年翘首以待的人们,心灰意冷,认为人工智能是忽悠,相关领域是“伪科学”。

            但是自 2006 年以来,机器学习领域,取得了突破性的进展。图灵试验,至少不是那么可望而不可及了。至于技术手段,不仅仅依赖于云计算对大数据的并行处理能力,而且依赖于算法。这个算法就是,Deep Learning。借助于 Deep Learning 算法,人类终于找到了如何处理“抽象概念”这个亘古难题的方法。


           2012年6月,《纽约时报》披露了Google Brain项目,吸引了公众的广泛关注。这个项目是由著名的斯坦福大学的机器学习教授Andrew Ng和在大规模计算机系统方面的世界顶尖专家JeffDean共同主导,用16000个CPU Core的并行计算平台训练一种称为“深度神经网络”(DNN,Deep Neural Networks)的机器学习模型(内部共有10亿个节点。这一网络自然是不能跟人类的神经网络相提并论的。要知道,人脑中可是有150多亿个神经元,互相连接的节点也就是突触数更是如银河沙数。曾经有人估算过,如果将一个人的大脑中所有神经细胞的轴突和树突依次连接起来,并拉成一根直线,可从地球连到月亮,再从月亮返回地球),在语音识别和图像识别等领域获得了巨大的成功。

           项目负责人之一Andrew称:“我们没有像通常做的那样自己框定边界,而是直接把海量数据投放到算法中,让数据自己说话,系统会自动从数据中学习。”另外一名负责人Jeff则说:“我们在训练的时候从来不会告诉机器说:‘这是一只猫。’系统其实是自己发明或者领悟了“猫”的概念。”

      

           2012年11月,微软在中国天津的一次活动上公开演示了一个全自动的同声传译系统,讲演者用英文演讲,后台的计算机一气呵成自动完成语音识别、英中机器翻译和中文语音合成,效果非常流畅。据报道,后面支撑的关键技术也是DNN,或者深度学习(DL,DeepLearning)。

           2013年1月,在百度年会上,创始人兼CEO李彦宏高调宣布要成立百度研究院,其中第一个成立的就是“深度学习研究所”(IDL,Institue of Deep Learning)。

     

           为什么拥有大数据的互联网公司争相投入大量资源研发深度学习技术。听起来感觉deeplearning很牛那样。那什么是deep learning?为什么有deep learning?它是怎么来的?又能干什么呢?目前存在哪些困难呢?这些问题的简答都需要慢慢来。咱们先来了解下机器学习(人工智能的核心)的背景。

     

    二、背景

          机器学习(Machine Learning)是一门专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能的学科。机器能否像人类一样能具有学习能力呢?1959年美国的塞缪尔(Samuel)设计了一个下棋程序,这个程序具有学习能力,它可以在不断的对弈中改善自己的棋艺。4年后,这个程序战胜了设计者本人。又过了3年,这个程序战胜了美国一个保持8年之久的常胜不败的冠军。这个程序向人们展示了机器学习的能力,提出了许多令人深思的社会问题与哲学问题(呵呵,人工智能正常的轨道没有很大的发展,这些什么哲学伦理啊倒发展的挺快。什么未来机器越来越像人,人越来越像机器啊。什么机器会反人类啊,ATM是开第一枪的啊等等。人类的思维无穷啊)。

            机器学习虽然发展了几十年,但还是存在很多没有良好解决的问题:


            例如图像识别、语音识别、自然语言理解、天气预测、基因表达、内容推荐等等。目前我们通过机器学习去解决这些问题的思路都是这样的(以视觉感知为例子):


            从开始的通过传感器(例如CMOS)来获得数据。然后经过预处理、特征提取、特征选择,再到推理、预测或者识别。最后一个部分,也就是机器学习的部分,绝大部分的工作是在这方面做的,也存在很多的paper和研究。

            而中间的三部分,概括起来就是特征表达。良好的特征表达,对最终算法的准确性起了非常关键的作用,而且系统主要的计算和测试工作都耗在这一大部分。但,这块实际中一般都是人工完成的。靠人工提取特征。


           截止现在,也出现了不少NB的特征(好的特征应具有不变性(大小、尺度和旋转等)和可区分性):例如Sift的出现,是局部图像特征描述子研究领域一项里程碑式的工作。由于SIFT对尺度、旋转以及一定视角和光照变化等图像变化都具有不变性,并且SIFT具有很强的可区分性,的确让很多问题的解决变为可能。但它也不是万能的。


           然而,手工地选取特征是一件非常费力、启发式(需要专业知识)的方法,能不能选取好很大程度上靠经验和运气,而且它的调节需要大量的时间。既然手工选取特征不太好,那么能不能自动地学习一些特征呢?答案是能!Deep Learning就是用来干这个事情的,看它的一个别名UnsupervisedFeature Learning,就可以顾名思义了,Unsupervised的意思就是不要人参与特征的选取过程。

           那它是怎么学习的呢?怎么知道哪些特征好哪些不好呢?我们说机器学习是一门专门研究计算机怎样模拟或实现人类的学习行为的学科。好,那我们人的视觉系统是怎么工作的呢?为什么在茫茫人海,芸芸众生,滚滚红尘中我们都可以找到另一个她(因为,你存在我深深的脑海里,我的梦里 我的心里 我的歌声里……)。人脑那么NB,我们能不能参考人脑,模拟人脑呢?(好像和人脑扯上点关系的特征啊,算法啊,都不错,但不知道是不是人为强加的,为了使自己的作品变得神圣和高雅。)

            近几十年以来,认知神经科学、生物学等等学科的发展,让我们对自己这个神秘的而又神奇的大脑不再那么的陌生。也给人工智能的发展推波助澜。

     

    三、人脑视觉机理

           1981 年的诺贝尔医学奖,颁发给了 David Hubel(出生于加拿大的美国神经生物学家) 和TorstenWiesel,以及 Roger Sperry。前两位的主要贡献,是“发现了视觉系统的信息处理”:可视皮层是分级的:


            我们看看他们做了什么。1958 年,DavidHubel 和Torsten Wiesel 在 JohnHopkins University,研究瞳孔区域与大脑皮层神经元的对应关系。他们在猫的后脑头骨上,开了一个3 毫米的小洞,向洞里插入电极,测量神经元的活跃程度。

          然后,他们在小猫的眼前,展现各种形状、各种亮度的物体。并且,在展现每一件物体时,还改变物体放置的位置和角度。他们期望通过这个办法,让小猫瞳孔感受不同类型、不同强弱的刺激。

           之所以做这个试验,目的是去证明一个猜测。位于后脑皮层的不同视觉神经元,与瞳孔所受刺激之间,存在某种对应关系。一旦瞳孔受到某一种刺激,后脑皮层的某一部分神经元就会活跃。经历了很多天反复的枯燥的试验,同时牺牲了若干只可怜的小猫,David Hubel 和Torsten Wiesel 发现了一种被称为“方向选择性细胞(Orientation Selective Cell)”的神经元细胞。当瞳孔发现了眼前的物体的边缘,而且这个边缘指向某个方向时,这种神经元细胞就会活跃。

           这个发现激发了人们对于神经系统的进一步思考。神经-中枢-大脑的工作过程,或许是一个不断迭代、不断抽象的过程。

           这里的关键词有两个,一个是抽象,一个是迭代。从原始信号,做低级抽象,逐渐向高级抽象迭代。人类的逻辑思维,经常使用高度抽象的概念。

            例如,从原始信号摄入开始(瞳孔摄入像素 Pixels),接着做初步处理(大脑皮层某些细胞发现边缘和方向),然后抽象(大脑判定,眼前的物体的形状,是圆形的),然后进一步抽象(大脑进一步判定该物体是只气球)。


          这个生理学的发现,促成了计算机人工智能,在四十年后的突破性发展。

          总的来说,人的视觉系统的信息处理是分级的。从低级的V1区提取边缘特征,再到V2区的形状或者目标的部分等,再到更高层,整个目标、目标的行为等。也就是说高层的特征是低层特征的组合,从低层到高层的特征表示越来越抽象,越来越能表现语义或者意图。而抽象层面越高,存在的可能猜测就越少,就越利于分类。例如,单词集合和句子的对应是多对一的,句子和语义的对应又是多对一的,语义和意图的对应还是多对一的,这是个层级体系。

          敏感的人注意到关键词了:分层。而Deep learning的deep是不是就表示我存在多少层,也就是多深呢?没错。那Deep learning是如何借鉴这个过程的呢?毕竟是归于计算机来处理,面对的一个问题就是怎么对这个过程建模?

           因为我们要学习的是特征的表达,那么关于特征,或者说关于这个层级特征,我们需要了解地更深入点。所以在说Deep Learning之前,我们有必要再啰嗦下特征(呵呵,实际上是看到那么好的对特征的解释,不放在这里有点可惜,所以就塞到这了)。


    下续

    展开全文
  • 目录(一)Few-shot learning(少样本学习)1. 问题定义2. 解决方法2.1 数据增强和正则化2.2 Meta-learning(元学习)(二)Meta-learning(元学习)1. 学习微调 (Learning to Fine-Tune)2. 基于 RNN 的记忆 (RNN ...

    (一)Few-shot learning(少样本学习)

    1. 问题定义

    众所周知,现在的主流的传统深度学习技术需要大量的数据来训练一个好的模型。例如典型的 MNIST 分类问题,一共有 10 个类,训练集一共有 6000 个样本,平均下来每个类大约 600 个样本,但是我们想一下我们人类自己,我们区分 0 到 9 的数字图片的时候需要看 6000 张图片才知道怎么区分吗?很显然,不需要!这表明当前的深度学习技术和我们人类智能差距还是很大的,要想弥补这一差距,少样本学习是一个很关键的问题。另外还有一个重要原因是如果想要构建新的数据集,还是举分类数据集为例,我们需要标记大量的数据,但是有的时候标记数据集需要某些领域的专家(例如医学图像的标记),这费时又费力,因此如果我们可以解决少样本学习问题,只需要每个类标记几张图片就可以高准确率的给剩余大量图片自动标记。这两方面的原因都让少样本学习问题很吸引人。

    在 few-shot learning 中有一个术语叫做 NN-way KK-shot 问题,简单的说就是我们需要分类的样本属于 NN 个类中一种,但是我们每个类训练集中的样本只有 KK 个,即一共只有 NKN * K 个样本的类别是已知的。
    在这里插入图片描述
    图片来自论文《Optimization as a Model for Few-Shot Learning.》,这是一个 5-way 1-shot 的图示,左边是训练集一共 5 张图片来自 5 个类,每个类只有一张图片。右边是测试集,理论上可以有任意多个图片用于测试,图中只给出了两张实例。

    Few-shot learning 问题的关键是解决过拟合 (overfitting) 的问题,因为训练的样本太少了,训练出的模型可能在训练集上效果还行,但是在测试集上面会遭遇灾难性的崩塌。

    2. 解决方法

    2.1 数据增强和正则化

    这一类方法想法很直接简单,既然训练数据不够那我就增加训练样本,既然过拟合那我就使用正则化技术。

    1. 数据加强:最常见的例子就是有时对 Omniglot 数据集的预处理,会将图片旋转 90 、180 、270 度,这样就可以使样本数量变为原来的 4 倍。
    2. 正则化:在训练的时候加入一个正则项,这个正则项的构建选择是关键。比如 《Few-shot Classification on Graphs with Structural Regularized GCNs》。该论文讨论 Graph 中节点分类的 few-shot 问题,常见的节点分类是使用 GCN 从节点的特征向量 feature 学习一个 embedding 然后用 embedding 来做分类,如果是 few-shot 问题,性能会大大下降(准确率大约从 70% 到了 40%),作者在训练的时候给损失函数加了一个正则项。作者将 feature 到 embedding 的过程看成编码器 encoder,然后额外加了几层网络作为 decoder,将 embedding 重构为 feature ,然后重构误差作为正则项(准确率从 40% 提升了 50%,大约 10 个百分点)。(更多内容可以参考这篇论文和别的使用正则化技术的论文)

    2.2 Meta-learning(元学习)

    元学习的核心想法是先学习一个先验知识(prior),这个先验知识对解决 few-shot learning 问题特别有帮助。Meta-learning 中有 task 的概念,比如上面图片讲的 5-way 1-shot 问题就是一个 task,我们需要先学习很多很多这样的 task,然后再来解决这个新的 task 。最最最重要的一点,这是一个新的 task。分类问题中,这个新的 task 中的类别是之前我们学习过的 task 中没有见过的! 在 Meta-learning 中之前学习的 task 我们称为 meta-training task,我们遇到的新的 task 称为 meta-testing task。因为每一个 task 都有自己的训练集和测试集,因此为了不引起混淆,我们把 task 内部的训练集和测试集一般称为 support setquery set
    在这里插入图片描述
    简单画了一个示意图,前面三个是三个 meta-training task (当然实际需要很多这样的 meta-training task 才能学到我们需要的先验知识),最后一个就是 meta-testing task。我们最后评价我们的 meta-learning 方法的好坏就是在红色标记部分上的 performance。

    方法 2.1 和方法 2.2 之间有个明显的差异就是 meta-learning 需要一些类来构建 meta-training task。由于 meta-testing 的类别要和 meta-training 完全不同,因此如果我们只有 MNIST 数据集,没法使用 meat-learning 来解决 MNIST 上的 10-way few-shot learning 问题,但是方法 2.1 可以。不过我们可以使用 meta-learning 解决 MNIST 上的 N-way (N < 6) 的 few-shot learning 问题。那么如果我们非要解决 MNIST 上的 10-way few-shot learning 问题怎么办呢,可以在另外一个数据集,例如 Omniglot ,上面进行 meta-training,然后学到的先验知识用来解决这个问题。《Siamese neural networks for one-shot image recognition.》 和 《Matching networks for one shot learning.》都在论文中做过这样子实验(这一种情况和迁移学习(transfer learning)有相似的地方)。

    (二)Meta-learning(元学习)

    Meta-learning 方法的分类标准有很多,个人喜欢按照如下标准分为三类。参考文章《Learning to Compare: Relation Network for Few-Shot Learning》

    1. 学习微调 (Learning to Fine-Tune)
    2. 基于 RNN 的记忆 (RNN Memory Based)
    3. 度量学习 (Metric Learning)

    Meta-learning 中 task 的概念是和 meta-learning 的本质有关的。Meta-learning 其实还有一个名字叫做“学会学习” (Learn to learn),这来自于对人类智能的基本认知:我们人类学习一个东西的时候不是从头开始学的,都是基于之前学习的知识来进行学习的。比如如果你会玩英雄联盟,那你学习玩王者荣耀会快很多。但是我们的深度学习模型呢,学习新的东西(可以看成新的类,新的 task)需要从头开始学习( 当然需要大量的样本 ),即使你之前学过特别类似的东西。因此 Meta-learning 就像让深度学习学会学习,利用之前学过的知识在面对新的问题可以学习得又快又好,如何体现又快又好呢? – few-shot learning 呗~ 因此 meta-learning 和 few-shot learning 现在的研究基本都是在一起的。接下来介绍如何从之前的 task 来学习我们想要的先验知识。

    1. 学习微调 (Learning to Fine-Tune)

    MAML(《Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks》) 是这类方法的范例之一。MAML 的思想是学习一个 初始化参数 (initialization parameter),这个初始化参数在遇到新的问题时,只需要使用少量的样本 (few-shot learning) 进行几步梯度下降就可以取得很好地效果( 参见后续博客 )。另一个典型是《Optimization as a Model for Few-Shot Learning》,他不仅关注于初始化,还训练了一个基于 LSTM 的优化器 (optimizer) 来帮助微调( 参见后续博客 )。

    2. 基于 RNN 的记忆 (RNN Memory Based)

    最直观的方法,使用基于 RNN 的技术记忆先前 task 中的表示等,这种表示将有助于学习新的 task。可参考《Meta networks》和 《Meta-learning with memory-augmented neural networks.》

    3.度量学习 (Metric Learning)

    主要可以参考《Learning a Similarity Metric Discriminatively, with Application to Face Verification.》,《Siamese neural networks for one-shot image recognition》,《Siamese neural networks for one-shot image recognition》,《Matching networks for one shot learning》,《Prototypical Networks for Few-shot Learning》,《Learning to Compare: Relation Network for Few-Shot Learning》。
    核心思想:学习一个 embedding 函数,将输入空间(例如图片)映射到一个新的嵌入空间,在嵌入空间中有一个相似性度量来区分不同类。我们的先验知识就是这个 embedding 函数,在遇到新的 task 的时候,只将需要分类的样本点用这个 embedding 函数映射到嵌入空间里面,使用相似性度量比较进行分类。

    4.方法简单比较

    三种方法会在后续博客中继续介绍,这里简单比较一下三种方法:

    1. 基于 RNN 的记忆 (RNN Memory Based) 有两个关键问题,一个是这种方法经常会加一个外部存储来记忆,另一个是对模型进行了限制 (RNN),这可能会在一定程度上阻碍其发展和应用。
    2. 学习微调 (Learning to Fine-Tune) 的方法需要在新的 task 上面进行微调,也正是由于需要新的 task 中 support set 中有样本来进行微调,目前我个人还没看到这种方法用于 zero-shot learning(参考 few-shot learning 问题的定义,可以得到 zero-shot learning的定义)的问题上,但是在《Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks》的作者 Chelsea Finn 的博士论文《Learning to Learn with Gradients》中给出了 MAML 的理论证明,并且获得了 2018 ACM 最佳博士论文奖,还有一点就是 MAML 可以用于强化学习,另外两种方法多用于分类问题。链接:https://mp.weixin.qq.com/s/AdlwI-nbVlDWCj0o5LR7Sw
    3. 度量学习 (Metric Learning),和学习微调 (Learning to Fine-Tune) 的方法一样不对模型进行任何限制,并且可以用于 zero-shot learning 问题。虽然效果比较理想但是现在好像多用于分类任务并且可能缺乏一些理论上的证明,比如相似性度量是基于余弦距离还是欧式距离亦或是其他?为什么是这个距离?(因为 embedding 函数是一个神经网络,可解释性差,导致无法很好解释新的 embedding 空间),虽然《Learning to Compare: Relation Network for Few-Shot Learning》中的 Relation Network 将两个需要比较的 embedding 又送到一个神经网络(而不是人为手动选择相似性度量)来计算相似性得分,但是同样缺乏很好地理论证明。

    5.未来方向

    5.1 更好的 meta-learning 方法

    现有方法都有各自的优缺点,提出一个新的更好的 meta-learning 方法是目前的主流研究方向。实验结果还有很大的提升空间。例如,如果想从基于度量学习方向出发,那么是否可以从理论入手推导出相似性度量应该怎么选择(图片分类和文本分类问题,CNN 和 RNN 作为 embedding 函数都有可能使度量选择不同)。

    5.2 meta-learning 的应用

    现在的主流还是算法的研究,一般研究问题都是理论上的问题,例如图片的 5-way 1-shot 问题。实际应用问题研究还很少,这也是一个未来的方向。

    (三)论文链接

    《Optimization as a Model for Few-Shot Learning》:https://openreview.net/pdf?id=rJY0-Kcll.
    《Few-shot Classification on Graphs with Structural Regularized GCNs 》: https://openreview.net/pdf?id=r1znKiAcY7.
    《Siamese neural networks for one-shot image recognition》:http://www.cs.toronto.edu/~gkoch/files/msc-thesis.pdf.
    《Matching networks for one shot learning》: http://papers.nips.cc/paper/6385-matching-networks-for-one-shot-learning.pdf.
    《Learning to Compare: Relation Network for Few-Shot Learning》:http://openaccess.thecvf.com/content_cvpr_2018/papers/Sung_Learning_to_Compare_CVPR_2018_paper.pdf.
    《Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks》:https://www.cs.utexas.edu/~sniekum/classes/RL-F17/papers/Meta.pdf
    《Meta networks》:https://pdfs.semanticscholar.org/3ecc/71263d5dd8a51438e351f0a27fba5a6e7592.pdf
    《Meta-learning with memory-augmented neural networks.》:http://proceedings.mlr.press/v48/santoro16.pdf
    《Prototypical Networks for Few-shot Learning》:http://papers.nips.cc/paper/6996-prototypical-networks-for-few-shot-learning.pdf
    《Learning a Similarity Metric Discriminatively, with Application to Face Verification.》:http://yann.lecun.com/exdb/publis/pdf/chopra-05.pdf.

    展开全文
  • 【强化学习】Q-Learning算法详解

    万次阅读 多人点赞 2018-06-19 21:18:18
    QLearning是强化学习算法中值迭代的算法,Q即为Q(s,a)就是在某一时刻的 s 状态下(s∈S),采取 a (a∈A)动作能够获得收益的期望,环境会根据agent的动作反馈相应的回报reward r,所以算法的主要思想就是将State与...

    【强化学习】Q-Learning详解

    https://morvanzhou.github.io/tutorials/machine-learning/reinforcement-learning/2-1-general-rl/ 莫凡大神的有趣的强化学习视频通俗易懂

    发现了很多RL资料搬砖过来,刚入门的可以用得上

    David Silver 博士的 UCL 公开课:http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching.html
    DeepMind 和 UCL 的DL、RL课程:https://www.youtube.com/playlist?list=PLqYmG7hTraZDNJre23vqCGIVpfZ_K2RZs
    Sergey Levine 的DRL课程:http://rail.eecs.berkeley.edu/deeprlcourse/
    OpenAI 的 Spinning Up in Deep RL:https://blog.openai.com/spinning-up-in-deep-rl/
    关于深度强化学习良心paper:https://arxiv.org/abs/1810.06339

    1、算法思想

    QLearning是强化学习算法中value-based的算法,Q即为Q(s,a)就是在某一时刻的 s 状态下(s∈S),采取 动作a (a∈A)动作能够获得收益的期望,环境会根据agent的动作反馈相应的回报reward r,所以算法的主要思想就是将State与Action构建成一张Q-table来存储Q值,然后根据Q值来选取能够获得最大的收益的动作。

    Q-Table a1 a2
    s1 q(s1,a1) q(s1,a2)
    s2 q(s2,a1) q(s2,a2)
    s3 q(s3,a1) q(s3,a2)

    2、公式推导

    举个例子如图有一个GridWorld的游戏从起点出发到达终点为胜利掉进陷阱为失败。智能体(Agent)、环境状态(environment)、奖励(reward)、动作(action)可以将问题抽象成一个马尔科夫决策过程,我们在每个格子都算是一个状态 sts_t , π(a|s)在s状态下采取动作a策略 。 P(s’|s,a)也可以写成PssaP_{ss'}^a为在s状态下选择a动作转换到下一个状态s’的概率。R(s’|s,a)表示在s状态下采取a动作转移到s’的奖励reward,我们的目的很明确就是找到一条能够到达终点获得最大奖赏的策略。
    这里写图片描述
    所以目标就是求出累计奖励最大的策略的期望:

    Goal:maxπE[t=0HγtR(St,At,St+1)π]\max_πE[\sum_{t=0}^{H}γ^tR(S_t,A_t,S_{t+1}) | π]

    Qlearning的主要优势就是使用了时间差分法TD(融合了蒙特卡洛和动态规划)能够进行离线学习, 使用bellman方程可以对马尔科夫过程求解最优策略

    贝尔曼方程

    通过bellman方程求解马尔科夫决策过程的最佳决策序列,状态值函数Vπ(s)V_\pi(s)可以评价当前状态的好坏,每个状态的值不仅由当前状态决定还要由后面的状态决定,所以状态的累计奖励求期望就可得出当前s的状态值函数V(s)。bellman方程如下

    Vπ(s)=E(UtSt=s)V_π(s) = E(U_t|S_t = s)
    Vπ(s)=Eπ[Rt+1+γ[Rt+2+γ[.......]]St=s]V_π(s) = E_π[R_{t+1}+γ[R_{t+2} + γ[.......]]|S_t = s]
    Vπ(s)=Eπ[Rt+1+γV(s)St=s]V_π(s) = E_π[R_{t+1}+γV(s')|S_t = s]

    最优累计期望可用V(s)V^*(s)表示,可知最优值函数就是V(s)=maxπVπ(s)V^*(s)=max_πV_\pi(s)
    V(s)=maxπE[t=0HγtR(St,At,St+1)π,s0=s]V^*(s)=\max_πE[\sum_{t=0}^{H}γ^tR(S_t,A_t,S_{t+1}) | π,s_0=s]

    Q(s,a)状态动作值函数
    qπ(s,a)=Eπ[rt+1+γrt+2+γ2rt+3+....At=a,St=s]q_π(s,a) = E_π[r_{t+1}+γr_{t+2}+γ^2r_{t+3}+....|A_t=a,S_t=s]
    qπ(s,a)=Eπ[GtAt=a,St=s]q_π(s,a) = E_π[G_t|A_t=a,S_t=s]
    其中GtG_t是t时刻开始的总折扣奖励,从这里我们能看出来 γ衰变值对Q函数的影响,γ越接近于1代表它越有远见会着重考虑后续状态的的价值,当γ接近0的时候就会变得近视只考虑当前的利益的影响。所以从0到1,算法就会越来越会考虑后续回报的影响。
    qπ(s,a)=Eπ[Rt+1+γqπ(St+1,At+1)At=a,St=s]q_π(s,a) = E_π[R_{t+1}+γq_π(S_{t+1},A_{t+1})|A_t=a,S_t=s]

    最优价值动作函数Q(s,a)=maxπQ(s,a)Q^*(s,a)=max_\pi Q^*(s,a),打开期望如下
    Q(s,a)=sP(ss,a)(R(s,a,s)+γmaxaQ(s,a))Q^*(s,a)=\sum_{s'} P(s'|s,a)(R(s,a,s')+γ\max_{a'}Q^*(s',a'))

    Bellman方程实际上就是价值动作函数的转换关系

    Vπ(s)=aAπ(as)qπ(s,a)V_π(s) = \sum_{a∈A}π(a|s)q_π(s,a)
    qπ(s,a)=Rsa+γsSPssaVπ(s)q_π(s,a) = R_s^a + γ\sum_{s'∈S}P_{ss'}^aV_π(s')
    Vπ(s)=aAπ(as)[Rsa+γsPssaVπ(s)]V_π(s)=\sum_{a'∈A}π(a|s)[R_s^a+γ\sum_{s'}P_{ss'}^aV_π(s')]

    Q值迭代公式
    根据下图更直观的了解V(s)与Q(s,a)的关系
    V(s)与Q(s,a)的关系

    时间差分法 https://blog.csdn.net/qq_30615903/article/details/80821061

    时间差分方法结合了蒙特卡罗的采样方法和动态规划方法的bootstrapping(利用后继状态的值函数估计当前值函数)使得他可以适用于model-free的算法并且是单步更新,速度更快。值函数计算方式如下

    V(s)V(s)+α(Rt+1+γV(s)V(s))V(s)←V(s)+\alpha (R_{t+1}+\gamma V(s')-V(s))

    其中Rt+1+γV(s)R_{t+1}+\gamma V(s')被称为TD目标,δt=Rt+1+γV(s)V(s)\delta_t=R_{t+1}+\gamma V(s')-V(s) 称为TD偏差。

    3、更新公式

    根据以上推导可以对Q值进行计算,所以有了Q值我们就可以进行学习,也就是Q-table的更新过程,其中α为学习率γ为奖励性衰变系数,采用时间差分法的方法进行更新。

    Q(s,a)Q(s,a)+α[r+γmaxaQ(s,a)Q(s,a)]Q(s,a) ← Q(s,a) + α[r + γmax_{a'}Q(s',a')-Q(s,a)]

    上式就是Q-learning更新的公式,根据下一个状态s’中选取最大的Q(s,a)Q(s',a')值乘以衰变γ加上真实回报值最为Q现实,而根据过往Q表里面的Q(s,a)作为Q估计。
    在这里插入图片描述
    这里写图片描述

    4、实现代码

    代码来自网上各路大神的源码,非原创,据反映没图片跑不通,所以建了个github,https://github.com/xshura/reinforcement_learning
    Q-Learning agent

    # -*- coding: utf-8 -*-
    import random
    from environment import Env
    from collections import defaultdict
    
    
    class QLearningAgent:
        def __init__(self, actions):
            # actions = [0, 1, 2, 3]
            self.actions = actions
            self.learning_rate = 0.01
            self.discount_factor = 0.9
            self.epsilon = 0.1
            self.q_table = defaultdict(lambda: [0.0, 0.0, 0.0, 0.0])
    
        # 采样 <s, a, r, s'>
        def learn(self, state, action, reward, next_state):
            current_q = self.q_table[state][action]
            # 贝尔曼方程更新
            new_q = reward + self.discount_factor * max(self.q_table[next_state])
            self.q_table[state][action] += self.learning_rate * (new_q - current_q)
    
        # 从Q-table中选取动作
        def get_action(self, state):
            if np.random.rand() < self.epsilon:
                # 贪婪策略随机探索动作
                action = np.random.choice(self.actions)
            else:
                # 从q表中选择
                state_action = self.q_table[state]
                action = self.arg_max(state_action)
            return action
    
        @staticmethod
        def arg_max(state_action):
            max_index_list = []
            max_value = state_action[0]
            for index, value in enumerate(state_action):
                if value > max_value:
                    max_index_list.clear()
                    max_value = value
                    max_index_list.append(index)
                elif value == max_value:
                    max_index_list.append(index)
            return random.choice(max_index_list)
    
    
    if __name__ == "__main__":
        env = Env()
        agent = QLearningAgent(actions=list(range(env.n_actions)))
        for episode in range(1000):
            state = env.reset()
            while True:
                env.render()
                # agent产生动作
                action = agent.get_action(str(state))
                next_state, reward, done = env.step(action)
                # 更新Q表
                agent.learn(str(state), action, reward, str(next_state))
                state = next_state
                env.print_value_all(agent.q_table)
                # 当到达终点就终止游戏开始新一轮训练
                if done:
                    break
    

    环境部分

    import time
    import numpy as np
    import tkinter as tk
    from PIL import ImageTk, Image
    
    np.random.seed(1)
    PhotoImage = ImageTk.PhotoImage
    UNIT = 100
    HEIGHT = 5
    WIDTH = 5
    
    
    class Env(tk.Tk):
        def __init__(self):
            super(Env, self).__init__()
            self.action_space = ['u', 'd', 'l', 'r']
            self.n_actions = len(self.action_space)
            self.title('Q Learning')
            self.geometry('{0}x{1}'.format(HEIGHT * UNIT, HEIGHT * UNIT))
            self.shapes = self.load_images()
            self.canvas = self._build_canvas()
            self.texts = []
    
        def _build_canvas(self):
            canvas = tk.Canvas(self, bg='white',
                               height=HEIGHT * UNIT,
                               width=WIDTH * UNIT)
            # create grids
            for c in range(0, WIDTH * UNIT, UNIT):  # 0~400 by 80
                x0, y0, x1, y1 = c, 0, c, HEIGHT * UNIT
                canvas.create_line(x0, y0, x1, y1)
            for r in range(0, HEIGHT * UNIT, UNIT):  # 0~400 by 80
                x0, y0, x1, y1 = 0, r, HEIGHT * UNIT, r
                canvas.create_line(x0, y0, x1, y1)
    
            # add img to canvas
            self.rectangle = canvas.create_image(50, 50, image=self.shapes[0])
            self.triangle1 = canvas.create_image(250, 150, image=self.shapes[1])
            self.triangle2 = canvas.create_image(150, 250, image=self.shapes[1])
            self.circle = canvas.create_image(250, 250, image=self.shapes[2])
    
            # pack all
            canvas.pack()
    
            return canvas
    
        def load_images(self):
            rectangle = PhotoImage(
                Image.open("../img/rectangle.png").resize((65, 65)))
            triangle = PhotoImage(
                Image.open("../img/triangle.png").resize((65, 65)))
            circle = PhotoImage(
                Image.open("../img/circle.png").resize((65, 65)))
    
            return rectangle, triangle, circle
    
        def text_value(self, row, col, contents, action, font='Helvetica', size=10,
                       style='normal', anchor="nw"):
            if action == 0:
                origin_x, origin_y = 7, 42
            elif action == 1:
                origin_x, origin_y = 85, 42
            elif action == 2:
                origin_x, origin_y = 42, 5
            else:
                origin_x, origin_y = 42, 77
    
            x, y = origin_y + (UNIT * col), origin_x + (UNIT * row)
            font = (font, str(size), style)
            text = self.canvas.create_text(x, y, fill="black", text=contents,
                                           font=font, anchor=anchor)
            return self.texts.append(text)
    
        def print_value_all(self, q_table):
            for i in self.texts:
                self.canvas.delete(i)
            self.texts.clear()
            for i in range(HEIGHT):
                for j in range(WIDTH):
                    for action in range(0, 4):
                        state = [i, j]
                        if str(state) in q_table.keys():
                            temp = q_table[str(state)][action]
                            self.text_value(j, i, round(temp, 2), action)
    
        def coords_to_state(self, coords):
            x = int((coords[0] - 50) / 100)
            y = int((coords[1] - 50) / 100)
            return [x, y]
    
        def state_to_coords(self, state):
            x = int(state[0] * 100 + 50)
            y = int(state[1] * 100 + 50)
            return [x, y]
    
        def reset(self):
            self.update()
            time.sleep(0.5)
            x, y = self.canvas.coords(self.rectangle)
            self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y)
            self.render()
            # return observation
            return self.coords_to_state(self.canvas.coords(self.rectangle))
    
        def step(self, action):
            state = self.canvas.coords(self.rectangle)
            base_action = np.array([0, 0])
            self.render()
    
            if action == 0:  # up
                if state[1] > UNIT:
                    base_action[1] -= UNIT
            elif action == 1:  # down
                if state[1] < (HEIGHT - 1) * UNIT:
                    base_action[1] += UNIT
            elif action == 2:  # left
                if state[0] > UNIT:
                    base_action[0] -= UNIT
            elif action == 3:  # right
                if state[0] < (WIDTH - 1) * UNIT:
                    base_action[0] += UNIT
    
            # 移动
            self.canvas.move(self.rectangle, base_action[0], base_action[1])
            self.canvas.tag_raise(self.rectangle)
            next_state = self.canvas.coords(self.rectangle)
            # 判断得分条件
            if next_state == self.canvas.coords(self.circle):
                reward = 100
                done = True
            elif next_state in [self.canvas.coords(self.triangle1),
                                self.canvas.coords(self.triangle2)]:
                reward = -100
                done = True
            else:
                reward = 0
                done = False
    
            next_state = self.coords_to_state(next_state)
            return next_state, reward, done
    
        # 渲染环境
        def render(self):
            time.sleep(0.03)
            self.update()
    
    展开全文
  • 用Tensorflow基于Deep Q Learning DQN 玩Flappy Bird

    万次阅读 多人点赞 2016-03-22 00:11:57
    前言2013年DeepMind 在NIPS上发表Playing Atari with Deep Reinforcement Learning 一文,提出了DQN(Deep Q Network)算法,实现端到端学习玩Atari游戏,即只有像素输入,看着屏幕玩游戏。Deep Mind就凭借这个应用...

    前言

    2013年DeepMind 在NIPS上发表Playing Atari with Deep Reinforcement Learning 一文,提出了DQN(Deep Q Network)算法,实现端到端学习玩Atari游戏,即只有像素输入,看着屏幕玩游戏。Deep Mind就凭借这个应用以6亿美元被Google收购。由于DQN的开源,在github上涌现了大量各种版本的DQN程序。但大多是复现Atari的游戏,代码量很大,也不好理解。

    Flappy Bird是个极其简单又困难的游戏,风靡一时。在很早之前,就有人使用Q-Learning 算法来实现完Flappy Bird。http://sarvagyavaish.github.io/FlappyBirdRL/
    但是这个的实现是通过获取小鸟的具体位置信息来实现的。

    能否使用DQN来实现通过屏幕学习玩Flappy Bird是一个有意思的挑战。(话说本人和朋友在去年年底也考虑了这个idea,但当时由于不知道如何截取游戏屏幕只能使用具体位置来学习,不过其实也成功了)

    最近,github上有人放出使用DQN玩Flappy Bird的代码,https://github.com/yenchenlin1994/DeepLearningFlappyBird【1】
    该repo通过结合之前的repo成功实现了这个想法。这个repo对整个实现过程进行了较详细的分析,但是由于其DQN算法的代码基本采用别人的repo,代码较为混乱,不易理解。
    这里写图片描述
    为此,本人改写了一个版本https://github.com/songrotek/DRL-FlappyBird

    对DQN代码进行了重新改写。本质上对其做了类的封装,从而使代码更具通用性。可以方便移植到其他应用。

    当然,本文的目的是借Flappy Bird DQN这个代码来详细分析一下DQN算法极其使用。

    DQN 伪代码

    这个是NIPS13版本的伪代码:

    Initialize replay memory D to size N
    Initialize action-value function Q with random weights
    for episode = 1, M do
        Initialize state s_1
        for t = 1, T do
            With probability ϵ select random action a_t
            otherwise select a_t=max_a  Q($s_t$,a; $θ_i$)
            Execute action a_t in emulator and observe r_t and s_(t+1)
            Store transition (s_t,a_t,r_t,s_(t+1)) in D
            Sample a minibatch of transitions (s_j,a_j,r_j,s_(j+1)) from D
            Set y_j:=
                r_j for terminal s_(j+1)
                r_j+γ*max_(a^' )  Q(s_(j+1),a'; θ_i) for non-terminal s_(j+1)
            Perform a gradient step on (y_j-Q(s_j,a_j; θ_i))^2 with respect to θ
        end for
    end for

    基本的分析详见Paper Reading 1 - Playing Atari with Deep Reinforcement Learning
    基础知识详见Deep Reinforcement Learning 基础知识(DQN方面)

    本文主要从代码实现的角度来分析如何编写Flappy Bird DQN的代码

    编写FlappyBirdDQN.py

    首先,FlappyBird的游戏已经编写好,是现成的。提供了很简单的接口:

    nextObservation,reward,terminal = game.frame_step(action)

    即输入动作,输出执行完动作的屏幕截图,得到的反馈reward,以及游戏是否结束。

    那么,现在先把DQN想象为一个大脑,这里我们也用BrainDQN类来表示,这个类只需获取感知信息也就是上面说的观察(截图),反馈以及是否结束,然后输出动作即可。

    完美的代码封装应该是这样。具体DQN里面如何存储。如何训练是外部不关心的。
    因此,我们的FlappyBirdDQN代码只有如下这么短:

    # -------------------------
    # Project: Deep Q-Learning on Flappy Bird
    # Author: Flood Sung
    # Date: 2016.3.21
    # -------------------------
    
    import cv2
    import sys
    sys.path.append("game/")
    import wrapped_flappy_bird as game
    from BrainDQN import BrainDQN
    import numpy as np
    
    # preprocess raw image to 80*80 gray image
    def preprocess(observation):
        observation = cv2.cvtColor(cv2.resize(observation, (80, 80)), cv2.COLOR_BGR2GRAY)
        ret, observation = cv2.threshold(observation,1,255,cv2.THRESH_BINARY)
        return np.reshape(observation,(80,80,1))
    
    def playFlappyBird():
        # Step 1: init BrainDQN
        brain = BrainDQN()
        # Step 2: init Flappy Bird Game
        flappyBird = game.GameState()
        # Step 3: play game
        # Step 3.1: obtain init state
        action0 = np.array([1,0])  # do nothing
        observation0, reward0, terminal = flappyBird.frame_step(action0)
        observation0 = cv2.cvtColor(cv2.resize(observation0, (80, 80)), cv2.COLOR_BGR2GRAY)
        ret, observation0 = cv2.threshold(observation0,1,255,cv2.THRESH_BINARY)
        brain.setInitState(observation0)
    
        # Step 3.2: run the game
        while 1!= 0:
            action = brain.getAction()
            nextObservation,reward,terminal = flappyBird.frame_step(action)
            nextObservation = preprocess(nextObservation)
            brain.setPerception(nextObservation,action,reward,terminal)
    
    def main():
        playFlappyBird()
    
    if __name__ == '__main__':
        main()

    核心部分就在while循环里面,由于要讲图像转换为80x80的灰度图,因此,加了一个preprocess预处理函数。

    这里,显然只有有游戏引擎,换一个游戏是一样的写法,非常方便。

    接下来就是编写BrainDQN.py 我们的游戏大脑

    编写BrainDQN

    基本架构:

    class BrainDQN:
        def __init__(self):
            # init replay memory
            self.replayMemory = deque()
            # init Q network
            self.createQNetwork()
        def createQNetwork(self):
    
        def trainQNetwork(self):
    
        def setPerception(self,nextObservation,action,reward,terminal):
        def getAction(self):
        def setInitState(self,observation):

    基本的架构也就只需要上面这几个函数,其他的都是多余了,接下来就是编写每一部分的代码。

    CNN代码

    也就是createQNetwork部分,这里采用如下图的结构(转自【1】):
    这里写图片描述

    这里就不讲解整个流程了。主要是针对具体的输入类型和输出设计卷积和全连接层。

    代码如下:

        def createQNetwork(self):
            # network weights
            W_conv1 = self.weight_variable([8,8,4,32])
            b_conv1 = self.bias_variable([32])
    
            W_conv2 = self.weight_variable([4,4,32,64])
            b_conv2 = self.bias_variable([64])
    
            W_conv3 = self.weight_variable([3,3,64,64])
            b_conv3 = self.bias_variable([64])
    
            W_fc1 = self.weight_variable([1600,512])
            b_fc1 = self.bias_variable([512])
    
            W_fc2 = self.weight_variable([512,self.ACTION])
            b_fc2 = self.bias_variable([self.ACTION])
    
            # input layer
    
            self.stateInput = tf.placeholder("float",[None,80,80,4])
    
            # hidden layers
            h_conv1 = tf.nn.relu(self.conv2d(self.stateInput,W_conv1,4) + b_conv1)
            h_pool1 = self.max_pool_2x2(h_conv1)
    
            h_conv2 = tf.nn.relu(self.conv2d(h_pool1,W_conv2,2) + b_conv2)
    
            h_conv3 = tf.nn.relu(self.conv2d(h_conv2,W_conv3,1) + b_conv3)
    
            h_conv3_flat = tf.reshape(h_conv3,[-1,1600])
            h_fc1 = tf.nn.relu(tf.matmul(h_conv3_flat,W_fc1) + b_fc1)
    
            # Q Value layer
            self.QValue = tf.matmul(h_fc1,W_fc2) + b_fc2
    
            self.actionInput = tf.placeholder("float",[None,self.ACTION])
            self.yInput = tf.placeholder("float", [None]) 
            Q_action = tf.reduce_sum(tf.mul(self.QValue, self.actionInput), reduction_indices = 1)
            self.cost = tf.reduce_mean(tf.square(self.yInput - Q_action))
            self.trainStep = tf.train.AdamOptimizer(1e-6).minimize(self.cost)

    记住输出是Q值,关键要计算出cost,里面关键是计算Q_action的值,即该state和action下的Q值。由于actionInput是one hot vector的形式,因此tf.mul(self.QValue, self.actionInput)正好就是该action下的Q值。

    training 部分。

    这部分是代码的关键部分,主要是要计算y值,也就是target Q值。

        def trainQNetwork(self):
            # Step 1: obtain random minibatch from replay memory
            minibatch = random.sample(self.replayMemory,self.BATCH_SIZE)
            state_batch = [data[0] for data in minibatch]
            action_batch = [data[1] for data in minibatch]
            reward_batch = [data[2] for data in minibatch]
            nextState_batch = [data[3] for data in minibatch]
    
            # Step 2: calculate y 
            y_batch = []
            QValue_batch = self.QValue.eval(feed_dict={self.stateInput:nextState_batch})
            for i in range(0,self.BATCH_SIZE):
                terminal = minibatch[i][4]
                if terminal:
                    y_batch.append(reward_batch[i])
                else:
                    y_batch.append(reward_batch[i] + GAMMA * np.max(QValue_batch[i]))
    
            self.trainStep.run(feed_dict={
                self.yInput : y_batch,
                self.actionInput : action_batch,
                self.stateInput : state_batch
                })

    其他部分

    其他部分就比较容易了,这里直接贴出完整的代码:

    # -----------------------------
    # File: Deep Q-Learning Algorithm
    # Author: Flood Sung
    # Date: 2016.3.21
    # -----------------------------
    
    import tensorflow as tf 
    import numpy as np 
    import random
    from collections import deque 
    
    class BrainDQN:
    
        # Hyper Parameters:
        ACTION = 2
        FRAME_PER_ACTION = 1
        GAMMA = 0.99 # decay rate of past observations
        OBSERVE = 100000. # timesteps to observe before training
        EXPLORE = 150000. # frames over which to anneal epsilon
        FINAL_EPSILON = 0.0 # final value of epsilon
        INITIAL_EPSILON = 0.0 # starting value of epsilon
        REPLAY_MEMORY = 50000 # number of previous transitions to remember
        BATCH_SIZE = 32 # size of minibatch
    
        def __init__(self):
            # init replay memory
            self.replayMemory = deque()
            # init Q network
            self.createQNetwork()
            # init some parameters
            self.timeStep = 0
            self.epsilon = self.INITIAL_EPSILON
    
        def createQNetwork(self):
            # network weights
            W_conv1 = self.weight_variable([8,8,4,32])
            b_conv1 = self.bias_variable([32])
    
            W_conv2 = self.weight_variable([4,4,32,64])
            b_conv2 = self.bias_variable([64])
    
            W_conv3 = self.weight_variable([3,3,64,64])
            b_conv3 = self.bias_variable([64])
    
            W_fc1 = self.weight_variable([1600,512])
            b_fc1 = self.bias_variable([512])
    
            W_fc2 = self.weight_variable([512,self.ACTION])
            b_fc2 = self.bias_variable([self.ACTION])
    
            # input layer
    
            self.stateInput = tf.placeholder("float",[None,80,80,4])
    
            # hidden layers
            h_conv1 = tf.nn.relu(self.conv2d(self.stateInput,W_conv1,4) + b_conv1)
            h_pool1 = self.max_pool_2x2(h_conv1)
    
            h_conv2 = tf.nn.relu(self.conv2d(h_pool1,W_conv2,2) + b_conv2)
    
            h_conv3 = tf.nn.relu(self.conv2d(h_conv2,W_conv3,1) + b_conv3)
    
            h_conv3_flat = tf.reshape(h_conv3,[-1,1600])
            h_fc1 = tf.nn.relu(tf.matmul(h_conv3_flat,W_fc1) + b_fc1)
    
            # Q Value layer
            self.QValue = tf.matmul(h_fc1,W_fc2) + b_fc2
    
            self.actionInput = tf.placeholder("float",[None,self.ACTION])
            self.yInput = tf.placeholder("float", [None]) 
            Q_action = tf.reduce_sum(tf.mul(self.QValue, self.actionInput), reduction_indices = 1)
            self.cost = tf.reduce_mean(tf.square(self.yInput - Q_action))
            self.trainStep = tf.train.AdamOptimizer(1e-6).minimize(self.cost)
    
            # saving and loading networks
            saver = tf.train.Saver()
            self.session = tf.InteractiveSession()
            self.session.run(tf.initialize_all_variables())
            checkpoint = tf.train.get_checkpoint_state("saved_networks")
            if checkpoint and checkpoint.model_checkpoint_path:
                    saver.restore(self.session, checkpoint.model_checkpoint_path)
                    print "Successfully loaded:", checkpoint.model_checkpoint_path
            else:
                    print "Could not find old network weights"
    
        def trainQNetwork(self):
            # Step 1: obtain random minibatch from replay memory
            minibatch = random.sample(self.replayMemory,self.BATCH_SIZE)
            state_batch = [data[0] for data in minibatch]
            action_batch = [data[1] for data in minibatch]
            reward_batch = [data[2] for data in minibatch]
            nextState_batch = [data[3] for data in minibatch]
    
            # Step 2: calculate y 
            y_batch = []
            QValue_batch = self.QValue.eval(feed_dict={self.stateInput:nextState_batch})
            for i in range(0,self.BATCH_SIZE):
                terminal = minibatch[i][4]
                if terminal:
                    y_batch.append(reward_batch[i])
                else:
                    y_batch.append(reward_batch[i] + GAMMA * np.max(QValue_batch[i]))
    
            self.trainStep.run(feed_dict={
                self.yInput : y_batch,
                self.actionInput : action_batch,
                self.stateInput : state_batch
                })
    
            # save network every 100000 iteration
            if self.timeStep % 10000 == 0:
                saver.save(self.session, 'saved_networks/' + 'network' + '-dqn', global_step = self.timeStep)
    
    
        def setPerception(self,nextObservation,action,reward,terminal):
            newState = np.append(nextObservation,self.currentState[:,:,1:],axis = 2)
            self.replayMemory.append((self.currentState,action,reward,newState,terminal))
            if len(self.replayMemory) > self.REPLAY_MEMORY:
                self.replayMemory.popleft()
            if self.timeStep > self.OBSERVE:
                # Train the network
                self.trainQNetwork()
    
            self.currentState = newState
            self.timeStep += 1
    
        def getAction(self):
            QValue = self.QValue.eval(feed_dict= {self.stateInput:[self.currentState]})[0]
            action = np.zeros(self.ACTION)
            action_index = 0
            if self.timeStep % self.FRAME_PER_ACTION == 0:
                if random.random() <= self.epsilon:
                    action_index = random.randrange(self.ACTION)
                    action[action_index] = 1
                else:
                    action_index = np.argmax(QValue)
                    action[action_index] = 1
            else:
                action[0] = 1 # do nothing
    
            # change episilon
            if self.epsilon > self.FINAL_EPSILON and self.timeStep > self.OBSERVE:
                self.epsilon -= (self.INITIAL_EPSILON - self.FINAL_EPSILON)/self.EXPLORE
    
            return action
    
        def setInitState(self,observation):
            self.currentState = np.stack((observation, observation, observation, observation), axis = 2)
    
        def weight_variable(self,shape):
            initial = tf.truncated_normal(shape, stddev = 0.01)
            return tf.Variable(initial)
    
        def bias_variable(self,shape):
            initial = tf.constant(0.01, shape = shape)
            return tf.Variable(initial)
    
        def conv2d(self,x, W, stride):
            return tf.nn.conv2d(x, W, strides = [1, stride, stride, 1], padding = "SAME")
    
        def max_pool_2x2(self,x):
            return tf.nn.max_pool(x, ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = "SAME")
    
    

    一共也只有160代码。
    如果这个任务不使用深度学习,而是人工的从图像中找到小鸟,然后计算小鸟的轨迹,然后计算出应该怎么按键,那么代码没有好几千行是不可能的。深度学习大大减少了代码工作。

    小结

    本文从代码角度对于DQN做了一定的分析,对于DQN的应用,大家可以在此基础上做各种尝试。

    展开全文
  • 迁移学习概述(Transfer Learning

    万次阅读 多人点赞 2019-01-06 23:41:45
    迁移学习概述(Transfer Learning)迁移学习概述背景定义及分类关键点基于实例的迁移基于特征的迁移特征选择特征映射基于共享参数的迁移深度学习和迁移学习结合Pre-training+Fine-tuningSDA (Stacked Denoising Auto...
  • 吴恩达 Coursera DeepLearning.ai《深度学习》系列课程笔记目录总集
  • 联邦学习(Federated Learning

    万次阅读 多人点赞 2019-04-27 10:38:47
    联邦学习(Federated Learning)是一种新兴的人工智能基础技术,在 2016 年由谷歌最先提出,原本用于解决安卓手机终端用户在本地更新模型的问题,其设计目标是在保障大数据交换时的信息安全、保护终端数据和个人...
  • 元学习Meta Learning/Learning to learn

    万次阅读 多人点赞 2018-12-11 12:56:35
    Meta Learning 元学习或者叫做 Learning to Learn 学会学习 已经成为继Reinforcement Learning 增强学习之后又一个重要的研究分支(以后仅称为Meta Learning)。对于人工智能的理论研究,呈现出了 Artificial ...
  • 本文是对 http://mnemstudio.org/path-finding-q-learning-tutorial.htm 的翻译,共分两部分,第一部分为中文翻译,第二部分为英文原文。...这篇教程通俗易懂,是学习理解 Q-learning 算法工作原理的绝佳入门材料。
  • from __future__ import print_function import IPython import sys from music21 import * import numpy as np from grammar import * from qa import * from preprocess import * from music_utils import * ...
  • Learning Spark

    千次下载 热门讨论 2015-01-07 16:43:17
    Learning Spark英文版,整理版,纠正其中的错误。只有前五章
  • Deep learning和structured learning的关系

    万次阅读 2020-05-25 17:16:35
    unidirectional RNN does not consider the whole ... Using Viterbi, structured learning consider the whole sequence. Cost and error in RNN are not always related. Cost in structured learning is the upp
  • Meta Learning/Learning to learn

    千次阅读 2019-05-30 11:09:32
    转自:知乎 智能单元 Flood Sung 《最前沿:百家争鸣的Meta Learning/Learning to learn》 仅供学习使用,如有侵权,请私删 1 前言 Meta Learning 元学习或者叫做 Learning to Learn 学会学习 已经成为继...
  • Lifelong Learning

    千次阅读 2019-05-26 21:51:38
    Lifelong Learning https://www.forbes.com/sites/kpmg/2018/04/23/the-changing-nature-of-work-why-lifelong-learning-matters-more-than-ever/#4e04e90e1e95 终身学习(Lifelong Learning或Continuous ...
  • Style Learning and Transfer Style-Content Separation by Anisotropic Part Scales (2010) [Paper] Design Preserving Garment Transfer (2012) [Paper] Analogy-Driven 3D Style Transfer (2014) [Paper] Elem...
  • L1 Mechine Learning to DeepLearning
  • 为了 “多快好省” 地通往炼丹之路,炼丹师们开始研究 Zero-shot Learning / One-shot Learning / Few-shot Learning。 爱上一匹野马 (泛化能力),可我的家里没有草原 (海量数据) 。 Learning类型
  • 【Meta Learning学习笔记】Meta Learning详解

    万次阅读 多人点赞 2019-06-07 14:09:03
    · 为何要研究Meta Learning? 尽管我是研究生成模型的,但是最近对于meta learning产生了强烈的兴趣。理由在于,GANs本身是一个特别吃数据集的模型,从某种意义上来说,数据集的好坏对最后生成效果的影响,不...
  • 2018 Knowledge Distillation by On-the-Fly Native Ensemble(NIPS... Memory Replay GANs: learning to generate images from new categories without forgetting (NIPS2018)  Rotate your Networks: Better W...
  • Ian Goodfellow, Yoshua Bengio, "Deep Learning (draft)" 2016 | ISBN-10: 0262035618 | 800 pages | PDF | 23 MB http://www.deeplearningbook.org/ "Written by three experts in the field, Deep Learning is...
  • DeepLearning | Zero Shot Learning 零样本学习

    万次阅读 多人点赞 2018-08-24 23:11:44
    最近因为比赛的原因看了一些关于Zero Shot Learning (ZSL)的论文,总的来说这个方向还是有一些前人的工作的,不过有些内容个人觉得确实有些不太靠谱和跑偏,找了两篇我个人认为思路比较清晰和实用的论文,在这里介绍...
  • 文章目录视频链接:台大 李宏毅 PPT_lifelong learning / continual learning1. 什么是灾难性遗忘?2. 解决方法:为什么不使用 multi-task trainingEWC (Elastic Weight Consolidation)Generation DatasKnowledge ...
  • Incremental Learning

    千次阅读 2019-04-19 17:03:10
    2018-2019 Paper: Multi-task settings: Class-incremental Learning via Deep Model Consolidation https://arxiv.org/abs/1903.07864v1 ...End-to-end Incremental Learning https://github.com/fmcp/EndToEndI...
  • SLAM Machine Learning based MVS

    万次阅读 2019-12-14 12:39:28
    Machine Learning based MVS Matchnet: Unifying feature and metric learning for patch-based matching, X. Han, Thomas Leung, Y. Jia, R. Sukthankar, A. C. Berg. CVPR 2015. Stereo matching by training a co...
  • 【3D Machine Learning】资源

    万次阅读 2019-12-14 19:15:07
    Available Courses Stanford CS231A: Computer Vision-From 3D Reconstruction to Recognition (Winter ...UCSD CSE291-I00: Machine Learning for 3D Data (Winter 2018) Stanford CS468: Machine Learning for ...
  • Residual Learning

    千次阅读 2018-06-05 01:04:57
    本文参考的论文 Deep Residual Learning for Image Recognition Identity Mappings in Deep Residual Networks Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning Wide ...
  • Curriculum Learning

    千次阅读 2018-09-05 22:29:32
    从一篇论文学习“课程学习”,着重关注Curriculum Learning,在此简单记录相关内容。   论文题目:Curriculum Learning for Natural Answer Generation(中科院自动化所) 论文地址:...
  • TD Learning,SARSA,Q Learning

    千次阅读 2018-08-27 10:51:29
    DEEP REINFORCEMENT LEARNING : AN OVERVIEW 发现里边介绍SARSA时,伪代码是错误的。 1.TD Learning 2.SARSA 错误就在于,sarsa算法的下一个动作在这次更新时就已经确定了。所以需要在step迭代之前对action...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 156,747
精华内容 62,698
关键字:

learning