引用模型参数的 PyTorch 损失函数



对于作业,我需要创建一个使用提供的损失函数的电影推荐系统:

sum(􏰀i=1,M) 􏰀sum(j=1,M) indicator[i̸=j](viT vj − Xi,j )**2

这意味着,两个电影嵌入之间的点积,Vi和Vj应该非常接近Xi,j。其中 Xi,j 是同时喜欢电影 i 和电影 j 的用户的总和。指标函数省略了 i == j 的条目(设置为 0(。

赋值可交付成果是隐藏层的权重矩阵。它的尺寸应为 9724x300,其中有 9724 个唯一的电影 ID 和 300 个神经元。300是一个任意选择,受到Google的word2vec中使用300个神经元的影响。

我有什么:

  • source_data:行是用户,列是电影。给定单元格中的 1 表示相应的用户喜欢相应的电影(不喜欢 = 0(。
  • preprocessed_data:source_data在自身上转置的矩阵乘法。(即每个单元格都是喜欢电影 i 和 j 的用户的总和。对角线条目对我来说没有用,因为它们只是喜欢一部电影的用户的总和。

我卡住的地方:

  • 不确定如何用 i 和 j 来定义我自己的损失函数,该函数可以将喜欢电影 i 和 j 的用户总和与隐藏层权重张量中的行 i 和 j 进行比较preprocessed_data。
  • 不确定如何将我的数据组织成 X 和 y 张量,以便数据适合损失函数。

在您进一步阅读之前,请注意,在 StackOverflow 的作业中寻求和接受直接帮助可能会违反您学校的规则,并对您作为学生造成后果!

话虽如此,我对此问题进行建模的方式如下:

import torch
U = 300 # number of users
M = 30  # number of movies
D = 4   # dimension of embedding vectors
source = torch.randint(0, 2, (U, M)) # users' ratings
X = source.transpose(0, 1) @ source  # your `preprocessed_data`
# initial values for your embedding. This is what your algorithm needs to learn
v = torch.randn(M, D, requires_grad=True)
X = X.to(torch.float32) # necessary to be in line with `v`
# this is the `(viT vj − Xi,j )**2` part
loss_elementwise = (v @ v.transpose(0, 1) - X).pow(2)
# now we need to get rid of the diagonal. Notice that we can equally
# well get rid of the diagonal and the whole upper triangular part,
# as well, since both V @ V.T and source.T @ source are symmetric, so
# the upper triangular part contains just
# a mirror reflection of the lower triangular part.
# This means that we actually implement a bit different summation:
# sum(i=1,M) sum(j=1,i-1) stuff(i, j)
# instead of
# sum(i=1,M) sum(j=1,M) indicator[i̸=j] stuff(i, j)
# and get exactly half the original value
masked = torch.tril(loss_elementwise, -1)
# finally we sum it up, multiplying by 2 to make up
# for the "lost" upper triangular part
loss = 2 * masked.sum()

现在留给你实现的是优化循环,它将使用loss梯度来优化v的值。

最新更新