build_model.py 6.0 KB
Newer Older
R
ruri 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#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.
import paddle
import paddle.fluid as fluid
import utils.utility as utility

P
pangyoki 已提交
18
AMP_MODEL_LIST = ["ResNet50", "SE_ResNet50_vd", "ResNet200_vd"]
19 20


R
ruri 已提交
21 22 23 24 25
def _calc_label_smoothing_loss(softmax_out, label, class_dim, epsilon):
    """Calculate label smoothing loss

    Returns:
        label smoothing loss
26

R
ruri 已提交
27 28 29 30 31 32 33 34 35 36 37 38 39
    """

    label_one_hot = fluid.layers.one_hot(input=label, depth=class_dim)
    smooth_label = fluid.layers.label_smooth(
        label=label_one_hot, epsilon=epsilon, dtype="float32")
    loss = fluid.layers.cross_entropy(
        input=softmax_out, label=smooth_label, soft_label=True)
    return loss


def _basic_model(data, model, args, is_train):
    image = data[0]
    label = data[1]
40
    if args.model in AMP_MODEL_LIST:
41
        image_data = (fluid.layers.cast(image, 'float16')
42
                      if args.use_pure_fp16 and not args.use_dali else image)
43
        image_transpose = fluid.layers.transpose(
44 45
            image_data,
            [0, 2, 3, 1]) if args.data_format == 'NHWC' else image_data
46 47
        image_transpose.stop_gradient = image.stop_gradient
        net_out = model.net(input=image_transpose,
48
                            class_dim=args.class_dim,
49
                            data_format=args.data_format)
50 51
    else:
        net_out = model.net(input=image, class_dim=args.class_dim)
52 53
    if args.use_pure_fp16:
        net_out = fluid.layers.cast(x=net_out, dtype="float32")
R
ruri 已提交
54 55 56 57
    softmax_out = fluid.layers.softmax(net_out, use_cudnn=False)

    if is_train and args.use_label_smoothing:
        cost = _calc_label_smoothing_loss(softmax_out, label, args.class_dim,
R
ruri 已提交
58
                                          args.label_smoothing_epsilon)
R
ruri 已提交
59 60 61
    else:
        cost = fluid.layers.cross_entropy(input=softmax_out, label=label)

62 63
    target_cost = (fluid.layers.reduce_sum(cost)
                   if args.use_pure_fp16 else fluid.layers.mean(cost))
R
ruri 已提交
64
    acc_top1 = fluid.layers.accuracy(input=softmax_out, label=label, k=1)
65 66
    acc_top5 = fluid.layers.accuracy(
        input=softmax_out, label=label, k=min(5, args.class_dim))
67
    return [target_cost, acc_top1, acc_top5]
R
ruri 已提交
68 69 70 71


def _googlenet_model(data, model, args, is_train):
    """GoogLeNet model output, include avg_cost, acc_top1 and acc_top5
72

R
ruri 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
    Returns:
         GoogLeNet model output

    """
    image = data[0]
    label = data[1]

    out0, out1, out2 = model.net(input=image, class_dim=args.class_dim)
    cost0 = fluid.layers.cross_entropy(input=out0, label=label)
    cost1 = fluid.layers.cross_entropy(input=out1, label=label)
    cost2 = fluid.layers.cross_entropy(input=out2, label=label)

    avg_cost0 = fluid.layers.mean(x=cost0)
    avg_cost1 = fluid.layers.mean(x=cost1)
    avg_cost2 = fluid.layers.mean(x=cost2)

    avg_cost = avg_cost0 + 0.3 * avg_cost1 + 0.3 * avg_cost2
    acc_top1 = fluid.layers.accuracy(input=out0, label=label, k=1)
91 92
    acc_top5 = fluid.layers.accuracy(
        input=out0, label=label, k=min(5, args.class_dim))
R
ruri 已提交
93 94 95 96 97 98 99 100 101 102 103 104

    return [avg_cost, acc_top1, acc_top5]


def _mixup_model(data, model, args, is_train):
    """output of Mixup processing network, include avg_cost
    """
    image = data[0]
    y_a = data[1]
    y_b = data[2]
    lam = data[3]

105
    if args.model in AMP_MODEL_LIST:
106
        image_data = (fluid.layers.cast(image, 'float16')
107
                      if args.use_pure_fp16 and not args.use_dali else image)
108
        image_transpose = fluid.layers.transpose(
109 110
            image_data,
            [0, 2, 3, 1]) if args.data_format == 'NHWC' else image_data
111 112
        image_transpose.stop_gradient = image.stop_gradient
        net_out = model.net(input=image_transpose,
113 114
                            class_dim=args.class_dim,
                            data_format=args.data_format)
115 116
    else:
        net_out = model.net(input=image, class_dim=args.class_dim)
117 118 119 120 121
    if args.use_pure_fp16:
        net_out_fp32 = fluid.layers.cast(x=net_out, dtype="float32")
        softmax_out = fluid.layers.softmax(net_out_fp32, use_cudnn=False)
    else:
        softmax_out = fluid.layers.softmax(net_out, use_cudnn=False)
R
ruri 已提交
122 123 124 125 126
    if not args.use_label_smoothing:
        loss_a = fluid.layers.cross_entropy(input=softmax_out, label=y_a)
        loss_b = fluid.layers.cross_entropy(input=softmax_out, label=y_b)
    else:
        loss_a = _calc_label_smoothing_loss(softmax_out, y_a, args.class_dim,
R
ruri 已提交
127
                                            args.label_smoothing_epsilon)
R
ruri 已提交
128
        loss_b = _calc_label_smoothing_loss(softmax_out, y_b, args.class_dim,
R
ruri 已提交
129
                                            args.label_smoothing_epsilon)
R
ruri 已提交
130

131 132 133 134 135 136 137 138 139 140 141
    if args.use_pure_fp16:
        target_loss_a = fluid.layers.reduce_sum(x=loss_a)
        target_loss_b = fluid.layers.reduce_sum(x=loss_b)
        cost = lam * target_loss_a + (1 - lam) * target_loss_b
        target_cost = fluid.layers.reduce_sum(x=cost)
    else:
        target_loss_a = fluid.layers.mean(x=loss_a)
        target_loss_b = fluid.layers.mean(x=loss_b)
        cost = lam * target_loss_a + (1 - lam) * target_loss_b
        target_cost = fluid.layers.mean(x=cost)
    return [target_cost]
R
ruri 已提交
142 143 144 145 146


def create_model(model, args, is_train):
    """Create model, include basic model, googlenet model and mixup model
    """
147
    data_loader, data = utility.create_data_loader(is_train, args)
R
ruri 已提交
148 149 150 151 152 153 154 155

    if args.model == "GoogLeNet":
        loss_out = _googlenet_model(data, model, args, is_train)
    else:
        if args.use_mixup and is_train:
            loss_out = _mixup_model(data, model, args, is_train)
        else:
            loss_out = _basic_model(data, model, args, is_train)
156
    return data_loader, loss_out