我有一个带有多个 (8) 个输出神经元的 keras 模型,它们都经过 softmax 激活函数。然而,我的数据集由大约 300,000 个数据点组成,其中大部分数据仅将第一个输出神经元设置为 1,将所有其他输出神经元设置为 0,从而使神经网络能够获得较高的准确度。当将我的模型拟合到数据集时,我陷入了 0.3 的损失(使用均方误差时),最终得到了一个糟糕的神经网络,这在新数据上不能很好地工作。
我想将每个神经元的误差权重设置得非常高,除了那些让网络获得高精度的神经元。在 python/伪代码中,这将如下所示,其中 y_true
和y_pred
可能是列表或 numpy 数组:
def some_error_function(...):
# something like mean_squared_error()
def weighted_loss(y_true, y_pred):
# Regular loss value for the first output neuron
loss = some_error_function(y_true[0], y_pred[0])
# Loss multiplied by 100 for the other output neurons
loss += some_error_function(y_true[1:], y_pred[1:]) * 100
澄清一下,some_error_function(...)
这里可以将单个值作为参数或列表,因此 y_pred[1:]
意味着传递除第一个值之外的每个值的列表或 numpy 数组。
编译模型时,如何用上面的加权损失函数替换当前的损失函数?
model.compile(optimizer=keras.optimizers.Adam(), loss=<current loss function>)
我尝试传递一个像 weighted_loss
这样的函数,但我不确定如何使用给定的 y_true
计算损失和y_true
,因为它们的类型为 <class 'tensorflow.python.framework.ops.Tensor'>
.
而且我不知道我到底应该返回什么。当我返回 0.0 作为测试时,我收到以下错误:
ValueError: No gradients provided for any variable: ['sequential/dense/kernel:0', 'sequential/dense/bias:0', 'sequential/dense_1/kernel:0', 'sequential/dense_1/bias:0', 'sequential/dense_2/kernel:0', 'sequential/dense_2/bias:0', 'sequential/dense_3/kernel:0', 'sequential/dense_3/bias:0'].
最佳答案
在fit
方法中,有一个class_weight
参数用于为每个类(输出神经元)赋予权重。
所以,使用它。阅读documentation
class_weight: Optional dictionary mapping class indices (integers) to a weight (float) value, used for weighting the loss function (during training only). This can be useful to tell the model to "pay more attention" to samples from an under-represented class.
你想要这样的字典:
weights = { 0: low_weight,
1: high_weight,
2: high_weight,
....
7: high_weight }
关于python - 如何在 keras 模型中对某些输出进行比其他输出更多的惩罚?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59493445/