對batch求算loss時loss是張量形式或是標量有什么不同?


  • 一般情況下我們使用一個batch的數據計算出一個平均的loss,再使用這個loss反向傳播求得模型參數的梯度並更新,例如:

    loss = tf.reduce_mean(y - y_pred)	# 文中y和y_pred的shape均為:[b, 1],其中b是batch_size.
    

    這種情況比較好理解,loss只是一個值,其反向傳播時對於每個參數也值計算出一個梯度值。

  • 而如果我們沒有使用tf.reduce_mean()等類似求平均的操作,即:

    loss = y - y_pred
    

    求出的loss其shape是[b, 1]。即batch中的每一個樣本都有一個對應的loss值。這個時候如果我們繼續調用:

    grads = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(grads, model.trainable_variables))
    

    也不會報錯,不禁讓人疑惑這個tape.gradient()是怎么處理loss不是標量值的情況的。

  • 先說結論:當loss不是單值時tape.gradient(loss, variables)會首先針對loss中每一個單值對variables求梯度得到多套梯度。再對每套梯度對應元素求和合並為一套梯度返回。

  • 驗證:
    image
    image

  • 其他補充

    • tf.keras.losses.BinaryCrossentopy等大寫字母開頭的損失類在我們傳入y, y_pred時會自動對所有樣本的loss求平均,其返回一個標量的loss。
    • tf.keras.losses.binary_crossentropy()等小寫字母開頭的函數式接口在我們傳入y, y_pred時不會對所有樣本的loss求平均,其返回一個張量形式的losses,維度為[batch, 1]。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM