Beispiel #1
0
    def _build_variables(self):
        self.user_feat = tf.get_variable(name="user_feat",
                                         shape=[self.n_users, self.embed_size],
                                         initializer=tf_truncated_normal(
                                             0.0, 0.01),
                                         regularizer=self.reg)

        # weight and bias parameters for last fc_layer
        self.item_biases = tf.get_variable(
            name="item_biases",
            shape=[self.n_items],
            initializer=tf.zeros,
        )
        self.item_weights = tf.get_variable(
            name="item_weights",
            shape=[self.n_items, self.embed_size * 2],
            initializer=tf_truncated_normal(0.0, 0.02),
            regularizer=self.reg)

        # input_embed for cnn_layer, include padding value
        self.input_embed = tf.get_variable(
            name="input_embed",
            shape=[self.n_items + 1, self.embed_size],
            initializer=tf_glorot_normal,
            regularizer=self.reg)
Beispiel #2
0
    def _build_sparse(self):
        self.sparse_indices = tf.placeholder(
            tf.int32, shape=[None, self.sparse_field_size])

        linear_sparse_feat = tf.get_variable(name="linear_sparse_feat",
                                             shape=[self.sparse_feature_size],
                                             initializer=tf_truncated_normal(
                                                 0.0, 0.03),
                                             regularizer=self.reg)
        pairwise_sparse_feat = tf.get_variable(
            name="pairwise_sparse_feat",
            shape=[self.sparse_feature_size, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.03),
            regularizer=self.reg)

        if (self.data_info.multi_sparse_combine_info
                and self.multi_sparse_combiner in ("sum", "mean", "sqrtn")):
            linear_sparse_embed = multi_sparse_combine_embedding(
                self.data_info, linear_sparse_feat, self.sparse_indices,
                self.multi_sparse_combiner, 1)
            pairwise_sparse_embed = multi_sparse_combine_embedding(
                self.data_info, pairwise_sparse_feat, self.sparse_indices,
                self.multi_sparse_combiner, self.embed_size)
        else:
            linear_sparse_embed = tf.nn.embedding_lookup(  # B * F1
                linear_sparse_feat, self.sparse_indices)
            pairwise_sparse_embed = tf.nn.embedding_lookup(  # B * F1 * K
                pairwise_sparse_feat, self.sparse_indices)

        self.linear_embed.append(linear_sparse_embed)
        self.pairwise_embed.append(pairwise_sparse_embed)
