Я оцениваю рейтинги в матрице пользовательских элементов, разбивая матрицу на две матрицы P
и Q
с помощью матричной факторизации PyTorch. Я получил свою функцию потерь L(X-PQ)
.
Допустим, строки X
соответствуют пользователям, а x
— это новая строка пользователя, так что новые X
являются X
конкатенированными с x
. Теперь я хочу минимизировать L(X' - P'Q) = L(X - PQ) + L(x - x_pQ)
. Так как я уже обучил P
и Q
. Я хочу обучить x_p
, который является строкой нового пользователя, но оставить Q
исправленным.
Итак, мой вопрос: есть ли в PyTorch способ обучить модель MatrixFactorization
для P
с фиксированным Q
?
Код, с которым я работаю:
class MatrixFactorizationWithBiasXavier(nn.Module):
def __init__(self, num_people, num_partners, bias=(-0.01, 0.01), emb_size=100):
super(MatrixFactorizationWithBiasXavier, self).__init__()
self.person_emb = nn.Embedding(num_people, emb_size)
self.person_bias = nn.Embedding(num_people, 1)
self.partner_emb = nn.Embedding(num_partners, emb_size)
self.parnter_bias = nn.Embedding(num_partners, 1)
torch.nn.init.xavier_uniform_(self.person_emb.weight)
torch.nn.init.xavier_uniform_(self.partner_emb.weight)
self.person_bias.weight.data.uniform_(bias[0], bias[1])
self.parnter_bias.weight.data.uniform_(bias[0], bias[1])
def forward(self, u, v):
u = self.person_emb(u)
v = self.partner_emb(v)
bias_u = self.person_bias(u).squeeze()
bias_v = self.parnter_bias(v).squeeze()
# calculate dot product
# u*v is a element wise vector multiplication
return torch.sigmoid((u*v).sum(1) + bias_u + bias_v)
def test(model, df_test, verbose=False):
model.eval()
# .to(dev) puts code on either gpu or cpu.
people = torch.LongTensor(df_test.id.values).to(dev)
partners = torch.LongTensor(df_test.pid.values).to(dev)
decision = torch.FloatTensor(df_test.decision.values).to(dev)
y_hat = model(people, partners)
loss = F.mse_loss(y_hat, decision)
if verbose:
print('test loss %.3f ' % loss.item())
return loss.item()
def train(model, df_train, epochs=100, learning_rate=0.01, weight_decay=1e-5, verbose=False):
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=weight_decay)
model.train()
for epoch in range(epochs):
# From numpy to PyTorch tensors.
# .to(dev) puts code on either gpu or cpu.
people = torch.LongTensor(df_train.id.values).to(dev)
partners = torch.LongTensor(df_train.pid.values).to(dev)
decision = torch.FloatTensor(df_train.decision.values).to(dev)
# calls forward method of the model
y_hat = model(people, partners)
# Using mean squared errors loss function
loss = F.mse_loss(y_hat, decision)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if verbose and epoch % 100 == 0:
print(loss.item())