train.py 5.2 KB
Newer Older
D
dangqingqing 已提交
1 2 3 4 5
import paddle.v2 as paddle
import paddle.fluid as fluid
import reader
import load_model as load_model
from mobilenet_ssd import mobile_net
6 7 8 9 10 11 12 13 14
from utility import add_arguments, print_arguments
import os
import numpy as np
import argparse
import functools

parser = argparse.ArgumentParser(description=__doc__)
add_arg = functools.partial(add_arguments, argparser=parser)
# yapf: disable
15 16 17
add_arg('batch_size',   int,    32,       "Minibatch size.")
add_arg('parallel',     bool,   True,     "Whether use parallel training.")
add_arg('use_gpu',      bool,   True,     "Whether use GPU.")
18
# yapf: disable
D
dangqingqing 已提交
19 20


21 22
def train(args,
          train_file_list,
D
dangqingqing 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
          val_file_list,
          data_args,
          learning_rate,
          batch_size,
          num_passes,
          model_save_dir='model',
          init_model_path=None):
    image_shape = [3, data_args.resize_h, data_args.resize_w]

    image = fluid.layers.data(name='image', shape=image_shape, dtype='float32')
    gt_box = fluid.layers.data(
        name='gt_box', shape=[4], dtype='float32', lod_level=1)
    gt_label = fluid.layers.data(
        name='gt_label', shape=[1], dtype='int32', lod_level=1)
    difficult = fluid.layers.data(
        name='gt_difficult', shape=[1], dtype='int32', lod_level=1)

40 41 42 43 44 45 46 47 48 49 50
    if args.parallel:
        places = fluid.layers.get_places()
        pd = fluid.layers.ParallelDo(places)
        with pd.do():
            image_ = pd.read_input(image)
            gt_box_ = pd.read_input(gt_box)
            gt_label_ = pd.read_input(gt_label)
            difficult_ = pd.read_input(difficult)
            locs, confs, box, box_var = mobile_net(image_, image_shape)
            loss = fluid.layers.ssd_loss(locs, confs, gt_box_, gt_label_,
                                         box, box_var)
51 52
            nmsed_out = fluid.layers.detection_output(
                locs, confs, box, box_var, nms_threshold=0.45)
53
            loss = fluid.layers.reduce_sum(loss)
54
            pd.write_output(loss)
55
            pd.write_output(nmsed_out)
56

57
        loss, nmsed_out = pd()
58
        loss = fluid.layers.mean(loss)
59 60 61
    else:
        locs, confs, box, box_var = mobile_net(image, image_shape)
        nmsed_out = fluid.layers.detection_output(
62 63
            locs, confs, box, box_var, nms_threshold=0.45)
        loss = fluid.layers.ssd_loss(locs, confs, gt_box, gt_label,
D
dangqingqing 已提交
64
                                     box, box_var)
65
        loss = fluid.layers.reduce_sum(loss)
D
dangqingqing 已提交
66 67 68

    test_program = fluid.default_main_program().clone(for_test=True)
    with fluid.program_guard(test_program):
69 70 71 72 73 74 75 76 77
        map_eval = fluid.evaluator.DetectionMAP(
            nmsed_out,
            gt_label,
            gt_box,
            difficult,
            21,
            overlap_threshold=0.5,
            evaluate_difficult=False,
            ap_version='11point')
D
dangqingqing 已提交
78

G
gaoyuan 已提交
79 80 81 82
    boundaries = [40000, 60000]
    values = [0.001, 0.0005, 0.00025]
    optimizer = fluid.optimizer.RMSProp(
        learning_rate=fluid.layers.piecewise_decay(boundaries, values),
G
gaoyuan 已提交
83
        regularization=fluid.regularizer.L2Decay(0.00005), )
D
dangqingqing 已提交
84

85
    optimizer.minimize(loss)
D
dangqingqing 已提交
86

87
    place = fluid.CUDAPlace(0) if args.use_gpu else fluid.CPUPlace()
D
dangqingqing 已提交
88 89 90
    exe = fluid.Executor(place)
    exe.run(fluid.default_startup_program())

G
gaoyuan 已提交
91 92
    load_model.load_and_set_vars(place)
    #load_model.load_paddlev1_vars(place)
D
dangqingqing 已提交
93 94 95 96 97 98 99 100
    train_reader = paddle.batch(
        reader.train(data_args, train_file_list), batch_size=batch_size)
    test_reader = paddle.batch(
        reader.test(data_args, val_file_list), batch_size=batch_size)
    feeder = fluid.DataFeeder(
        place=place, feed_list=[image, gt_box, gt_label, difficult])

    def test(pass_id):
101
        _, accum_map = map_eval.get_map_var()
D
dangqingqing 已提交
102 103 104 105 106 107 108 109 110 111
        map_eval.reset(exe)
        test_map = None
        for _, data in enumerate(test_reader()):
            test_map = exe.run(test_program,
                               feed=feeder.feed(data),
                               fetch_list=[accum_map])
        print("Test {0}, map {1}".format(pass_id, test_map[0]))

    for pass_id in range(num_passes):
        for batch_id, data in enumerate(train_reader()):
112 113 114
            loss_v = exe.run(fluid.default_main_program(),
                             feed=feeder.feed(data),
                             fetch_list=[loss])
G
gaoyuan 已提交
115 116 117
            if batch_id % 20 == 0:
                print("Pass {0}, batch {1}, loss {2}"
                      .format(pass_id, batch_id, loss_v[0]))
D
dangqingqing 已提交
118 119 120 121 122 123 124 125 126 127
        test(pass_id)

        if pass_id % 10 == 0:
            model_path = os.path.join(model_save_dir, str(pass_id))
            print 'save models to %s' % (model_path)
            fluid.io.save_inference_model(model_path, ['image'], [nmsed_out],
                                          exe)


if __name__ == '__main__':
128 129
    args = parser.parse_args()
    print_arguments(args)
D
dangqingqing 已提交
130 131 132
    data_args = reader.Settings(
        data_dir='./data',
        label_file='label_list',
G
gaoyuan 已提交
133 134
        apply_distort=True,
        apply_expand=True,
D
dangqingqing 已提交
135 136 137
        resize_h=300,
        resize_w=300,
        mean_value=[127.5, 127.5, 127.5])
138 139 140 141 142
    train(args,
          train_file_list='./data/trainval.txt',
          val_file_list='./data/test.txt',
          data_args=data_args,
          learning_rate=0.001,
143
          batch_size=args.batch_size,
144
          num_passes=300)