2

我首先使用 3 通道图像作为 VGG16 模型的输入,没有问题:

input_images = Input(shape=(img_width, img_height, 3), name='image_input')
vgg_out = base_model(input_images)  # Here base_model is a VGG16

现在我想改用 1 通道图像。所以我这样做了:

input_images = Input(shape=(img_width, img_height, 1), name='image_input')
repeat_2 = concatenate([input_images, input_images])
repeat_3 = concatenate([repeat_2, input_images])
vgg_out = base_model(repeat_3)  

但我收到一条错误消息:

File "test.py", line 423, in <module>
model = Model(inputs=[input_images], outputs=[vgg_out])
File "C:\Users\wzhou\AppData\Local\Continuum\Anaconda2\envs\tensorflow\lib\site-packages\keras\legacy\interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "C:\Users\wzhou\AppData\Local\Continuum\Anaconda2\envs\tensorflow\lib\site-packages\keras\engine\network.py", line 93, in __init__
self._init_graph_network(*args, **kwargs)
File "C:\Users\wzhou\AppData\Local\Continuum\Anaconda2\envs\tensorflow\lib\site-packages\keras\engine\network.py", line 237, in _init_graph_network
self.inputs, self.outputs)
File "C:\Users\wzhou\AppData\Local\Continuum\Anaconda2\envs\tensorflow\lib\site-packages\keras\engine\network.py", line 1430, in _map_graph_network
str(layers_with_complete_input))
ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_1:0", shape=(?, 64, 64, 3), dtype=float32) at layer "input_1". The following previous layers were accessed without issue: []

在 Keras 中将 1 通道图像转换为 3 通道图像的正确方法是什么?

4

2 回答 2

4

不知道为什么你不能以你的方式定义模型,但下面的一个有效。它还修复了您在原始定义中所犯的错误,即您必须以正确的方式对输入灰度图像进行归一化,以匹配预训练 VGG 网络中使用的原始图像预处理。否则,加载预训练的权重是没有意义的。

from keras.applications.vgg16 import VGG16
from keras.layers import *
from keras import backend as K
from keras.models import Model
import numpy as np 

class Gray2VGGInput( Layer ) :
    """Custom conversion layer
    """
    def build( self, x ) :
        self.image_mean = K.variable(value=np.array([103.939, 116.779, 123.68]).reshape([1,1,1,3]).astype('float32'), 
                                     dtype='float32', 
                                     name='imageNet_mean' )
        self.built = True
        return
    def call( self, x ) :
        rgb_x = K.concatenate( [x,x,x], axis=-1 )
        norm_x = rgb_x - self.image_mean
        return norm_x
    def compute_output_shape( self, input_shape ) :
        return input_shape[:3] + (3,)

# 1. load pretrain
backbone = VGG16(input_shape=(224,224,3) )
# 2. define gray input
gray_image = Input( shape=(224,224,1), name='gray_input' )
# 3. convert to VGG input
vgg_input_image = Gray2VGGInput( name='gray_to_rgb_norm')( gray_image )
# 4. process by pretrained VGG
pred = backbone( vgg_input_image )
# 5. define the model end-to-end
model = Model( input=gray_image, output=pred, name='my_gray_vgg' )
print model.summary()

# 6. test model
a = np.random.randint(0,255,size=(2,224,224,1))
p = model.predict(a)
print p.shape

根据您使用的预训练模型,预处理步骤可能会有所不同(有关详细信息,请参阅此内容)。

于 2018-08-29T04:58:53.810 回答
2

我在 Kaggle 上遇到了类似的解决方案,但它利用了现有的 Keras 层类:

from keras.applications.vgg16 import VGG16
from keras.layers import *

img_size_target = 224
img_input = Input(shape=(img_size_target, img_size_target, 1))
img_conc = Concatenate()([img_input, img_input, img_input])  
model = VGG16(input_tensor=img_conc)

前几层将如下所示:

型号:“vgg16”
__________________________________________________________________________________________________
层(类型)输出形状参数#连接到                     
==================================================== =================================================
input_20 (InputLayer) [(无, 224, 224, 1) 0                                            
__________________________________________________________________________________________________
concatenate_1 (连接) (无, 224, 224, 3) 0 input_20[0][0]                   
                                                                 输入_20[0][0]                   
                                                                 输入_20[0][0]                   
__________________________________________________________________________________________________
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792 concatenate_1[0][0]              
于 2020-10-16T13:15:20.937 回答