当前位置: 首页 > news >正文

认知深度学习:基于信度函数的不确定性量化与随机集神经网络实践

1. 认知深度学习:从“知道”到“知道不知道”的范式演进

在自动驾驶汽车试图识别雨雾中模糊的物体,或者医疗AI系统面对一张与训练集截然不同的病理影像时,我们最希望模型做的,不是给出一个高达99%的、但可能是错误的单一答案,而是坦诚地说:“这个情况我不确定,需要人类专家介入。”这种“知道不知道”的能力,正是当前人工智能,尤其是深度学习,在迈向安全、可靠部署过程中最缺失的一环。

我们常说的模型“自信”,在技术层面往往体现为softmax层输出的一个接近1.0的概率值。然而,这种自信可能是虚假的。当模型遇到从未见过的数据分布(Out-of-Distribution, OoD)、精心设计的对抗性扰动,或者仅仅是带有噪声的输入时,它依然可能“信心满满”地给出错误预测。这种过度自信的根源,在于传统模型无法有效区分和量化两种本质不同的不确定性:偶然不确定性认知不确定性

偶然不确定性是数据本身固有的、不可消除的随机性,比如传感器噪声或图像中物体的自然遮挡。而认知不确定性则源于模型知识的不足——训练数据有限、有偏差,或者模型结构无法捕捉复杂模式。传统方法,如贝叶斯神经网络或深度集成,主要通过对参数或预测的分布进行建模来提供不确定性估计。但它们输出的仍然是一个单一的概率分布,这个分布在面对完全未知的情况时,往往无法充分表达“我不知道”这种认知状态。这就像问一个只学过猫狗分类的模型“这张图片是飞机吗?”,它被迫在“猫”和“狗”之间分配概率总和为1的置信度,而无法表达“这既不是猫也不是狗”的根本性无知。

因此,我的研究核心,即“认知人工智能”,旨在推动模型从输出一个可能过度自信的“点估计”或“概率分布”,转向输出一个能显式表达无知的、更丰富的数学对象。这需要借助随机集、信度函数等二阶不确定性理论。简单来说,我们不再要求模型说“这是猫的概率是80%,是狗的概率是20%”,而是允许它说:“我有70%的把握认为这是猫或狗中的一种,但有30%的可能性它根本不属于我已知的任何类别。”这种表达方式为后续的安全决策(如拒绝判断、请求人工复核)提供了更可靠、更直观的依据。

2. 核心原理拆解:从概率分布到信度函数的跃迁

要理解认知深度学习的核心,我们需要暂时跳出熟悉的概率论框架。传统深度学习模型(如CNN)的最后一层通常使用softmax函数,将神经网络的原始输出(logits)转换为一个在所有类别上的概率分布。这个分布满足概率公理:每个类别的概率在0到1之间,且所有类别概率之和为1。这个“和为1”的约束,正是导致模型在陌生场景下被迫“硬着头皮”做出过度自信预测的数学根源。

2.1 信度函数:一种更灵活的不确定性语言

信度函数理论,也称为Dempster-Shafer理论,提供了一种更通用的不确定性表达框架。在这个框架中,基本单位不再是单个类别,而是所有可能类别的子集,称为“焦元”。模型可以为这些子集分配“质量”(mass)。

举个例子,假设一个三分类任务,类别为{猫, 狗, 鸟}。一个信度函数的输出可能如下:

  • 质量 0.6 分配给单元素集 {猫}
  • 质量 0.2 分配给集合 {猫, 狗}
  • 质量 0.1 分配给集合 {狗, 鸟}
  • 质量 0.1 分配给全集 {猫, 狗, 鸟}

这里,分配给{猫}的0.6表示模型有明确的证据支持“这是猫”;分配给{猫, 狗}的0.2表示证据支持“这是猫或狗,但无法区分具体是哪一种”;分配给全集的0.1则表示模型完全无知,证据不指向任何特定子集。所有焦元的质量之和为1。

从这个信度函数,我们可以推导出两个关键概念:

  1. 信度:对某个命题(如“是猫”)的最小支持程度。例如,Belief(猫) = 质量({猫}) = 0.6。
  2. 似真度:对某个命题的最大可能支持程度。例如,Plausibility(猫) = 质量({猫}) + 质量({猫, 狗}) + 质量({猫, 狗, 鸟}) = 0.9。

