什么时候在keras中使用sample_weights合适?

yuj*_*ao 6 python keras tensorflow

根据这个问题,我了解到,class_weightkeras训练期间应用加权损失,并且sample_weight如果我对所有训练样本没有相同的信心,则会按样本进行一些操作。

所以我的问题是,

  1. 验证期间的损失是由 加权class_weight,还是仅在训练期间加权?
  2. 我的数据集有 2 个类别,实际上我的类别分布并没有严重不平衡。该比例约为。1.7 : 1.是否有必要使用class_weight来平衡损失甚至使用过采样?可以将稍微不平衡的数据保留为通常的数据集处理吗?
  3. 我可以简单地考虑sample_weight为每个训练样本赋予的权重吗?而且我的训练样本可以得到同等的置信度,所以我可能不需要使用它。

Kri*_*R89 6

  1. 从 keras 文档中可以看出

class_weight:可选字典将类索引(整数)映射到权重(浮点)值,用于对损失函数进行加权(仅在训练期间)。这对于告诉模型“更多地关注”代表性不足的类别的样本很有用。

所以class_weight只影响训练期间的损失。我本人一直有兴趣了解在测试和训练期间如何处理类和样本权重。查看keras github repo以及metric和loss的代码,似乎loss或metric都没有受到它们的影响。model.fit()在训练代码及其相应的张量流后端训练函数中很难跟踪打印的值。所以我决定制作一个测试代码来测试可能的场景,请参阅下面的代码。结论是,两者都影响class_weight并且sample_weight只影响训练损失,对任何指标或验证损失没有影响。有点令人惊讶,因为val_sample_weights(您可以指定)似乎什么也没做(??)。

  1. 此类问题始终取决于您的问题、日期的偏差程度以及您尝试优化模型的方式。您是否针对准确性进行了优化,那么只要训练数据与模型在生产中时的偏差相同,只需训练即可获得最佳结果,而无需任何过采样/欠采样和/或类别权重。另一方面,如果您有一个类比另一个类更重要(或更昂贵)的东西,那么您应该对数据进行加权。例如,在预防欺诈方面,欺诈通常比非欺诈的收入要昂贵得多。我建议您尝试未加权的类别、加权的类别和一些欠采样/过采样,并检查哪一个可以提供最佳的验证结果。使用最能比较不同模型的验证函数(或编写自己的函数)(例如,根据成本对真阳性、假阳性、真阴性和假阴性进行不同的加权)。一个相对较新的损失函数是 ,它在偏斜数据的 Kaggle 竞赛中取得了很好的成绩Focal-lossFocal-loss减少过采样/欠采样的需要。不幸的Focal-loss是,keras 中还没有内置 inn 函数,但可以手动编程。

  2. 是的,我认为你是对的。我通常使用它sample_weight有两个原因。1、训练数据具有某种测量不确定性,如果已知的话,可以用来对准确数据进行加权,而不是对不准确测量进行加权。或者2,我们可以对新数据赋予比旧数据更大的权重,迫使模型更快地适应新行为,而不忽略有价值的旧数据。

class_weights用于比较与和不比较的代码sample_weights,同时保持模型和其他所有内容静态。

import tensorflow as tf
import numpy as np

data_size = 100
input_size=3
classes=3

x_train = np.random.rand(data_size ,input_size)
y_train= np.random.randint(0,classes,data_size )
#sample_weight_train = np.random.rand(data_size)
x_val = np.random.rand(data_size ,input_size)
y_val= np.random.randint(0,classes,data_size )
#sample_weight_val = np.random.rand(data_size )

inputs = tf.keras.layers.Input(shape=(input_size))
pred=tf.keras.layers.Dense(classes, activation='softmax')(inputs)

model = tf.keras.models.Model(inputs=inputs, outputs=pred)

loss = tf.keras.losses.sparse_categorical_crossentropy
metrics = tf.keras.metrics.sparse_categorical_accuracy

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

# Make model static, so we can compare it between different scenarios
for layer in model.layers:
    layer.trainable = False

# base model no weights (same result as without class_weights)
# model.fit(x=x_train,y=y_train, validation_data=(x_val,y_val))
class_weights={0:1.,1:1.,2:1.}
model.fit(x=x_train,y=y_train, class_weight=class_weights, validation_data=(x_val,y_val))
# which outputs:
> loss: 1.1882 - sparse_categorical_accuracy: 0.3300 - val_loss: 1.1965 - val_sparse_categorical_accuracy: 0.3100

#changing the class weights to zero, to check which loss and metric that is affected
class_weights={0:0,1:0,2:0}
model.fit(x=x_train,y=y_train, class_weight=class_weights, validation_data=(x_val,y_val))
# which outputs:
> loss: 0.0000e+00 - sparse_categorical_accuracy: 0.3300 - val_loss: 1.1945 - val_sparse_categorical_accuracy: 0.3100

#changing the sample_weights to zero, to check which loss and metric that is affected
sample_weight_train = np.zeros(100)
sample_weight_val = np.zeros(100)
model.fit(x=x_train,y=y_train,sample_weight=sample_weight_train, validation_data=(x_val,y_val,sample_weight_val))
# which outputs:
> loss: 0.0000e+00 - sparse_categorical_accuracy: 0.3300 - val_loss: 1.1931 - val_sparse_categorical_accuracy: 0.3100
Run Code Online (Sandbox Code Playgroud)

使用权重和不使用权重之间存在一些小偏差(即使所有权重都是一),可能是由于对加权和未加权数据使用不同的后端函数进行拟合,或者是由于舍入误差?