Image 如何使用单通道图像作为VGG模型的输入

Image 如何使用单通道图像作为VGG模型的输入,image,keras,vgg-net,Image,Keras,Vgg Net,我首先使用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 现在我想改用单通道图像。所以我是这样做的: input_images = Input(shape=(img_width, img_height, 1), nam

我首先使用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
现在我想改用单通道图像。所以我是这样做的:

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)  
Model: "vgg16" __________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ================================================================================================== input_20 (InputLayer) [(None, 224, 224, 1) 0 __________________________________________________________________________________________________ concatenate_1 (Concatenate) (None, 224, 224, 3) 0 input_20[0][0] input_20[0][0] input_20[0][0] __________________________________________________________________________________________________ block1_conv1 (Conv2D) (None, 224, 224, 64) 1792 concatenate_1[0][0] 但我收到一条错误信息:

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通道图像的正确方法是什么?

不确定为什么您不能以自己的方式定义模型,但下面的方法有效。它还修复了原始定义中的错误,即必须以正确的方式规范化输入灰度图像,以匹配预训练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

根据使用的预训练模型,预处理步骤可能会有所不同。有关详细信息,请参见

不确定为什么不能按自己的方式定义模型,但下面的方法很有效。它还修复了原始定义中的错误,即必须以正确的方式规范化输入灰度图像,以匹配预训练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

根据使用的预训练模型,预处理步骤可能会有所不同。有关详细信息,请参见

我遇到了一个类似的解决方案,但它利用了现有的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)
前几层将如下所示:

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)  
Model: "vgg16" __________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ================================================================================================== input_20 (InputLayer) [(None, 224, 224, 1) 0 __________________________________________________________________________________________________ concatenate_1 (Concatenate) (None, 224, 224, 3) 0 input_20[0][0] input_20[0][0] input_20[0][0] __________________________________________________________________________________________________ block1_conv1 (Conv2D) (None, 224, 224, 64) 1792 concatenate_1[0][0]
我遇到了一个类似的解决方案,但它利用了现有的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)
前几层将如下所示:

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)  
Model: "vgg16" __________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ================================================================================================== input_20 (InputLayer) [(None, 224, 224, 1) 0 __________________________________________________________________________________________________ concatenate_1 (Concatenate) (None, 224, 224, 3) 0 input_20[0][0] input_20[0][0] input_20[0][0] __________________________________________________________________________________________________ block1_conv1 (Conv2D) (None, 224, 224, 64) 1792 concatenate_1[0][0]
谢谢你的回复!这很奇怪。我仍然会收到同样的错误信息。我的TensorFlow是1.10.0,Keras是2.2.2。我对错误消息的理解是,它认为vgg模型的第一层没有得到形状为?、64、64、3的张量。我的理解正确吗?部分正确。对于卷积层,输入维度必须是一个固定的数字,对于VGG,它是3而不是1。感谢您的回复!这很奇怪。我仍然会收到同样的错误信息。我的TensorFlow是1.10.0,Keras是2.2.2。我对错误消息的理解是,它认为vgg模型的第一层没有得到形状为?、64、64、3的张量。我的理解正确吗?部分正确。对于卷积层,输入维度必须是一个固定的数字,对于VGG,它是3而不是1。