Learning Memory-guided Normality for Anomaly Detection 代码解析

Learning Memory-guided Normality for Anomaly Detection 代码解析

目录 :

  1. 整体结构
  2. 训练(train)部分分析
  3. 评估(evaluate)部分分析
  4. 模型(model)部分分析
  5. 代码环境配置及运行

1.整体结构

1.1 代码文件及作用

根目录下包含 :

  1. Evaluate.py 评估代码
  2. Train.py 模型训练代码
  3. utils.py 负责数值运算:包含均方根差,峰值信噪比,学习率以及评估最后的准确率等.

model文件夹下包含:

  1. final_future_prediction_with_spatial_sumonly_weight_ranking_top1.py 包含编码器(encoder),译码器(decoder)及卷积自动编码器(convAE)模块.
  2. memory_final_spatial_sumonly_weight_ranking_top1.py 包含记忆(memory)模块.
  3. utils.py 数据集(dataset)类模块.
  4. Memory.py
  5. Reconstruction.py
    上述4,5实现和作用与1,2基本一致,在训练中通过method参数来区别调用:pred对应1,2 , recon对应4,5.(下文省略recon)

1.2 代码结构

1.2.1 训练(Train)部分

Train调用的代码文件:
Learning Memory-guided Normality for Anomaly Detection 代码解析

1.2.2 评估(Evaluate)部分

Evaluate调用的代码文件:
Learning Memory-guided Normality for Anomaly Detection 代码解析

2.训练(train)部分分析

2.1 训练流程

Learning Memory-guided Normality for Anomaly Detection 代码解析

在训练开始之前还存在以下步骤:

  1. 载入数据集
  2. 模型设定
  3. 建立日志文件

训练结束后,会在工程目录下生成exp文件夹,其中包含模型文件及日志文件.

2.2 代码分析

2.2.1 启动参数

Learning Memory-guided Normality for Anomaly Detection 代码解析

  • 此处对训练(train)模块代码的启动,参数说明见图中help

2.2.2 数据集载入

Learning Memory-guided Normality for Anomaly Detection 代码解析

  • 此处调用的DataLoader为model文件夹下的DataLoader类,该类用于载入数据集,并将数据集分划成mini-batch的形式,每个batch中含5个视频帧.其中ToTensor将(H,W,C)的视频帧转化为(C,H,W)的张量.

2.2.3 模型设定

Learning Memory-guided Normality for Anomaly Detection 代码解析

  • 模型选择分为两类:pred与recon;启动时通过输入不同的参数来选择相应的模型.

  • model.encoder.parameters为torch基类torch.nn.Module的函数,其主要作用是作为nn.Module的可训练参数使用.

  • torch.optim.Adam:既Adam优化算法.对梯度的一阶矩估计和二阶矩估计进行综合考虑,计算出更新步长.

  • CosineAnnealingLR:即余弦退火学习率,让学习率随epoch的变化图类似于cos,更新策略:
    Learning Memory-guided Normality for Anomaly Detection 代码解析

    其中,new表示学习率,initial表示初始学习率,eta表示最小学习率,T表示cos周期的1/2.

2.2.4 训练模块主体部分

Learning Memory-guided Normality for Anomaly Detection 代码解析
Learning Memory-guided Normality for Anomaly Detection 代码解析

  • 训练模块的步骤见2.1节的训练流程及图中注释.

3.评估(evaluate)部分分析

3.1 评估流程

Learning Memory-guided Normality for Anomaly Detection 代码解析

3.2 代码分析

与训练部分代码类似,分为以下几部分:

3.2.1 启动参数

Learning Memory-guided Normality for Anomaly Detection 代码解析

3.2.2 载入数据集

Learning Memory-guided Normality for Anomaly Detection 代码解析

3.2.3 载入已训练的模型

Learning Memory-guided Normality for Anomaly Detection 代码解析

3.2.4 初始化

Learning Memory-guided Normality for Anomaly Detection 代码解析

此处对记录数据的数组和变量进行初始化(标签长度,视频编号,峰值信噪比,特征距离).

3.2.5 评估模块主体部分

Learning Memory-guided Normality for Anomaly Detection 代码解析

Learning Memory-guided Normality for Anomaly Detection 代码解析

Learning Memory-guided Normality for Anomaly Detection 代码解析

评估模块的步骤见3.1节的评估流程及图中注释.

4.模型(model)部分分析

该部分由卷积自动编码器(convAE)和记忆模块(Memory)两部分组成,其中卷积自动编码器调用了编码器(encoder),解码器(decoder)及记忆模块(Memory).下面将自上而下分别介绍卷积自动编码器和记忆模块两个部分.

4.1 卷积自动编码器(convAE)部分

4.1.1 编码器(encoder)

编码器的实现为类,继承了神经网络模块基类(torch.nn.Module).其中只定义了初始化函数(init)以及向前传播函数(forward):

Learning Memory-guided Normality for Anomaly Detection 代码解析

其中__init__的实现为:

Learning Memory-guided Normality for Anomaly Detection 代码解析
Learning Memory-guided Normality for Anomaly Detection 代码解析

在__init__中实现了Basic及Basic_函数,二者都对图像进行了卷积,归一化和激活操作,但细节略有不同.在每次调用Basic或Basic_函数之后,再对图像进行最大池化(MaxPool2d)操作.

