Keras:用于单热编码的类权重(class_weight)

Nao*_*ama 18 python keras

我想在keras model.fit中使用class_weight参数来处理不平衡的训练数据.通过查看一些文档,我知道我们可以传递这样的字典:

class_weight = {0 : 1,
    1: 1,
    2: 5}
Run Code Online (Sandbox Code Playgroud)

(在这个例子中,2级将在损失函数中获得更高的惩罚.)

问题是我的网络输出有一个热编码,即类0 =(1,0,0),类-1 =(0,1,0)和类-3 =(0,0,1).

我们如何使用class_weight进行单热编码输出?

通过查看Keras中的一些代码,它看起来像_feed_output_names包含输出类的列表,但在我的情况下,model.output_names/ model._feed_output_names返回['dense_1']

相关:如何为Keras中的不平衡类设置类权重?

Mel*_*ssa 16

这是一个更短,更快的解决方案.如果您的单热编码y是np.array:

import numpy as np
from sklearn.utils.class_weight import compute_class_weight

y_integers = np.argmax(y, axis=1)
class_weights = compute_class_weight('balanced', np.unique(y_integers), y_integers)
d_class_weights = dict(enumerate(class_weights))
Run Code Online (Sandbox Code Playgroud)

d_class_weights然后可以传递给class_weight.fit.

  • @tsveti_iko 发送类权重不适用于一种热编码, `elif isinstance(class_weight, dict): ... else: return np.ones((y.shape[0],), dtype=K.floatx() )` 您必须为其提供样本权重,例如使用 sklearn 的 `class_weight.compute_sample_weight('balanced', y_train)` (2认同)

Nao*_*ama 6

我想我们可以用它sample_weights代替。在 Keras 内部,实际上,class_weights被转换为sample_weights.

sample_weight:与 x 长度相同的可选数组,包含应用于每个样本的模型损失的权重。在时间数据的情况下,您可以传递一个形状为 (samples, sequence_length) 的二维数组,以对每个样本的每个时间步应用不同的权重。在这种情况下,您应该确保在 compile() 中指定 sample_weight_mode="temporal"。

https://github.com/fchollet/keras/blob/d89afdfd82e6e27b850d910890f4a4059ddea331/keras/engine/training.py#L1392

  • Sample_weight_mode="temporal" 如何帮助处理多类 one-hot 编码目标?您知道如何处理每个样本可以参加多个课程的情况吗?谢谢 (2认同)

tw0*_*000 6

有点令人费解的答案,但到目前为止我发现的最好.这假设您的数据是单热编码,多类,并且仅在标签DataFrame上工作df_y:

import pandas as pd
import numpy as np

# Create a pd.series that represents the categorical class of each one-hot encoded row
y_classes = df_y.idxmax(1, skipna=False)

from sklearn.preprocessing import LabelEncoder

# Instantiate the label encoder
le = LabelEncoder()

# Fit the label encoder to our label series
le.fit(list(y_classes))

# Create integer based labels Series
y_integers = le.transform(list(y_classes))

# Create dict of labels : integer representation
labels_and_integers = dict(zip(y_classes, y_integers))

from sklearn.utils.class_weight import compute_class_weight, compute_sample_weight

class_weights = compute_class_weight('balanced', np.unique(y_integers), y_integers)
sample_weights = compute_sample_weight('balanced', y_integers)

class_weights_dict = dict(zip(le.transform(list(le.classes_)), class_weights))
Run Code Online (Sandbox Code Playgroud)

这导致sample_weights计算向量以平衡可以传递给Keras sample_weight属性的不平衡数据集,并且class_weights_dict可以将其馈送到方法中的Keras class_weight属性.fit.你真的不想同时使用两者,只需选择一个.我使用的class_weight,因为现在它的复杂获得sample_weight与工作fit_generator.


小智 5

_standardize_weights,keras 做:

if y.shape[1] > 1:
    y_classes = y.argmax(axis=1)
Run Code Online (Sandbox Code Playgroud)

所以基本上,如果你选择使用 one-hot 编码,类就是列索引。

您可能还会问自己如何将列索引映射到数据的原始类。好吧,如果你使用scikit的LabelEncoder类学习执行one-hot编码,列索引映射unique labels.fit函数计算的顺序。医生说

提取唯一标签的有序数组

例子:

from sklearn.preprocessing import LabelBinarizer
y=[4,1,2,8]
l=LabelBinarizer()
y_transformed=l.fit_transorm(y)
y_transormed
> array([[0, 0, 1, 0],
   [1, 0, 0, 0],
   [0, 1, 0, 0],
   [0, 0, 0, 1]])
l.classes_
> array([1, 2, 4, 8])
Run Code Online (Sandbox Code Playgroud)

总之,class_weights字典的键应该反映classes_编码器属性中的顺序。