信度似真度构成了一个概率区间[Belief, Plausibility]。对于“猫”这个类别,其概率落在[0.6, 0.9]这个区间内。这个区间本身,而非一个单一数值,就是对认知不确定性的直接量化。区间越宽,表示模型的不确定性越高。

实操心得:理解信度函数的关键在于摆脱“概率必须精确分配”的思维定式。信度函数允许将部分概率质量分配给“模糊”的集合(如{猫,狗}),这正是在模型知识不完整时最合理的表达。在代码实现时,神经网络的输出维度会从类别数C变为2^C(所有可能子集的数量),这显然是指数爆炸的。因此,实际中需要通过“预算”技术,只考虑一部分有意义的子集(焦元),这是工程实现的核心挑战和技巧所在。

2.2 随机集神经网络:将理论嵌入深度学习架构

随机集神经网络是实现上述思想的具体架构。其核心创新在于对训练目标和输出表示的重新设计。

1. 训练目标的转变:从独热编码到信度编码传统分类使用独热编码作为监督信号:对于“猫”的图片,标签是[1, 0, 0]。RS-NN则使用信度函数作为监督信号。如何为每个训练样本构建这样的“软标签”?这通过一个称为“预算”的预处理步骤完成。

预算的目标是:基于训练数据的特征空间结构,自动为每个样本分配一个信度函数标签。具体步骤通常如下:

  • 使用一个预训练的特征提取器(如ResNet的倒数第二层)获取所有训练样本的特征向量。
  • 对这些特征进行聚类(如使用高斯混合模型GMM或层次聚类)。每个聚类中心代表一个“原型”。
  • 对于一个给定样本,根据其与各个聚类中心的距离,计算它属于每个聚类的“隶属度”。
  • 将这些聚类映射回类别标签的集合。如果一个聚类主要包含“猫”和“狗”的样本,那么这个聚类就对应焦元{猫, 狗}。样本属于该聚类的隶属度,就部分分配为这个焦元的质量。

这样,一个“猫”的图片,其真实标签不再是一个僵硬的[1,0,0],而可能是一个如{猫: 0.7, {猫,狗}: 0.2, {猫,狗,鸟}: 0.1}的信度函数。这更符合现实:即使是清晰的猫图,也可能与某些狗图在特征空间上接近。

2. 损失函数的设计模型的训练目标是让网络预测的信度函数尽可能接近上述“预算”得到的信度函数标签。这通常通过最小化两者之间的差异来实现,例如使用信度函数版本的交叉熵损失,或直接最小化信度/似真度向量的均方误差。损失函数中通常会引入正则化项,鼓励模型在证据不足时,将质量分配给更大的集合(即表达无知),而不是强行分配给某个单点。

3. 推理与决策在推理时,RS-NN输出一个信度函数。为了做出最终分类决策,我们需要从这个信度函数中提取一个点估计。最常用的方法是计算皮格尼斯蒂克概率。这是一种将信度函数转化为概率分布的方法,其思想是将分配给每个集合的质量,平均分摊给该集合内的所有元素。 对于之前的例子:

  • P(猫) = 0.6 (来自{猫}) + 0.2/2 (来自{猫,狗}) + 0.1/3 (来自{猫,狗,鸟}) = 0.6 + 0.1 + 0.033 ≈ 0.733
  • P(狗) = 0 + 0.2/2 + 0.1/3 ≈ 0.133
  • P(鸟) = 0 + 0.1/3 ≈ 0.033 然后取概率最大的类别作为预测结果。同时,我们可以计算这个概率分布的熵,作为预测不确定性的一个标量度量。更重要的是,我们可以直接观察信度函数输出的信度集宽度(即似真度与信度之差),这个区间宽度是认知不确定性的直接体现。

3. 实战构建:从零实现一个简易RS-NN

理论可能有些抽象,我们通过一个简化版的PyTorch实现,来具体感受RS-NN的构建过程。这里我们以CIFAR-10数据集为例,并使用一个简单的CNN作为骨干网络。

3.1 环境准备与数据加载

首先,确保安装必要的库,并准备好数据。

import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import numpy as np from sklearn.mixture import GaussianMixture from scipy.special import softmax import itertools # 设备配置 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 数据预处理和加载 transform_train = transforms.Compose([ transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) transform_test = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train) testset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test) trainloader = DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2) testloader = DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)

3.2 预算:生成信度函数标签

