tensorflow - Keras 对不同的错误分类应用不同的权重

标签 tensorflow keras loss-function cross-entropy

我正在尝试用三个类来实现一个分类问题:'A'、'B' 和 'C',我想在我的模型损失函数中对不同类型的错误分类进行惩罚(有点像加权交叉熵)。类权重不适合,因为它适用于属于该类的所有数据。例如,与被错误分类为“A”相比,真实标签“B”被错误分类为“C”应该具有更高的损失。重量表如下:

   A  B  C  
A  1  1  1  
B  1  1  1.2 
C  1  1  1    

在当前的 categorical_crossentropy 损失中,对于真正的“B”类,如果我将预测 softmax 设为
0.5 0.4 0.1  vs 0.1 0.4 0.5 

categorical_crossentropy 将相同。 'B' 是否被误分类为 A 或 C 并不重要。与第一个相比,我想增加第二个预测 softmax 的损失。

我试过 https://github.com/keras-team/keras/issues/2115但没有任何代码适用于 Keras v2。任何我可以直接将权重矩阵强制执行到 Keras 损失函数的帮助都将受到高度赞赏。

最佳答案

您可以更改损失函数以将损失值乘以矩阵中的适当权重。

因此,举个例子,考虑 mnist tensorflow example :

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

如果我们想改变它以根据以下矩阵对损失进行加权:

weights  = tf.constant([
       [1., 1.2, 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1.2, 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 10.9, 1.2, 1., 1., 1., 1., 1., 1.],
       [1., 0.9, 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])

然后我们可以包装现有的 sparse_categorical_crossentropy在一个新的自定义损失函数中,该函数将损失乘以适当的权重。像这样的东西:

def custom_loss(y_true, y_pred):
  # get the prediction from the final softmax layer:
  pred_idx = tf.argmax(y_pred, axis=1, output_type=tf.int32)

  # stack these so we have a tensor of [[predicted_i, actual_i], ...,] for each i in batch
  indices = tf.stack([tf.reshape(pred_idx, (-1,)), 
                       tf.reshape(tf.cast( y_true, tf.int32), (-1,))
                     ], axis=1)

  # use tf.gather_nd() to convert indices to the appropriate weight from our matrix [w_i, ...] for each i in batch
  batch_weights = tf.gather_nd(weights, indices)


  return batch_weights * tf.keras.losses.sparse_categorical_crossentropy(y_true, y_pred)



然后我们可以在模型中使用这个新的自定义损失函数:

model.compile(optimizer='adam',
              loss=custom_loss,
              metrics=['accuracy'])

关于tensorflow - Keras 对不同的错误分类应用不同的权重,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56696069/

相关文章:

tensorflow - 如何在 Call() 方法中使用位置参数保存 keras 子类模型?

python - Keras:进行预测时的 ValueError 和准确度为零

tensorflow - Keras 中的自定义损失函数应该返回批处理的单个损失值还是训练批处理中每个样本的一系列损失?

python - 如何有条件地将值分配给张量[损失函数的掩蔽]?

tensorflow - ImageNet 预训练的 ResNet50 主干在 Pytorch 和 TensorFlow 之间有所不同

python - Tensorflow:使用子/上对角线上的输入创建对角矩阵

python - 如何删除 tf.logging.info 打印出的前缀

tensorflow - 创建VGG16时来自Tensorflow的警告

python - 在 MNIST 数据集上训练后如何在 keras 中使用 cnn 预测我自己的图像

keras - 如果我想预测 0-1 区间的连续结果,我应该使用哪个输出激活和损失?