LeCun点赞华人女科学家!使用能量模型替代Softmax函数

点击上方“CVer”,选择加"星标"置顶

重磅干货,第一时间送达

本文转载自:AI科技评论

作者 | 赛文

编辑 | 陈大鑫

Softmax置信度得分应该是大家再熟悉不过的加在神经网络最后面的一个操作。

然鹅,Softmax置信度得分一直都是合适和可靠的吗?

目前已有很多机器学习模型部署在高风险领域中,例如特殊疾病的诊断,敏感信息的生物识别等,当模型部署上线后,往往无法控制输入的数据,这些高风险模型很容易受到训练分布外异常数据的攻击,所以需要在模型推理之前对数据进行异常检测(out-of-distribution, OOD)。

之前的OOD方法往往都根据softmax函数的输出来辨别异常样本,然而神经网络会对分布外的数据输出一个较高的随机值,这是由于softmax的后验分布会有一个标签过拟合的输出空间,这使得softmax置信度得分对OOD检测而言是不可靠的。

有什么方法能改善这种不可靠呢?

AI科技评论今天就来介绍一篇被NeurIPS 2020收录的论文:《Energy-based Out-of-distribution Detection》来改善

本文引入了能量模型来对数据进行建模,并使用能量分数(energy score)来分辨输入数据是否为异常样本,作者对能量分数和传统的softmax置信分数进行了对比,并从理论上分析,由于softmax函数偏置量的存在,导致其与输入样本的概率密度不一致,所以并不适合来检测异常样本。

本文还证明了能量分数与数据的概率密度对齐,可以获得较好的异常检测性能,就连能量模型的提出者“养乐村”同志(LeCun)也在推特上转推点赞了这篇论文。

1

论文一作Weitang Liu的指导老师

Sharon Yixuan Li,威斯康星大学麦迪逊分校计算机科学系助理教授,本科就读于上海交通大学,博士毕业于康奈尔大学,博士后一年在斯坦福大学计算机系度过,曾两次在Google AI实习,并在Facebook AI担任过研究科学家。

发表过多篇顶会一作,在ICLR 2021担任领域主席,并将成为ICML 2021领域主席。

研究的目:使算法和实践能够朝着可靠的开放世界学习方向发展,而这种学习方法可以在不断变化和不可预测的数据流存在的情况下安全、自适应地运行。

目前关注的研究主题包括:

  • 深度学习中的不确定性估计和分布外检测;

  • 鲁棒数据不规则性和分布外泛化;

  • 在医疗和计算机视觉中具有不确定性的深度学习。

个人主页:http://pages.cs.wisc.edu/~sharonli/

2

什么是能量模型(EBM)

基于能量的模型(EBM)[1]最早由LeCun在2006年提出,该模型的本质是构建一个函数E(x),对样本空间中的所有样本点映射到一个非概率的标量值(energy),一些样本能量值的组合可以反映出概率密度的情况,基于Gibbs分布,我们可以将一组输入的能量值转换为概率密度的形式:

     

其中分母是分割函数用来边缘化y,T为温度参数,输入样本的能量可以表示为分割函数取对数的负值:

对于一个简单的神经网络分类器f(x),使用softmax函数可以得到当前样本在全部K个类别上的概率:

   

其中 对应于第y类标签的logit值,联立上式,可以将输入的能量值表示为负的,这样就在原始神经网络分类器和能量模型之间建立起了联系,我们可以用softmax函数的分母来表示当前输入样本的能量,并且进行后续的异常检测操作。

 

3

能量模型指导下的OOD

能量异常分数

异常检测可以简单的看作是一个二分类问题,对于输入的样本模型需要给出一个分数值来衡量当前样本偏离正常分布的程度,直观的方法是使用密度估计,这里使用能量函数来构建模型的密度函数:

由于归整因子(分母)在输入空间很难可靠的估计,但是其不会对输入数据产生影响,所以可以直接对上式左右取对数:

