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



我首先使用 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:UserswzhouAppDataLocalContinuumAnaconda2envstensorflowlibsite-packageskeraslegacyinterfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "C:UserswzhouAppDataLocalContinuumAnaconda2envstensorflowlibsite-packageskerasenginenetwork.py", line 93, in __init__
self._init_graph_network(*args, **kwargs)
File "C:UserswzhouAppDataLocalContinuumAnaconda2envstensorflowlibsite-packageskerasenginenetwork.py", line 237, in _init_graph_network
self.inputs, self.outputs)
File "C:UserswzhouAppDataLocalContinuumAnaconda2envstensorflowlibsite-packageskerasenginenetwork.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 通道图像的正确方法是什么?

我在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 (输入层( [(无, 224, 224, 1( 0                                            __________________________________________________________________________________________________ concatenate_1 (连接( (无, 224, 224, 3( 0 input_20[0][0]                    input_20[0][0]                    input_20[0][0]                   __________________________________________________________________________________________________ block1_conv1 (Conv2D( (无, 224, 224, 64( 1792 concatenate_1[0][0]

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

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

最新更新