记忆自编码器(MemAE)
文章目录
主要功能:
- 异常检测(红框框出图像异常区域)
- 特征提取(从图像中提取指定的特征)
相对深度自编码器的改进: 提高对异常数据的敏感程度,即两极分化正常样本和异常样本的重构误差。
模型
-
编码器(Encoder)
$$ z = f_e(x; \theta_e) $$
$\theta_e$表示 Encoder 网络的权重,$f_e(x; \theta_e)$表示对输入变量 x 进行编码操作,降维输入图像张量
-
记忆模块(Memory Module)
-
解码器(Decoder) $$ \hat{x} = f_d(\hat{z}; \theta_d) $$ $\theta_d$表示 Decoder 网络的权重,$f_d(\hat{z}; \theta_d)$表示对输入变量$\hat{z}$进行解码操作,将数据还原成图像
可视化数据
基于 PyTorch 的 PCA 简单实现 主成分分析(PCA)降维原理、特征值分解与 SVD 分解 PCA 的原理和 pytorch 实现 Python 实现 PCA 降维
记忆模块
下面具体介绍 MemAE 的记忆模块。
memory 为一个包含 N 个行向量的矩阵$\pmb{M} \in R^{N \times C}$,每个行向量$m_i$表示 M 记忆模块的行。
记忆模块的计算流程如下:
- 编码器输出张量 z 和记忆矩阵 M 内积和 softmax 归一化,输出$\omega$ $$ \omega = \frac{exp(z * m_i)}{\sum_{i=1}^{N} z *m_i} $$
说明: 论文公布的源代码里面没有使用论文描述的余弦相似度,而是输入值和记忆模块内积,再进行 softmax。作者的回答是使用余弦相似度,导致$\omega$全都趋近 0,所以作者认为余弦相似度不适合该模型,所以改用矩阵内积。所以这里把计算公式修改成与源代码一致。 https://github.com/donggong1/memae-anomaly-detection/issues/12#issuecomment-659951371 2. 利用设定阈值$\lambda$,对$\omega$进行稀疏化,低于阈值$\lambda$的元素置 0。
$$ \hat{\omega_i} = \frac{max(\omega_i-\lambda,0)\omega_i}{|\omega_i-\lambda|+\varepsilon} $$
记忆模块的损失函数:
$$ E(\hat{\omega^t})=\sum^{T}_{i=1}-\hat{\omega} *log(\hat{\omega_i}) $$
损失函数是个针对记忆模块 1 的计算结果权重的信息熵,增加$\omega$的稀疏性,限制特征的个数,实现降维的同时,避免不重要信息的影响。
表示一个记忆力元素(memory item),维度为 C,等于编码器输出特征 z 的维度。因此通过记忆网络得到 query 可以表示为:
损失函数
熵函数取最小,提高记忆模块的稀疏性,增加模型的约束条件,避免过拟合
$$ L\left(\theta_{e}, \theta_{d}, \mathbf{M}\right)=\frac{1}{T} \sum_{t=1}^{T}\left(R\left(\mathbf{x}^{t}, \hat{\mathbf{x}}^{t}\right)+\alpha E\left(\widehat{\mathbf{w}}^{t}\right)\right) $$
其中$R=|\mathrm{x}-\widehat{\mathrm{x}}|_{2}^{2}$表示重构误差,超参数$ \alpha $原文作者选择的是 0.0002
源代码分析
数据集
- minist 数据集(图像数据集,手写体,PyTorch 等深度学习框基本自带)
- UCSD Anomaly Detection Dataset(视频数据集,视频流的图片都提取出来,加利福尼亚大学圣迭戈分校提供的异常检测数据集,非步行和异常步行视为异常,比如骑自行车、滑板、开车、轮椅等等)
mnist 数据集比较常用,就不介绍了。
UCSD 数据集是固定摄像头记录的行人视频,视频拆分成图片。UCSD 划分为两个子集,对应不同的场景。每个子集划分为训练集和测试集,训练集都是正常样本,测试集中夹杂者异常样本,同时记录异常数据所在图像的区域。 UCSD 数据集预处理:
-
tif 格式文件转 jpg(tif 和 jpg 是一种图片格式文件)
-
测试集异常图片提取标签
-
设定条件提取视频数据
模型
模型主要架构如开头所示,自编码器的编码器和解码器之间增加一个缓冲区(记忆模块),自编码器部分流程和神经网络训练基本一致,这里主要分析下记忆模块部分。
记忆模块参数非负
|
|
hard shrinkage for sparse addressing(稀疏定位硬压缩)
提高记忆矩阵稀疏性,设定阈值,矩阵中低于阈值的参数直接设为 0
代码里面没有使用论文中的余弦相似度,而是输入值和记忆模块内积,再进行 softmax,作者的回答是使用余弦相似度,导致记忆模块权重全都趋近 0,所以作者认为余弦相似度不适合该模型,所以改用矩阵内积
为了能够反向传播和简便性,这里使用 ReLU 激活函数筛选矩阵参数 hard_shrink_relu:
$$ \frac{max(\omega_i-\lambda,0)}{|\omega_i-\lambda|+\epsilon} $$
mnist 数据集训练
mem_dim: 记忆模块大小 正常样本标签为 0,异常样本为 1
cifar10
数据结果展示
当前项目
需要可视化训练过程
重构误差函数需要进一步改良
记忆自编码器无监督转有监督学习
实际上这是一个错误的改进方法,因为有监督学习不适合异常检测。现实生活中,异常发生机率非常小,数据难采集,而且异常样本不可预测,这些条件直接拒绝了有监督学习的应用。 不过,本人做完了才意识到,所以还是记录下。
有监督反向训练损失函数方法
参考论文: Deep Semi-Supervised Anomaly Detection
|
|
批处理操作,会对影响 ROC_AUC 指标有影响,原因是使用 PyTorch 自带损失函数,默认是批处理里的数据求和,跟手动编写的函数不一样
- 训练输入异常样本时,原来的损失函数添加负号。发现,这个跟损失函数
- 异常样本输入,损失函数取倒数
无监督转半监督
FAQ
Python pytorch 多进程运行
扩展资料
个人猜想
-
不在编码器和解码器之间增加记忆模块,而是在其他地方增加,是否会取得更好的效果
-
编码器之间增加 skip connection
-
中间输入增加随机噪声
-
新模型的改进不会只拘泥于一个旧模型,可以是其他模型,比如降噪自编码器的功能是剔除原有数据的噪声,通过无监督学习的方法,这个功能在原有自编码器功能上是没有,完全是基于功能进行改进的
-
编码器中间还是结尾增加 SVDD 模块
pretrain 只用了 mse,训练的时候增加了记忆模块和 svdd test 只用了 mse
r6. 经历了 3 次碰撞, 0.048ms p8. a. (1-1/N)^(N-1),. p=1/N b. 1/e=0.37 p9. max(p(1-p)^2(N-1))-1/2e
使用自己的网络模型,分别测试 svdd、autoencoder、mvdd 等方法 IAED 的网络模型和 Deep SVDD 的网络模型不一样
文章作者 crazyn2
上次更新 2022-07-29