当前位置:  开发笔记 > 编程语言 > 正文

TensorFlow中的KL分歧

如何解决《TensorFlow中的KL分歧》经验,为你挑选了3个好方法。

我有两个张量,prob_aprob_b与形状[None, 1000],我想从计算KL散prob_aprob_b.TensorFlow中是否有内置功能?我尝试过使用tf.contrib.distributions.kl(prob_a, prob_b)但它给出了:

prob_a

如果没有内置功能,那么什么是好的解决方法?



1> meferne..:

假设您的输入张量prob_a并且prob_b是沿第一轴总和为1的概率张量,您可以这样做:

def kl(x, y):
    X = tf.distributions.Categorical(probs=x)
    Y = tf.distributions.Categorical(probs=y)
    return tf.distributions.kl_divergence(X, Y)

result = kl(prob_a, prob_b)

一个简单的例子:

import numpy as np
import tensorflow as tf
a = np.array([[0.25, 0.1, 0.65], [0.8, 0.15, 0.05]])
b = np.array([[0.7, 0.2, 0.1], [0.15, 0.8, 0.05]])
sess = tf.Session()
print(kl(a, b).eval(session=sess))  # [0.88995184 1.08808468]

你会得到相同的结果

np.sum(a * np.log(a / b), axis=1) 

但是,这个实现有点儿错误(在Tensorflow 1.8.0中检查).

如果您的概率为零a,例如,如果您尝试[0.8, 0.2, 0.0]而不是[0.8, 0.15, 0.05],则nan即使Kullback-Leibler定义0 * log(0 / b)应该归零,您也会得到.

为了缓解这个问题,我们应该添加一些小的数值常数.tf.distributions.kl_divergence(X, Y, allow_nan_stats=False)在这种情况下使用导致运行时错误也是谨慎的.

此外,如果有一些零b,您将获得infallow_nan_stats=False选项不会捕获的值,因此必须处理这些值.



2> 小智..:

因为有softmax_cross_entropy_with_logits,所以不需要在KL上进行优化.

KL(prob_a, prob_b)  
  = Sum(prob_a * log(prob_a/prob_b))  
  = Sum(prob_a * log(prob_a) - prob_a * log(prob_b))  
  = - Sum(prob_a * log(prob_b)) + Sum(prob_a * log(prob_a)) 
  = - Sum(prob_a * log(prob_b)) + const 
  = H(prob_a, prob_b) + const 



3> 小智..:

我不确定为什么它没有实现,但也许有一个解决方法.KL分歧定义为:

KL(prob_a, prob_b) = Sum(prob_a * log(prob_a/prob_b))

另一方面,交叉熵H定义为:

H(prob_a, prob_b) = -Sum(prob_a * log(prob_b))

因此,如果您创建一个变量y = prob_a/prob_b,您可以通过调用负数来获得KL分歧H(proba_a, y).在Tensorflow表示法中,类似于:

KL = tf.reduce_mean(-tf.nn.softmax_cross_entropy_with_logits(prob_a, y))

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有