static_model.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. def _init_hyper_parameters(self):
  10. # 修改超参数初始化
  11. self.feature_nums = self.config.get("hyper_parameters.feature_nums", [5,5,5,5,5])
  12. self.embedding_dim = self.config.get("hyper_parameters.embedding_dim", 8)
  13. self.output_dim = self.config.get("hyper_parameters.output_dim", 16)
  14. self.hidden_layers = self.config.get("hyper_parameters.hidden_layers", [40, 32])
  15. self.hidden_acts = self.config.get("hyper_parameters.hidden_acts", ["relu", "relu"])
  16. self.learning_rate = self.config.get("hyper_parameters.optimizer.learning_rate", 0.001)
  17. self.margin = self.config.get("hyper_parameters.margin", 0.3) # 用于损失函数的margin参数
  18. self.feature_num = len(self.feature_nums)
  19. def create_feeds(self, is_infer=False):
  20. # 定义输入数据占位符
  21. # sample_id = paddle.static.data(
  22. # name="sample_id", shape=[-1, 1], dtype='int64')
  23. if not is_infer:
  24. label = paddle.static.data(
  25. name="label", shape=[-1, 1], dtype='float32')
  26. feeds_list.append(label)
  27. left_features = paddle.static.data(
  28. name="left_features", shape=[-1, self.feature_num], dtype='float32')
  29. right_features = paddle.static.data(
  30. name="right_features", shape=[-1, self.feature_num], dtype='float32')
  31. feeds_list = [left_features, right_features]
  32. return feeds_list
  33. def net(self, input, is_infer=False):
  34. # 创建模型实例
  35. dssm_model = DSSMLayer(
  36. feature_nums=self.feature_nums,
  37. embedding_dim=self.embedding_dim,
  38. output_dim=self.output_dim,
  39. hidden_layers=self.hidden_layers,
  40. hidden_acts=self.hidden_acts
  41. )
  42. if is_infer:
  43. left_features, right_features = input
  44. else:
  45. label,left_features, right_features = input
  46. paddle.static.Print(left_features, message="lqc left data feature shape:")
  47. paddle.static.Print(right_features, message="lqc right data feature shape:")
  48. paddle.static.Print(label, message="lqc label feature shape:")
  49. # 获取相似度和特征向量
  50. sim_score, left_vec, right_vec = dssm_model(left_features, right_features)
  51. self.inference_target_var = sim_score
  52. self.left_vector = left_vec
  53. self.right_vector = right_vec
  54. if is_infer:
  55. fetch_dict = {
  56. 'similarity': sim_score,
  57. 'left_vector': left_vec,
  58. 'right_vector': right_vec
  59. }
  60. return fetch_dict
  61. # 计算损失
  62. # 使用带margin的二元交叉熵损失
  63. pos_mask = paddle.cast(label > 0.5, 'float32')
  64. neg_mask = 1.0 - pos_mask
  65. positive_loss = -pos_mask * paddle.log(paddle.clip(sim_score, 1e-8, 1.0))
  66. negative_loss = -neg_mask * paddle.log(paddle.clip(1 - sim_score + self.margin, 1e-8, 1.0))
  67. loss = positive_loss + negative_loss
  68. avg_cost = paddle.mean(loss)
  69. self._cost = avg_cost
  70. # 计算accuracy
  71. predictions = paddle.cast(sim_score > 0.5, 'float32')
  72. accuracy = paddle.mean(paddle.cast(paddle.equal(predictions, label), 'float32'))
  73. fetch_dict = {
  74. 'loss': avg_cost,
  75. 'accuracy': accuracy,
  76. #'similarity': sim_score,
  77. #'left_vector': left_vec,
  78. #'right_vector': right_vec
  79. }
  80. return fetch_dict
  81. def create_optimizer(self, strategy=None):
  82. optimizer = paddle.optimizer.Adam(
  83. learning_rate=self.learning_rate)
  84. if strategy is not None:
  85. import paddle.distributed.fleet as fleet
  86. optimizer = fleet.distributed_optimizer(optimizer, strategy)
  87. optimizer.minimize(self._cost)
  88. def infer_net(self, input):
  89. return self.net(input, is_infer=True)