yuj*_*ao 6 python keras tensorflow
根据这个问题,我了解到,class_weight
在keras
训练期间应用加权损失,并且sample_weight
如果我对所有训练样本没有相同的信心,则会按样本进行一些操作。
所以我的问题是,
class_weight
,还是仅在训练期间加权?class_weight
来平衡损失甚至使用过采样?可以将稍微不平衡的数据保留为通常的数据集处理吗?sample_weight
为每个训练样本赋予的权重吗?而且我的训练样本可以得到同等的置信度,所以我可能不需要使用它。class_weight:可选字典将类索引(整数)映射到权重(浮点)值,用于对损失函数进行加权(仅在训练期间)。这对于告诉模型“更多地关注”代表性不足的类别的样本很有用。
所以class_weight
只影响训练期间的损失。我本人一直有兴趣了解在测试和训练期间如何处理类和样本权重。查看keras github repo以及metric和loss的代码,似乎loss或metric都没有受到它们的影响。model.fit()
在训练代码及其相应的张量流后端训练函数中很难跟踪打印的值。所以我决定制作一个测试代码来测试可能的场景,请参阅下面的代码。结论是,两者都影响class_weight
并且sample_weight
只影响训练损失,对任何指标或验证损失没有影响。有点令人惊讶,因为val_sample_weights
(您可以指定)似乎什么也没做(??)。
此类问题始终取决于您的问题、日期的偏差程度以及您尝试优化模型的方式。您是否针对准确性进行了优化,那么只要训练数据与模型在生产中时的偏差相同,只需训练即可获得最佳结果,而无需任何过采样/欠采样和/或类别权重。另一方面,如果您有一个类比另一个类更重要(或更昂贵)的东西,那么您应该对数据进行加权。例如,在预防欺诈方面,欺诈通常比非欺诈的收入要昂贵得多。我建议您尝试未加权的类别、加权的类别和一些欠采样/过采样,并检查哪一个可以提供最佳的验证结果。使用最能比较不同模型的验证函数(或编写自己的函数)(例如,根据成本对真阳性、假阳性、真阴性和假阴性进行不同的加权)。一个相对较新的损失函数是 ,它在偏斜数据的 Kaggle 竞赛中取得了很好的成绩Focal-loss
。Focal-loss
减少过采样/欠采样的需要。不幸的Focal-loss
是,keras 中还没有内置 inn 函数,但可以手动编程。
是的,我认为你是对的。我通常使用它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)
使用权重和不使用权重之间存在一些小偏差(即使所有权重都是一),可能是由于对加权和未加权数据使用不同的后端函数进行拟合,或者是由于舍入误差?
归档时间: |
|
查看次数: |
8719 次 |
最近记录: |