model.py 4.7 KB
Newer Older
Z
zhangwenhui03 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Copyright (c) 2020 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.

T
tangwei 已提交
15
import numpy as np
Z
zhangwenhui03 已提交
16 17
import paddle.fluid as fluid

18
from paddlerec.core.utils import envs
C
Chengmo 已提交
19
from paddlerec.core.model import ModelBase
Z
zhangwenhui03 已提交
20 21 22 23 24 25


class Model(ModelBase):
    def __init__(self, config):
        ModelBase.__init__(self, config)

F
frankwhzhang 已提交
26 27 28
    def _init_hyper_parameters(self):
        self.vocab_size = envs.get_global_env("hyper_parameters.vocab_size")
        self.embed_size = envs.get_global_env("hyper_parameters.embed_size")
T
for mat  
tangwei 已提交
29

F
frankwhzhang 已提交
30
    def input_data(self, is_infer=False, **kwargs):
Z
zhangwenhui03 已提交
31
        sparse_input_ids = [
T
tangwei 已提交
32 33 34 35 36
            fluid.data(
                name="field_" + str(i),
                shape=[-1, 1],
                dtype="int64",
                lod_level=1) for i in range(0, 23)
Z
zhangwenhui03 已提交
37 38 39 40
        ]
        label_ctr = fluid.data(name="ctr", shape=[-1, 1], dtype="int64")
        label_cvr = fluid.data(name="cvr", shape=[-1, 1], dtype="int64")
        inputs = sparse_input_ids + [label_ctr] + [label_cvr]
F
frankwhzhang 已提交
41 42 43 44
        if is_infer:
            return inputs
        else:
            return inputs
T
for mat  
tangwei 已提交
45

Z
zhangwenhui03 已提交
46
    def net(self, inputs, is_infer=False):
T
for mat  
tangwei 已提交
47

Z
zhangwenhui03 已提交
48
        emb = []
F
frankwhzhang 已提交
49
        # input feature data
Z
zhangwenhui03 已提交
50
        for data in inputs[0:-2]:
T
tangwei 已提交
51 52
            feat_emb = fluid.embedding(
                input=data,
F
frankwhzhang 已提交
53
                size=[self.vocab_size, self.embed_size],
T
tangwei 已提交
54 55 56 57
                param_attr=fluid.ParamAttr(
                    name='dis_emb',
                    learning_rate=5,
                    initializer=fluid.initializer.Xavier(
F
frankwhzhang 已提交
58
                        fan_in=self.embed_size, fan_out=self.embed_size)),
T
tangwei 已提交
59 60 61
                is_sparse=True)
            field_emb = fluid.layers.sequence_pool(
                input=feat_emb, pool_type='sum')
Z
zhangwenhui03 已提交
62 63
            emb.append(field_emb)
        concat_emb = fluid.layers.concat(emb, axis=1)
T
for mat  
tangwei 已提交
64

Z
zhangwenhui03 已提交
65 66
        # ctr
        active = 'relu'
F
frankwhzhang 已提交
67 68 69
        ctr_fc1 = self._fc('ctr_fc1', concat_emb, 200, active)
        ctr_fc2 = self._fc('ctr_fc2', ctr_fc1, 80, active)
        ctr_out = self._fc('ctr_out', ctr_fc2, 2, 'softmax')
T
for mat  
tangwei 已提交
70

Z
zhangwenhui03 已提交
71
        # cvr
F
frankwhzhang 已提交
72 73 74
        cvr_fc1 = self._fc('cvr_fc1', concat_emb, 200, active)
        cvr_fc2 = self._fc('cvr_fc2', cvr_fc1, 80, active)
        cvr_out = self._fc('cvr_out', cvr_fc2, 2, 'softmax')
T
for mat  
tangwei 已提交
75

Z
zhangwenhui03 已提交
76 77
        ctr_clk = inputs[-2]
        ctcvr_buy = inputs[-1]
T
for mat  
tangwei 已提交
78

T
tangwei 已提交
79 80 81 82
        ctr_prop_one = fluid.layers.slice(
            ctr_out, axes=[1], starts=[1], ends=[2])
        cvr_prop_one = fluid.layers.slice(
            cvr_out, axes=[1], starts=[1], ends=[2])
T
for mat  
tangwei 已提交
83

T
tangwei 已提交
84 85 86 87
        ctcvr_prop_one = fluid.layers.elementwise_mul(ctr_prop_one,
                                                      cvr_prop_one)
        ctcvr_prop = fluid.layers.concat(
            input=[1 - ctcvr_prop_one, ctcvr_prop_one], axis=1)
Z
zhangwenhui03 已提交
88

T
tangwei 已提交
89 90 91 92
        auc_ctr, batch_auc_ctr, auc_states_ctr = fluid.layers.auc(
            input=ctr_out, label=ctr_clk)
        auc_ctcvr, batch_auc_ctcvr, auc_states_ctcvr = fluid.layers.auc(
            input=ctcvr_prop, label=ctcvr_buy)
Z
zhangwenhui03 已提交
93 94 95 96 97 98

        if is_infer:
            self._infer_results["AUC_ctr"] = auc_ctr
            self._infer_results["AUC_ctcvr"] = auc_ctcvr
            return

Z
zhangwenhui03 已提交
99
        loss_ctr = fluid.layers.cross_entropy(input=ctr_out, label=ctr_clk)
T
tangwei 已提交
100 101
        loss_ctcvr = fluid.layers.cross_entropy(
            input=ctcvr_prop, label=ctcvr_buy)
Z
zhangwenhui03 已提交
102 103 104 105 106 107 108 109 110
        cost = loss_ctr + loss_ctcvr
        avg_cost = fluid.layers.mean(cost)

        self._cost = avg_cost
        self._metrics["AUC_ctr"] = auc_ctr
        self._metrics["BATCH_AUC_ctr"] = batch_auc_ctr
        self._metrics["AUC_ctcvr"] = auc_ctcvr
        self._metrics["BATCH_AUC_ctcvr"] = batch_auc_ctcvr

F
frankwhzhang 已提交
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    def _fc(self, tag, data, out_dim, active='prelu'):

        init_stddev = 1.0
        scales = 1.0 / np.sqrt(data.shape[1])

        p_attr = fluid.param_attr.ParamAttr(
            name='%s_weight' % tag,
            initializer=fluid.initializer.NormalInitializer(
                loc=0.0, scale=init_stddev * scales))

        b_attr = fluid.ParamAttr(
            name='%s_bias' % tag, initializer=fluid.initializer.Constant(0.1))

        out = fluid.layers.fc(input=data,
                              size=out_dim,
                              act=active,
                              param_attr=p_attr,
                              bias_attr=b_attr,
                              name=tag)
        return out