提交 5d694f59 编写于 作者: T Travis CI

Deploy to GitHub Pages: aef71a6e

上级 89c9066c
......@@ -251,7 +251,7 @@ PaddlePaddle的参数使用名字 :code:`name` 作为参数的ID,相同名字
那么用户需要拉取所有的远程分支到本机,命令为 :code:`git fetch upstream`,然后重新cmake即可。
12. A protocol message was rejected because it was too big
----------------------------------------------------------
------------------------------------------------------------
如果在训练NLP相关模型时,出现以下错误:
......@@ -316,10 +316,42 @@ Paddle二进制在运行时捕获了浮点数异常,只要出现浮点数异
* 模型一直不收敛,发散到了一个数值特别大的地方。
* 训练数据有问题,导致参数收敛到了一些奇异的情况。或者输入数据尺度过大,有些特征的取值达到数百万,这时进行矩阵乘法运算就可能导致浮点数溢出。
主要的解决办法是减小学习率或者对数据进行归一化处理。
这里有两种有效的解决方法:
1. 设置 :code:`gradient_clipping_threshold` 参数,示例代码如下:
.. code-block:: python
optimizer = paddle.optimizer.RMSProp(
learning_rate=1e-3,
gradient_clipping_threshold=10.0,
regularization=paddle.optimizer.L2Regularization(rate=8e-4))
具体可以参考 `nmt_without_attention <https://github.com/PaddlePaddle/models/blob/develop/nmt_without_attention/train.py#L35>`_ 示例。
2. 设置 :code:`error_clipping_threshold` 参数,示例代码如下:
.. code-block:: python
decoder_inputs = paddle.layer.fc(
act=paddle.activation.Linear(),
size=decoder_size * 3,
bias_attr=False,
input=[context, current_word],
layer_attr=paddle.attr.ExtraLayerAttribute(
error_clipping_threshold=100.0))
完整代码可以参考示例 `machine translation <https://github.com/PaddlePaddle/book/blob/develop/08.machine_translation/train.py#L66>`_ 。
两种方法的区别:
1. 两者都是对梯度的截断,但截断时机不同,前者在 :code:`optimzier` 更新网络参数时应用;后者在激活函数反向计算时被调用;
2. 截断对象不同:前者截断可学习参数的梯度,后者截断回传给前层的梯度;
除此之外,还可以通过减小学习律或者对数据进行归一化处理来解决这类问题。
15. 编译安装后执行 import paddle.v2 as paddle 报ImportError: No module named v2
------------------------------------------------------------------------
------------------------------------------------------------------------------------------
先查看一下是否曾经安装过paddle v1版本,有的话需要先卸载:
pip uninstall py_paddle paddle
......@@ -329,7 +361,7 @@ pip uninstall py_paddle paddle
pip install python/dist/paddle*.whl && pip install ../paddle/dist/py_paddle*.whl
16. PaddlePaddle存储的参数格式是什么,如何和明文进行相互转化
---------------------------------------------------------
---------------------------------------------------------------------
PaddlePaddle保存的模型参数文件内容由16字节头信息和网络参数两部分组成。头信息中,1~4字节表示PaddlePaddle版本信息,请直接填充0;5~8字节表示每个参数占用的字节数,当保存的网络参数为float类型时为4,double类型时为8;9~16字节表示保存的参数总个数。
......@@ -381,7 +413,7 @@ PaddlePaddle保存的模型参数文件内容由16字节头信息和网络参数
parameters.set('emb', load_parameter(emb_param_file, 30000, 256))
18. 集群多节点训练,日志中保存均为网络通信类错误
------------------------------
-----------------------------------------------------------
集群多节点训练,日志报错为网络通信类错误,比如 :code:`Connection reset by peer` 等。
此类报错通常是由于某一个节点的错误导致这个节点的训练进程退出,从而引发其他节点无法连接导致,可以参考下面的步骤排查:
......@@ -392,8 +424,8 @@ PaddlePaddle保存的模型参数文件内容由16字节头信息和网络参数
* 如果当前MPI集群并不支持任务独占模式,可以联系OP是否可以更换集群或升级当前集群。
19. PaddlePaddle如何输出多个层
------------------------------
19. 如何调用 infer 接口输出多个layer的预测结果
-----------------------------------------------------------
* 将需要输出的层作为 :code:`paddle.inference.Inference()` 接口的 :code:`output_layer` 参数输入,代码如下:
......@@ -405,9 +437,28 @@ PaddlePaddle保存的模型参数文件内容由16字节头信息和网络参数
.. code-block:: python
out = inferer.infer(input=data_batch, flatten_result=False, field=["value"])
out = inferer.infer(input=data_batch, field=["value"])
需要注意的是:
* 如果指定了2个layer作为输出层,实际上需要的输出结果是两个矩阵;
* 假设第一个layer的输出A是一个 N1 * M1 的矩阵,第二个 Layer 的输出B是一个 N2 * M2 的矩阵;
* paddle.v2 默认会将A和B 横向拼接,当N1 和 N2 大小不一样时,会报如下的错误:
.. code-block:: python
ValueError: all the input array dimensions except for the concatenation axis must match exactly
多个层的输出矩阵的高度不一致导致拼接失败,这种情况常常发生在:
这里设置 :code:`flatten_result=False`,得到的输出结果是元素个数等于输出字段数的 :code:`list`,该 :code:`list` 的每个元素是由所有输出层相应字段结果组成的 :code:`list`,每个字段结果的类型是 :code:`numpy.array`。:code:`flatten_result` 的默认值为 :code:`True`,该情况下,PaddlePaddle会分别对每个字段将所有输出层的结果按行进行拼接,如果各输出层该字段 :code:`numpy.array` 结果的相应维数不匹配,程序将不能正常运行。
* 同时输出序列层和非序列层;
* 多个输出层处理多个不同长度的序列;
此时可以在调用infer接口时通过设置 :code:`flatten_result=False` , 跳过“拼接”步骤,来解决上面的问题。这时,infer接口的返回值是一个python list:
* list 中元素的个数等于网络中输出层的个数;
* list 中每个元素是一个layer的输出结果矩阵,类型是numpy的ndarray;
* 每一个layer输出矩阵的高度,在非序列输入时:等于样本数;序列输入时等于:输入序列中元素的总数;宽度等于配置中layer的size;
20. :code:`paddle.layer.memory` 的参数 :code:`name` 如何使用
-------------------------------------------------------------
......@@ -416,8 +467,8 @@ PaddlePaddle保存的模型参数文件内容由16字节头信息和网络参数
* PaddlePaddle的所有layer都有唯一的name,用户通过参数 :code:`name` 设定,当用户没有显式设定时,PaddlePaddle会自动设定。而 :code:`paddle.layer.memory` 不是真正的layer,其name由参数 :code:`memory_name` 设定,当用户没有显式设定时,PaddlePaddle会自动设定。:code:`paddle.layer.memory` 的参数 :code:`name` 用于指定其要关联的layer,需要用户显式设定。
21. dropout 使用
-----------------
21. 两种使用 drop_out 的方法有何区别?
-----------------------------------------------------
* 在PaddlePaddle中使用dropout有两种方式
......@@ -512,3 +563,30 @@ PaddlePaddle目前支持8种learning_rate_schedule,这8种learning_rate_schedu
出现该错误的原因一般是用户对不同layer的参数 :code:`name` 设置了相同的取值。遇到该错误时,先找出参数 :code:`name` 取值相同的layer,然后将这些layer的参数 :code:`name` 设置为不同的值。
24. PaddlePaddle 中不同的 recurrent layer 的区别
--------------------------------------------------
以LSTM为例,在PaddlePaddle中包含以下 recurrent layer:
* :code:`paddle.layer.lstmemory`
* :code:`paddle.networks.simple_lstm`
* :code:`paddle.networks.lstmemory_group`
* :code:`paddle.networks.bidirectional_lstm`
按照具体实现方式可以归纳为2类:
1. 由 recurrent_group 实现的 recurrent layer:
* 用户在使用这一类recurrent layer时,可以访问由recurrent unit在一个时间步内计算得到的中间值(例如:hidden states, memory cells等);
* 上述的 :code:`paddle.networks.lstmemory_group` 是这一类的 recurrent layer ;
2. 将recurrent layer作为一个整体来实现:
* 用户在使用这一类recurrent layer,只能访问它们的输出值;
* 上述的 :code:`paddle.networks.lstmemory_group` 、 :code:`paddle.networks.simple_lstm` 和 :code:`paddle.networks.bidirectional_lstm` 属于这一类的实现;
将recurrent layer作为一个整体来实现, 能够针对CPU和GPU的计算做更多优化, 所以相比于recurrent group的实现方式, 第二类 recurrent layer 计算效率更高。 在实际应用中,如果用户不需要访问LSTM的中间变量,而只需要获得recurrent layer计算的输出,我们建议使用第二类实现。
此外,关于LSTM, PaddlePaddle中还包含 :code:`paddle.networks.lstmemory_unit` 这一计算单元:
* 不同于上述介绍的recurrent layer , :code:`paddle.networks.lstmemory_unit` 定义了LSTM单元在一个时间步内的计算过程,它并不是一个完整的recurrent layer,也不能接收序列数据作为输入;
* :code:`paddle.networks.lstmemory_unit` 只能在recurrent_group中作为step function使用;
......@@ -186,50 +186,51 @@
<div itemprop="articleBody">
<div class="section" id="faq">
<h1><a class="toc-backref" href="#id13">FAQ</a><a class="headerlink" href="#faq" title="永久链接至标题"></a></h1>
<h1><a class="toc-backref" href="#id12">FAQ</a><a class="headerlink" href="#faq" title="永久链接至标题"></a></h1>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#faq" id="id13">FAQ</a><ul>
<li><a class="reference internal" href="#id1" id="id14">1. 如何减少内存占用</a><ul>
<li><a class="reference internal" href="#dataprovider" id="id15">减少DataProvider缓冲池内存</a></li>
<li><a class="reference internal" href="#id2" id="id16">神经元激活内存</a></li>
<li><a class="reference internal" href="#id3" id="id17">参数内存</a></li>
<li><a class="reference internal" href="#faq" id="id12">FAQ</a><ul>
<li><a class="reference internal" href="#id1" id="id13">1. 如何减少内存占用</a><ul>
<li><a class="reference internal" href="#dataprovider" id="id14">减少DataProvider缓冲池内存</a></li>
<li><a class="reference internal" href="#id2" id="id15">神经元激活内存</a></li>
<li><a class="reference internal" href="#id3" id="id16">参数内存</a></li>
</ul>
</li>
<li><a class="reference internal" href="#paddlepaddle" id="id18">2. 如何加速PaddlePaddle的训练速度</a><ul>
<li><a class="reference internal" href="#id4" id="id19">减少数据载入的耗时</a></li>
<li><a class="reference internal" href="#id5" id="id20">加速训练速度</a></li>
<li><a class="reference internal" href="#id6" id="id21">利用更多的计算资源</a></li>
<li><a class="reference internal" href="#paddlepaddle" id="id17">2. 如何加速PaddlePaddle的训练速度</a><ul>
<li><a class="reference internal" href="#id4" id="id18">减少数据载入的耗时</a></li>
<li><a class="reference internal" href="#id5" id="id19">加速训练速度</a></li>
<li><a class="reference internal" href="#id6" id="id20">利用更多的计算资源</a></li>
</ul>
</li>
<li><a class="reference internal" href="#illegal-instruction" id="id22">3. 遇到“非法指令”或者是“illegal instruction”</a></li>
<li><a class="reference internal" href="#sgd" id="id23">4. 如何选择SGD算法的学习率</a></li>
<li><a class="reference internal" href="#id7" id="id24">5. 如何初始化参数</a></li>
<li><a class="reference internal" href="#id8" id="id25">6. 如何共享参数</a></li>
<li><a class="reference internal" href="#paddlepaddle-whl-is-not-a-supported-wheel-on-this-platform" id="id26">7. paddlepaddle*.whl is not a supported wheel on this platform.</a></li>
<li><a class="reference internal" href="#python" id="id27">8. python相关的单元测试都过不了</a></li>
<li><a class="reference internal" href="#docker-gpu-cuda-driver-version-is-insufficient" id="id28">9. 运行Docker GPU镜像出现 &#8220;CUDA driver version is insufficient&#8221;</a></li>
<li><a class="reference internal" href="#cmake-pythonlibspythoninterp" id="id29">10. CMake源码编译, 找到的PythonLibs和PythonInterp版本不一致</a></li>
<li><a class="reference internal" href="#cmake-paddle0-0-0" id="id30">11. CMake源码编译,Paddle版本号为0.0.0</a></li>
<li><a class="reference internal" href="#a-protocol-message-was-rejected-because-it-was-too-big" id="id31">12. A protocol message was rejected because it was too big</a></li>
<li><a class="reference internal" href="#gpu" id="id32">13. 如何指定GPU设备</a></li>
<li><a class="reference internal" href="#floating-point-exception" id="id33">14. 训练过程中出现 <code class="code docutils literal"><span class="pre">Floating</span> <span class="pre">point</span> <span class="pre">exception</span></code>, 训练因此退出怎么办?</a></li>
<li><a class="reference internal" href="#import-paddle-v2-as-paddle-importerror-no-module-named-v2" id="id34">15. 编译安装后执行 import paddle.v2 as paddle 报ImportError: No module named v2</a></li>
<li><a class="reference internal" href="#id9" id="id35">16. PaddlePaddle存储的参数格式是什么,如何和明文进行相互转化</a></li>
<li><a class="reference internal" href="#id10" id="id36">17. 如何加载预训练参数</a></li>
<li><a class="reference internal" href="#id11" id="id37">18. 集群多节点训练,日志中保存均为网络通信类错误</a></li>
<li><a class="reference internal" href="#id12" id="id38">19. PaddlePaddle如何输出多个层</a></li>
<li><a class="reference internal" href="#paddle-layer-memory-name" id="id39">20. <code class="code docutils literal"><span class="pre">paddle.layer.memory</span></code> 的参数 <code class="code docutils literal"><span class="pre">name</span></code> 如何使用</a></li>
<li><a class="reference internal" href="#dropout" id="id40">21. dropout 使用</a></li>
<li><a class="reference internal" href="#learning-rate-annealing" id="id41">22. 如何设置学习率退火(learning rate annealing)</a></li>
<li><a class="reference internal" href="#duplicated-layer-name" id="id42">23. 出现 <code class="code docutils literal"><span class="pre">Duplicated</span> <span class="pre">layer</span> <span class="pre">name</span></code> 错误怎么办</a></li>
<li><a class="reference internal" href="#illegal-instruction" id="id21">3. 遇到“非法指令”或者是“illegal instruction”</a></li>
<li><a class="reference internal" href="#sgd" id="id22">4. 如何选择SGD算法的学习率</a></li>
<li><a class="reference internal" href="#id7" id="id23">5. 如何初始化参数</a></li>
<li><a class="reference internal" href="#id8" id="id24">6. 如何共享参数</a></li>
<li><a class="reference internal" href="#paddlepaddle-whl-is-not-a-supported-wheel-on-this-platform" id="id25">7. paddlepaddle*.whl is not a supported wheel on this platform.</a></li>
<li><a class="reference internal" href="#python" id="id26">8. python相关的单元测试都过不了</a></li>
<li><a class="reference internal" href="#docker-gpu-cuda-driver-version-is-insufficient" id="id27">9. 运行Docker GPU镜像出现 &#8220;CUDA driver version is insufficient&#8221;</a></li>
<li><a class="reference internal" href="#cmake-pythonlibspythoninterp" id="id28">10. CMake源码编译, 找到的PythonLibs和PythonInterp版本不一致</a></li>
<li><a class="reference internal" href="#cmake-paddle0-0-0" id="id29">11. CMake源码编译,Paddle版本号为0.0.0</a></li>
<li><a class="reference internal" href="#a-protocol-message-was-rejected-because-it-was-too-big" id="id30">12. A protocol message was rejected because it was too big</a></li>
<li><a class="reference internal" href="#gpu" id="id31">13. 如何指定GPU设备</a></li>
<li><a class="reference internal" href="#floating-point-exception" id="id32">14. 训练过程中出现 <code class="code docutils literal"><span class="pre">Floating</span> <span class="pre">point</span> <span class="pre">exception</span></code>, 训练因此退出怎么办?</a></li>
<li><a class="reference internal" href="#import-paddle-v2-as-paddle-importerror-no-module-named-v2" id="id33">15. 编译安装后执行 import paddle.v2 as paddle 报ImportError: No module named v2</a></li>
<li><a class="reference internal" href="#id9" id="id34">16. PaddlePaddle存储的参数格式是什么,如何和明文进行相互转化</a></li>
<li><a class="reference internal" href="#id10" id="id35">17. 如何加载预训练参数</a></li>
<li><a class="reference internal" href="#id11" id="id36">18. 集群多节点训练,日志中保存均为网络通信类错误</a></li>
<li><a class="reference internal" href="#infer-layer" id="id37">19. 如何调用 infer 接口输出多个layer的预测结果</a></li>
<li><a class="reference internal" href="#paddle-layer-memory-name" id="id38">20. <code class="code docutils literal"><span class="pre">paddle.layer.memory</span></code> 的参数 <code class="code docutils literal"><span class="pre">name</span></code> 如何使用</a></li>
<li><a class="reference internal" href="#drop-out" id="id39">21. 两种使用 drop_out 的方法有何区别?</a></li>
<li><a class="reference internal" href="#learning-rate-annealing" id="id40">22. 如何设置学习率退火(learning rate annealing)</a></li>
<li><a class="reference internal" href="#duplicated-layer-name" id="id41">23. 出现 <code class="code docutils literal"><span class="pre">Duplicated</span> <span class="pre">layer</span> <span class="pre">name</span></code> 错误怎么办</a></li>
<li><a class="reference internal" href="#paddlepaddle-recurrent-layer" id="id42">24. PaddlePaddle 中不同的 recurrent layer 的区别</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="id1">
<h2><a class="toc-backref" href="#id14">1. 如何减少内存占用</a><a class="headerlink" href="#id1" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id13">1. 如何减少内存占用</a><a class="headerlink" href="#id1" title="永久链接至标题"></a></h2>
<p>神经网络的训练本身是一个非常消耗内存和显存的工作,经常会消耗数10GB的内存和数GB的显存。
PaddlePaddle的内存占用主要分为如下几个方面:</p>
<ul class="simple">
......@@ -240,7 +241,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
</ul>
<p>其中,其他内存杂项是指PaddlePaddle本身所用的一些内存,包括字符串分配,临时变量等等,暂不考虑在内。</p>
<div class="section" id="dataprovider">
<h3><a class="toc-backref" href="#id15">减少DataProvider缓冲池内存</a><a class="headerlink" href="#dataprovider" title="永久链接至标题"></a></h3>
<h3><a class="toc-backref" href="#id14">减少DataProvider缓冲池内存</a><a class="headerlink" href="#dataprovider" title="永久链接至标题"></a></h3>
<p>PyDataProvider使用的是异步加载,同时在内存里直接随即选取数据来做Shuffle。即</p>
<img src="../_images/graphviz-9be6aad37f57c60f4b971dde0ef44ce27179cf9a.png" alt="digraph {
rankdir=LR;
......@@ -260,7 +261,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
<p>这样做可以极大的减少内存占用,并且可能会加速训练过程,详细文档参考 <a class="reference internal" href="../api/v1/data_provider/pydataprovider2_cn.html#api-pydataprovider2"><span class="std std-ref">PyDataProvider2的使用</span></a></p>
</div>
<div class="section" id="id2">
<h3><a class="toc-backref" href="#id16">神经元激活内存</a><a class="headerlink" href="#id2" title="永久链接至标题"></a></h3>
<h3><a class="toc-backref" href="#id15">神经元激活内存</a><a class="headerlink" href="#id2" title="永久链接至标题"></a></h3>
<p>神经网络在训练的时候,会对每一个激活暂存一些数据,如神经元激活值等。
在反向传递的时候,这些数据会被用来更新参数。这些数据使用的内存主要和两个参数有关系,
一是batch size,另一个是每条序列(Sequence)长度。所以,其实也是和每个mini-batch中包含
......@@ -273,7 +274,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
</ul>
</div>
<div class="section" id="id3">
<h3><a class="toc-backref" href="#id17">参数内存</a><a class="headerlink" href="#id3" title="永久链接至标题"></a></h3>
<h3><a class="toc-backref" href="#id16">参数内存</a><a class="headerlink" href="#id3" title="永久链接至标题"></a></h3>
<p>PaddlePaddle支持非常多的优化算法(Optimizer),不同的优化算法需要使用不同大小的内存。
例如使用 <code class="code docutils literal"><span class="pre">adadelta</span></code> 算法,则需要使用等于权重参数规模大约5倍的内存。举例,如果参数保存下来的模型目录
文件为 <code class="code docutils literal"><span class="pre">100M</span></code>, 那么该优化算法至少需要 <code class="code docutils literal"><span class="pre">500M</span></code> 的内存。</p>
......@@ -281,7 +282,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
</div>
</div>
<div class="section" id="paddlepaddle">
<h2><a class="toc-backref" href="#id18">2. 如何加速PaddlePaddle的训练速度</a><a class="headerlink" href="#paddlepaddle" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id17">2. 如何加速PaddlePaddle的训练速度</a><a class="headerlink" href="#paddlepaddle" title="永久链接至标题"></a></h2>
<p>加速PaddlePaddle训练可以考虑从以下几个方面:</p>
<ul class="simple">
<li>减少数据载入的耗时</li>
......@@ -289,7 +290,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
<li>利用分布式训练驾驭更多的计算资源</li>
</ul>
<div class="section" id="id4">
<h3><a class="toc-backref" href="#id19">减少数据载入的耗时</a><a class="headerlink" href="#id4" title="永久链接至标题"></a></h3>
<h3><a class="toc-backref" href="#id18">减少数据载入的耗时</a><a class="headerlink" href="#id4" title="永久链接至标题"></a></h3>
<p>使用<code class="code docutils literal"><span class="pre">pydataprovider</span></code>时,可以减少缓存池的大小,同时设置内存缓存功能,即可以极大的加速数据载入流程。
<code class="code docutils literal"><span class="pre">DataProvider</span></code> 缓存池的减小,和之前减小通过减小缓存池来减小内存占用的原理一致。</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="nd">@provider</span><span class="p">(</span><span class="n">min_pool_size</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
......@@ -303,7 +304,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
<p>同时 <code class="code docutils literal"><span class="pre">&#64;provider</span></code> 接口有一个 <code class="code docutils literal"><span class="pre">cache</span></code> 参数来控制缓存方法,将其设置成 <code class="code docutils literal"><span class="pre">CacheType.CACHE_PASS_IN_MEM</span></code> 的话,会将第一个 <code class="code docutils literal"><span class="pre">pass</span></code> (过完所有训练数据即为一个pass)生成的数据缓存在内存里,在之后的 <code class="code docutils literal"><span class="pre">pass</span></code> 中,不会再从 <code class="code docutils literal"><span class="pre">python</span></code> 端读取数据,而是直接从内存的缓存里读取数据。这也会极大减少数据读入的耗时。</p>
</div>
<div class="section" id="id5">
<h3><a class="toc-backref" href="#id20">加速训练速度</a><a class="headerlink" href="#id5" title="永久链接至标题"></a></h3>
<h3><a class="toc-backref" href="#id19">加速训练速度</a><a class="headerlink" href="#id5" title="永久链接至标题"></a></h3>
<p>PaddlePaddle支持Sparse的训练,sparse训练需要训练特征是 <code class="code docutils literal"><span class="pre">sparse_binary_vector</span></code><code class="code docutils literal"><span class="pre">sparse_vector</span></code> 、或者 <code class="code docutils literal"><span class="pre">integer_value</span></code> 的任一一种。同时,与这个训练数据交互的Layer,需要将其Parameter设置成 sparse 更新模式,即设置 <code class="code docutils literal"><span class="pre">sparse_update=True</span></code></p>
<p>这里使用简单的 <code class="code docutils literal"><span class="pre">word2vec</span></code> 训练语言模型距离,具体使用方法为:</p>
<p>使用一个词前两个词和后两个词,来预测这个中间的词。这个任务的DataProvider为:</p>
......@@ -336,7 +337,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
</div>
</div>
<div class="section" id="id6">
<h3><a class="toc-backref" href="#id21">利用更多的计算资源</a><a class="headerlink" href="#id6" title="永久链接至标题"></a></h3>
<h3><a class="toc-backref" href="#id20">利用更多的计算资源</a><a class="headerlink" href="#id6" title="永久链接至标题"></a></h3>
<p>利用更多的计算资源可以分为一下几个方式来进行:</p>
<ul class="simple">
<li>单机CPU训练<ul>
......@@ -356,17 +357,17 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
</div>
</div>
<div class="section" id="illegal-instruction">
<h2><a class="toc-backref" href="#id22">3. 遇到“非法指令”或者是“illegal instruction”</a><a class="headerlink" href="#illegal-instruction" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id21">3. 遇到“非法指令”或者是“illegal instruction”</a><a class="headerlink" href="#illegal-instruction" title="永久链接至标题"></a></h2>
<p>PaddlePaddle使用avx SIMD指令提高cpu执行效率,因此错误的使用二进制发行版可能会导致这种错误,请选择正确的版本。</p>
</div>
<div class="section" id="sgd">
<h2><a class="toc-backref" href="#id23">4. 如何选择SGD算法的学习率</a><a class="headerlink" href="#sgd" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id22">4. 如何选择SGD算法的学习率</a><a class="headerlink" href="#sgd" title="永久链接至标题"></a></h2>
<p>在采用sgd/async_sgd进行训练时,一个重要的问题是选择正确的learning_rate。如果learning_rate太大,那么训练有可能不收敛,如果learning_rate太小,那么收敛可能很慢,导致训练时间过长。</p>
<p>通常做法是从一个比较大的learning_rate开始试,如果不收敛,那减少学习率10倍继续试验,直到训练收敛为止。那么如何判断训练不收敛呢?可以估计出如果模型采用不变的输出最小的cost0是多少。</p>
<p>如果训练过程的的cost明显高于这个常数输出的cost,那么我们可以判断为训练不收敛。举一个例子,假如我们是三分类问题,采用multi-class-cross-entropy作为cost,数据中0,1,2三类的比例为 <code class="code docutils literal"><span class="pre">0.2,</span> <span class="pre">0.5,</span> <span class="pre">0.3</span></code> , 那么常数输出所能达到的最小cost是 <code class="code docutils literal"><span class="pre">-(0.2*log(0.2)+0.5*log(0.5)+0.3*log(0.3))=1.03</span></code> 。如果训练一个pass(或者更早)后,cost还大于这个数,那么可以认为训练不收敛,应该降低学习率。</p>
</div>
<div class="section" id="id7">
<h2><a class="toc-backref" href="#id24">5. 如何初始化参数</a><a class="headerlink" href="#id7" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id23">5. 如何初始化参数</a><a class="headerlink" href="#id7" title="永久链接至标题"></a></h2>
<p>默认情况下,PaddlePaddle使用均值0,标准差为 <span class="math">\(\frac{1}{\sqrt{d}}\)</span> 来初始化参数。其中 <span class="math">\(d\)</span> 为参数矩阵的宽度。这种初始化方式在一般情况下不会产生很差的结果。如果用户想要自定义初始化方式,PaddlePaddle目前提供两种参数初始化的方式:</p>
<ul class="simple">
<li>高斯分布。将 <code class="code docutils literal"><span class="pre">param_attr</span></code> 设置成 <code class="code docutils literal"><span class="pre">param_attr=ParamAttr(initial_mean=0.0,</span> <span class="pre">initial_std=1.0)</span></code></li>
......@@ -380,7 +381,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
<p>上述代码将bias全部初始化为1.0, 同时将参数初始化为 <code class="code docutils literal"><span class="pre">[1.0,</span> <span class="pre">-1.0]</span></code> 的均匀分布。</p>
</div>
<div class="section" id="id8">
<h2><a class="toc-backref" href="#id25">6. 如何共享参数</a><a class="headerlink" href="#id8" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id24">6. 如何共享参数</a><a class="headerlink" href="#id8" title="永久链接至标题"></a></h2>
<p>PaddlePaddle的参数使用名字 <code class="code docutils literal"><span class="pre">name</span></code> 作为参数的ID,相同名字的参数,会共享参数。设置参数的名字,可以使用 <code class="code docutils literal"><span class="pre">ParamAttr(name=&quot;YOUR_PARAM_NAME&quot;)</span></code> 来设置。更方便的设置方式,是使得要共享的参数使用同样的 <code class="code docutils literal"><span class="pre">ParamAttr</span></code> 对象。</p>
<p>简单的全连接网络,参数共享的配置示例为:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">paddle.trainer_config_helpers</span> <span class="k">import</span> <span class="o">*</span>
......@@ -417,7 +418,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
<p>这里 <code class="code docutils literal"><span class="pre">hidden_a</span></code><code class="code docutils literal"><span class="pre">hidden_b</span></code> 使用了同样的parameter和bias。并且softmax层的两个输入也使用了同样的参数 <code class="code docutils literal"><span class="pre">softmax_param</span></code></p>
</div>
<div class="section" id="paddlepaddle-whl-is-not-a-supported-wheel-on-this-platform">
<h2><a class="toc-backref" href="#id26">7. paddlepaddle*.whl is not a supported wheel on this platform.</a><a class="headerlink" href="#paddlepaddle-whl-is-not-a-supported-wheel-on-this-platform" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id25">7. paddlepaddle*.whl is not a supported wheel on this platform.</a><a class="headerlink" href="#paddlepaddle-whl-is-not-a-supported-wheel-on-this-platform" title="永久链接至标题"></a></h2>
<p>出现这个问题的主要原因是,没有找到和当前系统匹配的paddlepaddle安装包。最新的paddlepaddle python安装包支持Linux x86_64和MacOS 10.12操作系统,并安装了python 2.7和pip 9.0.1。</p>
<p>更新 <code class="code docutils literal"><span class="pre">pip</span></code> 包的方法是:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>pip install --upgrade pip
......@@ -429,7 +430,7 @@ PaddlePaddle的内存占用主要分为如下几个方面:</p>
如果系统支持 <code class="code docutils literal"><span class="pre">manylinux1_x86_64</span></code> 而安装包(本地)是 <code class="code docutils literal"><span class="pre">linux_x86_64</span></code> ,可以重命名这个whl包为 <code class="code docutils literal"><span class="pre">manylinux1_x86_64</span></code> 再安装。</p>
</div>
<div class="section" id="python">
<h2><a class="toc-backref" href="#id27">8. python相关的单元测试都过不了</a><a class="headerlink" href="#python" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id26">8. python相关的单元测试都过不了</a><a class="headerlink" href="#python" title="永久链接至标题"></a></h2>
<p>如果出现以下python相关的单元测试都过不了的情况:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span><span class="m">24</span> - test_PyDataProvider <span class="o">(</span>Failed<span class="o">)</span>
<span class="m">26</span> - test_RecurrentGradientMachine <span class="o">(</span>Failed<span class="o">)</span>
......@@ -460,7 +461,7 @@ Please uninstall paddle package before start unittest. Try to <span class="s1">&
</ul>
</div>
<div class="section" id="docker-gpu-cuda-driver-version-is-insufficient">
<h2><a class="toc-backref" href="#id28">9. 运行Docker GPU镜像出现 &#8220;CUDA driver version is insufficient&#8221;</a><a class="headerlink" href="#docker-gpu-cuda-driver-version-is-insufficient" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id27">9. 运行Docker GPU镜像出现 &#8220;CUDA driver version is insufficient&#8221;</a><a class="headerlink" href="#docker-gpu-cuda-driver-version-is-insufficient" title="永久链接至标题"></a></h2>
<p>用户在使用PaddlePaddle GPU的Docker镜像的时候,常常出现 <cite>Cuda Error: CUDA driver version is insufficient for CUDA runtime version</cite>, 原因在于没有把机器上CUDA相关的驱动和库映射到容器内部。
具体的解决方法是:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ <span class="nb">export</span> <span class="nv">CUDA_SO</span><span class="o">=</span><span class="s2">&quot;</span><span class="k">$(</span><span class="se">\l</span>s usr/lib64/libcuda* <span class="p">|</span> xargs -I<span class="o">{}</span> <span class="nb">echo</span> <span class="s1">&#39;-v {}:{}&#39;</span><span class="k">)</span><span class="s2"> </span><span class="k">$(</span><span class="se">\l</span>s /usr/lib64/libnvidia* <span class="p">|</span> xargs -I<span class="o">{}</span> <span class="nb">echo</span> <span class="s1">&#39;-v {}:{}&#39;</span><span class="k">)</span><span class="s2">&quot;</span>
......@@ -471,7 +472,7 @@ $ docker run <span class="si">${</span><span class="nv">CUDA_SO</span><span clas
<p>更多关于Docker的安装与使用, 请参考 <a class="reference external" href="http://www.paddlepaddle.org/doc_cn/build_and_install/install/docker_install.html">PaddlePaddle Docker 文档</a></p>
</div>
<div class="section" id="cmake-pythonlibspythoninterp">
<h2><a class="toc-backref" href="#id29">10. CMake源码编译, 找到的PythonLibs和PythonInterp版本不一致</a><a class="headerlink" href="#cmake-pythonlibspythoninterp" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id28">10. CMake源码编译, 找到的PythonLibs和PythonInterp版本不一致</a><a class="headerlink" href="#cmake-pythonlibspythoninterp" title="永久链接至标题"></a></h2>
<p>这是目前CMake寻找Python的逻辑存在缺陷,如果系统安装了多个Python版本,CMake找到的Python库和Python解释器版本可能有不一致现象,导致编译PaddlePaddle失败。正确的解决方法是,
用户强制指定特定的Python版本,具体操作如下:</p>
<blockquote>
......@@ -482,7 +483,7 @@ $ docker run <span class="si">${</span><span class="nv">CUDA_SO</span><span clas
<p>用户需要指定本机上Python的路径:<code class="docutils literal"><span class="pre">&lt;exc_path&gt;</span></code>, <code class="docutils literal"><span class="pre">&lt;lib_path&gt;</span></code>, <code class="docutils literal"><span class="pre">&lt;inc_path&gt;</span></code></p>
</div>
<div class="section" id="cmake-paddle0-0-0">
<h2><a class="toc-backref" href="#id30">11. CMake源码编译,Paddle版本号为0.0.0</a><a class="headerlink" href="#cmake-paddle0-0-0" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id29">11. CMake源码编译,Paddle版本号为0.0.0</a><a class="headerlink" href="#cmake-paddle0-0-0" title="永久链接至标题"></a></h2>
<p>如果运行 <code class="code docutils literal"><span class="pre">paddle</span> <span class="pre">version</span></code>, 出现 <code class="code docutils literal"><span class="pre">PaddlePaddle</span> <span class="pre">0.0.0</span></code>;或者运行 <code class="code docutils literal"><span class="pre">cmake</span> <span class="pre">..</span></code>,出现</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>CMake Warning at cmake/version.cmake:20 <span class="o">(</span>message<span class="o">)</span>:
Cannot add paddle version from git tag
......@@ -491,7 +492,7 @@ $ docker run <span class="si">${</span><span class="nv">CUDA_SO</span><span clas
<p>那么用户需要拉取所有的远程分支到本机,命令为 <code class="code docutils literal"><span class="pre">git</span> <span class="pre">fetch</span> <span class="pre">upstream</span></code>,然后重新cmake即可。</p>
</div>
<div class="section" id="a-protocol-message-was-rejected-because-it-was-too-big">
<h2><a class="toc-backref" href="#id31">12. A protocol message was rejected because it was too big</a><a class="headerlink" href="#a-protocol-message-was-rejected-because-it-was-too-big" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id30">12. A protocol message was rejected because it was too big</a><a class="headerlink" href="#a-protocol-message-was-rejected-because-it-was-too-big" title="永久链接至标题"></a></h2>
<p>如果在训练NLP相关模型时,出现以下错误:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span><span class="o">[</span>libprotobuf ERROR google/protobuf/io/coded_stream.cc:171<span class="o">]</span> A protocol message was rejected because it was too big <span class="o">(</span>more than <span class="m">67108864</span> bytes<span class="o">)</span>. To increase the limit <span class="o">(</span>or to disable these warnings<span class="o">)</span>, see CodedInputStream::SetTotalBytesLimit<span class="o">()</span> in google/protobuf/io/coded_stream.h.
F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> TrainerConfigHelper.cpp:59<span class="o">]</span> Check failed: m-&gt;conf.ParseFromString<span class="o">(</span>configProtoStr<span class="o">)</span>
......@@ -522,7 +523,7 @@ F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> Traine
<p>完整源码可参考 <a class="reference external" href="https://github.com/PaddlePaddle/Paddle/tree/develop/demo/seqToseq">seqToseq</a> 示例。</p>
</div>
<div class="section" id="gpu">
<h2><a class="toc-backref" href="#id32">13. 如何指定GPU设备</a><a class="headerlink" href="#gpu" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id31">13. 如何指定GPU设备</a><a class="headerlink" href="#gpu" title="永久链接至标题"></a></h2>
<p>例如机器上有4块GPU,编号从0开始,指定使用2、3号GPU:</p>
<ul class="simple">
<li>方式1:通过 <a class="reference external" href="http://www.acceleware.com/blog/cudavisibledevices-masking-gpus">CUDA_VISIBLE_DEVICES</a> 环境变量来指定特定的GPU。</li>
......@@ -538,7 +539,7 @@ F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> Traine
</div>
</div>
<div class="section" id="floating-point-exception">
<h2><a class="toc-backref" href="#id33">14. 训练过程中出现 <code class="code docutils literal"><span class="pre">Floating</span> <span class="pre">point</span> <span class="pre">exception</span></code>, 训练因此退出怎么办?</a><a class="headerlink" href="#floating-point-exception" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id32">14. 训练过程中出现 <code class="code docutils literal"><span class="pre">Floating</span> <span class="pre">point</span> <span class="pre">exception</span></code>, 训练因此退出怎么办?</a><a class="headerlink" href="#floating-point-exception" title="永久链接至标题"></a></h2>
<p>Paddle二进制在运行时捕获了浮点数异常,只要出现浮点数异常(即训练过程中出现NaN或者Inf),立刻退出。浮点异常通常的原因是浮点数溢出、除零等问题。
主要原因包括两个方面:</p>
<ul class="simple">
......@@ -546,17 +547,54 @@ F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> Traine
<li>模型一直不收敛,发散到了一个数值特别大的地方。</li>
<li>训练数据有问题,导致参数收敛到了一些奇异的情况。或者输入数据尺度过大,有些特征的取值达到数百万,这时进行矩阵乘法运算就可能导致浮点数溢出。</li>
</ul>
<p>主要的解决办法是减小学习率或者对数据进行归一化处理。</p>
<p>这里有两种有效的解决方法:</p>
<ol class="arabic simple">
<li>设置 <code class="code docutils literal"><span class="pre">gradient_clipping_threshold</span></code> 参数,示例代码如下:</li>
</ol>
<div class="highlight-python"><div class="highlight"><pre><span></span>
</pre></div>
</div>
<dl class="docutils">
<dt>optimizer = paddle.optimizer.RMSProp(</dt>
<dd>learning_rate=1e-3,
gradient_clipping_threshold=10.0,
regularization=paddle.optimizer.L2Regularization(rate=8e-4))</dd>
</dl>
<p>具体可以参考 <a class="reference external" href="https://github.com/PaddlePaddle/models/blob/develop/nmt_without_attention/train.py#L35">nmt_without_attention</a> 示例。</p>
<ol class="arabic simple" start="2">
<li>设置 <code class="code docutils literal"><span class="pre">error_clipping_threshold</span></code> 参数,示例代码如下:</li>
</ol>
<div class="highlight-python"><div class="highlight"><pre><span></span>
</pre></div>
</div>
<dl class="docutils">
<dt>decoder_inputs = paddle.layer.fc(</dt>
<dd><p class="first">act=paddle.activation.Linear(),
size=decoder_size * 3,
bias_attr=False,
input=[context, current_word],
layer_attr=paddle.attr.ExtraLayerAttribute(</p>
<blockquote class="last">
<div>error_clipping_threshold=100.0))</div></blockquote>
</dd>
</dl>
<p>完整代码可以参考示例 <a class="reference external" href="https://github.com/PaddlePaddle/book/blob/develop/08.machine_translation/train.py#L66">machine translation</a></p>
<p>两种方法的区别:</p>
<ol class="arabic simple">
<li>两者都是对梯度的截断,但截断时机不同,前者在 <code class="code docutils literal"><span class="pre">optimzier</span></code> 更新网络参数时应用;后者在激活函数反向计算时被调用;</li>
<li>截断对象不同:前者截断可学习参数的梯度,后者截断回传给前层的梯度;</li>
</ol>
<p>除此之外,还可以通过减小学习律或者对数据进行归一化处理来解决这类问题。</p>
</div>
<div class="section" id="import-paddle-v2-as-paddle-importerror-no-module-named-v2">
<h2><a class="toc-backref" href="#id34">15. 编译安装后执行 import paddle.v2 as paddle 报ImportError: No module named v2</a><a class="headerlink" href="#import-paddle-v2-as-paddle-importerror-no-module-named-v2" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id33">15. 编译安装后执行 import paddle.v2 as paddle 报ImportError: No module named v2</a><a class="headerlink" href="#import-paddle-v2-as-paddle-importerror-no-module-named-v2" title="永久链接至标题"></a></h2>
<p>先查看一下是否曾经安装过paddle v1版本,有的话需要先卸载:</p>
<p>pip uninstall py_paddle paddle</p>
<p>然后安装paddle的python环境, 在build目录下执行</p>
<p>pip install python/dist/paddle*.whl &amp;&amp; pip install ../paddle/dist/py_paddle*.whl</p>
</div>
<div class="section" id="id9">
<h2><a class="toc-backref" href="#id35">16. PaddlePaddle存储的参数格式是什么,如何和明文进行相互转化</a><a class="headerlink" href="#id9" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id34">16. PaddlePaddle存储的参数格式是什么,如何和明文进行相互转化</a><a class="headerlink" href="#id9" title="永久链接至标题"></a></h2>
<p>PaddlePaddle保存的模型参数文件内容由16字节头信息和网络参数两部分组成。头信息中,1~4字节表示PaddlePaddle版本信息,请直接填充0;5~8字节表示每个参数占用的字节数,当保存的网络参数为float类型时为4,double类型时为8;9~16字节表示保存的参数总个数。</p>
<p>将PaddlePaddle保存的模型参数还原回明文时,可以使用相应数据类型的 <code class="code docutils literal"><span class="pre">numpy.array</span></code> 加载具体网络参数,此时可以跳过PaddlePaddle模型参数文件的头信息。若在PaddlePaddle编译时,未指定按照double精度编译,默认情况下按照float精度计算,保存的参数也是float类型。这时在使用 <code class="code docutils literal"><span class="pre">numpy.array</span></code> 时,一般设置 <code class="code docutils literal"><span class="pre">dtype=float32</span></code> 。示例如下:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">read_parameter</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">width</span><span class="p">):</span>
......@@ -579,7 +617,7 @@ F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> Traine
</div>
</div>
<div class="section" id="id10">
<h2><a class="toc-backref" href="#id36">17. 如何加载预训练参数</a><a class="headerlink" href="#id10" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id35">17. 如何加载预训练参数</a><a class="headerlink" href="#id10" title="永久链接至标题"></a></h2>
<ul class="simple">
<li>对加载预训练参数的层,设置其参数属性 <code class="code docutils literal"><span class="pre">is_static=True</span></code>,使该层的参数在训练过程中保持不变。以embedding层为例,代码如下:</li>
</ul>
......@@ -601,7 +639,7 @@ F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> Traine
</div>
</div>
<div class="section" id="id11">
<h2><a class="toc-backref" href="#id37">18. 集群多节点训练,日志中保存均为网络通信类错误</a><a class="headerlink" href="#id11" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id36">18. 集群多节点训练,日志中保存均为网络通信类错误</a><a class="headerlink" href="#id11" title="永久链接至标题"></a></h2>
<p>集群多节点训练,日志报错为网络通信类错误,比如 <code class="code docutils literal"><span class="pre">Connection</span> <span class="pre">reset</span> <span class="pre">by</span> <span class="pre">peer</span></code> 等。
此类报错通常是由于某一个节点的错误导致这个节点的训练进程退出,从而引发其他节点无法连接导致,可以参考下面的步骤排查:</p>
<ul class="simple">
......@@ -610,8 +648,8 @@ F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> Traine
<li>如果当前MPI集群并不支持任务独占模式,可以联系OP是否可以更换集群或升级当前集群。</li>
</ul>
</div>
<div class="section" id="id12">
<h2><a class="toc-backref" href="#id38">19. PaddlePaddle如何输出多个层</a><a class="headerlink" href="#id12" title="永久链接至标题"></a></h2>
<div class="section" id="infer-layer">
<h2><a class="toc-backref" href="#id37">19. 如何调用 infer 接口输出多个layer的预测结果</a><a class="headerlink" href="#infer-layer" title="永久链接至标题"></a></h2>
<ul class="simple">
<li>将需要输出的层作为 <code class="code docutils literal"><span class="pre">paddle.inference.Inference()</span></code> 接口的 <code class="code docutils literal"><span class="pre">output_layer</span></code> 参数输入,代码如下:</li>
</ul>
......@@ -621,20 +659,39 @@ F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> Traine
<ul class="simple">
<li>指定要输出的字段进行输出。以输出 <code class="code docutils literal"><span class="pre">value</span></code> 字段为例,代码如下:</li>
</ul>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">out</span> <span class="o">=</span> <span class="n">inferer</span><span class="o">.</span><span class="n">infer</span><span class="p">(</span><span class="nb">input</span><span class="o">=</span><span class="n">data_batch</span><span class="p">,</span> <span class="n">flatten_result</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">field</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;value&quot;</span><span class="p">])</span>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">out</span> <span class="o">=</span> <span class="n">inferer</span><span class="o">.</span><span class="n">infer</span><span class="p">(</span><span class="nb">input</span><span class="o">=</span><span class="n">data_batch</span><span class="p">,</span> <span class="n">field</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;value&quot;</span><span class="p">])</span>
</pre></div>
</div>
<p>需要注意的是:</p>
<ul class="simple">
<li>如果指定了2个layer作为输出层,实际上需要的输出结果是两个矩阵;</li>
<li>假设第一个layer的输出A是一个 N1 * M1 的矩阵,第二个 Layer 的输出B是一个 N2 * M2 的矩阵;</li>
<li>paddle.v2 默认会将A和B 横向拼接,当N1 和 N2 大小不一样时,会报如下的错误:</li>
</ul>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="ne">ValueError</span><span class="p">:</span> <span class="nb">all</span> <span class="n">the</span> <span class="nb">input</span> <span class="n">array</span> <span class="n">dimensions</span> <span class="k">except</span> <span class="k">for</span> <span class="n">the</span> <span class="n">concatenation</span> <span class="n">axis</span> <span class="n">must</span> <span class="n">match</span> <span class="n">exactly</span>
</pre></div>
</div>
<p>这里设置 <code class="code docutils literal"><span class="pre">flatten_result=False</span></code>,得到的输出结果是元素个数等于输出字段数的 <code class="code docutils literal"><span class="pre">list</span></code>,该 <code class="code docutils literal"><span class="pre">list</span></code> 的每个元素是由所有输出层相应字段结果组成的 <code class="code docutils literal"><span class="pre">list</span></code>,每个字段结果的类型是 <code class="code docutils literal"><span class="pre">numpy.array</span></code><code class="code docutils literal"><span class="pre">flatten_result</span></code> 的默认值为 <code class="code docutils literal"><span class="pre">True</span></code>,该情况下,PaddlePaddle会分别对每个字段将所有输出层的结果按行进行拼接,如果各输出层该字段 <code class="code docutils literal"><span class="pre">numpy.array</span></code> 结果的相应维数不匹配,程序将不能正常运行。</p>
<p>多个层的输出矩阵的高度不一致导致拼接失败,这种情况常常发生在:</p>
<ul class="simple">
<li>同时输出序列层和非序列层;</li>
<li>多个输出层处理多个不同长度的序列;</li>
</ul>
<p>此时可以在调用infer接口时通过设置 <code class="code docutils literal"><span class="pre">flatten_result=False</span></code> , 跳过“拼接”步骤,来解决上面的问题。这时,infer接口的返回值是一个python list:</p>
<ul class="simple">
<li>list 中元素的个数等于网络中输出层的个数;</li>
<li>list 中每个元素是一个layer的输出结果矩阵,类型是numpy的ndarray;</li>
<li>每一个layer输出矩阵的高度,在非序列输入时:等于样本数;序列输入时等于:输入序列中元素的总数;宽度等于配置中layer的size;</li>
</ul>
</div>
<div class="section" id="paddle-layer-memory-name">
<h2><a class="toc-backref" href="#id39">20. <code class="code docutils literal"><span class="pre">paddle.layer.memory</span></code> 的参数 <code class="code docutils literal"><span class="pre">name</span></code> 如何使用</a><a class="headerlink" href="#paddle-layer-memory-name" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id38">20. <code class="code docutils literal"><span class="pre">paddle.layer.memory</span></code> 的参数 <code class="code docutils literal"><span class="pre">name</span></code> 如何使用</a><a class="headerlink" href="#paddle-layer-memory-name" title="永久链接至标题"></a></h2>
<ul class="simple">
<li><code class="code docutils literal"><span class="pre">paddle.layer.memory</span></code> 用于获取特定layer上一时间步的输出,该layer是通过参数 <code class="code docutils literal"><span class="pre">name</span></code> 指定,即,<code class="code docutils literal"><span class="pre">paddle.layer.memory</span></code> 会关联参数 <code class="code docutils literal"><span class="pre">name</span></code> 取值相同的layer,并将该layer上一时间步的输出作为自身当前时间步的输出。</li>
<li>PaddlePaddle的所有layer都有唯一的name,用户通过参数 <code class="code docutils literal"><span class="pre">name</span></code> 设定,当用户没有显式设定时,PaddlePaddle会自动设定。而 <code class="code docutils literal"><span class="pre">paddle.layer.memory</span></code> 不是真正的layer,其name由参数 <code class="code docutils literal"><span class="pre">memory_name</span></code> 设定,当用户没有显式设定时,PaddlePaddle会自动设定。<code class="code docutils literal"><span class="pre">paddle.layer.memory</span></code> 的参数 <code class="code docutils literal"><span class="pre">name</span></code> 用于指定其要关联的layer,需要用户显式设定。</li>
</ul>
</div>
<div class="section" id="dropout">
<h2><a class="toc-backref" href="#id40">21. dropout 使用</a><a class="headerlink" href="#dropout" title="永久链接至标题"></a></h2>
<div class="section" id="drop-out">
<h2><a class="toc-backref" href="#id39">21. 两种使用 drop_out 的方法有何区别?</a><a class="headerlink" href="#drop-out" title="永久链接至标题"></a></h2>
<ul>
<li><p class="first">在PaddlePaddle中使用dropout有两种方式</p>
<ul class="simple">
......@@ -660,7 +717,7 @@ F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> Traine
</ul>
</div>
<div class="section" id="learning-rate-annealing">
<h2><a class="toc-backref" href="#id41">22. 如何设置学习率退火(learning rate annealing)</a><a class="headerlink" href="#learning-rate-annealing" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id40">22. 如何设置学习率退火(learning rate annealing)</a><a class="headerlink" href="#learning-rate-annealing" title="永久链接至标题"></a></h2>
<p>在相应的优化算法里设置learning_rate_schedule及相关参数,以使用Adam算法为例,代码如下:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">optimizer</span> <span class="o">=</span> <span class="n">paddle</span><span class="o">.</span><span class="n">optimizer</span><span class="o">.</span><span class="n">Adam</span><span class="p">(</span>
<span class="n">learning_rate</span><span class="o">=</span><span class="mf">1e-3</span><span class="p">,</span>
......@@ -713,9 +770,46 @@ F1205 <span class="m">14</span>:59:50.295174 <span class="m">14703</span> Traine
</ul>
</div>
<div class="section" id="duplicated-layer-name">
<h2><a class="toc-backref" href="#id42">23. 出现 <code class="code docutils literal"><span class="pre">Duplicated</span> <span class="pre">layer</span> <span class="pre">name</span></code> 错误怎么办</a><a class="headerlink" href="#duplicated-layer-name" title="永久链接至标题"></a></h2>
<h2><a class="toc-backref" href="#id41">23. 出现 <code class="code docutils literal"><span class="pre">Duplicated</span> <span class="pre">layer</span> <span class="pre">name</span></code> 错误怎么办</a><a class="headerlink" href="#duplicated-layer-name" title="永久链接至标题"></a></h2>
<p>出现该错误的原因一般是用户对不同layer的参数 <code class="code docutils literal"><span class="pre">name</span></code> 设置了相同的取值。遇到该错误时,先找出参数 <code class="code docutils literal"><span class="pre">name</span></code> 取值相同的layer,然后将这些layer的参数 <code class="code docutils literal"><span class="pre">name</span></code> 设置为不同的值。</p>
</div>
<div class="section" id="paddlepaddle-recurrent-layer">
<h2><a class="toc-backref" href="#id42">24. PaddlePaddle 中不同的 recurrent layer 的区别</a><a class="headerlink" href="#paddlepaddle-recurrent-layer" title="永久链接至标题"></a></h2>
<p>以LSTM为例,在PaddlePaddle中包含以下 recurrent layer:</p>
<ul class="simple">
<li><code class="code docutils literal"><span class="pre">paddle.layer.lstmemory</span></code></li>
<li><code class="code docutils literal"><span class="pre">paddle.networks.simple_lstm</span></code></li>
<li><code class="code docutils literal"><span class="pre">paddle.networks.lstmemory_group</span></code></li>
<li><code class="code docutils literal"><span class="pre">paddle.networks.bidirectional_lstm</span></code></li>
</ul>
<p>按照具体实现方式可以归纳为2类:</p>
<ol class="arabic simple">
<li>由 recurrent_group 实现的 recurrent layer:</li>
</ol>
<blockquote>
<div><ul class="simple">
<li>用户在使用这一类recurrent layer时,可以访问由recurrent unit在一个时间步内计算得到的中间值(例如:hidden states, memory cells等);</li>
<li>上述的 <code class="code docutils literal"><span class="pre">paddle.networks.lstmemory_group</span></code> 是这一类的 recurrent layer ;</li>
</ul>
</div></blockquote>
<ol class="arabic simple" start="2">
<li>将recurrent layer作为一个整体来实现:</li>
</ol>
<blockquote>
<div><ul class="simple">
<li>用户在使用这一类recurrent layer,只能访问它们的输出值;</li>
<li>上述的 <code class="code docutils literal"><span class="pre">paddle.networks.lstmemory_group</span></code><code class="code docutils literal"><span class="pre">paddle.networks.simple_lstm</span></code><code class="code docutils literal"><span class="pre">paddle.networks.bidirectional_lstm</span></code> 属于这一类的实现;</li>
</ul>
</div></blockquote>
<p>将recurrent layer作为一个整体来实现, 能够针对CPU和GPU的计算做更多优化, 所以相比于recurrent group的实现方式, 第二类 recurrent layer 计算效率更高。 在实际应用中,如果用户不需要访问LSTM的中间变量,而只需要获得recurrent layer计算的输出,我们建议使用第二类实现。</p>
<p>此外,关于LSTM, PaddlePaddle中还包含 <code class="code docutils literal"><span class="pre">paddle.networks.lstmemory_unit</span></code> 这一计算单元:</p>
<blockquote>
<div><ul class="simple">
<li>不同于上述介绍的recurrent layer , <code class="code docutils literal"><span class="pre">paddle.networks.lstmemory_unit</span></code> 定义了LSTM单元在一个时间步内的计算过程,它并不是一个完整的recurrent layer,也不能接收序列数据作为输入;</li>
<li><code class="code docutils literal"><span class="pre">paddle.networks.lstmemory_unit</span></code> 只能在recurrent_group中作为step function使用;</li>
</ul>
</div></blockquote>
</div>
</div>
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册