尝试在 Keras 中输出倒数第二层时出错

Error when trying to output previous to last layer in Keras

我正在尝试输出 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。如果我对它们进行评论,则最后一个密集层不会被有效删除(我的意思是当我在 model 上调用 predict 时,我仍然会得到最后一个密集层的输出)。我该如何解决这个问题?

此外,如果有不同的方法让模型输出前一个到最后一个密集层,我也可以将其作为答案(而不是尝试修复这种方式)。

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

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: []

试图削减模型,改变他们的 inputs/outputs 等听起来不是 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)

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

上述答案的简短版本。

#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")