gpt4 book ai didi

python - 在 Keras 中使用 sample_weight 进行序列标注

转载 作者:太空狗 更新时间:2023-10-29 22:28:45 25 4
gpt4 key购买 nike

我正在处理不平衡类的顺序标记问题,我想使用 sample_weight 来解决不平衡问题。基本上,如果我训练模型大约 10 个时期,我会得到很好的结果。如果我训练更多的 epoch,val_loss 会不断下降,但我会得到更差的结果。我猜该模型只是检测到更多的优势类别,而不利于较小的类别。

该模型有两个输入,用于词嵌入和字符嵌入,输入是从 0 到 6 的 7 个可能类别之一。

有了填充,我的词嵌入输入层的形状是(3000, 150),词嵌入的输入层是(3000, 150, 15)。我使用 0.3 分割来测试和训练数据,这意味着用于词嵌入的 X_train(2000, 150)(2000, 150, 15) 用于字符嵌入。 y 包含每个单词的正确类别,编码为 7 维单热向量,因此其形状为 (3000, 150, 7)y 同样分为训练集和测试集。然后将每个输入输入双向 LSTM。

输出是一个矩阵,其中为 2000 个训练样本的每个单词分配了 7 个类别之一,因此大小为 (2000, 150, 7)


起初,我只是尝试将 sample_weight 定义为长度为 7 的 np.array,其中包含每个类别的权重:

count = [list(array).index(1) for arrays in y for array in arrays]
count = dict(Counter(count))
count[0] = 0
total = sum([count[key] for key in count])
count = {k: count[key] / total for key in count}
category_weights = np.zeros(7)
for f in count:
category_weights[f] = count[f]

但我收到以下错误 ValueError:为形状为 (2000, 150, 7) 的输入找到形状为 (7,) 的 sample_weight 数组。 sample_weight 无法广播。

查看文档,看起来我应该传递一个形状为 (samples, sequence_length) 的二维数组。所以我创建了一个 (3000, 150) 数组,其中串联了每个序列的每个单词的权重:

weights = []

for sample in y:
current_weight = []
for line in sample:
current_weight.append(frequency[list(line).index(1)])
weights.append(current_weight)

weights = np.array(weights)

compile() 中添加 sample_weight_mode="temporal" 选项后,通过 sample_weight 参数将其传递给 fit 函数。

我首先收到一个错误,告诉我维度是错误的,但是在只为训练样本生成权重之后,我最终得到了一个 (2000, 150) 数组,我可以用它来拟合我的模型。


  • 这是定义 sample_weights 的正确方法还是我做错了?我不能说我注意到添加权重后有任何改进,所以我一定是漏掉了什么。

最佳答案

我认为您混淆了 sample_weightsclass_weights。检查 docs有点我们可以看出它们之间的区别:

sample_weights 用于为每个 训练样本提供权重。 这意味着您应该传递一个具有相同数量的一维数组元素作为您的训练样本(指示每个样本的权重)。如果您使用的是时间数据,您可以传递一个二维数组,使您能够为每个样本的每个时间步赋予权重。

class_weights 用于为每个输出类提供权重或偏差。这意味着您应该为您尝试分类的每个类别传递一个权重。此外,此参数需要将字典 传递给它(不是数组,这就是您出现该错误的原因)。例如考虑这种情况:

class_weight = {0 : 1. , 1: 50.}

在这种情况下(二元分类问题),与 0 类相比,1 类样本的权重(或“相关性”)是 50 倍.这样您就可以补偿不平衡的数据集。这是另一个有用的 post在处理不平衡数据集时,详细解释这个选项和其他要考虑的选项。

If I train for more epochs, val_loss keeps dropping, but I get worse results.

可能您过度拟合了,正如您正确怀疑的那样,您的数据集所具有的不平衡类可能是造成这种情况的原因。补偿类权重应该有助于缓解这种情况,但是可能仍有其他因素会导致超出此问题/答案范围的过度拟合(因此请务必在解决此问题后注意这些因素)。


从你的帖子来看,在我看来你需要的是使用 class_weight 来平衡你的训练数据集,为此你需要传递一个字典指示您的 7 个类(class)之间的重量比。仅当您想为每个 样本提供自定义权重以供考虑时,才考虑使用sample_weight

如果您想对这两者进行更详细的比较,请考虑查看 this answer我发布了一个相关问题。 剧透:sample_weight 覆盖 class_weight,因此您必须使用其中之一,但不能同时使用这两个,因此请注意不要混合使用它们。


更新:截至本次编辑(2020 年 3 月 27 日),查看 source code training_utils.standardize_weights() 我们可以看到它现在支持两者 class_weightssample_weights:

Everything gets normalized to a single sample-wise (or timestep-wise) weight array. If both sample_weights and class_weights are provided, the weights are multiplied together.

关于python - 在 Keras 中使用 sample_weight 进行序列标注,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48315094/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com