我正在尝试用三个类来实现一个分类问题:'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/