Liuwq-bit / LightGT

LightGT: A Light Graph Transformer for Multimedia Recommendation, SIGIR2023
19 stars 2 forks source link

关于lightgcn和transformer输入数据的一些格式问题 #5

Closed tw1stszz closed 4 months ago

tw1stszz commented 4 months ago

非常仰慕前辈的工作,近期我试图复现前辈的代码,但是由于数据集原因无法在您的代码上直接复现。 (1)我在您的class TrainingDataset里面看到return torch.LongTensor([user, user]), torch.LongTensor([pos_item, neg_item]), user_item, mask然后在main.py中看到 for users, items, user_item, mask in train_dataloader: 我理解的是users是shape为(batchsize, 2)的tensor,items是shape为(batch_size, 2)的tensor, user_item的shape为(batch_size, src_len+1),其中您设置的src_len默认为50,mask的shape也为(batch_size, src_len+1),请问我理解的正确吗? (2)还有就是在lightGCN模块中,此处users_mean和items_mean是作为self-attention的输入,但是看代码调试结果好像users_mean和items_mean中的每一层的tensor都是相同的,这是不是和论文中描述的做法不太一样? (3)还有就是在transformer.py中attn_output_weights = attn_output_weights.view(batch_size, nheads, tgt_len, src_len),我在此处调试时的shape为(2048, 1, 51, 51),但是key_padding_mask的shape为(2048, 51),经过key_padding_mask.unsqueeze(1).unsqueeze(2)之后变成了(2048,1,1,51)这两者在mask_fill的时候好像对不太上,我就感觉是不是我的key_padding_mask在输入格式上出现了问题? 还请前辈能抽空为我答疑解惑。十分感谢。

Liuwq-bit commented 4 months ago

您好,感谢您对本工作的关注! 您对(1)的理解是正确的,src_len为每个用户可输入的最大物品个数,+1是为后续添加用户表征预留空间; 您在(3)中的操作也是正确的,mask_fill中所传入的key_padding_mask的size就是(batch_size, 1, 1, src_len)。 (2)中的问题确实存在,与论文所述不符。应该是因为我们最后做了其他实现方式的实验,版本管理出现失误,非常感谢您的指出!正确的实现方式应该如下: image

tw1stszz commented 4 months ago

非常感谢您的回答,我还有一个额外的问题,您在索引方面对所有的item_num的处理是加上了一个n_user使得两者没有交集,我想问一下如果不这么做会对结果有什么影响吗?因为在其他图网络的工作中好像不常提到这种做法,您当时是基于什么考虑的呢?非常感谢您的指教

Liuwq-bit commented 4 months ago

这个跟所使用的数据集有关。 我在实现过程中复用了部分MMGCN的代码,该模型最初所使用的数据集中,item编号的加上了n_user。 为贴合该部分代码,我直接将数据构造成类似的格式,在LightGT中并没有实际意义。

tw1stszz commented 4 months ago

非常感谢前辈抽出时间为我答疑解惑,在进一步研究您的代码的时候我对模型的输出还有些不确定的地方: (1)以item的视觉特征为例,v = self.v_linear(self.v_feat) ,模型对视觉特征v进行降维之后,虽然v进入了self-attention模块,但是v_out = self.v_encoder(v_in.transpose(0, 1), v_src, src_key_padding_mask=mask).transpose(0, 1)[:, 0]这段代码似乎只是输出了user在视觉方面的特征,最后模型输出物品的v也是只经过了一个nn.linear。 请问我理解的对吗,您似乎没有将self-attention输出的物品视觉特征使用进来

Liuwq-bit commented 4 months ago

您理解的对,Encoder只取输出的一维,再经过一个线性层。 Encoder的每一维输出实际上包含了对输入数据中所有维度的分析结果,并非仅是user的特征。 代码此处取了[:, 0],理论上,诸如[:, 1]、[:, -1]等实现具有同样的效果。