这是RS-NN训练前最关键的预处理步骤。我们需要为每个训练样本生成一个信度函数形式的软标签。

def budget_belief_labels(trainset, n_classes=10, n_components=30, feature_dim=512): """ 预算函数:为训练集生成信度函数标签。 简化版:使用预训练特征提取器+GMM聚类来生成软标签。 实际论文中可能使用更复杂的层次聚类或图方法。 """ # 步骤1: 提取特征。这里为了简化,我们使用一个预训练的ResNet18的倒数第二层。 # 在实际研究中,你可能需要先训练或加载一个特征提取器。 print("Extracting features for budgeting...") # 假设我们有一个预训练的特征提取器 `feature_extractor` # all_features = [] # all_labels = [] # with torch.no_grad(): # for data, target in trainloader: # data, target = data.to(device), target.to(device) # features = feature_extractor(data) # 形状: [batch, feature_dim] # all_features.append(features.cpu().numpy()) # all_labels.append(target.cpu().numpy()) # all_features = np.vstack(all_features) # [N, feature_dim] # all_labels = np.hstack(all_labels) # [N] # 由于简化,我们这里用一个随机生成的特征矩阵模拟。实际应用必须替换。 num_samples = len(trainset) all_features = np.random.randn(num_samples, feature_dim) # 模拟特征 all_labels = np.array([trainset[i][1] for i in range(num_samples)]) # 步骤2: 使用高斯混合模型(GMM)对特征空间进行聚类 print("Fitting GMM for clustering...") gmm = GaussianMixture(n_components=n_components, covariance_type='diag', random_state=42) gmm.fit(all_features) cluster_probs = gmm.predict_proba(all_features) # [N, n_components], 样本属于每个聚类的概率 # 步骤3: 将每个聚类映射到类别集合(焦元) # 计算每个聚类中,各类别样本的占比 cluster_class_distribution = np.zeros((n_components, n_classes)) for i in range(n_components): # 获取属于聚类i的样本的标签 weights = cluster_probs[:, i] # 样本属于聚类i的概率作为权重 for c in range(n_classes): # 加权计算聚类i中类别c的“质量” cluster_class_distribution[i, c] = np.sum(weights * (all_labels == c)) # 归一化,使每个聚类的类别分布和为1 if cluster_class_distribution[i].sum() > 0: cluster_class_distribution[i] /= cluster_class_distribution[i].sum() # 定义焦元:这里简化,只考虑单点集和最大的两个集合(基于类内相似性)。 # 实际论文中会通过阈值或层次聚类自动确定焦元。 focal_sets = [] # 添加所有单点集 for c in range(n_classes): focal_sets.append(frozenset([c])) # 添加一些双点集示例(例如,根据CIFAR-10语义:猫 vs 狗, 车 vs 卡车) semantic_pairs = [(3, 5), (1, 9), (2, 4), (7, 8)] # 示例:猫(3)-狗(5), 鸟(2)-鹿(4)等 for c1, c2 in semantic_pairs: focal_sets.append(frozenset([c1, c2])) # 添加全集(表示完全无知) focal_sets.append(frozenset(range(n_classes))) K = len(focal_sets) # 焦元数量 print(f"Defined {K} focal sets.") # 步骤4: 为每个样本计算属于每个焦元的质量 # 一个样本属于一个焦元的质量,等于它属于那些“主导类别在该焦元内”的聚类的概率之和。 belief_labels = np.zeros((num_samples, K)) for idx, sample_feat in enumerate(all_features): # 样本属于各聚类的概率 [n_components] sample_cluster_probs = cluster_probs[idx] for k, focal_set in enumerate(focal_sets): mass = 0.0 for comp_idx in range(n_components): # 检查聚类comp_idx的“主导类别”是否在焦元focal_set内 # 这里简化:取该聚类分布中概率最大的类别作为主导类别 dominant_class = np.argmax(cluster_class_distribution[comp_idx]) if dominant_class in focal_set: # 如果主导类别在焦元内,则将该聚类概率的一部分加入质量 # 更精细的做法可以按类别比例分配 mass += sample_cluster_probs[comp_idx] * (cluster_class_distribution[comp_idx, dominant_class]) belief_labels[idx, k] = mass # 归一化,使该样本的所有焦元质量和为1 belief_labels[idx] /= belief_labels[idx].sum() + 1e-10 # 将numpy数组转换为PyTorch张量,并创建信度标签数据集 from torch.utils.data import TensorDataset belief_labels_tensor = torch.FloatTensor(belief_labels) # 注意:我们需要重新包装数据集,将原始图像和信度标签对应起来 # 这里简化处理,实际需要重构数据加载器 # 我们返回一个映射关系:样本索引 -> 信度标签 return belief_labels_tensor, focal_sets # 执行预算(在实际运行中,这会比较耗时) belief_labels_tensor, focal_sets = budget_belief_labels(trainset) print(f"Focal sets: {focal_sets}") print(f"Belief labels shape: {belief_labels_tensor.shape}")

