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

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

目录 :

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

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调用的代码文件:
在这里插入图片描述

1.2.2 评估(Evaluate)部分

Evaluate调用的代码文件:
在这里插入图片描述

2.训练(train)部分分析

2.1 训练流程

在这里插入图片描述

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

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

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

2.2 代码分析

2.2.1 启动参数

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

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

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

  • CosineAnnealingLR:即余弦退火学习率,让学习率随epoch的变化图类似于cos,更新策略:
    在这里插入图片描述

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

2.2.4 训练模块主体部分

在这里插入图片描述
在这里插入图片描述

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

3.评估(evaluate)部分分析

3.1 评估流程

在这里插入图片描述

3.2 代码分析

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

3.2.1 启动参数

在这里插入图片描述

3.2.2 载入数据集

在这里插入图片描述

3.2.3 载入已训练的模型

在这里插入图片描述

3.2.4 初始化

在这里插入图片描述

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

3.2.5 评估模块主体部分

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

4.模型(model)部分分析

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

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

4.1.1 编码器(encoder)

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

在这里插入图片描述

其中__init__的实现为:

在这里插入图片描述
在这里插入图片描述

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

forward的实现为:

在这里插入图片描述

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

4.1.2 解码器(decoder)

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

在这里插入图片描述

其中__init__的实现为:

在这里插入图片描述

在这里插入图片描述

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

forward的实现为:

在这里插入图片描述

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

4.1.3 卷积自动编码器(convAE)

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

其中__init__与forward的实现为:

在这里插入图片描述

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

4.2 记忆模块(Memory)部分

Memory实现如下:

在这里插入图片描述

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

4.2.1 read

read实现如下:

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

get_score实现如下:

在这里插入图片描述

4.2.2 update

update实现如下:

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

get_update_query用于获取包含查询的索引的集合(集合U),即公式5:
在这里插入图片描述

4.2.3 forward

forward实现如下:

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

其中p:

在这里插入图片描述

在这里插入图片描述

其中n:

在这里插入图片描述

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:
在这里插入图片描述

Evaluate.py:
在这里插入图片描述

其中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__如下:

在这里插入图片描述

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

在这里插入图片描述

6.相关资料参考

  1. 模型(model)部分介绍
  2. 该论文创新点介绍
  3. 论文综述

注意:以上所有内容仅用作科学研究及参考.如若转载,请注明出处.

根据已有信息,**DeSTSeg: Segmentation Guided Denoising Student-Teacher for Anomaly Detection** 是一种结合了学生-教师框架与去噪机制的异常检测方法,特别关注于语义分割引导的异常识别[^1]。该项目的核心思想是通过学生网络去噪教师网络的特征表示,并在异常输入上表现出较大的重建差异,从而实现有效的异常检测。 目前,该项目的代码尚未在主流平台(如 GitHub)上广泛传播,但可以通过以下几种方式寻找其实现: 1. **访问相关论文的发布页面**:许多研究者会在论文的项目页面或 arXiv 页面提供代码链接。可以尝试访问论文中提到的链接,例如作者的主页或机构库。 2. **GitHub 搜索**: - 使用以下关键词在 GitHub 上进行搜索: - `"DeSTSeg"` 或 `"Segmentation Guided Denoising Student-Teacher"` - `"anomaly detection student teacher segmentation"` - 高级搜索语法示例: ``` "DeSTSeg" in:name language:python ``` 3. **学术搜索引擎**: - 在 Google Scholar 或 Semantic Scholar 上搜索论文标题,并查看是否有“Code”或“Project”链接。 - 访问 [Papers with Code](https://paperswithcode.com/) 网站,搜索该论文名称,查看是否已有开源实现。 4. **社区与论坛**: - 在 [Stack Overflow](https://stackoverflow.com/)、[Reddit](https://www.reddit.com/r/MachineLearning/) 或 [Kaggle](https://www.kaggle.com/) 等平台上提问,询问是否有开发者实现过该模型。 - 在 GitHub Discussions 或相关开源项目的 Issues 中寻求帮助。 5. **复现代码**: - 如果官方代码不可得,可以尝试基于论文描述自行实现,或参考类似的学生-教师结构项目,如: - [DenseNet Student-Teacher Models](https://github.com/pytorch/vision) - [Anomaly Detection using Autoencoders](https://github.com/fastmachinelearning/VAE-AnomalyDetection) ### 示例代码结构(非官方实现) 以下是一个基于学生-教师结构的简化框架示例: ```python import torch import torch.nn as nn class Teacher(nn.Module): def __init__(self): super(Teacher, self).__init__() self.encoder = nn.Sequential( nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2) ) self.decoder = nn.Sequential( nn.ConvTranspose2d(64, 3, kernel_size=2, stride=2), nn.Sigmoid() ) def forward(self, x): encoded = self.encoder(x) decoded = self.decoder(encoded) return encoded, decoded class Student(nn.Module): def __init__(self): super(Student, self).__init__() self.encoder = nn.Sequential( nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1), nn.ReLU() ) self.decoder = nn.Sequential( nn.ConvTranspose2d(64, 3, kernel_size=2, stride=2), nn.Sigmoid() ) def forward(self, x): encoded = self.encoder(x) decoded = self.decoder(encoded) return decoded # 损失函数 criterion = nn.MSELoss() teacher = Teacher() student = Student() # 假设输入为 x with torch.no_grad(): t_encoded, t_decoded = teacher(x) s_decoded = student(x) loss = criterion(s_decoded, t_decoded.detach()) loss.backward() ```
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值