如何在 keras 中创建自定义损失函数? (自定义加权二进制交叉熵)
How can I create a custom loss function in keras ? (Custom Weighted Binary Cross Entropy)
我正在创建一个完全卷积神经网络,给定输入图像能够识别其中的区域(黑色,0),还可以识别背景(白色,255)。
我的目标是二值化图像(范围为 0-255),我想在我的两个语义 类(0 或 255)之间取得一些平衡。
事实上,我得到的“特殊”区域 (0) 是背景区域 (255) 的 1.8 倍,所以我需要抵消这种影响,我想更多地惩罚在背景上出错的事实,以避免仅预测特殊区域。
我试着关注一些关于它的主题,它似乎并不难,但我在实现中卡住了,我真的不知道为什么。
每次我的实现都在编译阶段工作,但只在拟合步骤中 returns 出错。
到目前为止,这是我尝试过的:
import keras.backend as kb
def custom_binary_crossentropy(y_true, y_pred):
"""
Used to reequilibrate the data, as there is more black (0., articles), than white (255., non-articles) on the pages.
"""
if y_true >=128: # Half the 0-255 range
return -1.8*kb.log(y_pred/255.)
else:
return -kb.log(1-(y_pred/255.))
但是它返回了:
InvalidArgumentError: The second input must be a scalar, but it has shape [16,256,256]
[[{{node gradient_tape/custom_binary_crossentropy/cond/StatelessIf/gradient_tape/custom_binary_crossentropy/weighted_loss/Mul/_17}}]] [Op:__inference_train_function_24327]
Function call stack:
train_function
我不太明白这个错误。
我之前试过:
def custom_binary_crossentropy(y_true, y_pred):
"""
Used to reequilibrate the data, as there is more black (0., articles), than white (255., non-articles) on the pages.
"""
if y_true >=128: # Half the 0-255 range
return 1.8*keras.losses.BinaryCrossentropy(y_true, y_pred)
else:
return keras.losses.BinaryCrossentropy(y_true, y_pred)
但是我得到了:
TypeError: in user code:
/Users/axeldurand/opt/anaconda3/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:806 train_function *
return step_function(self, iterator)
<ipython-input-67-7b6815236f63>:6 custom_binary_crossentropy *
return -1.8*keras.losses.BinaryCrossentropy(y_true, y_pred)
TypeError: unsupported operand type(s) for *: 'float' and 'BinaryCrossentropy'
我有点困惑,Keras 总是让它变得如此简单,我必须省略一些简单的东西,但我真的不明白。
您使用 keras.losses.BinaryCrossentropy
的方式有误。您实际上想要此损失的功能版本,即 tf.keras.losses.binary_crossentropy
见https://www.tensorflow.org/api_docs/python/tf/keras/losses/BinaryCrossentropy and https://www.tensorflow.org/api_docs/python/tf/keras/losses/binary_crossentropy
非常感谢@qmeeus,你向我展示了成功之路!
我不知道 keras.losses.BinaryCrossentropy 和 keras.losses.binary_crossentropy 之间的区别,但这是一个主要区别。
这是我的做法:
def custom_binary_crossentropy(y_true, y_pred):
"""
Used to reequilibrate the data, as there is more black (0., articles),
than white (255. (recalibrated to 1.), non-articles) on the pages.
"""
# I put 0 so that the shape is (batch_size, 256, 256)
# and not (batch_size, 256, 256, 1)
is_white = y_true[:,:,:,0]>=0.5
white_error = 1.8*keras.losses.binary_crossentropy(y_true, y_pred)
black_error = keras.losses.binary_crossentropy(y_true, y_pred)
# Returns the right loss for each type of error.
# We do make twice the calculation but I did not find a better way for now
return tf.where(is_white, white_error, black_error)
我不知道tf.where的用途,但它非常有用。
我在 Aurélien Géron 的优秀书籍 Machine learning with Keras and TensorFlow 上看到了这个教程。
只需使用下一个:
# Compiling using this function
model.compile(optimizer="rmsprop", loss=custom_binary_crossentropy)
然后使用您的数据和最喜欢的超参数拟合您的模型,一切顺利!
我正在创建一个完全卷积神经网络,给定输入图像能够识别其中的区域(黑色,0),还可以识别背景(白色,255)。 我的目标是二值化图像(范围为 0-255),我想在我的两个语义 类(0 或 255)之间取得一些平衡。 事实上,我得到的“特殊”区域 (0) 是背景区域 (255) 的 1.8 倍,所以我需要抵消这种影响,我想更多地惩罚在背景上出错的事实,以避免仅预测特殊区域。
我试着关注一些关于它的主题,它似乎并不难,但我在实现中卡住了,我真的不知道为什么。
每次我的实现都在编译阶段工作,但只在拟合步骤中 returns 出错。
到目前为止,这是我尝试过的:
import keras.backend as kb
def custom_binary_crossentropy(y_true, y_pred):
"""
Used to reequilibrate the data, as there is more black (0., articles), than white (255., non-articles) on the pages.
"""
if y_true >=128: # Half the 0-255 range
return -1.8*kb.log(y_pred/255.)
else:
return -kb.log(1-(y_pred/255.))
但是它返回了:
InvalidArgumentError: The second input must be a scalar, but it has shape [16,256,256]
[[{{node gradient_tape/custom_binary_crossentropy/cond/StatelessIf/gradient_tape/custom_binary_crossentropy/weighted_loss/Mul/_17}}]] [Op:__inference_train_function_24327]
Function call stack:
train_function
我不太明白这个错误。
我之前试过:
def custom_binary_crossentropy(y_true, y_pred):
"""
Used to reequilibrate the data, as there is more black (0., articles), than white (255., non-articles) on the pages.
"""
if y_true >=128: # Half the 0-255 range
return 1.8*keras.losses.BinaryCrossentropy(y_true, y_pred)
else:
return keras.losses.BinaryCrossentropy(y_true, y_pred)
但是我得到了:
TypeError: in user code:
/Users/axeldurand/opt/anaconda3/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:806 train_function *
return step_function(self, iterator)
<ipython-input-67-7b6815236f63>:6 custom_binary_crossentropy *
return -1.8*keras.losses.BinaryCrossentropy(y_true, y_pred)
TypeError: unsupported operand type(s) for *: 'float' and 'BinaryCrossentropy'
我有点困惑,Keras 总是让它变得如此简单,我必须省略一些简单的东西,但我真的不明白。
您使用 keras.losses.BinaryCrossentropy
的方式有误。您实际上想要此损失的功能版本,即 tf.keras.losses.binary_crossentropy
见https://www.tensorflow.org/api_docs/python/tf/keras/losses/BinaryCrossentropy and https://www.tensorflow.org/api_docs/python/tf/keras/losses/binary_crossentropy
非常感谢@qmeeus,你向我展示了成功之路!
我不知道 keras.losses.BinaryCrossentropy 和 keras.losses.binary_crossentropy 之间的区别,但这是一个主要区别。
这是我的做法:
def custom_binary_crossentropy(y_true, y_pred):
"""
Used to reequilibrate the data, as there is more black (0., articles),
than white (255. (recalibrated to 1.), non-articles) on the pages.
"""
# I put 0 so that the shape is (batch_size, 256, 256)
# and not (batch_size, 256, 256, 1)
is_white = y_true[:,:,:,0]>=0.5
white_error = 1.8*keras.losses.binary_crossentropy(y_true, y_pred)
black_error = keras.losses.binary_crossentropy(y_true, y_pred)
# Returns the right loss for each type of error.
# We do make twice the calculation but I did not find a better way for now
return tf.where(is_white, white_error, black_error)
我不知道tf.where的用途,但它非常有用。 我在 Aurélien Géron 的优秀书籍 Machine learning with Keras and TensorFlow 上看到了这个教程。
只需使用下一个:
# Compiling using this function
model.compile(optimizer="rmsprop", loss=custom_binary_crossentropy)
然后使用您的数据和最喜欢的超参数拟合您的模型,一切顺利!