一、AutoEncoder的结构

encoder的作用是:学习一个好的特征,将图片压缩为一个低维特征;
decoder的作用是:逼迫encoder学到的特征,包含图片的主要结构,而不是随机特征
autoencoder的loss函数是复现误差,所以encoder学习到的特征必须包含图片特征,否则无法经过decoder复现出来。
autoencoder的起源,假设你是一个早期的数学家,一张人脸图片,你手工提取了眼睛位置、鼻子形状、脸型或者光照等,几十个变量来代表这张图片,你看,你在做一件事,就是找一个低维表示,同时保留数据的主要信息,这个是早期的手搓特征。
在数据分析界呆久了,PCA主成分分析这个算法你肯定会听说过,PCA的思想就是在原始空间中找到主要信息的方向,然后将信息投影到这个主要方向上,只保留前几个主要变量的维度就行,将这个保留的信息重新投影回来,尽可能接近原数据,然后计算复现误差,这个结构就是encoder decoder。
混迹神经网络后,word2Vec给你的启发是,不要人工去设计特征,使用神经网络,通过任务逼近网络学习合适的特征,使用几层网络搭建一个编码器encoder,再搭建decoder在encoder提取的特征之上重建原始图片,通过拉近重建图片和原始图片的距离,逼迫encoder提取的特征包含主要信息。
我们之前一直在研究yolov8m的P5特征,这里使用autoEncoder中的encoder又可以提取到特征,不仅要去思考,二者特征的区别是什么。autoEncoder提取的特征是用来重建的,所以这个特征必须要能够去描述整张图片,才可以尽可能的重建原始图片;但是yolov8m的P5是为了做车轮的目标检测,所以P5需要去特征关注车轮,钢轨,车辆结构等,不需要去关心背景变化,整体相似性,以及颜色细节。
二、Deep SVDD
既然autoencoder就可以提取重建的特征,为什么不可以直接用来度量,因为Deep SVDD发现,autoEncoder学到的feature空间,不一定适合距离的度量,论文里有句是这样说的:
Autoencoders have the objective of dimensionality reduction and do not target AD directly. The main difficulty of applying autoencoders for AD is given in choosing the right degree of compression, i.e.dimensionality reduction. If there was no compression, an autoencoder would just learn the identity function. In the other edge case of information reduction to a single value, the mean would be the optimal solution. That is, the "compactness" of the data representation is a model hyperparameter and choosing the right balance is hard due to the unsupervised nature and since the intrinsic dimensionality of the data is often difficult to estimate (Bengio et al., 2013). In comparison, we include the compactness of representation into our Deep SVDD objective by minimizing the volume of a data-enclosing hypersphere and thus target AD directly.
这段话直接解释了,为什么Deep SVDD要从autoEncoder走出来,因为autoEncoder的目标是降维,不是直接针对异常检测的,将autoEncoder的特征直接用于异常检测最大的困难是选择正确的压缩程度,什么意思呢,例如输入图片是3072维度,encoder将其压缩为2048维度,这种压缩很弱;压缩为128维度,中等压缩;压缩为1,极端压缩,到底什么合适?
这里论文专门提到了两种极端情况,一种是,输入多少维度,encoder就输出多少维度,没有压缩,网络学会了恒等映射(identity function),因为autoencoder的目标函数是复现误差,模型的特点是走捷径,为了达到这个目标,最快速的方法,就是输入x , encoder 输出z=x, decoder 输出 y = x,这种情况肯定不利于异常检测;还有一种极端情况,就是压缩为一个数值,在这种情况下,对于最小化重建误差,最优策略是,输出平均,这种也不利于异常检测。
就是具体压缩到多少,这个是一个人工设定的值,压缩维度的多少,决定了encoder后的特征向量中包含什么信息,Deep SVDD是让autoencoder直接提取特征就行,后面Deep SVDD把表示的紧凑性加入到第二步骤中。
Deep SVDD 的第一步就是autoencoder,学习一个能够表示整个图片的特征
Deep SVDD的第二步,是使用autoEncoder中的encoder网络,将正常图片的特征拉到一个中心点为c,半径为R的求内,例如下图

什么意思呢,就是使用autoencoder的encoder提取特征,然后使用下面的目标函数,进行二次训练

看代码会更清楚写,
- output是encoder提取的特征向量,例如128维度;
- self.c,是提取所有的正常图片的特征向量,从而求得的平均值;
- dist是在128维的特征空间,计算该图片与中心点的距离;
- 非软边界是,比较极端,直接把dist当成损失,意思是让所有的特征向量都向中心点靠近,越靠近,损失值越小,这种比较暴力;
- 第二种是软边界,意思是该图片的特征,只要在以self.c为中心点,半径为R的球体中就行,不需要和中心点非常靠近就行,而且是在球体内,在球体外的才产生损失,才惩罚,torch.mean(torch.max(torch.zeros_like(scores),scores)),这句话就是这个意思;
- 损失的第二部分是让所有的点尽可能在球体内,将球体外的那部分长度作为损失值,当点在球体内,dist < R,loss = 0;这里有一个惩罚因子,就是1 / self.nu,在(0,1)范围内,这控制允许多少异常点在球外。
- 损失的第一部分是R的平方,是让球体半径尽可能小;
- 第一部分负责让球体缩小,第二部分负责惩罚跑出去的点;
python
outputs = net(inputs)
dist = torch.sum((outputs - self.c) ** 2, dim=1)
if self.objective == 'soft-boundary':
scores = dist - self.R ** 2
loss = self.R ** 2 + (1 / self.nu) * torch.mean(torch.max(torch.zeros_like(scores), scores))
else:
loss = torch.mean(dist)
loss.backward()
optimizer.step()
三、Deep SVDD的疑问
Deep SVDD的第二个步骤,就是为了把正常的图片的特征都拉近,那么这里有一个疑问,当出现一张异常图片,比如故障图片,障碍物图片等,提取的特征真的可以将其分开么?
比如想做轨道上的障碍物检测,那么正常轨道有直的,弯的,白天的,晚上的,不同光照的,而异常只是在轨道上有个人,有个石头,有些泥石流等,那么Encoder提取的异常特征真的会远离正常特征么?
我觉得这个是不一定的,Deep SVDD要想有效果,核心在于,Encoder需要学习到正常图片的本质结构,哪些视觉变化是正常的,哪些视觉变化是异常的。
其实你发现,要想神经网络快速学习和约束,最好是告诉它哪些是正常的同时,也要告诉它,哪些是异常的,但是Deep SVDD最关键的一点是,无法统一异常的形态,但是我们人眼是可以分清楚,哪些变化是属于一样,哪些变化是属于异常,这种特点要在特征空间中凸显出来。
回过来再看Deep SVDD,Deep SVDD希望正常的特征都集中在一个球里面,如果我们做轨道异常检测,那有一个问题,轨道的形态,光照等是否放在特征球里面呢;另外,我的障碍物有可能很小,有障碍物的轨道的特征,有是否在特征球体外呢。
Deep SVDD是一种解题的思路,但是这个方法不一定使用目前我想做的事情,但是它让我学会了如何去控制特征的分布,从而对特征进一步的理解,同时虽然不适用这个问题,但是有可能会在别的问题中给你带来解题思路。