【问题标题】:how to calculate entropy on float numbers over a tensor in python keras如何在python keras中计算张量上浮点数的熵
【发布时间】:2019-10-11 21:36:57
【问题描述】:

我一直在努力解决这个问题,但无法让它发挥作用。希望有人可以帮助我。

我想计算tensor 每一行的entropy因为我的数据是浮点数而不是整数,所以我认为我需要使用 bin_histogram。

例如我的数据样本是tensor =[[0.2, -0.1, 1],[2.09,-1.4,0.9]]

仅供参考我的模型是seq2seq,用keras 编写,带有tensorflow 后端。

这是我目前的代码:我需要更正rev_entropy

class entropy_measure(Layer):

    def __init__(self, beta,batch, **kwargs):
        self.beta = beta
        self.batch = batch
        self.uses_learning_phase = True
        self.supports_masking = True
        super(entropy_measure, self).__init__(**kwargs)

    def call(self, x):
        return K.in_train_phase(self.rev_entropy(x, self.beta,self.batch), x)

    def get_config(self):
        config = {'beta': self.beta}
        base_config = super(entropy_measure, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

    def rev_entropy(self, x, beta,batch):

        for i in x:
            i = pd.Series(i)
            p_data = i.value_counts()  # counts occurrence of each value
            entropy = entropy(p_data)  # get entropy from counts
            rev = 1/(1+entropy)
            return rev

        new_f_w_t = x * (rev.reshape(rev.shape[0], 1))*beta

        return new_f_w_t

非常感谢任何输入:)

【问题讨论】:

    标签: numpy tensorflow keras scipy entropy


    【解决方案1】:

    看起来你有一系列关于这个问题的问题。我会在这里解决的。

    你根据你的代码计算entropyscipy.stats.entropy如下形式:

    scipy.stats.entropy(pk, qk=None, base=None)

    计算给定概率值的分布熵。

    如果只给出概率pk,熵计算为S = -sum(pk * log(pk),axis=0).

    Tensorflow 不提供直接 API 来计算张量每一行的entropy。我们要做的就是实现上面的公式。

    import tensorflow as tf
    import pandas as pd
    from scipy.stats import entropy
    
    a = [1.1,2.2,3.3,4.4,2.2,3.3]
    res = entropy(pd.value_counts(a))
    
    _, _, count = tf.unique_with_counts(tf.constant(a))
    # [1 2 2 1]
    prob = count / tf.reduce_sum(count)
    # [0.16666667 0.33333333 0.33333333 0.16666667]
    tf_res = -tf.reduce_sum(prob * tf.log(prob))
    
    with tf.Session() as sess:
        print('scipy version: \n',res)
        print('tensorflow version: \n',sess.run(tf_res))
    
    scipy version: 
     1.329661348854758
    tensorflow version: 
     1.3296613488547582
    

    然后我们需要定义一个函数,按照上面的代码在你的自定义层中通过tf.map_fn实现for loop

    def rev_entropy(self, x, beta,batch):
        def row_entropy(row):
            _, _, count = tf.unique_with_counts(row)
            prob = count / tf.reduce_sum(count)
            return -tf.reduce_sum(prob * tf.log(prob))
    
        value_ranges = [-10.0, 100.0]
        nbins = 50
        new_f_w_t = tf.histogram_fixed_width_bins(x, value_ranges, nbins)
        rev = tf.map_fn(row_entropy, new_f_w_t,dtype=tf.float32)
    
        new_f_w_t = x * 1/(1+rev)*beta
    
        return new_f_w_t
    

    请注意,隐藏层不会产生无法向后传播的梯度,因为entropy 是根据统计概率值计算得出的。也许你需要重新考虑你的隐藏层结构。

    【讨论】:

    • 非常感谢,你是救生员 :),你是如何在不使用 bin_histogram 的情况下计算实数的熵的?你知道我的意思,问题是我没有整数,它们是浮点数,这就是我说微分熵的原因。我认为微分熵也可能无济于事,因为变量的总和必须为 1,在我的情况下这不是真的。这就是为什么我需要在计算最终熵之前首先使用 bin_histogram 。我说得有道理吗?
    • 您能否更改您的答案以包括 value_ranges = [-10.0, 100.0] nbins = 50 new_f_w_t = tf.histogram_fixed_width_bins(x, value_ranges, nbins) rev = tf.map_fn(row_entropy, new_f_w_t) 所以我可以接受作为接受的答案吗?
    • 我还有一个问题。在“row_entropy”之后,张量的形状从 (?,20) 变为 (?,) 这就是为什么我收到错误消息 ValueError: Input 0 is incompatible with layer repeater: expected ndim=2, found ndim=None 。您对此有任何想法/意见吗?谢谢你:)
    • @sariii entropy 与实数无关,而是与它们的分布有关。比如我把[1,2,3,4,2,3]改成[1.1,2.2,3.3,4.4,2.2,3.3]不影响entropy的值。你的ValueError 出现在哪一行?
    • @sariii 我的意思是entropy 是根据概率值而不是实数值计算的。当然,如果你想把数据放在同一个bin里,我会改成bin_histogram
    猜你喜欢
    • 2017-10-22
    • 2022-01-05
    • 2022-01-07
    • 2017-10-06
    • 2023-04-03
    • 2020-02-23
    • 2018-07-07
    • 2013-06-10
    • 1970-01-01
    相关资源
    最近更新 更多