test_while_training.rst 4.3 KB
Newer Older
F
fengjiayi 已提交
1 2
.. _user_guide_test_while_training:

Y
yuyang18 已提交
3 4 5 6
##################
训练过程中评测模型
##################

T
Tink_Y 已提交
7
模型的测试评价与训练的 :code:`fluid.Program` 不同。在测试评价中:
Y
yuyang18 已提交
8 9 10

1. 评价测试不进行反向传播,不优化更新参数。
2. 评价测试执行的操作可以不同。
Y
yuyang18 已提交
11

Y
yuyang18 已提交
12
   * 例如 BatchNorm 操作,在训练和测试时执行不同的算法。
Y
yuyang18 已提交
13

Y
yuyang18 已提交
14 15
   * 评价模型与训练相比可以是完全不同的模型。

T
Tink_Y 已提交
16
生成测试 :code:`fluid.Program`
Y
yuyang18 已提交
17 18
#################################

T
Tink_Y 已提交
19
通过克隆训练 :code:`fluid.Program` 生成测试 :code:`fluid.Program`
Y
yuyang18 已提交
20 21
=======================================================================

T
Tink_Y 已提交
22
:code:`Program.clone()` 方法可以复制出新的 :code:`fluid.Program` 。 通过设置
Y
yuyang18 已提交
23
:code:`Program.clone(for_test=True)` 复制含有用于测试的操作Program。简单的使用方法如下:
Y
yuyang18 已提交
24

F
fengjiayi 已提交
25
.. code-block:: python
Y
yuyang18 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

   import paddle.fluid as fluid

   img = fluid.layers.data(name="image", shape=[784])
   prediction = fluid.layers.fc(
     input=fluid.layers.fc(input=img, size=100, act='relu'),
     size=10,
     act='softmax'
   )
   label = fluid.layers.data(name="label", shape=[1], dtype="int64")
   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)

Y
yuyang18 已提交
44 45
在使用 :code:`Optimizer` 之前,将 :code:`fluid.default_main_program()` 复制\
成一个 :code:`test_program` 。之后使用测试数据运行 :code:`test_program`,\
Y
yuyang18 已提交
46 47
就可以做到运行测试程序,而不影响训练结果。

T
Tink_Y 已提交
48
分别配置训练 :code:`fluid.Program` 和测试 :code:`fluid.Program`
Y
yuyang18 已提交
49 50
=====================================================================

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

Y
yuyang18 已提交
56 57
PaddlePaddle Fluid中使用 :code:`fluid.unique_name` 包来随机初始化用户未定义的\
参数名称。通过 :code:`fluid.unique_name.guard` 可以确保多次调用某函数\
Y
yuyang18 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
参数初始化的名称一致。

例如:

.. code-block:: python

   import paddle.fluid as fluid

   def network(is_test):
       file_obj = fluid.layers.open_files(filenames=["test.recordio"] if is_test else ["train.recordio"], ...)
       img, label = fluid.layers.read_file(file_obj)
       hidden = fluid.layers.fc(input=img, 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_gurad(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

T
Tink_Y 已提交
87
执行测试 :code:`fluid.Program`
Y
yuyang18 已提交
88 89
#################################

T
Tink_Y 已提交
90
使用 :code:`Executor` 执行测试 :code:`fluid.Program`
Y
yuyang18 已提交
91 92 93
=======================================================

用户可以使用 :code:`Executor.run(program=...)` 来执行测试
T
Tink_Y 已提交
94
:code:`fluid.Program`。
Y
yuyang18 已提交
95 96 97 98 99 100 101 102 103

例如

.. code-block:: python

   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

T
Tink_Y 已提交
104
使用 :code:`ParallelExecutor` 执行测试 :code:`fluid.Program`
Y
yuyang18 已提交
105 106
===============================================================

T
Tink_Y 已提交
107
用户可以使用训练用的 :code:`ParallelExecutor` 与测试 :code:`fluid.Program`
Y
yuyang18 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120
一起新建一个测试的 :code:`ParallelExecutor` ;再使用测试
:code:`ParallelExecutor.run` 来执行测试。

例如:

.. code-block:: python

   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], ...)