使用 Keras 进行异常检测 - 低预测率
Posted
技术标签:
【中文标题】使用 Keras 进行异常检测 - 低预测率【英文标题】:Anomaly Detection Using Keras - Low Prediction Rate 【发布时间】:2021-03-24 07:26:39 【问题描述】:我使用自动编码器构建了一个异常检测系统,在 keras 中实现。 我的输入是一个长度为 13 的归一化向量。 我的数据集包含大约 25,000 个非异常输入,专门用于学习。 在学习了 1-3 个 epoch 后,我得到了大约 10^-5 MSE。 问题是,虽然我得到了一个小的 MSE,但我的 AE 无法检测到足够好的异常...... 模型类:
class AutoEncoder:
def __init__(self, inputLen, modelName,Batch,epochs):
self.modelName = modelName
self.DL_BATCH_SIZE = Batch
self.DL_EPOCHS = epochs
self.DL_LAYER1 = 200
self.DL_LAYER2 = 150
self.DL_LAYER3 = 100
self.DL_LAYEROUT = 13
self.DL_LOADMODEL = None
#self.DL_SAVEMODEL = fileConfig.getConfigParam(DL_SAVEMODEL)
#print(tensorflow.version.VERSION)
if self.DL_LOADMODEL == None or self.DL_LOADMODEL == 0:
my_init = keras.initializers.glorot_uniform(seed=1)
self.dlModel = keras.models.Sequential()
self.dlModel.add(keras.layers.Dense(units=self.DL_LAYER1, activation='tanh', input_dim=inputLen,kernel_initializer=my_init))
self.dlModel.add(keras.layers.Dense(units=self.DL_LAYER2, activation='tanh',kernel_initializer=my_init))
self.dlModel.add(keras.layers.Dense(units=self.DL_LAYER3, activation='tanh',kernel_initializer=my_init))
self.dlModel.add(keras.layers.Dense(units=self.DL_LAYER2, activation='tanh',kernel_initializer=my_init))
self.dlModel.add(keras.layers.Dense(units=self.DL_LAYER1, activation='tanh',kernel_initializer=my_init))
self.dlModel.add(keras.layers.Dense(units=self.DL_LAYEROUT, activation='tanh',kernel_initializer=my_init))
#sgd = keras.optimizers.SGD(lr=0.0001, decay=0.0005, momentum=0, nesterov=True)
#adam = keras.optimizers.Adam(learning_rate=0.005,decay=0.005)
simple_adam=keras.optimizers.Adam()
self.dlModel.compile(loss='mse', optimizer=simple_adam, metrics=['accuracy'])
else:
self.dlModel = keras.models.load_model(self.DL_LOADMODEL + ".h5")
训练后,我在 2500 个非异常的特定数据集上找到了最大重建 MSE。 然后我测试我的异常检测器并将其重建的每个输入都标记为异常,该输入超过最大 MSE*0.9 值。 找到最大误差:
N = len(non_anomaly)
max_se = 0.0;
max_ix = 0
second_max=0
predicteds = kerasNN.predict(non_anomaly)
for i in range(N):
curr_se = np.square(np.subtract(non_anomaly[i],predicteds[i])).mean()
if curr_se > max_se:
second_max=max_se
max_se = curr_se;
max_ix = i
测试模型:
predicteds=kerasNN.predict(x_train_temp)
#errors vector generation
anomaly_binary_vector = []
i=0
anomalies=0
for x_original,x_reconstructed in zip(x_train_temp,predicteds):
MSE=np.square(np.subtract(x_original,x_reconstructed)).mean()
if(MSE>=0.95*max_se):
anomaly_binary_vector.append(1)
else:
anomaly_binary_vector.append(0)
i+=1
输出:
anomalies 2419
not detected anomalies 2031
non anomaly but marked as anomaly 2383
percentage of non anomaly instructions that marked as anomalies out of non anomalies : 0.3143384777733808
percentage of anomaly instructions that wasn't detected out of anomalies: 0.8396031417941298
如何改进我的异常检测?
【问题讨论】:
您是否也使用正常数据训练了您的模型,还是只看到了异常? 您应该绘制异常分数的直方图,标记的异常和非异常的颜色不同。然后你会看到你的模型能够区分两者 【参考方案1】:一个问题可能是你正在“炸毁”你是自动编码器。您的输入为 13,然后再次将其映射到 200、150、100 和 13。网络中没有瓶颈,它必须学习输入的压缩表示。
也许尝试 13 -> 6 -> 4 -> 6 -> 13 或类似的东西。比它学习压缩表示和重建输入的任务不再是微不足道的。
另外使用其他超参数,如激活函数。也许在中间模型中将其更改为“relu”。
【讨论】:
首先,感谢您的回答。通过将层的宽度更改为 13->6>4>6>13,我没有得到改进。并通过将“中间”层更改为 relu ... 10^-5 MSE 不够准确以检测异常吗? 不看数据很难说。您是否尝试过其他一些分类器来检测异常值,例如“隔离森林”或“Oneclass SVM”?如果是这样,他们的表现如何?也许数据只是不适合这种任务 没有。我会尝试 。不适合这种任务是指一般的异常检测或特别是 AE? 是的,我指的是一般的异常检测。但我想如果它至少在某种程度上适用于其他技术,那么可能有办法让它也适用于 AE。以上是关于使用 Keras 进行异常检测 - 低预测率的主要内容,如果未能解决你的问题,请参考以下文章
CNN autoencoder 进行异常检测——TODO,使用keras进行测试