net.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import paddle
  2. import paddle.nn as nn
  3. import paddle.nn.functional as F
  4. import numpy as np
  5. class DSSMLayer(nn.Layer):
  6. def __init__(self, feature_nums=[5,5,5,5,5], embedding_dim=8, output_dim=16,
  7. hidden_layers=[40, 32], hidden_acts=["relu", "relu"]):
  8. super(DSSMLayer, self).__init__()
  9. self.feature_num = len(feature_nums)
  10. self.embedding_dim = embedding_dim
  11. self.output_dim = output_dim
  12. # 第一层的输入维度是所有特征的embedding拼接
  13. self.hidden_layers = [self.feature_num * embedding_dim] + hidden_layers + [output_dim]
  14. self.hidden_acts = hidden_acts
  15. # 为每个特征创建对应维度的Embedding层
  16. self.left_embeddings = nn.LayerList([
  17. nn.Embedding(
  18. num_embeddings=feature_nums[i],
  19. embedding_dim=embedding_dim,
  20. weight_attr=paddle.ParamAttr(
  21. initializer=paddle.nn.initializer.XavierNormal()
  22. )
  23. ) for i in range(self.feature_num)
  24. ])
  25. self.right_embeddings = nn.LayerList([
  26. nn.Embedding(
  27. num_embeddings=feature_nums[i],
  28. embedding_dim=embedding_dim,
  29. weight_attr=paddle.ParamAttr(
  30. initializer=paddle.nn.initializer.XavierNormal()
  31. )
  32. ) for i in range(self.feature_num)
  33. ])
  34. # 左视频塔
  35. self._left_tower = []
  36. for i in range(len(self.hidden_layers) - 1):
  37. linear = paddle.nn.Linear(
  38. in_features=self.hidden_layers[i],
  39. out_features=self.hidden_layers[i + 1],
  40. weight_attr=paddle.ParamAttr(
  41. initializer=paddle.nn.initializer.XavierNormal()
  42. ),
  43. bias_attr=paddle.ParamAttr(
  44. initializer=paddle.nn.initializer.Constant(value=0.0)
  45. )
  46. )
  47. self.add_sublayer('left_linear_%d' % i, linear)
  48. self._left_tower.append(linear)
  49. if i < len(hidden_acts) and self.hidden_acts[i] == "relu":
  50. act = paddle.nn.ReLU()
  51. self.add_sublayer('left_act_%d' % i, act)
  52. self._left_tower.append(act)
  53. # 右视频塔
  54. self._right_tower = []
  55. for i in range(len(self.hidden_layers) - 1):
  56. linear = paddle.nn.Linear(
  57. in_features=self.hidden_layers[i],
  58. out_features=self.hidden_layers[i + 1],
  59. weight_attr=paddle.ParamAttr(
  60. initializer=paddle.nn.initializer.XavierNormal()
  61. ),
  62. bias_attr=paddle.ParamAttr(
  63. initializer=paddle.nn.initializer.Constant(value=0.0)
  64. )
  65. )
  66. self.add_sublayer('right_linear_%d' % i, linear)
  67. self._right_tower.append(linear)
  68. if i < len(hidden_acts) and self.hidden_acts[i] == "relu":
  69. act = paddle.nn.ReLU()
  70. self.add_sublayer('right_act_%d' % i, act)
  71. self._right_tower.append(act)
  72. def _process_features(self, features, embeddings):
  73. # 将每个特征转换为embedding
  74. embedded_features = []
  75. for i in range(self.feature_num):
  76. feature = paddle.slice(
  77. features,
  78. axes=[1],
  79. starts=[i],
  80. ends=[i+1]
  81. )
  82. feature = paddle.cast(feature, dtype='int64')
  83. embedded = embeddings[i](feature)
  84. paddle.static.Print(embedded, message="lqc debug _process_features embedded {i}:")
  85. embedded_features.append(embedded)
  86. # 将所有embedding连接起来
  87. return paddle.concat(embedded_features, axis=1)
  88. def forward(self, left_features, right_features):
  89. # 获取两个视频的特征表示
  90. left_vec, right_vec = self.get_vectors(left_features, right_features)
  91. # 计算相似度
  92. sim_score = F.cosine_similarity(
  93. left_vec,
  94. right_vec,
  95. axis=1
  96. ).reshape([-1, 1])
  97. return sim_score, left_vec, right_vec
  98. def get_vectors(self, left_features, right_features):
  99. """获取两个视频的16维特征向量"""
  100. # 处理左视频特征
  101. left_embedded = self._process_features(left_features, self.left_embeddings)
  102. paddle.static.Print(left_embedded, message="lqc left_embedded shape:")
  103. left_vec = left_embedded
  104. paddle.static.Print(left_vec, message=f"lqc lqc left_vec {i}:")
  105. for i, layer in enumerate(self._left_tower):
  106. left_vec = layer(left_vec)
  107. paddle.static.Print(left_vec, message=f"After layer {i}:")
  108. # 处理右视频特征
  109. right_embedded = self._process_features(right_features, self.right_embeddings)
  110. right_vec = right_embedded
  111. for layer in self._right_tower:
  112. right_vec = layer(right_vec)
  113. # 确保输出是L2归一化的
  114. left_vec = F.normalize(left_vec, p=2, axis=1)
  115. right_vec = F.normalize(right_vec, p=2, axis=1)
  116. return left_vec, right_vec