test_recognize_digits_conv.py 4.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
#   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
14

15 16
from __future__ import print_function

17 18
import argparse
import paddle.fluid as fluid
19
import paddle.fluid.core as core
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
import paddle
import sys
import numpy
import unittest
import math
import sys
import os

BATCH_SIZE = 64


def inference_program():
    img = fluid.layers.data(name='img', shape=[1, 28, 28], dtype='float32')

    conv_pool_1 = fluid.nets.simple_img_conv_pool(
        input=img,
        filter_size=5,
        num_filters=20,
        pool_size=2,
        pool_stride=2,
        act="relu")
    conv_pool_1 = fluid.layers.batch_norm(conv_pool_1)
    conv_pool_2 = fluid.nets.simple_img_conv_pool(
        input=conv_pool_1,
        filter_size=5,
        num_filters=50,
        pool_size=2,
        pool_stride=2,
        act="relu")
    prediction = fluid.layers.fc(input=conv_pool_2, size=10, act='softmax')
    return prediction


def train_program():
    label = fluid.layers.data(name='label', shape=[1], dtype='int64')

    predict = inference_program()
    cost = fluid.layers.cross_entropy(input=predict, label=label)
    avg_cost = fluid.layers.mean(cost)
D
daminglu 已提交
59 60
    acc = fluid.layers.accuracy(input=predict, label=label)
    return [avg_cost, acc]
61 62


63 64 65 66
def optimizer_func():
    return fluid.optimizer.Adam(learning_rate=0.001)


67
def train(use_cuda, train_program, parallel, params_dirname):
68
    place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
69 70 71 72

    trainer = fluid.Trainer(
        train_func=train_program,
        place=place,
73
        optimizer_func=optimizer_func,
74
        parallel=parallel)
75 76

    def event_handler(event):
77
        if isinstance(event, fluid.EndEpochEvent):
D
daminglu 已提交
78 79
            test_reader = paddle.batch(
                paddle.dataset.mnist.test(), batch_size=BATCH_SIZE)
80
            avg_cost, acc = trainer.test(
D
daminglu 已提交
81 82
                reader=test_reader, feed_order=['img', 'label'])

83 84
            print("avg_cost: %s" % avg_cost)
            print("acc     : %s" % acc)
D
daminglu 已提交
85

86
            if acc > 0.2:  # Smaller value to increase CI speed
87
                trainer.save_params(params_dirname)
D
daminglu 已提交
88
            else:
89 90
                print('BatchID {0}, Test Loss {1:0.2}, Acc {2:0.2}'.format(
                    event.epoch + 1, avg_cost, acc))
91
                if math.isnan(avg_cost):
D
daminglu 已提交
92
                    sys.exit("got NaN loss, training failed.")
Y
yuyang18 已提交
93
        elif isinstance(event, fluid.EndStepEvent):
94 95 96 97
            print(
                ("Step {0}, Epoch {1} Metrics {2}".format(
                    event.step, event.epoch,
                    list(map(numpy.array, event.metrics)))))
98 99 100 101 102

    train_reader = paddle.batch(
        paddle.reader.shuffle(
            paddle.dataset.mnist.train(), buf_size=500),
        batch_size=BATCH_SIZE)
103 104

    trainer.train(
105 106 107 108
        num_epochs=1,
        event_handler=event_handler,
        reader=train_reader,
        feed_order=['img', 'label'])
109 110


111
def infer(use_cuda, inference_program, parallel, params_dirname=None):
112 113
    place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()

D
daminglu 已提交
114
    inferencer = fluid.Inferencer(
115 116 117 118
        infer_func=inference_program,
        param_path=params_dirname,
        place=place,
        parallel=parallel)
119 120 121 122 123 124 125

    batch_size = 1
    tensor_img = numpy.random.uniform(-1.0, 1.0,
                                      [batch_size, 1, 28, 28]).astype("float32")

    results = inferencer.infer({'img': tensor_img})

126
    print("infer results: ", results[0])
127 128


129
def main(use_cuda, parallel):
130
    params_dirname = "recognize_digits_conv.inference.model"
131 132

    # call train() with is_local argument to run distributed train
133
    os.environ['CPU_NUM'] = str(4)
D
daminglu 已提交
134 135 136
    train(
        use_cuda=use_cuda,
        train_program=train_program,
137 138 139 140 141 142 143 144
        params_dirname=params_dirname,
        parallel=parallel)

    # FIXME(zcd): in the inference stage, the number of
    # input data is one, it is not appropriate to use parallel.
    if parallel and use_cuda:
        return
    os.environ['CPU_NUM'] = str(1)
D
daminglu 已提交
145 146 147
    infer(
        use_cuda=use_cuda,
        inference_program=inference_program,
148 149
        params_dirname=params_dirname,
        parallel=parallel)
150 151 152


if __name__ == '__main__':
153 154 155 156 157
    for use_cuda in (False, True):
        for parallel in (False, True):
            if use_cuda and not core.is_compiled_with_cuda():
                continue
            main(use_cuda=use_cuda, parallel=parallel)