首页 > 解决方案 > 尽管只使用另一个标签,模型只预测错误的标签,并且特异性为 0,但灵敏度高?

问题描述

这可能有点远,但我不确定我还能做什么。我的问题是我目前有一个应该执行二进制分类的模型。训练后我注意到灵敏度非常高(大约 98%),但特异性接近 0。这是因为我的模型只预测 1。

为了检查模型是否正确训练,我过滤了数据,这样我就可以得到只有标签 0 的数据样本。然而,结果是相同的(只有 1 个预测),这让我相信我的模型没有正确训练(如果有的话)。

代码如下:

模型

import torch
import torch.nn as nn
import torch.nn.functional as F


class Model(nn.Module):
    def __init__(self, num, dim):
        super().__init__()
        self.hidden_dim = 100
        self.embedding_dim = 300
        self.dropout_p = 0.8
        self.feature_dim = dim
        self.num = num

        self.features_linear = nn.Linear(in_features=self.feature_dim, out_features=self.hidden_dim)
        nn.init.xavier_uniform_(self.features_linear.weight)

        self.embedding = nn.Embedding(num_embeddings=self.num, embedding_dim=self.embedding_dim)
        nn.init.xavier_uniform_(self.embedding.weight)

        self.output_linear = nn.Linear(in_features=(self.hidden_dim + self.embedding_dim), out_features=1)
        nn.init.xavier_uniform_(self.output_linear.weight)

    def forward(self, a, b):
        a_out = F.relu(self.features_linear(a))
        b_emb = self.embedding(b)
        b_sum = torch.sum(b_emb, dim=1)

        input_rep = torch.cat((a_out, b_sum), dim=1)
        input_rep = self.dropout(input_rep)
        output = self.output_linear(input_rep)

        return output

求解器代码。

from sklearn.metrics import confusion_matrix
import torch
import torch.optim as optim


model = Model(num=16, dim=189)
criterion = nn.BCELoss(reduction='mean')
optimizer = optim.Adam(params=model.parameters())

with open(file='train_data.pkl', mode='rb') as f:
    train_data = pickle.load(f)

for epoch in range(200):
    epoch_loss = 0.0
    predicted_targets = []
    ground_truth_targets = []

    for batch in train_data:
        optimizer.zero_grad()

        input_1, input_2, input_3, input_4, label = batch

        if torch.cuda.is_available():
            input_1 = input_1.to('cuda')
            input_2 = input_2.to('cuda')
            input_3 = input_3.to('cuda')
            input_4 = input_4.to('cuda')
            label = label.to('cuda')

        output = input_2

        for i in range(len(input_3)):
            input_data = torch.cat([input_1, output.view(1, -1), input4[i].view(1, -1)], dim=1)
            output = torch.sigmoid(model(input_data, input_3[i].unsqueeze(dim=0)))

        loss = criterion(output, label.float().view(1, -1))
        epoch_loss += loss.item()

        loss.backward()
        optimizer.step()

        output_start = input_2.cpu().item()
        output_end = output.cpu().item()
        label_threshold = output_end / output_start
        prediction = 1 if label_threshold <= 0.1 else 0

        predicted_targets.append(prediction)
        ground_truth_targets.append(label.cpu().item())

    tn, fp, fn, tp = confusion_matrix(ground_truth_targets, predicted_targets).ravel()

    sensitivity = tp / (tp + fn)
    specificity = tn / (tn + fp)

    if epoch % 5 == 0:
        print('Epoch: %d | loss: %.6f | sens: %.4f | spec: %.4f' % (epoch, epoch_loss, sensitivity, specificity)

对不起,如果代码有点长,我尽量保持最小的基本框架没有太多混乱。数据可以在这里找到。

如果有人可以就可能存在的问题提供一些反馈或任何想法,我们将不胜感激。在过去的几周里,我一直试图找出问题所在,但没有任何运气。谢谢!

标签: pythonmachine-learningdeep-learningpytorch

解决方案


推荐阅读