1. 程式人生 > >VAE----變分自編碼器Keras實現

VAE----變分自編碼器Keras實現

這篇部落格用來記錄我自己用keras實現(抄寫)VAE過程中,掉進的一個坑。。。。。。
最近這幾天在網上看了很多VAE的介紹,並且看了一下keras中的實現。自我感覺良好,就想按著官方的程式碼自己也去寫一遍。不寫不知道,一寫嚇一跳!!我跳進了一個很大坑中(笑哭),我在把程式碼寫完以後,開始訓練模型,發現程式碼報出如下錯誤。

InvalidArgumentError: Incompatible shapes: [64,784] vs. [64]
	 [[Node: add_3 = Add[T=DT_FLOAT, _class=["loc:@training_1/Adam/gradients/add_3_grad/Reshape"], _device="/job:localhost/replica:0/task:0/device:CPU:0"](logistic_loss_1, Sum_2)]]

維度不匹配嗎這不是,於是我非常認真仔細的開始找錯誤的原因,找了好久也沒發現哪裡維度不匹配,我跟keras中實現的VAE開始一行一行的比對自己定義的模型,並且都都把模型的結構都畫了出來,發現完全一樣,這就讓我納悶了。。。憋的我都想哭。到底哪裡出了問題呢?(抓狂)
鬼知道我找了多久,我終於發現了問題所在,原來是重構誤差定義的問題,官方中實現的方式是用的from keras.losses import binary_crossentropy中的交叉熵損失,而我用的是K.binary_crossentropy(我是TensorFlow的後端),我把重構誤差改成keras中的交叉熵損失後,OK!問題解決。(神清氣爽!!)
我查了一下Keras中和TensorFlow中這binary_crossentropy的原始碼,如下:

# keras.losses
def binary_crossentropy(y_true, y_pred):
    return K.mean(K.binary_crossentropy(y_true, y_pred), axis=-1) 
	
# tensorflow 後端
def binary_crossentropy(target, output, from_logits=False):
    return tf.nn.sigmoid_cross_entropy_with_logits(labels=target,
                                                   logits=output)

keras中雖然也是呼叫的TensorFlow中的方法,但是它求均值了(劃重點),當然shape不匹配了。。如果還想繼續使用K.binary_crossentropy那麼定義重構損失如下:

reconstruction_loss = K.sum(K.binary_crossentropy(inputs, outputs), axis=-1)

官方提供示例中的定義:

reconstruction_loss = binary_crossentropy(inputs, outputs) * original_dim

由於keras中求了平均,所以還得乘以原來的維度,變成求和(何必呢。。。)

看來以後看程式碼還得仔細加認真啊。。。。由於現在框架眾多,隱藏了太多的細節,所以看一看原始碼還是很有必要的,要不遇到大坑,都不知道什麼情況。(好氣啊。。。),努力!!!