前言
papers with code统计的在MVTec数据集上排名为20(截至博文发出时间),目前来看使用Normalizing Flow做主要思想的网络架构检测效果大都排在前列。本文主要通过源码针对DifferNet网络运行架构进行理解,未涉及到损失函数及实验相关介绍。
背景
网络的思想结合神经网络特征提取和标准化流进行密度估计的方式,解决传统方法利用高类内方差无法检测到缺陷的问题。
标准化流是能实现数据到密度估计转化的一种神经网络,特点是在两个方向上传播方便。仿射变换层的实现方式有两种(自回归和固定)。RealNVP是一种特殊的逆自回归流。本文使用RealNVP结构并设计了一个指数函数使训练更好收敛。
该网络对异常检测模型提出了一个分类基于生成模型的和基于预训练网络的。该网络是最先一批使用标准化流应用于异常检测的网络。.
源码原理(模型部分)
找准函数输入,理解主干函数,下面所述对照下图理解。
class DifferNet(nn.Module)
batchsize设置为24,经过图像增强后*4,即一次输入模型96张图片,注意96张图同时处理。每张图片分别下采样成1/1,1/2和1/4大小,之后三张下采样图片分别通过AlexNet网络提取特征,将提取的特征图每个通道的所有像素值求平均,由于是96张图同时处理,形成(96,256)张量,三张图cat后形成(96,768)张量。
def nf_head(input_dim=c.n_feat)
构建10个流块,8个NormalizingFlow流块,1个Input快,1个output块。8个流块是一致的结构:
(1)class permute_layer(nn.Module)
将0~768个数做两个乱序排列,这两个乱序排列之间有个规律,一个是随机乱序,另一个在随机乱序基础上做了另一种乱序。
(2)class glow_coupling_layer(nn.module)
将768维度分为两半(0~364,364~768),后一半经全连接激活后,s2,t2将后一半又各分一半,经原论文公式(1)与前一半生成768维度计算版。计算版经全连接激活后,s1,t1将计算版又各分一半,经原论文公式(1)与前一半计算生成最终版。将计算版与最终版以列的方式结合,并限制结合后的值范围。
1)class F_fully_connected(nn.Module)
四层全连接层,全连阶层设置有Dropout概率性减少神经元个数,防止过拟合,最后一层不设置激活函数,不设置Dropout。
2)def log_e(self,s)
前面提到的指数函数,原论文的公式(2),将维度的数值限制在(-3,3)之间。
tips(源码一些有意思的程序段)
(1)父类调用子类
源码段
if not self.input_dims: # Only do it if this hasn't been computed yet
self.input_dims = [n.build_modules(verbose=verbose)[c]
for n, c in self.inputs]
解释
self.inputs是InputNode.out0,回看InputNode类里self.out0 = (self, 0),也就是n代表self这个类本身,c代表0,通过build_modules函数返回输入维数768。
(2)96张图片张量形式转换(即torch.Size([24, 4, 3, 448, 448])-->torch.Size([96, 3, 448, 448]))
源码段
inputs = inputs.view(-1, *inputs.shape[-3:])
解释
*:代表实参传入
view:-1表示该处的数值未确定,根据后面已确定的数值进行确定,(24,4,...)到(96,...)由源码完成转换。