Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Keras中具有类权重的多标签分类_Keras_Multilabel Classification - Fatal编程技术网

Keras中具有类权重的多标签分类

Keras中具有类权重的多标签分类,keras,multilabel-classification,Keras,Multilabel Classification,我在网络中有1000个类,它们有多标签输出。对于每个培训示例,正输出的数量相同(即10个),但它们可以分配给1000个类中的任何一个。因此,10个类的输出为1,其余990个类的输出为0 对于多标签分类,我使用“二进制交叉熵”作为代价函数,使用“sigmoid”作为激活函数。当我尝试将0.5作为1或0的截止值时。全部为0。我理解这是一个班级不平衡的问题。从这一点上,我明白了,我可能必须创建额外的输出标签。不幸的是,我还没有弄清楚如何将其合并到keras中的简单神经网络中 nclasses = 10

我在网络中有1000个类,它们有多标签输出。对于每个培训示例,正输出的数量相同(即10个),但它们可以分配给1000个类中的任何一个。因此,10个类的输出为1,其余990个类的输出为0

对于多标签分类,我使用“二进制交叉熵”作为代价函数,使用“sigmoid”作为激活函数。当我尝试将0.5作为1或0的截止值时。全部为0。我理解这是一个班级不平衡的问题。从这一点上,我明白了,我可能必须创建额外的输出标签。不幸的是,我还没有弄清楚如何将其合并到keras中的简单神经网络中

nclasses = 1000

# if we wanted to maximize an imbalance problem!
#class_weight = {k: len(Y_train)/(nclasses*(Y_train==k).sum()) for k in range(nclasses)}


inp = Input(shape=[X_train.shape[1]])
x = Dense(5000, activation='relu')(inp)

x = Dense(4000, activation='relu')(x)

x = Dense(3000, activation='relu')(x)
x = Dense(2000, activation='relu')(x)
x = Dense(nclasses, activation='sigmoid')(x)
model = Model(inputs=[inp], outputs=[x])

adam=keras.optimizers.adam(lr=0.00001)
model.compile('adam', 'binary_crossentropy')
history = model.fit(
    X_train, Y_train, batch_size=32, epochs=50,verbose=0,shuffle=False)
这里有人能帮我写代码吗?如果你能为这个问题提出一个好的“准确度”指标,我也会非常感激


非常感谢:):)

我有一个类似的问题,不幸的是大多数问题都没有答案。尤其是阶级失衡问题

就度量而言,有几种可能性:在我的例子中,我使用前1/2/3/4/5结果,并检查其中一个是否正确。因为在你的情况下,你总是有相同数量的标签=1,你可以拿你的前10个结果,看看他们中有多少是正确的,并在你的批量大小上平均这个结果。我没有发现将此算法作为keras度量的可能性。相反,我编写了一个回调,它在我的验证数据集上计算epoch结束时的度量

此外,如果预测测试数据集上的前n个结果,请查看每个类的预测次数。对于这一目的来说,这是非常方便的

编辑:如果找到包含类权重而不拆分输出的方法。 您需要一个numpy 2d数组,其中包含具有形状[要预测的数字类,2(背景和信号)]的权重。 可以使用此函数计算这样的数组:

def calculating_class_weights(y_true):
    from sklearn.utils.class_weight import compute_class_weight
    number_dim = np.shape(y_true)[1]
    weights = np.empty([number_dim, 2])
    for i in range(number_dim):
        weights[i] = compute_class_weight('balanced', [0.,1.], y_true[:, i])
    return weights
model.compile(optimizer=Adam(), loss=get_weighted_loss(class_weights))
现在的解决方案是构建您自己的二进制交叉熵损失函数,在该函数中,您可以自己乘以权重:

def get_weighted_loss(weights):
    def weighted_loss(y_true, y_pred):
        return K.mean((weights[:,0]**(1-y_true))*(weights[:,1]**(y_true))*K.binary_crossentropy(y_true, y_pred), axis=-1)
    return weighted_loss
权重[:,0]是包含所有背景权重的数组,权重[:,1]包含所有信号权重

剩下的就是将此损失包含到编译函数中:

def calculating_class_weights(y_true):
    from sklearn.utils.class_weight import compute_class_weight
    number_dim = np.shape(y_true)[1]
    weights = np.empty([number_dim, 2])
    for i in range(number_dim):
        weights[i] = compute_class_weight('balanced', [0.,1.], y_true[:, i])
    return weights
model.compile(optimizer=Adam(), loss=get_weighted_loss(class_weights))

尝试将
1
s分配给前20名分数,而不是使用阈值。我应该如何考虑班级不平衡?你能解释一下,如果我使用前10/20的分数,会如何处理吗?:)我真的很喜欢这个答案!顺便说一下,如果其他人遇到此问题:如果保存使用此自定义损失函数训练的模型并希望再次加载它,则会出现“未知损失函数”错误。这可以通过设置“custom_objects”参数来克服,例如model=load_model(“path/to/model.hd5f”,custom_objects={“weighted_loss”:get_weighted_loss(weights)}有人能解释一下加权公式
K.mean((weights[:,0]**(1-y_-true))*(weights[:,1]**(y_-true))*K.binary_交叉熵(y_-true,y_-pred),axis=-1)
是构建的吗?谢谢。我在上一篇文章中对此进行了解释。基本上,一切都是K.mean中的一个形状向量(样本数、输出数)。新的是构建的权重因子,其中一个是一个,另一个是相应的权重。只是一个更正(无法编辑注释?)。应该是加载模型(“path/to/model.h5”,…)not.hd5fA小添加:如果保存模型(添加自定义对象)并加载模型仅用于推理,则不再需要该函数。只需使用另一个keras损失函数:自定义对象={“加权损失”:一些其他损失函数}。这无关紧要,因为您无论如何都不会使用它。因此,您不必在推理代码中复制丢失函数的代码。