预期模型改变:选择对模型参数影响最大的样本

FreeGuideOnline 最新 2026-06-27

python def expected_model_change_scores(model, unlabeled_loader, loss_fn): """ model: 当前训练好的模型 (处于eval模式但需要梯度计算) unlabeled_loader: 未标注数据加载器 (仅包含x) loss_fn: 损失函数 返回: scores列表,每个元素对应一个样本的预期模型改变量 """ model.eval() scores = [] num_classes = model.num_classes # 假设模型有该属性

for batch_x in unlabeled_loader:
    batch_x = batch_x.to(device)
    # 计算当前模型对所有类别的预测概率
    with torch.no_grad():
        probas = model.predict_proba(batch_x)  # shape: (batch_size, num_classes)

    batch_scores = []
    for i, x in enumerate(batch_x):
        x_single = x.unsqueeze(0)  # 添加batch维度
        emc = 0.0
        # 遍历每个可能的类别标签
        for y in range(num_classes):
            # 构造该假想标签下的损失
            label = torch.tensor([y]).to(device)
            loss = loss_fn(model(x_single), label)
            # 计算损失对模型所有参数的梯度
            grads = torch.autograd.grad(loss, model.parameters(), create_graph=False)
            # 展平所有梯度并计算L2范数
            grad_norm = torch.cat([g.view(-1) for g in grads]).norm(2)
            # 累加概率加权的梯度范数
            emc += probas[i, y].item() * grad_norm.item()
        batch_scores.append(emc)
    scores.extend(batch_scores)
return scores