尝试在Keras中输出上一层到上一层时出错

时间:2017-11-30 04:20:20

标签: python deep-learning keras keras-2

我正在尝试在keras模型中输出上一个Dense图层。我首先加载模型架构和权重:

base_model = applications.ResNet50(weights = None,
                                            include_top = False, 
                                            input_shape = (image_size[0], image_size[1], nb_channels))
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(1024, init = 'glorot_uniform', activation='relu', name = 'last_layer_1024'))
top_model.add(Dropout(0.5))
top_model.add(Dense(nb_classes, activation = 'softmax', name = 'softmax_layer'))
top_model_tensor = top_model(base_model.output)
model = Model(inputs = base_model.input, outputs = top_model_tensor)
model.load_weights(weights_path)

然后我通过这样做删除最后一个Dense图层:

model.layers[-1].pop()
#model.outputs = [model.layers[-1].layers[-1].output]
#model.layers[-1].layers[-1].outbound_nodes = []

如果我取消注释注释行,我会收到此错误:InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'flatten_1_input' with dtype float。如果我对它们进行评论,那么最后一个密集层就不会被有效删除(我的意思是,当我在predict上调用model时,我仍然得到最后一个密集层的输出。我该如何解决这个问题?

另外,如果有一种不同的方法让模型输出上一个到最后一个密集层,我也可以把它当作一个答案(而不是试图修复这种方式)。

另一个不起作用的解决方案是在加载权重后通过简单地执行此操作来剪切长模型:

short_top_model = Model(top_model.input, top_model.get_layer('last_layer_1024').output)

您收到以下错误:

RuntimeError: Graph disconnected: cannot obtain value for tensor Tensor("flatten_1_input:0", shape=(?, 1, 1, 2048), dtype=float32, device=/device:GPU:2) at layer "flatten_1_input". The following previous layers were accessed without issue: []

2 个答案:

答案 0 :(得分:2)

尝试削减模型,更改输入/输出等等听起来并不是keras对用户的期望。

您应该创建一个遵循相同路径但更早结束的另一个模型:

#do this "before" creating "top_model_tensor".
short_top = Model(
                  top_model.input,
                  top_model.get_layer('last_layer_1024').output
                 )

top_model_out = top_model(base_model.output)
short_top_out = short_top(base_model.output)

model = Model(base_model.input,top_model_out)
short_model = Model(base_model.input,short_top_out)

根据预期结果选择使用哪一个。训练一更新另一个。

答案 1 :(得分:0)

上述答案的简短版本。

#again create connection between two model
feature_vec_model = Model(
                  top_model.input,
                  top_model.get_layer('last_layer_1024').output
                 )
feature_vec_model_output = feature_vec_model(base_model.output)
#Connection created


# Define final connected model & load pretrained weights
complete_feature_vec_model = Model(base_model.input,feature_vec_model_output)
complete_feature_vec_model.load_weights("path_to_model")