我想以矢量化的方式实现场感知分解模型(FFM)。在 FFM 中,通过以下等式进行预测
其中 w 是依赖于特征和另一个特征的字段的嵌入。有关详细信息,请参阅FFM(4)
中的方程式。
为此,我定义了以下参数:
import torch
W = torch.nn.Parameter(torch.Tensor(n_features, n_fields, n_factors), requires_grad=True)
现在,给定x
size的输入(batch_size, n_features)
,我希望能够计算前面的等式。这是我当前的(非矢量化)实现:
total_inter = torch.zeros(x.shape[0])
for i in range(n_features):
for j in range(i + 1, n_features):
temp1 = torch.mm(
x[:, i].unsqueeze(1),
W[i, feature2field[j], :].unsqueeze(0))
temp2 = torch.mm(
x[:, j].unsqueeze(1),
W[j, feature2field[i], :].unsqueeze(0))
total_inter += torch.sum(temp1 * temp2, dim=1)
不出所料,这个实现非常慢,因为n_features
很容易达到 1000!但是请注意,大多数条目x
都是 0。感谢所有输入!
编辑:
如果它可以在任何方面有所帮助,以下是 PyTorch 中此模型的一些实现:
不幸的是,我无法弄清楚他们是如何做到的。
附加更新:
我现在可以通过以下方式以更有效的方式获得x
产品W
:
temp = torch.einsum('ij, jkl -> ijkl', x, W)
因此,我的循环现在是:
total_inter = torch.zeros(x.shape[0])
for i in range(n_features):
for j in range(i + 1, n_features):
temp1 = temp[:, i, feature2field[j], :]
temp2 = temp[:, j, feature2field[i], :]
total_inter += 0.5 * torch.sum(temp1 * temp2, dim=1)
然而,由于该循环进行了大约 500 000 次迭代,因此仍然太长。