注意事项:预算过程是RS-NN性能的关键。上述简化版仅用于演示原理。在实际研究中,预算算法需要精心设计,以确保生成的焦元具有语义意义(如{猫,狗}、{汽车,卡车}),并且质量分配能准确反映特征空间的局部结构。低质量的预算会导致模型学习到无���义的信度模式。一个常见的技巧是使用层次聚类来自动发现数据中自然形成的类别分组,并将其作为焦元。

3.3 网络架构设计

RS-NN的网络架构与传统CNN的主要区别在于最后一层。传统CNN输出C个logits(C为类别数),然后通过softmax得到概率分布。RS-NN需要输出K个值(K为焦元数量),然后通过softmax(或其他归一化函数,如softplus后归一化)得到分配给每个焦元的质量。

class SimpleCNN(nn.Module): def __init__(self, num_focal_sets): super(SimpleCNN, self).__init__() # 一个简单的CNN骨干 self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1) self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1) self.pool = nn.MaxPool2d(2, 2) self.dropout = nn.Dropout(0.25) self.fc1 = nn.Linear(64 * 8 * 8, 256) # CIFAR-10经过两次池化后是8x8 self.fc2 = nn.Linear(256, num_focal_sets) # 关键:输出维度 = 焦元数K def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = torch.flatten(x, 1) x = F.relu(self.fc1(x)) x = self.dropout(x) x = self.fc2(x) # 输出K个logits return x class RSNetwork(nn.Module): def __init__(self, backbone, focal_sets): super(RSNetwork, self).__init__() self.backbone = backbone self.focal_sets = focal_sets self.num_classes = max([max(fs) for fs in focal_sets if fs]) + 1 # 从焦元推断类别数 def forward(self, x): focal_logits = self.backbone(x) # [batch, K] # 使用softmax将logits转换为质量函数m(A) mass = F.softmax(focal_logits, dim=-1) # [batch, K] return mass def predict_pignistic(self, mass): """ 根据质量函数计算皮格尼斯蒂克概率分布。 mass: [batch, K] 或 [K] """ if mass.dim() == 1: mass = mass.unsqueeze(0) batch_size = mass.shape[0] pignistic = torch.zeros(batch_size, self.num_classes).to(mass.device) for k, focal_set in enumerate(self.focal_sets): if len(focal_set) > 0: for cls in focal_set: pignistic[:, cls] += mass[:, k] / len(focal_set) return pignistic # [batch, C] def predict_credal_width(self, mass): """ 计算每个类别的信度集宽度(似真度 - 信度)。 mass: [batch, K] """ batch_size, _ = mass.shape belief = torch.zeros(batch_size, self.num_classes).to(mass.device) plausibility = torch.zeros(batch_size, self.num_classes).to(mass.device) for k, focal_set in enumerate(self.focal_sets): mass_k = mass[:, k].unsqueeze(1) # [batch, 1] for cls in range(self.num_classes): # 信度:质量分配给的子集必须是该类子的子集 if cls in focal_set and focal_set.issubset({cls}): # 单点集{cls} belief[:, cls] += mass_k.squeeze() # 似真度:质量分配给的子集与该类别有交集 if cls in focal_set: plausibility[:, cls] += mass_k.squeeze() width = plausibility - belief return width # [batch, C]

3.4 损失函数与训练循环

损失函数需要衡量预测的质量函数与预算得到的真实质量函数之间的差异。一个直接的选择是分类任务中常用的交叉熵损失,但这里是在焦元空间上。

