视频异常检测 综述
Posted Shawn Mendes
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了视频异常检测 综述相关的知识,希望对你有一定的参考价值。
视频异常检测 综述(二)
文章目录
特征提取的常用手段
大体上,视频异常检测方法使用两类表示:手工制作的特征和来自CNN的深度特征。
手工制作的特征包括时空梯度、动态纹理、梯度直方图、流直方图、流场、密集轨迹和前景掩码。
深度特征可以直接从预训练网络中提取,或者在优化与异常检测相关的特定任务时学习,例如使用自动编码器去优化低重构误差。
模型处理的原子单元
算法处理的原子单元包括:图像块、视频块,到单个完整帧、视频片段(完整帧的短序列)
在处理图像或视频块时,算法可以以单个固定大小块、多尺度固定大小块、任意大小区域的块为单位进行操作。
模型建模的常用手段
建模中的常用方法包括:one-class SVM、最近邻(knn)方法、隐马尔可夫模型以及更普遍的概率图形模型。最近,深度学习方法开始使用对抗性训练策略。
一些工作仅关注帧级(时间)定位,这意味着帧级内容会被构建到模型中,但这种情况下模型无法执行适当的空间定位。例如,使用完整帧或视频片段作为其原子处理单元的方法,它们都无法区分异常到底是有人在大使馆大楼外游荡,还是在在大使馆旁边的公园游荡。
其他方法以如下两种方式之一解释异常的空间位置性:(1)根据其在帧中的位置对像素进行评分,(2)根据相邻像素所提供额外的上下文信息以进行评分。
视频异常检测方法的分类
从宏观上看,过去的视频异常检测工作可以分为基于距离、概率和基于重构的方法。这些方法之间并不相互排斥,因为以基于距离的方式运行的方法很容易产生概率解释,分类仅仅是为了方便。
基于距离的视频异常检测方法
基于距离的方法通过使用训练数据创建“正态”模型,并通过测量测试数据与该模型的偏差以确定异常分数。通常,这些模型本身非常简单,但巧妙的特征提取和公式化会带来良好的性能。基于距离的方法可以被视为概率和基于重建的方法的更一般形式。
在过去基于距离的方法中使用了许多不同类型的特征提取方法,以及测量到正常特征距离的许多不同方法。一种常见方法是使用one-class SVM来计算来自正常训练视频的特征向量周围的决策边界。但这种方法的缺点是在给定新的正常训练数据的情况下更新模型是昂贵的,因为SVM学习算法必须在所有旧数据和新数据上重新运行。另一种方法是使用高斯混合来建模法线特征向量,然后使用马氏距离来测量到法线的距离。
传统的特征提取方法不建议继续使用,一方面是由于提取较为困难,另一方面是提取出来的特征精度较低
较新的方法侧重于深度网络学习的特征,这些特征通常具有较高的精度,这些基于深度网络的方法包括学习深度特征的多种方法,以及在不同的正态模型中使用深度特征的各种方法。
下面简单描述2篇2020年的基于距离的视频异常检测方法的论文方法:
第一篇
B. Ramachandra and M. Jones, “Street scene: A new dataset and evaluation protocol for video anomaly detection,” in Proc. IEEE Winter Conf. Appl. Comput. Vis., 2020, pp. 2558–2567
作者在最近发布的数据集Street Scene上提出了两种baseline算法,用于未来工作的比较。他们使用简单的最近邻位置(nearest neighbor location)异常检测方案,使用手工制作的视频特征表示(流场或模糊前景掩码)以及手工制作的距离测量方法(分别为L1或L2归一化的像素级距离)。通过从训练数据构建出简洁的代表性样本模型,大大减少了距离计算的数量。
有趣的是,他们表明,这些简单的方法能够在其他数据集上优于一些先前的最先进方法,这可能表明算法已经产生了特定于某些数据集的偏差。
第二篇
B. Ramachandra, M. Jones, and R. Vatsavai, “Learning a distance function with a siamese network to localize anomalies in videos,” in Proc. IEEE Winter Conf. Appl. Comput. Vis., 2020, pp. 2587–2596.
作者在一个很简单的最邻近位置模式上建模,训练一个孪生神经网络,将原模式中的手工特征提取方式与距离函数替换掉。这个孪生神经网络被训练为判断视频之间是相似的还是不同的,用于判断测试视频是否与其余的训练视频都不相同,以此将其归类为异常。
从数据集的训练数据学习正态模型,使用训练好的模型在测试视频和样本视频进行最邻近评分,并且为每个测试视频分配异常分数。
基于概率的视频异常检测方法
概率方法在一定概率空间中计算模型下的距离。这些方法通常将模型建模到一个概率框架中,如概率图模型(PGMs)或高维概率分布的混合模型。大多数概率方法在深度学习方法浪潮之前出现,并且依赖于时空梯度、光流场等特征,以及STIP特征与传统的马尔可夫随机场和混合高斯模型等。最近的一些方法使用了深度神经网络,也显示出了更高的准确性。
这些方法的一个优点是具有高度原则性,并且能够很好地模拟异常的连续性质,但是它们在测试时通常很慢。
下面简单描述2篇通过深度神经网络实现的基于概率视频异常检测的论文方法:
第一篇
R. Hinami, T. Mei, and S. Satoh, “Joint detection and recounting of abnormal events by learning deep generic knowledge,” in Proc. IEEE Int. Conf. Comput. Vis., 2017, pp. 3639–3647.
这篇论文中,作者提出了一种在检测到异常事件时重新计数的方法,他们首先训练了一个Fast-RCNN模型去在大规模的数据集如COCO、Visual Genome去预测物体、行为、种类等属性。之后对于每一帧,他们通过倒数第二个全连接层去提取每一个感兴趣对象区域(region of interest RoI)的特征,再使用最邻近距离、RBF核的one-class SVM、RBF核核密度估计下的似然来进行异常检测。
重新计算是通过简单的查看对对象、行为、属性类的最大预测来实现的。
第二篇
Y. Feng, Y. Yuan, and X. Lu, “Learning deep event models for crowd anomaly detection,” Neurocomputing, vol. 219, pp. 548–556, Jan. 2017
这篇论文中,作者使用PCANet,通过正常的图像patch的3D梯度来提取深度表征,然后使用 Deep GMMs来对正常模式的生成过程进行建模,使得log likelihood的下限最大化。deep GMM模型可以对测试的数据进行相似度评分生成,这个得分通常被用作异常得分。
基于重构的视频异常检测方法
基于重构的方法是通过从正常视频中学习到的特征来重新表示输入的图像或视频片段。这种方法基于的假设是,与分布内的正常数据相比,使用从正常视频中学习到的特征去重构分布外的输入(如异常输入)在本质上是更困难的,这也证明了使用重构误差来代表异常分数是合理的。几乎所有基于重构的方法都使用了现代的深度学习方法,尤其是大多数基于卷积自编码器(auto-encoders)或生成式对抗网络(GANs)的方法。
通常,基于重构的方法有一个缺点,当使用或添加了新的训练视频后,它们使用的模型(例如,自编码器或GAN)需要重新训练,以适应新的正常训练视频。 许多这些方法不评估异常的空间定位,据推测,这是因为它们的空间定位精度较低。其中使用自编码器模型重构方法的另一个缺点是,帧的重构误差与帧中前景对象的数量成正比,这也是大多数这类方法必须对每个视频进行归一化的后处理步骤的原因。
下面简单描述2篇2020年的基于重构的视频异常检测方法的论文方法:
第一篇
Y. Tang, L. Zhao, S. Zhang, C. Gong, G. Li, and J. Yang, “Integrating prediction and reconstruction for anomaly detection,” Pattern Recognit. Lett., vol. 129, pp. 123–130, Jan. 2020
作者认为,预测与重构可以结合起来,去利用两者的优点、平衡两者的缺点。他们通过构建一个生成器来实现这一目标,这个生成器由两个连续的U-net结构组成,用来处理视频片段,第一个U-net去预测一个过渡时刻的帧,接着第二个U-net通过这个帧去预测未来时刻的帧,通过强度值与梯度值去最小化重构误差。他们还在未来时刻的Ground Truth与预测的未来帧使用对抗性的损失函数来训练。
第二篇
H. Park, J. Noh, and B. Ham, “Learning memory-guided normality for anomaly detection,” in Proc. IEEE/CVF Conf. Comput. Vis. Pattern Recognit., 2020, pp. 14 372–14 381
作者认为,基于CNN的重构方法由于CNN的高表示容量(模型的最大容量)而很难重构异常事件,他们提出使用已经通过训练的、存储了重要的正常模式特征的记忆模块来增强U-net风格的编码器-解码器,即用于未来帧预测、重构的网络模型。这个经过训练的记忆模块使用帧与其重构帧的PSNR,以及编码的内容与其最近的记忆单元的距离来计算异常分数。最后也要对每个视频的异常得分进行归一化处理。
稀疏重构方法
稀疏重构方法是重构方法的一个子集,它对重构施加了额外的约束条件,即重构必须仅使用稀疏特征集来执行。几乎所有稀疏重建方法都优化了某种稀疏组合学习公式。
这类方法通常具有快速(其目标就是稀疏性)和易于更新正态模型的一些有利特性。
这类方法的一个缺点是,它们通常过于依赖去记忆显著的正常特征,这给用于穷举的正常训练集带来了很大负担。也正因于此,这类方法无法很好的去建模异常的本质,即得分较低的异常行为通常不对应与人类直觉中的异常活动。
D. Gong, L. Liu, V. Le, B. Saha, M. R. Mansour, and S. Venkatesh, “Memorizing normality to detect anomaly: Memory-augmented deep autoencoder for unsupervised anomaly detection,” in Proc. IEEE/CVF Int. Conf. Comput. Vis., 2019, pp. 1705–1714
作者提出使用存储模块去扩充3D卷积自动编码器,他们认为这种方法有助于克服现有的一些自编码器方法在测试数据时出现的漏检问题。在bottleneck层,他们加入了存储模块,这个模块使用固定大小的内存,通过基于注意力的编码方式,以及硬阈值的方法来促进对输入的视频片段进行稀疏重构。这种方法最后也要对每个视频的异常得分进行归一化处理,但对空间定位方面的性能不加以考虑。
总结与展望
该领域的研究人员应尽量使用推荐的可靠数据集,新的评估方案,并参与可复用性研究。随着该领域逐渐成熟,产生了在实践中可行的方法,研究人员在提出相应方法时也应该提供使用这些方法的运行对比分析。
对假阳性数据质量的定性评估很重要,尤其对发现建模中的偏差有很大帮助。
对多个数据集进行评估也是必不可少的,例如:一些只在UCSD Ped1、UCSD Ped2或UMN数据集上进行异常评估的工作成果很有可能固有地偏向于这些数据集中的异常,这些数据集主要由运动幅度较大的物体组成。
过去视频异常检测算法的输入主要由原始、固定大小的图像块组成;由于有些异常需要分析时间信息,因此研究人员转向使用视频patch,这也需要更多的计算能力。最近,研究人员开始使用视频的多模态输入,包括原始帧和光流场,现在这种模式已经成为常态模式。尤其现在I3D在视频动作识别领域的流行趋势,GPU计算能力的进步,输入表示的日益复杂的趋势将逆转。
与此同时,建模遵循了一种不同的趋势。最开始时,研究人员使用了非常简单的手工特征,这些特征的分布可以通过简单的假设来进行建模。很快,研究人员通过更复杂的模型、更复杂的假设和许多巧妙的工程设计,取得了更好的结果。
最近,这种趋势发生了逆转,人们更依赖从数据中学习表示来更直接地优化方案和建模方法。预计这种数据主导的趋势将继续下去,特别是当更大、更复杂的数据集变得可用时。
一方面,视频异常检测的研究已经取得了长足的进步,但另一方面,以往的研究也忽视了视频异常检测中一些更具挑战性的问题。在现有的数据集中,徘徊异常还没有被建模来解决。事实上,过去的大多数方法都无法检测到这类异常,因为它们严重依赖于动作线索,而忽略了视频的处理部分。
就异常类型而言,组异常、轨迹异常和时间异常在很大程度上还没有得到解决,因为包含这些异常的baseline数据集还不存在。随着研究内容专注于精度趋于饱和的更小、更不复杂的数据集转移到更大、更复杂、有更多种异常类型的数据集,新的视频表示和新的建模策略会被迫切需要,以在低假阳性率(误报率)下实现高检测率,从而使算法在实际应用中具有实用性。
禁止搬运、转载
深度盘点:时序预测之异常检测算法综述
本文将介绍在时间序列预测相关问题中常见的异常检测算法,可以很大程度上帮助改善最终预测效果。喜欢记得收藏、关注、点赞。
注:完整版代码、数据、技术交流,文末获取
异常分类
时间序列的异常检测问题通常表示为相对于某些标准信号或常见信号的离群点。虽然有很多的异常类型,但是我们只关注业务角度中最重要的类型,比如意外的峰值、下降、趋势变化以及等级转换(level shifts)。
常见的异常有如下几种:
-
革新性异常:innovational outlier (IO),造成离群点干扰不仅作用于X(T),而且影响T时刻以后序列的所有观察值。
-
附加性异常:additive outlier (AO),造成这种离群点的干扰,只影响该干扰发生的那一个时刻T上的序列值,而不影响该时刻以后的序列值。
-
水平移位异常:level shift (LS),造成这种离群点的干扰是在某一时刻T,系统的结构发生了变化,并持续影响T时刻以后的所有行为,在数列上往往表现出T时刻前后的序列均值发生水平位移。
-
暂时变更异常temporary change (TC):造成这种离群点的干扰是在T时刻干扰发生时具有一定初始效应,以后随时间根据衰减因子的大小呈指数衰减。
上面的解释可能不太容易理解,我们结合图片来看一下:
通常,异常检测算法应该将每个时间点标记为异常/非异常,或者预测某个点的信号,并衡量这个点的真实值与预测值的差值是否足够大,从而将其视为异常。使用后面的方法,你将能够得到一个可视化的置信区间,这有助于理解为什么会出现异常并进行验证。
常见异常检测方法
从分类看,当前发展阶段的时序异常检测算法和模型可以分为一下几类:
-
统计模型:优点是复杂度低,计算速度快,泛化能力强悍。因为没有训练过程,即使没有前期的数据积累,也可以快速的投入生产使用。缺点是准确率一般。但是这个其实是看场景的,并且也有简单的方法来提高业务层面的准确率。这个后面会提到。
-
机器学习模型:鲁棒性较好,准确率较高。需要训练模型,泛化能力一般。
-
深度学习模型:普遍需要喂大量的数据,计算复杂度高。整体看,准确性高,尤其是近段时间,强化学习的引入,进一步巩固其准确性方面的领先优势。
3-Sigma
3-Sigma原则又称为拉依达准则,该准则定义如下:假设一组检测数据只含有随机误差,对原始数据进行计算处理得到标准差,然后按一定的概率确定一个区间,认为误差超过这个区间的就属于异常值。
使用3-Sigma的前提是数据服从正态分布,满足这个条件之后,在3-Sigma范围(μ–3σ,μ+3σ)内99.73%的为正常数据,其中σ代表标准差,μ代表均值,x=μ为图形的对称轴。下面是3-Sigma的Python实现:
import numpy as np
def three_sigma(df_col):
'''
df_col:DataFrame数据的某一列
'''
rule = (df_col.mean() - 3 * df_col.std() > df_col) | (df_col.mean() + 3 * df_col.std() < df_col)
index = np.arange(df_col.shape[0])[rule]
out_range = df_col.iloc[index]
return out_range
对于异常值检测出来的结果,有多种处理方式,如果是时间序列中的值,那么我们可以认为这个时刻的操作属于异常的;如果是将异常值检测用于数据预处理阶段,处理方法有以下四种:
-
删除带有异常值的数据;
-
将异常值视为缺失值,交给缺失值处理方法来处理;
-
用平均值进行修正;
-
当然我们也可以选择不处理。
Grubbs测试
Grubbs’Test为一种假设检验的方法,常被用来检验服从正太分布的单变量数据集(univariate data set)Y 中的单个异常值。若有异常值,则其必为数据集中的最大值或最小值。原假设与备择假设如下:
-
H0: 数据集中没有异常值
-
H1: 数据集中有一个异常值
使用Grubbs测试需要总体是正态分布的。算法流程:
-
样本从小到大排序
-
求样本的mean和dev
-
计算min/max与mean的差距,更大的那个为可疑值
-
求可疑值的z-score (standard score),如果大于Grubbs临界值,那么就是outlier
Grubbs临界值可以查表得到,它由两个值决定:检出水平α(越严格越小),样本数量n,排除outlier,对剩余序列循环做 1-4 步骤。由于这里需要的是异常判定,只需要判断tail_avg是否outlier即可。
from outliers import smirnov_grubbs as grubbs
print(grubbs.test([8, 9, 10, 1, 9], alpha=0.05))
print(grubbs.min_test_outliers([8, 9, 10, 1, 9], alpha=0.05))
print(grubbs.max_test_outliers([8, 9, 10, 1, 9], alpha=0.05))
print(grubbs.max_test_indices([8, 9, 10, 50, 9], alpha=0.05))
S-ESD与S-H-ESD
鉴于时间序列数据具有周期性(seasonal)、趋势性(trend),异常检测时不能作为孤立的样本点处理;故而Twitter的工程师提出了S- ESD (Seasonal ESD)与S-H-ESD (Seasonal Hybrid ESD)算法,将ESD扩展到时间序列数据。
STL分解
STL (Seasonal-Trend decomposition procedure based on Loess) 为时序分解中一种常见的算法,基于LOESS将某时刻的数据Yv分解为趋势分量(trend component)、季节性分量(seasonal component)和残差(remainder component):
由上到下依次为:原始时间序列和使用 STL 分解得到的季节变化部分、趋势变化部分以及残差部分。
STL分为内循环(inner loop)与外循环(outer loop),其中内循环主要做了趋势拟合与周期分量的计算。假定T(k)v、Sv(k)为内循环中第k-1次pass结束时的趋势分量、周期分量,初始时T(k)v=0;并有以下参数:
-
n(i)内层循环数
-
n(o)外层循环数
-
n§为一个周期的样本数
-
n(s)为Step 2中LOESS平滑参数
-
n(l)为Step 3中LOESS平滑参数
-
n(t)为Step 6中LOESS平滑参数
每个周期相同位置的样本点组成一个子序列(subseries),容易知道这样的子序列共有共有n§个,我们称其为cycle-subseries。
Python的statsmodels实现了一个简单版的时序分解,通过加权滑动平均提取趋势分量,然后对cycle-subseries每个时间点数据求平均组成周期分量:
使用示例:
import numpy as np
import pandas as pd
from statsmodels.tsa.seasonal import seasonal_decompose
import matplotlib.pyplot as plt
# Generate some data
np.random.seed(0)
n = 1500
dates = np.array('2019-01-01', dtype=np.datetime64) + np.arange(n)
data = 12 * np.sin(2 * np.pi * np.arange(n) / 365) + np.random.normal(12, 2, 1500)
df = pd.DataFrame('data': data, index=dates)
# Reproduce the example in OP
seasonal_decompose(df, model='additive', period=1).plot()
plt.show()
S-ESD
STL将时间序列数据分解为趋势分量、周期分量和余项分量。想当然的解法——将ESD运用于STL分解后的余项分量中,即可得到时间序列上的异常点。但是,我们会发现在余项分量中存在着部分假异常点(spurious anomalies)。如下图所示:
在红色矩形方框中,向下突起点被误报为异常点。为了解决这种假阳性降低准确率的问题,S-ESD算法用中位数(median)替换掉趋势分量;
使用示例:
import numpy as np
import sesd
ts = np.random.random(100)
# Introduce artificial anomalies
ts[14] = 9
ts[83] = 10
outliers_indices = sesd.seasonal_esd(ts, periodicity=20, hybrid=True, max_anomalies=2)
for idx in outliers_indices:
print(f'Anomaly index: idx, anomaly value: ts[idx]')
移动平均/加权移动平均/指数加权移动平均
移动平均 moving average
给定一个时间序列和窗口长度N,moving average等于当前data point之前N个点(包括当前点)的平均值。不停地移动这个窗口,就得到移动平均曲线。
累加移动平均 cumulative moving average
设xi:i≥1是观察到的数据序列。累积移动平均线是所有数据的未加权平均值。如果若干天的值是x1,…,xi,那么:
加权移动平均 weighted moving average
加权移动平均值是先前w个数据的加权平均值
指数加权移动平均 exponential weighted moving average
指数移动与移动平均有些不同:
-
并没有时间窗口,用的是从时间序列第一个data point到当前data point之间的所有点。
-
每个data point的权重不同,离当前时间点越近的点的权重越大,历史时间点的权重随着离当前时间点的距离呈指数衰减,从当前data point往前的data point,权重依次为
该算法可以检测一个异常较短时间后发生另外一个异常的情况,异常持续一段时间后可能被判定为正常。
ARIMA 模型
自回归移动平均模型(ARIMA)是一种设计上非常简单的方法,但其效果足够强大,可以预测信号并发现其中的异常。该方法的思路是从过去的几个数据点来生成下一个数据点的预测,在过程中添加一些随机变量(通常是添加白噪声)。以此类推,预测得到的数据点可以用来生成新的预测。很明显:它会使得后续预测信号数据更平滑。使用这种方法最困难的部分是选择差异数量、自回归数量和预测误差系数。另一个障碍是信号经过差分后应该是固定的。也就是说,这意味着信号不应该依赖于时间,这是一个比较显著的限制。
异常检测是利用离群点来建立一个经过调整的信号模型,然后利用t-统计量来检验该模型是否比原模型能更好的拟合数据。
在这种情况下,你可以找到适合信号的 ARIMA 模型,它可以检测出所有类型的异常。
神经网络
与CART方法一样,神经网络有两种应用方式:监督学习和无监督学习。我们处理的数据是时间序列,所以最适合的神经网络类型是 LSTM。如果构建得当,这种循环神经网络将可以建模实现时间序列中最复杂的依赖关系,包括高级的季节性依赖关系。如果存在多个时间序列相互耦合,该方法也非常有用。该领域还在研究中,可以参考这里,构建时序模型需要大量的工作。构建成功完成后,就可能在精确度方面取得优异的成绩。
推荐文章
技术交流
欢迎转载、收藏、有所收获点赞支持一下!数据、代码可以找我获取
目前开通了技术交流群,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友
- 方式①、发送如下图片至微信,长按识别,后台回复:加群;
- 方式②、添加微信号:dkl88191,备注:来自CSDN
- 方式③、微信搜索公众号:Python学习与数据挖掘,后台回复:加群
以上是关于视频异常检测 综述的主要内容,如果未能解决你的问题,请参考以下文章
异常检测:综述(基本都是无监督算法)时间序列算法:AR/MA/ARMA传统机器学习算法:孤独森林One Class SVM深度学习算法:AutoEncoderLSTMDeepLog
50+篇必看2020综述论文《深度学习/机器学习/知识图谱/NLP/CV》大集合