【问题标题】:Setting up a CNN network with multi-label classification建立具有多标签分类的 CNN 网络
【发布时间】:2019-01-31 06:23:00
【问题描述】:

我有一组 100x100 的图像,以及一个对应于输入大小(即长度为 10000)的输出数组,其中每个元素可以是 1 或 0。

我正在尝试使用 TensorFlow/Keras 编写一个 python 程序来训练一个基于这些数据的 CNN,但是,我不确定如何设置层来处理它,或者要使用的网络类型。

目前,我正在执行以下操作(基于 TensorFlow 教程):

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(100, 100)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10000, activation=tf.nn.softmax)
])
model.compile(optimizer=tf.train.AdamOptimizer(), 
          loss='sparse_categorical_crossentropy',
          metrics=['accuracy'])

但是,我似乎找不到应该为输出层使用哪种类型的激活来使我能够拥有多个输出值? 我该如何设置?

【问题讨论】:

  • 这个answer 可能会帮助您进行激活和您需要使用的损失函数。如果你想要一个卷积架构,那么显然你需要使用像Conv2D 这样的卷积层。通常会连续使用一组Conv2DMaxPooling2D 层,最后可能会有一个或几个密集层。

标签: python tensorflow keras


【解决方案1】:

我不确定如何设置图层来处理它。

您的代码是处理该问题的一种方法,但正如您在文献中所读到的那样,它并不是最好的。最先进的模型通常使用 2D Convolution Neural Networks。例如:

    img_input = keras.layers.Input(shape=img_shape)
    conv1 = keras.layers.Conv2D(16, 3, activation='relu', padding='same')(img_input)
    pol1 = keras.layers.MaxPooling2D(2)(conv1)
    conv2 = keras.layers.Conv2D(32, 3, activation='relu', padding='same')(pol1)
    pol2 = keras.layers.MaxPooling2D(2)(conv2)
    conv3 = keras.layers.Conv2D(64, 3, activation='relu', padding='same')(pol2)
    pol3 = keras.layers.MaxPooling2D(2)(conv3)
    flatten = keras.layers.Flatten()(pol3)
    dens1 = keras.layers.Dense(512, activation='relu')(flatten)
    dens2 = keras.layers.Dense(512, activation='relu')(dens1)
    drop1 = keras.layers.Dropout(0.2)(dens2)
    output = keras.layers.Dense(10000, activation='softmax')(drop1)

我似乎找不到应该使用哪种类型的激活 输出层,使我能够有多个输出值

Softmax 是个不错的选择。它将任意实数值的 K 维向量压缩为实数值的 K 维向量,其中每个条目都在 (0, 1] 范围内。

您可以将 Softmax 的输出传递给 top_k 函数以提取顶部 k 预测:

softmax_out = tf.nn.softmax(logit)
tf.nn.top_k(softmax_out, k=5, sorted=True)

如果您需要multi-label classification,您应该更改上述网络。 Last Activation 函数将变为 sigmoid:

output = keras.layers.Dense(10000, activation='sigmoid')(drop1)

然后使用tf.roundtf.where提取标签:

indices = tf.where(tf.round(output) > 0.5)
final_output = tf.gather(x, indices)

【讨论】:

  • OP想要做多标签分类而不是单标签多类分类。因此,sigmoid必须作为最后一层的激活函数,而不是softmax
  • @today 感谢您的通知。我将更改我的答案以涵盖这两种情况
  • @AmirHadifar , 1) 您能否详细说明需要所有这些层的原因?多个 Conv2D/MaxPooling 层是否常见,或者数量取决于网络大小? 2) 当我尝试基于此创建模型时,使用 keras.Model(inputs=img_input,outputs=output) 失败:“节点”对象没有属性“输出掩码”。我错过了什么吗?
  • @Hawkeye001 查看here 以了解我们为什么需要这些卷积和池化。对于错误,您可以查看herehere
  • @AmirHadifar 感谢这些链接;关于我的错误,我实际上已经看到了这些链接,但是重新运行我的示例,我之前可能已经从 tensorflow 加载了 keras,而不是原生的,这是导致我的错误的原因。当我开始清理并验证我使用的是哪个版本的 keras 时,它工作正常。
猜你喜欢
  • 1970-01-01
  • 2019-11-03
  • 1970-01-01
  • 2021-11-18
  • 2021-01-26
  • 2020-02-21
  • 2018-09-23
  • 2017-06-28
  • 1970-01-01
相关资源
最近更新 更多