def belief_loss(pred_mass, true_mass, alpha=1e-3, beta=1e-3): """ 信度损失函数。 pred_mass: 模型预测的质量 [batch, K] true_mass: 预算得到的真实质量 [batch, K] alpha, beta: 正则化超参数,鼓励模型在不确定时将质量分配给更大的集合。 """ # 主损失:预测质量与真实质量之间的KL散度或交叉熵 main_loss = F.kl_div(F.log_softmax(pred_mass, dim=-1), true_mass, reduction='batchmean') # 正则化项1:鼓励对单点集的质量不要过高(避免过度自信) # 假设focal_sets中前C个是单点集 singleton_mass = pred_mass[:, :10].sum(dim=1).mean() # 示例,假设前10个是单点集 reg_singleton = alpha * singleton_mass # 正则化项2:鼓励对全集(最后一个焦元)分配一定质量(保留无知能力) # 假设最后一个焦元是全集 ignorance_mass = pred_mass[:, -1].mean() reg_ignorance = -beta * ignorance_mass # 负号是因为我们希望鼓励它,所以减去 total_loss = main_loss + reg_singleton + reg_ignorance return total_loss, main_loss, reg_singleton, reg_ignorance # 初始化模型、优化器 num_focal_sets = len(focal_sets) backbone = SimpleCNN(num_focal_sets) model = RSNetwork(backbone, focal_sets).to(device) optimizer = optim.Adam(model.parameters(), lr=0.001) scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1) # 训练循环(简化版,需要将信度标签与图像数据配对加载) def train(epoch): model.train() running_loss = 0.0 for batch_idx, (data, target) in enumerate(trainloader): # 注意:这里target是原始类别标签,我们需要的是信度标签。 # 在实际训练中,需要创建一个新的DataLoader,能同时加载图像和对应的belief_labels_tensor。 # 此处为演示,我们跳过数据配对细节,假设data和对应的belief_label已准备好。 # data, belief_label = data.to(device), belief_label.to(device) # optimizer.zero_grad() # mass_pred = model(data) # loss, main_loss, reg1, reg2 = belief_loss(mass_pred, belief_label) # loss.backward() # optimizer.step() # running_loss += loss.item() pass # scheduler.step() print(f'Epoch {epoch}, Loss: {running_loss/len(trainloader)}')

3.5 推理与不确定性评估

训练完成后,我们可以使用模型进行预测,并观察其不确定性量化能力。

def evaluate(model, testloader, ood_loader=None): model.eval() correct = 0 total = 0 entropy_list = [] width_list = [] with torch.no_grad(): for data, target in testloader: data, target = data.to(device), target.to(device) mass = model(data) # [batch, K] pignistic = model.predict_pignistic(mass) # [batch, C] credal_width = model.predict_credal_width(mass) # [batch, C] # 预测类别 _, predicted = torch.max(pignistic, 1) total += target.size(0) correct += (predicted == target).sum().item() # 计算预测分布的熵(偶然+认知不确定性) entropy = -torch.sum(pignistic * torch.log(pignistic + 1e-10), dim=1) # [batch] entropy_list.extend(entropy.cpu().numpy()) # 计算平均信度集宽度(认知不确定性的直接度量) avg_width = credal_width.mean(dim=1) # [batch] width_list.extend(avg_width.cpu().numpy()) accuracy = 100 * correct / total avg_entropy = np.mean(entropy_list) avg_width = np.mean(width_list) print(f'Test Accuracy: {accuracy:.2f}%') print(f'Average Predictive Entropy: {avg_entropy:.4f}') print(f'Average Credal Set Width: {avg_width:.4f}') # OoD检测评估(如果提供了OoD数据) if ood_loader: # 计算在ID和OoD数据上的熵分布,然后计算AUROC # 通常,OoD样本应有更高的熵/信度集宽度 id_entropies = np.array(entropy_list) ood_entropies = [] for data, _ in ood_loader: data = data.to(device) mass = model(data) pignistic = model.predict_pignistic(mass) entropy = -torch.sum(pignistic * torch.log(pignistic + 1e-10), dim=1) ood_entropies.extend(entropy.cpu().numpy()) ood_entropies = np.array(ood_entropies) # 这里省略AUROC计算代码,可使用sklearn.metrics.roc_auc_score # labels = np.concatenate([np.zeros_like(id_entropies), np.ones_like(ood_entropies)]) # scores = np.concatenate([-id_entropies, -ood_entropies]) # 用负熵,因为OoD熵高 # auroc = roc_auc_score(labels, scores) # print(f'OoD Detection AUROC (using entropy): {auroc:.4f}') return accuracy, avg_entropy, avg_width

