使用tensorflow2.x解決離散分佈之間的KL散度

寫在前面

  • 我看了一下keras文檔,想了解一下如何方便的計算KL散度,於是發現了一點線索。Keras文檔只寫了離散分佈的KL散度,它們不寫連續分佈的KL散度庫函數是有原因的,連續分佈太過於複雜,不同分佈之間有着不同的公式,無法統一。而離散分佈就有統一公式,只需要給出分佈律就能計算。

KLDivergence class

  • 用來計算y_true和y_predict之間的KL散度
  • loss = y_true * log(y_true / y_pred)
tf.keras.losses.KLDivergence(reduction="auto", name="kl_divergence")

Args:
y_true: Ground truth values. shape = [batch_size, d0, .. dN]
y_pred: The predicted values. shape = [batch_size, d0, .. dN]

  • 下面給出幾種KL散度的不同形式(怎麼去求)

1.auto/sum_over_batch_size:在batch_size上求和,即求出每個樣本的分佈律,然後求和。

>>> y_true = [[0, 1], [0, 0]]
>>> y_pred = [[0.6, 0.4], [0.4, 0.6]]
>>> # Using 'auto'/'sum_over_batch_size' reduction type.  
>>> kl = tf.keras.losses.KLDivergence()
>>> kl(y_true, y_pred).numpy()
0.458

2.sum:全部求和

>>> # Using 'sum' reduction type.  
>>> kl = tf.keras.losses.KLDivergence(
...     reduction=tf.keras.losses.Reduction.SUM)
>>> kl(y_true, y_pred).numpy()
0.916

3.None:不做任何形狀的改變,最後的shape爲(batch_size,)

>>> # Using 'none' reduction type.  
>>> kl = tf.keras.losses.KLDivergence(
...     reduction=tf.keras.losses.Reduction.NONE)
>>> kl(y_true, y_pred).numpy()
array([0.916, -3.08e-06], dtype=float32)

kl_divergence function

  • 用法和上面的差不多
tf.keras.losses.kl_divergence(y_true, y_pred)
>>> y_true = np.random.randint(0, 2, size=(2, 3)).astype(np.float64)
>>> y_pred = np.random.random(size=(2, 3))
>>> loss = tf.keras.losses.kullback_leibler_divergence(y_true, y_pred)
>>> assert loss.shape == (2,)
>>> y_true = tf.keras.backend.clip(y_true, 1e-7, 1)
>>> y_pred = tf.keras.backend.clip(y_pred, 1e-7, 1)
>>> assert np.array_equal(
...     loss.numpy(), np.sum(y_true * np.log(y_true / y_pred), axis=-1))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章