簡體   English   中英

在 keras 后端的 K.sum 中,axis=[1,2,3] 是什么意思?

[英]What does axis=[1,2,3] mean in K.sum in keras backend?

我正在嘗試為我的 CNN 模型實現自定義損失函數。 我找到了一個IPython notebook ,里面實現了一個自定義的損失函數,名為Dice,如下:

from keras import backend as K
smooth = 1.

def dice_coef(y_true, y_pred, smooth=1):
    intersection = K.sum(y_true * y_pred, axis=[1,2,3])
    union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3])
    return K.mean( (2. * intersection + smooth) / (union + smooth), axis=0)

def bce_dice(y_true, y_pred):
    return binary_crossentropy(y_true, y_pred)-K.log(dice_coef(y_true, y_pred))

def true_positive_rate(y_true, y_pred):
    return K.sum(K.flatten(y_true)*K.flatten(K.round(y_pred)))/K.sum(y_true)

seg_model.compile(optimizer = 'adam', 
              loss = bce_dice, 
              metrics = ['binary_accuracy', dice_coef, true_positive_rate])

我之前從未使用過 keras 后端,並且真的對 keras 后端的矩陣計算感到困惑。 所以,我創建了一些張量來查看代碼中發生了什么:

val1 = np.arange(24).reshape((4, 6))
y_true = K.variable(value=val1)

val2 = np.arange(10,34).reshape((4, 6))
y_pred = K.variable(value=val2)

現在我運行dice_coef函數:

result = K.eval(dice_coef(y_true=y_true, y_pred=y_pred))
print('result is:', result)

但它給了我這個錯誤:

ValueError: Invalid reduction dimension 2 for input with 2 dimensions. for 'Sum_32' (op: 'Sum') with input shapes: [4,6], [3] and with computed input tensors: input[1] = <1 2 3>.

然后我將所有[1,2,3]更改為-1 ,如下所示:

def dice_coef(y_true, y_pred, smooth=1):
    intersection = K.sum(y_true * y_pred, axis=-1)
    # intersection = K.sum(y_true * y_pred, axis=[1,2,3])
    # union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3])
    union = K.sum(y_true, axis=-1) + K.sum(y_pred, axis=-1)
    return K.mean( (2. * intersection + smooth) / (union + smooth), axis=0)

現在它給了我一個價值。

result is: 14.7911625

問題:

  1. 什么是[1,2,3]
  2. 為什么當我將[1,2,3]更改為-1時代碼有效?
  3. 這個dice_coef函數有什么作用?

就像在 numpy 中一樣,您可以定義要執行某個操作的軸。 例如,對於 4d 數組,我們可以像這樣沿特定軸求和

>>> a = np.arange(150).reshape((2, 3, 5, 5))
>>> a.sum(axis=0).shape
(3, 5, 5)
>>> a.sum(axis=0, keepdims=True).shape
(1, 3, 5, 5)
>>> a.sum(axis=1, keepdims=True).shape
(2, 1, 5, 5)

如果我們提供一個元組,我們可以沿多個軸執行此操作。

>>> a.sum(axis=(1, 2, 3), keepdims=True).shape
(2, 1, 1, 1)

如果參數為-1 ,則默認在最后一個軸上執行操作,無論有多少個軸。

>>> a.sum(axis=-1, keepdims=True).shape
(2, 3, 5, 1)

這應該澄清了第 1 點和第 2 點。由於軸參數是(1, 2, 3) ,因此您至少需要 4 個軸才能使操作有效。 嘗試將您的變量更改為val1 = np.arange(24).reshape((2, 2, 2, 3))東西,一切正常。

該模型似乎計算二元交叉熵 Dice 損失和dice_coeff() ,顧名思義,計算Dice 系數 我不確定smooth的目的是什么,但如果它是為了避免除以 0,你會期望一個小數字,比如 1e-6。

什么是 [1,2,3]?

這些數字指定了我們想要求和的維度。 最小的數字表示外部尺寸,最大的數字表示內部尺寸。 看例子:

import tensorflow as tf

tf.enable_eager_execution()

    a = tf.constant([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])

    print(tf.reduce_sum(a, axis=2).numpy())
    #[[ 3  7]
    # [11 15]]
    print(tf.reduce_sum(a, axis=1).numpy())
    #[[ 4  6]
    # [12 14]]
    print(tf.reduce_sum(a, axis=0).numpy())
    #[[ 6  8]
    # [10 12]]

在上面的示例中, axis = 2表示內部條目是:[1,2]、[3,4]、[5,6] 和 [7,8]。 結果,求和后,我們得到了張量: [[3, 7], [11, 15]] 同樣的想法適用於其他軸。

為什么當我將 [1,2,3] 更改為 -1 時代碼有效

當我們沒有指定任何軸或另一方面指定所有軸時,意味着我們對所有張量元素求和。 這導致我們的張量轉換為單個標量。 見示例:

a = tf.constant([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(tf.reduce_sum(a).numpy()) # 36
print(tf.reduce_sum(a, axis=[0,1,2])) # 36

如果我們有 3 個維度 [0, 1, 2], axis = -1等於axis = 2 有關 python 索引的完整教程,請參見此處

這個 dice_coef 函數有什么作用?

在此處輸入圖片說明

有關 dice_coef 的完整說明,請參見此處

你問題的前兩部分已經解釋過了。 我會解釋最后一個。

  • 這個 dice_coef 函數有什么作用?

dice_coef 函數是計算骰子相似系數,它是一個損失函數。 我將解釋圖像分割任務的上下文,因此骰子相似系數是衡量兩個輪廓重疊程度的指標。

img 來源:Coursera

它的值范圍從 0 到 1。

  • 0 表示完全不匹配,即它們根本不重疊
  • 1 表示完美匹配,即它們完全重疊

一般來說,對於兩組A和B,Dice相似系數定義為:

DSC(A,B)=( 2 × |A ∩ B| ) / ( |A|+|B| )。

為了避免被零除,添加了一個很小的數 ϵ

DSC(A,B)= ( 2 × |A ∩ B| + ϵ ) / ( |A| + |B|+ ϵ )。

在你的情況下:

  • A 是 y_true

  • B 是 y_pred

  • ϵ 是平滑的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM