|
@@ -4,45 +4,30 @@ import paddle.nn.functional as F
|
|
import numpy as np
|
|
import numpy as np
|
|
|
|
|
|
class DSSMLayer(nn.Layer):
|
|
class DSSMLayer(nn.Layer):
|
|
- def __init__(self, feature_nums=[5,5,5,5,5], embedding_dim=8, output_dim=16,
|
|
|
|
|
|
+ def __init__(self, tag_feature_nums=[5,5,5,5,5],
|
|
|
|
+ stat_features_num=47,
|
|
|
|
+ stat_features_num_embeddings=100,
|
|
|
|
+ embedding_dim=8, output_dim=16,
|
|
hidden_layers=[40, 32], hidden_acts=["relu", "relu"]):
|
|
hidden_layers=[40, 32], hidden_acts=["relu", "relu"]):
|
|
super(DSSMLayer, self).__init__()
|
|
super(DSSMLayer, self).__init__()
|
|
- tag_features_dict = [
|
|
|
|
- {"vid": 3407301},
|
|
|
|
- {"cate1": 42},
|
|
|
|
- {"cate2": 67},
|
|
|
|
- {"video_style": 6517},
|
|
|
|
- {"valid_time": 728},
|
|
|
|
- {"captions_color": 656},
|
|
|
|
- {"audience_age_group": 65},
|
|
|
|
- {"audience_value_type": 61},
|
|
|
|
- {"font_size": 49},
|
|
|
|
- {"cover_persons_num": 44},
|
|
|
|
- {"audience_gender": 37},
|
|
|
|
- {"sentiment_tendency": 11},
|
|
|
|
- {"video_type": 8},
|
|
|
|
- {"background_music_type": 6},
|
|
|
|
- {"captions": 3},
|
|
|
|
- {"has_end_credit_guide": 2}
|
|
|
|
- ]
|
|
|
|
-
|
|
|
|
- self.stat_features_num = 47
|
|
|
|
- self.stat_features_num_embeddings = 100
|
|
|
|
|
|
+
|
|
|
|
+ self.stat_features_num = stat_features_num
|
|
|
|
+ self.stat_features_num_embeddings = stat_features_num_embeddings
|
|
|
|
|
|
- self.feature_num = len(tag_features_dict)
|
|
|
|
- feature_nums = [list(d.values())[0] for d in tag_features_dict]
|
|
|
|
|
|
+ self.tag_feature_num = len(tag_feature_nums)
|
|
|
|
+ self.tag_feature_nums = tag_feature_nums
|
|
self.embedding_dim = embedding_dim
|
|
self.embedding_dim = embedding_dim
|
|
self.output_dim = output_dim
|
|
self.output_dim = output_dim
|
|
# 第一层的输入维度是所有特征的embedding拼接
|
|
# 第一层的输入维度是所有特征的embedding拼接
|
|
- self.hidden_layers = [self.feature_num * embedding_dim + self.stat_features_num*3*embedding_dim] + hidden_layers + [output_dim]
|
|
|
|
|
|
+ self.hidden_layers = [self.tag_feature_num * embedding_dim + self.stat_features_num*3*embedding_dim] + hidden_layers + [output_dim]
|
|
self.hidden_acts = hidden_acts
|
|
self.hidden_acts = hidden_acts
|
|
|
|
|
|
|
|
|
|
# 为每个特征创建对应维度的Embedding层
|
|
# 为每个特征创建对应维度的Embedding层
|
|
self.left_embeddings = nn.LayerList()
|
|
self.left_embeddings = nn.LayerList()
|
|
- for i in range(self.feature_num): # 视频的静态特征
|
|
|
|
|
|
+ for i in range(self.tag_feature_num): # 视频的静态特征
|
|
layer = nn.Embedding(
|
|
layer = nn.Embedding(
|
|
- num_embeddings=feature_nums[i],
|
|
|
|
|
|
+ num_embeddings=self.tag_feature_nums[i],
|
|
embedding_dim=embedding_dim,
|
|
embedding_dim=embedding_dim,
|
|
weight_attr=paddle.ParamAttr(
|
|
weight_attr=paddle.ParamAttr(
|
|
initializer=paddle.nn.initializer.XavierNormal()
|
|
initializer=paddle.nn.initializer.XavierNormal()
|
|
@@ -70,9 +55,9 @@ class DSSMLayer(nn.Layer):
|
|
|
|
|
|
|
|
|
|
self.right_embeddings = nn.LayerList()
|
|
self.right_embeddings = nn.LayerList()
|
|
- for i in range(self.feature_num): # 视频的静态特征
|
|
|
|
|
|
+ for i in range(self.tag_feature_num): # 视频的静态特征
|
|
layer = nn.Embedding(
|
|
layer = nn.Embedding(
|
|
- num_embeddings=feature_nums[i],
|
|
|
|
|
|
+ num_embeddings=self.tag_feature_nums[i],
|
|
embedding_dim=embedding_dim,
|
|
embedding_dim=embedding_dim,
|
|
weight_attr=paddle.ParamAttr(
|
|
weight_attr=paddle.ParamAttr(
|
|
initializer=paddle.nn.initializer.XavierNormal()
|
|
initializer=paddle.nn.initializer.XavierNormal()
|
|
@@ -146,7 +131,7 @@ class DSSMLayer(nn.Layer):
|
|
|
|
|
|
|
|
|
|
# 1. 处理视频静态特征 (使用Embedding)
|
|
# 1. 处理视频静态特征 (使用Embedding)
|
|
- for i in range(self.feature_num):
|
|
|
|
|
|
+ for i in range(self.tag_feature_num):
|
|
feature = paddle.slice(
|
|
feature = paddle.slice(
|
|
features,
|
|
features,
|
|
axes=[1],
|
|
axes=[1],
|
|
@@ -158,7 +143,7 @@ class DSSMLayer(nn.Layer):
|
|
embedded_features.append(embedded)
|
|
embedded_features.append(embedded)
|
|
|
|
|
|
# 2. 处理长短期和品类表现的分桶特征 (使用Embedding)
|
|
# 2. 处理长短期和品类表现的分桶特征 (使用Embedding)
|
|
- start_idx = self.feature_num
|
|
|
|
|
|
+ start_idx = self.tag_feature_num
|
|
for i in range(self.stat_features_num):
|
|
for i in range(self.stat_features_num):
|
|
feature = paddle.slice(
|
|
feature = paddle.slice(
|
|
features,
|
|
features,
|
|
@@ -167,11 +152,11 @@ class DSSMLayer(nn.Layer):
|
|
ends=[start_idx + i + 1]
|
|
ends=[start_idx + i + 1]
|
|
)
|
|
)
|
|
feature = paddle.cast(feature, dtype='int64')
|
|
feature = paddle.cast(feature, dtype='int64')
|
|
- embedded = embeddings[self.feature_num + i](feature)
|
|
|
|
|
|
+ embedded = embeddings[self.tag_feature_num + i](feature)
|
|
embedded_features.append(embedded)
|
|
embedded_features.append(embedded)
|
|
|
|
|
|
# 3. 处理原始值特征 (使用Linear)
|
|
# 3. 处理原始值特征 (使用Linear)
|
|
- start_idx = self.feature_num + self.stat_features_num
|
|
|
|
|
|
+ start_idx = self.tag_feature_num + self.stat_features_num
|
|
for i in range(self.stat_features_num * 2):
|
|
for i in range(self.stat_features_num * 2):
|
|
feature = paddle.slice(
|
|
feature = paddle.slice(
|
|
features,
|
|
features,
|
|
@@ -180,7 +165,7 @@ class DSSMLayer(nn.Layer):
|
|
ends=[start_idx + i + 1]
|
|
ends=[start_idx + i + 1]
|
|
)
|
|
)
|
|
feature = paddle.cast(feature, dtype='float32')
|
|
feature = paddle.cast(feature, dtype='float32')
|
|
- embedded = embeddings[self.feature_num + self.stat_features_num + i](feature)
|
|
|
|
|
|
+ embedded = embeddings[self.tag_feature_num + self.stat_features_num + i](feature)
|
|
# 将Linear层输出reshape为 [-1, 1, embedding_dim]
|
|
# 将Linear层输出reshape为 [-1, 1, embedding_dim]
|
|
embedded = paddle.reshape(embedded, [-1, 1, self.embedding_dim])
|
|
embedded = paddle.reshape(embedded, [-1, 1, self.embedding_dim])
|
|
embedded_features.append(embedded)
|
|
embedded_features.append(embedded)
|
|
@@ -216,7 +201,7 @@ class DSSMLayer(nn.Layer):
|
|
left_embedded = self._process_features(left_features, self.left_embeddings)
|
|
left_embedded = self._process_features(left_features, self.left_embeddings)
|
|
|
|
|
|
# left_vec = left_embedded
|
|
# left_vec = left_embedded
|
|
- left_vec = paddle.reshape(left_embedded, [-1, self.feature_num * self.embedding_dim])
|
|
|
|
|
|
+ left_vec = paddle.reshape(left_embedded, [-1, self.tag_feature_num * self.embedding_dim])
|
|
|
|
|
|
for i, layer in enumerate(self._left_tower):
|
|
for i, layer in enumerate(self._left_tower):
|
|
left_vec = layer(left_vec)
|
|
left_vec = layer(left_vec)
|
|
@@ -231,7 +216,7 @@ class DSSMLayer(nn.Layer):
|
|
# 处理右视频特征
|
|
# 处理右视频特征
|
|
right_embedded = self._process_features(right_features, self.right_embeddings)
|
|
right_embedded = self._process_features(right_features, self.right_embeddings)
|
|
# right_vec = right_embedded
|
|
# right_vec = right_embedded
|
|
- right_vec = paddle.reshape(right_embedded, [-1, self.feature_num * self.embedding_dim])
|
|
|
|
|
|
+ right_vec = paddle.reshape(right_embedded, [-1, self.tag_feature_num * self.embedding_dim])
|
|
|
|
|
|
for layer in self._right_tower:
|
|
for layer in self._right_tower:
|
|
right_vec = layer(right_vec)
|
|
right_vec = layer(right_vec)
|
|
@@ -254,7 +239,7 @@ class DSSMLayer(nn.Layer):
|
|
left_embedded = self._process_features(left_features, self.left_embeddings)
|
|
left_embedded = self._process_features(left_features, self.left_embeddings)
|
|
|
|
|
|
# left_vec = left_embedded
|
|
# left_vec = left_embedded
|
|
- left_vec = paddle.reshape(left_embedded, [-1, self.feature_num * self.embedding_dim])
|
|
|
|
|
|
+ left_vec = paddle.reshape(left_embedded, [-1, self.tag_feature_num * self.embedding_dim])
|
|
|
|
|
|
for i, layer in enumerate(self._left_tower):
|
|
for i, layer in enumerate(self._left_tower):
|
|
left_vec = layer(left_vec)
|
|
left_vec = layer(left_vec)
|
|
@@ -263,7 +248,7 @@ class DSSMLayer(nn.Layer):
|
|
# 处理右视频特征
|
|
# 处理右视频特征
|
|
right_embedded = self._process_features(right_features, self.left_embeddings)
|
|
right_embedded = self._process_features(right_features, self.left_embeddings)
|
|
# right_vec = right_embedded
|
|
# right_vec = right_embedded
|
|
- right_vec = paddle.reshape(right_embedded, [-1, self.feature_num * self.embedding_dim])
|
|
|
|
|
|
+ right_vec = paddle.reshape(right_embedded, [-1, self.tag_feature_num * self.embedding_dim])
|
|
|
|
|
|
for layer in self._left_tower:
|
|
for layer in self._left_tower:
|
|
right_vec = layer(right_vec)
|
|
right_vec = layer(right_vec)
|