| 68 | |
| 69 | |
| 70 | class FANVMModel(torch.nn.Module): |
| 71 | def __init__(self,bert_model,fea_dim): |
| 72 | super(FANVMModel, self).__init__() |
| 73 | self.text_dim = 768 |
| 74 | self.img_dim = 4096 |
| 75 | self.topic_dim = 15 |
| 76 | |
| 77 | self.bert = BertModel.from_pretrained(bert_model).requires_grad_(False) |
| 78 | self.title_encoder = TextCNN(fea_dim, self.text_dim) |
| 79 | self.comments_encoder = BiLSTM(self.text_dim,300,fea_dim) |
| 80 | self.video_encoder = VideoEncoder(self.img_dim,fea_dim) |
| 81 | |
| 82 | self.gate_m1 = torch.nn.Linear(fea_dim*2,1) |
| 83 | self.gate_m2 = torch.nn.Linear(fea_dim*2,1) |
| 84 | |
| 85 | self.classifier = nn.Linear(fea_dim*2,2) |
| 86 | self.classifier_topic = nn.Linear(fea_dim*3,self.topic_dim) |
| 87 | |
| 88 | def forward(self, **kwargs): |
| 89 | title_inputid = kwargs['title_inputid']#(batch,512) |
| 90 | title_mask = kwargs['title_mask']#(batch,512) |
| 91 | fea_text = self.bert(title_inputid,attention_mask=title_mask)[0] #(bs,seq,768) |
| 92 | fea_text = self.title_encoder(fea_text) |
| 93 | fea_R = fea_text # (bs, 128) |
| 94 | |
| 95 | comments_inputid = kwargs['comments_inputid']#(batch,20,250) |
| 96 | comments_mask=kwargs['comments_mask']#(batch,20,250) |
| 97 | comments_like=kwargs['comments_like'] |
| 98 | comments_feature=[] |
| 99 | for i in range(comments_inputid.shape[0]): |
| 100 | bert_fea=self.bert(comments_inputid[i], attention_mask=comments_mask[i])[0] |
| 101 | comments_feature.append(self.comments_encoder(bert_fea)) |
| 102 | comments_feature=torch.stack(comments_feature) #(batch,seq,fea_dim) |
| 103 | fea_comments =[] |
| 104 | for v in range(comments_like.shape[0]): # batch内循环 |
| 105 | # print (reviews_like[v]) |
| 106 | comments_weight=torch.stack([torch.true_divide((i+1),(comments_like[v].shape[0]+comments_like[v].sum())) for i in comments_like[v]]) |
| 107 | comments_fea_reweight = torch.sum(comments_feature[v]*(comments_weight.reshape(comments_weight.shape[0],1)),dim=0) |
| 108 | fea_comments.append(comments_fea_reweight) |
| 109 | fea_comments = torch.stack(fea_comments) |
| 110 | fea_H = fea_comments # (bs, 600) |
| 111 | |
| 112 | frames = kwargs['frames'] # (bs, 30, 4096) |
| 113 | frame_thumb = kwargs['frame_thmub'] # (bs,1,4096) |
| 114 | fea_video = self.video_encoder(frame_thumb, frames) |
| 115 | fea_V = fea_video # (bs, 128) |
| 116 | |
| 117 | s = kwargs['s'] |
| 118 | |
| 119 | ## fusion: title, frames |
| 120 | m1 = self.gate_m1(torch.cat((fea_V, fea_R),1)) |
| 121 | fea_P = torch.add(torch.mul(m1,fea_V),torch.mul((1-m1),fea_R)) |
| 122 | ## fusion: comments, title |
| 123 | m2 = s.reshape((s.shape[0],1)) |
| 124 | fea_E = torch.add(torch.mul(fea_H,m2),torch.mul(fea_R,(1-m2))) |
| 125 | |
| 126 | fea_fnd = torch.cat((fea_P,fea_E),1).to(torch.float32) |
| 127 | output = self.classifier(fea_fnd) |