互信息的 Tensorflow 成对自定义损失

Tensorflow pairwise custom loss for mutual information

我正在学习如何使用 tensorflow,运行 在实现自定义损失函数时遇到了问题。具体来说,我正在尝试计算所有变量对之间的平均互信息(想法是确定一个 class 的哪些预测与另一个变量紧密相关)。

例如,如果我有一个数组

# In simple case, 2 entries of data showing predictions for non-exclusive
# properties A, B, C, and D in that order.
data = np.array([[0.99, 0.05, 0.85, 0.2], [0.97, 0.57, 0.88, 0.1]])

我想取回一个张量,显示 A 和 B、A 和 C、A 和 D、B 和 A 等之间的互信息,其中 A 是每个行向量的第一个元素,B 是第二个等。我也可以只获取每个变量的平均成对互信息(例如 MI(A, B)、MI(A, C) 和 MI(A, D) 的平均值)

我这样做的方法是计算每对变量的行间熵,然后单独减去每个变量的熵。

作为起点,我查看了用于计算两个变量的协方差的现有代码:

def tf_cov(x):
    mean_x = tf.reduce_mean(x, axis=0, keepdims=True)
    mx = tf.matmul(tf.transpose(mean_x), mean_x)
    vx = tf.matmul(tf.transpose(x), x)/tf.cast(tf.shape(x)[0], tf.float32)
    cov_xx = vx - mx
    return cov_xx

这是一个很好的例子,说明了如何获得成对统计数据,但它并没有得到我想要的指标。

我也可以计算单个变量的熵:

def tf_entropy(prob_a):
    # Calculates the entropy along each column
    col_entropy = tf.reduce_sum(prob_a * tf.log(prob_a), axis=0)

    return col_entropy

有谁知道计算成对熵的好方法吗?我想它看起来很像 matmul,但我不是计算元素乘积,而是计算熵。当然,如果您知道现有的 tensorflow 函数已经可以满足我的要求,那就太好了。我一直在阅读各种与熵相关的函数,但它们似乎从来都不是我想要的。

如果你想计算 X 和 Y 之间的互信息,这取决于你可以做出的基本假设。如果你有非常高维的数据和复杂的分布,我建议分箱,这是非参数的。我还使用了一些更复杂的方法。 参见 here, here and here

前两个并不能很好地扩展,最后一个涉及一些超参数调整,可以让你的数字完全消失(或者我做错了事),但扩展相对较好。