nextrec 0.4.21__py3-none-any.whl → 0.4.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nextrec/__version__.py +1 -1
- nextrec/basic/activation.py +1 -1
- nextrec/basic/heads.py +2 -3
- nextrec/basic/metrics.py +1 -2
- nextrec/basic/model.py +115 -80
- nextrec/basic/summary.py +36 -2
- nextrec/data/preprocessor.py +137 -5
- nextrec/loss/__init__.py +0 -4
- nextrec/loss/grad_norm.py +3 -3
- nextrec/loss/listwise.py +19 -6
- nextrec/loss/pairwise.py +6 -4
- nextrec/loss/pointwise.py +8 -6
- nextrec/models/multi_task/esmm.py +3 -26
- nextrec/models/multi_task/mmoe.py +2 -24
- nextrec/models/multi_task/ple.py +13 -35
- nextrec/models/multi_task/poso.py +4 -28
- nextrec/models/multi_task/share_bottom.py +1 -24
- nextrec/models/ranking/afm.py +3 -27
- nextrec/models/ranking/autoint.py +5 -38
- nextrec/models/ranking/dcn.py +1 -26
- nextrec/models/ranking/dcn_v2.py +5 -33
- nextrec/models/ranking/deepfm.py +2 -29
- nextrec/models/ranking/dien.py +2 -28
- nextrec/models/ranking/din.py +2 -27
- nextrec/models/ranking/eulernet.py +3 -30
- nextrec/models/ranking/ffm.py +0 -26
- nextrec/models/ranking/fibinet.py +8 -32
- nextrec/models/ranking/fm.py +0 -29
- nextrec/models/ranking/lr.py +0 -30
- nextrec/models/ranking/masknet.py +4 -30
- nextrec/models/ranking/pnn.py +4 -28
- nextrec/models/ranking/widedeep.py +0 -32
- nextrec/models/ranking/xdeepfm.py +0 -30
- nextrec/models/retrieval/dssm.py +0 -24
- nextrec/models/retrieval/dssm_v2.py +0 -24
- nextrec/models/retrieval/mind.py +0 -20
- nextrec/models/retrieval/sdm.py +0 -20
- nextrec/models/retrieval/youtube_dnn.py +0 -21
- nextrec/models/sequential/hstu.py +0 -18
- nextrec/utils/__init__.py +5 -1
- nextrec/{loss/loss_utils.py → utils/loss.py} +17 -7
- nextrec/utils/model.py +79 -1
- nextrec/utils/types.py +62 -23
- {nextrec-0.4.21.dist-info → nextrec-0.4.23.dist-info}/METADATA +8 -6
- nextrec-0.4.23.dist-info/RECORD +81 -0
- nextrec-0.4.21.dist-info/RECORD +0 -81
- {nextrec-0.4.21.dist-info → nextrec-0.4.23.dist-info}/WHEEL +0 -0
- {nextrec-0.4.21.dist-info → nextrec-0.4.23.dist-info}/entry_points.txt +0 -0
- {nextrec-0.4.21.dist-info → nextrec-0.4.23.dist-info}/licenses/LICENSE +0 -0
|
@@ -32,7 +32,7 @@ EulerNet 使用欧拉公式将特征嵌入映射到复数域,通过复数相
|
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
34
|
from __future__ import annotations
|
|
35
|
-
|
|
35
|
+
from typing import Literal
|
|
36
36
|
import torch
|
|
37
37
|
import torch.nn as nn
|
|
38
38
|
import torch.nn.functional as F
|
|
@@ -61,7 +61,7 @@ class EulerInteractionLayer(nn.Module):
|
|
|
61
61
|
num_fields: int,
|
|
62
62
|
num_orders: int,
|
|
63
63
|
use_implicit: bool = True,
|
|
64
|
-
norm:
|
|
64
|
+
norm: Literal["bn", "ln"] | None = "ln", # None | "bn" | "ln"
|
|
65
65
|
eps: float = 1e-9,
|
|
66
66
|
):
|
|
67
67
|
super().__init__()
|
|
@@ -203,42 +203,22 @@ class EulerNet(BaseModel):
|
|
|
203
203
|
num_layers: int = 2,
|
|
204
204
|
num_orders: int = 8,
|
|
205
205
|
use_implicit: bool = True,
|
|
206
|
-
norm:
|
|
206
|
+
norm: Literal["bn", "ln"] | None = "ln",
|
|
207
207
|
use_linear: bool = False,
|
|
208
|
-
target: list[str] | str | None = None,
|
|
209
|
-
task: str | list[str] | None = None,
|
|
210
|
-
optimizer: str = "adam",
|
|
211
|
-
optimizer_params: dict | None = None,
|
|
212
|
-
loss: str | nn.Module | None = "bce",
|
|
213
|
-
loss_params: dict | list[dict] | None = None,
|
|
214
|
-
embedding_l1_reg=0.0,
|
|
215
|
-
dense_l1_reg=0.0,
|
|
216
|
-
embedding_l2_reg=0.0,
|
|
217
|
-
dense_l2_reg=0.0,
|
|
218
208
|
**kwargs,
|
|
219
209
|
):
|
|
220
210
|
|
|
221
211
|
dense_features = dense_features or []
|
|
222
212
|
sparse_features = sparse_features or []
|
|
223
213
|
sequence_features = sequence_features or []
|
|
224
|
-
optimizer_params = optimizer_params or {}
|
|
225
|
-
if loss is None:
|
|
226
|
-
loss = "bce"
|
|
227
214
|
|
|
228
215
|
super(EulerNet, self).__init__(
|
|
229
216
|
dense_features=dense_features,
|
|
230
217
|
sparse_features=sparse_features,
|
|
231
218
|
sequence_features=sequence_features,
|
|
232
|
-
target=target,
|
|
233
|
-
task=task or self.default_task,
|
|
234
|
-
embedding_l1_reg=embedding_l1_reg,
|
|
235
|
-
dense_l1_reg=dense_l1_reg,
|
|
236
|
-
embedding_l2_reg=embedding_l2_reg,
|
|
237
|
-
dense_l2_reg=dense_l2_reg,
|
|
238
219
|
**kwargs,
|
|
239
220
|
)
|
|
240
221
|
|
|
241
|
-
self.loss = loss
|
|
242
222
|
self.use_linear = use_linear
|
|
243
223
|
|
|
244
224
|
self.linear_features = dense_features + sparse_features + sequence_features
|
|
@@ -303,13 +283,6 @@ class EulerNet(BaseModel):
|
|
|
303
283
|
embedding_attr="embedding", include_modules=modules
|
|
304
284
|
)
|
|
305
285
|
|
|
306
|
-
self.compile(
|
|
307
|
-
optimizer=optimizer,
|
|
308
|
-
optimizer_params=optimizer_params,
|
|
309
|
-
loss=loss,
|
|
310
|
-
loss_params=loss_params,
|
|
311
|
-
)
|
|
312
|
-
|
|
313
286
|
def forward(self, x):
|
|
314
287
|
field_emb = self.embedding(
|
|
315
288
|
x=x, features=self.interaction_features, squeeze_dim=False
|
nextrec/models/ranking/ffm.py
CHANGED
|
@@ -63,35 +63,16 @@ class FFM(BaseModel):
|
|
|
63
63
|
dense_features: list[DenseFeature] | None = None,
|
|
64
64
|
sparse_features: list[SparseFeature] | None = None,
|
|
65
65
|
sequence_features: list[SequenceFeature] | None = None,
|
|
66
|
-
target: list[str] | str | None = None,
|
|
67
|
-
task: str | list[str] | None = None,
|
|
68
|
-
optimizer: str = "adam",
|
|
69
|
-
optimizer_params: dict | None = None,
|
|
70
|
-
loss: str | nn.Module | None = "bce",
|
|
71
|
-
loss_params: dict | list[dict] | None = None,
|
|
72
|
-
embedding_l1_reg=0.0,
|
|
73
|
-
dense_l1_reg=0.0,
|
|
74
|
-
embedding_l2_reg=0.0,
|
|
75
|
-
dense_l2_reg=0.0,
|
|
76
66
|
**kwargs,
|
|
77
67
|
):
|
|
78
68
|
dense_features = dense_features or []
|
|
79
69
|
sparse_features = sparse_features or []
|
|
80
70
|
sequence_features = sequence_features or []
|
|
81
|
-
optimizer_params = optimizer_params or {}
|
|
82
|
-
if loss is None:
|
|
83
|
-
loss = "bce"
|
|
84
71
|
|
|
85
72
|
super(FFM, self).__init__(
|
|
86
73
|
dense_features=dense_features,
|
|
87
74
|
sparse_features=sparse_features,
|
|
88
75
|
sequence_features=sequence_features,
|
|
89
|
-
target=target,
|
|
90
|
-
task=task or self.default_task,
|
|
91
|
-
embedding_l1_reg=embedding_l1_reg,
|
|
92
|
-
dense_l1_reg=dense_l1_reg,
|
|
93
|
-
embedding_l2_reg=embedding_l2_reg,
|
|
94
|
-
dense_l2_reg=dense_l2_reg,
|
|
95
76
|
**kwargs,
|
|
96
77
|
)
|
|
97
78
|
|
|
@@ -154,13 +135,6 @@ class FFM(BaseModel):
|
|
|
154
135
|
embedding_attr="field_aware_embeddings", include_modules=["linear_dense"]
|
|
155
136
|
)
|
|
156
137
|
|
|
157
|
-
self.compile(
|
|
158
|
-
optimizer=optimizer,
|
|
159
|
-
optimizer_params=optimizer_params,
|
|
160
|
-
loss=loss,
|
|
161
|
-
loss_params=loss_params,
|
|
162
|
-
)
|
|
163
|
-
|
|
164
138
|
def field_aware_key(
|
|
165
139
|
self, src_feature: SparseFeature | SequenceFeature, target_field
|
|
166
140
|
) -> str:
|
|
@@ -41,8 +41,7 @@ FiBiNET 是一个 CTR 预估模型,通过 SENET 重新分配特征字段的重
|
|
|
41
41
|
"""
|
|
42
42
|
|
|
43
43
|
import torch
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
from typing import Literal
|
|
46
45
|
from nextrec.basic.features import DenseFeature, SequenceFeature, SparseFeature
|
|
47
46
|
from nextrec.basic.layers import (
|
|
48
47
|
LR,
|
|
@@ -71,19 +70,13 @@ class FiBiNET(BaseModel):
|
|
|
71
70
|
sparse_features: list[SparseFeature] | None = None,
|
|
72
71
|
sequence_features: list[SequenceFeature] | None = None,
|
|
73
72
|
mlp_params: dict | None = None,
|
|
74
|
-
interaction_combo:
|
|
75
|
-
|
|
73
|
+
interaction_combo: Literal[
|
|
74
|
+
"01", "11", "10", "00"
|
|
75
|
+
] = "11", # "0": Hadamard, "1": Bilinear
|
|
76
|
+
bilinear_type: Literal[
|
|
77
|
+
"field_all", "field_each", "field_interaction"
|
|
78
|
+
] = "field_interaction",
|
|
76
79
|
senet_reduction: int = 3,
|
|
77
|
-
target: list[str] | str | None = None,
|
|
78
|
-
task: str | list[str] | None = None,
|
|
79
|
-
optimizer: str = "adam",
|
|
80
|
-
optimizer_params: dict | None = None,
|
|
81
|
-
loss: str | nn.Module | None = "bce",
|
|
82
|
-
loss_params: dict | list[dict] | None = None,
|
|
83
|
-
embedding_l1_reg=0.0,
|
|
84
|
-
dense_l1_reg=0.0,
|
|
85
|
-
embedding_l2_reg=0.0,
|
|
86
|
-
dense_l2_reg=0.0,
|
|
87
80
|
**kwargs,
|
|
88
81
|
):
|
|
89
82
|
|
|
@@ -91,24 +84,14 @@ class FiBiNET(BaseModel):
|
|
|
91
84
|
sparse_features = sparse_features or []
|
|
92
85
|
sequence_features = sequence_features or []
|
|
93
86
|
mlp_params = mlp_params or {}
|
|
94
|
-
optimizer_params = optimizer_params or {}
|
|
95
|
-
if loss is None:
|
|
96
|
-
loss = "bce"
|
|
97
87
|
|
|
98
88
|
super(FiBiNET, self).__init__(
|
|
99
89
|
dense_features=dense_features,
|
|
100
90
|
sparse_features=sparse_features,
|
|
101
91
|
sequence_features=sequence_features,
|
|
102
|
-
target=target,
|
|
103
|
-
task=task or self.default_task,
|
|
104
|
-
embedding_l1_reg=embedding_l1_reg,
|
|
105
|
-
dense_l1_reg=dense_l1_reg,
|
|
106
|
-
embedding_l2_reg=embedding_l2_reg,
|
|
107
|
-
dense_l2_reg=dense_l2_reg,
|
|
108
92
|
**kwargs,
|
|
109
93
|
)
|
|
110
94
|
|
|
111
|
-
self.loss = loss
|
|
112
95
|
self.linear_features = sparse_features + sequence_features
|
|
113
96
|
self.interaction_features = sparse_features + sequence_features
|
|
114
97
|
|
|
@@ -166,7 +149,7 @@ class FiBiNET(BaseModel):
|
|
|
166
149
|
num_pairs = self.num_fields * (self.num_fields - 1) // 2
|
|
167
150
|
interaction_dim = num_pairs * self.embedding_dim * 2
|
|
168
151
|
self.mlp = MLP(input_dim=interaction_dim, **mlp_params)
|
|
169
|
-
self.prediction_layer = TaskHead(task_type=self.
|
|
152
|
+
self.prediction_layer = TaskHead(task_type=self.task)
|
|
170
153
|
|
|
171
154
|
# Register regularization weights
|
|
172
155
|
self.register_regularization_weights(
|
|
@@ -180,13 +163,6 @@ class FiBiNET(BaseModel):
|
|
|
180
163
|
],
|
|
181
164
|
)
|
|
182
165
|
|
|
183
|
-
self.compile(
|
|
184
|
-
optimizer=optimizer,
|
|
185
|
-
optimizer_params=optimizer_params,
|
|
186
|
-
loss=loss,
|
|
187
|
-
loss_params=loss_params,
|
|
188
|
-
)
|
|
189
|
-
|
|
190
166
|
def forward(self, x):
|
|
191
167
|
input_linear = self.embedding(
|
|
192
168
|
x=x, features=self.linear_features, squeeze_dim=True
|
nextrec/models/ranking/fm.py
CHANGED
|
@@ -38,8 +38,6 @@ FM 是一种通过分解二阶特征交互矩阵、以线性复杂度建模特
|
|
|
38
38
|
- 结构简单、表现强健,常作 CTR 基线
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
import torch.nn as nn
|
|
42
|
-
|
|
43
41
|
from nextrec.basic.features import DenseFeature, SequenceFeature, SparseFeature
|
|
44
42
|
from nextrec.basic.layers import FM as FMInteraction
|
|
45
43
|
from nextrec.basic.heads import TaskHead
|
|
@@ -61,16 +59,6 @@ class FM(BaseModel):
|
|
|
61
59
|
dense_features: list[DenseFeature] | None = None,
|
|
62
60
|
sparse_features: list[SparseFeature] | None = None,
|
|
63
61
|
sequence_features: list[SequenceFeature] | None = None,
|
|
64
|
-
target: list[str] | str | None = None,
|
|
65
|
-
task: str | list[str] | None = None,
|
|
66
|
-
optimizer: str = "adam",
|
|
67
|
-
optimizer_params: dict | None = None,
|
|
68
|
-
loss: str | nn.Module | None = "bce",
|
|
69
|
-
loss_params: dict | list[dict] | None = None,
|
|
70
|
-
embedding_l1_reg=0.0,
|
|
71
|
-
dense_l1_reg=0.0,
|
|
72
|
-
embedding_l2_reg=0.0,
|
|
73
|
-
dense_l2_reg=0.0,
|
|
74
62
|
**kwargs,
|
|
75
63
|
):
|
|
76
64
|
|
|
@@ -82,19 +70,9 @@ class FM(BaseModel):
|
|
|
82
70
|
dense_features=dense_features,
|
|
83
71
|
sparse_features=sparse_features,
|
|
84
72
|
sequence_features=sequence_features,
|
|
85
|
-
target=target,
|
|
86
|
-
task=task or self.default_task,
|
|
87
|
-
embedding_l1_reg=embedding_l1_reg,
|
|
88
|
-
dense_l1_reg=dense_l1_reg,
|
|
89
|
-
embedding_l2_reg=embedding_l2_reg,
|
|
90
|
-
dense_l2_reg=dense_l2_reg,
|
|
91
73
|
**kwargs,
|
|
92
74
|
)
|
|
93
75
|
|
|
94
|
-
self.loss = loss
|
|
95
|
-
if self.loss is None:
|
|
96
|
-
self.loss = "bce"
|
|
97
|
-
|
|
98
76
|
self.fm_features = sparse_features + sequence_features
|
|
99
77
|
if len(self.fm_features) == 0:
|
|
100
78
|
raise ValueError("FM requires at least one sparse or sequence feature.")
|
|
@@ -111,13 +89,6 @@ class FM(BaseModel):
|
|
|
111
89
|
embedding_attr="embedding", include_modules=["linear"]
|
|
112
90
|
)
|
|
113
91
|
|
|
114
|
-
self.compile(
|
|
115
|
-
optimizer=optimizer,
|
|
116
|
-
optimizer_params=optimizer_params,
|
|
117
|
-
loss=loss,
|
|
118
|
-
loss_params=loss_params,
|
|
119
|
-
)
|
|
120
|
-
|
|
121
92
|
def forward(self, x):
|
|
122
93
|
input_fm = self.embedding(x=x, features=self.fm_features, squeeze_dim=False)
|
|
123
94
|
y_linear = self.linear(input_fm.flatten(start_dim=1))
|
nextrec/models/ranking/lr.py
CHANGED
|
@@ -38,8 +38,6 @@ LR 是 CTR/排序任务中最经典的线性基线模型。它将稠密、稀疏
|
|
|
38
38
|
- 权重可解释性强
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
import torch.nn as nn
|
|
42
|
-
|
|
43
41
|
from nextrec.basic.features import DenseFeature, SequenceFeature, SparseFeature
|
|
44
42
|
from nextrec.basic.layers import EmbeddingLayer, LR as LinearLayer
|
|
45
43
|
from nextrec.basic.heads import TaskHead
|
|
@@ -60,41 +58,20 @@ class LR(BaseModel):
|
|
|
60
58
|
dense_features: list[DenseFeature] | None = None,
|
|
61
59
|
sparse_features: list[SparseFeature] | None = None,
|
|
62
60
|
sequence_features: list[SequenceFeature] | None = None,
|
|
63
|
-
target: list[str] | str | None = None,
|
|
64
|
-
task: str | list[str] | None = None,
|
|
65
|
-
optimizer: str = "adam",
|
|
66
|
-
optimizer_params: dict | None = None,
|
|
67
|
-
loss: str | nn.Module | None = "bce",
|
|
68
|
-
loss_params: dict | list[dict] | None = None,
|
|
69
|
-
embedding_l1_reg=0.0,
|
|
70
|
-
dense_l1_reg=0.0,
|
|
71
|
-
embedding_l2_reg=0.0,
|
|
72
|
-
dense_l2_reg=0.0,
|
|
73
61
|
**kwargs,
|
|
74
62
|
):
|
|
75
63
|
|
|
76
64
|
dense_features = dense_features or []
|
|
77
65
|
sparse_features = sparse_features or []
|
|
78
66
|
sequence_features = sequence_features or []
|
|
79
|
-
optimizer_params = optimizer_params or {}
|
|
80
|
-
if loss is None:
|
|
81
|
-
loss = "bce"
|
|
82
67
|
|
|
83
68
|
super(LR, self).__init__(
|
|
84
69
|
dense_features=dense_features,
|
|
85
70
|
sparse_features=sparse_features,
|
|
86
71
|
sequence_features=sequence_features,
|
|
87
|
-
target=target,
|
|
88
|
-
task=task or self.default_task,
|
|
89
|
-
embedding_l1_reg=embedding_l1_reg,
|
|
90
|
-
dense_l1_reg=dense_l1_reg,
|
|
91
|
-
embedding_l2_reg=embedding_l2_reg,
|
|
92
|
-
dense_l2_reg=dense_l2_reg,
|
|
93
72
|
**kwargs,
|
|
94
73
|
)
|
|
95
74
|
|
|
96
|
-
self.loss = loss
|
|
97
|
-
|
|
98
75
|
self.embedding = EmbeddingLayer(features=self.all_features)
|
|
99
76
|
linear_input_dim = self.embedding.input_dim
|
|
100
77
|
self.linear = LinearLayer(linear_input_dim)
|
|
@@ -104,13 +81,6 @@ class LR(BaseModel):
|
|
|
104
81
|
embedding_attr="embedding", include_modules=["linear"]
|
|
105
82
|
)
|
|
106
83
|
|
|
107
|
-
self.compile(
|
|
108
|
-
optimizer=optimizer,
|
|
109
|
-
optimizer_params=optimizer_params,
|
|
110
|
-
loss=loss,
|
|
111
|
-
loss_params=loss_params,
|
|
112
|
-
)
|
|
113
|
-
|
|
114
84
|
def forward(self, x):
|
|
115
85
|
input_linear = self.embedding(x=x, features=self.all_features, squeeze_dim=True)
|
|
116
86
|
y = self.linear(input_linear)
|
|
@@ -56,7 +56,7 @@ embedding 表示生成一个个性化的 “mask” 向量,通过逐元素的
|
|
|
56
56
|
import torch
|
|
57
57
|
import torch.nn as nn
|
|
58
58
|
import torch.nn.functional as F
|
|
59
|
-
|
|
59
|
+
from typing import Literal
|
|
60
60
|
from nextrec.basic.features import DenseFeature, SequenceFeature, SparseFeature
|
|
61
61
|
from nextrec.basic.layers import MLP, EmbeddingLayer
|
|
62
62
|
from nextrec.basic.heads import TaskHead
|
|
@@ -167,48 +167,28 @@ class MaskNet(BaseModel):
|
|
|
167
167
|
dense_features: list[DenseFeature] | None = None,
|
|
168
168
|
sparse_features: list[SparseFeature] | None = None,
|
|
169
169
|
sequence_features: list[SequenceFeature] | None = None,
|
|
170
|
-
architecture:
|
|
170
|
+
architecture: Literal[
|
|
171
|
+
"serial", "parallel"
|
|
172
|
+
] = "parallel", # "serial" or "parallel"
|
|
171
173
|
num_blocks: int = 3,
|
|
172
174
|
mask_hidden_dim: int = 64,
|
|
173
175
|
block_hidden_dim: int = 256,
|
|
174
176
|
block_dropout: float = 0.0,
|
|
175
177
|
mlp_params: dict | None = None,
|
|
176
|
-
target: list[str] | str | None = None,
|
|
177
|
-
task: str | list[str] | None = None,
|
|
178
|
-
optimizer: str = "adam",
|
|
179
|
-
optimizer_params: dict | None = None,
|
|
180
|
-
loss: str | nn.Module | None = "bce",
|
|
181
|
-
loss_params: dict | list[dict] | None = None,
|
|
182
|
-
embedding_l1_reg=0.0,
|
|
183
|
-
dense_l1_reg=0.0,
|
|
184
|
-
embedding_l2_reg=0.0,
|
|
185
|
-
dense_l2_reg=0.0,
|
|
186
178
|
**kwargs,
|
|
187
179
|
):
|
|
188
180
|
dense_features = dense_features or []
|
|
189
181
|
sparse_features = sparse_features or []
|
|
190
182
|
sequence_features = sequence_features or []
|
|
191
|
-
target = target or []
|
|
192
183
|
mlp_params = mlp_params or {}
|
|
193
|
-
optimizer_params = optimizer_params or {}
|
|
194
184
|
|
|
195
185
|
super().__init__(
|
|
196
186
|
dense_features=dense_features,
|
|
197
187
|
sparse_features=sparse_features,
|
|
198
188
|
sequence_features=sequence_features,
|
|
199
|
-
target=target,
|
|
200
|
-
task=task or self.default_task,
|
|
201
|
-
embedding_l1_reg=embedding_l1_reg,
|
|
202
|
-
dense_l1_reg=dense_l1_reg,
|
|
203
|
-
embedding_l2_reg=embedding_l2_reg,
|
|
204
|
-
dense_l2_reg=dense_l2_reg,
|
|
205
189
|
**kwargs,
|
|
206
190
|
)
|
|
207
191
|
|
|
208
|
-
if loss is None:
|
|
209
|
-
loss = "bce"
|
|
210
|
-
self.loss = loss
|
|
211
|
-
|
|
212
192
|
self.dense_features = dense_features
|
|
213
193
|
self.sparse_features = sparse_features
|
|
214
194
|
self.sequence_features = sequence_features
|
|
@@ -293,12 +273,6 @@ class MaskNet(BaseModel):
|
|
|
293
273
|
self.register_regularization_weights(
|
|
294
274
|
embedding_attr="embedding", include_modules=["mask_blocks", "final_mlp"]
|
|
295
275
|
)
|
|
296
|
-
self.compile(
|
|
297
|
-
optimizer=optimizer,
|
|
298
|
-
optimizer_params=optimizer_params,
|
|
299
|
-
loss=loss,
|
|
300
|
-
loss_params=loss_params,
|
|
301
|
-
)
|
|
302
276
|
|
|
303
277
|
def forward(self, x: dict[str, torch.Tensor]) -> torch.Tensor:
|
|
304
278
|
field_emb = self.embedding(x=x, features=self.mask_features, squeeze_dim=False)
|
nextrec/models/ranking/pnn.py
CHANGED
|
@@ -36,7 +36,7 @@ PNN 是一种 CTR 预估模型,通过将线性信号与乘积信号结合,
|
|
|
36
36
|
|
|
37
37
|
import torch
|
|
38
38
|
import torch.nn as nn
|
|
39
|
-
|
|
39
|
+
from typing import Literal
|
|
40
40
|
from nextrec.basic.features import DenseFeature, SequenceFeature, SparseFeature
|
|
41
41
|
from nextrec.basic.layers import MLP, EmbeddingLayer
|
|
42
42
|
from nextrec.basic.heads import TaskHead
|
|
@@ -59,18 +59,10 @@ class PNN(BaseModel):
|
|
|
59
59
|
sparse_features: list[SparseFeature] | None = None,
|
|
60
60
|
sequence_features: list[SequenceFeature] | None = None,
|
|
61
61
|
mlp_params: dict | None = None,
|
|
62
|
-
product_type:
|
|
62
|
+
product_type: Literal[
|
|
63
|
+
"inner", "outer", "both"
|
|
64
|
+
] = "inner", # "inner" (IPNN), "outer" (OPNN), "both" (PNN*)
|
|
63
65
|
outer_product_dim: int | None = None,
|
|
64
|
-
target: list[str] | str | None = None,
|
|
65
|
-
task: str | list[str] | None = None,
|
|
66
|
-
optimizer: str = "adam",
|
|
67
|
-
optimizer_params: dict | None = None,
|
|
68
|
-
loss: str | nn.Module | None = "bce",
|
|
69
|
-
loss_params: dict | list[dict] | None = None,
|
|
70
|
-
embedding_l1_reg=0.0,
|
|
71
|
-
dense_l1_reg=0.0,
|
|
72
|
-
embedding_l2_reg=0.0,
|
|
73
|
-
dense_l2_reg=0.0,
|
|
74
66
|
**kwargs,
|
|
75
67
|
):
|
|
76
68
|
|
|
@@ -80,20 +72,11 @@ class PNN(BaseModel):
|
|
|
80
72
|
mlp_params = mlp_params or {}
|
|
81
73
|
if outer_product_dim is not None and outer_product_dim <= 0:
|
|
82
74
|
raise ValueError("outer_product_dim must be a positive integer.")
|
|
83
|
-
optimizer_params = optimizer_params or {}
|
|
84
|
-
if loss is None:
|
|
85
|
-
loss = "bce"
|
|
86
75
|
|
|
87
76
|
super(PNN, self).__init__(
|
|
88
77
|
dense_features=dense_features,
|
|
89
78
|
sparse_features=sparse_features,
|
|
90
79
|
sequence_features=sequence_features,
|
|
91
|
-
target=target,
|
|
92
|
-
task=task or self.default_task,
|
|
93
|
-
embedding_l1_reg=embedding_l1_reg,
|
|
94
|
-
dense_l1_reg=dense_l1_reg,
|
|
95
|
-
embedding_l2_reg=embedding_l2_reg,
|
|
96
|
-
dense_l2_reg=dense_l2_reg,
|
|
97
80
|
**kwargs,
|
|
98
81
|
)
|
|
99
82
|
|
|
@@ -144,13 +127,6 @@ class PNN(BaseModel):
|
|
|
144
127
|
embedding_attr="embedding", include_modules=modules
|
|
145
128
|
)
|
|
146
129
|
|
|
147
|
-
self.compile(
|
|
148
|
-
optimizer=optimizer,
|
|
149
|
-
optimizer_params=optimizer_params,
|
|
150
|
-
loss=loss,
|
|
151
|
-
loss_params=loss_params,
|
|
152
|
-
)
|
|
153
|
-
|
|
154
130
|
def compute_inner_products(self, field_emb: torch.Tensor) -> torch.Tensor:
|
|
155
131
|
interactions = []
|
|
156
132
|
for i in range(self.num_fields - 1):
|
|
@@ -38,8 +38,6 @@ Wide & Deep 同时使用宽线性部分(记忆共现/手工交叉)与深网
|
|
|
38
38
|
- 共享特征空间,减少工程开销
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
import torch.nn as nn
|
|
42
|
-
|
|
43
41
|
from nextrec.basic.features import DenseFeature, SequenceFeature, SparseFeature
|
|
44
42
|
from nextrec.basic.layers import LR, MLP, EmbeddingLayer
|
|
45
43
|
from nextrec.basic.heads import TaskHead
|
|
@@ -61,40 +59,16 @@ class WideDeep(BaseModel):
|
|
|
61
59
|
sparse_features: list[SparseFeature],
|
|
62
60
|
sequence_features: list[SequenceFeature],
|
|
63
61
|
mlp_params: dict,
|
|
64
|
-
target: list[str] | str | None = None,
|
|
65
|
-
task: str | list[str] | None = None,
|
|
66
|
-
optimizer: str = "adam",
|
|
67
|
-
optimizer_params: dict | None = None,
|
|
68
|
-
loss: str | nn.Module | None = "bce",
|
|
69
|
-
loss_params: dict | list[dict] | None = None,
|
|
70
|
-
embedding_l1_reg=0.0,
|
|
71
|
-
dense_l1_reg=0.0,
|
|
72
|
-
embedding_l2_reg=0.0,
|
|
73
|
-
dense_l2_reg=0.0,
|
|
74
62
|
**kwargs,
|
|
75
63
|
):
|
|
76
64
|
|
|
77
|
-
if target is None:
|
|
78
|
-
target = []
|
|
79
|
-
optimizer_params = optimizer_params or {}
|
|
80
|
-
if loss is None:
|
|
81
|
-
loss = "bce"
|
|
82
|
-
|
|
83
65
|
super(WideDeep, self).__init__(
|
|
84
66
|
dense_features=dense_features,
|
|
85
67
|
sparse_features=sparse_features,
|
|
86
68
|
sequence_features=sequence_features,
|
|
87
|
-
target=target,
|
|
88
|
-
task=task or self.default_task,
|
|
89
|
-
embedding_l1_reg=embedding_l1_reg,
|
|
90
|
-
dense_l1_reg=dense_l1_reg,
|
|
91
|
-
embedding_l2_reg=embedding_l2_reg,
|
|
92
|
-
dense_l2_reg=dense_l2_reg,
|
|
93
69
|
**kwargs,
|
|
94
70
|
)
|
|
95
71
|
|
|
96
|
-
self.loss = loss
|
|
97
|
-
|
|
98
72
|
# Wide part: use all features for linear model
|
|
99
73
|
self.wide_features = sparse_features + sequence_features
|
|
100
74
|
# Deep part: use all features
|
|
@@ -117,12 +91,6 @@ class WideDeep(BaseModel):
|
|
|
117
91
|
self.register_regularization_weights(
|
|
118
92
|
embedding_attr="embedding", include_modules=["linear", "mlp"]
|
|
119
93
|
)
|
|
120
|
-
self.compile(
|
|
121
|
-
optimizer=optimizer,
|
|
122
|
-
optimizer_params=optimizer_params,
|
|
123
|
-
loss=loss,
|
|
124
|
-
loss_params=loss_params,
|
|
125
|
-
)
|
|
126
94
|
|
|
127
95
|
def forward(self, x):
|
|
128
96
|
# Deep part
|
|
@@ -121,41 +121,18 @@ class xDeepFM(BaseModel):
|
|
|
121
121
|
mlp_params: dict,
|
|
122
122
|
cin_size: list[int] | None = None,
|
|
123
123
|
split_half: bool = True,
|
|
124
|
-
target: list[str] | str | None = None,
|
|
125
|
-
task: str | list[str] | None = None,
|
|
126
|
-
optimizer: str = "adam",
|
|
127
|
-
optimizer_params: dict | None = None,
|
|
128
|
-
loss: str | nn.Module | None = "bce",
|
|
129
|
-
loss_params: dict | list[dict] | None = None,
|
|
130
|
-
embedding_l1_reg=0.0,
|
|
131
|
-
dense_l1_reg=0.0,
|
|
132
|
-
embedding_l2_reg=0.0,
|
|
133
|
-
dense_l2_reg=0.0,
|
|
134
124
|
**kwargs,
|
|
135
125
|
):
|
|
136
126
|
|
|
137
127
|
cin_size = cin_size or [128, 128]
|
|
138
|
-
if target is None:
|
|
139
|
-
target = []
|
|
140
|
-
optimizer_params = optimizer_params or {}
|
|
141
|
-
if loss is None:
|
|
142
|
-
loss = "bce"
|
|
143
128
|
|
|
144
129
|
super(xDeepFM, self).__init__(
|
|
145
130
|
dense_features=dense_features,
|
|
146
131
|
sparse_features=sparse_features,
|
|
147
132
|
sequence_features=sequence_features,
|
|
148
|
-
target=target,
|
|
149
|
-
task=task or self.default_task,
|
|
150
|
-
embedding_l1_reg=embedding_l1_reg,
|
|
151
|
-
dense_l1_reg=dense_l1_reg,
|
|
152
|
-
embedding_l2_reg=embedding_l2_reg,
|
|
153
|
-
dense_l2_reg=dense_l2_reg,
|
|
154
133
|
**kwargs,
|
|
155
134
|
)
|
|
156
135
|
|
|
157
|
-
self.loss = loss
|
|
158
|
-
|
|
159
136
|
# Linear part and CIN part: use sparse and sequence features
|
|
160
137
|
self.linear_features = sparse_features + sequence_features
|
|
161
138
|
|
|
@@ -195,13 +172,6 @@ class xDeepFM(BaseModel):
|
|
|
195
172
|
embedding_attr="embedding", include_modules=["linear", "cin", "mlp"]
|
|
196
173
|
)
|
|
197
174
|
|
|
198
|
-
self.compile(
|
|
199
|
-
optimizer=optimizer,
|
|
200
|
-
optimizer_params=optimizer_params,
|
|
201
|
-
loss=loss,
|
|
202
|
-
loss_params=loss_params,
|
|
203
|
-
)
|
|
204
|
-
|
|
205
175
|
def forward(self, x):
|
|
206
176
|
# Get embeddings for linear and CIN (sparse features only)
|
|
207
177
|
input_linear = self.embedding(
|
nextrec/models/retrieval/dssm.py
CHANGED
|
@@ -10,7 +10,6 @@ Reference:
|
|
|
10
10
|
from typing import Literal
|
|
11
11
|
|
|
12
12
|
import torch
|
|
13
|
-
import torch.nn as nn
|
|
14
13
|
|
|
15
14
|
from nextrec.basic.features import DenseFeature, SequenceFeature, SparseFeature
|
|
16
15
|
from nextrec.basic.layers import MLP, EmbeddingLayer
|
|
@@ -54,17 +53,6 @@ class DSSM(BaseMatchModel):
|
|
|
54
53
|
dense_l1_reg=0.0,
|
|
55
54
|
embedding_l2_reg=0.0,
|
|
56
55
|
dense_l2_reg=0.0,
|
|
57
|
-
optimizer: str | torch.optim.Optimizer = "adam",
|
|
58
|
-
optimizer_params: dict | None = None,
|
|
59
|
-
scheduler: (
|
|
60
|
-
str
|
|
61
|
-
| torch.optim.lr_scheduler._LRScheduler
|
|
62
|
-
| type[torch.optim.lr_scheduler._LRScheduler]
|
|
63
|
-
| None
|
|
64
|
-
) = None,
|
|
65
|
-
scheduler_params: dict | None = None,
|
|
66
|
-
loss: str | nn.Module | list[str | nn.Module] | None = "bce",
|
|
67
|
-
loss_params: dict | list[dict] | None = None,
|
|
68
56
|
**kwargs,
|
|
69
57
|
):
|
|
70
58
|
|
|
@@ -159,18 +147,6 @@ class DSSM(BaseMatchModel):
|
|
|
159
147
|
embedding_attr="item_embedding", include_modules=["item_dnn"]
|
|
160
148
|
)
|
|
161
149
|
|
|
162
|
-
if optimizer_params is None:
|
|
163
|
-
optimizer_params = {"lr": 1e-3, "weight_decay": 1e-5}
|
|
164
|
-
|
|
165
|
-
self.compile(
|
|
166
|
-
optimizer=optimizer,
|
|
167
|
-
optimizer_params=optimizer_params,
|
|
168
|
-
scheduler=scheduler,
|
|
169
|
-
scheduler_params=scheduler_params,
|
|
170
|
-
loss=loss,
|
|
171
|
-
loss_params=loss_params,
|
|
172
|
-
)
|
|
173
|
-
|
|
174
150
|
def user_tower(self, user_input: dict) -> torch.Tensor:
|
|
175
151
|
"""
|
|
176
152
|
User tower encodes user features into embeddings.
|
|
@@ -9,7 +9,6 @@ DSSM v2 - DSSM with pairwise training using BPR loss
|
|
|
9
9
|
from typing import Literal
|
|
10
10
|
|
|
11
11
|
import torch
|
|
12
|
-
import torch.nn as nn
|
|
13
12
|
|
|
14
13
|
from nextrec.basic.features import DenseFeature, SequenceFeature, SparseFeature
|
|
15
14
|
from nextrec.basic.layers import MLP, EmbeddingLayer
|
|
@@ -50,17 +49,6 @@ class DSSM_v2(BaseMatchModel):
|
|
|
50
49
|
dense_l1_reg: float = 0.0,
|
|
51
50
|
embedding_l2_reg: float = 0.0,
|
|
52
51
|
dense_l2_reg: float = 0.0,
|
|
53
|
-
optimizer: str | torch.optim.Optimizer = "adam",
|
|
54
|
-
optimizer_params: dict | None = None,
|
|
55
|
-
scheduler: (
|
|
56
|
-
str
|
|
57
|
-
| torch.optim.lr_scheduler._LRScheduler
|
|
58
|
-
| type[torch.optim.lr_scheduler._LRScheduler]
|
|
59
|
-
| None
|
|
60
|
-
) = None,
|
|
61
|
-
scheduler_params: dict | None = None,
|
|
62
|
-
loss: str | nn.Module | list[str | nn.Module] | None = "bce",
|
|
63
|
-
loss_params: dict | list[dict] | None = None,
|
|
64
52
|
**kwargs,
|
|
65
53
|
):
|
|
66
54
|
|
|
@@ -151,18 +139,6 @@ class DSSM_v2(BaseMatchModel):
|
|
|
151
139
|
embedding_attr="item_embedding", include_modules=["item_dnn"]
|
|
152
140
|
)
|
|
153
141
|
|
|
154
|
-
if optimizer_params is None:
|
|
155
|
-
optimizer_params = {"lr": 1e-3, "weight_decay": 1e-5}
|
|
156
|
-
|
|
157
|
-
self.compile(
|
|
158
|
-
optimizer=optimizer,
|
|
159
|
-
optimizer_params=optimizer_params,
|
|
160
|
-
scheduler=scheduler,
|
|
161
|
-
scheduler_params=scheduler_params,
|
|
162
|
-
loss=loss,
|
|
163
|
-
loss_params=loss_params,
|
|
164
|
-
)
|
|
165
|
-
|
|
166
142
|
def user_tower(self, user_input: dict) -> torch.Tensor:
|
|
167
143
|
"""User tower"""
|
|
168
144
|
all_user_features = (
|