4. 效果验证与对比分析:RS-NN的优势何在?

为了验证RS-NN的有效性,我们需要将其与基线模型在多个维度进行对比。以下是基于原论文实验和我个人复现经验的总结。

4.1 准确性、校准与效率

在标准测试集(如CIFAR-10)上,一个设计良好的RS-NN的分类准确率应该与同结构的传统CNN相当或略低(1-2%以内),因为它的学习目标更复杂(学习信度函数)。关键在于预期校准误差。ECE衡量模型预测置信度与真实准确率之间的匹配程度。理想情况下,一个预测置信度为80%的样本组,其真实准确率应接近80%。传统CNN往往过于自信,ECE较高。RS-NN通过输出概率区间(信度集),其点估计(皮格尼斯蒂克概率)通常校准得更好。

训练与推理时间:RS-NN的主要开销在预算阶段(离线进行,一次性的)和网络前向传播(输出维度K可能大于类别数C)。训练时间由于损失函数更复杂会略有增加。推理时间相比原CNN有轻微上升,但远低于需要多次采样的贝叶斯方法或需要运行多个模型的深度集成。

4.2 分布外检测能力

这是RS-NN的强项。我们将CIFAR-10训练的模型,在SVHN(街景门牌号)或ImageNet子集(如Intel Image数据集)上进行测试。评估指标是AUROC和AUPRC,即模型能否根据其不确定性分数(如预测熵、信度集宽度)将ID样本和OoD样本分开。

实验结果通常显示

  • 传统CNN:在OoD数据上,其softmax输出的“最大概率”依然可能很高,熵很低,无法有效区分。
  • 贝叶斯方法(如MC Dropout):通过多次采样计算预测方差,对OoD更敏感,但计算成本高。
  • 深度集成:效果较好,但需要训练和存储多个模型。
  • RS-NN:其信度集宽度在OoD样本上会显著增大,皮格尼斯蒂克概率的熵也更高。在AUROC/AUPRC指标上,RS-NN常能达到与深度集成相当甚至更好的性能,同时模型更轻量。

4.3 对抗鲁棒性

使用FGSM或PGD等方法生成对抗样本。观察模型在对抗攻击下的准确率下降程度,以及其不确定性是否同步升高。

关键发现:传统CNN在对抗样本上准确率骤降,但其输出的置信度依然可能很高(“自信的错误”)。RS-NN在对抗样本上的表现是:1) 准确率下降幅度可能更小(得益于其更鲁棒的表征);2) 更重要的是,它对对抗样本预测的信度集宽度会显著增加,熵值升高。这意味着模型“意识到”输入有问题,发出了高不确定性信号。这对于安全系统至关重要,因为一个能“报警”的失败比一个“沉默的失败”要好得多。

4.4 噪声与旋转鲁棒性

在测试图像中加入高斯噪声或进行随机旋转。RS-NN对于这类分布变化的敏感性也体现在其不确定性度量的增加上,而分类准确率的下降可能比传统CNN更平缓。

4.5 超参数影响与消融实验

  • 预算中焦元的选择:焦元的设计至关重要。仅使用单点集会退化为传统模型。加入过多、过大的集合(如过大的双点集、三点集)可能会使模型过于“懒惰”,总是输出宽区间。需要通过验证集性能(如OoD检测的AUROC)来选择有意义的焦元集合。原论文中使用层次聚类来自动发现语义相关的类别组是一个好方法。
  • 损失函数中的正则化系数α和β:α控制对单点集的惩罚,β控制对全集的鼓励。α太大可能导致模型拒绝做出任何明确预测,β太大可能导致模型总是倾向于表达无知。需要精细调参。
  • 骨干网络:RS-NN的思想可以嫁接在任何骨干网络上(CNN, ResNet, ViT, BERT, LLM)。实验表明,随着骨干网络能力增强,RS-NN的性能提升更明显。

避坑指南:在初次实现RS-NN时,最常见的失败模式是模型学不到有意义的信度分配,所有样本的质量都集中在全集上(输出完全无知)。这通常是因为:1) 预算过程不合理,生成的软标签噪声太大;2) 损失函数中鼓励无知的正则项β过强;3) 网络容量不足或训练不充分。调试时,建议先可视化一批样本的预测质量分布,检查是否与预期(清晰样本质量集中在单点集,模糊样本质量分布在较大集合)相符。

5. 统一评估框架:如何公平比较不同的不确定性量化方法?

