layers.py 8.9 KB
Newer Older
X
xiexionghang 已提交
1
import paddle.fluid as fluid
T
tangwei 已提交
2
from .base import Layer
X
xiexionghang 已提交
3

X
xiexionghang 已提交
4

X
xiexionghang 已提交
5
class EmbeddingInputLayer(Layer):
X
xiexionghang 已提交
6 7
    """R
    """
T
tangwei 已提交
8

X
xiexionghang 已提交
9
    def __init__(self, config):
X
xiexionghang 已提交
10 11
        """R
        """
X
xiexionghang 已提交
12 13
        self._cvm = config['cvm']
        self._name = config['name']
X
xiexionghang 已提交
14
        self._slots = [str(slot) for slot in config['slots']]
X
xiexionghang 已提交
15 16
        self._mf_dim = config['mf_dim']
        self._backward = config['backward']
T
tangwei 已提交
17
        self._emb_dim = self._mf_dim + 3  # append show ctr lr
X
xiexionghang 已提交
18
        self._emb_layers = []
T
tangwei 已提交
19 20

    def generate_fluid(self, param):
X
xiexionghang 已提交
21 22
        """R
        """
X
xiexionghang 已提交
23 24 25 26 27 28 29
        show_clk = fluid.layers.concat(
            [param['layer']['show'], param['layer']['click']], axis=1)
        show_clk.stop_gradient = True
        data_var = []
        for slot in self._slots:
            l = fluid.layers.data(name=slot, shape=[1], dtype="int64", lod_level=1)
            data_var.append(l)
X
xiexionghang 已提交
30
            emb = fluid.layers.embedding(input=l, size=[10, self._emb_dim], \
T
tangwei 已提交
31 32
                                         is_sparse=True, is_distributed=True,
                                         param_attr=fluid.ParamAttr(name="embedding"))
X
xiexionghang 已提交
33 34 35 36
            emb = fluid.layers.sequence_pool(input=emb, pool_type='sum')
            emb = fluid.layers.continuous_value_model(emb, show_clk, self._cvm)
            self._emb_layers.append(emb)
        output = fluid.layers.concat(input=self._emb_layers, axis=1, name=self._name)
X
xiexionghang 已提交
37
        return output, {'data_var': data_var}
X
xiexionghang 已提交
38

X
xiexionghang 已提交
39

X
xiexionghang 已提交
40
class LabelInputLayer(Layer):
X
xiexionghang 已提交
41 42
    """R
    """
T
tangwei 已提交
43

X
xiexionghang 已提交
44
    def __init__(self, config):
X
xiexionghang 已提交
45 46
        """R
        """
X
xiexionghang 已提交
47 48 49 50 51
        self._name = config['name']
        self._dim = config.get('dim', 1)
        self._data_type = config.get('data_type', "int64")
        self._label_idx = config['label_idx']

T
tangwei 已提交
52
    def generate_fluid(self, param):
X
xiexionghang 已提交
53 54 55
        """R
        """
        label = fluid.layers.data(name=self._name, shape=[-1, self._dim], \
T
tangwei 已提交
56
                                  dtype=self._data_type, lod_level=0, append_batch_size=False)
X
xiexionghang 已提交
57 58
        cast_label = fluid.layers.cast(label, dtype='float32')
        cast_label.stop_gradient = True
X
xiexionghang 已提交
59 60
        return cast_label, {'data_var': [label]}

X
xiexionghang 已提交
61

T
tangwei 已提交
62
class TagInputLayer(Layer):
X
xiexionghang 已提交
63 64
    """R
    """
T
tangwei 已提交
65

X
xiexionghang 已提交
66
    def __init__(self, config):
X
xiexionghang 已提交
67 68
        """R
        """
X
xiexionghang 已提交
69 70 71 72 73
        self._name = config['name']
        self._tag = config['tag']
        self._dim = config.get('dim', 1)
        self._data_type = config['data_type']

T
tangwei 已提交
74
    def generate_fluid(self, param):
X
xiexionghang 已提交
75 76 77
        """R
        """
        output = fluid.layers.data(name=self._name, shape=[-1, self._dim], \
T
tangwei 已提交
78
                                   dtype=self._data_type, lod_level=0, append_batch_size=False, stop_gradient=True)
X
xiexionghang 已提交
79 80
        return output, {'data_var': [output]}

T
tangwei 已提交
81 82

class ParamLayer(Layer):
X
xiexionghang 已提交
83 84
    """R
    """
T
tangwei 已提交
85