Beispiel #3
0
    def _build_sparse(self):
        self.sparse_indices = tf.placeholder(
            tf.int32, shape=[None, self.sparse_field_size])

        wide_sparse_feat = tf.get_variable(name="wide_sparse_feat",
                                           shape=[self.sparse_feature_size],
                                           initializer=tf_truncated_normal(
                                               0.0, 0.01),
                                           regularizer=self.reg)
        deep_sparse_feat = tf.get_variable(
            name="deep_sparse_feat",
            shape=[self.sparse_feature_size, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)

        if (self.data_info.multi_sparse_combine_info
                and self.multi_sparse_combiner in ("sum", "mean", "sqrtn")):
            wide_sparse_embed = multi_sparse_combine_embedding(
                self.data_info, wide_sparse_feat, self.sparse_indices,
                self.multi_sparse_combiner, 1)
            deep_sparse_embed = multi_sparse_combine_embedding(
                self.data_info, deep_sparse_feat, self.sparse_indices,
                self.multi_sparse_combiner, self.embed_size)
        else:
            wide_sparse_embed = tf.nn.embedding_lookup(wide_sparse_feat,
                                                       self.sparse_indices)
            deep_sparse_embed = tf.nn.embedding_lookup(deep_sparse_feat,
                                                       self.sparse_indices)

        deep_sparse_embed = tf.reshape(
            deep_sparse_embed,
            [-1, self.true_sparse_field_size * self.embed_size])
        self.wide_embed.append(wide_sparse_embed)
        self.deep_embed.append(deep_sparse_embed)
Beispiel #4
0
    def _build_sparse(self):
        self.sparse_indices = tf.placeholder(
            tf.int32, shape=[None, self.sparse_field_size])

        linear_sparse_feat = tf.get_variable(
            name="linear_sparse_feat",
            shape=[self.sparse_feature_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)
        embed_sparse_feat = tf.get_variable(
            name="embed_sparse_feat",
            shape=[self.sparse_feature_size, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)

        linear_sparse_embed = tf.nn.embedding_lookup(    # B * F1
            linear_sparse_feat, self.sparse_indices)
        pairwise_sparse_embed = tf.nn.embedding_lookup(  # B * F1 * K
            embed_sparse_feat, self.sparse_indices)
        deep_sparse_embed = tf.reshape(
            pairwise_sparse_embed,
            [-1, self.sparse_field_size * self.embed_size]
        )
        self.linear_embed.append(linear_sparse_embed)
        self.pairwise_embed.append(pairwise_sparse_embed)
        self.deep_embed.append(deep_sparse_embed)
Beispiel #5
0
    def _build_model(self):
        self.graph_built = True
        self.user_indices = tf.placeholder(tf.int32, shape=[None])
        self.item_indices = tf.placeholder(tf.int32, shape=[None])
        self.labels = tf.placeholder(tf.float32, shape=[None])

        self.bu_var = tf.get_variable(name="bu_var", shape=[self.n_users + 1],
                                      initializer=tf_zeros,
                                      regularizer=self.reg)
        self.bi_var = tf.get_variable(name="bi_var", shape=[self.n_items + 1],
                                      initializer=tf_zeros,
                                      regularizer=self.reg)
        self.pu_var = tf.get_variable(name="pu_var",
                                      shape=[self.n_users + 1, self.embed_size],
                                      initializer=tf_truncated_normal(
                                          0.0, 0.05),
                                      regularizer=self.reg)
        self.qi_var = tf.get_variable(name="qi_var",
                                      shape=[self.n_items + 1, self.embed_size],
                                      initializer=tf_truncated_normal(
                                          0.0, 0.05),
                                      regularizer=self.reg)

        bias_user = tf.nn.embedding_lookup(self.bu_var, self.user_indices)
        bias_item = tf.nn.embedding_lookup(self.bi_var, self.item_indices)
        embed_user = tf.nn.embedding_lookup(self.pu_var, self.user_indices)
        embed_item = tf.nn.embedding_lookup(self.qi_var, self.item_indices)

        self.output = bias_user + bias_item + tf.reduce_sum(
            tf.multiply(embed_user, embed_item), axis=1)
Beispiel #6
0
    def _build_dense(self):
        self.dense_values = tf.placeholder(tf.float32,
                                           shape=[None, self.dense_field_size])
        dense_values_reshape = tf.reshape(self.dense_values,
                                          [-1, self.dense_field_size, 1])
        batch_size = tf.shape(self.dense_values)[0]

        linear_dense_feat = tf.get_variable(name="linear_dense_feat",
                                            shape=[self.dense_field_size],
                                            initializer=tf_truncated_normal(
                                                0.0, 0.03),
                                            regularizer=self.reg)
        pairwise_dense_feat = tf.get_variable(
            name="pairwise_dense_feat",
            shape=[self.dense_field_size, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.03),
            regularizer=self.reg)

        # B * F2
        linear_dense_embed = tf.tile(linear_dense_feat, [batch_size])
        linear_dense_embed = tf.reshape(linear_dense_embed,
                                        [-1, self.dense_field_size])
        linear_dense_embed = tf.multiply(linear_dense_embed, self.dense_values)

        pairwise_dense_embed = tf.expand_dims(pairwise_dense_feat, axis=0)
        # B * F2 * K
        pairwise_dense_embed = tf.tile(pairwise_dense_embed,
                                       [batch_size, 1, 1])
        pairwise_dense_embed = tf.multiply(pairwise_dense_embed,
                                           dense_values_reshape)

        self.linear_embed.append(linear_dense_embed)
        self.pairwise_embed.append(pairwise_dense_embed)
Beispiel #7
0
    def _build_dense(self):
        self.dense_values = tf.placeholder(tf.float32,
                                           shape=[None, self.dense_field_size])
        dense_values_reshape = tf.reshape(self.dense_values,
                                          [-1, self.dense_field_size, 1])
        batch_size = tf.shape(self.dense_values)[0]

        wide_dense_feat = tf.get_variable(name="wide_dense_feat",
                                          shape=[self.dense_field_size],
                                          initializer=tf_truncated_normal(
                                              0.0, 0.01),
                                          regularizer=self.reg)
        deep_dense_feat = tf.get_variable(
            name="deep_dense_feat",
            shape=[self.dense_field_size, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)

        wide_dense_embed = tf.tile(wide_dense_feat, [batch_size])
        wide_dense_embed = tf.reshape(wide_dense_embed,
                                      [-1, self.dense_field_size])
        wide_dense_embed = tf.multiply(wide_dense_embed, self.dense_values)

        deep_dense_embed = tf.expand_dims(deep_dense_feat, axis=0)
        deep_dense_embed = tf.tile(deep_dense_embed, [batch_size, 1, 1])
        deep_dense_embed = tf.multiply(deep_dense_embed, dense_values_reshape)
        deep_dense_embed = tf.reshape(
            deep_dense_embed, [-1, self.dense_field_size * self.embed_size])
        self.wide_embed.append(wide_dense_embed)
        self.deep_embed.append(deep_dense_embed)
Beispiel #8
0
    def _build_model(self):
        self.graph_built = True
        tf.set_random_seed(self.seed)
        self.user_indices = tf.placeholder(tf.int32, shape=[None])
        self.item_indices = tf.placeholder(tf.int32, shape=[None])
        self.user_interacted_seq = tf.placeholder(
            tf.int32, shape=[None, self.interaction_num])
        self.user_interacted_len = tf.placeholder(tf.float32, shape=[None])
        self.labels = tf.placeholder(tf.float32, shape=[None])
        self.is_training = tf.placeholder_with_default(False, shape=[])
        self.concat_embed = []

        user_features = tf.get_variable(
            name="user_features",
            shape=[self.n_users + 1, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)
        item_features = tf.get_variable(
            name="item_features",
            shape=[self.n_items + 1, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)
        user_embed = tf.nn.embedding_lookup(user_features, self.user_indices)
        item_embed = tf.nn.embedding_lookup(item_features, self.item_indices)

        # unknown items are padded to 0-vector
        zero_padding_op = tf.scatter_update(
            item_features, self.n_items,
            tf.zeros([self.embed_size], dtype=tf.float32))
        with tf.control_dependencies([zero_padding_op]):
            multi_item_embed = tf.nn.embedding_lookup(
                item_features, self.user_interacted_seq)  # B * seq * K
        pooled_embed = tf.div_no_nan(
            tf.reduce_sum(multi_item_embed, axis=1),
            tf.expand_dims(tf.sqrt(self.user_interacted_len), axis=1))
        self.concat_embed.extend([user_embed, item_embed, pooled_embed])

        if self.sparse:
            self._build_sparse()
        if self.dense:
            self._build_dense()

        concat_embed = tf.concat(self.concat_embed, axis=1)
        mlp_layer = dense_nn(concat_embed,
                             self.hidden_units,
                             use_bn=self.use_bn,
                             dropout_rate=self.dropout_rate,
                             is_training=self.is_training)
        self.output = tf.reshape(tf.layers.dense(inputs=mlp_layer, units=1),
                                 [-1])
        count_params()
Beispiel #9
0
    def _build_model(self, sparse_implicit_interaction):
        self.graph_built = True
        self.user_indices = tf.placeholder(tf.int32, shape=[None])
        self.item_indices = tf.placeholder(tf.int32, shape=[None])
        self.labels = tf.placeholder(tf.float32, shape=[None])

        self.bu_var = tf.get_variable(name="bu_var",
                                      shape=[self.n_users],
                                      initializer=tf_zeros,
                                      regularizer=self.reg)
        self.bi_var = tf.get_variable(name="bi_var",
                                      shape=[self.n_items],
                                      initializer=tf_zeros,
                                      regularizer=self.reg)
        self.pu_var = tf.get_variable(name="pu_var",
                                      shape=[self.n_users, self.embed_size],
                                      initializer=tf_truncated_normal(
                                          0.0, 0.03),
                                      regularizer=self.reg)
        self.qi_var = tf.get_variable(name="qi_var",
                                      shape=[self.n_items, self.embed_size],
                                      initializer=tf_truncated_normal(
                                          0.0, 0.03),
                                      regularizer=self.reg)

        yj_var = tf.get_variable(name="yj_var",
                                 shape=[self.n_items, self.embed_size],
                                 initializer=tf_truncated_normal(0.0, 0.03),
                                 regularizer=self.reg)

        uj = tf.nn.safe_embedding_lookup_sparse(
            yj_var,
            sparse_implicit_interaction,
            sparse_weights=None,
            combiner="sqrtn",
            default_id=None)  # unknown user will return 0-vector
        self.puj_var = self.pu_var + uj

        bias_user = tf.nn.embedding_lookup(self.bu_var, self.user_indices)
        bias_item = tf.nn.embedding_lookup(self.bi_var, self.item_indices)
        embed_user = tf.nn.embedding_lookup(self.puj_var, self.user_indices)
        embed_item = tf.nn.embedding_lookup(self.qi_var, self.item_indices)

        self.output = bias_user + bias_item + tf.reduce_sum(
            tf.multiply(embed_user, embed_item), axis=1)
Beispiel #10
0
    def _build_user_item(self):
        self.user_indices = tf.placeholder(tf.int32, shape=[None])
        self.item_indices = tf.placeholder(tf.int32, shape=[None])

        linear_user_feat = tf.get_variable(
            name="linear_user_feat",
            shape=[self.n_users + 1, 1],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)
        linear_item_feat = tf.get_variable(
            name="linear_item_feat",
            shape=[self.n_items + 1, 1],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)
        embed_user_feat = tf.get_variable(
            name="embed_user_feat",
            shape=[self.n_users + 1, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)
        embed_item_feat = tf.get_variable(
            name="embed_item_feat",
            shape=[self.n_items + 1, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)

        linear_user_embed = tf.nn.embedding_lookup(linear_user_feat,
                                                   self.user_indices)
        linear_item_embed = tf.nn.embedding_lookup(linear_item_feat,
                                                   self.item_indices)
        self.linear_embed.extend([linear_user_embed, linear_item_embed])

        pairwise_user_embed = tf.expand_dims(
            tf.nn.embedding_lookup(embed_user_feat, self.user_indices),
            axis=1)
        pairwise_item_embed = tf.expand_dims(
            tf.nn.embedding_lookup(embed_item_feat, self.item_indices),
            axis=1)
        self.pairwise_embed.extend([pairwise_user_embed, pairwise_item_embed])

        deep_user_embed = tf.nn.embedding_lookup(embed_user_feat,
                                                 self.user_indices)
        deep_item_embed = tf.nn.embedding_lookup(embed_item_feat,
                                                 self.item_indices)
        self.deep_embed.extend([deep_user_embed, deep_item_embed])
    def _build_train_ops(self, global_steps=None):
        self.nce_weights = tf.get_variable(
            name="nce_weights",
            # n_classes, embed_size
            shape=[self.n_items, self.user_vector_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg
        )
        self.nce_biases = tf.get_variable(
            name="nce_biases",
            shape=[self.n_items],
            initializer=tf_zeros,
            regularizer=self.reg,
            trainable=True
        )

        if self.loss_type == "nce":
            self.loss = tf.reduce_mean(tf.nn.nce_loss(
                weights=self.nce_weights,
                biases=self.nce_biases,
                labels=tf.reshape(self.item_indices, [-1, 1]),
                inputs=self.user_vector_repr,
                num_sampled=self.num_neg,
                num_classes=self.n_items,
                num_true=1,
                remove_accidental_hits=True,
                partition_strategy="div")
            )
        elif self.loss_type == "sampled_softmax":
            self.loss = tf.reduce_mean(tf.nn.sampled_softmax_loss(
                weights=self.nce_weights,
                biases=self.nce_biases,
                labels=tf.reshape(self.item_indices, [-1, 1]),
                inputs=self.user_vector_repr,
                num_sampled=self.num_neg,
                num_classes=self.n_items,
                num_true=1,
                remove_accidental_hits=True,
                seed=self.seed,
                partition_strategy="div")
            )
        else:
            raise ValueError("Loss type must either be 'nce' "
                             "or 'sampled_softmax")

        if self.reg is not None:
            reg_keys = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
            total_loss = self.loss + tf.add_n(reg_keys)
        else:
            total_loss = self.loss

        optimizer = tf.train.AdamOptimizer(self.lr)
        optimizer_op = optimizer.minimize(total_loss, global_step=global_steps)
        update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
        self.training_op = tf.group([optimizer_op, update_ops])
        self.sess.run(tf.global_variables_initializer())
Beispiel #12
0
    def _build_model_tf(self):
        self.graph_built = True
        if isinstance(self.reg, float) and self.reg > 0.0:
            tf_reg = tf.keras.regularizers.l2(self.reg)
        else:
            tf_reg = None

        self.user_indices = tf.placeholder(tf.int32, shape=[None])
        self.item_indices_pos = tf.placeholder(tf.int32, shape=[None])
        self.item_indices_neg = tf.placeholder(tf.int32, shape=[None])

        self.item_bias_var = tf.get_variable(name="item_bias_var",
                                             shape=[self.n_items + 1],
                                             initializer=tf_zeros,
                                             regularizer=tf_reg)
        self.user_embed_var = tf.get_variable(
            name="user_embed_var",
            shape=[self.n_users + 1, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.03),
            regularizer=tf_reg)
        self.item_embed_var = tf.get_variable(
            name="item_embed_var",
            shape=[self.n_items + 1, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.03),
            regularizer=tf_reg)

        bias_item_pos = tf.nn.embedding_lookup(self.item_bias_var,
                                               self.item_indices_pos)
        bias_item_neg = tf.nn.embedding_lookup(self.item_bias_var,
                                               self.item_indices_neg)
        embed_user = tf.nn.embedding_lookup(self.user_embed_var,
                                            self.user_indices)
        embed_item_pos = tf.nn.embedding_lookup(self.item_embed_var,
                                                self.item_indices_pos)
        embed_item_neg = tf.nn.embedding_lookup(self.item_embed_var,
                                                self.item_indices_neg)

        item_diff = tf.subtract(
            bias_item_pos, bias_item_neg) + tf.reduce_sum(tf.multiply(
                embed_user, tf.subtract(embed_item_pos, embed_item_neg)),
                                                          axis=1)
        self.log_sigmoid = tf.log_sigmoid(item_diff)
Beispiel #13
0
    def _build_model(self):
        self.graph_built = True
        self.user_indices = tf.placeholder(tf.int32, shape=[None])
        self.item_indices = tf.placeholder(tf.int32, shape=[None])
        self.labels = tf.placeholder(tf.float32, shape=[None])
        self.is_training = tf.placeholder_with_default(False, shape=[])

        user_gmf = tf.get_variable(name="user_gmf",
                                   shape=[self.n_users + 1, self.embed_size],
                                   initializer=tf_truncated_normal(0.0, 0.01),
                                   regularizer=self.reg)
        item_gmf = tf.get_variable(name="item_gmf",
                                   shape=[self.n_items + 1, self.embed_size],
                                   initializer=tf_truncated_normal(0.0, 0.01),
                                   regularizer=self.reg)
        user_mlp = tf.get_variable(name="user_mlp",
                                   shape=[self.n_users + 1, self.embed_size],
                                   initializer=tf_truncated_normal(0.0, 0.01),
                                   regularizer=self.reg)
        item_mlp = tf.get_variable(name="item_mlp",
                                   shape=[self.n_items + 1, self.embed_size],
                                   initializer=tf_truncated_normal(0.0, 0.01),
                                   regularizer=self.reg)

        user_gmf_embed = tf.nn.embedding_lookup(user_gmf, self.user_indices)
        item_gmf_embed = tf.nn.embedding_lookup(item_gmf, self.item_indices)
        user_mlp_embed = tf.nn.embedding_lookup(user_mlp, self.user_indices)
        item_mlp_embed = tf.nn.embedding_lookup(item_mlp, self.item_indices)

        gmf_layer = tf.multiply(user_gmf_embed, item_gmf_embed)
        mlp_input = tf.concat([user_mlp_embed, item_mlp_embed], axis=1)
        mlp_layer = dense_nn(mlp_input,
                             self.hidden_units,
                             use_bn=self.use_bn,
                             dropout_rate=self.dropout_rate,
                             is_training=self.is_training)

        concat_layer = tf.concat([gmf_layer, mlp_layer], axis=1)
        self.output = tf.reshape(tf.layers.dense(inputs=concat_layer, units=1),
                                 [-1])
Beispiel #14
0
 def _build_variables(self):
     self.user_feat = tf.get_variable(
         name="user_feat",
         shape=[self.n_users + 1, self.embed_size],
         initializer=tf_truncated_normal(0.0, 0.01),
         regularizer=self.reg)
     self.item_feat = tf.get_variable(
         name="item_feat",
         shape=[self.n_items + 1, self.embed_size],
         initializer=tf_truncated_normal(0.0, 0.01),
         regularizer=self.reg)
     if self.sparse:
         self.sparse_feat = tf.get_variable(
             name="sparse_feat",
             shape=[self.sparse_feature_size, self.embed_size],
             initializer=tf_truncated_normal(0.0, 0.01),
             regularizer=self.reg)
     if self.dense:
         self.dense_feat = tf.get_variable(
             name="dense_feat",
             shape=[self.dense_field_size, self.embed_size],
             initializer=tf_truncated_normal(0.0, 0.01),
             regularizer=self.reg)
    def _build_sparse(self):
        self.sparse_indices = tf.placeholder(
            tf.int32, shape=[None, self.sparse_field_size])
        sparse_features = tf.get_variable(
            name="sparse_features",
            shape=[self.sparse_feature_size, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)

        sparse_embed = tf.nn.embedding_lookup(sparse_features,
                                              self.sparse_indices)
        sparse_embed = tf.reshape(
            sparse_embed, [-1, self.sparse_field_size * self.embed_size])
        self.concat_embed.append(sparse_embed)
Beispiel #16
0
    def _build_sparse(self):
        self.sparse_indices = tf.placeholder(
            tf.int32, shape=[None, self.sparse_field_size])

        wide_sparse_feat = tf.get_variable(name="wide_sparse_feat",
                                           shape=[self.sparse_feature_size],
                                           initializer=tf_truncated_normal(
                                               0.0, 0.01),
                                           regularizer=self.reg)
        deep_sparse_feat = tf.get_variable(
            name="deep_sparse_feat",
            shape=[self.sparse_feature_size, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)

        wide_sparse_embed = tf.nn.embedding_lookup(wide_sparse_feat,
                                                   self.sparse_indices)
        deep_sparse_embed = tf.nn.embedding_lookup(deep_sparse_feat,
                                                   self.sparse_indices)
        deep_sparse_embed = tf.reshape(
            deep_sparse_embed, [-1, self.sparse_field_size * self.embed_size])
        self.wide_embed.append(wide_sparse_embed)
        self.deep_embed.append(deep_sparse_embed)
Beispiel #17
0
    def _build_user_item(self):
        self.user_indices = tf.placeholder(tf.int32, shape=[None])
        self.item_indices = tf.placeholder(tf.int32, shape=[None])

        wide_user_feat = tf.get_variable(name="wide_user_feat",
                                         shape=[self.n_users, 1],
                                         initializer=tf_truncated_normal(
                                             0.0, 0.01),
                                         regularizer=self.reg)
        wide_item_feat = tf.get_variable(name="wide_item_feat",
                                         shape=[self.n_items, 1],
                                         initializer=tf_truncated_normal(
                                             0.0, 0.01),
                                         regularizer=self.reg)
        deep_user_feat = tf.get_variable(name="deep_user_feat",
                                         shape=[self.n_users, self.embed_size],
                                         initializer=tf_truncated_normal(
                                             0.0, 0.01),
                                         regularizer=self.reg)
        deep_item_feat = tf.get_variable(name="deep_item_feat",
                                         shape=[self.n_items, self.embed_size],
                                         initializer=tf_truncated_normal(
                                             0.0, 0.01),
                                         regularizer=self.reg)

        wide_user_embed = tf.nn.embedding_lookup(wide_user_feat,
                                                 self.user_indices)
        wide_item_embed = tf.nn.embedding_lookup(wide_item_feat,
                                                 self.item_indices)
        self.wide_embed.extend([wide_user_embed, wide_item_embed])

        deep_user_embed = tf.nn.embedding_lookup(deep_user_feat,
                                                 self.user_indices)
        deep_item_embed = tf.nn.embedding_lookup(deep_item_feat,
                                                 self.item_indices)
        self.deep_embed.extend([deep_user_embed, deep_item_embed])
    def _build_dense(self):
        self.dense_values = tf.placeholder(tf.float32,
                                           shape=[None, self.dense_field_size])
        dense_values_reshape = tf.reshape(self.dense_values,
                                          [-1, self.dense_field_size, 1])
        batch_size = tf.shape(self.dense_values)[0]

        dense_features = tf.get_variable(
            name="dense_features",
            shape=[self.dense_field_size, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)

        dense_embed = tf.tile(dense_features, [batch_size, 1])
        dense_embed = tf.reshape(dense_embed,
                                 [-1, self.dense_field_size, self.embed_size])
        dense_embed = tf.multiply(dense_embed, dense_values_reshape)
        dense_embed = tf.reshape(dense_embed,
                                 [-1, self.dense_field_size * self.embed_size])
        self.concat_embed.append(dense_embed)
    def _build_item_interaction(self):
        self.item_interaction_indices = tf.placeholder(
            tf.int64, shape=[None, 2])
        self.item_interaction_values = tf.placeholder(tf.int32, shape=[None])
        self.modified_batch_size = tf.placeholder(tf.int32, shape=[])

        item_interaction_features = tf.get_variable(
            name="item_interaction_features",
            shape=[self.n_items, self.embed_size],
            initializer=tf_truncated_normal(0.0, 0.01),
            regularizer=self.reg)

        sparse_item_interaction = tf.SparseTensor(
            self.item_interaction_indices,
            self.item_interaction_values,
            [self.modified_batch_size, self.n_items]
        )
        pooled_embed = tf.nn.safe_embedding_lookup_sparse(
            item_interaction_features, sparse_item_interaction,
            sparse_weights=None, combiner="sqrtn", default_id=None
        )  # unknown user will return 0-vector
        self.concat_embed.append(pooled_embed)