如何在變分自動編碼器中加權 KLD 損失與重建損失
在我見過的幾乎所有關於 VAE 的代碼示例中,損失函數的定義如下(這是 tensorflow 代碼,但我在 theano、torch 等方面也看到過類似的情況。它也適用於 convnet,但這也不太相關,只影響總和被接管的軸):
# latent space loss. KL divergence between latent space distribution and unit gaussian, for each batch. # first half of eq 10. in https://arxiv.org/abs/1312.6114 kl_loss = -0.5 * tf.reduce_sum(1 + log_sigma_sq - tf.square(mu) - tf.exp(log_sigma_sq), axis=1) # reconstruction error, using pixel-wise L2 loss, for each batch rec_loss = tf.reduce_sum(tf.squared_difference(y, x), axis=[1,2,3]) # or binary cross entropy (assuming 0...1 values) y = tf.clip_by_value(y, 1e-8, 1-1e-8) # prevent nan on log(0) rec_loss = -tf.reduce_sum(x * tf.log(y) + (1-x) * tf.log(1-y), axis=[1,2,3]) # sum the two and average over batches loss = tf.reduce_mean(kl_loss + rec_loss)
然而 kl_loss 和 rec_loss 的數值範圍分別非常依賴於潛在空間暗淡和輸入特徵大小(例如像素分辨率)。用 reduce_mean 替換 reduce_sum 以獲得每個 z-dim KLD 和每個像素(或特徵)LSE 或 BCE 是否明智?更重要的是,在對最終損失求和時,我們如何對潛在損失和重建損失進行加權?這只是反複試驗嗎?還是有一些理論(或至少是經驗法則)?我在任何地方都找不到有關此的任何信息(包括原始論文)。
我遇到的問題是,如果我的輸入特徵 (x) 維度和潛在空間 (z) 維度之間的平衡不是“最佳”,那麼我的重建要么非常好,但學習到的潛在空間是非結構化的(如果 x 維度非常高並且重建誤差優於 KLD),反之亦然(重建不好,但如果 KLD 占主導地位,則學習到的潛在空間結構良好)。
我發現自己必須對重建損失(除以輸入特徵大小)和 KLD(除以 z 維度)進行歸一化,然後用任意權重因子手動加權 KLD 項(歸一化是為了讓我可以使用相同的或與x 或 z 的尺寸無關的相似重量)。根據經驗,我發現 0.1 左右可以在重建和結構化潛在空間之間提供良好的平衡,這對我來說就像一個“甜蜜點”。我正在尋找該領域的先前工作。
根據要求,上述數學符號(專注於重構誤差的 L2 損失)
在哪裡是潛在向量的維數(和相應的平均值和方差),是輸入特徵的維度,是小批量大小,上標表示數據點和是損失小批量。
對於任何偶然發現這篇文章也正在尋找答案的人來說,這個 twitter 線程增加了很多非常有用的見解。
即:
通過一些實驗討論了我的確切問題。有趣的是,他們的(類似於我的歸一化 KLD 權重)也以 0.1 為中心,較高的值會以較差的重建為代價提供更多結構化的潛在空間,較低的值會以較少的結構化潛在空間提供更好的重建(儘管他們的重點是學習解開的表示)。
和相關閱讀(討論類似問題的地方)