forward的实现为:

Learning Memory-guided Normality for Anomaly Detection 代码解析

forward仅调用了__init__中的参数,对传入的图像进行了重复的卷积和池化操作,再分别返回.

4.1.2 解码器(decoder)

与编码器类似,解码器同样继承了torch.nn.Module.也定义了初始化函数和前向传播函数:

Learning Memory-guided Normality for Anomaly Detection 代码解析

其中__init__的实现为:

Learning Memory-guided Normality for Anomaly Detection 代码解析

Learning Memory-guided Normality for Anomaly Detection 代码解析

与编码器不同,解码器的初始化函数包含了Basic,Gen及Upsample函数.其中Basic与Gen类似,对图像进行卷积,归一化和激活函数.在每次调用Basic函数后,进行上采样(Upsample)操作.其中上采样(Unsample)函数对图像进行反置卷积操作.

forward的实现为:

Learning Memory-guided Normality for Anomaly Detection 代码解析

forward通过调用__init__函数重复着卷积,上采样,拼接张量的操作.在最后调用Gen操作.

4.1.3 卷积自动编码器(convAE)

同样的,卷积自动编码器(convAE)也继承与torch.nn.Module,定义了__init__和forward函数.

其中__init__与forward的实现为:

Learning Memory-guided Normality for Anomaly Detection 代码解析

可见__init__和forward都调用了编码器和解码器对应的函数,除此之外还对记忆模块(Memory)进行了调用.需要注意的是,在forward中针对训练(train)和评估(evaluate)两个不同状态返回的值也不同.

4.2 记忆模块(Memory)部分

Memory实现如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析

其中,Memory分为read和update两个阶段,下面分别介绍各模块.

4.2.1 read

read实现如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析

该操作主要计算了对于每个查询(query)和记忆项(Memory item)的匹配概率(公式1),以及计算对每个记忆项和匹配概率的特征(公式2)(此时匹配概率作为加权平均值).
其中get_score用于计算匹配概率,后续操作计算基于匹配概率的特征.论文中给出公式如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析

Learning Memory-guided Normality for Anomaly Detection 代码解析

get_score实现如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析

4.2.2 update

update实现如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析

该操作与read同样调用get_score计算了匹配概率,不同的是,read计算的是垂直方向上的概率,而update计算的是水平方向上的概率.接着update在集合U中使用相关概率来计算加权平均值,再与最初的记忆项相加.最后根据集合U来更新记忆项(公式3).论文中给出公式如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析
Learning Memory-guided Normality for Anomaly Detection 代码解析

get_update_query用于获取包含查询的索引的集合(集合U),即公式5:
Learning Memory-guided Normality for Anomaly Detection 代码解析

4.2.3 forward

forward实现如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析

forward为前向传播函数,在训练模式通过下计算了特征分离性损失(Feature separateness loss,公式10)以及特征紧凑性损失(Feature compactness loss,公式12).再通过read和update的调用对记忆模块进行更新(训练和评估时).其中gather_loss的实现如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析

Learning Memory-guided Normality for Anomaly Detection 代码解析

可见在训练时,gather_loss创建了一个三元损失标准,其作用是为了鼓励查询记忆项中最相似的item,从而减小相同正常行为类的差异,增大不同行为的差异.论文中给出公式如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析

其中p:

Learning Memory-guided Normality for Anomaly Detection 代码解析

Learning Memory-guided Normality for Anomaly Detection 代码解析

其中n:

Learning Memory-guided Normality for Anomaly Detection 代码解析

5.代码环境配置及运行

项目地址:https://github.com/cvlab-yonsei/MNAD
其中README介绍了该项目使用的环境版本及使用的训练集(USCD Ped2 , CUHK Avenue , ShanghaiTech).

除了上述的项目文件,我们还需要下载数据集以及预训练模型.

以上文件都准备完毕后,在Pycharm中新建工程,并安装缺失的各种库(numpy,torch等).
需要注意的是,在安装cv2的时候可能会提示失败,此时可以安装opencv-python替代cv2,其使用方法完全一样.

接着我们需要将训练集以及预训练模型放在工程目录下,并在Train.py和Evaluate.py中修改启动参数:

Train.py:
Learning Memory-guided Normality for Anomaly Detection 代码解析

Evaluate.py:
Learning Memory-guided Normality for Anomaly Detection 代码解析

其中dataset_type需要指定数据集的类型(ped2,avenue,shanghai),在dataset_path中给出训练集的路径;model_dir和m_items_dir同样需要给出预训练模型的路径.

下面就可以进行运行测试了.如果想使用cpu进行测试,可以按以下步骤修改代码:

  1. 在代码的开头加上:
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  2. 将所有的.cuda()修改成.to(device);其中torch.load需要在模型路径后再添加一个参数:map_location = torch.device(device).

以上修改将使代码在运行时检测cuda,若不存在则使用cpu运算.

可能出现的问题:
在model/utils.py下的DataLoader类中,定义了__getitem__如下:

Learning Memory-guided Normality for Anomaly Detection 代码解析

其中可能产生路径错误.如报错,可修改为:

Learning Memory-guided Normality for Anomaly Detection 代码解析

上一篇:java 中sendredirect()和forward()方法的区别


下一篇:前端页面请求转发(forward)与重定向(redirect)