上式表明实际上与对数似然函数线性对齐,这有助于提高异常检测的性能,具有较高能量(似然函数值较小)的数据会被判别为异常样本。

为了与常规定义相匹配,即正常样本得分应更高,本文直接使用负能量函数          构成异常检测器 :

其中为能量阈值,从正常样本数据分布统计得到。

能量分数 VS Softmax分数

为了证明能量函数可以直接对任意预训练网络的softmax置信度进行替换,需要首先推导出能量分数与softmax置信分数之间的数学联系:

当T=1时,上式表明softmax置信度的对数其实属于能量分数的一个特例,对于softmax函数而言,随着模型的优化,当输入一个正常样本时, 倾向于得到一个较高的置信分数,这种倾向将导致评分函数不再与概率密度成正比。

而能量函数不受这类偏移影响,将始终与概率密度对齐,进而提高了模型对异常样本的检测能力。

能量边界学习

在模型训练阶段,本文提出了一种能量限度目标函数来微调网络,网络优化的过程就是在对能量表面进行整流,促使分布内数据的能量分数较低,而分布外的异常数据能量分数较高,具体来说,基于能量的分类器的目标函数如下:

除了一个标准的交叉熵损失函数之外,还引入了两个hinge loss作为正则项来拉远正常数据和异常数据之间的分布距离。

4

实验结果

本文使用SVHN、CIFAR-10和CIFAR-100作为正常样本数据集,并且在六个异常样本数据集上进行了实验,网络结构使用WideResNet。

Softmax对比实验

下面的直方图分别展示了softmax分数与能量分数在相同数据上的异常对比结果,样本数据来自SVHN数据集,在softmax直方图中,正常样本与异常样本的得分基本一致(1.0 vs 0.99),而在能量分数直方图中,正常样本与异常样本的得分差异非常明显(11.19 vs 7.11)。

作者还在其他异常数据集上对softmax和能量分数进行了对比,实验结果如下:

模型微调实验

本文使用能量限度目标函数来对预训练网络进行微调,不会给网络带来附加参数,同时保持了网络本身的分类精度,在CIFAR-10数据集上进行能量微调后,网络在异常测试集上的FPR95值降低到3.32,同时在分布内数据上的分类误差为4.87%,总体来说,这种基于能量的微调方法不仅可以提高网络的异常检测能力,也不会对网络本身的分类性能造成影响。


5

总结

本文主要提出了一种基于能量的异常检测框架,本文证明了可以将任何预训练神经网络的softmax置信度替换为能量函数。

相比于其他使用预训练模型的异常检测方法,得益于能量量度无参数的特点,本文方法无需对模型其他参数进行调整,便于部署,与softmax置信度得分不同,能量分数被证明与数据的概率密度对齐,因此,可以显著提高异常检测性能。

作者称未来会在图像分类任务之外进一步探索基于能量的异常检测方法。

参考

LeCun Y, Chopra S, Hadsell R, et al. A tutorial on energy-based learning[J]. Predicting structured data, 2006, 1(0). 

上述论文PDF和代码下载

后台回复:1215,即可下载上述论文PDF和项目源代码,赶紧学起来!

目标检测综述下载

后台回复:目标检测二十年,即可下载39页的目标检测最全综述,共计411篇参考文献。

下载2

后台回复:CVPR2020,即可下载代码开源的论文合集

后台回复:ECCV2020,即可下载代码开源的论文合集

后台回复:YOLO,即可下载YOLOv4论文和代码

重磅!CVer-目标检测 微信交流群已成立

扫码添加CVer助手,可申请加入CVer-目标检测 微信交流群,目前已汇集4000人!涵盖2D/3D目标检测、小目标检测、遥感目标检测等。互相交流,一起进步!

同时也可申请加入CVer大群和细分方向技术群,细分方向已涵盖:目标检测、图像分割、目标跟踪、人脸检测&识别、OCR、姿态估计、超分辨率、SLAM、医疗影像、Re-ID、GAN、NAS、深度估计、自动驾驶、强化学习、车道线检测、模型剪枝&压缩、去噪、去雾、去雨、风格迁移、遥感图像、行为识别、视频理解、图像融合、图像检索、论文投稿&交流、PyTorch和TensorFlow等群。

