<!DOCTYPE html> <!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]--> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Recurrent Group教程 — PaddlePaddle 文档</title> <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" /> <link rel="index" title="索引" href="../../genindex.html"/> <link rel="search" title="搜索" href="../../search.html"/> <link rel="top" title="PaddlePaddle 文档" href="../../index.html"/> <link rel="up" title="RNN模型" href="index_cn.html"/> <link rel="next" title="支持双层序列作为输入的Layer" href="hierarchical_layer_cn.html"/> <link rel="prev" title="RNN配置" href="rnn_config_cn.html"/> <link rel="stylesheet" href="https://cdn.jsdelivr.net/perfect-scrollbar/0.6.14/css/perfect-scrollbar.min.css" type="text/css" /> <link rel="stylesheet" href="../../_static/css/override.css" type="text/css" /> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?b9a314ab40d04d805655aab1deee08ba"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> <script src="../../_static/js/modernizr.min.js"></script> </head> <body class="wy-body-for-nav" role="document"> <header class="site-header"> <div class="site-logo"> <a href="/"><img src="../../_static/images/PP_w.png"></a> </div> <div class="site-nav-links"> <div class="site-menu"> <a class="fork-on-github" href="https://github.com/PaddlePaddle/Paddle" target="_blank"><i class="fa fa-github"></i>Fork me on Github</a> <div class="language-switcher dropdown"> <a type="button" data-toggle="dropdown"> <span>English</span> <i class="fa fa-angle-up"></i> <i class="fa fa-angle-down"></i> </a> <ul class="dropdown-menu"> <li><a href="/doc_cn">中文</a></li> <li><a href="/doc">English</a></li> </ul> </div> <ul class="site-page-links"> <li><a href="/">Home</a></li> </ul> </div> <div class="doc-module"> <ul class="current"> <li class="toctree-l1"><a class="reference internal" href="../../getstarted/index_cn.html">新手入门</a></li> <li class="toctree-l1"><a class="reference internal" href="../../build_and_install/index_cn.html">安装与编译</a></li> <li class="toctree-l1 current"><a class="reference internal" href="../index_cn.html">进阶使用</a></li> <li class="toctree-l1"><a class="reference internal" href="../../dev/index_cn.html">开发标准</a></li> <li class="toctree-l1"><a class="reference internal" href="../../faq/index_cn.html">FAQ</a></li> </ul> <div role="search"> <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get"> <input type="text" name="q" placeholder="Search docs" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> </div> </div> </header> <div class="main-content-wrap"> <nav class="doc-menu-vertical" role="navigation"> <ul class="current"> <li class="toctree-l1"><a class="reference internal" href="../../getstarted/index_cn.html">新手入门</a><ul> <li class="toctree-l2"><a class="reference internal" href="../../getstarted/quickstart_cn.html">快速开始</a></li> <li class="toctree-l2"><a class="reference internal" href="../../getstarted/concepts/use_concepts_cn.html">基本使用概念</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="../../build_and_install/index_cn.html">安装与编译</a><ul> <li class="toctree-l2"><a class="reference internal" href="../../build_and_install/pip_install_cn.html">使用pip安装</a></li> <li class="toctree-l2"><a class="reference internal" href="../../build_and_install/docker_install_cn.html">使用Docker安装运行</a></li> <li class="toctree-l2"><a class="reference internal" href="../../build_and_install/build_from_source_cn.html">从源码编译</a></li> </ul> </li> <li class="toctree-l1 current"><a class="reference internal" href="../index_cn.html">进阶使用</a><ul class="current"> <li class="toctree-l2"><a class="reference internal" href="../cmd_parameter/index_cn.html">命令行参数设置</a><ul> <li class="toctree-l3"><a class="reference internal" href="../cmd_parameter/use_case_cn.html">使用案例</a></li> <li class="toctree-l3"><a class="reference internal" href="../cmd_parameter/arguments_cn.html">参数概述</a></li> <li class="toctree-l3"><a class="reference internal" href="../cmd_parameter/detail_introduction_cn.html">细节描述</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="../cluster/index_cn.html">分布式训练</a><ul> <li class="toctree-l3"><a class="reference internal" href="../cluster/preparations_cn.html">环境准备</a></li> <li class="toctree-l3"><a class="reference internal" href="../cluster/cmd_argument_cn.html">启动参数说明</a></li> <li class="toctree-l3"><a class="reference internal" href="../cluster/multi_cluster/index_cn.html">在不同集群中运行</a><ul> <li class="toctree-l4"><a class="reference internal" href="../cluster/multi_cluster/k8s_cn.html">Kubernetes单机训练</a></li> <li class="toctree-l4"><a class="reference internal" href="../cluster/multi_cluster/k8s_distributed_cn.html">Kubernetes分布式训练</a></li> <li class="toctree-l4"><a class="reference internal" href="../cluster/multi_cluster/openmpi_cn.html">在OpenMPI集群中启动训练</a></li> <li class="toctree-l4"><a class="reference internal" href="../cluster/multi_cluster/fabric_cn.html">使用fabric启动集群训练</a></li> <li class="toctree-l4"><a class="reference internal" href="../cluster/multi_cluster/k8s_aws_cn.html">Kubernetes on AWS</a></li> </ul> </li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="../capi/index_cn.html">C-API预测库</a><ul> <li class="toctree-l3"><a class="reference internal" href="../capi/compile_paddle_lib_cn.html">安装与编译C-API预测库</a></li> <li class="toctree-l3"><a class="reference internal" href="../capi/organization_of_the_inputs_cn.html">输入/输出数据组织</a></li> <li class="toctree-l3"><a class="reference internal" href="../capi/workflow_of_capi_cn.html">C-API使用流程</a></li> </ul> </li> <li class="toctree-l2 current"><a class="reference internal" href="index_cn.html">RNN模型</a><ul class="current"> <li class="toctree-l3"><a class="reference internal" href="rnn_config_cn.html">RNN配置</a></li> <li class="toctree-l3 current"><a class="current reference internal" href="#">Recurrent Group教程</a></li> <li class="toctree-l3"><a class="reference internal" href="hierarchical_layer_cn.html">支持双层序列作为输入的Layer</a></li> <li class="toctree-l3"><a class="reference internal" href="hrnn_rnn_api_compare_cn.html">单双层RNN API对比介绍</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="../optimization/gpu_profiling_cn.html">GPU性能调优</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="../../dev/index_cn.html">开发标准</a><ul> <li class="toctree-l2"><a class="reference internal" href="../../dev/contribute_to_paddle_cn.html">如何贡献代码</a></li> <li class="toctree-l2"><a class="reference internal" href="../../dev/write_docs_cn.html">如何贡献文档</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="../../faq/index_cn.html">FAQ</a><ul> <li class="toctree-l2"><a class="reference internal" href="../../faq/build_and_install/index_cn.html">编译安装与单元测试</a></li> <li class="toctree-l2"><a class="reference internal" href="../../faq/model/index_cn.html">模型配置</a></li> <li class="toctree-l2"><a class="reference internal" href="../../faq/parameter/index_cn.html">参数设置</a></li> <li class="toctree-l2"><a class="reference internal" href="../../faq/local/index_cn.html">本地训练与预测</a></li> <li class="toctree-l2"><a class="reference internal" href="../../faq/cluster/index_cn.html">集群训练与预测</a></li> </ul> </li> </ul> </nav> <section class="doc-content-wrap"> <div role="navigation" aria-label="breadcrumbs navigation"> <ul class="wy-breadcrumbs"> <li><a href="../index_cn.html">进阶使用</a> > </li> <li><a href="index_cn.html">RNN模型</a> > </li> <li>Recurrent Group教程</li> </ul> </div> <div class="wy-nav-content" id="doc-content"> <div class="rst-content"> <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> <div itemprop="articleBody"> <div class="section" id="recurrent-group"> <span id="recurrent-group"></span><h1>Recurrent Group教程<a class="headerlink" href="#recurrent-group" title="永久链接至标题">¶</a></h1> <div class="section" id=""> <span id="id1"></span><h2>概述<a class="headerlink" href="#" title="永久链接至标题">¶</a></h2> <p>序列数据是自然语言处理任务面对的一种主要输入数据类型。</p> <p>一句话是由词语构成的序列,多句话进一步构成了段落。因此,段落可以看作是一个嵌套的双层的序列,这个序列的每个元素又是一个序列。</p> <p>双层序列是PaddlePaddle支持的一种非常灵活的数据组织方式,帮助我们更好地描述段落、多轮对话等更为复杂的语言数据。基于双层序列输入,我们可以设计搭建一个灵活的、层次化的RNN,分别从词语和句子级别编码输入数据,同时也能够引入更加复杂的记忆机制,更好地完成一些复杂的语言理解任务。</p> <p>在PaddlePaddle中,<code class="docutils literal"><span class="pre">recurrent_group</span></code>是一种任意复杂的RNN单元,用户只需定义RNN在一个时间步内完成的计算,PaddlePaddle负责完成信息和误差在时间序列上的传播。</p> <p>更进一步,<code class="docutils literal"><span class="pre">recurrent_group</span></code>同样可以扩展到双层序列的处理上。通过两个嵌套的<code class="docutils literal"><span class="pre">recurrent_group</span></code>分别定义子句级别和词语级别上需要完成的运算,最终实现一个层次化的复杂RNN。</p> <p>目前,在PaddlePaddle中,能够对双向序列进行处理的有<code class="docutils literal"><span class="pre">recurrent_group</span></code>和部分Layer,具体可参考文档:<a href = "hierarchical_layer_cn.html">支持双层序列作为输入的Layer</a>。</p> </div> <div class="section" id=""> <span id="id2"></span><h2>相关概念<a class="headerlink" href="#" title="永久链接至标题">¶</a></h2> <div class="section" id=""> <span id="id3"></span><h3>基本原理<a class="headerlink" href="#" title="永久链接至标题">¶</a></h3> <p><code class="docutils literal"><span class="pre">recurrent_group</span></code> 是PaddlePaddle支持的一种任意复杂的RNN单元。使用者只需要关注于设计RNN在一个时间步之内完成的计算,PaddlePaddle负责完成信息和梯度在时间序列上的传播。</p> <p>PaddlePaddle中,<code class="docutils literal"><span class="pre">recurrent_group</span></code>的一个简单调用如下:</p> <div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">recurrent_group</span><span class="p">(</span><span class="n">step</span><span class="p">,</span> <span class="nb">input</span><span class="p">,</span> <span class="n">reverse</span><span class="p">)</span> </pre></div> </div> <ul class="simple"> <li>step:一个可调用的函数,定义一个时间步之内RNN单元完成的计算</li> <li>input:输入,必须是一个单层序列,或者一个双层序列</li> <li>reverse:是否以逆序处理输入序列</li> </ul> <p>使用<code class="docutils literal"><span class="pre">recurrent_group</span></code>的核心是设计step函数的计算逻辑。step函数内部可以自由组合PaddlePaddle支持的各种layer,完成任意的运算逻辑。<code class="docutils literal"><span class="pre">recurrent_group</span></code> 的输入(即input)会成为step函数的输入,由于step 函数只关注于RNN一个时间步之内的计算,在这里<code class="docutils literal"><span class="pre">recurrent_group</span></code>替我们完成了原始输入数据的拆分。</p> </div> <div class="section" id=""> <span id="id4"></span><h3>输入<a class="headerlink" href="#" title="永久链接至标题">¶</a></h3> <p><code class="docutils literal"><span class="pre">recurrent_group</span></code>处理的输入序列主要分为以下三种类型:</p> <ul class="simple"> <li><strong>数据输入</strong>:一个双层序列进入<code class="docutils literal"><span class="pre">recurrent_group</span></code>会被拆解为一个单层序列,一个单层序列进入<code class="docutils literal"><span class="pre">recurrent_group</span></code>会被拆解为非序列,然后交给step函数,这一过程对用户是完全透明的。可以有以下两种:1)通过data_layer拿到的用户输入;2)其它layer的输出。</li> <li><strong>只读Memory输入</strong>:<code class="docutils literal"><span class="pre">StaticInput</span></code> 定义了一个只读的Memory,由<code class="docutils literal"><span class="pre">StaticInput</span></code>指定的输入不会被<code class="docutils literal"><span class="pre">recurrent_group</span></code>拆解,<code class="docutils literal"><span class="pre">recurrent_group</span></code> 循环展开的每个时间步总是能够引用所有输入,可以是一个非序列,或者一个单层序列。</li> <li><strong>序列生成任务的输入</strong>:<code class="docutils literal"><span class="pre">GeneratedInput</span></code>只用于在序列生成任务中指定输入数据。</li> </ul> </div> <div class="section" id=""> <span id="id5"></span><h3>输入示例<a class="headerlink" href="#" title="永久链接至标题">¶</a></h3> <p>序列生成任务大多遵循encoder-decoer架构,encoder和decoder可以是能够处理序列的任意神经网络单元,而RNN是最流行的选择。</p> <p>给定encoder输出和当前词,decoder每次预测产生下一个最可能的词语。在这种结构中,decoder接受两个输入:</p> <ul class="simple"> <li>要生成的目标序列:是decoder的数据输入,也是decoder循环展开的依据,<code class="docutils literal"><span class="pre">recurrent_group</span></code>会对这类输入进行拆解。</li> <li>encoder输出,可以是一个非序列,或者一个单层序列:是一个unbounded memory,decoder循环展开的每一个时间步会引用全部结果,不应该被拆解,这种类型的输入必须通过<code class="docutils literal"><span class="pre">StaticInput</span></code>指定。关于Unbounded Memory的更多讨论请参考论文 <a class="reference external" href="https://arxiv.org/abs/1410.5401">Neural Turning Machine</a>。</li> </ul> <p>在序列生成任务中,decoder RNN总是引用上一时刻预测出的词的词向量,作为当前时刻输入。<code class="docutils literal"><span class="pre">GeneratedInput</span></code>自动完成这一过程。</p> </div> <div class="section" id=""> <span id="id6"></span><h3>输出<a class="headerlink" href="#" title="永久链接至标题">¶</a></h3> <p><code class="docutils literal"><span class="pre">step</span></code>函数必须返回一个或多个Layer的输出,这个Layer的输出会作为整个<code class="docutils literal"><span class="pre">recurrent_group</span></code> 最终的输出结果。在输出的过程中,<code class="docutils literal"><span class="pre">recurrent_group</span></code> 会将每个时间步的输出拼接,这个过程对用户也是透明的。</p> </div> <div class="section" id="memory"> <span id="memory"></span><h3>memory<a class="headerlink" href="#memory" title="永久链接至标题">¶</a></h3> <p>memory只能在<code class="docutils literal"><span class="pre">recurrent_group</span></code>中定义和使用。memory不能独立存在,必须指向一个PaddlePaddle定义的Layer。引用memory得到这layer上一时刻输出,因此,可以将memory理解为一个时延操作。</p> <p>可以显示地指定一个layer的输出用于初始化memory。不指定时,memory默认初始化为0。</p> </div> </div> <div class="section" id="rnn"> <span id="rnn"></span><h2>双层RNN介绍<a class="headerlink" href="#rnn" title="永久链接至标题">¶</a></h2> <p><code class="docutils literal"><span class="pre">recurrent_group</span></code>帮助我们完成对输入序列的拆分,对输出的合并,以及计算逻辑在序列上的循环展开。</p> <p>利用这种特性,两个嵌套的<code class="docutils literal"><span class="pre">recurrent_group</span></code>能够处理双层序列,实现词语和句子两个级别的双层RNN结构。</p> <ul class="simple"> <li>单层(word-level)RNN:每个状态(state)对应一个词(word)。</li> <li>双层(sequence-level)RNN:一个双层RNN由多个单层RNN组成,每个单层RNN(即双层RNN的每个状态)对应一个子句(subseq)。</li> </ul> <p>为了描述方便,下文以NLP任务为例,将含有子句(subseq)的段落定义为一个双层序列,将含有词语的句子定义为一个单层序列,那么0层序列即为一个词语。</p> </div> <div class="section" id="rnn"> <span id="id7"></span><h2>双层RNN的使用<a class="headerlink" href="#rnn" title="永久链接至标题">¶</a></h2> <div class="section" id=""> <span id="id8"></span><h3>训练流程的使用方法<a class="headerlink" href="#" title="永久链接至标题">¶</a></h3> <p>使用 <code class="docutils literal"><span class="pre">recurrent_group</span></code>需要遵循以下约定:</p> <ul class="simple"> <li><strong>单进单出</strong>:输入和输出都是单层序列。<ul> <li>如果有多个输入,不同输入序列含有的词语数必须严格相等。</li> <li>输出一个单层序列,输出序列的词语数和输入序列一致。</li> <li>memory:在step函数中定义 memory指向一个layer,通过引用memory得到这个layer上一个时刻输出,形成recurrent 连接。memory的is_seq参数必须为false。如果没有定义memory,每个时间步之内的运算是独立的。</li> <li>boot_layer:memory的初始状态,默认初始状为0,memory的is_seq参数必须为false。</li> </ul> </li> <li><strong>双进双出</strong>:输入和输出都是双层序列。<ul> <li>如果有多个输入序列,不同输入含有的子句(subseq)数必须严格相等,但子句含有的词语数可以不相等。</li> <li>输出一个双层序列,子句(subseq)数、子句的单词数和指定的一个输入序列一致,默认为第一个输入。</li> <li>memory:在step函数中定义memory,指向一个layer,通过引用memory得到这个layer上一个时刻的输出,形成recurrent连接。定义在外层<code class="docutils literal"><span class="pre">recurrent_group</span></code> step函数中的memory,能够记录上一个subseq 的状态,可以是一个单层序列(只作为read-only memory),也可以是一个词语。如果没有定义memory,那么 subseq 之间的运算是独立的。</li> <li>boot_layer:memory 初始状态,可以是一个单层序列(只作为read-only memory)或一个向量。默认不设置,即初始状态为0。</li> </ul> </li> <li><strong>双进单出</strong>:目前还未支持,会报错”In hierachical RNN, all out links should be from sequences now”。</li> </ul> </div> <div class="section" id=""> <span id="id9"></span><h3>生成流程的使用方法<a class="headerlink" href="#" title="永久链接至标题">¶</a></h3> <p>使用<code class="docutils literal"><span class="pre">beam_search</span></code>需要遵循以下约定:</p> <ul class="simple"> <li>单层RNN:从一个word生成下一个word。</li> <li>双层RNN:即把单层RNN生成后的subseq给拼接成一个新的双层seq。从语义上看,也不存在一个subseq直接生成下一个subseq的情况。</li> </ul> </div> </div> </div> </div> </div> <footer> <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation"> <a href="hierarchical_layer_cn.html" class="btn btn-neutral float-right" title="支持双层序列作为输入的Layer" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a> <a href="rnn_config_cn.html" class="btn btn-neutral" title="RNN配置" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a> </div> <hr/> <div role="contentinfo"> <p> © Copyright 2016, PaddlePaddle developers. </p> </div> Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>. </footer> </div> </div> </section> </div> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', VERSION:'', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true, SOURCELINK_SUFFIX: ".txt", }; </script> <script type="text/javascript" src="../../_static/jquery.js"></script> <script type="text/javascript" src="../../_static/underscore.js"></script> <script type="text/javascript" src="../../_static/doctools.js"></script> <script type="text/javascript" src="../../_static/translations.js"></script> <script type="text/javascript" src="https://cdn.bootcss.com/mathjax/2.7.0/MathJax.js"></script> <script type="text/javascript" src="../../_static/js/theme.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/perfect-scrollbar/0.6.14/js/perfect-scrollbar.jquery.min.js"></script> <script src="../../_static/js/paddle_doc_init.js"></script> </body> </html>