• 训练过程中评测模型
    • 生成测试 fluid.Program
      • 通过克隆训练 fluid.Program 生成测试 fluid.Program
      • 分别配置训练 fluid.Program 和测试 fluid.Program
    • 执行测试 fluid.Program
      • 使用 Executor 执行测试 fluid.Program
      • 使用 ParallelExecutor 执行测试 fluid.Program

    训练过程中评测模型

    模型的测试评价与训练的 fluid.Program 不同。在测试评价中:

    • 测试评价不进行反向传播,不优化更新参数。
    • 测试评价执行的操作可以不同。
      • 例如 BatchNorm 操作,在训练和测试时执行不同的算法。
      • 测试评价模型与训练模型可以是完全不同的模型。

    生成测试 fluid.Program

    通过克隆训练 fluid.Program 生成测试 fluid.Program

    用:code:Program.clone() 方法可以复制出新的 fluid.Program 。 通过设置Program.clone(for_test=True) 复制含有用于测试的操作 fluid.Program 。简单的使用方法如下:

    1. import paddle.fluid as fluid
    2.  
    3. img = fluid.layers.data(name="image", shape=[784])
    4. prediction = fluid.layers.fc(
    5. input=fluid.layers.fc(input=img, size=100, act='relu'),
    6. size=10,
    7. act='softmax'
    8. )
    9. label = fluid.layers.data(name="label", shape=[1], dtype="int64")
    10. loss = fluid.layers.mean(fluid.layers.cross_entropy(input=prediction, label=label))
    11. acc = fluid.layers.accuracy(input=prediction, label=label)
    12.  
    13. test_program = fluid.default_main_program().clone(for_test=True)
    14.  
    15. adam = fluid.optimizer.Adam(learning_rate=0.001)
    16. adam.minimize(loss)

    在使用 Optimizer 之前,将 fluid.default_main_program() 复制成一个 test_program 。之后使用测试数据运行 test_program,就可以做到运行测试程序,而不影响训练结果。

    分别配置训练 fluid.Program 和测试 fluid.Program

    如果训练程序和测试程序相差较大时,用户也可以通过完全定义两个不同的fluid.Program,分别进行训练和测试。在PaddlePaddle Fluid中,所有的参数都有名字。如果两个不同的操作,甚至两个不同的网络使用了同样名字的参数,那么他们的值和内存空间都是共享的。

    PaddlePaddle Fluid中使用 fluid.unique_name 包来随机初始化用户未定义的参数名称。通过 fluid.unique_name.guard 可以确保多次调用某函数参数初始化的名称一致。

    例如:

    1. import paddle.fluid as fluid
    2.  
    3. def network(is_test):
    4. file_obj = fluid.layers.open_files(filenames=["test.recordio"] if is_test else ["train.recordio"], ...)
    5. img, label = fluid.layers.read_file(file_obj)
    6. hidden = fluid.layers.fc(input=img, size=100, act="relu")
    7. hidden = fluid.layers.batch_norm(input=hidden, is_test=is_test)
    8. ...
    9. return loss
    10.  
    11. with fluid.unique_name.guard():
    12. train_loss = network(is_test=False)
    13. sgd = fluid.optimizer.SGD(0.001)
    14. sgd.minimize(train_loss)
    15.  
    16. test_program = fluid.Program()
    17. with fluid.unique_name.guard():
    18. with fluid.program_gurad(test_program, fluid.Program()):
    19. test_loss = network(is_test=True)
    20.  
    21. # fluid.default_main_program() is the train program
    22. # fluid.test_program is the test program

    执行测试 fluid.Program

    使用 Executor 执行测试 fluid.Program

    用户可以使用 Executor.run(program=…) 来执行测试fluid.Program

    例如

    1. exe = fluid.Executor(fluid.CPUPlace())
    2. test_acc = exe.run(program=test_program, feed=test_data_batch, fetch_list=[acc])
    3. print 'Test accuracy is ', test_acc

    使用 ParallelExecutor 执行测试 fluid.Program

    用户可以使用训练用的 ParallelExecutor 与测试 fluid.Program一起,新建一个测试的 ParallelExecutor ;再使用测试ParallelExecutor.run 来执行测试。

    例如:

    1. train_exec = fluid.ParallelExecutor(use_cuda=True, loss_name=loss.name)
    2.  
    3. test_exec = fluid.ParallelExecutor(use_cuda=True, share_vars_from=train_exec,
    4. main_program=test_program)
    5. test_acc = test_exec.run(fetch_list=[acc], ...)