参数调整常见问题

问题:如何将本地数据传入paddle.nn.embedding的参数矩阵中?

  • 答复:需将本地词典向量读取为 NumPy 数据格式,然后使用paddle.nn.initializer.Assign这个 API 初始化paddle.nn.embedding里的param_attr参数,即可实现加载用户自定义(或预训练)的 Embedding 向量。


问题:如何实现网络层中多个 feature 间共享该层的向量权重?

  • 答复:你可以使用paddle.ParamAttr并设定一个 name 参数,然后再将这个类的对象传入网络层的param_attr参数中,即将所有网络层中param_attr参数里的name设置为同一个,即可实现共享向量权重。如使用 embedding 层时,可以设置param_attr=paddle.ParamAttr(name="word_embedding"),然后把param_attr传入 embedding 层中。


问题:使用 optimizer 或 ParamAttr 设置的正则化和学习率,二者什么差异?

  • 答复:ParamAttr 中定义的regularizer优先级更高。若 ParamAttr 中定义了regularizer,则忽略 Optimizer 中的regularizer;否则,则使用 Optimizer 中的regularizer。ParamAttr 中的学习率默认为 1.0,在对参数优化时,最终的学习率等于 optimizer 的学习率乘以 ParamAttr 的学习率。


问题:如何导出指定层的权重,如导出最后一层的weightsbias

  • 答复:

  1. 在动态图中,使用paddle.save API, 并将最后一层的layer.state_dict() 传入至 save 方法的 obj 参数即可, 然后使用paddle.load 方法加载对应层的参数值。详细可参考 API 文档saveload

  2. 在静态图中,使用paddle.static.save_vars保存指定的 vars,然后使用paddle.static.load_vars加载对应层的参数值。具体示例请见 API 文档:load_varssave_vars


问题:训练过程中如何固定网络和 Batch Normalization(BN)?

  • 答复:

  1. 对于固定 BN:设置 use_global_stats=True,使用已加载的全局均值和方差:global mean/variance,具体内容可查看官网 API 文档batch_norm

  2. 对于固定网络层:如: stage1→ stage2 → stage3 ,设置 stage2 的输出,假设为y,设置 y.stop_gradient=True,那么, stage1→ stage2 整体都固定了,不再更新。


问题:训练的 step 在参数优化器中是如何变化的?

图片名称
  • 答复:

    step表示的是经历了多少组 mini_batch,其统计方法为exe.run(对应 Program)运行的当前次数,即每运行一次exe.run,step 加 1。举例代码如下:

# 执行下方代码后相当于 step 增加了 N x Epoch 总数
for epoch in range(epochs):
    # 执行下方代码后 step 相当于自增了 N
    for data in [mini_batch_1,2,3...N]:
        # 执行下方代码后 step += 1
        exe.run(data)

问题:如何修改全连接层参数,比如 weight,bias?

  • 答复:可以通过param_attr设置参数的属性,paddle.ParamAttr(initializer=paddle.nn.initializer.Normal(0.0, 0.02), learning_rate=2.0),如果learning_rate设置为 0,该层就不参与训练。也可以构造一个 numpy 数据,使用paddle.nn.initializer.Assign来给权重设置想要的值。


问题:如何进行梯度裁剪?

注:该类接口在动态图、静态图下均会生效,是动静统一的。目前不支持其他方式的梯度裁剪。

linear = paddle.nn.Linear(10, 10)
clip = paddle.nn.ClipGradByNorm(clip_norm=1.0)  # 可以选择三种裁剪方式
sdg = paddle.optimizer.SGD(learning_rate=0.1, parameters=linear.parameters(), grad_clip=clip)
sdg.step()                                      # 更新参数前,会先对参数的梯度进行裁剪

了解更多梯度裁剪知识


问题:如何在同一个优化器中定义不同参数的优化策略,比如 bias 的参数 weight_decay 的值为 0.0,非 bias 的参数 weight_decay 的值为 0.01?

  • 答复:

    1. AdamW的参数apply_decay_param_fun可以用来选择哪些参数使用 decay_weight 策略。

    2. 在创建Param的时候,可以通过设置ParamAttr的属性来控制参数的属性。


问题:paddle fluid 如何自定义优化器,自定义更新模型参数的规则?

  • 答复:

    1. 要定义全新优化器,自定义优化器中参数的更新规则,可以通过继承 fluid.Optimizer,重写_append_optimize_op 方法实现。不同优化器实现原理各不相同,一般流程是先获取 learning_rate,gradients 参数,可训练参数,以及该优化器自身特别需要的参数,然后实现更新参数的代码,最后返回更新后的参数。 在实现更新参数代码时,可以选择直接调用paddle 的 API或者使用自定义原生算子。在使用自定义原生算子时,要注意动态图与静态图调用方式有所区别: 需要首先使用framework.in_dygraph_mode()判断是否为动态图模式,如果是动态图模式,则需要调用paddle._C_ops中相应的优化器算子;如果不是动态图模式,则需要调用block.append_op 来添加优化器算子。 代码样例可参考paddle 源码中 AdamOptimizer 等优化器的实现。

    2. 使用现有的常用优化器,可以在创建Param的时候,可以通过设置ParamAttr的属性来控制参数的属性,可以通过设置regularizerlearning_rate等参数简单设置参数的更新规则。