MAMO模型复现
原文为MAMO: Memory-Augmented Meta-Optimization for Cold-start Recommendation。
本文重点是用几个记忆网络保存用户、物品及任务的一些信息,在遇到新任务时,用之前任务学到的一些先验知识进行初始化,之后经过少量迭代就可以收敛到一个不错的效果。
for i in range(self.n_epoch):
start = time.time()
u_grad_sum, i_grad_sum, r_grad_sum = self.model.get_zero_weights()
for u in self.train_users[:100]:
bias_term, att_values = user_mem_init(self.user_feature[u], self.device, self.FeatureMEM, self.x1_loading,self.alpha)
self.model.init_u_mem_weights(self.phi_u, bias_term, self.tao, self.phi_i, self.phi_r)
self.model.init_ui_mem_weights(att_values, self.TaskMEM)
interaction_info = [[self.user_feature[u]] * (self.support_size + self.query_size) ,
[self.item_feature[item_id] for item_id in self.dataset_['ui_interactions'][u]],
self.dataset_['ui_ratings'][u] - 1,
self.dataset_['ui_states'][u]]
user_module = LOCALUpdate(self.model, u, self.dataset, self.support_size, self.query_size, self.batch_size,
self.n_inner_loop, self.rho, top_k=3, device=self.device, interaction_info=interaction_info)
u_grad, i_grad, r_grad = user_module.train()
u_grad_sum, i_grad_sum, r_grad_sum = grads_sum(u_grad_sum, u_grad), grads_sum(i_grad_sum, i_grad), \
grads_sum(r_grad_sum, r_grad)
self.FeatureMEM.write_head(u_grad, self.beta)
u_mui = self.model.get_ui_mem_weights()
self.TaskMEM.write_head(u_mui[0], self.gamma)
self.phi_u, self.phi_i, self.phi_r = maml_train(self.phi_u, self.phi_i, self.phi_r,
u_grad_sum, i_grad_sum, r_grad_sum, self.lamda)
self.test_with_meta_optimization(i)
end = time.time()
print('Epoch {} cost {:.2f}s'.format(i+1, end-start))
实际流程和文章中给出的伪代码略有些不同。
第6行是获取\(b_u\)和\(a_u\),\(b_u\)是个性化偏置,\(a_u\)是用户与用户记忆的attention分数,同时更新\(M_P\)。
第8行是获取\(\theta_u\)、\(\theta_i\)、\(\theta_r\),分别对应用户embedding生成模块、物品embedding生成模块、推荐模块的参数。
第10行是获取\(M_{u,I}\),获取用户偏好矩阵。
第12~15行是获取本轮训练的数据。
第17~18和21行进行inner update,更新模型参数,并且获取到用户embedding生成模块、物品embedding生成模块、推荐模块的梯度。
第22~23行,梯度累加。
第25行,更新\(M_U\)。
第27行,更新\(M_{U,I}\)。
第29~30行,更新全局的用户embedding生成模块、物品embedding生成模块、推荐模块参数。
这里想要吐槽一下,作者给出的源码把每个用户的数据单独存储,处理后的数据大小变成1个G,我优化了一下存储数据的方法,数据只有几十M,而且运行速度和作者的基本上没差。
本文的思路很好,为每个用户生成独有的embedding生成器和推荐器,但是实验结果不太稳定,甚至在一些情况下MeLU比它要好不少,我觉得该方法应该还有较大的改进空间。
在movielens-1m上进行实验,四个场景分别为老用户-老物品、老用户-新物品、新用户-老物品、新用户-新物品,评估指标为MAE。
W-W | W-C | C-W | C-C | |
---|---|---|---|---|
原文结果 | 0.8725 | 0.9306 | 0.8967 | 0.8894 |
复现结果 | 0.8234 | 1.0043 | 0.7904 | 0.7778 |