使用 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 模型进行二进制分类的输出层的主要内容,如果未能解决你的问题,请参考以下文章
Image_classification 使用 resnet50 模型和带有我的自定义标签的 imagenet db