Keras多个二进制输出

时间:2017-10-27 19:31:47

标签: neural-network deep-learning keras

有人可以帮我理解这个问题。

我必须训练一个神经网络,它应该输出200个相互独立的类别,这些类别中的每一个都是从0到1的百分比。对我而言,这似乎是binary_crossentropy问题,但我在互联网上看到的每个例子将binary_crossentropy与单个输出一起使用。由于我的输出应为200,如果我应用inputs = Input(shape=(input_shape,)) hidden = Dense(2048, activation='relu')(inputs) hidden = Dense(2048, activation='relu')(hidden) output = Dense(200, name='output_cat', activation='sigmoid')(hidden) model = Model(inputs=inputs, outputs=[output]) loss_map = {'output_cat': 'binary_crossentropy'} model.compile(loss=loss_map, optimizer="sgd", metrics=['mae', 'accuracy']) ,那是正确的吗?

这就是我想到的,是正确的方法还是我应该改变它?

{{1}}

4 个答案:

答案 0 :(得分:6)

要使用Keras优化多个独立的二进制分类问题(而不是可以使用categorical_crossentropy的多类别问题),您可以执行以下操作(这里我以2个独立的二进制输出为例,但您可以扩展它根据需要):

    inputs = Input(shape=(input_shape,))
    hidden = Dense(2048, activation='relu')(inputs)
    hidden = Dense(2048, activation='relu')(hidden)
    output = Dense(units = 2, activation='sigmoid')(hidden )

在这里,您使用Keras的Lambda图层分割输出:

    output_1 = Lambda(lambda x: x[...,:1])(output)
    output_2 = Lambda(lambda x: x[...,1:])(output)

    adad = optimizers.Adadelta()

您的模型输出变为不同独立输出的列表

    model = Model(inputs, [output_1, output_2])

在列表中使用每个输出的一个损失函数编译模型。 (事实上​​,如果你只提供一种损失函数,我相信它将独立地应用于所有输出)

    model.compile(optimizer=adad, loss=['binary_crossentropy','binary_crossentropy'])

答案 1 :(得分:2)

对于多个类别分类问题,您应该使用categorical_crossentropy而不是binary_crossentropy。有了这个,当你的模型对输入进行分类时,它会在所有200个类别之间分散概率。接收概率最高的类别将是该特定输入的输出。

您拨打model.predict()时可以看到此消息。例如,如果您仅在一个输入上调用此函数并打印结果,您将看到200%的结果(总计为1)。希望这200%的百分比中的一个会远远高于其他百分比,这表明该模型认为这是特定输入的正确输出(类别)的可能性很大。

This video可能有助于澄清预测片段。打印预测从3:17左右开始,但要获得完整的上下文,您需要从头开始。

答案 2 :(得分:0)

我知道这是一个古老的问题,但是我相信公认的答案是不正确的,最受支持的答案是可行的,但不是最佳的。原始海报者的方法是解决此问题的正确方法。他的输出是200个从0到1的独立概率,因此他的输出层应该是一个具有200个神经元的密集层和一个S型激活层。这不是categorical_crossentropy问题,因为它不是200个互斥的类别。同样,当单个密集层可以使用时,也没有理由使用lambda层拆分输出。原始海报的方法是正确的。这是使用Keras界面执行此操作的另一种方法。

        model = Sequential()
        model.add(Dense(2048, input_dim=n_input, activation='relu'))
        model.add(Dense(2048, input_dim=n_input, activation='relu'))
        model.add(Dense(200, activation='sigmoid'))
        model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

答案 3 :(得分:-1)

如果有多个班级,则应使用categorical_crossentropy。请参阅another answer here