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,2,3]
?[1,2,3]
来-1
?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)
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。