python - 尽管只使用另一个标签,模型只预测错误的标签,并且特异性为 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)
对不起,如果代码有点长,我尽量保持最小的基本框架没有太多混乱。数据可以在这里找到。
如果有人可以就可能存在的问题提供一些反馈或任何想法,我们将不胜感激。在过去的几周里,我一直试图找出问题所在,但没有任何运气。谢谢!
解决方案
推荐阅读
- python - 从 Python (ctypes) 向 PARI/GP 发送多项式
- python - 我正在尝试排序并设置一个字符串以查看它是否与字母表匹配。如果是,我想返回 True 但它返回 False
- react-player - 用户点击缩略图后保持 react-player 灯光模式
- matlab - 在 MATLAB 中用复数绘制圆
- alexa-skills-kit - Alexa Skill Developers 基于参考的目录管理 API
- ios - 地图注释点击未触发且注释栏未显示
- php - 使用谷歌客户端 api php 获取登录用户
- pyspark - 排除在 AWS Glue ELT 作业 s3 连接中不起作用
- sql - 如何将 COUNT 与 JOIN SQL 3 表一起使用
- java - 从 Piccaso 保存到 Drawable