如何使用预训练的神经网络处理灰度图像?

85

我有一个包含灰度图像的数据集,想用最先进的卷积神经网络(CNN)对其进行训练。我非常希望微调预训练模型 (如这里提供的模型)。

问题是我找到的几乎所有模型参数都是在ImageNet数据集上训练得到的,该数据集包含RGB图像。

因为它们的输入层期望的批次形状为(batch_size, height, width, 3)(64, 224, 224, 3),而我的图像批次为(64, 224, 224),所以我不能使用这些模型。

有没有办法可以使用其中一个模型?我考虑过在加载权重后删除输入层并添加自己的输入层(就像我们对顶部层做的那样)。这种方法是否正确?


1
你可以尝试移除输入层并添加自己的层。然后,你可以尝试仅训练该层。如果你锁定了所有其他层,但没有看到损失减少,那么这种方法可能行不通。 - kevinkayaks
9
不要问我们这种方法是否正确:问问电脑吧!试一试吧!另一种方法是将输入向量三倍化:将灰度值馈送到所有三个彩色层。 - Prune
2
我的个人感觉是这对你来说不会行。这些分类网络肯定是使用颜色之间的相互关系来对物体进行分类,而这些信息深深地融入了中间层的权重中。 - kevinkayaks
21
训练这些模型可能需要数天时间,如果有人遇到过这个问题并能提供一些见解,我会非常感激。 - Jcart
2
正如其他人所提到的,将3个相同的灰度数组堆叠作为输入是可行的--但我会将其视为实现更多数据增强的机会--对原始灰度图像应用图像滤镜,并随机分配它们到3个通道中。 - ohailolcat
显示剩余2条评论
12个回答

0

我相信您可以使用一个预训练的ResNet来处理单通道灰度图像,而不需要将图像重复三次。

我的做法是替换第一层(这是PyTorch而不是Keras,但思路可能类似):

(conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)

使用以下层:

(conv1): Conv2d(1, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)

然后将权重的总和(在通道轴上)复制到新层中,例如,原始权重的形状为:

torch.Size([64, 3, 7, 7])

所以我这样做了:

resnet18.conv1.weight.data = resnet18.conv1.weight.data.sum(axis=1).reshape(64, 1, 7, 7)

然后检查新模型的输出是否与灰度图像的输出相同:

y_1 = model_resnet_1(input_image_1)
y_3 = model_resnet_3(input_image_3)
print(torch.abs(y_1).sum(), torch.abs(y_3).sum())
(tensor(710.8860, grad_fn=<SumBackward0>),
 tensor(710.8861, grad_fn=<SumBackward0>))

input_image_1: 单通道图像

input_image_3: 三通道图像(灰度 - 所有通道相等)

model_resnet_1: 修改后的模型

model_resnet_3: 原始的resnet模型


-10

当您将Resnet添加到模型中时,应在Resnet定义中输入input_shape。

model = ResNet50(include_top=True,input_shape=(256,256,1))

.


1
这个无法运行: ValueError: 输入必须有3个通道 - Matt Hancock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接