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

Mus*_*ser 5 python conv-neural-network keras tensorflow

我正在尝试为我的 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])
Run Code Online (Sandbox Code Playgroud)

我之前从未使用过 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)
Run Code Online (Sandbox Code Playgroud)

现在我运行这个dice_coef函数:

result = K.eval(dice_coef(y_true=y_true, y_pred=y_pred))
print('result is:', result)
Run Code Online (Sandbox Code Playgroud)

但它给了我这个错误:

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>.
Run Code Online (Sandbox Code Playgroud)

然后,我改变了这一切[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)
Run Code Online (Sandbox Code Playgroud)

现在它给了我一个价值。

result is: 14.7911625
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 什么是[1,2,3]
  2. 为什么当我改变了代码工作[1,2,3]-1
  3. 这个dice_coef函数有什么作用?

Ret*_*i43 4

就像在 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)
Run Code Online (Sandbox Code Playgroud)

如果我们提供一个元组,我们可以沿多个轴执行此操作。

>>> a.sum(axis=(1, 2, 3), keepdims=True).shape
(2, 1, 1, 1)
Run Code Online (Sandbox Code Playgroud)

如果参数为-1,则默认在最后一个轴上执行操作,无论有多少个轴。

>>> a.sum(axis=-1, keepdims=True).shape
(2, 3, 5, 1)
Run Code Online (Sandbox Code Playgroud)

这应该澄清了第 1 点和第 2 点。由于 axis 参数为(1, 2, 3),因此您至少需要 4 个轴才能使操作有效。尝试将变量更改为类似的内容val1 = np.arange(24).reshape((2, 2, 2, 3)),一切都会起作用。

该模型似乎计算了 Binary Cross Entropy Dice 损失,dice_coeff()顾名思义,计算了Dice 系数。我不确定它的目的smooth是什么,但如果是为了避免被 0 除,你会期望一个很小的数字,比如 1e-6。