static_model.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import math
  2. import paddle
  3. from net import DSSMLayer
  4. class StaticModel():
  5. def __init__(self, config):
  6. self.cost = None
  7. self.config = config
  8. self._init_hyper_parameters()
  9. self.is_infer = False
  10. tag_features_dict = [
  11. {"vid": 5034920},
  12. {"video_style": 10382},
  13. {"captions_color": 3000},
  14. {"valid_time": 1054},
  15. {"audience_age_group": 100},
  16. {"cate2": 107},
  17. {"audience_value_type": 105},
  18. {"font_size": 109},
  19. {"audience_gender": 107},
  20. {"cover_persons_num": 105},
  21. {"cate1": 102},
  22. {"sentiment_tendency": 101},
  23. {"video_type": 20},
  24. {"background_music_type": 20},
  25. {"captions": 3},
  26. {"has_end_credit_guide": 20},
  27. {"timeliness": 10}
  28. ]
  29. self.stat_features_num = 47
  30. self.stat_features_num_embeddings = 100
  31. self.tag_feature_num = len(tag_features_dict)
  32. self.tag_feature_nums = [list(d.values())[0] for d in tag_features_dict]
  33. print(f"debug debug data tag_feature_nums: {self.tag_feature_nums}")
  34. # 第一层的输入维度是所有特征的embedding拼接
  35. self.input_dim = self.tag_feature_num + self.stat_features_num*3
  36. print(f"debug debug data input dim: {self.input_dim}")
  37. def _init_hyper_parameters(self):
  38. # 修改超参数初始化
  39. self.feature_nums = self.config.get("hyper_parameters.feature_nums", [5,5,5,5,5])
  40. self.embedding_dim = self.config.get("hyper_parameters.embedding_dim", 8)
  41. self.output_dim = self.config.get("hyper_parameters.output_dim", 16)
  42. self.hidden_layers = self.config.get("hyper_parameters.hidden_layers", [40, 32])
  43. self.hidden_acts = self.config.get("hyper_parameters.hidden_acts", ["relu", "relu"])
  44. self.learning_rate = self.config.get("hyper_parameters.optimizer.learning_rate", 0.001)
  45. self.margin = self.config.get("hyper_parameters.margin", 0.0) # 用于损失函数的margin参数
  46. self.feature_num = len(self.feature_nums)
  47. self.is_infer = self.config.get("hyper_parameters.is_infer", False)
  48. def create_feeds(self, is_infer=False):
  49. # 定义输入数据占位符
  50. feeds_list = []
  51. if not is_infer:
  52. label = paddle.static.data(
  53. name="label", shape=[-1, 1], dtype='float32')
  54. feeds_list.append(label)
  55. left_features = paddle.static.data(
  56. name="left_features", shape=[-1, self.input_dim], dtype='float32')
  57. feeds_list.append(left_features)
  58. right_features = paddle.static.data(
  59. name="right_features", shape=[-1, self.input_dim], dtype='float32')
  60. feeds_list.append(right_features)
  61. else:
  62. #sample_id = paddle.static.data(
  63. # name="sample_id", shape=[-1, 1], dtype='int64')
  64. #feeds_list.append(sample_id)
  65. left_features = paddle.static.data(
  66. name="left_features", shape=[-1, self.input_dim], dtype='float32')
  67. feeds_list.append(left_features)
  68. return feeds_list
  69. def net(self, input, is_infer=False):
  70. # 创建模型实例
  71. dssm_model = DSSMLayer(
  72. tag_feature_nums=self.tag_feature_nums,
  73. stat_features_num = self.stat_features_num,
  74. stat_features_num_embeddings = self.stat_features_num_embeddings,
  75. embedding_dim=self.embedding_dim,
  76. output_dim=self.output_dim,
  77. hidden_layers=self.hidden_layers,
  78. hidden_acts=self.hidden_acts
  79. )
  80. if is_infer:
  81. left_features = input[0]
  82. left_vec = dssm_model(left_features,None,is_infer=True)
  83. self.inference_target_var = left_vec
  84. fetch_dict = {
  85. 'left_vector': left_vec
  86. }
  87. return fetch_dict
  88. else:
  89. label,left_features, right_features = input
  90. # 获取相似度和特征向量
  91. sim_score, left_vec, right_vec = dssm_model(left_features, right_features)
  92. self.inference_target_var = left_vec
  93. # self.left_vector = left_vec
  94. # self.right_vector = right_vec
  95. # 计算损失
  96. # 使用带margin的二元交叉熵损失
  97. pos_mask = paddle.cast(label > 0.5, 'float32')
  98. neg_mask = 1.0 - pos_mask
  99. positive_loss = -pos_mask * paddle.log(paddle.clip(sim_score, 1e-8, 1.0))
  100. negative_loss = -neg_mask * paddle.log(paddle.clip(1 - sim_score + self.margin, 1e-8, 1.0))
  101. loss = positive_loss + negative_loss
  102. avg_cost = paddle.mean(loss)
  103. self._cost = avg_cost
  104. # 计算accuracy
  105. predictions = paddle.cast(sim_score > 0.5, 'float32')
  106. accuracy = paddle.mean(paddle.cast(paddle.equal(predictions, label), 'float32'))
  107. fetch_dict = {
  108. 'loss': avg_cost,
  109. 'accuracy': accuracy,
  110. #'similarity': sim_score,
  111. #'left_vector': left_vec,
  112. #'right_vector': right_vec
  113. }
  114. return fetch_dict
  115. def create_optimizer(self, strategy=None,is_infer=False):
  116. optimizer = paddle.optimizer.Adam(
  117. learning_rate=self.learning_rate)
  118. if strategy is not None:
  119. import paddle.distributed.fleet as fleet
  120. optimizer = fleet.distributed_optimizer(optimizer, strategy)
  121. if is_infer:
  122. zero_var = paddle.zeros(shape=[1], dtype='float32')
  123. optimizer.minimize(paddle.mean(zero_var))
  124. else:
  125. optimizer.minimize(self._cost)
  126. def infer_net(self, input):
  127. return self.net(input, is_infer=True)