Jca*_*art 12 python machine-learning deep-learning keras tensorflow
我有一个包含灰度图像的数据集,我想在它们上训练一个最先进的CNN.我非常想调整一个预先训练好的模型(就像这里的模型一样).
问题在于我几乎所有可以找到权重的模型都在ImageNet数据集上进行了训练,该数据集包含RGB图像.
我不能使用其中一个模型,因为他们的输入层需要一批形状(batch_size, height, width, 3)
或(64, 224, 224, 3)
在我的情况下,但我的图像批次是(64, 224, 224)
.
有什么方法可以使用其中一种型号吗?我已经考虑过在加载权重并添加自己的权重后丢弃输入层(就像我们为顶层做的那样).这种方法是否正确?
Dji*_*011 17
无法更改模型的体系结构,因为权重已针对特定输入配置进行了训练.用你自己替换第一层几乎会使其余的权重变得无用.
- 编辑:Prune建议的详细说明 - 建立
CNN以便随着它们的深入,它们可以提取从前一层提取的较低级别特征派生的高级特征.通过删除CNN的初始层,您正在破坏该功能层次结构,因为后续层将不会接收它们应该作为其输入的功能.在您的情况下,第二层已经过训练,可以期待第一层的特征.通过用随机权重替换你的第一层,你实际上丢弃了对后续层进行的任何训练,因为它们需要重新训练.我怀疑他们可以保留在初始培训期间学到的任何知识.
---结束编辑---
但是,有一种简单的方法可以让您的模型使用灰度图像.您只需要使图像看起来像RGB.最简单的方法是在新维度上重复图像阵列3次.因为您将在所有3个通道上拥有相同的图像,所以模型的性能应与RGB图像上的相同.
在numpy中,这可以很容易地完成:
print(grayscale_batch.shape) # (64, 224, 224)
rgb_batch = np.repeat(grayscale_batch[..., np.newaxis], 3, -1)
print(rgb_batch.shape) # (64, 224, 224, 3)
Run Code Online (Sandbox Code Playgroud)
这种方式的工作方式是首先创建一个新维度(放置通道),然后在这个新维度上重复现有数组3次.
我也很确定keras的ImageDataGenerator可以将灰度图像加载为RGB.
mmr*_*bul 12
一个简单的方法是在基础模型之前添加一个卷积层,然后将输出馈送到基础模型。像这样:
from keras.models import Model
from keras.layers import Input
resnet = Resnet50(weights='imagenet',include_top= 'TRUE')
input_tensor = Input(shape=(IMG_SIZE,IMG_SIZE,1) )
x = Conv2D(3,(3,3),padding='same')(input_tensor) # x has a dimension of (IMG_SIZE,IMG_SIZE,3)
out = resnet (x)
model = Model(inputs=input_tensor,outputs=out)
Run Code Online (Sandbox Code Playgroud)
小智 9
根据当前接受的答案将灰度图像转换为RGB是解决此问题的一种方法,但不是最有效的方法。您当然可以修改模型的第一个卷积层的权重并达到指定的目标。修改后的模型将立即可用(精度降低)并且是可调的。修改第一层的权重不会像其他人所建议的那样使其余权重无用。
为此,您必须在加载预训练权重的位置添加一些代码。在您选择的框架中,您需要弄清楚如何在分配给您的1通道模型之前掌握网络中第一卷积层的权重并进行修改。所需的修改是对输入通道的尺寸上的权重张量求和。权重张量的组织方式因框架而异。PyTorch的默认值为[out_channels,in_channels,kernel_height,kernel_width]。在Tensorflow中,我相信它是[kernel_height,kernel_width,in_channels,out_channels]。
以PyTorch为例,在Torchvision的ResNet50模型(https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py)中,conv1的权重形状为[64,3 ,7,7]。对维度1求和得出张量形状[64、1、7、7]。在底部,我提供了一个代码片段,该代码片段可与Torchvision中的ResNet模型一起使用,假定已添加一个参数(inchans)为该模型指定了不同数量的输入通道。
为了证明这项工作,我在ResNet50上使用预先训练的权重进行了3次ImageNet验证。运行2和3的数字略有不同,但是这是最小的,一旦进行微调就应该无关紧要。
def _load_pretrained(model, url, inchans=3):
state_dict = model_zoo.load_url(url)
if inchans == 1:
conv1_weight = state_dict['conv1.weight']
state_dict['conv1.weight'] = conv1_weight.sum(dim=1, keepdim=True)
elif inchans != 3:
assert False, "Invalid number of inchans for pretrained weights"
model.load_state_dict(state_dict)
def resnet50(pretrained=False, inchans=3):
"""Constructs a ResNet-50 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(Bottleneck, [3, 4, 6, 3], inchans=inchans)
if pretrained:
_load_pretrained(model, model_urls['resnet50'], inchans=inchans)
return model
Run Code Online (Sandbox Code Playgroud)
为什么不尝试将灰度图像转换为 RGB 图像?
tf.image.grayscale_to_rgb(
images,
name=None
)
Run Code Online (Sandbox Code Playgroud)
删除输入层是行不通的。这将导致所有后续层都受到影响。
您可以做的是将 3 个黑白图像连接在一起以扩展您的色彩维度。
img_input = tf.keras.layers.Input(shape=(img_size_target, img_size_target,1))
img_conc = tf.keras.layers.Concatenate()([img_input, img_input, img_input])
model = ResNet50(include_top=True, weights='imagenet', input_tensor=img_conc)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
10459 次 |
最近记录: |