我正在训练图卷积神经网络。分类器连接到该网络的末端,当我尝试将整个模型作为单个(多类)进行训练时,我可以获得 91% 的巨大成功(F1 加权分数)。
但是当我尝试训练与多标签相同的模型时,模型的训练时间要长得多并且模型会失败。
分类器代码如下,根据single或者multi分别进行工作。
class Classifier(nn.Module):
def __init__(self, input_dim, hidden_size, tag_size, args, pred_type='SINGLE'):
super(Classifier, self).__init__()
self.emotion_att = MaskedEmotionAtt(input_dim)
self.lin1 = nn.Linear(input_dim, hidden_size)
self.drop = nn.Dropout(args.drop_rate)
self.lin2 = nn.Linear(hidden_size, tag_size)
self.pred_type = pred_type
if args.class_weight:
self.loss_weights = (torch.rand(tag_size) * 9 + 1).to(args.device)
if self.pred_type == 'SINGLE':
self.loss_func = nn.NLLLoss(self.loss_weights)
elif self.pred_type == 'MULTI':
self.loss_func = nn.BCELoss(self.loss_weights)
else:
if self.pred_type == 'SINGLE':
self.loss_func = nn.NLLLoss()
elif self.pred_type == 'MULTI':
self.loss_func = nn.BCELoss()
def get_prob(self, h, text_len_tensor):
# h_hat = self.emotion_att(h, text_len_tensor)
hidden = self.drop(F.relu(self.lin1(h)))
scores = self.lin2(hidden)
if self.pred_type == 'SINGLE':
log_prob = F.log_softmax(scores, dim=-1)
elif self.pred_type == 'MULTI':
log_prob = F.sigmoid(scores)
else:
return scores
return log_prob
def forward(self, h, text_len_tensor):
log_prob = self.get_prob(h, text_len_tensor)
if self.pred_type == 'SINGLE':
y_hat = torch.argmax(log_prob, dim=-1)
elif self.pred_type == 'MULTI':
y_hat = []
for pred in log_prob:
y_hat.append([1 if p > 0.5 else 0 for p in pred.flatten().tolist()])
y_hat = torch.tensor(y_hat)
try:
y_hat
except NameError:
log.error('Prediction type should be one of these [\'SINGLE\', \'MULTI\']')
return y_hat
def get_loss(self, h, label_tensor, text_len_tensor):
log_prob = self.get_prob(h, text_len_tensor)
if self.pred_type == 'SINGLE':
loss = self.loss_func(log_prob, label_tensor)
elif self.pred_type == 'MULTI':
loss = self.loss_func(log_prob, label_tensor.float())
return loss
在评估数据中的无标签类时,多标签和单数据集可能会产生差异。
在我的示例中,只有 20% 的内容有标签。我为那些没有标签的人设置了具有代表性的 0 标签。虽然多标签训练中不包含这些 0 值,但单标签也包含在内。为此,通过多预测 0,单个数据集很快就达到了 85% 的成功率。
此外,降低模型复杂度(层数、神经元数量)也会增加训练epoch数,但拟合速度更快。 并减少了过度拟合。