如何在Keras中正确拼接Flatten层与特征向量?
问题重现
你尝试在Keras中把VGGFace的Flatten输出和自定义特征向量拼接,但运行时抛出了图断开的错误,你的代码如下:
# custom parameters n_features = 38 vgg_model = VGGFace(include_top=False, input_shape=(224, 224, 3)) last_layer = vgg_model.get_layer('pool5').output x = Flatten(name='flatten')(last_layer) # feature vector feature_vector = Input(shape = (n_features,)) conc = concatenate(([x, feature_vector]), axis=1) layer_intermediate = Dense(128, activation='relu', name='fc6')(conc) layer_intermediate1 = Dense(32, activation='relu', name='fc7')(layer_intermediate) out = Dense(5, activation='softmax', name='fc8')(layer_intermediate1) custom_vgg_model = Model(vgg_model.input, out)
得到的错误信息:
ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_88:0", shape=(?, 38), dtype=float32) at layer "input_88". The following previous layers were accessed without issue: ['input_87', 'conv1_1', 'conv1_2', 'pool1', 'conv2_1', 'conv2_2', 'pool2', 'conv3_1', 'conv3_2', 'conv3_3', 'pool3', 'conv4_1', 'conv4_2', 'conv4_3', 'pool4', 'conv5_1', 'conv5_2', 'conv5_3', 'pool5', 'flatten']
错误原因
这个问题的核心很直白:你的模型实际上有两个输入源——VGGFace接收的图像输入,以及你定义的38维特征向量输入,但你在创建Model对象时只传入了vgg_model.input作为唯一输入,完全没把feature_vector这个输入张量包含进去。Keras找不到这个特征向量输入的来源,自然就会报错说计算图断开了。
修正后的代码
只需要修改最后一行的Model定义,把两个输入都传进去就行,完整代码如下:
# custom parameters n_features = 38 vgg_model = VGGFace(include_top=False, input_shape=(224, 224, 3)) last_layer = vgg_model.get_layer('pool5').output x = Flatten(name='flatten')(last_layer) # feature vector feature_vector = Input(shape = (n_features,)) conc = concatenate([x, feature_vector], axis=1) # 这里可以简化括号,不用套两层 layer_intermediate = Dense(128, activation='relu', name='fc6')(conc) layer_intermediate1 = Dense(32, activation='relu', name='fc7')(layer_intermediate) out = Dense(5, activation='softmax', name='fc8')(layer_intermediate1) # 关键修改:传入两个输入组成的列表 custom_vgg_model = Model(inputs=[vgg_model.input, feature_vector], outputs=out)
额外注意事项
训练这个模型的时候,你需要传入两组输入数据,比如:
# 假设X_img是形状为(样本数,224,224,3)的图像数据,X_feat是形状为(样本数,38)的特征向量数据 custom_vgg_model.fit([X_img, X_feat], y_labels, epochs=10, batch_size=32)
预测的时候也要对应传入两个输入,这样模型才能正常运行。
内容的提问来源于stack exchange,提问作者shinigami023

