python - (变分)自编码器中异常阈值的实际确定
问题描述
虽然严格来说不是一个编程问题,但我在这个网站上没有找到关于这个主题的任何内容。我目前正在处理(变分)自动编码器((V)AE),并计划部署它们来检测异常。出于测试目的,我在 tensorflow 中实现了一个 VAE 来检测手写数字。
训练进行得很顺利,重建的图像与原始图像非常相似。但是对于实际使用自动编码器,我必须通过将其与阈值进行比较来确定输入自动编码器的新图像是否为数字。
在这一点上,我有两个主要问题:
1.) 对于训练,我使用了由两个组件组成的损失。第一个是重建误差,它是一个交叉熵函数:
# x: actual input
# x_hat: reconstructed input
epsilon = 1e-10 # <-- small number for numeric stability within log
recons_loss = - f.reduce_sum( x * tf.log( epsilon + x_hat) + (1 - x) * tf.log( epsilon + 1 - x_hat),
axis=1)
第二个是 KL 散度,它衡量两个概率分布的相似程度,因为我们要求潜在变量空间是类似于高斯分布的分布。
# z_mean: vector representing the means of the latent distribution
# z_log_var: vector representing the variances of the latent distribution
KL_div = -0.5 * tf.reduce_sum( 1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var),
axis=1)
为了确定新图像的重建误差,我是否必须使用训练损失的两个部分?直觉上,我会说不,只是使用 recon_loss。
2.)如何确定阈值?是否已经实现了我可以使用的 tf 功能?
如果您有任何相关内容的良好来源,请分享链接!
谢谢!
解决方案
我最近遇到了类似的问题。VAE 非常擅长将高维数据投影到低维潜在空间中。改变潜在向量并将其馈送到解码器部分会创建新样本。
我希望我的问题是正确的,您尝试在低维潜在空间上使用编码器部分进行异常检测?
我猜你已经在 MNIST 上训练了你的 VAE。您可以做的是获取 MNIST 数字的所有潜在向量,并通过与它们的欧几里得距离比较新数字的潜在向量。阈值将是您设置的最大距离。
代码将是这样的:
x_mnist_encoded = encoder.predict(x_mnist, batch_size=batch_size) #array of MNIST latent vectors
test_digit_encoded = encoder.predict(x_testdigit, batch_size=1) #your testdigit latent vector
#calc the distance
from scipy.spatial import distance
threshold = 0.3 #min eucledian distance
for vector in x_mnist_encoded:
dst = distance.euclidean(vector,test_digit_encoded[0])
if dst <= threshold:
return True
VAE 代码来自https://blog.keras.io/building-autoencoders-in-keras.html
推荐阅读
- python - 获取给定时间字符串和时区的 UTC 时间
- azure - 使用带有 ActiveDirectoryClient 的 https://graph.microsoft.com 将用户添加到 Azure Active Directory
- python - 计算特定单词
- c++ - 无法理解为什么这个简单的递归正在工作并且崩溃
- .htaccess - REQUEST_URI 不匹配显式路径和文件名
- javascript - 我想通过点击文本 id 来阅读
- javascript - 如何在突出显示输入、拖动、释放时保持下拉菜单打开?
- telegram - 我在我的电报机器人 API 上找不到任何东西
- reactjs - Jest 无法导入 ts/tsx 模块
- c# - 将 Json 字符串反序列化为枚举 C#