我使用Autoencoder构建了一个异常检测系统,在keras中实现。我的输入是一个长度为13的归一化向量。我的数据集包含大约25000个非异常输入,专门用于学习。在学习了1-3个时期后,我得到了大约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
如何改进异常检测?
问题可能是您;"炸毁";你是自动编码器。您有一个13的输入,然后再次将其映射到200、150、100和13。网络中不存在必须学习输入的压缩表示的瓶颈。
也许试试13->6->4->6->13之类的。然后,它获得了一个压缩的表示,重建输入的任务不再是琐碎的。
此外,还可以使用其他超参数,如激活函数。也许在中间模型中将其更改为"relu"。