我一般都不熟悉Keras和神经网络。我正在尝试针对要用于异常检测的多层自动编码器实现基于均方误差的自定义损失函数。基本上,我要采用的方法是从这里https://www.jstage.jst.go.jp/article/ipsjjip/27/0/27_335/_pdf
不幸的是,我没有发布图像的声誉,因为我也是SO的新手,但是公式在第2页的第3节为Lprop
这里的直觉是,我不希望自动编码器为返回错误的损耗百分比以上的数据点更新权重。通过这种方式,它学会了在与异常值作斗争的同时重建数据集中的异常值,从而将其检测为异常。
这是我尝试过的一些代码和已编译的模型
import keras.backend as K
c = 70.0
def mean_squared_errorx(y_true, y_pred):
es = K.square(y_pred - y_true)
const = np.percentile(es, c)
w = K.cast(K.less(const, K.mean(K.square(y_pred - y_true), axis=-1)), dtype = "float32")
return w * K.mean(K.square(y_pred - y_true), axis=-1)
#'mean_squared_error'
autoencoder.compile(optimizer=adam, loss=mean_squared_errorx)
autoencoder.fit(train, train,
epochs=num_epochs,
batch_size=round(len(train)/50),
shuffle=True,
validation_data=(train, train),
verbose = 0)
encoded_d = encoder.predict(train)
decoded_pred = decoder.predict(encoded_d)
这个想法是让K.less为每个错误返回布尔值,然后将其转换为浮点数,以作为return语句中的权重。 我知道np.percentile部分可能无法在Tensor上使用,但不知道如何通过其他方法来完成百分位排名。
使用该代码,我会收到此错误消息
InvalidArgumentError: Incompatible shapes: [37,21] vs. [37]
[[{{node loss_25/dense_104_loss/Less}}]]
在这种情况下,批处理大小为37,功能数量为21。感谢您对此代码或其他部分的反馈-谢谢!
答案 0 :(得分:0)
找到了可能的解决方法,如果有人在做类似的事情
import keras.backend as K
def mean_squared_error_w(y_true, y_pred):
mses = K.mean(K.square(y_pred - y_true), axis = -1)
std_of_mses = K.std(mses)
const = K.mean(mses, axis = -1) + (std_of_mses * 0.5)
mask = K.cast(K.less(K.mean(K.square(y_pred - y_true), axis=-1), const), dtype = "float32")
return mask * K.mean(K.square(y_pred - y_true), axis=-1)
我相信这将为错误发生的所有值创建布尔张量 大于阈值,该阈值由批量MSE的平均值加标准偏差的一半定义(如果误差是正态分布的,则该值应约等于截止值的数据的70%)。它将布尔值转换为权重0或1作为掩码,然后将其应用于输出的MSE损失