基础概念
总得来说:
- 一个模型是一个 Fluid
Program
,一个模型可以含有多于一个Program
; Program
由嵌套的Block
构成,Block
的概念可以类比到 C++ 或是 Java 中的一对大括号,或是 Python 语言中的一个缩进块;Block
中包含对计算和计算对象的描述。计算的描述称之为 Operator;计算作用的对象(或者说 Operator 的输入和输出)被统一为 Tensor,在Fluid中,Tensor 用层级为0的 Lod_Tensor 表示。
Block
Block
是高级语言中变量作用域的概念,在编程语言中,Block是一对大括号,其中包含局部变量定义和一系列指令或操作符。编程语言中的控制流结构 if-else
和 for
在深度学习中可以被等效为:
如上文所说,Fluid 中的 Block
描述了一组以顺序、选择或是循环执行的 Operator 以及 Operator 操作的对象:Tensor。
在 Fluid 中,所有对数据的操作都由 Operator
表示,为了便于用户使用,在 Python 端,Fluid 中的 Operator
被一步封装入 paddle.fluid.layers
, paddle.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_attr
和bias_attr
创建了权重变量或偏置变量, 如 embedding 、 ,则 Fluid 会自动生成前缀.w_数字
或前缀.b_数字
的唯一标识对其进行命名,其中前缀
为用户指定的name
或自动生成的OP名_数字
。若在param_attr
和bias_attr
中指定了name
,则用此name
,不再自动生成。细节请参考示例代码。
示例代码如下:
上述示例中, fc_none
和 fc_none1
均未指定 name
参数,则以 OP名_数字.tmp_数字
分别对该OP输出进行命名:fc_0.tmp_1
和 fc_1.tmp_1
,其中 fc_0
和 fc_1
中的数字自动递增以区分两个全连接层; my_fc1
和 my_fc2
均指定了 name
参数,但取值相同,Fluid 以后缀 进行区分,即 my_fc.tmp_1
和 my_fc.tmp_3
。
对于网络层中创建的变量, emb
层和 fc_none
、 fc_none1
层均默认以 OP名_数字
为前缀对权重或偏置变量进行命名,如 embedding_0.w_0
、 fc_0.w_0
、 fc_0.b_0
,其前缀与OP输出的前缀一致。 my_fc1
层和 my_fc2
层则优先以 ParamAttr
中指定的 fc_weight
作为共享权重的名称。而偏置变量 my_fc.b_0
和 my_fc.b_1
则次优地以 name
作为前缀标识。
在上述示例中,my_fc1
和 my_fc2
两个全连接层通过构建 ParamAttr
,并指定 name
参数,实现了网络层权重变量的共享机制。