【视频异常检测-论文阅读】Learning Not to Reconstruct Anomalies

本文介绍了Learning Not to Reconstruct (BMVC 2021) 中的方法,针对视频异常检测中的自动编码器(Autoencoder, AE)重建异常问题。研究者提出利用伪异常训练策略,通过patch和skip frame生成机制限制AE对异常数据的重建能力,提升正常数据的区分度。文章详细阐述了模型结构、损失函数和实验对比,旨在改进OCC(One-Class Classification)下的异常检测性能。

Astrid, M., M. Zaheer, Jae-Yeong Lee and Seung-Ik Lee. “Learning Not to Reconstruct Anomalies.” BMVC (2021).

Code:GitHub - aseuteurideu/LearningNotToReconstructAnomalies: Official implementation of "Learning Not to Reconstruct" (BMVC 2021)

Paper URL:[PDF] Learning Not to Reconstruct Anomalies | Semantic Scholar 

 与下面这一篇 是同一个团队,并且实现方法非常类似【视频异常检测-论文阅读】Synthetic Temporal Anomaly Guided End-to-End Video Anomaly Detection_不喝可乐不快乐的博客-优快云博客

 

这篇文章主要针对 解决视频异常检测问题 中以 one-class classification (OCC) 的方式(经常使用的是自动把编码器(Atuoencoder))存在这样一个问题: 即使只有正常的数据训练,AEs通常也可以较好的重建异常,这会降低异常检测性能。

ps: (论文中的一个解释)

这很可能是一个结果,因为只要边界在训练集中包含正常数据,AE仅根据正常数据进行训练的AE的重建边界就不会受到约束</

### 自编码器异常检测 PyTorch 实现 #### 构建自编码器模型 为了实现信用卡数据集上的异常检测,可以构建一个基础的全连接神经网络作为自编码器结构[^1]。 ```python import torch from torch import nn, optim from torch.utils.data import DataLoader, TensorDataset class Autoencoder(nn.Module): def __init__(input_dim: int, hidden_dims: list[int]): super(Autoencoder, self).__init__() encoder_layers = [] decoder_layers = [] current_dim = input_dim for hdim in hidden_dims: encoder_layers.append( nn.Sequential( nn.Linear(current_dim, hdim), nn.ReLU() ) ) current_dim = hdim for hdim in reversed(hidden_dims[:-1]): decoder_layers.append( nn.Sequential( nn.Linear(current_dim, hdim), nn.ReLU() ) ) # Add final layer to reconstruct the original dimensions. decoder_layers.append( nn.Linear(current_dim, input_dim) ) model.encoder = nn.Sequential(*encoder_layers) model.decoder = nn.Sequential(*decoder_layers) def forward(self, x): encoded = model.encoder(x) decoded = model.decoder(encoded) return decoded ``` #### 训练过程设置 训练过程中主要关注正常样本的学习,通过重构损失来衡量输入与输出之间的差异。对于异常情况,则期望该误差较大从而能够区分出异常实例。 ```python def train_autoencoder(model, dataloader, epochs=50): criterion = nn.MSELoss() # 使用均方差作为损失函数 optimizer = optim.Adam(model.parameters(), lr=1e-3) for epoch in range(epochs): total_loss = 0 for batch_features in dataloader: # reshape mini-batch data to [N, 784] matrix # load it to the active device batch_features = batch_features.to(device) # reset the gradients back to zero # PyTorch accumulates gradients on subsequent backward passes optimizer.zero_grad() # compute reconstructions outputs = model(batch_features) # compute training reconstruction loss train_loss = criterion(outputs, batch_features) # compute accumulated gradients train_loss.backward() # perform parameter update based on current gradients optimizer.step() # add the mini-batch training loss to epoch loss total_loss += train_loss.item() average_loss = total_loss / len(dataloader.dataset) print(f'Epoch [{epoch + 1}/{epochs}], Loss:{average_loss:.4f}') ``` #### 测试阶段评估 测试时计算每条记录经过自编码器后的重建误差,并设定阈值判断是否属于异常类别。通常会对比已知正常的样本分布来进行决策[^2]。 ```python def evaluate_anomalies(model, dataset, threshold=None): with torch.no_grad(): predictions, losses = [], [] for features in dataset: output = model(features.unsqueeze_(0)) prediction = output.squeeze().cpu().numpy() loss = ((features.cpu().numpy() - prediction)**2).mean(axis=-1)[0] predictions.append(prediction) losses.append(loss) if not threshold: sorted_losses = np.sort(losses) cutoff_index = int(len(sorted_losses)*0.95) # top 5% as anomalies threshold = sorted_losses[cutoff_index] predicted_labels = ['normal' if l <= threshold else 'anomaly' for l in losses] return {'predictions': predictions, 'losses': losses, 'threshold': threshold, 'labels': predicted_labels} ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值