提交 66e1859f 编写于 作者: T tangwei

fix code style

上级 64dbc133
...@@ -22,4 +22,3 @@ mkdir -p data/train ...@@ -22,4 +22,3 @@ mkdir -p data/train
mkdir -p data/test mkdir -p data/test
python generate_synthetic_data.py python generate_synthetic_data.py
...@@ -18,8 +18,10 @@ from paddlerec.core.utils import envs ...@@ -18,8 +18,10 @@ from paddlerec.core.utils import envs
class EvaluateReader(Reader): class EvaluateReader(Reader):
def init(self): def init(self):
self.query_slots = envs.get_global_env("hyper_parameters.query_slots", None, "train.model") self.query_slots = envs.get_global_env("hyper_parameters.query_slots",
self.title_slots = envs.get_global_env("hyper_parameters.title_slots", None, "train.model") None, "train.model")
self.title_slots = envs.get_global_env("hyper_parameters.title_slots",
None, "train.model")
self.all_slots = [] self.all_slots = []
for i in range(self.query_slots): for i in range(self.query_slots):
......
...@@ -21,7 +21,11 @@ class Dataset: ...@@ -21,7 +21,11 @@ class Dataset:
class SyntheticDataset(Dataset): class SyntheticDataset(Dataset):
def __init__(self, sparse_feature_dim, query_slot_num, title_slot_num, dataset_size=10000): def __init__(self,
sparse_feature_dim,
query_slot_num,
title_slot_num,
dataset_size=10000):
# ids are randomly generated # ids are randomly generated
self.ids_per_slot = 10 self.ids_per_slot = 10
self.sparse_feature_dim = sparse_feature_dim self.sparse_feature_dim = sparse_feature_dim
...@@ -46,14 +50,20 @@ class SyntheticDataset(Dataset): ...@@ -46,14 +50,20 @@ class SyntheticDataset(Dataset):
for i in range(self.title_slot_num): for i in range(self.title_slot_num):
pt_slot = generate_ids(self.ids_per_slot, pt_slot = generate_ids(self.ids_per_slot,
self.sparse_feature_dim) self.sparse_feature_dim)
pt_slot = [str(fea) + ':' + str(i + self.query_slot_num) for fea in pt_slot] pt_slot = [
str(fea) + ':' + str(i + self.query_slot_num)
for fea in pt_slot
]
pos_title_slots += pt_slot pos_title_slots += pt_slot
if is_train: if is_train:
for i in range(self.title_slot_num): for i in range(self.title_slot_num):
nt_slot = generate_ids(self.ids_per_slot, nt_slot = generate_ids(self.ids_per_slot,
self.sparse_feature_dim) self.sparse_feature_dim)
nt_slot = [str(fea) + ':' + str(i + self.query_slot_num + self.title_slot_num) for fea in nt_slot = [
nt_slot] str(fea) + ':' +
str(i + self.query_slot_num + self.title_slot_num)
for fea in nt_slot
]
neg_title_slots += nt_slot neg_title_slots += nt_slot
yield query_slots + pos_title_slots + neg_title_slots yield query_slots + pos_title_slots + neg_title_slots
else: else:
...@@ -76,7 +86,8 @@ if __name__ == '__main__': ...@@ -76,7 +86,8 @@ if __name__ == '__main__':
query_slots = 1 query_slots = 1
title_slots = 1 title_slots = 1
dataset_size = 10 dataset_size = 10
dataset = SyntheticDataset(sparse_feature_dim, query_slots, title_slots, dataset_size) dataset = SyntheticDataset(sparse_feature_dim, query_slots, title_slots,
dataset_size)
train_reader = dataset.train() train_reader = dataset.train()
test_reader = dataset.test() test_reader = dataset.test()
......
...@@ -103,12 +103,18 @@ class Model(ModelBase): ...@@ -103,12 +103,18 @@ class Model(ModelBase):
def init_config(self): def init_config(self):
self._fetch_interval = 1 self._fetch_interval = 1
query_encoder = envs.get_global_env("hyper_parameters.query_encoder", None, self._namespace) query_encoder = envs.get_global_env("hyper_parameters.query_encoder",
title_encoder = envs.get_global_env("hyper_parameters.title_encoder", None, self._namespace) None, self._namespace)
query_encode_dim = envs.get_global_env("hyper_parameters.query_encode_dim", None, self._namespace) title_encoder = envs.get_global_env("hyper_parameters.title_encoder",
title_encode_dim = envs.get_global_env("hyper_parameters.title_encode_dim", None, self._namespace) None, self._namespace)
query_slots = envs.get_global_env("hyper_parameters.query_slots", None, self._namespace) query_encode_dim = envs.get_global_env(
title_slots = envs.get_global_env("hyper_parameters.title_slots", None, self._namespace) "hyper_parameters.query_encode_dim", None, self._namespace)
title_encode_dim = envs.get_global_env(
"hyper_parameters.title_encode_dim", None, self._namespace)
query_slots = envs.get_global_env("hyper_parameters.query_slots", None,
self._namespace)
title_slots = envs.get_global_env("hyper_parameters.title_slots", None,
self._namespace)
factory = SimpleEncoderFactory() factory = SimpleEncoderFactory()
self.query_encoders = [ self.query_encoders = [
factory.create(query_encoder, query_encode_dim) factory.create(query_encoder, query_encode_dim)
...@@ -119,10 +125,13 @@ class Model(ModelBase): ...@@ -119,10 +125,13 @@ class Model(ModelBase):
for i in range(title_slots) for i in range(title_slots)
] ]
self.emb_size = envs.get_global_env("hyper_parameters.sparse_feature_dim", None, self._namespace) self.emb_size = envs.get_global_env(
self.emb_dim = envs.get_global_env("hyper_parameters.embedding_dim", None, self._namespace) "hyper_parameters.sparse_feature_dim", None, self._namespace)
self.emb_dim = envs.get_global_env("hyper_parameters.embedding_dim",
None, self._namespace)
self.emb_shape = [self.emb_size, self.emb_dim] self.emb_shape = [self.emb_size, self.emb_dim]
self.hidden_size = envs.get_global_env("hyper_parameters.hidden_size", None, self._namespace) self.hidden_size = envs.get_global_env("hyper_parameters.hidden_size",
None, self._namespace)
self.margin = 0.1 self.margin = 0.1
def input(self, is_train=True): def input(self, is_train=True):
...@@ -133,8 +142,10 @@ class Model(ModelBase): ...@@ -133,8 +142,10 @@ class Model(ModelBase):
] ]
self.pt_slots = [ self.pt_slots = [
fluid.data( fluid.data(
name="%d" % (i + len(self.query_encoders)), shape=[None, 1], lod_level=1, dtype='int64') name="%d" % (i + len(self.query_encoders)),
for i in range(len(self.title_encoders)) shape=[None, 1],
lod_level=1,
dtype='int64') for i in range(len(self.title_encoders))
] ]
if is_train == False: if is_train == False:
...@@ -142,9 +153,11 @@ class Model(ModelBase): ...@@ -142,9 +153,11 @@ class Model(ModelBase):
self.nt_slots = [ self.nt_slots = [
fluid.data( fluid.data(
name="%d" % (i + len(self.query_encoders) + len(self.title_encoders)), shape=[None, 1], lod_level=1, name="%d" %
dtype='int64') (i + len(self.query_encoders) + len(self.title_encoders)),
for i in range(len(self.title_encoders)) shape=[None, 1],
lod_level=1,
dtype='int64') for i in range(len(self.title_encoders))
] ]
return self.q_slots + self.pt_slots + self.nt_slots return self.q_slots + self.pt_slots + self.nt_slots
...@@ -153,11 +166,15 @@ class Model(ModelBase): ...@@ -153,11 +166,15 @@ class Model(ModelBase):
res = self.input() res = self.input()
self._data_var = res self._data_var = res
use_dataloader = envs.get_global_env("hyper_parameters.use_DataLoader", False, self._namespace) use_dataloader = envs.get_global_env("hyper_parameters.use_DataLoader",
False, self._namespace)
if self._platform != "LINUX" or use_dataloader: if self._platform != "LINUX" or use_dataloader:
self._data_loader = fluid.io.DataLoader.from_generator( self._data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._data_var, capacity=256, use_double_buffer=False, iterable=False) feed_list=self._data_var,
capacity=256,
use_double_buffer=False,
iterable=False)
def get_acc(self, x, y): def get_acc(self, x, y):
less = tensor.cast(cf.less_than(x, y), dtype='float32') less = tensor.cast(cf.less_than(x, y), dtype='float32')
...@@ -190,10 +207,12 @@ class Model(ModelBase): ...@@ -190,10 +207,12 @@ class Model(ModelBase):
self.query_encoders[i].forward(emb) for i, emb in enumerate(q_embs) self.query_encoders[i].forward(emb) for i, emb in enumerate(q_embs)
] ]
pt_encodes = [ pt_encodes = [
self.title_encoders[i].forward(emb) for i, emb in enumerate(pt_embs) self.title_encoders[i].forward(emb)
for i, emb in enumerate(pt_embs)
] ]
nt_encodes = [ nt_encodes = [
self.title_encoders[i].forward(emb) for i, emb in enumerate(nt_embs) self.title_encoders[i].forward(emb)
for i, emb in enumerate(nt_embs)
] ]
# concat multi view for query, pos_title, neg_title # concat multi view for query, pos_title, neg_title
...@@ -252,7 +271,8 @@ class Model(ModelBase): ...@@ -252,7 +271,8 @@ class Model(ModelBase):
self.metrics() self.metrics()
def optimizer(self): def optimizer(self):
learning_rate = envs.get_global_env("hyper_parameters.learning_rate", None, self._namespace) learning_rate = envs.get_global_env("hyper_parameters.learning_rate",
None, self._namespace)
optimizer = fluid.optimizer.Adam(learning_rate=learning_rate) optimizer = fluid.optimizer.Adam(learning_rate=learning_rate)
return optimizer return optimizer
...@@ -261,7 +281,10 @@ class Model(ModelBase): ...@@ -261,7 +281,10 @@ class Model(ModelBase):
self._infer_data_var = res self._infer_data_var = res
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
def infer_net(self): def infer_net(self):
self.infer_input() self.infer_input()
...@@ -281,7 +304,8 @@ class Model(ModelBase): ...@@ -281,7 +304,8 @@ class Model(ModelBase):
self.query_encoders[i].forward(emb) for i, emb in enumerate(q_embs) self.query_encoders[i].forward(emb) for i, emb in enumerate(q_embs)
] ]
pt_encodes = [ pt_encodes = [
self.title_encoders[i].forward(emb) for i, emb in enumerate(pt_embs) self.title_encoders[i].forward(emb)
for i, emb in enumerate(pt_embs)
] ]
# concat multi view for query, pos_title, neg_title # concat multi view for query, pos_title, neg_title
q_concat = fluid.layers.concat(q_encodes) q_concat = fluid.layers.concat(q_encodes)
......
...@@ -18,8 +18,10 @@ from paddlerec.core.utils import envs ...@@ -18,8 +18,10 @@ from paddlerec.core.utils import envs
class TrainReader(Reader): class TrainReader(Reader):
def init(self): def init(self):
self.query_slots = envs.get_global_env("hyper_parameters.query_slots", None, "train.model") self.query_slots = envs.get_global_env("hyper_parameters.query_slots",
self.title_slots = envs.get_global_env("hyper_parameters.title_slots", None, "train.model") None, "train.model")
self.title_slots = envs.get_global_env("hyper_parameters.title_slots",
None, "train.model")
self.all_slots = [] self.all_slots = []
for i in range(self.query_slots): for i in range(self.query_slots):
......
...@@ -20,9 +20,11 @@ from paddlerec.core.reader import Reader ...@@ -20,9 +20,11 @@ from paddlerec.core.reader import Reader
class EvaluateReader(Reader): class EvaluateReader(Reader):
def init(self): def init(self):
all_field_id = ['101', '109_14', '110_14', '127_14', '150_14', '121', '122', '124', '125', '126', '127', '128', all_field_id = [
'129', '101', '109_14', '110_14', '127_14', '150_14', '121', '122', '124',
'205', '206', '207', '210', '216', '508', '509', '702', '853', '301'] '125', '126', '127', '128', '129', '205', '206', '207', '210',
'216', '508', '509', '702', '853', '301'
]
self.all_field_id_dict = defaultdict(int) self.all_field_id_dict = defaultdict(int)
for i, field_id in enumerate(all_field_id): for i, field_id in enumerate(all_field_id):
self.all_field_id_dict[field_id] = [False, i] self.all_field_id_dict[field_id] = [False, i]
......
...@@ -21,9 +21,11 @@ from paddlerec.core.reader import Reader ...@@ -21,9 +21,11 @@ from paddlerec.core.reader import Reader
class TrainReader(Reader): class TrainReader(Reader):
def init(self): def init(self):
all_field_id = ['101', '109_14', '110_14', '127_14', '150_14', '121', '122', '124', '125', '126', '127', '128', all_field_id = [
'129', '101', '109_14', '110_14', '127_14', '150_14', '121', '122', '124',
'205', '206', '207', '210', '216', '508', '509', '702', '853', '301'] '125', '126', '127', '128', '129', '205', '206', '207', '210',
'216', '508', '509', '702', '853', '301'
]
self.all_field_id_dict = defaultdict(int) self.all_field_id_dict = defaultdict(int)
for i, field_id in enumerate(all_field_id): for i, field_id in enumerate(all_field_id):
self.all_field_id_dict[field_id] = [False, i] self.all_field_id_dict[field_id] = [False, i]
......
...@@ -28,11 +28,13 @@ class Model(ModelBase): ...@@ -28,11 +28,13 @@ class Model(ModelBase):
init_stddev = 1.0 init_stddev = 1.0
scales = 1.0 / np.sqrt(data.shape[1]) scales = 1.0 / np.sqrt(data.shape[1])
p_attr = fluid.param_attr.ParamAttr(name='%s_weight' % tag, p_attr = fluid.param_attr.ParamAttr(
initializer=fluid.initializer.NormalInitializer(loc=0.0, name='%s_weight' % tag,
scale=init_stddev * scales)) 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)) b_attr = fluid.ParamAttr(
name='%s_bias' % tag, initializer=fluid.initializer.Constant(0.1))
out = fluid.layers.fc(input=data, out = fluid.layers.fc(input=data,
size=out_dim, size=out_dim,
...@@ -44,7 +46,11 @@ class Model(ModelBase): ...@@ -44,7 +46,11 @@ class Model(ModelBase):
def input_data(self): def input_data(self):
sparse_input_ids = [ sparse_input_ids = [
fluid.data(name="field_" + str(i), shape=[-1, 1], dtype="int64", lod_level=1) for i in range(0, 23) fluid.data(
name="field_" + str(i),
shape=[-1, 1],
dtype="int64",
lod_level=1) for i in range(0, 23)
] ]
label_ctr = fluid.data(name="ctr", shape=[-1, 1], dtype="int64") label_ctr = fluid.data(name="ctr", shape=[-1, 1], dtype="int64")
label_cvr = fluid.data(name="cvr", shape=[-1, 1], dtype="int64") label_cvr = fluid.data(name="cvr", shape=[-1, 1], dtype="int64")
...@@ -55,19 +61,23 @@ class Model(ModelBase): ...@@ -55,19 +61,23 @@ class Model(ModelBase):
def net(self, inputs, is_infer=False): def net(self, inputs, is_infer=False):
vocab_size = envs.get_global_env("hyper_parameters.vocab_size", None, self._namespace) vocab_size = envs.get_global_env("hyper_parameters.vocab_size", None,
embed_size = envs.get_global_env("hyper_parameters.embed_size", None, self._namespace) self._namespace)
embed_size = envs.get_global_env("hyper_parameters.embed_size", None,
self._namespace)
emb = [] emb = []
for data in inputs[0:-2]: for data in inputs[0:-2]:
feat_emb = fluid.embedding(input=data, feat_emb = fluid.embedding(
size=[vocab_size, embed_size], input=data,
param_attr=fluid.ParamAttr(name='dis_emb', size=[vocab_size, embed_size],
learning_rate=5, param_attr=fluid.ParamAttr(
initializer=fluid.initializer.Xavier( name='dis_emb',
fan_in=embed_size, fan_out=embed_size) learning_rate=5,
), initializer=fluid.initializer.Xavier(
is_sparse=True) fan_in=embed_size, fan_out=embed_size)),
field_emb = fluid.layers.sequence_pool(input=feat_emb, pool_type='sum') is_sparse=True)
field_emb = fluid.layers.sequence_pool(
input=feat_emb, pool_type='sum')
emb.append(field_emb) emb.append(field_emb)
concat_emb = fluid.layers.concat(emb, axis=1) concat_emb = fluid.layers.concat(emb, axis=1)
...@@ -85,14 +95,20 @@ class Model(ModelBase): ...@@ -85,14 +95,20 @@ class Model(ModelBase):
ctr_clk = inputs[-2] ctr_clk = inputs[-2]
ctcvr_buy = inputs[-1] ctcvr_buy = inputs[-1]
ctr_prop_one = fluid.layers.slice(ctr_out, axes=[1], starts=[1], ends=[2]) ctr_prop_one = fluid.layers.slice(
cvr_prop_one = fluid.layers.slice(cvr_out, axes=[1], starts=[1], ends=[2]) ctr_out, axes=[1], starts=[1], ends=[2])
cvr_prop_one = fluid.layers.slice(
cvr_out, axes=[1], starts=[1], ends=[2])
ctcvr_prop_one = fluid.layers.elementwise_mul(ctr_prop_one, cvr_prop_one) ctcvr_prop_one = fluid.layers.elementwise_mul(ctr_prop_one,
ctcvr_prop = fluid.layers.concat(input=[1 - ctcvr_prop_one, ctcvr_prop_one], axis=1) cvr_prop_one)
ctcvr_prop = fluid.layers.concat(
input=[1 - ctcvr_prop_one, ctcvr_prop_one], axis=1)
auc_ctr, batch_auc_ctr, auc_states_ctr = fluid.layers.auc(input=ctr_out, label=ctr_clk) auc_ctr, batch_auc_ctr, auc_states_ctr = fluid.layers.auc(
auc_ctcvr, batch_auc_ctcvr, auc_states_ctcvr = fluid.layers.auc(input=ctcvr_prop, label=ctcvr_buy) input=ctr_out, label=ctr_clk)
auc_ctcvr, batch_auc_ctcvr, auc_states_ctcvr = fluid.layers.auc(
input=ctcvr_prop, label=ctcvr_buy)
if is_infer: if is_infer:
self._infer_results["AUC_ctr"] = auc_ctr self._infer_results["AUC_ctr"] = auc_ctr
...@@ -100,7 +116,8 @@ class Model(ModelBase): ...@@ -100,7 +116,8 @@ class Model(ModelBase):
return return
loss_ctr = fluid.layers.cross_entropy(input=ctr_out, label=ctr_clk) loss_ctr = fluid.layers.cross_entropy(input=ctr_out, label=ctr_clk)
loss_ctcvr = fluid.layers.cross_entropy(input=ctcvr_prop, label=ctcvr_buy) loss_ctcvr = fluid.layers.cross_entropy(
input=ctcvr_prop, label=ctcvr_buy)
cost = loss_ctr + loss_ctcvr cost = loss_ctr + loss_ctcvr
avg_cost = fluid.layers.mean(cost) avg_cost = fluid.layers.mean(cost)
...@@ -117,5 +134,8 @@ class Model(ModelBase): ...@@ -117,5 +134,8 @@ class Model(ModelBase):
def infer_net(self): def infer_net(self):
self._infer_data_var = self.input_data() self._infer_data_var = self.input_data()
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
self.net(self._infer_data_var, is_infer=True) self.net(self._infer_data_var, is_infer=True)
...@@ -19,6 +19,7 @@ from paddlerec.core.reader import Reader ...@@ -19,6 +19,7 @@ from paddlerec.core.reader import Reader
class EvaluateReader(Reader): class EvaluateReader(Reader):
def init(self): def init(self):
pass pass
def generate_sample(self, line): def generate_sample(self, line):
......
...@@ -24,6 +24,7 @@ class TrainReader(Reader): ...@@ -24,6 +24,7 @@ class TrainReader(Reader):
def generate_sample(self, line): def generate_sample(self, line):
""" """
Read the data line by line and process it as a dictionary Read the data line by line and process it as a dictionary
""" """
def reader(): def reader():
......
...@@ -23,44 +23,58 @@ class Model(ModelBase): ...@@ -23,44 +23,58 @@ class Model(ModelBase):
ModelBase.__init__(self, config) ModelBase.__init__(self, config)
def MMOE(self, is_infer=False): def MMOE(self, is_infer=False):
feature_size = envs.get_global_env("hyper_parameters.feature_size",
feature_size = envs.get_global_env("hyper_parameters.feature_size", None, self._namespace) None, self._namespace)
expert_num = envs.get_global_env("hyper_parameters.expert_num", None, self._namespace) expert_num = envs.get_global_env("hyper_parameters.expert_num", None,
gate_num = envs.get_global_env("hyper_parameters.gate_num", None, self._namespace) self._namespace)
expert_size = envs.get_global_env("hyper_parameters.expert_size", None, self._namespace) gate_num = envs.get_global_env("hyper_parameters.gate_num", None,
tower_size = envs.get_global_env("hyper_parameters.tower_size", None, self._namespace) self._namespace)
expert_size = envs.get_global_env("hyper_parameters.expert_size", None,
input_data = fluid.data(name="input", shape=[-1, feature_size], dtype="float32") self._namespace)
label_income = fluid.data(name="label_income", shape=[-1, 2], dtype="float32", lod_level=0) tower_size = envs.get_global_env("hyper_parameters.tower_size", None,
label_marital = fluid.data(name="label_marital", shape=[-1, 2], dtype="float32", lod_level=0) self._namespace)
input_data = fluid.data(
name="input", shape=[-1, feature_size], dtype="float32")
label_income = fluid.data(
name="label_income", shape=[-1, 2], dtype="float32", lod_level=0)
label_marital = fluid.data(
name="label_marital", shape=[-1, 2], dtype="float32", lod_level=0)
if is_infer: if is_infer:
self._infer_data_var = [input_data, label_income, label_marital] self._infer_data_var = [input_data, label_income, label_marital]
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
self._data_var.extend([input_data, label_income, label_marital]) self._data_var.extend([input_data, label_income, label_marital])
# f_{i}(x) = activation(W_{i} * x + b), where activation is ReLU according to the paper # f_{i}(x) = activation(W_{i} * x + b), where activation is ReLU according to the paper
expert_outputs = [] expert_outputs = []
for i in range(0, expert_num): for i in range(0, expert_num):
expert_output = fluid.layers.fc(input=input_data, expert_output = fluid.layers.fc(
size=expert_size, input=input_data,
act='relu', size=expert_size,
bias_attr=fluid.ParamAttr(learning_rate=1.0), act='relu',
name='expert_' + str(i)) bias_attr=fluid.ParamAttr(learning_rate=1.0),
name='expert_' + str(i))
expert_outputs.append(expert_output) expert_outputs.append(expert_output)
expert_concat = fluid.layers.concat(expert_outputs, axis=1) expert_concat = fluid.layers.concat(expert_outputs, axis=1)
expert_concat = fluid.layers.reshape(expert_concat, [-1, expert_num, expert_size]) expert_concat = fluid.layers.reshape(expert_concat,
[-1, expert_num, expert_size])
# g^{k}(x) = activation(W_{gk} * x + b), where activation is softmax according to the paper # g^{k}(x) = activation(W_{gk} * x + b), where activation is softmax according to the paper
output_layers = [] output_layers = []
for i in range(0, gate_num): for i in range(0, gate_num):
cur_gate = fluid.layers.fc(input=input_data, cur_gate = fluid.layers.fc(
size=expert_num, input=input_data,
act='softmax', size=expert_num,
bias_attr=fluid.ParamAttr(learning_rate=1.0), act='softmax',
name='gate_' + str(i)) bias_attr=fluid.ParamAttr(learning_rate=1.0),
name='gate_' + str(i))
# f^{k}(x) = sum_{i=1}^{n}(g^{k}(x)_{i} * f_{i}(x)) # f^{k}(x) = sum_{i=1}^{n}(g^{k}(x)_{i} * f_{i}(x))
cur_gate_expert = fluid.layers.elementwise_mul(expert_concat, cur_gate, axis=0) cur_gate_expert = fluid.layers.elementwise_mul(
expert_concat, cur_gate, axis=0)
cur_gate_expert = fluid.layers.reduce_sum(cur_gate_expert, dim=1) cur_gate_expert = fluid.layers.reduce_sum(cur_gate_expert, dim=1)
# Build tower layer # Build tower layer
cur_tower = fluid.layers.fc(input=cur_gate_expert, cur_tower = fluid.layers.fc(input=cur_gate_expert,
...@@ -74,25 +88,33 @@ class Model(ModelBase): ...@@ -74,25 +88,33 @@ class Model(ModelBase):
output_layers.append(out) output_layers.append(out)
pred_income = fluid.layers.clip(output_layers[0], min=1e-15, max=1.0 - 1e-15) pred_income = fluid.layers.clip(
pred_marital = fluid.layers.clip(output_layers[1], min=1e-15, max=1.0 - 1e-15) output_layers[0], min=1e-15, max=1.0 - 1e-15)
pred_marital = fluid.layers.clip(
label_income_1 = fluid.layers.slice(label_income, axes=[1], starts=[1], ends=[2]) output_layers[1], min=1e-15, max=1.0 - 1e-15)
label_marital_1 = fluid.layers.slice(label_marital, axes=[1], starts=[1], ends=[2])
label_income_1 = fluid.layers.slice(
auc_income, batch_auc_1, auc_states_1 = fluid.layers.auc(input=pred_income, label_income, axes=[1], starts=[1], ends=[2])
label=fluid.layers.cast(x=label_income_1, label_marital_1 = fluid.layers.slice(
dtype='int64')) label_marital, axes=[1], starts=[1], ends=[2])
auc_marital, batch_auc_2, auc_states_2 = fluid.layers.auc(input=pred_marital,
label=fluid.layers.cast(x=label_marital_1, auc_income, batch_auc_1, auc_states_1 = fluid.layers.auc(
dtype='int64')) input=pred_income,
label=fluid.layers.cast(
x=label_income_1, dtype='int64'))
auc_marital, batch_auc_2, auc_states_2 = fluid.layers.auc(
input=pred_marital,
label=fluid.layers.cast(
x=label_marital_1, dtype='int64'))
if is_infer: if is_infer:
self._infer_results["AUC_income"] = auc_income self._infer_results["AUC_income"] = auc_income
self._infer_results["AUC_marital"] = auc_marital self._infer_results["AUC_marital"] = auc_marital
return return
cost_income = fluid.layers.cross_entropy(input=pred_income, label=label_income, soft_label=True) cost_income = fluid.layers.cross_entropy(
cost_marital = fluid.layers.cross_entropy(input=pred_marital, label=label_marital, soft_label=True) input=pred_income, label=label_income, soft_label=True)
cost_marital = fluid.layers.cross_entropy(
input=pred_marital, label=label_marital, soft_label=True)
avg_cost_income = fluid.layers.mean(x=cost_income) avg_cost_income = fluid.layers.mean(x=cost_income)
avg_cost_marital = fluid.layers.mean(x=cost_marital) avg_cost_marital = fluid.layers.mean(x=cost_marital)
......
...@@ -24,27 +24,38 @@ class Model(ModelBase): ...@@ -24,27 +24,38 @@ class Model(ModelBase):
def model(self, is_infer=False): def model(self, is_infer=False):
feature_size = envs.get_global_env("hyper_parameters.feature_size", None, self._namespace) feature_size = envs.get_global_env("hyper_parameters.feature_size",
bottom_size = envs.get_global_env("hyper_parameters.bottom_size", None, self._namespace) None, self._namespace)
tower_size = envs.get_global_env("hyper_parameters.tower_size", None, self._namespace) bottom_size = envs.get_global_env("hyper_parameters.bottom_size", None,
tower_nums = envs.get_global_env("hyper_parameters.tower_nums", None, self._namespace) self._namespace)
tower_size = envs.get_global_env("hyper_parameters.tower_size", None,
input_data = fluid.data(name="input", shape=[-1, feature_size], dtype="float32") self._namespace)
label_income = fluid.data(name="label_income", shape=[-1, 2], dtype="float32", lod_level=0) tower_nums = envs.get_global_env("hyper_parameters.tower_nums", None,
label_marital = fluid.data(name="label_marital", shape=[-1, 2], dtype="float32", lod_level=0) self._namespace)
input_data = fluid.data(
name="input", shape=[-1, feature_size], dtype="float32")
label_income = fluid.data(
name="label_income", shape=[-1, 2], dtype="float32", lod_level=0)
label_marital = fluid.data(
name="label_marital", shape=[-1, 2], dtype="float32", lod_level=0)
if is_infer: if is_infer:
self._infer_data_var = [input_data, label_income, label_marital] self._infer_data_var = [input_data, label_income, label_marital]
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
self._data_var.extend([input_data, label_income, label_marital]) self._data_var.extend([input_data, label_income, label_marital])
bottom_output = fluid.layers.fc(input=input_data, bottom_output = fluid.layers.fc(
size=bottom_size, input=input_data,
act='relu', size=bottom_size,
bias_attr=fluid.ParamAttr(learning_rate=1.0), act='relu',
name='bottom_output') bias_attr=fluid.ParamAttr(learning_rate=1.0),
name='bottom_output')
# Build tower layer from bottom layer # Build tower layer from bottom layer
output_layers = [] output_layers = []
...@@ -59,26 +70,34 @@ class Model(ModelBase): ...@@ -59,26 +70,34 @@ class Model(ModelBase):
name='output_layer_' + str(index)) name='output_layer_' + str(index))
output_layers.append(output_layer) output_layers.append(output_layer)
pred_income = fluid.layers.clip(output_layers[0], min=1e-15, max=1.0 - 1e-15) pred_income = fluid.layers.clip(
pred_marital = fluid.layers.clip(output_layers[1], min=1e-15, max=1.0 - 1e-15) output_layers[0], min=1e-15, max=1.0 - 1e-15)
pred_marital = fluid.layers.clip(
label_income_1 = fluid.layers.slice(label_income, axes=[1], starts=[1], ends=[2]) output_layers[1], min=1e-15, max=1.0 - 1e-15)
label_marital_1 = fluid.layers.slice(label_marital, axes=[1], starts=[1], ends=[2])
label_income_1 = fluid.layers.slice(
auc_income, batch_auc_1, auc_states_1 = fluid.layers.auc(input=pred_income, label_income, axes=[1], starts=[1], ends=[2])
label=fluid.layers.cast(x=label_income_1, label_marital_1 = fluid.layers.slice(
dtype='int64')) label_marital, axes=[1], starts=[1], ends=[2])
auc_marital, batch_auc_2, auc_states_2 = fluid.layers.auc(input=pred_marital,
label=fluid.layers.cast(x=label_marital_1, auc_income, batch_auc_1, auc_states_1 = fluid.layers.auc(
dtype='int64')) input=pred_income,
label=fluid.layers.cast(
x=label_income_1, dtype='int64'))
auc_marital, batch_auc_2, auc_states_2 = fluid.layers.auc(
input=pred_marital,
label=fluid.layers.cast(
x=label_marital_1, dtype='int64'))
if is_infer: if is_infer:
self._infer_results["AUC_income"] = auc_income self._infer_results["AUC_income"] = auc_income
self._infer_results["AUC_marital"] = auc_marital self._infer_results["AUC_marital"] = auc_marital
return return
cost_income = fluid.layers.cross_entropy(input=pred_income, label=label_income, soft_label=True) cost_income = fluid.layers.cross_entropy(
cost_marital = fluid.layers.cross_entropy(input=pred_marital, label=label_marital, soft_label=True) input=pred_income, label=label_income, soft_label=True)
cost_marital = fluid.layers.cross_entropy(
input=pred_marital, label=label_marital, soft_label=True)
cost = fluid.layers.elementwise_add(cost_income, cost_marital, axis=1) cost = fluid.layers.elementwise_add(cost_income, cost_marital, axis=1)
avg_cost = fluid.layers.mean(x=cost) avg_cost = fluid.layers.mean(x=cost)
......
...@@ -25,12 +25,18 @@ class Model(ModelBase): ...@@ -25,12 +25,18 @@ class Model(ModelBase):
ModelBase.__init__(self, config) ModelBase.__init__(self, config)
def init_network(self): def init_network(self):
self.cross_num = envs.get_global_env("hyper_parameters.cross_num", None, self._namespace) self.cross_num = envs.get_global_env("hyper_parameters.cross_num",
self.dnn_hidden_units = envs.get_global_env("hyper_parameters.dnn_hidden_units", None, self._namespace) None, self._namespace)
self.l2_reg_cross = envs.get_global_env("hyper_parameters.l2_reg_cross", None, self._namespace) self.dnn_hidden_units = envs.get_global_env(
self.dnn_use_bn = envs.get_global_env("hyper_parameters.dnn_use_bn", None, self._namespace) "hyper_parameters.dnn_hidden_units", None, self._namespace)
self.clip_by_norm = envs.get_global_env("hyper_parameters.clip_by_norm", None, self._namespace) self.l2_reg_cross = envs.get_global_env(
cat_feat_num = envs.get_global_env("hyper_parameters.cat_feat_num", None, self._namespace) "hyper_parameters.l2_reg_cross", None, self._namespace)
self.dnn_use_bn = envs.get_global_env("hyper_parameters.dnn_use_bn",
None, self._namespace)
self.clip_by_norm = envs.get_global_env(
"hyper_parameters.clip_by_norm", None, self._namespace)
cat_feat_num = envs.get_global_env("hyper_parameters.cat_feat_num",
None, self._namespace)
self.sparse_inputs = self._sparse_data_var[1:] self.sparse_inputs = self._sparse_data_var[1:]
self.dense_inputs = self._dense_data_var self.dense_inputs = self._dense_data_var
...@@ -43,7 +49,8 @@ class Model(ModelBase): ...@@ -43,7 +49,8 @@ class Model(ModelBase):
cat_feat_dims_dict[spls[0]] = int(spls[1]) cat_feat_dims_dict[spls[0]] = int(spls[1])
self.cat_feat_dims_dict = cat_feat_dims_dict if cat_feat_dims_dict else OrderedDict( self.cat_feat_dims_dict = cat_feat_dims_dict if cat_feat_dims_dict else OrderedDict(
) )
self.is_sparse = envs.get_global_env("hyper_parameters.is_sparse", None, self._namespace) self.is_sparse = envs.get_global_env("hyper_parameters.is_sparse",
None, self._namespace)
self.dense_feat_names = [i.name for i in self.dense_inputs] self.dense_feat_names = [i.name for i in self.dense_inputs]
self.sparse_feat_names = [i.name for i in self.sparse_inputs] self.sparse_feat_names = [i.name for i in self.sparse_inputs]
...@@ -55,16 +62,19 @@ class Model(ModelBase): ...@@ -55,16 +62,19 @@ class Model(ModelBase):
self.net_input = None self.net_input = None
self.loss = None self.loss = None
def _create_embedding_input(self): def _create_embedding_input(self):
# sparse embedding # sparse embedding
sparse_emb_dict = OrderedDict() sparse_emb_dict = OrderedDict()
for var in self.sparse_inputs: for var in self.sparse_inputs:
sparse_emb_dict[var.name] = fluid.embedding(input=var, sparse_emb_dict[var.name] = fluid.embedding(
size=[self.feat_dims_dict[var.name] + 1, input=var,
6 * int(pow(self.feat_dims_dict[var.name], 0.25)) size=[
],is_sparse=self.is_sparse) self.feat_dims_dict[var.name] + 1,
6 * int(pow(self.feat_dims_dict[var.name], 0.25))
],
is_sparse=self.is_sparse)
# combine dense and sparse_emb # combine dense and sparse_emb
dense_input_list = self.dense_inputs dense_input_list = self.dense_inputs
sparse_emb_list = list(sparse_emb_dict.values()) sparse_emb_list = list(sparse_emb_dict.values())
...@@ -114,10 +124,11 @@ class Model(ModelBase): ...@@ -114,10 +124,11 @@ class Model(ModelBase):
def train_net(self): def train_net(self):
self.model._init_slots() self.model._init_slots()
self.init_network() self.init_network()
self.net_input = self._create_embedding_input() self.net_input = self._create_embedding_input()
deep_out = self._deep_net(self.net_input, self.dnn_hidden_units, self.dnn_use_bn, False) deep_out = self._deep_net(self.net_input, self.dnn_hidden_units,
self.dnn_use_bn, False)
cross_out, l2_reg_cross_loss = self._cross_net(self.net_input, cross_out, l2_reg_cross_loss = self._cross_net(self.net_input,
self.cross_num) self.cross_num)
...@@ -134,9 +145,11 @@ class Model(ModelBase): ...@@ -134,9 +145,11 @@ class Model(ModelBase):
input=prob_2d, label=label_int, slide_steps=0) input=prob_2d, label=label_int, slide_steps=0)
self._metrics["AUC"] = auc_var self._metrics["AUC"] = auc_var
self._metrics["BATCH_AUC"] = batch_auc_var self._metrics["BATCH_AUC"] = batch_auc_var
# logloss # logloss
logloss = fluid.layers.log_loss(self.prob, fluid.layers.cast(self.target_input, dtype='float32')) logloss = fluid.layers.log_loss(
self.prob, fluid.layers.cast(
self.target_input, dtype='float32'))
self.avg_logloss = fluid.layers.reduce_mean(logloss) self.avg_logloss = fluid.layers.reduce_mean(logloss)
# reg_coeff * l2_reg_cross # reg_coeff * l2_reg_cross
...@@ -145,7 +158,8 @@ class Model(ModelBase): ...@@ -145,7 +158,8 @@ class Model(ModelBase):
self._cost = self.loss self._cost = self.loss
def optimizer(self): def optimizer(self):
learning_rate = envs.get_global_env("hyper_parameters.learning_rate", None, self._namespace) learning_rate = envs.get_global_env("hyper_parameters.learning_rate",
None, self._namespace)
optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True) optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True)
return optimizer return optimizer
......
...@@ -27,21 +27,26 @@ class Model(ModelBase): ...@@ -27,21 +27,26 @@ class Model(ModelBase):
def deepfm_net(self): def deepfm_net(self):
init_value_ = 0.1 init_value_ = 0.1
is_distributed = True if envs.get_trainer() == "CtrTrainer" else False is_distributed = True if envs.get_trainer() == "CtrTrainer" else False
sparse_feature_number = envs.get_global_env("hyper_parameters.sparse_feature_number", None, self._namespace) sparse_feature_number = envs.get_global_env(
sparse_feature_dim = envs.get_global_env("hyper_parameters.sparse_feature_dim", None, self._namespace) "hyper_parameters.sparse_feature_number", None, self._namespace)
sparse_feature_dim = envs.get_global_env(
"hyper_parameters.sparse_feature_dim", None, self._namespace)
# ------------------------- network input -------------------------- # ------------------------- network input --------------------------
num_field = envs.get_global_env("hyper_parameters.num_field", None, self._namespace) num_field = envs.get_global_env("hyper_parameters.num_field", None,
self._namespace)
raw_feat_idx = self._sparse_data_var[1] raw_feat_idx = self._sparse_data_var[1]
raw_feat_value = self._dense_data_var[0] raw_feat_value = self._dense_data_var[0]
self.label = self._sparse_data_var[0] self.label = self._sparse_data_var[0]
feat_idx = raw_feat_idx feat_idx = raw_feat_idx
feat_value = fluid.layers.reshape(raw_feat_value, [-1, num_field, 1]) # None * num_field * 1 feat_value = fluid.layers.reshape(
raw_feat_value, [-1, num_field, 1]) # None * num_field * 1
reg = envs.get_global_env("hyper_parameters.reg", 1e-4, self._namespace)
reg = envs.get_global_env("hyper_parameters.reg", 1e-4,
self._namespace)
first_weights_re = fluid.embedding( first_weights_re = fluid.embedding(
input=feat_idx, input=feat_idx,
is_sparse=True, is_sparse=True,
...@@ -55,7 +60,8 @@ class Model(ModelBase): ...@@ -55,7 +60,8 @@ class Model(ModelBase):
regularizer=fluid.regularizer.L1DecayRegularizer(reg))) regularizer=fluid.regularizer.L1DecayRegularizer(reg)))
first_weights = fluid.layers.reshape( first_weights = fluid.layers.reshape(
first_weights_re, shape=[-1, num_field, 1]) # None * num_field * 1 first_weights_re, shape=[-1, num_field, 1]) # None * num_field * 1
y_first_order = fluid.layers.reduce_sum((first_weights * feat_value), 1) y_first_order = fluid.layers.reduce_sum((first_weights * feat_value),
1)
# ------------------------- second order term -------------------------- # ------------------------- second order term --------------------------
...@@ -68,7 +74,8 @@ class Model(ModelBase): ...@@ -68,7 +74,8 @@ class Model(ModelBase):
padding_idx=0, padding_idx=0,
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(
initializer=fluid.initializer.TruncatedNormalInitializer( initializer=fluid.initializer.TruncatedNormalInitializer(
loc=0.0, scale=init_value_ / math.sqrt(float(sparse_feature_dim))))) loc=0.0,
scale=init_value_ / math.sqrt(float(sparse_feature_dim)))))
feat_embeddings = fluid.layers.reshape( feat_embeddings = fluid.layers.reshape(
feat_embeddings_re, feat_embeddings_re,
shape=[-1, num_field, shape=[-1, num_field,
...@@ -76,8 +83,8 @@ class Model(ModelBase): ...@@ -76,8 +83,8 @@ class Model(ModelBase):
feat_embeddings = feat_embeddings * feat_value # None * num_field * embedding_size feat_embeddings = feat_embeddings * feat_value # None * num_field * embedding_size
# sum_square part # sum_square part
summed_features_emb = fluid.layers.reduce_sum(feat_embeddings, summed_features_emb = fluid.layers.reduce_sum(
1) # None * embedding_size feat_embeddings, 1) # None * embedding_size
summed_features_emb_square = fluid.layers.square( summed_features_emb_square = fluid.layers.square(
summed_features_emb) # None * embedding_size summed_features_emb) # None * embedding_size
...@@ -88,13 +95,16 @@ class Model(ModelBase): ...@@ -88,13 +95,16 @@ class Model(ModelBase):
squared_features_emb, 1) # None * embedding_size squared_features_emb, 1) # None * embedding_size
y_second_order = 0.5 * fluid.layers.reduce_sum( y_second_order = 0.5 * fluid.layers.reduce_sum(
summed_features_emb_square - squared_sum_features_emb, 1, summed_features_emb_square - squared_sum_features_emb,
1,
keep_dim=True) # None * 1 keep_dim=True) # None * 1
# ------------------------- DNN -------------------------- # ------------------------- DNN --------------------------
layer_sizes = envs.get_global_env("hyper_parameters.fc_sizes", None, self._namespace) layer_sizes = envs.get_global_env("hyper_parameters.fc_sizes", None,
act = envs.get_global_env("hyper_parameters.act", None, self._namespace) self._namespace)
act = envs.get_global_env("hyper_parameters.act", None,
self._namespace)
y_dnn = fluid.layers.reshape(feat_embeddings, y_dnn = fluid.layers.reshape(feat_embeddings,
[-1, num_field * sparse_feature_dim]) [-1, num_field * sparse_feature_dim])
for s in layer_sizes: for s in layer_sizes:
...@@ -121,7 +131,8 @@ class Model(ModelBase): ...@@ -121,7 +131,8 @@ class Model(ModelBase):
# ------------------------- DeepFM -------------------------- # ------------------------- DeepFM --------------------------
self.predict = fluid.layers.sigmoid(y_first_order + y_second_order + y_dnn) self.predict = fluid.layers.sigmoid(y_first_order + y_second_order +
y_dnn)
def train_net(self): def train_net(self):
self.model._init_slots() self.model._init_slots()
...@@ -129,7 +140,8 @@ class Model(ModelBase): ...@@ -129,7 +140,8 @@ class Model(ModelBase):
# ------------------------- Cost(logloss) -------------------------- # ------------------------- Cost(logloss) --------------------------
cost = fluid.layers.log_loss(input=self.predict, label=fluid.layers.cast(self.label, "float32")) cost = fluid.layers.log_loss(
input=self.predict, label=fluid.layers.cast(self.label, "float32"))
avg_cost = fluid.layers.reduce_sum(cost) avg_cost = fluid.layers.reduce_sum(cost)
self._cost = avg_cost self._cost = avg_cost
...@@ -145,7 +157,8 @@ class Model(ModelBase): ...@@ -145,7 +157,8 @@ class Model(ModelBase):
self._metrics["BATCH_AUC"] = batch_auc_var self._metrics["BATCH_AUC"] = batch_auc_var
def optimizer(self): def optimizer(self):
learning_rate = envs.get_global_env("hyper_parameters.learning_rate", None, self._namespace) learning_rate = envs.get_global_env("hyper_parameters.learning_rate",
None, self._namespace)
optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True) optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True)
return optimizer return optimizer
......
...@@ -21,14 +21,14 @@ from paddlerec.core.model import Model as ModelBase ...@@ -21,14 +21,14 @@ from paddlerec.core.model import Model as ModelBase
class Model(ModelBase): class Model(ModelBase):
def __init__(self, config): def __init__(self, config):
ModelBase.__init__(self, config) ModelBase.__init__(self, config)
def config_read(self, config_path): def config_read(self, config_path):
with open(config_path, "r") as fin: with open(config_path, "r") as fin:
user_count = int(fin.readline().strip()) user_count = int(fin.readline().strip())
item_count = int(fin.readline().strip()) item_count = int(fin.readline().strip())
cat_count = int(fin.readline().strip()) cat_count = int(fin.readline().strip())
return user_count, item_count, cat_count return user_count, item_count, cat_count
def din_attention(self, hist, target_expand, mask): def din_attention(self, hist, target_expand, mask):
"""activation weight""" """activation weight"""
...@@ -58,56 +58,66 @@ class Model(ModelBase): ...@@ -58,56 +58,66 @@ class Model(ModelBase):
out = fluid.layers.matmul(weight, hist) out = fluid.layers.matmul(weight, hist)
out = fluid.layers.reshape(x=out, shape=[0, hidden_size]) out = fluid.layers.reshape(x=out, shape=[0, hidden_size])
return out return out
def train_net(self): def train_net(self):
seq_len = -1 seq_len = -1
self.item_emb_size = envs.get_global_env("hyper_parameters.item_emb_size", 64, self._namespace) self.item_emb_size = envs.get_global_env(
self.cat_emb_size = envs.get_global_env("hyper_parameters.cat_emb_size", 64, self._namespace) "hyper_parameters.item_emb_size", 64, self._namespace)
self.act = envs.get_global_env("hyper_parameters.act", "sigmoid", self._namespace) self.cat_emb_size = envs.get_global_env(
"hyper_parameters.cat_emb_size", 64, self._namespace)
self.act = envs.get_global_env("hyper_parameters.act", "sigmoid",
self._namespace)
#item_emb_size = 64 #item_emb_size = 64
#cat_emb_size = 64 #cat_emb_size = 64
self.is_sparse = envs.get_global_env("hyper_parameters.is_sparse", False, self._namespace) self.is_sparse = envs.get_global_env("hyper_parameters.is_sparse",
False, self._namespace)
#significant for speeding up the training process #significant for speeding up the training process
self.config_path = envs.get_global_env("hyper_parameters.config_path", "data/config.txt", self._namespace) self.config_path = envs.get_global_env(
self.use_DataLoader = envs.get_global_env("hyper_parameters.use_DataLoader", False, self._namespace) "hyper_parameters.config_path", "data/config.txt", self._namespace)
self.use_DataLoader = envs.get_global_env(
"hyper_parameters.use_DataLoader", False, self._namespace)
user_count, item_count, cat_count = self.config_read(self.config_path) user_count, item_count, cat_count = self.config_read(self.config_path)
item_emb_attr = fluid.ParamAttr(name="item_emb") item_emb_attr = fluid.ParamAttr(name="item_emb")
cat_emb_attr = fluid.ParamAttr(name="cat_emb") cat_emb_attr = fluid.ParamAttr(name="cat_emb")
hist_item_seq = fluid.data( hist_item_seq = fluid.data(
name="hist_item_seq", shape=[None, seq_len], dtype="int64") name="hist_item_seq", shape=[None, seq_len], dtype="int64")
self._data_var.append(hist_item_seq) self._data_var.append(hist_item_seq)
hist_cat_seq = fluid.data( hist_cat_seq = fluid.data(
name="hist_cat_seq", shape=[None, seq_len], dtype="int64") name="hist_cat_seq", shape=[None, seq_len], dtype="int64")
self._data_var.append(hist_cat_seq) self._data_var.append(hist_cat_seq)
target_item = fluid.data(name="target_item", shape=[None], dtype="int64") target_item = fluid.data(
name="target_item", shape=[None], dtype="int64")
self._data_var.append(target_item) self._data_var.append(target_item)
target_cat = fluid.data(name="target_cat", shape=[None], dtype="int64") target_cat = fluid.data(name="target_cat", shape=[None], dtype="int64")
self._data_var.append(target_cat) self._data_var.append(target_cat)
label = fluid.data(name="label", shape=[None, 1], dtype="float32") label = fluid.data(name="label", shape=[None, 1], dtype="float32")
self._data_var.append(label) self._data_var.append(label)
mask = fluid.data(name="mask", shape=[None, seq_len, 1], dtype="float32") mask = fluid.data(
name="mask", shape=[None, seq_len, 1], dtype="float32")
self._data_var.append(mask) self._data_var.append(mask)
target_item_seq = fluid.data( target_item_seq = fluid.data(
name="target_item_seq", shape=[None, seq_len], dtype="int64") name="target_item_seq", shape=[None, seq_len], dtype="int64")
self._data_var.append(target_item_seq) self._data_var.append(target_item_seq)
target_cat_seq = fluid.data( target_cat_seq = fluid.data(
name="target_cat_seq", shape=[None, seq_len], dtype="int64") name="target_cat_seq", shape=[None, seq_len], dtype="int64")
self._data_var.append(target_cat_seq) self._data_var.append(target_cat_seq)
if self.use_DataLoader: if self.use_DataLoader:
self._data_loader = fluid.io.DataLoader.from_generator( self._data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._data_var, capacity=10000, use_double_buffer=False, iterable=False) feed_list=self._data_var,
capacity=10000,
use_double_buffer=False,
iterable=False)
hist_item_emb = fluid.embedding( hist_item_emb = fluid.embedding(
input=hist_item_seq, input=hist_item_seq,
size=[item_count, self.item_emb_size], size=[item_count, self.item_emb_size],
...@@ -149,7 +159,8 @@ class Model(ModelBase): ...@@ -149,7 +159,8 @@ class Model(ModelBase):
size=[item_count, 1], size=[item_count, 1],
param_attr=fluid.initializer.Constant(value=0.0)) param_attr=fluid.initializer.Constant(value=0.0))
hist_seq_concat = fluid.layers.concat([hist_item_emb, hist_cat_emb], axis=2) hist_seq_concat = fluid.layers.concat(
[hist_item_emb, hist_cat_emb], axis=2)
target_seq_concat = fluid.layers.concat( target_seq_concat = fluid.layers.concat(
[target_item_seq_emb, target_cat_seq_emb], axis=2) [target_item_seq_emb, target_cat_seq_emb], axis=2)
target_concat = fluid.layers.concat( target_concat = fluid.layers.concat(
...@@ -157,21 +168,22 @@ class Model(ModelBase): ...@@ -157,21 +168,22 @@ class Model(ModelBase):
out = self.din_attention(hist_seq_concat, target_seq_concat, mask) out = self.din_attention(hist_seq_concat, target_seq_concat, mask)
out_fc = fluid.layers.fc(name="out_fc", out_fc = fluid.layers.fc(name="out_fc",
input=out, input=out,
size=self.item_emb_size + self.cat_emb_size, size=self.item_emb_size + self.cat_emb_size,
num_flatten_dims=1) num_flatten_dims=1)
embedding_concat = fluid.layers.concat([out_fc, target_concat], axis=1) embedding_concat = fluid.layers.concat([out_fc, target_concat], axis=1)
fc1 = fluid.layers.fc(name="fc1", fc1 = fluid.layers.fc(name="fc1",
input=embedding_concat, input=embedding_concat,
size=80, size=80,
act=self.act) act=self.act)
fc2 = fluid.layers.fc(name="fc2", input=fc1, size=40, act=self.act) fc2 = fluid.layers.fc(name="fc2", input=fc1, size=40, act=self.act)
fc3 = fluid.layers.fc(name="fc3", input=fc2, size=1) fc3 = fluid.layers.fc(name="fc3", input=fc2, size=1)
logit = fc3 + item_b logit = fc3 + item_b
loss = fluid.layers.sigmoid_cross_entropy_with_logits(x=logit, label=label) loss = fluid.layers.sigmoid_cross_entropy_with_logits(
x=logit, label=label)
avg_loss = fluid.layers.mean(loss) avg_loss = fluid.layers.mean(loss)
self._cost = avg_loss self._cost = avg_loss
...@@ -179,14 +191,14 @@ class Model(ModelBase): ...@@ -179,14 +191,14 @@ class Model(ModelBase):
predict_2d = fluid.layers.concat([1 - self.predict, self.predict], 1) predict_2d = fluid.layers.concat([1 - self.predict, self.predict], 1)
label_int = fluid.layers.cast(label, 'int64') label_int = fluid.layers.cast(label, 'int64')
auc_var, batch_auc_var, _ = fluid.layers.auc(input=predict_2d, auc_var, batch_auc_var, _ = fluid.layers.auc(input=predict_2d,
label=label_int, label=label_int,
slide_steps=0) slide_steps=0)
self._metrics["AUC"] = auc_var self._metrics["AUC"] = auc_var
self._metrics["BATCH_AUC"] = batch_auc_var self._metrics["BATCH_AUC"] = batch_auc_var
def optimizer(self): def optimizer(self):
learning_rate = envs.get_global_env("hyper_parameters.learning_rate", None, self._namespace) learning_rate = envs.get_global_env("hyper_parameters.learning_rate",
None, self._namespace)
optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True) optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True)
return optimizer return optimizer
......
...@@ -29,13 +29,15 @@ from paddlerec.core.utils import envs ...@@ -29,13 +29,15 @@ from paddlerec.core.utils import envs
class TrainReader(Reader): class TrainReader(Reader):
def init(self): def init(self):
self.train_data_path = envs.get_global_env("train_data_path", None, "train.reader") self.train_data_path = envs.get_global_env("train_data_path", None,
"train.reader")
self.res = [] self.res = []
self.max_len = 0 self.max_len = 0
data_file_list = os.listdir(self.train_data_path) data_file_list = os.listdir(self.train_data_path)
for i in range(0, len(data_file_list)): for i in range(0, len(data_file_list)):
train_data_file = os.path.join(self.train_data_path, data_file_list[i]) train_data_file = os.path.join(self.train_data_path,
data_file_list[i])
with open(train_data_file, "r") as fin: with open(train_data_file, "r") as fin:
for line in fin: for line in fin:
line = line.strip().split(';') line = line.strip().split(';')
...@@ -78,11 +80,13 @@ class TrainReader(Reader): ...@@ -78,11 +80,13 @@ class TrainReader(Reader):
len_array = [len(x[0]) for x in b] len_array = [len(x[0]) for x in b]
mask = np.array( mask = np.array(
[[0] * x + [-1e9] * (max_len - x) for x in len_array]).reshape( [[0] * x + [-1e9] * (max_len - x) for x in len_array]).reshape(
[-1, max_len, 1]) [-1, max_len, 1])
target_item_seq = np.array( target_item_seq = np.array(
[[x[2]] * max_len for x in b]).astype("int64").reshape([-1, max_len]) [[x[2]] * max_len for x in b]).astype("int64").reshape(
[-1, max_len])
target_cat_seq = np.array( target_cat_seq = np.array(
[[x[3]] * max_len for x in b]).astype("int64").reshape([-1, max_len]) [[x[3]] * max_len for x in b]).astype("int64").reshape(
[-1, max_len])
res = [] res = []
for i in range(len(b)): for i in range(len(b)):
res.append([ res.append([
...@@ -127,4 +131,5 @@ class TrainReader(Reader): ...@@ -127,4 +131,5 @@ class TrainReader(Reader):
def generate_batch_from_trainfiles(self, files): def generate_batch_from_trainfiles(self, files):
data_set = self.base_read(files) data_set = self.base_read(files)
random.shuffle(data_set) random.shuffle(data_set)
return self.batch_reader(data_set, self.batch_size, self.batch_size * 20) return self.batch_reader(data_set, self.batch_size,
self.batch_size * 20)
...@@ -31,8 +31,10 @@ class Model(ModelBase): ...@@ -31,8 +31,10 @@ class Model(ModelBase):
def net(self): def net(self):
is_distributed = True if envs.get_trainer() == "CtrTrainer" else False is_distributed = True if envs.get_trainer() == "CtrTrainer" else False
sparse_feature_number = envs.get_global_env("hyper_parameters.sparse_feature_number", None, self._namespace) sparse_feature_number = envs.get_global_env(
sparse_feature_dim = envs.get_global_env("hyper_parameters.sparse_feature_dim", None, self._namespace) "hyper_parameters.sparse_feature_number", None, self._namespace)
sparse_feature_dim = envs.get_global_env(
"hyper_parameters.sparse_feature_dim", None, self._namespace)
def embedding_layer(input): def embedding_layer(input):
emb = fluid.layers.embedding( emb = fluid.layers.embedding(
...@@ -42,25 +44,27 @@ class Model(ModelBase): ...@@ -42,25 +44,27 @@ class Model(ModelBase):
size=[sparse_feature_number, sparse_feature_dim], size=[sparse_feature_number, sparse_feature_dim],
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(
name="SparseFeatFactors", name="SparseFeatFactors",
initializer=fluid.initializer.Uniform()), initializer=fluid.initializer.Uniform()), )
) emb_sum = fluid.layers.sequence_pool(input=emb, pool_type='sum')
emb_sum = fluid.layers.sequence_pool(
input=emb, pool_type='sum')
return emb_sum return emb_sum
def fc(input, output_size): def fc(input, output_size):
output = fluid.layers.fc( output = fluid.layers.fc(
input=input, size=output_size, input=input,
act='relu', param_attr=fluid.ParamAttr( size=output_size,
act='relu',
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.Normal( initializer=fluid.initializer.Normal(
scale=1.0 / math.sqrt(input.shape[1])))) scale=1.0 / math.sqrt(input.shape[1]))))
return output return output
sparse_embed_seq = list(map(embedding_layer, self.sparse_inputs)) sparse_embed_seq = list(map(embedding_layer, self.sparse_inputs))
concated = fluid.layers.concat(sparse_embed_seq + [self.dense_input], axis=1) concated = fluid.layers.concat(
sparse_embed_seq + [self.dense_input], axis=1)
fcs = [concated] fcs = [concated]
hidden_layers = envs.get_global_env("hyper_parameters.fc_sizes", None, self._namespace) hidden_layers = envs.get_global_env("hyper_parameters.fc_sizes", None,
self._namespace)
for size in hidden_layers: for size in hidden_layers:
fcs.append(fc(fcs[-1], size)) fcs.append(fc(fcs[-1], size))
...@@ -75,14 +79,15 @@ class Model(ModelBase): ...@@ -75,14 +79,15 @@ class Model(ModelBase):
self.predict = predict self.predict = predict
def avg_loss(self): def avg_loss(self):
cost = fluid.layers.cross_entropy(input=self.predict, label=self.label_input) cost = fluid.layers.cross_entropy(
input=self.predict, label=self.label_input)
avg_cost = fluid.layers.reduce_mean(cost) avg_cost = fluid.layers.reduce_mean(cost)
self._cost = avg_cost self._cost = avg_cost
def metrics(self): def metrics(self):
auc, batch_auc, _ = fluid.layers.auc(input=self.predict, auc, batch_auc, _ = fluid.layers.auc(input=self.predict,
label=self.label_input, label=self.label_input,
num_thresholds=2 ** 12, num_thresholds=2**12,
slide_steps=20) slide_steps=20)
self._metrics["AUC"] = auc self._metrics["AUC"] = auc
self._metrics["BATCH_AUC"] = batch_auc self._metrics["BATCH_AUC"] = batch_auc
...@@ -95,7 +100,8 @@ class Model(ModelBase): ...@@ -95,7 +100,8 @@ class Model(ModelBase):
self.metrics() self.metrics()
def optimizer(self): def optimizer(self):
learning_rate = envs.get_global_env("hyper_parameters.learning_rate", None, self._namespace) learning_rate = envs.get_global_env("hyper_parameters.learning_rate",
None, self._namespace)
optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True) optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True)
return optimizer return optimizer
......
...@@ -25,27 +25,27 @@ class Model(ModelBase): ...@@ -25,27 +25,27 @@ class Model(ModelBase):
ModelBase.__init__(self, config) ModelBase.__init__(self, config)
def wide_part(self, data): def wide_part(self, data):
out = fluid.layers.fc(input=data, out = fluid.layers.fc(
size=1, input=data,
param_attr=fluid.ParamAttr(initializer=fluid.initializer.TruncatedNormal(loc=0.0, size=1,
scale=1.0 / math.sqrt( param_attr=fluid.ParamAttr(
data.shape[ initializer=fluid.initializer.TruncatedNormal(
1])), loc=0.0, scale=1.0 / math.sqrt(data.shape[1])),
regularizer=fluid.regularizer.L2DecayRegularizer( regularizer=fluid.regularizer.L2DecayRegularizer(
regularization_coeff=1e-4)), regularization_coeff=1e-4)),
act=None, act=None,
name='wide') name='wide')
return out return out
def fc(self, data, hidden_units, active, tag): def fc(self, data, hidden_units, active, tag):
output = fluid.layers.fc(input=data, output = fluid.layers.fc(
size=hidden_units, input=data,
param_attr=fluid.ParamAttr(initializer=fluid.initializer.TruncatedNormal(loc=0.0, size=hidden_units,
scale=1.0 / math.sqrt( param_attr=fluid.ParamAttr(
data.shape[ initializer=fluid.initializer.TruncatedNormal(
1]))), loc=0.0, scale=1.0 / math.sqrt(data.shape[1]))),
act=active, act=active,
name=tag) name=tag)
return output return output
...@@ -62,43 +62,63 @@ class Model(ModelBase): ...@@ -62,43 +62,63 @@ class Model(ModelBase):
deep_input = self._dense_data_var[1] deep_input = self._dense_data_var[1]
label = self._sparse_data_var[0] label = self._sparse_data_var[0]
hidden1_units = envs.get_global_env("hyper_parameters.hidden1_units", 75, self._namespace) hidden1_units = envs.get_global_env("hyper_parameters.hidden1_units",
hidden2_units = envs.get_global_env("hyper_parameters.hidden2_units", 50, self._namespace) 75, self._namespace)
hidden3_units = envs.get_global_env("hyper_parameters.hidden3_units", 25, self._namespace) hidden2_units = envs.get_global_env("hyper_parameters.hidden2_units",
50, self._namespace)
hidden3_units = envs.get_global_env("hyper_parameters.hidden3_units",
25, self._namespace)
wide_output = self.wide_part(wide_input) wide_output = self.wide_part(wide_input)
deep_output = self.deep_part(deep_input, hidden1_units, hidden2_units, hidden3_units) deep_output = self.deep_part(deep_input, hidden1_units, hidden2_units,
hidden3_units)
wide_model = fluid.layers.fc(input=wide_output,
size=1, wide_model = fluid.layers.fc(
param_attr=fluid.ParamAttr( input=wide_output,
initializer=fluid.initializer.TruncatedNormal(loc=0.0, scale=1.0)), size=1,
act=None, param_attr=fluid.ParamAttr(
name='w_wide') initializer=fluid.initializer.TruncatedNormal(
loc=0.0, scale=1.0)),
deep_model = fluid.layers.fc(input=deep_output, act=None,
size=1, name='w_wide')
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.TruncatedNormal(loc=0.0, scale=1.0)), deep_model = fluid.layers.fc(
act=None, input=deep_output,
name='w_deep') size=1,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.TruncatedNormal(
loc=0.0, scale=1.0)),
act=None,
name='w_deep')
prediction = fluid.layers.elementwise_add(wide_model, deep_model) prediction = fluid.layers.elementwise_add(wide_model, deep_model)
pred = fluid.layers.sigmoid(fluid.layers.clip(prediction, min=-15.0, max=15.0), name="prediction") pred = fluid.layers.sigmoid(
fluid.layers.clip(
prediction, min=-15.0, max=15.0),
name="prediction")
num_seqs = fluid.layers.create_tensor(dtype='int64') num_seqs = fluid.layers.create_tensor(dtype='int64')
acc = fluid.layers.accuracy(input=pred, label=fluid.layers.cast(x=label, dtype='int64'), total=num_seqs) acc = fluid.layers.accuracy(
auc_var, batch_auc, auc_states = fluid.layers.auc(input=pred, label=fluid.layers.cast(x=label, dtype='int64')) input=pred,
label=fluid.layers.cast(
x=label, dtype='int64'),
total=num_seqs)
auc_var, batch_auc, auc_states = fluid.layers.auc(
input=pred, label=fluid.layers.cast(
x=label, dtype='int64'))
self._metrics["AUC"] = auc_var self._metrics["AUC"] = auc_var
self._metrics["BATCH_AUC"] = batch_auc self._metrics["BATCH_AUC"] = batch_auc
self._metrics["ACC"] = acc self._metrics["ACC"] = acc
cost = fluid.layers.sigmoid_cross_entropy_with_logits(x=prediction, label=fluid.layers.cast(label, dtype='float32')) cost = fluid.layers.sigmoid_cross_entropy_with_logits(
x=prediction, label=fluid.layers.cast(
label, dtype='float32'))
avg_cost = fluid.layers.mean(cost) avg_cost = fluid.layers.mean(cost)
self._cost = avg_cost self._cost = avg_cost
def optimizer(self): def optimizer(self):
learning_rate = envs.get_global_env("hyper_parameters.learning_rate", None, self._namespace) learning_rate = envs.get_global_env("hyper_parameters.learning_rate",
None, self._namespace)
optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True) optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True)
return optimizer return optimizer
......
...@@ -28,18 +28,22 @@ class Model(ModelBase): ...@@ -28,18 +28,22 @@ class Model(ModelBase):
loc=0.0, scale=init_value_) loc=0.0, scale=init_value_)
is_distributed = True if envs.get_trainer() == "CtrTrainer" else False is_distributed = True if envs.get_trainer() == "CtrTrainer" else False
sparse_feature_number = envs.get_global_env("hyper_parameters.sparse_feature_number", None, self._namespace) sparse_feature_number = envs.get_global_env(
sparse_feature_dim = envs.get_global_env("hyper_parameters.sparse_feature_dim", None, self._namespace) "hyper_parameters.sparse_feature_number", None, self._namespace)
sparse_feature_dim = envs.get_global_env(
"hyper_parameters.sparse_feature_dim", None, self._namespace)
# ------------------------- network input -------------------------- # ------------------------- network input --------------------------
num_field = envs.get_global_env("hyper_parameters.num_field", None, self._namespace) num_field = envs.get_global_env("hyper_parameters.num_field", None,
self._namespace)
raw_feat_idx = self._sparse_data_var[1] raw_feat_idx = self._sparse_data_var[1]
raw_feat_value = self._dense_data_var[0] raw_feat_value = self._dense_data_var[0]
self.label = self._sparse_data_var[0] self.label = self._sparse_data_var[0]
feat_idx = raw_feat_idx feat_idx = raw_feat_idx
feat_value = fluid.layers.reshape(raw_feat_value, [-1, num_field, 1]) # None * num_field * 1 feat_value = fluid.layers.reshape(
raw_feat_value, [-1, num_field, 1]) # None * num_field * 1
feat_embeddings = fluid.embedding( feat_embeddings = fluid.embedding(
input=feat_idx, input=feat_idx,
...@@ -48,9 +52,9 @@ class Model(ModelBase): ...@@ -48,9 +52,9 @@ class Model(ModelBase):
size=[sparse_feature_number + 1, sparse_feature_dim], size=[sparse_feature_number + 1, sparse_feature_dim],
padding_idx=0, padding_idx=0,
param_attr=fluid.ParamAttr(initializer=initer)) param_attr=fluid.ParamAttr(initializer=initer))
feat_embeddings = fluid.layers.reshape( feat_embeddings = fluid.layers.reshape(feat_embeddings, [
feat_embeddings, -1, num_field, sparse_feature_dim
[-1, num_field, sparse_feature_dim]) # None * num_field * embedding_size ]) # None * num_field * embedding_size
feat_embeddings = feat_embeddings * feat_value # None * num_field * embedding_size feat_embeddings = feat_embeddings * feat_value # None * num_field * embedding_size
# -------------------- linear -------------------- # -------------------- linear --------------------
...@@ -73,7 +77,8 @@ class Model(ModelBase): ...@@ -73,7 +77,8 @@ class Model(ModelBase):
# -------------------- CIN -------------------- # -------------------- CIN --------------------
layer_sizes_cin = envs.get_global_env("hyper_parameters.layer_sizes_cin", None, self._namespace) layer_sizes_cin = envs.get_global_env(
"hyper_parameters.layer_sizes_cin", None, self._namespace)
Xs = [feat_embeddings] Xs = [feat_embeddings]
last_s = num_field last_s = num_field
for s in layer_sizes_cin: for s in layer_sizes_cin:
...@@ -84,7 +89,8 @@ class Model(ModelBase): ...@@ -84,7 +89,8 @@ class Model(ModelBase):
1]) # None, embedding_size, num_field, 1 1]) # None, embedding_size, num_field, 1
X_k = fluid.layers.reshape( X_k = fluid.layers.reshape(
fluid.layers.transpose(Xs[-1], [0, 2, 1]), fluid.layers.transpose(Xs[-1], [0, 2, 1]),
[-1, sparse_feature_dim, 1, last_s]) # None, embedding_size, 1, last_s [-1, sparse_feature_dim, 1,
last_s]) # None, embedding_size, 1, last_s
Z_k_1 = fluid.layers.matmul( Z_k_1 = fluid.layers.matmul(
X_0, X_k) # None, embedding_size, num_field, last_s X_0, X_k) # None, embedding_size, num_field, last_s
...@@ -124,16 +130,19 @@ class Model(ModelBase): ...@@ -124,16 +130,19 @@ class Model(ModelBase):
# -------------------- DNN -------------------- # -------------------- DNN --------------------
layer_sizes_dnn = envs.get_global_env("hyper_parameters.layer_sizes_dnn", None, self._namespace) layer_sizes_dnn = envs.get_global_env(
act = envs.get_global_env("hyper_parameters.act", None, self._namespace) "hyper_parameters.layer_sizes_dnn", None, self._namespace)
act = envs.get_global_env("hyper_parameters.act", None,
self._namespace)
y_dnn = fluid.layers.reshape(feat_embeddings, y_dnn = fluid.layers.reshape(feat_embeddings,
[-1, num_field * sparse_feature_dim]) [-1, num_field * sparse_feature_dim])
for s in layer_sizes_dnn: for s in layer_sizes_dnn:
y_dnn = fluid.layers.fc(input=y_dnn, y_dnn = fluid.layers.fc(
size=s, input=y_dnn,
act=act, size=s,
param_attr=fluid.ParamAttr(initializer=initer), act=act,
bias_attr=None) param_attr=fluid.ParamAttr(initializer=initer),
bias_attr=None)
y_dnn = fluid.layers.fc(input=y_dnn, y_dnn = fluid.layers.fc(input=y_dnn,
size=1, size=1,
act=None, act=None,
...@@ -148,7 +157,10 @@ class Model(ModelBase): ...@@ -148,7 +157,10 @@ class Model(ModelBase):
self.model._init_slots() self.model._init_slots()
self.xdeepfm_net() self.xdeepfm_net()
cost = fluid.layers.log_loss(input=self.predict, label=fluid.layers.cast(self.label, "float32"), epsilon=0.0000001) cost = fluid.layers.log_loss(
input=self.predict,
label=fluid.layers.cast(self.label, "float32"),
epsilon=0.0000001)
batch_cost = fluid.layers.reduce_mean(cost) batch_cost = fluid.layers.reduce_mean(cost)
self._cost = batch_cost self._cost = batch_cost
...@@ -162,7 +174,8 @@ class Model(ModelBase): ...@@ -162,7 +174,8 @@ class Model(ModelBase):
self._metrics["BATCH_AUC"] = batch_auc_var self._metrics["BATCH_AUC"] = batch_auc_var
def optimizer(self): def optimizer(self):
learning_rate = envs.get_global_env("hyper_parameters.learning_rate", None, self._namespace) learning_rate = envs.get_global_env("hyper_parameters.learning_rate",
None, self._namespace)
optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True) optimizer = fluid.optimizer.Adam(learning_rate, lazy_mode=True)
return optimizer return optimizer
......
...@@ -23,7 +23,8 @@ from paddlerec.core.utils import envs ...@@ -23,7 +23,8 @@ from paddlerec.core.utils import envs
class EvaluateReader(Reader): class EvaluateReader(Reader):
def init(self): def init(self):
self.batch_size = envs.get_global_env("batch_size", None, "evaluate.reader") self.batch_size = envs.get_global_env("batch_size", None,
"evaluate.reader")
self.input = [] self.input = []
self.length = None self.length = None
...@@ -34,7 +35,8 @@ class EvaluateReader(Reader): ...@@ -34,7 +35,8 @@ class EvaluateReader(Reader):
with open(f, "r") as fin: with open(f, "r") as fin:
for line in fin: for line in fin:
line = line.strip().split('\t') line = line.strip().split('\t')
res.append(tuple([map(int, line[0].split(',')), int(line[1])])) res.append(
tuple([map(int, line[0].split(',')), int(line[1])]))
return res return res
def make_data(self, cur_batch, batch_size): def make_data(self, cur_batch, batch_size):
...@@ -75,10 +77,8 @@ class EvaluateReader(Reader): ...@@ -75,10 +77,8 @@ class EvaluateReader(Reader):
u_deg_out[np.where(u_deg_out == 0)] = 1 u_deg_out[np.where(u_deg_out == 0)] = 1
adj_out.append(np.divide(adj.transpose(), u_deg_out).transpose()) adj_out.append(np.divide(adj.transpose(), u_deg_out).transpose())
seq_index.append( seq_index.append([[id, np.where(node == i)[0][0]] for i in e[0]])
[[id, np.where(node == i)[0][0]] for i in e[0]]) last_index.append([id, np.where(node == e[0][last_id[id]])[0][0]])
last_index.append(
[id, np.where(node == e[0][last_id[id]])[0][0]])
label.append(e[1] - 1) label.append(e[1] - 1)
mask.append([[1] * (last_id[id] + 1) + [0] * mask.append([[1] * (last_id[id] + 1) + [0] *
(max_seq_len - last_id[id] - 1)]) (max_seq_len - last_id[id] - 1)])
...@@ -101,10 +101,13 @@ class EvaluateReader(Reader): ...@@ -101,10 +101,13 @@ class EvaluateReader(Reader):
def _reader(): def _reader():
random.shuffle(self.input) random.shuffle(self.input)
group_remain = self.length % batch_group_size group_remain = self.length % batch_group_size
for bg_id in range(0, self.length - group_remain, batch_group_size): for bg_id in range(0, self.length - group_remain,
cur_bg = copy.deepcopy(self.input[bg_id:bg_id + batch_group_size]) batch_group_size):
cur_bg = copy.deepcopy(self.input[bg_id:bg_id +
batch_group_size])
if train: if train:
cur_bg = sorted(cur_bg, key=lambda x: len(x[0]), reverse=True) cur_bg = sorted(
cur_bg, key=lambda x: len(x[0]), reverse=True)
for i in range(0, batch_group_size, batch_size): for i in range(0, batch_group_size, batch_size):
cur_batch = cur_bg[i:i + batch_size] cur_batch = cur_bg[i:i + batch_size]
yield self.make_data(cur_batch, batch_size) yield self.make_data(cur_batch, batch_size)
......
...@@ -30,15 +30,21 @@ class Model(ModelBase): ...@@ -30,15 +30,21 @@ class Model(ModelBase):
def init_config(self): def init_config(self):
self._fetch_interval = 1 self._fetch_interval = 1
self.items_num, self.ins_num = self.config_read( self.items_num, self.ins_num = self.config_read(
envs.get_global_env("hyper_parameters.config_path", None, self._namespace)) envs.get_global_env("hyper_parameters.config_path", None,
self.train_batch_size = envs.get_global_env("batch_size", None, "train.reader") self._namespace))
self.evaluate_batch_size = envs.get_global_env("batch_size", None, "evaluate.reader") self.train_batch_size = envs.get_global_env("batch_size", None,
self.hidden_size = envs.get_global_env("hyper_parameters.sparse_feature_dim", None, self._namespace) "train.reader")
self.step = envs.get_global_env("hyper_parameters.gnn_propogation_steps", None, self._namespace) self.evaluate_batch_size = envs.get_global_env("batch_size", None,
"evaluate.reader")
self.hidden_size = envs.get_global_env(
"hyper_parameters.sparse_feature_dim", None, self._namespace)
self.step = envs.get_global_env(
"hyper_parameters.gnn_propogation_steps", None, self._namespace)
def config_read(self, config_path=None): def config_read(self, config_path=None):
if config_path is None: if config_path is None:
raise ValueError("please set train.model.hyper_parameters.config_path at first") raise ValueError(
"please set train.model.hyper_parameters.config_path at first")
with open(config_path, "r") as fin: with open(config_path, "r") as fin:
item_nums = int(fin.readline().strip()) item_nums = int(fin.readline().strip())
ins_nums = int(fin.readline().strip()) ins_nums = int(fin.readline().strip())
...@@ -46,100 +52,108 @@ class Model(ModelBase): ...@@ -46,100 +52,108 @@ class Model(ModelBase):
def input(self, bs): def input(self, bs):
self.items = fluid.data( self.items = fluid.data(
name="items", name="items", shape=[bs, -1],
shape=[bs, -1],
dtype="int64") # [batch_size, uniq_max] dtype="int64") # [batch_size, uniq_max]
self.seq_index = fluid.data( self.seq_index = fluid.data(
name="seq_index", name="seq_index", shape=[bs, -1, 2],
shape=[bs, -1, 2],
dtype="int32") # [batch_size, seq_max, 2] dtype="int32") # [batch_size, seq_max, 2]
self.last_index = fluid.data( self.last_index = fluid.data(
name="last_index", name="last_index", shape=[bs, 2], dtype="int32") # [batch_size, 2]
shape=[bs, 2],
dtype="int32") # [batch_size, 2]
self.adj_in = fluid.data( self.adj_in = fluid.data(
name="adj_in", name="adj_in", shape=[bs, -1, -1],
shape=[bs, -1, -1],
dtype="float32") # [batch_size, seq_max, seq_max] dtype="float32") # [batch_size, seq_max, seq_max]
self.adj_out = fluid.data( self.adj_out = fluid.data(
name="adj_out", name="adj_out", shape=[bs, -1, -1],
shape=[bs, -1, -1],
dtype="float32") # [batch_size, seq_max, seq_max] dtype="float32") # [batch_size, seq_max, seq_max]
self.mask = fluid.data( self.mask = fluid.data(
name="mask", name="mask", shape=[bs, -1, 1],
shape=[bs, -1, 1],
dtype="float32") # [batch_size, seq_max, 1] dtype="float32") # [batch_size, seq_max, 1]
self.label = fluid.data( self.label = fluid.data(
name="label", name="label", shape=[bs, 1], dtype="int64") # [batch_size, 1]
shape=[bs, 1],
dtype="int64") # [batch_size, 1]
res = [self.items, self.seq_index, self.last_index, self.adj_in, self.adj_out, self.mask, self.label] res = [
self.items, self.seq_index, self.last_index, self.adj_in,
self.adj_out, self.mask, self.label
]
return res return res
def train_input(self): def train_input(self):
res = self.input(self.train_batch_size) res = self.input(self.train_batch_size)
self._data_var = res self._data_var = res
use_dataloader = envs.get_global_env("hyper_parameters.use_DataLoader", False, self._namespace) use_dataloader = envs.get_global_env("hyper_parameters.use_DataLoader",
False, self._namespace)
if self._platform != "LINUX" or use_dataloader: if self._platform != "LINUX" or use_dataloader:
self._data_loader = fluid.io.DataLoader.from_generator( self._data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._data_var, capacity=256, use_double_buffer=False, iterable=False) feed_list=self._data_var,
capacity=256,
use_double_buffer=False,
iterable=False)
def net(self, items_num, hidden_size, step, bs): def net(self, items_num, hidden_size, step, bs):
stdv = 1.0 / math.sqrt(hidden_size) stdv = 1.0 / math.sqrt(hidden_size)
def embedding_layer(input, table_name, emb_dim, initializer_instance=None): def embedding_layer(input,
table_name,
emb_dim,
initializer_instance=None):
emb = fluid.embedding( emb = fluid.embedding(
input=input, input=input,
size=[items_num, emb_dim], size=[items_num, emb_dim],
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(
name=table_name, name=table_name, initializer=initializer_instance), )
initializer=initializer_instance),
)
return emb return emb
sparse_initializer = fluid.initializer.Uniform(low=-stdv, high=stdv) sparse_initializer = fluid.initializer.Uniform(low=-stdv, high=stdv)
items_emb = embedding_layer(self.items, "emb", hidden_size, sparse_initializer) items_emb = embedding_layer(self.items, "emb", hidden_size,
sparse_initializer)
pre_state = items_emb pre_state = items_emb
for i in range(step): for i in range(step):
pre_state = layers.reshape(x=pre_state, shape=[bs, -1, hidden_size]) pre_state = layers.reshape(
x=pre_state, shape=[bs, -1, hidden_size])
state_in = layers.fc( state_in = layers.fc(
input=pre_state, input=pre_state,
name="state_in", name="state_in",
size=hidden_size, size=hidden_size,
act=None, act=None,
num_flatten_dims=2, num_flatten_dims=2,
param_attr=fluid.ParamAttr(initializer=fluid.initializer.Uniform( param_attr=fluid.ParamAttr(
low=-stdv, high=stdv)), initializer=fluid.initializer.Uniform(
bias_attr=fluid.ParamAttr(initializer=fluid.initializer.Uniform( low=-stdv, high=stdv)),
low=-stdv, high=stdv))) # [batch_size, uniq_max, h] bias_attr=fluid.ParamAttr(
initializer=fluid.initializer.Uniform(
low=-stdv, high=stdv))) # [batch_size, uniq_max, h]
state_out = layers.fc( state_out = layers.fc(
input=pre_state, input=pre_state,
name="state_out", name="state_out",
size=hidden_size, size=hidden_size,
act=None, act=None,
num_flatten_dims=2, num_flatten_dims=2,
param_attr=fluid.ParamAttr(initializer=fluid.initializer.Uniform( param_attr=fluid.ParamAttr(
low=-stdv, high=stdv)), initializer=fluid.initializer.Uniform(
bias_attr=fluid.ParamAttr(initializer=fluid.initializer.Uniform( low=-stdv, high=stdv)),
low=-stdv, high=stdv))) # [batch_size, uniq_max, h] bias_attr=fluid.ParamAttr(
initializer=fluid.initializer.Uniform(
low=-stdv, high=stdv))) # [batch_size, uniq_max, h]
state_adj_in = layers.matmul(self.adj_in, state_in) # [batch_size, uniq_max, h] state_adj_in = layers.matmul(self.adj_in,
state_adj_out = layers.matmul(self.adj_out, state_out) # [batch_size, uniq_max, h] state_in) # [batch_size, uniq_max, h]
state_adj_out = layers.matmul(
self.adj_out, state_out) # [batch_size, uniq_max, h]
gru_input = layers.concat([state_adj_in, state_adj_out], axis=2) gru_input = layers.concat([state_adj_in, state_adj_out], axis=2)
gru_input = layers.reshape(x=gru_input, shape=[-1, hidden_size * 2]) gru_input = layers.reshape(
gru_fc = layers.fc( x=gru_input, shape=[-1, hidden_size * 2])
input=gru_input, gru_fc = layers.fc(input=gru_input,
name="gru_fc", name="gru_fc",
size=3 * hidden_size, size=3 * hidden_size,
bias_attr=False) bias_attr=False)
pre_state, _, _ = fluid.layers.gru_unit( pre_state, _, _ = fluid.layers.gru_unit(
input=gru_fc, input=gru_fc,
hidden=layers.reshape(x=pre_state, shape=[-1, hidden_size]), hidden=layers.reshape(
x=pre_state, shape=[-1, hidden_size]),
size=3 * hidden_size) size=3 * hidden_size)
final_state = layers.reshape(pre_state, shape=[bs, -1, hidden_size]) final_state = layers.reshape(pre_state, shape=[bs, -1, hidden_size])
...@@ -153,24 +167,22 @@ class Model(ModelBase): ...@@ -153,24 +167,22 @@ class Model(ModelBase):
bias_attr=False, bias_attr=False,
act=None, act=None,
num_flatten_dims=2, num_flatten_dims=2,
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(initializer=fluid.initializer.Uniform(
initializer=fluid.initializer.Uniform( low=-stdv, high=stdv))) # [batch_size, seq_max, h]
low=-stdv, high=stdv))) # [batch_size, seq_max, h] last_fc = layers.fc(input=last,
last_fc = layers.fc( name="last_fc",
input=last, size=hidden_size,
name="last_fc", bias_attr=False,
size=hidden_size, act=None,
bias_attr=False, num_flatten_dims=1,
act=None, param_attr=fluid.ParamAttr(
num_flatten_dims=1, initializer=fluid.initializer.Uniform(
param_attr=fluid.ParamAttr( low=-stdv, high=stdv))) # [bathc_size, h]
initializer=fluid.initializer.Uniform(
low=-stdv, high=stdv))) # [bathc_size, h]
seq_fc_t = layers.transpose( seq_fc_t = layers.transpose(
seq_fc, perm=[1, 0, 2]) # [seq_max, batch_size, h] seq_fc, perm=[1, 0, 2]) # [seq_max, batch_size, h]
add = layers.elementwise_add( add = layers.elementwise_add(seq_fc_t,
seq_fc_t, last_fc) # [seq_max, batch_size, h] last_fc) # [seq_max, batch_size, h]
b = layers.create_parameter( b = layers.create_parameter(
shape=[hidden_size], shape=[hidden_size],
dtype='float32', dtype='float32',
...@@ -188,12 +200,13 @@ class Model(ModelBase): ...@@ -188,12 +200,13 @@ class Model(ModelBase):
act=None, act=None,
num_flatten_dims=2, num_flatten_dims=2,
bias_attr=False, bias_attr=False,
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(initializer=fluid.initializer.Uniform(
initializer=fluid.initializer.Uniform( low=-stdv, high=stdv))) # [batch_size, seq_max, 1]
low=-stdv, high=stdv))) # [batch_size, seq_max, 1]
weight *= self.mask weight *= self.mask
weight_mask = layers.elementwise_mul(seq, weight, axis=0) # [batch_size, seq_max, h] weight_mask = layers.elementwise_mul(
global_attention = layers.reduce_sum(weight_mask, dim=1) # [batch_size, h] seq, weight, axis=0) # [batch_size, seq_max, h]
global_attention = layers.reduce_sum(
weight_mask, dim=1) # [batch_size, h]
final_attention = layers.concat( final_attention = layers.concat(
[global_attention, last], axis=1) # [batch_size, 2*h] [global_attention, last], axis=1) # [batch_size, 2*h]
...@@ -213,7 +226,8 @@ class Model(ModelBase): ...@@ -213,7 +226,8 @@ class Model(ModelBase):
# persistable=True, # persistable=True,
# name="all_vocab") # name="all_vocab")
all_vocab = np.arange(1, items_num).reshape((-1)).astype('int32') all_vocab = np.arange(1, items_num).reshape((-1)).astype('int32')
all_vocab = fluid.layers.cast(x=fluid.layers.assign(all_vocab), dtype='int64') all_vocab = fluid.layers.cast(
x=fluid.layers.assign(all_vocab), dtype='int64')
all_emb = fluid.embedding( all_emb = fluid.embedding(
input=all_vocab, input=all_vocab,
...@@ -240,15 +254,19 @@ class Model(ModelBase): ...@@ -240,15 +254,19 @@ class Model(ModelBase):
def train_net(self): def train_net(self):
self.train_input() self.train_input()
self.net(self.items_num, self.hidden_size, self.step, self.train_batch_size) self.net(self.items_num, self.hidden_size, self.step,
self.train_batch_size)
self.avg_loss() self.avg_loss()
self.metrics() self.metrics()
def optimizer(self): def optimizer(self):
learning_rate = envs.get_global_env("hyper_parameters.learning_rate", None, self._namespace) learning_rate = envs.get_global_env("hyper_parameters.learning_rate",
None, self._namespace)
step_per_epoch = self.ins_num // self.train_batch_size step_per_epoch = self.ins_num // self.train_batch_size
decay_steps = envs.get_global_env("hyper_parameters.decay_steps", None, self._namespace) decay_steps = envs.get_global_env("hyper_parameters.decay_steps", None,
decay_rate = envs.get_global_env("hyper_parameters.decay_rate", None, self._namespace) self._namespace)
decay_rate = envs.get_global_env("hyper_parameters.decay_rate", None,
self._namespace)
l2 = envs.get_global_env("hyper_parameters.l2", None, self._namespace) l2 = envs.get_global_env("hyper_parameters.l2", None, self._namespace)
optimizer = fluid.optimizer.Adam( optimizer = fluid.optimizer.Adam(
learning_rate=fluid.layers.exponential_decay( learning_rate=fluid.layers.exponential_decay(
...@@ -266,10 +284,14 @@ class Model(ModelBase): ...@@ -266,10 +284,14 @@ class Model(ModelBase):
self._infer_data_var = res self._infer_data_var = res
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
def infer_net(self): def infer_net(self):
self.infer_input() self.infer_input()
self.net(self.items_num, self.hidden_size, self.step, self.evaluate_batch_size) self.net(self.items_num, self.hidden_size, self.step,
self.evaluate_batch_size)
self._infer_results['acc'] = self.acc self._infer_results['acc'] = self.acc
self._infer_results['loss'] = self.loss self._infer_results['loss'] = self.loss
...@@ -23,7 +23,8 @@ from paddlerec.core.utils import envs ...@@ -23,7 +23,8 @@ from paddlerec.core.utils import envs
class TrainReader(Reader): class TrainReader(Reader):
def init(self): def init(self):
self.batch_size = envs.get_global_env("batch_size", None, "train.reader") self.batch_size = envs.get_global_env("batch_size", None,
"train.reader")
self.input = [] self.input = []
self.length = None self.length = None
...@@ -34,7 +35,8 @@ class TrainReader(Reader): ...@@ -34,7 +35,8 @@ class TrainReader(Reader):
with open(f, "r") as fin: with open(f, "r") as fin:
for line in fin: for line in fin:
line = line.strip().split('\t') line = line.strip().split('\t')
res.append(tuple([map(int, line[0].split(',')), int(line[1])])) res.append(
tuple([map(int, line[0].split(',')), int(line[1])]))
return res return res
def make_data(self, cur_batch, batch_size): def make_data(self, cur_batch, batch_size):
...@@ -75,10 +77,8 @@ class TrainReader(Reader): ...@@ -75,10 +77,8 @@ class TrainReader(Reader):
u_deg_out[np.where(u_deg_out == 0)] = 1 u_deg_out[np.where(u_deg_out == 0)] = 1
adj_out.append(np.divide(adj.transpose(), u_deg_out).transpose()) adj_out.append(np.divide(adj.transpose(), u_deg_out).transpose())
seq_index.append( seq_index.append([[id, np.where(node == i)[0][0]] for i in e[0]])
[[id, np.where(node == i)[0][0]] for i in e[0]]) last_index.append([id, np.where(node == e[0][last_id[id]])[0][0]])
last_index.append(
[id, np.where(node == e[0][last_id[id]])[0][0]])
label.append(e[1] - 1) label.append(e[1] - 1)
mask.append([[1] * (last_id[id] + 1) + [0] * mask.append([[1] * (last_id[id] + 1) + [0] *
(max_seq_len - last_id[id] - 1)]) (max_seq_len - last_id[id] - 1)])
...@@ -101,10 +101,13 @@ class TrainReader(Reader): ...@@ -101,10 +101,13 @@ class TrainReader(Reader):
def _reader(): def _reader():
random.shuffle(self.input) random.shuffle(self.input)
group_remain = self.length % batch_group_size group_remain = self.length % batch_group_size
for bg_id in range(0, self.length - group_remain, batch_group_size): for bg_id in range(0, self.length - group_remain,
cur_bg = copy.deepcopy(self.input[bg_id:bg_id + batch_group_size]) batch_group_size):
cur_bg = copy.deepcopy(self.input[bg_id:bg_id +
batch_group_size])
if train: if train:
cur_bg = sorted(cur_bg, key=lambda x: len(x[0]), reverse=True) cur_bg = sorted(
cur_bg, key=lambda x: len(x[0]), reverse=True)
for i in range(0, batch_group_size, batch_size): for i in range(0, batch_group_size, batch_size):
cur_batch = cur_bg[i:i + batch_size] cur_batch = cur_bg[i:i + batch_size]
yield self.make_data(cur_batch, batch_size) yield self.make_data(cur_batch, batch_size)
......
...@@ -24,14 +24,22 @@ class Model(ModelBase): ...@@ -24,14 +24,22 @@ class Model(ModelBase):
def all_vocab_network(self, is_infer=False): def all_vocab_network(self, is_infer=False):
""" network definition """ """ network definition """
recall_k = envs.get_global_env("hyper_parameters.recall_k", None, self._namespace) recall_k = envs.get_global_env("hyper_parameters.recall_k", None,
vocab_size = envs.get_global_env("hyper_parameters.vocab_size", None, self._namespace) self._namespace)
hid_size = envs.get_global_env("hyper_parameters.hid_size", None, self._namespace) vocab_size = envs.get_global_env("hyper_parameters.vocab_size", None,
init_low_bound = envs.get_global_env("hyper_parameters.init_low_bound", None, self._namespace) self._namespace)
init_high_bound = envs.get_global_env("hyper_parameters.init_high_bound", None, self._namespace) hid_size = envs.get_global_env("hyper_parameters.hid_size", None,
emb_lr_x = envs.get_global_env("hyper_parameters.emb_lr_x", None, self._namespace) self._namespace)
gru_lr_x = envs.get_global_env("hyper_parameters.gru_lr_x", None, self._namespace) init_low_bound = envs.get_global_env("hyper_parameters.init_low_bound",
fc_lr_x = envs.get_global_env("hyper_parameters.fc_lr_x", None, self._namespace) None, self._namespace)
init_high_bound = envs.get_global_env(
"hyper_parameters.init_high_bound", None, self._namespace)
emb_lr_x = envs.get_global_env("hyper_parameters.emb_lr_x", None,
self._namespace)
gru_lr_x = envs.get_global_env("hyper_parameters.gru_lr_x", None,
self._namespace)
fc_lr_x = envs.get_global_env("hyper_parameters.fc_lr_x", None,
self._namespace)
# Input data # Input data
src_wordseq = fluid.data( src_wordseq = fluid.data(
name="src_wordseq", shape=[None, 1], dtype="int64", lod_level=1) name="src_wordseq", shape=[None, 1], dtype="int64", lod_level=1)
...@@ -41,7 +49,10 @@ class Model(ModelBase): ...@@ -41,7 +49,10 @@ class Model(ModelBase):
if is_infer: if is_infer:
self._infer_data_var = [src_wordseq, dst_wordseq] self._infer_data_var = [src_wordseq, dst_wordseq]
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
emb = fluid.embedding( emb = fluid.embedding(
input=src_wordseq, input=src_wordseq,
...@@ -56,7 +67,8 @@ class Model(ModelBase): ...@@ -56,7 +67,8 @@ class Model(ModelBase):
size=hid_size * 3, size=hid_size * 3,
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(
initializer=fluid.initializer.Uniform( initializer=fluid.initializer.Uniform(
low=init_low_bound, high=init_high_bound), low=init_low_bound,
high=init_high_bound),
learning_rate=gru_lr_x)) learning_rate=gru_lr_x))
gru_h0 = fluid.layers.dynamic_gru( gru_h0 = fluid.layers.dynamic_gru(
input=fc0, input=fc0,
......
...@@ -25,9 +25,12 @@ class Model(ModelBase): ...@@ -25,9 +25,12 @@ class Model(ModelBase):
ModelBase.__init__(self, config) ModelBase.__init__(self, config)
def input_data(self, is_infer=False): def input_data(self, is_infer=False):
user_input = fluid.data(name="user_input", shape=[-1, 1], dtype="int64", lod_level=0) user_input = fluid.data(
item_input = fluid.data(name="item_input", shape=[-1, 1], dtype="int64", lod_level=0) name="user_input", shape=[-1, 1], dtype="int64", lod_level=0)
label = fluid.data(name="label", shape=[-1, 1], dtype="int64", lod_level=0) item_input = fluid.data(
name="item_input", shape=[-1, 1], dtype="int64", lod_level=0)
label = fluid.data(
name="label", shape=[-1, 1], dtype="int64", lod_level=0)
if is_infer: if is_infer:
inputs = [user_input] + [item_input] inputs = [user_input] + [item_input]
else: else:
...@@ -35,81 +38,104 @@ class Model(ModelBase): ...@@ -35,81 +38,104 @@ class Model(ModelBase):
self._data_var = inputs self._data_var = inputs
return inputs return inputs
def net(self, inputs, is_infer=False): def net(self, inputs, is_infer=False):
num_users = envs.get_global_env("hyper_parameters.num_users", None, self._namespace) num_users = envs.get_global_env("hyper_parameters.num_users", None,
num_items = envs.get_global_env("hyper_parameters.num_items", None, self._namespace) self._namespace)
latent_dim = envs.get_global_env("hyper_parameters.latent_dim", None, self._namespace) num_items = envs.get_global_env("hyper_parameters.num_items", None,
layers = envs.get_global_env("hyper_parameters.layers", None, self._namespace) self._namespace)
latent_dim = envs.get_global_env("hyper_parameters.latent_dim", None,
num_layer = len(layers) #Number of layers in the MLP self._namespace)
layers = envs.get_global_env("hyper_parameters.layers", None,
MF_Embedding_User = fluid.embedding(input=inputs[0], self._namespace)
size=[num_users, latent_dim],
param_attr=fluid.initializer.Normal(loc=0.0, scale=0.01), num_layer = len(layers) #Number of layers in the MLP
is_sparse=True)
MF_Embedding_Item = fluid.embedding(input=inputs[1], MF_Embedding_User = fluid.embedding(
size=[num_items, latent_dim], input=inputs[0],
param_attr=fluid.initializer.Normal(loc=0.0, scale=0.01), size=[num_users, latent_dim],
is_sparse=True) param_attr=fluid.initializer.Normal(
loc=0.0, scale=0.01),
MLP_Embedding_User = fluid.embedding(input=inputs[0], is_sparse=True)
size=[num_users, int(layers[0] / 2)], MF_Embedding_Item = fluid.embedding(
param_attr=fluid.initializer.Normal(loc=0.0, scale=0.01), input=inputs[1],
is_sparse=True) size=[num_items, latent_dim],
MLP_Embedding_Item = fluid.embedding(input=inputs[1], param_attr=fluid.initializer.Normal(
size=[num_items, int(layers[0] / 2)], loc=0.0, scale=0.01),
param_attr=fluid.initializer.Normal(loc=0.0, scale=0.01), is_sparse=True)
is_sparse=True)
MLP_Embedding_User = fluid.embedding(
input=inputs[0],
size=[num_users, int(layers[0] / 2)],
param_attr=fluid.initializer.Normal(
loc=0.0, scale=0.01),
is_sparse=True)
MLP_Embedding_Item = fluid.embedding(
input=inputs[1],
size=[num_items, int(layers[0] / 2)],
param_attr=fluid.initializer.Normal(
loc=0.0, scale=0.01),
is_sparse=True)
# MF part # MF part
mf_user_latent = fluid.layers.flatten(x=MF_Embedding_User, axis=1) mf_user_latent = fluid.layers.flatten(x=MF_Embedding_User, axis=1)
mf_item_latent = fluid.layers.flatten(x=MF_Embedding_Item, axis=1) mf_item_latent = fluid.layers.flatten(x=MF_Embedding_Item, axis=1)
mf_vector = fluid.layers.elementwise_mul(mf_user_latent, mf_item_latent) mf_vector = fluid.layers.elementwise_mul(mf_user_latent,
mf_item_latent)
# MLP part # MLP part
# The 0-th layer is the concatenation of embedding layers # The 0-th layer is the concatenation of embedding layers
mlp_user_latent = fluid.layers.flatten(x=MLP_Embedding_User, axis=1) mlp_user_latent = fluid.layers.flatten(x=MLP_Embedding_User, axis=1)
mlp_item_latent = fluid.layers.flatten(x=MLP_Embedding_Item, axis=1) mlp_item_latent = fluid.layers.flatten(x=MLP_Embedding_Item, axis=1)
mlp_vector = fluid.layers.concat(input=[mlp_user_latent, mlp_item_latent], axis=-1) mlp_vector = fluid.layers.concat(
input=[mlp_user_latent, mlp_item_latent], axis=-1)
for i in range(1, num_layer): for i in range(1, num_layer):
mlp_vector = fluid.layers.fc(input=mlp_vector, mlp_vector = fluid.layers.fc(
size=layers[i], input=mlp_vector,
act='relu', size=layers[i],
param_attr=fluid.ParamAttr(initializer=fluid.initializer.TruncatedNormal(loc=0.0, scale=1.0 / math.sqrt(mlp_vector.shape[1])), act='relu',
regularizer=fluid.regularizer.L2DecayRegularizer(regularization_coeff=1e-4)), param_attr=fluid.ParamAttr(
name='layer_' + str(i)) initializer=fluid.initializer.TruncatedNormal(
loc=0.0, scale=1.0 / math.sqrt(mlp_vector.shape[1])),
regularizer=fluid.regularizer.L2DecayRegularizer(
regularization_coeff=1e-4)),
name='layer_' + str(i))
# Concatenate MF and MLP parts # Concatenate MF and MLP parts
predict_vector = fluid.layers.concat(input=[mf_vector, mlp_vector], axis=-1) predict_vector = fluid.layers.concat(
input=[mf_vector, mlp_vector], axis=-1)
# Final prediction layer # Final prediction layer
prediction = fluid.layers.fc(input=predict_vector, prediction = fluid.layers.fc(
size=1, input=predict_vector,
act='sigmoid', size=1,
param_attr=fluid.initializer.MSRAInitializer(uniform=True), act='sigmoid',
name='prediction') param_attr=fluid.initializer.MSRAInitializer(uniform=True),
name='prediction')
if is_infer: if is_infer:
self._infer_results["prediction"] = prediction self._infer_results["prediction"] = prediction
return return
cost = fluid.layers.log_loss(input=prediction, label=fluid.layers.cast(x=inputs[2], dtype='float32')) cost = fluid.layers.log_loss(
input=prediction,
label=fluid.layers.cast(
x=inputs[2], dtype='float32'))
avg_cost = fluid.layers.mean(cost) avg_cost = fluid.layers.mean(cost)
self._cost = avg_cost self._cost = avg_cost
self._metrics["cost"] = avg_cost self._metrics["cost"] = avg_cost
def train_net(self): def train_net(self):
input_data = self.input_data() input_data = self.input_data()
self.net(input_data) self.net(input_data)
def infer_net(self): def infer_net(self):
self._infer_data_var = self.input_data(is_infer=True) self._infer_data_var = self.input_data(is_infer=True)
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
self.net(self._infer_data_var, is_infer=True) self.net(self._infer_data_var, is_infer=True)
...@@ -33,7 +33,9 @@ class EvaluateReader(Reader): ...@@ -33,7 +33,9 @@ class EvaluateReader(Reader):
This function needs to be implemented by the user, based on data format This function needs to be implemented by the user, based on data format
""" """
features = line.strip().split(',') features = line.strip().split(',')
feature_name = ["user_input", "item_input"] feature_name = ["user_input", "item_input"]
yield zip(feature_name, [[int(features[0])]] + [[int(features[1])]]) yield zip(feature_name,
[[int(features[0])]] + [[int(features[1])]])
return reader return reader
...@@ -33,10 +33,9 @@ class TrainReader(Reader): ...@@ -33,10 +33,9 @@ class TrainReader(Reader):
This function needs to be implemented by the user, based on data format This function needs to be implemented by the user, based on data format
""" """
features = line.strip().split(',') features = line.strip().split(',')
feature_name = ["user_input", "item_input", "label"] feature_name = ["user_input", "item_input", "label"]
yield zip(feature_name, [[int(features[0])]] + [[int(features[1])]] + [[int(features[2])]]) yield zip(feature_name, [[int(features[0])]] +
[[int(features[1])]] + [[int(features[2])]])
return reader return reader
...@@ -79,9 +79,12 @@ class Model(ModelBase): ...@@ -79,9 +79,12 @@ class Model(ModelBase):
return correct return correct
def train(self): def train(self):
vocab_size = envs.get_global_env("hyper_parameters.vocab_size", None, self._namespace) vocab_size = envs.get_global_env("hyper_parameters.vocab_size", None,
emb_dim = envs.get_global_env("hyper_parameters.emb_dim", None, self._namespace) self._namespace)
hidden_size = envs.get_global_env("hyper_parameters.hidden_size", None, self._namespace) emb_dim = envs.get_global_env("hyper_parameters.emb_dim", None,
self._namespace)
hidden_size = envs.get_global_env("hyper_parameters.hidden_size", None,
self._namespace)
emb_shape = [vocab_size, emb_dim] emb_shape = [vocab_size, emb_dim]
self.user_encoder = GrnnEncoder() self.user_encoder = GrnnEncoder()
...@@ -131,24 +134,34 @@ class Model(ModelBase): ...@@ -131,24 +134,34 @@ class Model(ModelBase):
self.train() self.train()
def infer(self): def infer(self):
vocab_size = envs.get_global_env("hyper_parameters.vocab_size", None, self._namespace) vocab_size = envs.get_global_env("hyper_parameters.vocab_size", None,
emb_dim = envs.get_global_env("hyper_parameters.emb_dim", None, self._namespace) self._namespace)
hidden_size = envs.get_global_env("hyper_parameters.hidden_size", None, self._namespace) emb_dim = envs.get_global_env("hyper_parameters.emb_dim", None,
self._namespace)
hidden_size = envs.get_global_env("hyper_parameters.hidden_size", None,
self._namespace)
user_data = fluid.data( user_data = fluid.data(
name="user", shape=[None, 1], dtype="int64", lod_level=1) name="user", shape=[None, 1], dtype="int64", lod_level=1)
all_item_data = fluid.data( all_item_data = fluid.data(
name="all_item", shape=[None, vocab_size], dtype="int64") name="all_item", shape=[None, vocab_size], dtype="int64")
pos_label = fluid.data(name="pos_label", shape=[None, 1], dtype="int64") pos_label = fluid.data(
name="pos_label", shape=[None, 1], dtype="int64")
self._infer_data_var = [user_data, all_item_data, pos_label] self._infer_data_var = [user_data, all_item_data, pos_label]
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
user_emb = fluid.embedding( user_emb = fluid.embedding(
input=user_data, size=[vocab_size, emb_dim], param_attr="emb.item") input=user_data, size=[vocab_size, emb_dim], param_attr="emb.item")
all_item_emb = fluid.embedding( all_item_emb = fluid.embedding(
input=all_item_data, size=[vocab_size, emb_dim], param_attr="emb.item") input=all_item_data,
all_item_emb_re = fluid.layers.reshape(x=all_item_emb, shape=[-1, emb_dim]) size=[vocab_size, emb_dim],
param_attr="emb.item")
all_item_emb_re = fluid.layers.reshape(
x=all_item_emb, shape=[-1, emb_dim])
user_encoder = GrnnEncoder() user_encoder = GrnnEncoder()
user_enc = user_encoder.forward(user_emb) user_enc = user_encoder.forward(user_emb)
...@@ -156,7 +169,8 @@ class Model(ModelBase): ...@@ -156,7 +169,8 @@ class Model(ModelBase):
size=hidden_size, size=hidden_size,
param_attr='user.w', param_attr='user.w',
bias_attr="user.b") bias_attr="user.b")
user_exp = fluid.layers.expand(x=user_hid, expand_times=[1, vocab_size]) user_exp = fluid.layers.expand(
x=user_hid, expand_times=[1, vocab_size])
user_re = fluid.layers.reshape(x=user_exp, shape=[-1, hidden_size]) user_re = fluid.layers.reshape(x=user_exp, shape=[-1, hidden_size])
all_item_hid = fluid.layers.fc(input=all_item_emb_re, all_item_hid = fluid.layers.fc(input=all_item_emb_re,
......
...@@ -22,7 +22,8 @@ from paddlerec.core.utils import envs ...@@ -22,7 +22,8 @@ from paddlerec.core.utils import envs
class EvaluateReader(Reader): class EvaluateReader(Reader):
def init(self): def init(self):
self.vocab_size = envs.get_global_env("vocab_size", 10, "train.model.hyper_parameters") self.vocab_size = envs.get_global_env("vocab_size", 10,
"train.model.hyper_parameters")
def generate_sample(self, line): def generate_sample(self, line):
""" """
...@@ -39,6 +40,9 @@ class EvaluateReader(Reader): ...@@ -39,6 +40,9 @@ class EvaluateReader(Reader):
src = conv_ids[:boundary] src = conv_ids[:boundary]
pos_tgt = [conv_ids[boundary]] pos_tgt = [conv_ids[boundary]]
feature_name = ["user", "all_item", "p_item"] feature_name = ["user", "all_item", "p_item"]
yield zip(feature_name, [src] + [np.arange(self.vocab_size).astype("int64").tolist()] + [pos_tgt]) yield zip(
feature_name,
[src] + [np.arange(self.vocab_size).astype("int64").tolist()] +
[pos_tgt])
return reader return reader
...@@ -24,46 +24,57 @@ class Model(ModelBase): ...@@ -24,46 +24,57 @@ class Model(ModelBase):
ModelBase.__init__(self, config) ModelBase.__init__(self, config)
def input(self): def input(self):
neg_num = int(envs.get_global_env( neg_num = int(
"hyper_parameters.neg_num", None, self._namespace)) envs.get_global_env("hyper_parameters.neg_num", None,
self.input_word = fluid.data(name="input_word", shape=[ self._namespace))
None, 1], dtype='int64') self.input_word = fluid.data(
self.true_word = fluid.data(name='true_label', shape=[ name="input_word", shape=[None, 1], dtype='int64')
None, 1], dtype='int64') self.true_word = fluid.data(
name='true_label', shape=[None, 1], dtype='int64')
self._data_var.append(self.input_word) self._data_var.append(self.input_word)
self._data_var.append(self.true_word) self._data_var.append(self.true_word)
with_shuffle_batch = bool(int(envs.get_global_env( with_shuffle_batch = bool(
"hyper_parameters.with_shuffle_batch", None, self._namespace))) int(
envs.get_global_env("hyper_parameters.with_shuffle_batch",
None, self._namespace)))
if not with_shuffle_batch: if not with_shuffle_batch:
self.neg_word = fluid.data(name="neg_label", shape=[ self.neg_word = fluid.data(
None, neg_num], dtype='int64') name="neg_label", shape=[None, neg_num], dtype='int64')
self._data_var.append(self.neg_word) self._data_var.append(self.neg_word)
if self._platform != "LINUX": if self._platform != "LINUX":
self._data_loader = fluid.io.DataLoader.from_generator( self._data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
def net(self): def net(self):
is_distributed = True if envs.get_trainer() == "CtrTrainer" else False is_distributed = True if envs.get_trainer() == "CtrTrainer" else False
neg_num = int(envs.get_global_env( neg_num = int(
"hyper_parameters.neg_num", None, self._namespace)) envs.get_global_env("hyper_parameters.neg_num", None,
self._namespace))
sparse_feature_number = envs.get_global_env( sparse_feature_number = envs.get_global_env(
"hyper_parameters.sparse_feature_number", None, self._namespace) "hyper_parameters.sparse_feature_number", None, self._namespace)
sparse_feature_dim = envs.get_global_env( sparse_feature_dim = envs.get_global_env(
"hyper_parameters.sparse_feature_dim", None, self._namespace) "hyper_parameters.sparse_feature_dim", None, self._namespace)
with_shuffle_batch = bool(int(envs.get_global_env( with_shuffle_batch = bool(
"hyper_parameters.with_shuffle_batch", None, self._namespace))) int(
envs.get_global_env("hyper_parameters.with_shuffle_batch",
None, self._namespace)))
def embedding_layer(input, table_name, emb_dim, initializer_instance=None, squeeze=False): def embedding_layer(input,
table_name,
emb_dim,
initializer_instance=None,
squeeze=False):
emb = fluid.embedding( emb = fluid.embedding(
input=input, input=input,
is_sparse=True, is_sparse=True,
is_distributed=is_distributed, is_distributed=is_distributed,
size=[sparse_feature_number, emb_dim], size=[sparse_feature_number, emb_dim],
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(
name=table_name, name=table_name, initializer=initializer_instance), )
initializer=initializer_instance),
)
if squeeze: if squeeze:
return fluid.layers.squeeze(input=emb, axes=[1]) return fluid.layers.squeeze(input=emb, axes=[1])
else: else:
...@@ -73,35 +84,38 @@ class Model(ModelBase): ...@@ -73,35 +84,38 @@ class Model(ModelBase):
emb_initializer = fluid.initializer.Uniform(-init_width, init_width) emb_initializer = fluid.initializer.Uniform(-init_width, init_width)
emb_w_initializer = fluid.initializer.Constant(value=0.0) emb_w_initializer = fluid.initializer.Constant(value=0.0)
input_emb = embedding_layer( input_emb = embedding_layer(self.input_word, "emb", sparse_feature_dim,
self.input_word, "emb", sparse_feature_dim, emb_initializer, True) emb_initializer, True)
true_emb_w = embedding_layer( true_emb_w = embedding_layer(self.true_word, "emb_w",
self.true_word, "emb_w", sparse_feature_dim, emb_w_initializer, True) sparse_feature_dim, emb_w_initializer,
true_emb_b = embedding_layer( True)
self.true_word, "emb_b", 1, emb_w_initializer, True) true_emb_b = embedding_layer(self.true_word, "emb_b", 1,
emb_w_initializer, True)
if with_shuffle_batch: if with_shuffle_batch:
neg_emb_w_list = [] neg_emb_w_list = []
for i in range(neg_num): for i in range(neg_num):
neg_emb_w_list.append(fluid.contrib.layers.shuffle_batch( neg_emb_w_list.append(
true_emb_w)) # shuffle true_word fluid.contrib.layers.shuffle_batch(
true_emb_w)) # shuffle true_word
neg_emb_w_concat = fluid.layers.concat(neg_emb_w_list, axis=0) neg_emb_w_concat = fluid.layers.concat(neg_emb_w_list, axis=0)
neg_emb_w = fluid.layers.reshape( neg_emb_w = fluid.layers.reshape(
neg_emb_w_concat, shape=[-1, neg_num, sparse_feature_dim]) neg_emb_w_concat, shape=[-1, neg_num, sparse_feature_dim])
neg_emb_b_list = [] neg_emb_b_list = []
for i in range(neg_num): for i in range(neg_num):
neg_emb_b_list.append(fluid.contrib.layers.shuffle_batch( neg_emb_b_list.append(
true_emb_b)) # shuffle true_word fluid.contrib.layers.shuffle_batch(
true_emb_b)) # shuffle true_word
neg_emb_b = fluid.layers.concat(neg_emb_b_list, axis=0) neg_emb_b = fluid.layers.concat(neg_emb_b_list, axis=0)
neg_emb_b_vec = fluid.layers.reshape( neg_emb_b_vec = fluid.layers.reshape(
neg_emb_b, shape=[-1, neg_num]) neg_emb_b, shape=[-1, neg_num])
else: else:
neg_emb_w = embedding_layer( neg_emb_w = embedding_layer(self.neg_word, "emb_w",
self.neg_word, "emb_w", sparse_feature_dim, emb_w_initializer) sparse_feature_dim, emb_w_initializer)
neg_emb_b = embedding_layer( neg_emb_b = embedding_layer(self.neg_word, "emb_b", 1,
self.neg_word, "emb_b", 1, emb_w_initializer) emb_w_initializer)
neg_emb_b_vec = fluid.layers.reshape( neg_emb_b_vec = fluid.layers.reshape(
neg_emb_b, shape=[-1, neg_num]) neg_emb_b, shape=[-1, neg_num])
...@@ -117,7 +131,8 @@ class Model(ModelBase): ...@@ -117,7 +131,8 @@ class Model(ModelBase):
neg_matmul = fluid.layers.matmul( neg_matmul = fluid.layers.matmul(
input_emb_re, neg_emb_w, transpose_y=True) input_emb_re, neg_emb_w, transpose_y=True)
neg_logits = fluid.layers.elementwise_add( neg_logits = fluid.layers.elementwise_add(
fluid.layers.reshape(neg_matmul, shape=[-1, neg_num]), fluid.layers.reshape(
neg_matmul, shape=[-1, neg_num]),
neg_emb_b_vec) neg_emb_b_vec)
label_ones = fluid.layers.fill_constant_batch_size_like( label_ones = fluid.layers.fill_constant_batch_size_like(
...@@ -136,9 +151,17 @@ class Model(ModelBase): ...@@ -136,9 +151,17 @@ class Model(ModelBase):
neg_xent, dim=1)) neg_xent, dim=1))
self.avg_cost = fluid.layers.reduce_mean(cost) self.avg_cost = fluid.layers.reduce_mean(cost)
global_right_cnt = fluid.layers.create_global_var( global_right_cnt = fluid.layers.create_global_var(
name="global_right_cnt", persistable=True, dtype='float32', shape=[1], value=0) name="global_right_cnt",
persistable=True,
dtype='float32',
shape=[1],
value=0)
global_total_cnt = fluid.layers.create_global_var( global_total_cnt = fluid.layers.create_global_var(
name="global_total_cnt", persistable=True, dtype='float32', shape=[1], value=0) name="global_total_cnt",
persistable=True,
dtype='float32',
shape=[1],
value=0)
global_right_cnt.stop_gradient = True global_right_cnt.stop_gradient = True
global_total_cnt.stop_gradient = True global_total_cnt.stop_gradient = True
...@@ -155,12 +178,12 @@ class Model(ModelBase): ...@@ -155,12 +178,12 @@ class Model(ModelBase):
self.metrics() self.metrics()
def optimizer(self): def optimizer(self):
learning_rate = envs.get_global_env( learning_rate = envs.get_global_env("hyper_parameters.learning_rate",
"hyper_parameters.learning_rate", None, self._namespace) None, self._namespace)
decay_steps = envs.get_global_env( decay_steps = envs.get_global_env("hyper_parameters.decay_steps", None,
"hyper_parameters.decay_steps", None, self._namespace) self._namespace)
decay_rate = envs.get_global_env( decay_rate = envs.get_global_env("hyper_parameters.decay_rate", None,
"hyper_parameters.decay_rate", None, self._namespace) self._namespace)
optimizer = fluid.optimizer.SGD( optimizer = fluid.optimizer.SGD(
learning_rate=fluid.layers.exponential_decay( learning_rate=fluid.layers.exponential_decay(
learning_rate=learning_rate, learning_rate=learning_rate,
...@@ -180,11 +203,15 @@ class Model(ModelBase): ...@@ -180,11 +203,15 @@ class Model(ModelBase):
name="analogy_c", shape=[None], dtype='int64') name="analogy_c", shape=[None], dtype='int64')
self.analogy_d = fluid.data( self.analogy_d = fluid.data(
name="analogy_d", shape=[None], dtype='int64') name="analogy_d", shape=[None], dtype='int64')
self._infer_data_var = [self.analogy_a, self._infer_data_var = [
self.analogy_b, self.analogy_c, self.analogy_d] self.analogy_a, self.analogy_b, self.analogy_c, self.analogy_d
]
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
def infer_net(self): def infer_net(self):
sparse_feature_dim = envs.get_global_env( sparse_feature_dim = envs.get_global_env(
...@@ -216,18 +243,28 @@ class Model(ModelBase): ...@@ -216,18 +243,28 @@ class Model(ModelBase):
dist = fluid.layers.matmul( dist = fluid.layers.matmul(
x=target, y=emb_all_label_l2, transpose_y=True) x=target, y=emb_all_label_l2, transpose_y=True)
values, pred_idx = fluid.layers.topk(input=dist, k=4) values, pred_idx = fluid.layers.topk(input=dist, k=4)
label = fluid.layers.expand(fluid.layers.unsqueeze( label = fluid.layers.expand(
self.analogy_d, axes=[1]), expand_times=[1, 4]) fluid.layers.unsqueeze(
self.analogy_d, axes=[1]),
expand_times=[1, 4])
label_ones = fluid.layers.fill_constant_batch_size_like( label_ones = fluid.layers.fill_constant_batch_size_like(
label, shape=[-1, 1], value=1.0, dtype='float32') label, shape=[-1, 1], value=1.0, dtype='float32')
right_cnt = fluid.layers.reduce_sum( right_cnt = fluid.layers.reduce_sum(input=fluid.layers.cast(
input=fluid.layers.cast(fluid.layers.equal(pred_idx, label), dtype='float32')) fluid.layers.equal(pred_idx, label), dtype='float32'))
total_cnt = fluid.layers.reduce_sum(label_ones) total_cnt = fluid.layers.reduce_sum(label_ones)
global_right_cnt = fluid.layers.create_global_var( global_right_cnt = fluid.layers.create_global_var(
name="global_right_cnt", persistable=True, dtype='float32', shape=[1], value=0) name="global_right_cnt",
persistable=True,
dtype='float32',
shape=[1],
value=0)
global_total_cnt = fluid.layers.create_global_var( global_total_cnt = fluid.layers.create_global_var(
name="global_total_cnt", persistable=True, dtype='float32', shape=[1], value=0) name="global_total_cnt",
persistable=True,
dtype='float32',
shape=[1],
value=0)
global_right_cnt.stop_gradient = True global_right_cnt.stop_gradient = True
global_total_cnt.stop_gradient = True global_total_cnt.stop_gradient = True
......
...@@ -49,8 +49,7 @@ def parse_args(): ...@@ -49,8 +49,7 @@ def parse_args():
'--file_nums', '--file_nums',
type=int, type=int,
default=1024, default=1024,
help="re-split input corpus file nums" help="re-split input corpus file nums")
)
parser.add_argument( parser.add_argument(
'--downsample', '--downsample',
type=float, type=float,
...@@ -137,9 +136,11 @@ def filter_corpus(args): ...@@ -137,9 +136,11 @@ def filter_corpus(args):
if not os.path.exists(args.output_corpus_dir): if not os.path.exists(args.output_corpus_dir):
os.makedirs(args.output_corpus_dir) os.makedirs(args.output_corpus_dir)
for file in os.listdir(args.input_corpus_dir): for file in os.listdir(args.input_corpus_dir):
with io.open(args.output_corpus_dir + '/convert_' + file + '.csv', "w") as wf: with io.open(args.output_corpus_dir + '/convert_' + file + '.csv',
"w") as wf:
with io.open( with io.open(
args.input_corpus_dir + '/' + file, encoding='utf-8') as rf: args.input_corpus_dir + '/' + file,
encoding='utf-8') as rf:
print(args.input_corpus_dir + '/' + file) print(args.input_corpus_dir + '/' + file)
for line in rf: for line in rf:
signal = False signal = False
...@@ -154,9 +155,9 @@ def filter_corpus(args): ...@@ -154,9 +155,9 @@ def filter_corpus(args):
count_w = id_counts[idx] count_w = id_counts[idx]
corpus_size = word_all_count corpus_size = word_all_count
keep_prob = ( keep_prob = (
math.sqrt(count_w / math.sqrt(count_w /
(args.downsample * corpus_size)) + 1 (args.downsample * corpus_size)) + 1
) * (args.downsample * corpus_size) / count_w ) * (args.downsample * corpus_size) / count_w
r_value = random.random() r_value = random.random()
if r_value > keep_prob: if r_value > keep_prob:
continue continue
...@@ -182,7 +183,8 @@ def build_dict(args): ...@@ -182,7 +183,8 @@ def build_dict(args):
for file in os.listdir(args.build_dict_corpus_dir): for file in os.listdir(args.build_dict_corpus_dir):
with io.open( with io.open(
args.build_dict_corpus_dir + "/" + file, encoding='utf-8') as f: args.build_dict_corpus_dir + "/" + file,
encoding='utf-8') as f:
print("build dict : ", args.build_dict_corpus_dir + "/" + file) print("build dict : ", args.build_dict_corpus_dir + "/" + file)
for line in f: for line in f:
line = text_strip(line) line = text_strip(line)
...@@ -232,7 +234,8 @@ def data_split(args): ...@@ -232,7 +234,8 @@ def data_split(args):
for i in range(1, num + 1): for i in range(1, num + 1):
with open(os.path.join(new_data_dir, "part_" + str(i)), 'w') as fout: with open(os.path.join(new_data_dir, "part_" + str(i)), 'w') as fout:
data = contents[(i - 1) * lines_per_file:min(i * lines_per_file, len(contents))] data = contents[(i - 1) * lines_per_file:min(i * lines_per_file,
len(contents))]
for line in data: for line in data:
fout.write(line) fout.write(line)
......
...@@ -22,7 +22,8 @@ from paddlerec.core.utils import envs ...@@ -22,7 +22,8 @@ from paddlerec.core.utils import envs
class EvaluateReader(Reader): class EvaluateReader(Reader):
def init(self): def init(self):
dict_path = envs.get_global_env("word_id_dict_path", None, "evaluate.reader") dict_path = envs.get_global_env("word_id_dict_path", None,
"evaluate.reader")
self.word_to_id = dict() self.word_to_id = dict()
self.id_to_word = dict() self.id_to_word = dict()
with io.open(dict_path, 'r', encoding='utf-8') as f: with io.open(dict_path, 'r', encoding='utf-8') as f:
...@@ -68,14 +69,17 @@ class EvaluateReader(Reader): ...@@ -68,14 +69,17 @@ class EvaluateReader(Reader):
a unicode string - a space-delimited sequence of words. a unicode string - a space-delimited sequence of words.
""" """
return u" ".join([ return u" ".join([
word if word in original_vocab else u"<UNK>" for word in line.split() word if word in original_vocab else u"<UNK>"
for word in line.split()
]) ])
def generate_sample(self, line): def generate_sample(self, line):
def reader(): def reader():
features = self.strip_lines(line.lower(), self.word_to_id) features = self.strip_lines(line.lower(), self.word_to_id)
features = features.split() features = features.split()
yield [('analogy_a', [self.word_to_id[features[0]]]), ('analogy_b', [self.word_to_id[features[1]]]), yield [('analogy_a', [self.word_to_id[features[0]]]),
('analogy_c', [self.word_to_id[features[2]]]), ('analogy_d', [self.word_to_id[features[3]]])] ('analogy_b', [self.word_to_id[features[1]]]),
('analogy_c', [self.word_to_id[features[2]]]),
('analogy_d', [self.word_to_id[features[3]]])]
return reader return reader
...@@ -40,10 +40,14 @@ class NumpyRandomInt(object): ...@@ -40,10 +40,14 @@ class NumpyRandomInt(object):
class TrainReader(Reader): class TrainReader(Reader):
def init(self): def init(self):
dict_path = envs.get_global_env("word_count_dict_path", None, "train.reader") dict_path = envs.get_global_env("word_count_dict_path", None,
self.window_size = envs.get_global_env("hyper_parameters.window_size", None, "train.model") "train.reader")
self.neg_num = envs.get_global_env("hyper_parameters.neg_num", None, "train.model") self.window_size = envs.get_global_env("hyper_parameters.window_size",
self.with_shuffle_batch = envs.get_global_env("hyper_parameters.with_shuffle_batch", None, "train.model") None, "train.model")
self.neg_num = envs.get_global_env("hyper_parameters.neg_num", None,
"train.model")
self.with_shuffle_batch = envs.get_global_env(
"hyper_parameters.with_shuffle_batch", None, "train.model")
self.random_generator = NumpyRandomInt(1, self.window_size + 1) self.random_generator = NumpyRandomInt(1, self.window_size + 1)
self.cs = None self.cs = None
...@@ -81,13 +85,15 @@ class TrainReader(Reader): ...@@ -81,13 +85,15 @@ class TrainReader(Reader):
def reader(): def reader():
word_ids = [w for w in line.split()] word_ids = [w for w in line.split()]
for idx, target_id in enumerate(word_ids): for idx, target_id in enumerate(word_ids):
context_word_ids = self.get_context_words( context_word_ids = self.get_context_words(word_ids, idx)
word_ids, idx)
for context_id in context_word_ids: for context_id in context_word_ids:
output = [('input_word', [int(target_id)]), ('true_label', [int(context_id)])] output = [('input_word', [int(target_id)]),
('true_label', [int(context_id)])]
if not self.with_shuffle_batch: if not self.with_shuffle_batch:
neg_array = self.cs.searchsorted(np.random.sample(self.neg_num)) neg_array = self.cs.searchsorted(
output += [('neg_label', [int(str(i)) for i in neg_array])] np.random.sample(self.neg_num))
output += [('neg_label',
[int(str(i)) for i in neg_array])]
yield output yield output
return reader return reader
...@@ -25,14 +25,20 @@ class Model(ModelBase): ...@@ -25,14 +25,20 @@ class Model(ModelBase):
ModelBase.__init__(self, config) ModelBase.__init__(self, config)
def input_data(self, is_infer=False): def input_data(self, is_infer=False):
watch_vec_size = envs.get_global_env("hyper_parameters.watch_vec_size", None, self._namespace) watch_vec_size = envs.get_global_env("hyper_parameters.watch_vec_size",
search_vec_size = envs.get_global_env("hyper_parameters.search_vec_size", None, self._namespace) None, self._namespace)
other_feat_size = envs.get_global_env("hyper_parameters.other_feat_size", None, self._namespace) search_vec_size = envs.get_global_env(
"hyper_parameters.search_vec_size", None, self._namespace)
watch_vec = fluid.data(name="watch_vec", shape=[None, watch_vec_size], dtype="float32") other_feat_size = envs.get_global_env(
search_vec = fluid.data(name="search_vec", shape=[None, search_vec_size], dtype="float32") "hyper_parameters.other_feat_size", None, self._namespace)
other_feat = fluid.data(name="other_feat", shape=[None, other_feat_size], dtype="float32")
watch_vec = fluid.data(
name="watch_vec", shape=[None, watch_vec_size], dtype="float32")
search_vec = fluid.data(
name="search_vec", shape=[None, search_vec_size], dtype="float32")
other_feat = fluid.data(
name="other_feat", shape=[None, other_feat_size], dtype="float32")
label = fluid.data(name="label", shape=[None, 1], dtype="int64") label = fluid.data(name="label", shape=[None, 1], dtype="int64")
inputs = [watch_vec] + [search_vec] + [other_feat] + [label] inputs = [watch_vec] + [search_vec] + [other_feat] + [label]
self._data_var = inputs self._data_var = inputs
...@@ -41,27 +47,32 @@ class Model(ModelBase): ...@@ -41,27 +47,32 @@ class Model(ModelBase):
def fc(self, tag, data, out_dim, active='relu'): def fc(self, tag, data, out_dim, active='relu'):
init_stddev = 1.0 init_stddev = 1.0
scales = 1.0 / np.sqrt(data.shape[1]) scales = 1.0 / np.sqrt(data.shape[1])
if tag == 'l4': if tag == 'l4':
p_attr = fluid.param_attr.ParamAttr(name='%s_weight' % tag, p_attr = fluid.param_attr.ParamAttr(
initializer=fluid.initializer.NormalInitializer(loc=0.0, scale=init_stddev * scales)) name='%s_weight' % tag,
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=init_stddev * scales))
else: else:
p_attr = None p_attr = None
b_attr = fluid.ParamAttr(name='%s_bias' % tag, initializer=fluid.initializer.Constant(0.1)) b_attr = fluid.ParamAttr(
name='%s_bias' % tag, initializer=fluid.initializer.Constant(0.1))
out = fluid.layers.fc(input=data, out = fluid.layers.fc(input=data,
size=out_dim, size=out_dim,
act=active, act=active,
param_attr=p_attr, param_attr=p_attr,
bias_attr =b_attr, bias_attr=b_attr,
name=tag) name=tag)
return out return out
def net(self, inputs): def net(self, inputs):
output_size = envs.get_global_env("hyper_parameters.output_size", None, self._namespace) output_size = envs.get_global_env("hyper_parameters.output_size", None,
layers = envs.get_global_env("hyper_parameters.layers", None, self._namespace) self._namespace)
layers = envs.get_global_env("hyper_parameters.layers", None,
self._namespace)
concat_feats = fluid.layers.concat(input=inputs[:-1], axis=-1) concat_feats = fluid.layers.concat(input=inputs[:-1], axis=-1)
l1 = self.fc('l1', concat_feats, layers[0], 'relu') l1 = self.fc('l1', concat_feats, layers[0], 'relu')
......
...@@ -21,10 +21,14 @@ import numpy as np ...@@ -21,10 +21,14 @@ import numpy as np
class TrainReader(Reader): class TrainReader(Reader):
def init(self): def init(self):
self.watch_vec_size = envs.get_global_env("hyper_parameters.watch_vec_size", None, "train.model") self.watch_vec_size = envs.get_global_env(
self.search_vec_size = envs.get_global_env("hyper_parameters.search_vec_size", None, "train.model") "hyper_parameters.watch_vec_size", None, "train.model")
self.other_feat_size = envs.get_global_env("hyper_parameters.other_feat_size", None, "train.model") self.search_vec_size = envs.get_global_env(
self.output_size = envs.get_global_env("hyper_parameters.output_size", None, "train.model") "hyper_parameters.search_vec_size", None, "train.model")
self.other_feat_size = envs.get_global_env(
"hyper_parameters.other_feat_size", None, "train.model")
self.output_size = envs.get_global_env("hyper_parameters.output_size",
None, "train.model")
def generate_sample(self, line): def generate_sample(self, line):
""" """
...@@ -35,13 +39,12 @@ class TrainReader(Reader): ...@@ -35,13 +39,12 @@ class TrainReader(Reader):
""" """
This function needs to be implemented by the user, based on data format This function needs to be implemented by the user, based on data format
""" """
feature_name = ["watch_vec", "search_vec", "other_feat", "label"] feature_name = ["watch_vec", "search_vec", "other_feat", "label"]
yield zip(feature_name, [np.random.rand(self.watch_vec_size).tolist()] + yield zip(feature_name,
[np.random.rand(self.search_vec_size).tolist()] + [np.random.rand(self.watch_vec_size).tolist()] +
[np.random.rand(self.other_feat_size).tolist()] + [np.random.rand(self.search_vec_size).tolist()] +
[[np.random.randint(self.output_size)]] ) [np.random.rand(self.other_feat_size).tolist()] +
[[np.random.randint(self.output_size)]])
return reader return reader
...@@ -25,38 +25,38 @@ class Model(ModelBase): ...@@ -25,38 +25,38 @@ class Model(ModelBase):
def __init__(self, config): def __init__(self, config):
ModelBase.__init__(self, config) ModelBase.__init__(self, config)
# tree meta hyper parameters # tree meta hyper parameters
self.max_layers = envs.get_global_env( self.max_layers = envs.get_global_env("tree_parameters.max_layers", 4,
"tree_parameters.max_layers", 4, self._namespace) self._namespace)
self.node_nums = envs.get_global_env( self.node_nums = envs.get_global_env("tree_parameters.node_nums", 26,
"tree_parameters.node_nums", 26, self._namespace) self._namespace)
self.leaf_node_nums = envs.get_global_env( self.leaf_node_nums = envs.get_global_env(
"tree_parameters.leaf_node_nums", 13, self._namespace) "tree_parameters.leaf_node_nums", 13, self._namespace)
self.output_positive = envs.get_global_env( self.output_positive = envs.get_global_env(
"tree_parameters.output_positive", True, self._namespace) "tree_parameters.output_positive", True, self._namespace)
self.layer_node_num_list = envs.get_global_env( self.layer_node_num_list = envs.get_global_env(
"tree_parameters.layer_node_num_list", [ "tree_parameters.layer_node_num_list", [2, 4, 7,
2, 4, 7, 12], self._namespace) 12], self._namespace)
self.child_nums = envs.get_global_env( self.child_nums = envs.get_global_env("tree_parameters.child_nums", 2,
"tree_parameters.child_nums", 2, self._namespace) self._namespace)
self.tree_layer_path = envs.get_global_env( self.tree_layer_path = envs.get_global_env("tree.tree_layer_path",
"tree.tree_layer_path", None, "train.startup") None, "train.startup")
# model training hyper parameter # model training hyper parameter
self.node_emb_size = envs.get_global_env( self.node_emb_size = envs.get_global_env(
"hyper_parameters.node_emb_size", 64, self._namespace) "hyper_parameters.node_emb_size", 64, self._namespace)
self.input_emb_size = envs.get_global_env( self.input_emb_size = envs.get_global_env(
"hyper_parameters.input_emb_size", 768, self._namespace) "hyper_parameters.input_emb_size", 768, self._namespace)
self.act = envs.get_global_env( self.act = envs.get_global_env("hyper_parameters.act", "tanh",
"hyper_parameters.act", "tanh", self._namespace) self._namespace)
self.neg_sampling_list = envs.get_global_env( self.neg_sampling_list = envs.get_global_env(
"hyper_parameters.neg_sampling_list", [ "hyper_parameters.neg_sampling_list", [1, 2, 3,
1, 2, 3, 4], self._namespace) 4], self._namespace)
# model infer hyper parameter # model infer hyper parameter
self.topK = envs.get_global_env( self.topK = envs.get_global_env("hyper_parameters.node_nums", 1,
"hyper_parameters.node_nums", 1, self._namespace) self._namespace)
self.batch_size = envs.get_global_env( self.batch_size = envs.get_global_env("batch_size", 1,
"batch_size", 1, "evaluate.reader") "evaluate.reader")
def train_net(self): def train_net(self):
self.train_input() self.train_input()
...@@ -76,21 +76,22 @@ class Model(ModelBase): ...@@ -76,21 +76,22 @@ class Model(ModelBase):
input_emb = fluid.data( input_emb = fluid.data(
name="input_emb", name="input_emb",
shape=[None, self.input_emb_size], shape=[None, self.input_emb_size],
dtype="float32", dtype="float32", )
)
self._data_var.append(input_emb) self._data_var.append(input_emb)
item_label = fluid.data( item_label = fluid.data(
name="item_label", name="item_label",
shape=[None, 1], shape=[None, 1],
dtype="int64", dtype="int64", )
)
self._data_var.append(item_label) self._data_var.append(item_label)
if self._platform != "LINUX": if self._platform != "LINUX":
self._data_loader = fluid.io.DataLoader.from_generator( self._data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
def tdm_net(self): def tdm_net(self):
""" """
...@@ -116,8 +117,7 @@ class Model(ModelBase): ...@@ -116,8 +117,7 @@ class Model(ModelBase):
output_list=True, output_list=True,
seed=0, seed=0,
tree_dtype='int64', tree_dtype='int64',
dtype='int64' dtype='int64')
)
# 查表得到每个节点的Embedding # 查表得到每个节点的Embedding
sample_nodes_emb = [ sample_nodes_emb = [
...@@ -125,35 +125,34 @@ class Model(ModelBase): ...@@ -125,35 +125,34 @@ class Model(ModelBase):
input=sample_nodes[i], input=sample_nodes[i],
is_sparse=True, is_sparse=True,
size=[self.node_nums, self.node_emb_size], size=[self.node_nums, self.node_emb_size],
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(name="TDM_Tree_Emb"))
name="TDM_Tree_Emb") for i in range(self.max_layers)
) for i in range(self.max_layers)
] ]
# 此处进行Reshape是为了之后层次化的分类器训练 # 此处进行Reshape是为了之后层次化的分类器训练
sample_nodes_emb = [ sample_nodes_emb = [
fluid.layers.reshape(sample_nodes_emb[i], fluid.layers.reshape(sample_nodes_emb[i], [
[-1, self.neg_sampling_list[i] + -1, self.neg_sampling_list[i] + self.output_positive,
self.output_positive, self.node_emb_size] self.node_emb_size
) for i in range(self.max_layers) ]) for i in range(self.max_layers)
] ]
# 对输入的input_emb进行转换,使其维度与node_emb维度一致 # 对输入的input_emb进行转换,使其维度与node_emb维度一致
input_trans_emb = self.input_trans_layer(input_emb) input_trans_emb = self.input_trans_layer(input_emb)
# 分类器的主体网络,分别训练不同层次的分类器 # 分类器的主体网络,分别训练不同层次的分类器
layer_classifier_res = self.classifier_layer( layer_classifier_res = self.classifier_layer(input_trans_emb,
input_trans_emb, sample_nodes_emb) sample_nodes_emb)
# 最后的概率判别FC,将所有层次的node分类结果放到一起以相同的标准进行判别 # 最后的概率判别FC,将所有层次的node分类结果放到一起以相同的标准进行判别
# 考虑到树极大可能不平衡,有些item不在最后一层,所以需要这样的机制保证每个item都有机会被召回 # 考虑到树极大可能不平衡,有些item不在最后一层,所以需要这样的机制保证每个item都有机会被召回
tdm_fc = fluid.layers.fc(input=layer_classifier_res, tdm_fc = fluid.layers.fc(
size=2, input=layer_classifier_res,
act=None, size=2,
num_flatten_dims=2, act=None,
param_attr=fluid.ParamAttr( num_flatten_dims=2,
name="tdm.cls_fc.weight"), param_attr=fluid.ParamAttr(name="tdm.cls_fc.weight"),
bias_attr=fluid.ParamAttr(name="tdm.cls_fc.bias")) bias_attr=fluid.ParamAttr(name="tdm.cls_fc.bias"))
# 将loss打平,放到一起计算整体网络的loss # 将loss打平,放到一起计算整体网络的loss
tdm_fc_re = fluid.layers.reshape(tdm_fc, [-1, 2]) tdm_fc_re = fluid.layers.reshape(tdm_fc, [-1, 2])
...@@ -202,7 +201,7 @@ class Model(ModelBase): ...@@ -202,7 +201,7 @@ class Model(ModelBase):
def metrics(self): def metrics(self):
auc, batch_auc, _ = fluid.layers.auc(input=self._predict, auc, batch_auc, _ = fluid.layers.auc(input=self._predict,
label=self.mask_label, label=self.mask_label,
num_thresholds=2 ** 12, num_thresholds=2**12,
slide_steps=20) slide_steps=20)
self._metrics["AUC"] = auc self._metrics["AUC"] = auc
self._metrics["BATCH_AUC"] = batch_auc self._metrics["BATCH_AUC"] = batch_auc
...@@ -218,8 +217,7 @@ class Model(ModelBase): ...@@ -218,8 +217,7 @@ class Model(ModelBase):
size=self.node_emb_size, size=self.node_emb_size,
act=None, act=None,
param_attr=fluid.ParamAttr(name="trans.input_fc.weight"), param_attr=fluid.ParamAttr(name="trans.input_fc.weight"),
bias_attr=fluid.ParamAttr(name="trans.input_fc.bias"), bias_attr=fluid.ParamAttr(name="trans.input_fc.bias"), )
)
# 将input_emb映射到各个不同层次的向量表示空间 # 将input_emb映射到各个不同层次的向量表示空间
input_layer_fc_out = [ input_layer_fc_out = [
...@@ -229,8 +227,9 @@ class Model(ModelBase): ...@@ -229,8 +227,9 @@ class Model(ModelBase):
act=self.act, act=self.act,
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(
name="trans.layer_fc.weight." + str(i)), name="trans.layer_fc.weight." + str(i)),
bias_attr=fluid.ParamAttr(name="trans.layer_fc.bias." + str(i)), bias_attr=fluid.ParamAttr(
) for i in range(self.max_layers) name="trans.layer_fc.bias." + str(i)), )
for i in range(self.max_layers)
] ]
return input_layer_fc_out return input_layer_fc_out
...@@ -246,20 +245,22 @@ class Model(ModelBase): ...@@ -246,20 +245,22 @@ class Model(ModelBase):
input_layer_unsequeeze, expand_times=[1, node.shape[1], 1]) input_layer_unsequeeze, expand_times=[1, node.shape[1], 1])
else: else:
input_layer_expand = fluid.layers.expand( input_layer_expand = fluid.layers.expand(
input_layer_unsequeeze, expand_times=[1, node[layer_idx].shape[1], 1]) input_layer_unsequeeze,
expand_times=[1, node[layer_idx].shape[1], 1])
return input_layer_expand return input_layer_expand
def classifier_layer(self, input, node): def classifier_layer(self, input, node):
# 扩展input,使维度与node匹配 # 扩展input,使维度与node匹配
input_expand = [ input_expand = [
self._expand_layer(input[i], node, i) for i in range(self.max_layers) self._expand_layer(input[i], node, i)
for i in range(self.max_layers)
] ]
# 将input_emb与node_emb concat到一起过分类器FC # 将input_emb与node_emb concat到一起过分类器FC
input_node_concat = [ input_node_concat = [
fluid.layers.concat( fluid.layers.concat(
input=[input_expand[i], node[i]], input=[input_expand[i], node[i]], axis=2)
axis=2) for i in range(self.max_layers) for i in range(self.max_layers)
] ]
hidden_states_fc = [ hidden_states_fc = [
fluid.layers.fc( fluid.layers.fc(
...@@ -269,8 +270,8 @@ class Model(ModelBase): ...@@ -269,8 +270,8 @@ class Model(ModelBase):
act=self.act, act=self.act,
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(
name="cls.concat_fc.weight." + str(i)), name="cls.concat_fc.weight." + str(i)),
bias_attr=fluid.ParamAttr(name="cls.concat_fc.bias." + str(i)) bias_attr=fluid.ParamAttr(name="cls.concat_fc.bias." + str(i)))
) for i in range(self.max_layers) for i in range(self.max_layers)
] ]
# 如果将所有层次的node放到一起计算loss,则需要在此处concat # 如果将所有层次的node放到一起计算loss,则需要在此处concat
...@@ -285,12 +286,14 @@ class Model(ModelBase): ...@@ -285,12 +286,14 @@ class Model(ModelBase):
input_emb = fluid.layers.data( input_emb = fluid.layers.data(
name="input_emb", name="input_emb",
shape=[self.input_emb_size], shape=[self.input_emb_size],
dtype="float32", dtype="float32", )
)
self._infer_data_var.append(input_emb) self._infer_data_var.append(input_emb)
self._infer_data_loader = fluid.io.DataLoader.from_generator( self._infer_data_loader = fluid.io.DataLoader.from_generator(
feed_list=self._infer_data_var, capacity=64, use_double_buffer=False, iterable=False) feed_list=self._infer_data_var,
capacity=64,
use_double_buffer=False,
iterable=False)
def get_layer_list(self): def get_layer_list(self):
"""get layer list from layer_list.txt""" """get layer list from layer_list.txt"""
...@@ -318,10 +321,12 @@ class Model(ModelBase): ...@@ -318,10 +321,12 @@ class Model(ModelBase):
node_list = [] node_list = []
mask_list = [] mask_list = []
for id in first_layer_node: for id in first_layer_node:
node_list.append(fluid.layers.fill_constant( node_list.append(
[self.batch_size, 1], value=int(id), dtype='int64')) fluid.layers.fill_constant(
mask_list.append(fluid.layers.fill_constant( [self.batch_size, 1], value=int(id), dtype='int64'))
[self.batch_size, 1], value=0, dtype='int64')) mask_list.append(
fluid.layers.fill_constant(
[self.batch_size, 1], value=0, dtype='int64'))
self.first_layer_node = fluid.layers.concat(node_list, axis=1) self.first_layer_node = fluid.layers.concat(node_list, axis=1)
self.first_layer_node_mask = fluid.layers.concat(mask_list, axis=1) self.first_layer_node_mask = fluid.layers.concat(mask_list, axis=1)
...@@ -359,28 +364,26 @@ class Model(ModelBase): ...@@ -359,28 +364,26 @@ class Model(ModelBase):
size=[self.node_nums, self.node_emb_size], size=[self.node_nums, self.node_emb_size],
param_attr=fluid.ParamAttr(name="TDM_Tree_Emb")) param_attr=fluid.ParamAttr(name="TDM_Tree_Emb"))
input_fc_out = self.layer_fc_infer( input_fc_out = self.layer_fc_infer(input_trans_emb, layer_idx)
input_trans_emb, layer_idx)
# 过每一层的分类器 # 过每一层的分类器
layer_classifier_res = self.classifier_layer_infer(input_fc_out, layer_classifier_res = self.classifier_layer_infer(
node_emb, input_fc_out, node_emb, layer_idx)
layer_idx)
# 过最终的判别分类器 # 过最终的判别分类器
tdm_fc = fluid.layers.fc(input=layer_classifier_res, tdm_fc = fluid.layers.fc(
size=2, input=layer_classifier_res,
act=None, size=2,
num_flatten_dims=2, act=None,
param_attr=fluid.ParamAttr( num_flatten_dims=2,
name="tdm.cls_fc.weight"), param_attr=fluid.ParamAttr(name="tdm.cls_fc.weight"),
bias_attr=fluid.ParamAttr(name="tdm.cls_fc.bias")) bias_attr=fluid.ParamAttr(name="tdm.cls_fc.bias"))
prob = fluid.layers.softmax(tdm_fc) prob = fluid.layers.softmax(tdm_fc)
positive_prob = fluid.layers.slice( positive_prob = fluid.layers.slice(
prob, axes=[2], starts=[1], ends=[2]) prob, axes=[2], starts=[1], ends=[2])
prob_re = fluid.layers.reshape( prob_re = fluid.layers.reshape(positive_prob,
positive_prob, [-1, current_layer_node_num]) [-1, current_layer_node_num])
# 过滤掉padding产生的无效节点(node_id=0) # 过滤掉padding产生的无效节点(node_id=0)
node_zero_mask = fluid.layers.cast(current_layer_node, 'bool') node_zero_mask = fluid.layers.cast(current_layer_node, 'bool')
...@@ -395,11 +398,11 @@ class Model(ModelBase): ...@@ -395,11 +398,11 @@ class Model(ModelBase):
# index_sample op根据下标索引tensor对应位置的值 # index_sample op根据下标索引tensor对应位置的值
# 若paddle版本>2.0,调用方式为paddle.index_sample # 若paddle版本>2.0,调用方式为paddle.index_sample
top_node = fluid.contrib.layers.index_sample( top_node = fluid.contrib.layers.index_sample(current_layer_node,
current_layer_node, topk_i) topk_i)
prob_re_mask = prob_re * current_layer_node_mask # 过滤掉非叶子节点 prob_re_mask = prob_re * current_layer_node_mask # 过滤掉非叶子节点
topk_value = fluid.contrib.layers.index_sample( topk_value = fluid.contrib.layers.index_sample(prob_re_mask,
prob_re_mask, topk_i) topk_i)
node_score.append(topk_value) node_score.append(topk_value)
node_list.append(top_node) node_list.append(top_node)
...@@ -424,7 +427,8 @@ class Model(ModelBase): ...@@ -424,7 +427,8 @@ class Model(ModelBase):
res_node = fluid.layers.reshape(res_layer_node, [-1, self.topK, 1]) res_node = fluid.layers.reshape(res_layer_node, [-1, self.topK, 1])
# 利用Tree_info信息,将node_id转换为item_id # 利用Tree_info信息,将node_id转换为item_id
tree_info = fluid.default_main_program().global_block().var("TDM_Tree_Info") tree_info = fluid.default_main_program().global_block().var(
"TDM_Tree_Info")
res_node_emb = fluid.layers.gather_nd(tree_info, res_node) res_node_emb = fluid.layers.gather_nd(tree_info, res_node)
res_item = fluid.layers.slice( res_item = fluid.layers.slice(
...@@ -442,8 +446,7 @@ class Model(ModelBase): ...@@ -442,8 +446,7 @@ class Model(ModelBase):
size=self.node_emb_size, size=self.node_emb_size,
act=None, act=None,
param_attr=fluid.ParamAttr(name="trans.input_fc.weight"), param_attr=fluid.ParamAttr(name="trans.input_fc.weight"),
bias_attr=fluid.ParamAttr(name="trans.input_fc.bias"), bias_attr=fluid.ParamAttr(name="trans.input_fc.bias"), )
)
return input_fc_out return input_fc_out
def layer_fc_infer(self, input_fc_out, layer_idx): def layer_fc_infer(self, input_fc_out, layer_idx):
...@@ -458,8 +461,7 @@ class Model(ModelBase): ...@@ -458,8 +461,7 @@ class Model(ModelBase):
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(
name="trans.layer_fc.weight." + str(layer_idx)), name="trans.layer_fc.weight." + str(layer_idx)),
bias_attr=fluid.ParamAttr( bias_attr=fluid.ParamAttr(
name="trans.layer_fc.bias." + str(layer_idx)), name="trans.layer_fc.bias." + str(layer_idx)), )
)
return input_layer_fc_out return input_layer_fc_out
def classifier_layer_infer(self, input, node, layer_idx): def classifier_layer_infer(self, input, node, layer_idx):
...@@ -480,5 +482,6 @@ class Model(ModelBase): ...@@ -480,5 +482,6 @@ class Model(ModelBase):
act=self.act, act=self.act,
param_attr=fluid.ParamAttr( param_attr=fluid.ParamAttr(
name="cls.concat_fc.weight." + str(layer_idx)), name="cls.concat_fc.weight." + str(layer_idx)),
bias_attr=fluid.ParamAttr(name="cls.concat_fc.bias." + str(layer_idx))) bias_attr=fluid.ParamAttr(
name="cls.concat_fc.bias." + str(layer_idx)))
return hidden_states_fc return hidden_states_fc
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册