基础概念

    总得来说:

    • 一个模型是一个 Fluid Program ,一个模型可以含有多于一个 Program
    • Program 由嵌套的 Block 构成,Block 的概念可以类比到 C++ 或是 Java 中的一对大括号,或是 Python 语言中的一个缩进块;
    • Block 中包含对计算和计算对象的描述。计算的描述称之为 Operator;计算作用的对象(或者说 Operator 的输入和输出)被统一为 Tensor,在Fluid中,Tensor 用层级为0的 Lod_Tensor 表示。

    Block

    Block 是高级语言中变量作用域的概念,在编程语言中,Block是一对大括号,其中包含局部变量定义和一系列指令或操作符。编程语言中的控制流结构 if-elsefor 在深度学习中可以被等效为:

    如上文所说,Fluid 中的 Block 描述了一组以顺序、选择或是循环执行的 Operator 以及 Operator 操作的对象:Tensor。

    在 Fluid 中,所有对数据的操作都由 Operator 表示,为了便于用户使用,在 Python 端,Fluid 中的 Operator 被一步封装入 paddle.fluid.layerspaddle.fluid.nets 等模块。

    更多内容可参考阅读 Fluid设计思想

    Variable

    Fluid 中的 Variable 可以包含任何类型的值———在大多数情况下是一个 Lod_Tensor

    模型中所有的可学习参数都以 Variable 的形式保留在内存空间中,您在绝大多数情况下都不需要自己来创建网络中的可学习参数, Fluid 为几乎常见的神经网络基本计算模块都提供了封装。以最简单的全连接模型为例,调用 fluid.layers.fc 会直接为全连接层创建连接权值( W )和偏置( bias )两个可学习参数,无需显示地调用 variable 相关接口创建可学习参数。

    Fluid 中部分网络层里包含了 name 参数,如 。此 name 一般用来作为网络层输出、权重的前缀标识,具体规则如下:

    • 用于网络层输出的前缀标识。若网络层中指定了 name 参数,Fluid 将以 name值_数字.tmp_数字 作为唯一标识对网络层输出进行命名;未指定 参数时,则以 OP名_数字.tmp_数字 的方式进行命名,其中的数字会自动递增,以区分同名OP下的不同网络层。
    • 用于权重或偏置变量的前缀标识。若在网络层中通过 param_attrbias_attr 创建了权重变量或偏置变量, 如 embedding 、 ,则 Fluid 会自动生成 前缀.w_数字前缀.b_数字 的唯一标识对其进行命名,其中 前缀 为用户指定的 name 或自动生成的 OP名_数字 。若在 param_attrbias_attr 中指定了 name ,则用此 name ,不再自动生成。细节请参考示例代码。

    示例代码如下:

    上述示例中, fc_nonefc_none1 均未指定 name 参数,则以 OP名_数字.tmp_数字 分别对该OP输出进行命名:fc_0.tmp_1fc_1.tmp_1 ,其中 fc_0fc_1 中的数字自动递增以区分两个全连接层; my_fc1my_fc2 均指定了 name 参数,但取值相同,Fluid 以后缀 进行区分,即 my_fc.tmp_1my_fc.tmp_3

    对于网络层中创建的变量, emb 层和 fc_nonefc_none1 层均默认以 OP名_数字 为前缀对权重或偏置变量进行命名,如 embedding_0.w_0fc_0.w_0fc_0.b_0 ,其前缀与OP输出的前缀一致。 my_fc1 层和 my_fc2 层则优先以 ParamAttr 中指定的 fc_weight 作为共享权重的名称。而偏置变量 my_fc.b_0my_fc.b_1 则次优地以 name 作为前缀标识。

    在上述示例中,my_fc1my_fc2 两个全连接层通过构建 ParamAttr ,并指定 name 参数,实现了网络层权重变量的共享机制。

    ParamAttr

    • 用户配置的单个神经网络叫做 。值得注意的是,训练神经网 络时,用户经常需要配置和操作多个 Program 。比如参数初始化的 Program , 训练用的 Program ,测试用的 Program 等等。
    • 在Fluid中,Block内部执行顺序由控制流决定,如 IfElse , , Switch 等,更多内容可参考: