我有一个keras模型(已经过训练),我想分成两部分(一部分计算原始输入的内部表示,另一部分计算预计算内部表示的输出)
获得第一部分很简单(输入到内部表示) 但第二部分是有问题的
我找到了两个相关的答案,但在我的案例中它们是有问题的
这些答案中描述的方法是:
在此解决方案中,您重新定义了网络的第二部分 - 这似乎是可行的,但需要大量的代码重复(网络非常复杂)
在此解决方案中,模型由两个模型的组合定义 - 这看起来是一个很好的解决方案,但与现有的经过培训的网络无关
答案 0 :(得分:2)
我找到的最佳解决方案:
定义“嵌套”模型(子模型的组合) - this答案中的建议
确保图层名称与旧模型中的图层名称相对应 - 这是重要的部分,因为它使图层映射更简单
将权重从旧模型复制到新模型 - 如下例所示:
for sub_model in filter(lambda l: isinstance(l, keras.models.Model), new_model.model.layers):
for layer in filter(lambda l: l.weights, sub_model.layers):
layer.set_weights(original_model.model.get_layer(layer.name).get_weights())
答案 1 :(得分:1)
这是我的解决方案(仅适用于顺序模型)。我在MobileNet2上使用了它,它对我来说效果很好,只需调用该函数并提供预训练的模型和要分割的索引,它将返回两个分割的模型:
def split_keras_model(model, index):
'''
Input:
model: A pre-trained Keras Sequential model
index: The index of the layer where we want to split the model
Output:
model1: From layer 0 to index
model2: From index+1 layer to the output of the original model
The index layer will be the last layer of the model_1 and the same shape of that layer will be the input layer of the model_2
'''
# Creating the first part...
# Get the input layer shape
layer_input_1 = Input(model.layers[0].input_shape[1:])
# Initialize the model with the input layer
x = layer_input_1
# Foreach layer: connect it to the new model
for layer in model.layers[1:index]:
x = layer(x)
# Create the model instance
model1 = Model(inputs=layer_input_1, outputs=x)
# Creating the second part...
# Get the input shape of desired layer
input_shape_2 = model.layers[index].get_input_shape_at(0)[1:]
print("Input shape of model 2: "+str(input_shape_2))
# A new input tensor to be able to feed the desired layer
layer_input_2 = Input(shape=input_shape_2)
# Create the new nodes for each layer in the path
x = layer_input_2
# Foreach layer connect it to the new model
for layer in model.layers[index:]:
x = layer(x)
# create the model
model2 = Model(inputs=layer_input_2, outputs=x)
return (model1, model2)
答案 2 :(得分:0)
您可以使用以下函数来拆分模型
from keras.layers import Input
from keras.models import Model
def get_bottom_top_model(model, layer_name):
layer = model.get_layer(layer_name)
bottom_input = Input(model.input_shape[1:])
bottom_output = bottom_input
top_input = Input(layer.output_shape[1:])
top_output = top_input
bottom = True
for layer in model.layers:
if bottom:
bottom_output = layer(bottom_output)
else:
top_output = layer(top_output)
if layer.name == layer_name:
bottom = False
bottom_model = Model(bottom_input, bottom_output)
top_model = Model(top_input, top_output)
return bottom_model, top_model
bottom_model, top_model = get_bottom_top_model(model, "dense_1")
Layer_name 只是您要拆分的图层的名称。