不同的不确定性量化方法输出形式各异:贝叶斯网络输出概率分布样本,集成方法输出多个预测的分布,RS-NN输出信度函数,证据深度学习输出狄利克雷分布参数。这使得直接比较它们的不确定性估计好坏变得困难。原论文提出的统一评估框架旨在解决这个问题。

核心思想:将所有模型的不确定性输出,统一映射到信度集这一公共表示上。然后定义一个评估指标E,该指标是两个部分的加权和:

  1. 距离:预测的信度集与真实标签(一个单点分布)之间的距离。距离越小,预测越准确。
  2. 非特异性:信度集的大小(体积或宽度)。非特异性越小,预测越精确。

指标公式可简化为:E = λ * 距离 + (1 - λ) * 非特异性。其中λ是权衡参数,取决于应用场景。在安全关键场景(如医疗),我们可能更看重低距离(高准确率),λ接近1;在需要模型诚实表达无知的场景(如自动驾驶遇到未知物体),我们可能允许距离稍大,但要求非特异性在不确定时必须增大,λ接近0。

具体操作

  • 对于贝叶斯模型,其多次采样得到的概率向量集合,可以计算其凸包,这个凸包就是一个信度集(所有可能概率分布的集合)。
  • 对于深度集成,每个成员模型的预测构成一个概率向量集合,同样计算凸包。
  • 对于RS-NN,其信度函数天然对应一个信度集(所有与信度/似真度约束一致的概率分布集合)。
  • 然后计算这个信度集到真实标签点的平均距离(如KL散度、欧氏距离),以及信度集的体积(非特异性)。

这个框架的好处是提供了一个与模型无关的“标尺”。我们可以客观地说,在某个λ取值下,模型A的综合表现(准确性与不确定性表达的平衡)优于模型B。这为模型选择提供了更全面的依据,而不仅仅是看准确率或AUROC。

6. 扩展与应用:从图像到文本,从研究到落地

6.1 随机集大语言模型

将RS-NN的思想扩展到LLM是自然而然的。在文本生成中,每个时间步预测下一个词的概率分布。RS-LLM预测下一个词的信度函数。例如,在生成“The capital of France is ___”时,传统LLM会给“Paris”很高的概率。RS-LLM可能会给{Paris}分配高质量,但也可能给{Paris, Lyon, Marseille}这个集合分配一些质量,如果上下文模糊(比如有歧义)。更重要的是,当被问到训练数据之外的事实(“The capital of Mars is ___”)时,理想的RS-LLM应该将大部分质量分配给大的集合(如所有城市名的集合)甚至全集(词汇表),从而表现出高不确定性,而不是像当前LLM那样“一本正经地胡说八道”(幻觉)。

技术实现上,需要对LLM的词汇表进行“预算”,形成有语义关联的词组作为焦元(如通过词嵌入聚类),并修改损失函数。初步实验表明,RS-LLM能在保持回答质量的同时,对自身不知道的问题给出更高的不确定性信号。

6.2 在自动驾驶中的应用:天气与锥桶分类

这是一个非常贴切的落地场景。自动驾驶车辆需要识别天气(晴、雨、��、雪)和锥桶颜色/类型。挑战在于:

  • 数据有限:难以收集所有极端天气条件下的充足数据。
  • 域适应:在一个数据集(如模拟器)上训练的模型,需要在真实世界数据上工作。
  • 安全关键:错误识别可能导致事故。

在该研究中,使用RS-NN进行天气分类。当遇到训练集中未见的极端天气(如沙尘暴)时,传统CNN可能错误地将其分类为“雾”或“雪”并给出高置信度。而RS-NN则会表现出很高的信度集宽度和熵,系统可以据此触发降级策略(如降低车速、请求人类接管)。实验证实,在跨域测试中,RS-NN在保持可接受准确率的同时,其不确定性指标对域偏移的敏感度远高于传统模型。

7. 总结与展望:认知AI的未来

认知深度学习的核心价值,在于将模型的“自知之明”从一种理想转化为可计算、可优化的工程属性。通过随机集和信度函数,我们为模型提供了一种数学语言,使其能够区分“我知道这是猫”和“我觉得这可能是猫或狗,但我不确定”。

