From 5ce6f2f843706c09b25fe998916de69ce9b9dd34 Mon Sep 17 00:00:00 2001 From: yuyinxiao Date: Thu, 23 Jun 2022 12:11:16 +0800 Subject: [PATCH 1/6] =?UTF-8?q?CAN:=20Feature=20Co-Action=20for=20Click-Th?= =?UTF-8?q?rough=20Rate=20Prediction=20=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 向量网络化交互模型,仅实现Layer,暂未实现estimator --- deepctr/layers/__init__.py | 2 +- deepctr/layers/interaction.py | 81 ++++++++++++++++++++++++++++++++ deepctr/models/__init__.py | 5 +- deepctr/models/can.py | 46 ++++++++++++++++++ examples/run_can.py | 70 +++++++++++++++++++++++++++ tests/layers/interaction_test.py | 5 ++ 6 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 deepctr/models/can.py create mode 100644 examples/run_can.py diff --git a/deepctr/layers/__init__.py b/deepctr/layers/__init__.py index 1bfd40ef..2e32e551 100644 --- a/deepctr/layers/__init__.py +++ b/deepctr/layers/__init__.py @@ -5,7 +5,7 @@ from .interaction import (CIN, FM, AFMLayer, BiInteractionPooling, CrossNet, CrossNetMix, InnerProductLayer, InteractingLayer, OutterProductLayer, FGCNNLayer, SENETLayer, BilinearInteraction, - FieldWiseBiInteraction, FwFMLayer, FEFMLayer) + FieldWiseBiInteraction, FwFMLayer, FEFMLayer, CoActionLayer) from .normalization import LayerNormalization from .sequence import (AttentionSequencePoolingLayer, BiasEncoding, BiLSTM, KMaxPooling, SequencePoolingLayer, WeightedSequenceLayer, diff --git a/deepctr/layers/interaction.py b/deepctr/layers/interaction.py index d26eb2c1..49c54ff9 100644 --- a/deepctr/layers/interaction.py +++ b/deepctr/layers/interaction.py @@ -1489,3 +1489,84 @@ def get_config(self): 'regularizer': self.regularizer, }) return config + +class CoActionLayer(Layer): + """ + build co-action output for target item(type) and user pref seq item(type) + Input shape + - 3D tensor with shape: ``(batch_size,field_size,embedding_size)``. + + Output shape + - 2D tensor with shape: ``(batch_size, 2nd_mlp_dims)``. + + References + - [CAN: Feature Co-Action for Click-Through Rate Prediction](https://arxiv.org/abs/2011.05625) + """ + + def __init__(self, target_input, co_action_config, name, **kwargs): + + self._target_input = target_input + self._co_action_config = co_action_config + self._name = name + self._weight_orders, self._bias_orders = self._build_mlp() + + super(CoActionLayer, self).__init__(**kwargs) + + def build(self, input_shape): + if len(input_shape) != 3: + raise ValueError("Unexpected inputs dimensions % d,\ + expect to be 3 dimensions" % (len(input_shape))) + + super(CoActionLayer, self).build(input_shape) # Be sure to call this somewhere! + + def build_mlp(self): + target_emb = tf.reduce_sum(self._target_input, axis=1) # avoid target varlength + weight_orders, bias_orders = [], [] + idx = 0 + for i in range(self._co_action_config['orders']): + weight, bias = [], [] + for w, b in zip(self._co_action_config['target_emb_w'], self._co_action_config['target_emb_b']): + weight.append(tf.reshape(target_emb[:, idx:idx + w[0] * w[1]], [-1, w[0], w[1]])) + idx += w[0] * w[1] + if b == 0: + bias.append(None) + else: + bias.append(tf.reshape(target_emb[:, idx:idx + b], [-1, 1, b])) + idx += b + weight_orders.append(weight) + bias_orders.append(bias) + if not self._co_action_config['indep_action']: + break + return weight_orders, bias_orders + + def co_action_op(self, hist_pref_seq, mask=None): + inputs = [] + for i in range(self._co_action_config['orders']): + inputs.append(tf.math.pow(hist_pref_seq, i + 1.0)) + out_seq = [] + for i, h in enumerate(inputs): + if self._co_action_config['indep_action']: + weight, bias = self._weight_orders[i], self._bias_orders[i] + else: + weight, bias = self._weight_orders[i], self._bias_orders[i] + for j, (w, b) in enumerate(zip(weight, bias)): + h = tf.matmul(h, w) + if b is not None: + h = h + b + if j != len(weight) - 1: + h = tf.nn.tanh(h) + out_seq.append(h) + out_seq = tf.concat(out_seq, 2) + if mask is not None: + mask = tf.expand_dims(mask, axis=-1) + out_seq = out_seq * mask + out = tf.reduce_sum(out_seq, 1) + return out + + def call(self, inputs, **kwargs): + mask = tf.where(tf.sequence_mask(inputs, tf.shape(inputs)[1]), 1.0, 0.0) + result = self.co_action_op(inputs, mask) + return result + + def compute_output_shape(self, input_shape): + return (None, 1) diff --git a/deepctr/models/__init__.py b/deepctr/models/__init__.py index 2d19714b..d3c35ee3 100644 --- a/deepctr/models/__init__.py +++ b/deepctr/models/__init__.py @@ -16,11 +16,12 @@ from .multitask import SharedBottom, ESMM, MMOE, PLE from .nfm import NFM from .onn import ONN +from .can import CAN from .pnn import PNN from .sequence import DIN, DIEN, DSIN, BST from .wdl import WDL from .xdeepfm import xDeepFM -__all__ = ["AFM", "CCPM", "DCN", "IFM", "DIFM", "DCNMix", "MLR", "DeepFM", "MLR", "NFM", "DIN", "DIEN", "FNN", "PNN", - "WDL", "xDeepFM", "AutoInt", "ONN", "FGCNN", "DSIN", "FiBiNET", 'FLEN', "FwFM", "BST", "DeepFEFM", +__all__ = ["AFM", "CCPM", "DCN", "IFM", "DIFM", "DCNMix", "MLR", "DeepFM", "MLR", "NFM", "DIN", "DIEN", "FNN", 'CAN', + "PNN", "WDL", "xDeepFM", "AutoInt", "ONN", "FGCNN", "DSIN", "FiBiNET", 'FLEN', "FwFM", "BST", "DeepFEFM", "SharedBottom", "ESMM", "MMOE", "PLE"] diff --git a/deepctr/models/can.py b/deepctr/models/can.py new file mode 100644 index 00000000..7a43ae30 --- /dev/null +++ b/deepctr/models/can.py @@ -0,0 +1,46 @@ +# -*- coding:utf-8 -*- +""" + +Author: + Weichen Shen, weichenswc@163.com + +Reference: + [1] Xiao J, Ye H, He X, et al. Attentional factorization machines: Learning the weight of feature interactions via attention networks[J]. arXiv preprint arXiv:1708.04617, 2017. + (https://arxiv.org/abs/1708.04617) + +""" +from tensorflow.python.keras.models import Model +from tensorflow.python.keras.layers import Dense +from ..feature_column import build_input_features, get_linear_logit, DEFAULT_GROUP_NAME, input_from_feature_columns +from ..layers.core import PredictionLayer +from ..layers.interaction import CoActionLayer +from ..layers.utils import concat_func, add_func + +def CAN(dnn_feature_columns, co_action_config, l2_reg_embedding=1e-5, seed=1024, task='binary'): + """Instantiates the CAN architecture. + + :param dnn_feature_columns: An iterable containing all the features used by deep part of the model. + :param co_action_config: A dict containing the bindings with all the features(target, hist_pref_seq) . + :param l2_reg_embedding: float. L2 regularizer strength applied to embedding vector + :param seed: integer ,to use as random seed. + :param task: str, ``"binary"`` for binary logloss or ``"regression"`` for regression loss + :return: A Keras model instance. + """ + + features = build_input_features(dnn_feature_columns) + inputs_list = list(features.values()) + group_embedding_dict, _ = input_from_feature_columns(features, dnn_feature_columns, l2_reg_embedding, + seed, prefix='', support_dense=False, support_group=True) + + # co-action for target type with multi hist pref seq + can_output_list = [] + for conf in co_action_config: + cur_can_layer = CoActionLayer(group_embedding_dict[conf['target']], conf['co_action_conf'], name=conf['name']) + for his_pref_seq in conf['pref_seq']: + can_output_list.append(cur_can_layer(group_embedding_dict[his_pref_seq])) + + can_output = concat_func(can_output_list) + final_logit = Dense(1, use_bias=False)(can_output) + output = PredictionLayer(task)(final_logit) + model = Model(inputs=inputs_list, outputs=output) + return model diff --git a/examples/run_can.py b/examples/run_can.py new file mode 100644 index 00000000..d83873b9 --- /dev/null +++ b/examples/run_can.py @@ -0,0 +1,70 @@ +import numpy as np + +from deepctr.models import CAN +from deepctr.feature_column import SparseFeat, VarLenSparseFeat, DenseFeat, get_feature_names + + +def get_xy_fd(): + feature_columns = [SparseFeat('user', 3, embedding_dim=10), + SparseFeat('gender', 2, embedding_dim=4), + # target emb size: sum([w[0] * w[1] for w in can_config['target_emb_w']]) + sum(can_config['target_emb_b']) + SparseFeat('item_id', 3 + 1, embedding_dim=160), + SparseFeat('cate_id', 2 + 1, embedding_dim=160), DenseFeat('pay_score', 1)] + feature_columns += [ + # hist pref seq emb size : can_config['target_emb_w'][0][0], + VarLenSparseFeat(SparseFeat('hist_item_id', vocabulary_size=3 + 1, embedding_dim=16), + maxlen=4, length_name="seq_length"), + VarLenSparseFeat(SparseFeat('hist_cate_id', 2 + 1, embedding_dim=16), maxlen=4, + length_name="seq_length")] + # Notice: History behavior sequence feature name must start with "hist_". + behavior_feature_list = ["item_id", "cate_id"] + uid = np.array([0, 1, 2]) + ugender = np.array([0, 1, 0]) + iid = np.array([1, 2, 3]) # 0 is mask value + cate_id = np.array([1, 2, 2]) # 0 is mask value + pay_score = np.array([0.1, 0.2, 0.3]) + + hist_iid = np.array([[1, 2, 3, 0], [3, 2, 1, 0], [1, 2, 0, 0]]) + hist_cate_id = np.array([[1, 2, 2, 0], [2, 2, 1, 0], [1, 2, 0, 0]]) + seq_length = np.array([3, 3, 2]) # the actual length of the behavior sequence + + feature_dict = {'user': uid, 'gender': ugender, 'item_id': iid, 'cate_id': cate_id, + 'hist_item_id': hist_iid, 'hist_cate_id': hist_cate_id, + 'pay_score': pay_score, 'seq_length': seq_length} + x = {name: feature_dict[name] for name in get_feature_names(feature_columns)} + y = np.array([1, 0, 1]) + return x, y, feature_columns, behavior_feature_list + + +if __name__ == "__main__": + x, y, feature_columns, behavior_feature_list = get_xy_fd() + + co_action_config = [ + { + 'name': 'co_action_for_item', + 'target': 'item_id', # target emb need to reshape + 'pref_seq': ['hist_item_id', ], # seq emb need to co-action + 'co_action_conf': { + 'target_emb_w': [[16, 8], [8, 4]], + 'target_emb_b': [0, 0], + 'indep_action': False, + 'orders': 3, # exp non_linear trans + } + }, + { + 'name': 'co_action_for_cate', + 'target': 'cate_id', + 'pref_seq': ['hist_cate_id', ], + 'co_action_conf': { + 'target_emb_w': [[16, 8], [8, 4]], + 'target_emb_b': [0, 0], + 'indep_action': False, + 'orders': 3, # exp non_linear trans + } + } + ] + + model = CAN(feature_columns, co_action_config=co_action_config) + model.compile('adam', 'binary_crossentropy', + metrics=['binary_crossentropy']) + history = model.fit(x, y, verbose=1, epochs=10, validation_split=0.5) diff --git a/tests/layers/interaction_test.py b/tests/layers/interaction_test.py index 5f162f42..7910975a 100644 --- a/tests/layers/interaction_test.py +++ b/tests/layers/interaction_test.py @@ -147,3 +147,8 @@ def test_BilinearInteraction(bilinear_type): with CustomObjectScope({'BilinearInteraction': layers.BilinearInteraction}): layer_test(layers.BilinearInteraction, kwargs={'bilinear_type': bilinear_type}, input_shape=[( BATCH_SIZE, 1, EMBEDDING_SIZE)] * FIELD_SIZE) + +def test_CAN(): + with CustomObjectScope({'CAN': layers.CoActionLayer}): + layer_test(layers.CoActionLayer, kwargs={}, input_shape=( + BATCH_SIZE, FIELD_SIZE, EMBEDDING_SIZE)) \ No newline at end of file From d94e98d23358a129fb818a01e1f7bf50b78efccb Mon Sep 17 00:00:00 2001 From: yuyinxiao Date: Thu, 23 Jun 2022 14:52:51 +0800 Subject: [PATCH 2/6] fix --- deepctr/feature_column.py | 16 ++++++++++++++++ deepctr/layers/interaction.py | 7 +++---- deepctr/models/can.py | 14 ++++++++------ examples/run_can.py | 35 +++++++++++++++++------------------ 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/deepctr/feature_column.py b/deepctr/feature_column.py index 6f277ba1..a4ed4d55 100644 --- a/deepctr/feature_column.py +++ b/deepctr/feature_column.py @@ -212,3 +212,19 @@ def input_from_feature_columns(features, feature_columns, l2_reg, seed, prefix=' if not support_group: group_embedding_dict = list(chain.from_iterable(group_embedding_dict.values())) return group_embedding_dict, dense_value_list + + +def input_from_seq_feature_columns(features, feature_columns, l2_reg, seed, prefix='', seq_mask_zero=True, + support_dense=True): + + varlen_sparse_feature_columns = list( + filter(lambda x: isinstance(x, VarLenSparseFeat), feature_columns)) if feature_columns else [] + + embedding_matrix_dict = create_embedding_matrix(feature_columns, l2_reg, seed, prefix=prefix, + seq_mask_zero=seq_mask_zero) + dense_value_list = get_dense_input(features, feature_columns) + if not support_dense and len(dense_value_list) > 0: + raise ValueError("DenseFeat is not supported in dnn_feature_columns") + + sequence_embed_dict = varlen_embedding_lookup(embedding_matrix_dict, features, varlen_sparse_feature_columns) + return sequence_embed_dict, dense_value_list diff --git a/deepctr/layers/interaction.py b/deepctr/layers/interaction.py index 49c54ff9..b17f2003 100644 --- a/deepctr/layers/interaction.py +++ b/deepctr/layers/interaction.py @@ -1519,7 +1519,7 @@ def build(self, input_shape): super(CoActionLayer, self).build(input_shape) # Be sure to call this somewhere! - def build_mlp(self): + def _build_mlp(self): target_emb = tf.reduce_sum(self._target_input, axis=1) # avoid target varlength weight_orders, bias_orders = [], [] idx = 0 @@ -1548,7 +1548,7 @@ def co_action_op(self, hist_pref_seq, mask=None): if self._co_action_config['indep_action']: weight, bias = self._weight_orders[i], self._bias_orders[i] else: - weight, bias = self._weight_orders[i], self._bias_orders[i] + weight, bias = self._weight_orders[0], self._bias_orders[0] for j, (w, b) in enumerate(zip(weight, bias)): h = tf.matmul(h, w) if b is not None: @@ -1564,8 +1564,7 @@ def co_action_op(self, hist_pref_seq, mask=None): return out def call(self, inputs, **kwargs): - mask = tf.where(tf.sequence_mask(inputs, tf.shape(inputs)[1]), 1.0, 0.0) - result = self.co_action_op(inputs, mask) + result = self.co_action_op(inputs, mask=None) return result def compute_output_shape(self, input_shape): diff --git a/deepctr/models/can.py b/deepctr/models/can.py index 7a43ae30..4f76ab86 100644 --- a/deepctr/models/can.py +++ b/deepctr/models/can.py @@ -11,10 +11,10 @@ """ from tensorflow.python.keras.models import Model from tensorflow.python.keras.layers import Dense -from ..feature_column import build_input_features, get_linear_logit, DEFAULT_GROUP_NAME, input_from_feature_columns +from ..feature_column import build_input_features, input_from_seq_feature_columns from ..layers.core import PredictionLayer from ..layers.interaction import CoActionLayer -from ..layers.utils import concat_func, add_func +from ..layers.utils import concat_func def CAN(dnn_feature_columns, co_action_config, l2_reg_embedding=1e-5, seed=1024, task='binary'): """Instantiates the CAN architecture. @@ -29,15 +29,17 @@ def CAN(dnn_feature_columns, co_action_config, l2_reg_embedding=1e-5, seed=1024, features = build_input_features(dnn_feature_columns) inputs_list = list(features.values()) - group_embedding_dict, _ = input_from_feature_columns(features, dnn_feature_columns, l2_reg_embedding, - seed, prefix='', support_dense=False, support_group=True) + sequence_embed_dict, _ = input_from_seq_feature_columns(features, dnn_feature_columns, l2_reg_embedding, + seed, prefix='', support_dense=False) # co-action for target type with multi hist pref seq can_output_list = [] for conf in co_action_config: - cur_can_layer = CoActionLayer(group_embedding_dict[conf['target']], conf['co_action_conf'], name=conf['name']) + cur_can_layer = CoActionLayer(sequence_embed_dict[conf['target']], conf['co_action_conf'], name=conf['name']) + print(cur_can_layer.name) for his_pref_seq in conf['pref_seq']: - can_output_list.append(cur_can_layer(group_embedding_dict[his_pref_seq])) + can_output_list.append(cur_can_layer(sequence_embed_dict[his_pref_seq])) + print(can_output_list) can_output = concat_func(can_output_list) final_logit = Dense(1, use_bias=False)(can_output) diff --git a/examples/run_can.py b/examples/run_can.py index d83873b9..e820a678 100644 --- a/examples/run_can.py +++ b/examples/run_can.py @@ -3,34 +3,33 @@ from deepctr.models import CAN from deepctr.feature_column import SparseFeat, VarLenSparseFeat, DenseFeat, get_feature_names +import tensorflow as tf +tf.compat.v1.disable_eager_execution() def get_xy_fd(): - feature_columns = [SparseFeat('user', 3, embedding_dim=10), - SparseFeat('gender', 2, embedding_dim=4), - # target emb size: sum([w[0] * w[1] for w in can_config['target_emb_w']]) + sum(can_config['target_emb_b']) - SparseFeat('item_id', 3 + 1, embedding_dim=160), - SparseFeat('cate_id', 2 + 1, embedding_dim=160), DenseFeat('pay_score', 1)] - feature_columns += [ + + feature_columns = [ + # target emb size: sum([w[0] * w[1] for w in can_config['target_emb_w']]) + sum(can_config['target_emb_b']) + VarLenSparseFeat(SparseFeat('item_id', 3 + 1, embedding_dim=190), maxlen=1, length_name="target_length"), + VarLenSparseFeat(SparseFeat('cate_id', 2 + 1, embedding_dim=190), maxlen=2, length_name="cate_target_length"), + # hist pref seq emb size : can_config['target_emb_w'][0][0], - VarLenSparseFeat(SparseFeat('hist_item_id', vocabulary_size=3 + 1, embedding_dim=16), - maxlen=4, length_name="seq_length"), - VarLenSparseFeat(SparseFeat('hist_cate_id', 2 + 1, embedding_dim=16), maxlen=4, - length_name="seq_length")] + VarLenSparseFeat(SparseFeat('hist_item_id', 3 + 1, embedding_dim=16), maxlen=4, length_name="seq_length"), + VarLenSparseFeat(SparseFeat('hist_cate_id', 2 + 1, embedding_dim=16), maxlen=4, length_name="seq_length")] # Notice: History behavior sequence feature name must start with "hist_". behavior_feature_list = ["item_id", "cate_id"] - uid = np.array([0, 1, 2]) - ugender = np.array([0, 1, 0]) - iid = np.array([1, 2, 3]) # 0 is mask value - cate_id = np.array([1, 2, 2]) # 0 is mask value - pay_score = np.array([0.1, 0.2, 0.3]) - + iid = np.array([1, 2, 3]) # target 1 + cate_id = np.array([[1,2], [2,0], [2,0]]) # cate maybe multi hist_iid = np.array([[1, 2, 3, 0], [3, 2, 1, 0], [1, 2, 0, 0]]) hist_cate_id = np.array([[1, 2, 2, 0], [2, 2, 1, 0], [1, 2, 0, 0]]) seq_length = np.array([3, 3, 2]) # the actual length of the behavior sequence + target_length = np.array([1, 1, 1]) + cate_target_length = np.array([2, 1, 1]) - feature_dict = {'user': uid, 'gender': ugender, 'item_id': iid, 'cate_id': cate_id, + feature_dict = {'item_id': iid, 'cate_id': cate_id, 'hist_item_id': hist_iid, 'hist_cate_id': hist_cate_id, - 'pay_score': pay_score, 'seq_length': seq_length} + 'seq_length': seq_length, 'target_length': target_length, + 'cate_target_length': cate_target_length} x = {name: feature_dict[name] for name in get_feature_names(feature_columns)} y = np.array([1, 0, 1]) return x, y, feature_columns, behavior_feature_list From f7379d950ffb7cbe5b39c6da22e1a19974c5e04f Mon Sep 17 00:00:00 2001 From: yuyinxiao Date: Thu, 23 Jun 2022 14:56:47 +0800 Subject: [PATCH 3/6] fix --- deepctr/layers/interaction.py | 2 +- deepctr/models/can.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/deepctr/layers/interaction.py b/deepctr/layers/interaction.py index b17f2003..a0c6a76e 100644 --- a/deepctr/layers/interaction.py +++ b/deepctr/layers/interaction.py @@ -1507,7 +1507,7 @@ def __init__(self, target_input, co_action_config, name, **kwargs): self._target_input = target_input self._co_action_config = co_action_config - self._name = name + self._layer_name = name self._weight_orders, self._bias_orders = self._build_mlp() super(CoActionLayer, self).__init__(**kwargs) diff --git a/deepctr/models/can.py b/deepctr/models/can.py index 4f76ab86..82c23f2b 100644 --- a/deepctr/models/can.py +++ b/deepctr/models/can.py @@ -36,10 +36,9 @@ def CAN(dnn_feature_columns, co_action_config, l2_reg_embedding=1e-5, seed=1024, can_output_list = [] for conf in co_action_config: cur_can_layer = CoActionLayer(sequence_embed_dict[conf['target']], conf['co_action_conf'], name=conf['name']) - print(cur_can_layer.name) + print(cur_can_layer._layer_name) for his_pref_seq in conf['pref_seq']: can_output_list.append(cur_can_layer(sequence_embed_dict[his_pref_seq])) - print(can_output_list) can_output = concat_func(can_output_list) final_logit = Dense(1, use_bias=False)(can_output) From a52f024d078675476962345aa64c904ccfc957cb Mon Sep 17 00:00:00 2001 From: yuyinxiao Date: Thu, 23 Jun 2022 14:57:12 +0800 Subject: [PATCH 4/6] fix --- examples/run_can.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/run_can.py b/examples/run_can.py index e820a678..94f71eaa 100644 --- a/examples/run_can.py +++ b/examples/run_can.py @@ -3,8 +3,8 @@ from deepctr.models import CAN from deepctr.feature_column import SparseFeat, VarLenSparseFeat, DenseFeat, get_feature_names -import tensorflow as tf -tf.compat.v1.disable_eager_execution() +# import tensorflow as tf +# tf.compat.v1.disable_eager_execution() def get_xy_fd(): From b8e1148d3a44dced0f00ea1cd9c8c30c19306628 Mon Sep 17 00:00:00 2001 From: yuyinxiao Date: Thu, 23 Jun 2022 15:01:35 +0800 Subject: [PATCH 5/6] add some --- deepctr/models/can.py | 27 +++++++++++++++++++++++++++ examples/run_can.py | 1 + 2 files changed, 28 insertions(+) diff --git a/deepctr/models/can.py b/deepctr/models/can.py index 82c23f2b..a1a3b6e3 100644 --- a/deepctr/models/can.py +++ b/deepctr/models/can.py @@ -16,6 +16,33 @@ from ..layers.interaction import CoActionLayer from ..layers.utils import concat_func + +# template_can_config = [ +# { +# 'name': 'co_action_for_item', +# 'target': 'item_id', # target emb need to reshape +# 'pref_seq': ['hist_item_id', ], # seq emb need to co-action +# 'co_action_conf': { +# 'target_emb_w': [[16, 8], [8, 4]], +# 'target_emb_b': [0, 0], +# 'indep_action': False, +# 'orders': 3, # exp non_linear trans +# } +# }, +# { +# 'name': 'co_action_for_cate', +# 'target': 'cate_id', +# 'pref_seq': ['hist_cate_id', ], +# 'co_action_conf': { +# 'target_emb_w': [[16, 8], [8, 4]], +# 'target_emb_b': [0, 0], +# 'indep_action': False, +# 'orders': 3, # exp non_linear trans +# } +# } +# ] + + def CAN(dnn_feature_columns, co_action_config, l2_reg_embedding=1e-5, seed=1024, task='binary'): """Instantiates the CAN architecture. diff --git a/examples/run_can.py b/examples/run_can.py index 94f71eaa..ccab33de 100644 --- a/examples/run_can.py +++ b/examples/run_can.py @@ -3,6 +3,7 @@ from deepctr.models import CAN from deepctr.feature_column import SparseFeat, VarLenSparseFeat, DenseFeat, get_feature_names +# for tf2.x # import tensorflow as tf # tf.compat.v1.disable_eager_execution() From 5cac2443a550a2e919f7a442e5905ecd4d33ab88 Mon Sep 17 00:00:00 2001 From: yuyinxiao Date: Mon, 24 Oct 2022 11:23:20 +0800 Subject: [PATCH 6/6] add some --- deepctr/feature_column.py | 3 ++- examples/run_can.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/deepctr/feature_column.py b/deepctr/feature_column.py index 2e72783d..b79eda12 100644 --- a/deepctr/feature_column.py +++ b/deepctr/feature_column.py @@ -215,7 +215,7 @@ def input_from_feature_columns(features, feature_columns, l2_reg, seed, prefix=' def input_from_seq_feature_columns(features, feature_columns, l2_reg, seed, prefix='', seq_mask_zero=True, - support_dense=True): + support_dense=True, support_group=True): varlen_sparse_feature_columns = list( filter(lambda x: isinstance(x, VarLenSparseFeat), feature_columns)) if feature_columns else [] @@ -228,3 +228,4 @@ def input_from_seq_feature_columns(features, feature_columns, l2_reg, seed, pref sequence_embed_dict = varlen_embedding_lookup(embedding_matrix_dict, features, varlen_sparse_feature_columns) return sequence_embed_dict, dense_value_list + diff --git a/examples/run_can.py b/examples/run_can.py index ccab33de..4d494c64 100644 --- a/examples/run_can.py +++ b/examples/run_can.py @@ -4,8 +4,8 @@ from deepctr.feature_column import SparseFeat, VarLenSparseFeat, DenseFeat, get_feature_names # for tf2.x -# import tensorflow as tf -# tf.compat.v1.disable_eager_execution() +import tensorflow as tf +tf.compat.v1.disable_eager_execution() def get_xy_fd():