network_conf.py 5.4 KB
Newer Older
1 2 3 4
import paddle.fluid as fluid
import math


5 6 7 8 9 10 11 12
def ctr_xdeepfm_model(embedding_size,
                      num_field,
                      num_feat,
                      layer_sizes_dnn,
                      act,
                      reg,
                      layer_sizes_cin,
                      is_sparse=False):
13 14 15 16
    init_value_ = 0.1
    initer = fluid.initializer.TruncatedNormalInitializer(
        loc=0.0, scale=init_value_)

17 18 19 20 21 22
    raw_feat_idx = fluid.data(
        name='feat_idx', shape=[None, num_field], dtype='int64')
    raw_feat_value = fluid.data(
        name='feat_value', shape=[None, num_field], dtype='float32')
    label = fluid.data(
        name='label', shape=[None, 1], dtype='float32')  # None * 1
23
    feat_idx = fluid.layers.reshape(raw_feat_idx,
24
                                    [-1, 1])  # (None * num_field) * 1
25 26 27
    feat_value = fluid.layers.reshape(
        raw_feat_value, [-1, num_field, 1])  # None * num_field * 1

28
    feat_embeddings = fluid.embedding(
29
        input=feat_idx,
30
        is_sparse=is_sparse,
31 32 33
        dtype='float32',
        size=[num_feat + 1, embedding_size],
        padding_idx=0,
34 35 36 37
        param_attr=fluid.ParamAttr(initializer=initer))
    feat_embeddings = fluid.layers.reshape(
        feat_embeddings,
        [-1, num_field, embedding_size])  # None * num_field * embedding_size
38 39 40 41
    feat_embeddings = feat_embeddings * feat_value  # None * num_field * embedding_size

    # -------------------- linear  --------------------

42
    weights_linear = fluid.embedding(
43
        input=feat_idx,
44
        is_sparse=is_sparse,
45 46 47
        dtype='float32',
        size=[num_feat + 1, 1],
        padding_idx=0,
48 49 50
        param_attr=fluid.ParamAttr(initializer=initer))
    weights_linear = fluid.layers.reshape(
        weights_linear, [-1, num_field, 1])  # None * num_field * 1
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    b_linear = fluid.layers.create_parameter(
        shape=[1],
        dtype='float32',
        default_initializer=fluid.initializer.ConstantInitializer(value=0))
    y_linear = fluid.layers.reduce_sum(
        (weights_linear * feat_value), 1) + b_linear

    # -------------------- CIN  --------------------

    Xs = [feat_embeddings]
    last_s = num_field
    for s in layer_sizes_cin:
        # calculate Z^(k+1) with X^k and X^0
        X_0 = fluid.layers.reshape(
            fluid.layers.transpose(Xs[0], [0, 2, 1]),
            [-1, embedding_size, num_field,
             1])  # None, embedding_size, num_field, 1
        X_k = fluid.layers.reshape(
            fluid.layers.transpose(Xs[-1], [0, 2, 1]),
            [-1, embedding_size, 1, last_s])  # None, embedding_size, 1, last_s
        Z_k_1 = fluid.layers.matmul(
            X_0, X_k)  # None, embedding_size, num_field, last_s

        # compresses Z^(k+1) to X^(k+1)
        Z_k_1 = fluid.layers.reshape(Z_k_1, [
            -1, embedding_size, last_s * num_field
        ])  # None, embedding_size, last_s*num_field
        Z_k_1 = fluid.layers.transpose(
            Z_k_1, [0, 2, 1])  # None, s*num_field, embedding_size
        Z_k_1 = fluid.layers.reshape(
            Z_k_1, [-1, last_s * num_field, 1, embedding_size]
        )  # None, last_s*num_field, 1, embedding_size  (None, channal_in, h, w) 
        X_k_1 = fluid.layers.conv2d(
            Z_k_1,
            num_filters=s,
            filter_size=(1, 1),
            act=None,
            bias_attr=False,
            param_attr=fluid.ParamAttr(
                initializer=initer))  # None, s, 1, embedding_size
        X_k_1 = fluid.layers.reshape(
            X_k_1, [-1, s, embedding_size])  # None, s, embedding_size

        Xs.append(X_k_1)
        last_s = s

    # sum pooling
    y_cin = fluid.layers.concat(Xs[1:],
                                1)  # None, (num_field++), embedding_size
    y_cin = fluid.layers.reduce_sum(y_cin, -1)  # None, (num_field++)
    y_cin = fluid.layers.fc(input=y_cin,
                            size=1,
                            act=None,
                            param_attr=fluid.ParamAttr(initializer=initer),
                            bias_attr=None)
    y_cin = fluid.layers.reduce_sum(y_cin, dim=-1, keep_dim=True)

    # -------------------- DNN --------------------

    y_dnn = fluid.layers.reshape(feat_embeddings,
                                 [-1, num_field * embedding_size])
    for s in layer_sizes_dnn:
        y_dnn = fluid.layers.fc(input=y_dnn,
                                size=s,
                                act=act,
                                param_attr=fluid.ParamAttr(initializer=initer),
                                bias_attr=None)
    y_dnn = fluid.layers.fc(input=y_dnn,
                            size=1,
                            act=None,
                            param_attr=fluid.ParamAttr(initializer=initer),
                            bias_attr=None)

    # ------------------- xDeepFM ------------------

    predict = fluid.layers.sigmoid(y_linear + y_cin + y_dnn)
    cost = fluid.layers.log_loss(input=predict, label=label, epsilon=0.0000001)
    batch_cost = fluid.layers.reduce_mean(cost)

    # for auc
    predict_2d = fluid.layers.concat([1 - predict, predict], 1)
    label_int = fluid.layers.cast(label, 'int64')
    auc_var, batch_auc_var, auc_states = fluid.layers.auc(input=predict_2d,
                                                          label=label_int,
                                                          slide_steps=0)

137 138
    return batch_cost, auc_var, [raw_feat_idx, raw_feat_value,
                                 label], auc_states