一定要备注:研究方向+地点+学校/公司+昵称(如目标检测+上海+上交+卡卡),根据格式备注,可更快被通过且邀请进群

▲长按加群

▲长按关注我们

整理不易,请给CVer点赞和在看

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我理解了您的要求,我可以回答您的问题。下面是使用mnist数据集训练softmax模型的代码示例: ``` import numpy as np import urllib.request import gzip # load data from online source def load_data(): url = 'http://yann.lecun.com/exdb/mnist/' files = ['train-images-idx3-ubyte.gz', 'train-labels-idx1-ubyte.gz', 't10k-images-idx3-ubyte.gz', 't10k-labels-idx1-ubyte.gz'] data = [] for file_name in files: print('Downloading:', url+file_name) urllib.request.urlretrieve(url+file_name, file_name) print('Download complete') with gzip.open(file_name, 'rb') as f: file_content = f.read() if file_name.endswith('ubyte.gz'): data.append(np.frombuffer(file_content, dtype=np.uint8, offset=16).reshape(-1, 784)) elif file_name.endswith('labels-idx1-ubyte.gz'): data.append(np.frombuffer(file_content, dtype=np.uint8, offset=8)) return tuple(data) # one-hot encode labels def one_hot(labels): n_labels = len(labels) n_classes = len(np.unique(labels)) onehot_labels = np.zeros((n_labels, n_classes)) onehot_labels[np.arange(n_labels), labels] = 1 return onehot_labels # softmax function def softmax(y): exp_y = np.exp(y - np.max(y)) return exp_y / np.sum(exp_y, axis=1, keepdims=True) # cross-entropy loss def cross_entropy_loss(y_pred, y_true): n_samples = y_pred.shape[0] loss = -np.sum(y_true * np.log(y_pred+1e-12)) / n_samples return loss # train softmax model def train_softmax(X_train, y_train, alpha=0.1, epochs=500): n_samples, n_features = X_train.shape n_classes = y_train.shape[1] W = np.random.randn(n_features, n_classes) * 0.01 b = np.zeros((1, n_classes)) for i in range(epochs): y_pred = softmax(np.dot(X_train, W) + b) loss = cross_entropy_loss(y_pred, y_train) if i % 100 == 0: print('Epoch %d loss: %.4f' % (i, loss)) dW = (1 / n_samples) * np.dot(X_train.T, (y_pred - y_train)) db = (1 / n_samples) * np.sum(y_pred - y_train, axis=0, keepdims=True) W -= alpha * dW b -= alpha * db return W, b # test softmax model def test_softmax(X_test, y_test, W, b): y_pred = softmax(np.dot(X_test, W) + b) accuracy = np.mean(np.argmax(y_pred, axis=1) == np.argmax(y_test, axis=1)) return accuracy # load data X_train, y_train, X_test, y_test = load_data() X_train = X_train / 255.0 X_test = X_test / 255.0 y_train = one_hot(y_train) y_test = one_hot(y_test) # train model W, b = train_softmax(X_train, y_train) # test model accuracy = test_softmax(X_test, y_test, W, b) print('Accuracy:', accuracy) ``` 这是一个使用Numpy实现的softmax分类器,对mnist数据集进行训练与测试。其中`load_data`函数用于从在线源加载mnist数据集,`one_hot`函数用于对标签进行One-Hot编码,`softmax`函数计算softmax输出,`cross_entropy_loss`函数计算交叉熵损失,`train_softmax`函数用于训练softmax模型,`test_softmax`函数用于测试softmax模型。在代码中使用的学习率`alpha`为0.1,训练轮数`epochs`为500。运行以上代码可以得到模型的测试准确率,这个准确率可能并不是很高,因为这是一个比较简单的模型。但是,它可以作为使用mnist数据集训练softmax模型的例子,供您参考。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值