【问题标题】:Keras multiple binary outputsKeras 多个二进制输出
【发布时间】:2018-04-09 11:35:40
【问题描述】:

谁能帮我更好地理解这个问题。

我必须训练一个神经网络,它应该输出 200 个相互独立的类别,每个类别都是从 0 到 1 的百分比。对我来说,这似乎是一个 binary_crossentropy 问题,但我在互联网上看到的每个示例都使用 @ 987654322@ 单输出。由于我的输出应该是 200,如果我申请 binary_crossentropy,那是否正确?

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

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'])

【问题讨论】:

  • 我认为您的方法还可以。您可以搜索多标签示例而不是二进制分类示例。

标签: neural-network deep-learning keras


【解决方案1】:

要使用 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'])

【讨论】:

    【解决方案2】:

    我知道这是一个老问题,但我认为接受的答案是不正确的,最受好评的答案是可行的,但不是最优的。原始发帖人的方法是解决这个问题的正确方法。他的输出是从 0 到 1 的 200 个独立概率,所以他的输出层应该是一个密集层,有 200 个神经元和一个 sigmoid 激活层。这不是 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】:

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

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

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

      【讨论】:

      • 我正在寻找的是 200 个类别,每个类别的百分比介于 0 和 1 之间。不是所有 200 个的总和为 1。那么 categorical_crossentropy 会有帮助吗?
      【解决方案4】:

      当有多个类时,应该使用categorical_crossentropy。参考another answer here

      【讨论】:

      • 我如何用categorical_crossentropy返回百分比?有 200 个类,每个类的百分比可以在 0 到 1 之间?这些类并不相互排斥,这意味着我需要全部 200
      猜你喜欢
      • 2021-05-02
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      • 2023-03-29
      • 2023-03-13
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多