X
xiexionghang 已提交
86
    def __init__(self, config):
X
xiexionghang 已提交
87 88
        """R
        """
X
xiexionghang 已提交
89 90 91 92 93 94 95
        self._name = config['name']
        self._coln = config['coln']
        self._table_id = config.get('table_id', -1)
        self._init_range = config.get('init_range', 1)
        self._data_type = config.get('data_type', 'float32')
        self._config = config

T
tangwei 已提交
96
    def generate_fluid(self, param):
X
xiexionghang 已提交
97 98
        """R
        """
T
tangwei 已提交
99
        return self._config, {'inference_param': {'name': 'param', 'params': [], 'table_id': self._table_id}}
X
xiexionghang 已提交
100

X
xiexionghang 已提交
101

T
tangwei 已提交
102
class SummaryLayer(Layer):
X
xiexionghang 已提交
103 104
    """R
    """
T
tangwei 已提交
105

X
xiexionghang 已提交
106
    def __init__(self, config):
X
xiexionghang 已提交
107 108
        """R
        """
X
xiexionghang 已提交
109 110 111 112 113
        self._name = config['name']
        self._table_id = config.get('table_id', -1)
        self._data_type = config.get('data_type', 'float32')
        self._config = config

T
tangwei 已提交
114
    def generate_fluid(self, param):
X
xiexionghang 已提交
115 116
        """R
        """
T
tangwei 已提交
117
        return self._config, {'inference_param': {'name': 'summary', 'params': [], 'table_id': self._table_id}}
X
xiexionghang 已提交
118

X
xiexionghang 已提交
119

T
tangwei 已提交
120
class NormalizetionLayer(Layer):
X
xiexionghang 已提交
121 122
    """R
    """
T
tangwei 已提交
123

X
xiexionghang 已提交
124
    def __init__(self, config):
X
xiexionghang 已提交
125 126
        """R
        """
X
xiexionghang 已提交
127 128
        self._name = config['name']
        self._input = config['input']
T
tangwei 已提交
129
        self._summary = config['summary']
X
xiexionghang 已提交
130 131
        self._table_id = config.get('table_id', -1)

T
tangwei 已提交
132
    def generate_fluid(self, param):
X
xiexionghang 已提交
133 134
        """R
        """
X
xiexionghang 已提交
135 136 137
        input_layer = param['layer'][self._input[0]]
        summary_layer = param['layer'][self._summary]
        if len(self._input) > 0:
T
tangwei 已提交
138
            input_list = [param['layer'][i] for i in self._input]
X
xiexionghang 已提交
139 140
            input_layer = fluid.layers.concat(input=input_list, axis=1)
        bn = fluid.layers.data_norm(input=input_layer, name=self._name, epsilon=1e-4, param_attr={
T
tangwei 已提交
141
            "batch_size": 1e4, "batch_sum_default": 0.0, "batch_square": 1e4})
X
xiexionghang 已提交
142
        inference_param = [self._name + '.batch_size', self._name + '.batch_sum', self._name + '.batch_square_sum']
T
tangwei 已提交
143 144
        return bn, {'inference_param': {'name': 'summary', \
                                        'params': inference_param, 'table_id': summary_layer.get('table_id', -1)}}
X
xiexionghang 已提交
145

X
xiexionghang 已提交
146

T
tangwei 已提交
147
class NeuralLayer(Layer):
X
xiexionghang 已提交
148 149
    """R
    """
T
tangwei 已提交
150

X
xiexionghang 已提交
151
    def __init__(self, config):
X
xiexionghang 已提交
152 153
        """R
        """
X
xiexionghang 已提交
154 155 156 157 158 159
        self._name = config['name']
        self._param = config['param']
        self._input = config['input']
        self._bias = config.get('bias', True)
        self._act_func = config.get('act_func', None)

T
tangwei 已提交
160
    def generate_fluid(self, param):
X
xiexionghang 已提交
161 162
        """R
        """
X
xiexionghang 已提交
163 164 165
        param_layer = param['layer'][self._param]
        input_layer = param['layer'][self._input[0]]
        if len(self._input) > 0:
T
tangwei 已提交
166
            input_list = [param['layer'][i] for i in self._input]
X
xiexionghang 已提交
167 168 169 170 171
            input_layer = fluid.layers.concat(input=input_list, axis=1)
        input_coln = input_layer.shape[1]
        scale = param_layer['init_range'] / (input_coln ** 0.5)
        bias = None
        if self._bias:
T
tangwei 已提交
172 173
            bias = fluid.ParamAttr(learning_rate=1.0,
                                   initializer=fluid.initializer.NormalInitializer(loc=0.0, scale=scale))
X
xiexionghang 已提交
174
        fc = fluid.layers.fc(
T
tangwei 已提交
175 176 177 178 179
            name=self._name,
            input=input_layer,
            size=param_layer['coln'],
            act=self._act_func,
            param_attr= \
X
xiexionghang 已提交
180
                fluid.ParamAttr(learning_rate=1.0, \
T
tangwei 已提交
181 182
                                initializer=fluid.initializer.NormalInitializer(loc=0.0, scale=scale)),
            bias_attr=bias)
X
xiexionghang 已提交
183
        inference_param = [self._name + '.w_0', self._name + '.b_0']
T
tangwei 已提交
184 185
        return fc, {'inference_param': {'name': 'param', 'params': inference_param, \
                                        'table_id': param_layer.get('table_id', -1)}}
X
xiexionghang 已提交
186

X
xiexionghang 已提交
187

X
xiexionghang 已提交
188
class SigmoidLossLayer(Layer):
X
xiexionghang 已提交
189 190
    """R
    """
T
tangwei 已提交
191

X
xiexionghang 已提交
192
    def __init__(self, config):
X
xiexionghang 已提交
193 194
        """R
        """
X
xiexionghang 已提交
195 196 197 198 199 200 201
        self._name = config['name']
        self._label = config['label']
        self._input = config['input']
        self._weight = config.get('weight', None)
        self._metric_label = config.get('metric_label', None)
        self._bound = config.get('bound', [-15.0, 15.0])
        self._extend_output = {
X
xiexionghang 已提交
202 203 204 205 206 207 208 209 210 211 212 213 214 215
            'metric_label': self._metric_label,
            'metric_dict': {
                'auc': {'var': None},
                'batch_auc': {'var': None},
                'stat_pos': {'var': None, 'data_type': 'int64'},
                'stat_neg': {'var': None, 'data_type': 'int64'},
                'batch_stat_pos': {'var': None, 'data_type': 'int64'},
                'batch_stat_neg': {'var': None, 'data_type': 'int64'},
                'pos_ins_num': {'var': None},
                'abserr': {'var': None},
                'sqrerr': {'var': None},
                'prob': {'var': None},
                'total_ins_num': {'var': None},
                'q': {'var': None}
X
xiexionghang 已提交
216 217
            }
        }
T
tangwei 已提交
218 219

    def generate_fluid(self, param):
X
xiexionghang 已提交
220 221
        """R
        """
X
xiexionghang 已提交
222 223
        input_layer = param['layer'][self._input[0]]
        label_layer = param['layer'][self._label]
X
xiexionghang 已提交
224
        output = fluid.layers.clip(input_layer, self._bound[0], self._bound[1], name=self._name)
X
xiexionghang 已提交
225 226 227 228 229 230 231
        norm = fluid.layers.sigmoid(output, name=self._name)
        output = fluid.layers.log_loss(norm, fluid.layers.cast(x=label_layer, dtype='float32'))
        if self._weight:
            weight_layer = param['layer'][self._weight]
            output = fluid.layers.elementwise_mul(output, weight_layer)
        output = fluid.layers.mean(x=output)
        self._extend_output['loss'] = output
T
tangwei 已提交
232 233

        # For AUC Metric
X
xiexionghang 已提交
234 235 236 237
        metric = self._extend_output['metric_dict']
        binary_predict = fluid.layers.concat(
            input=[fluid.layers.elementwise_sub(fluid.layers.ceil(norm), norm), norm], axis=1)
        metric['auc']['var'], metric['batch_auc']['var'], [metric['batch_stat_pos']['var'], \
T
tangwei 已提交
238 239
                                                           metric['batch_stat_neg']['var'], metric['stat_pos']['var'],
                                                           metric['stat_neg']['var']] = \
X
xiexionghang 已提交
240
            fluid.layers.auc(input=binary_predict, label=fluid.layers.cast(x=label_layer, dtype='int64'), \
T
tangwei 已提交
241
                             curve='ROC', num_thresholds=32)
X
xiexionghang 已提交
242 243 244 245 246 247

        metric['sqrerr']['var'], metric['abserr']['var'], metric['prob']['var'], metric['q']['var'], \
        metric['pos_ins_num']['var'], metric['total_ins_num']['var'] = \
            fluid.contrib.layers.ctr_metric_bundle(norm, fluid.layers.cast(x=label_layer, dtype='float32'))

        return norm, self._extend_output