训练过程中评测模型
模型的测试评价与训练的 fluid.Program
不同。在测试评价中:
- 测试评价不进行反向传播,不优化更新参数。
- 测试评价执行的操作可以不同。
- 例如 BatchNorm 操作,在训练和测试时执行不同的算法。
- 测试评价模型与训练模型可以是完全不同的模型。
生成测试 fluid.Program
通过克隆训练 fluid.Program
生成测试 fluid.Program
用 Program.clone()
方法可以复制出新的 fluid.Program
。 通过设置 Program.clone(for_test=True)
复制含有用于测试的操作 fluid.Program
。简单的使用方法如下:
import paddle.fluid as fluid
image = fluid.data(name="image", shape=[None, 784], dtype='float32')
label = fluid.data(name="label", shape=[None, 1], dtype="int64")
prediction = fluid.layers.fc(
input=fluid.layers.fc(input=image, size=100, act='relu'),
size=10,
act='softmax'
)
loss = fluid.layers.mean(fluid.layers.cross_entropy(input=prediction, label=label))
acc = fluid.layers.accuracy(input=prediction, label=label)
test_program = fluid.default_main_program().clone(for_test=True)
adam = fluid.optimizer.Adam(learning_rate=0.001)
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
可以确保多次调用某函数参数初始化的名称一致。
例如:
import paddle.fluid as fluid
def network(is_test):
image = fluid.data(name="image", shape=[None, 784], dtype='float32')
label = fluid.data(name="label", shape=[None, 1], dtype="int64")
hidden = fluid.layers.fc(input=image, size=100, act="relu")
hidden = fluid.layers.batch_norm(input=hidden, is_test=is_test)
...
return loss
with fluid.unique_name.guard():
train_loss = network(is_test=False)
sgd = fluid.optimizer.SGD(0.001)
sgd.minimize(train_loss)
test_program = fluid.Program()
with fluid.unique_name.guard():
with fluid.program_guard(test_program, fluid.Program()):
test_loss = network(is_test=True)
# fluid.default_main_program() is the train program
# fluid.test_program is the test program
执行测试 fluid.Program
使用 Executor
执行测试 fluid.Program
用户可以使用 Executor.run(program=...)
来执行测试 fluid.Program
。
例如
exe = fluid.Executor(fluid.CPUPlace())
test_acc = exe.run(program=test_program, feed=test_data_batch, fetch_list=[acc])
print 'Test accuracy is ', test_acc
使用 ParallelExecutor
执行测试 fluid.Program
用户可以使用训练用的 ParallelExecutor
与测试 fluid.Program
一起,新建一个测试的 ParallelExecutor
;再使用测试 ParallelExecutor.run
来执行测试。
例如:
train_exec = fluid.ParallelExecutor(use_cuda=True, loss_name=loss.name)
test_exec = fluid.ParallelExecutor(use_cuda=True, share_vars_from=train_exec,
main_program=test_program)
test_acc = test_exec.run(fetch_list=[acc], ...)