从我个人的复现和实验经验来看,这条路充满挑战但也极具前景。最大的挑战在于可扩展性效率。对于有C个类别的任务,理论上焦元数量是2^C,这不可行。因此,如何智能地、自适应地学习或选择一小部分有意义的焦元,是未来研究的关键。另一个挑战是评估。虽然有了统一的评估框架,但如何为不同的下游任务(医疗诊断 vs. 内容推荐)设定合理的权衡参数λ,仍需领域知识。

未来的方向可能包括:

  • 动态焦元学习:让模型在训练或推理过程中,根据输入数据动态决定使用哪些焦元,而不是固定预设。
  • 与因果推理结合:将认知不确定性建模与因果发现结合,区分由于混淆变量引起的不确定性和真正的机制性无知。
  • 更高效的推理算法:开发近似算法,在保持性能的同时降低RS-NN的计算开销。
  • 大规模预训练模型的认知化:将RS思想注入如GPT、CLIP等大模型,构建具有“自知之明”的基础模型。

最终,让机器学习模型“知其所不知”,不仅是提升其可靠性的技术手段,更是迈向更稳健、更可信、更可合作的人工智能系统的必经之路。当模型能够诚实地说“我不知道”时,我们才能真正放心地将决策权部分移交,构建起人机协同的智能新范式。

http://www.jsqmd.com/news/882519/

相关文章:

  • Unity UI布局进阶:拆解LayoutGroup里Control Child Size和Child Force Expand的‘爱恨情仇’
  • Unity项目从Built-in到URP渲染管线升级保姆级教程(含粉色材质修复)
  • 2026廊坊黄金 铂金 白银 彩金回收口碑榜出炉:这五家店稳居前列,靠谱又放心 - 前途无量YY
  • 如何在macOS上使用QMCDecode快速解密QQ音乐加密格式:完整指南与3大应用场景
  • Unity打包Linux服务器应用踩坑记:从发布到后台稳定运行(含Systemd服务配置)
  • 原神帧率解锁终极指南:告别60FPS限制,畅享丝滑游戏体验
  • 保姆级教程:用UE5 Niagara系统10分钟搞定一个逼真的烟雾特效(附材质与帧动画设置)
  • 5分钟上手:XUnity.AutoTranslator实现Unity游戏实时翻译
  • 2026怀化黄金 铂金 白银 彩金回收口碑榜出炉:这五家店稳居前列,靠谱又放心 - 前途无量YY
  • ARM ETE跟踪技术:嵌入式系统调试的核心原理与实践
  • 终极Minecraft数据编辑器:NBTExplorer完整使用指南
  • 2026淮安黄金 铂金 白银 彩金回收口碑榜出炉:这五家店稳居前列,靠谱又放心 - 前途无量YY
  • UE5 PhysicsControl物理动画入门:手把手教你用蓝图控制骨骼网格体(附完整配置流程)
  • 从Windows/Ubuntu到麒麟V10:给双系统玩家的分区避坑指南(附ESP/SYSBOOT详解)
  • QtOpenGL中实现Unity风格材质系统实战
  • 别再为导入发愁!Houdini RBD碎片在UE里动起来的三种‘野路子’:VAT、APEX与原生物理对比
  • Unity独立游戏开发者的地形救星:MTE插件从安装到出第一个场景全记录
  • 大语言模型在嵌入式系统开发中的应用与挑战
  • Houdini RBD破碎导入UE5避坑指南:ABC与FBX流程详解(含材质与动画还原)
  • 如何用ViGEmBus实现Windows游戏控制器虚拟化:终极实战指南
  • ARM SME指令集与UMLAL指令深度解析
  • 2026淮北黄金 铂金 白银 彩金回收口碑榜出炉:这五家店稳居前列,靠谱又放心 - 前途无量YY
  • 机器学习在宇宙学模拟中的应用:非线性回归模型解析黑洞与星系演化关系
  • Unity UI布局避坑指南:搞懂LayoutGroup那三个勾选框,你的滚动列表就成功了一半
  • Unity打包Linux服务器应用实战:从导出到用systemd守护进程部署
  • 2026南宁名包回收优选:5家实体老店,安全高价 - 奢侈品回收测评
  • 如何快速彻底清理C盘空间:Windows Cleaner终极解决方案
  • 随机集神经网络:让自动驾驶感知系统学会表达“我不知道”
  • 终极指南:如何在Blender中轻松制作专业级MMD动画
  • 如何在Windows中构建虚拟游戏控制器:ViGEmBus驱动开发终极指南