我一直在尝试训练一个相对简单的两塔网络进行推荐。我正在使用 PyTorch,实现如下 - 基本上为用户和项目嵌入层,两个塔的可选前馈网络,用户和项目表示之间的点积,以及 sigmoid。
class SimpleTwoTower(nn.Module):
def __init__(self, n_items, n_users, ln):
super(SimpleTwoTower, self).__init__()
self.ln = ln
self.item_emb = nn.Embedding(num_embeddings=n_items, embedding_dim=self.ln[0])
self.user_emb = nn.Embedding(num_embeddings=n_users, embedding_dim=self.ln[0])
self.item_layers = [] #nn.ModuleList()
self.user_layers = [] #nn.ModuleList()
for i, n in enumerate(ln[0:-1]):
m = int(ln[i+1])
self.item_layers.append(nn.Linear(n, m, bias=True))
self.item_layers.append(nn.ReLU())
self.user_layers.append(nn.Linear(n, m, bias=True))
self.user_layers.append(nn.ReLU())
self.item_layers = nn.Sequential(*self.item_layers)
self.user_layers = nn.Sequential(*self.user_layers)
self.dot = torch.matmul
self.sigmoid = nn.Sigmoid()
def forward(self, items, users):
item_emb = self.item_emb(items)
user_emb = self.user_emb(users)
item_emb = self.item_layers(item_emb)
user_emb = self.user_layers(user_emb)
dp = self.dot(user_emb, item_emb.t())
return self.sigmoid(dp)
我正在使用二进制交叉熵损失和 Adam 优化器。当我只使用嵌入时,我看到了从一个时期到另一个时期的改进(损失在减少,评估指标在增加)。然而,一旦我添加了一个前馈层,网络在第一个 epoch 中只学习了一点,然后就停滞不前了。我试图用 ReLU 编写一个线性层,以检查问题是否与我创建层列表的方式有关,但这并没有改变任何东西。
有没有其他人有类似的问题?
编辑:在这里,我在 PyTorch 论坛上发布了这个问题,我有一些回复。