使用 keras ResNet50 模型进行二进制分类的输出层

Posted

技术标签:

【中文标题】使用 keras ResNet50 模型进行二进制分类的输出层【英文标题】:Output layer for binary classification using keras ResNet50 model 【发布时间】:2020-12-20 17:30:33 【问题描述】:

我正在尝试使用 Keras ResNet50 实现来训练二值图像分类模型。

我想在不使用迁移学习的情况下测试模型,但是当我尝试使用具有 sigmoid 激活功能的简单密集层来更改输出层以进行二元分类时,我遇到了关于形状大小的错误。

我的代码是这样的:

baseModel= ResNet50(weights=None, include_top=False, classes=2, pooling=max)

output = baseModel.output
output = layers.Dense(1, activation='sigmoid')(output)

model = keras.models.Model(inputs=baseModel.input, outputs=output)

model.compile(optimizer=Adam(learning_rate=0.0001), loss='binary_crossentropy',  metrics=['accuracy'])

这样做我得到了这个错误:

ValueError: logits and labels must have the same shape ((None, 7, 7, 1) vs (None, 1))

如果我在得到的密集层之前添加一个扁平层:

ValueError: The last dimension of the inputs to `Dense` should be defined. Found `None`.

我在这里缺少什么?如何更改密集层的输入形状?

【问题讨论】:

为什么不使用ResNet50(weights=None, include_top=True, classes=1) 使用默认的top,不使用包含的权重不包括imageNet数据集中的所有类进行预测? 好的,我最好阅读文档,“类”参数就是为此目的。对于二元分类,我应该使用 1 还是 2? 您可以使用 1 个具有 sigmoid 激活函数的类,或 2 个具有 softmax 激活函数的类。 在你的代码中你有 output = layers.Dense(1, activation='sigmoid')(out) 但是在哪里定义了?我怀疑你的意思是输出。你能提供模型的第一行和最后一行,总结吗? classes 是:可选的分类数量,如果 include_top 为 True,并且没有指定 weights 参数,则需要指定。你有 Top=False 所以不要指定类 【参考方案1】:

对于 ResNet,您指定了 Top=False 和 pooling = 'max',因此 Resent 模型向模型添加了最终的最大池化层。所以使用下面的代码:你不需要添加一个展平层,最大池化为你展平输出。

out=basemodel.layers[-1].output 
output = layers.Dense(1, activation='sigmoid')(out)

您可以使用 model.summary() 查看模型结构。 你也不应该使用classes=2。当 top 为 false 时,不应指定类。

【讨论】:

感谢您的扩展回复,这有助于我更好地了解修改现有模型的正确方法。这样做基本上和@jakub 的评论一样对吗? 无论如何,尝试了这种方法,但它给了我同样的错误。我应该明白其中的逻辑,所以我会尝试修复它。

以上是关于使用 keras ResNet50 模型进行二进制分类的输出层的主要内容,如果未能解决你的问题,请参考以下文章

Keras深度学习实战——基于ResNet模型实现性别分类

keras中使用预训练模型进行图片分类

Image_classification 使用 resnet50 模型和带有我的自定义标签的 imagenet db

keras调用预训练模型分类

错误 "IndexError: 如何在Keras中使用训练好的模型预测输入图像?

Keras Resnet-50 图像分类过拟合