所以可以说我有一些自己喜欢的Keras模型:
from keras.layers import Input, Dense, BatchNormalization, Subtract
from keras.models import Model
input_layer = Input((10, ))
x = Dense(5)(input_layer)
output_layer = Dense(10)(x)
model = Model(input_layer, output_layer)
我可以使用summary()
函数来了解我的模型,并且得到:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 10) 0
_________________________________________________________________
dense_1 (Dense) (None, 5) 55
_________________________________________________________________
dense_2 (Dense) (None, 10) 60
=================================================================
Total params: 115
Trainable params: 115
Non-trainable params: 0
_________________________________________________________________
现在,我想尝试向模型添加一些预处理和后期处理步骤,例如,我可以执行以下操作:
# Add preprocessing layers
new_input = Input((10,))
x = BatchNormalization()(new_input)
model.layers.pop(0) # remove original input
x = model(x)
# Change the model to residual modeling with a subtract layer
new_output = Subtract()([new_input, x])
new_model = Model(new_input, new_output)
但是现在当我打电话给summary()
时,我只了解预处理和后期处理层,而不是原始模型:
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_2 (InputLayer) (None, 10) 0
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 10) 40 input_2[0][0]
__________________________________________________________________________________________________
model_1 (Model) (None, 10) 115 batch_normalization_1[0][0]
__________________________________________________________________________________________________
subtract_1 (Subtract) (None, 10) 0 input_2[0][0]
model_1[1][0]
==================================================================================================
Total params: 155
Trainable params: 135
Non-trainable params: 20
__________________________________________________________________________________________________
这意味着在内部,而不是将第一个模型的每一层都添加到新模型的new_model.layers
中,而是将整个模型作为单个元素添加到new_model.layers
列表中。我希望它实际上使单个元素变平,因此摘要看起来更像这样:
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_2 (InputLayer) (None, 10) 0
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 10) 40 input_2[0][0]
__________________________________________________________________________________________________
dense_1 (Dense) (None, 5) 55 batch_normalization_1[0][0]
__________________________________________________________________________________________________
dense_2 (Dense) (None, 10) 60 dense_1[0]
__________________________________________________________________________________________________
subtract_1 (Subtract) (None, 10) 0 input_2[0][0]
dense_2[1][0]
==================================================================================================
Total params: 155
Trainable params: 135
Non-trainable params: 20
__________________________________________________________________________________________________
我为什么要关心?基本上,我正在尝试一些不同的建模方法,在这些方法中,我可以尝试将预处理和后处理以及不同的基础模型进行不同的组合,并观察它们如何影响我的结果。但是,当有关基本模型及其参数的信息全部包装在仅包含有关预处理和后期处理信息的包装模型的单个“模型”层中时,进行比较分析确实很困难。
答案 0 :(得分:0)
这是Keras的正确行为,因为Model
实际上是从Layer
继承而来的。您可以将基本模型包装到一个函数中,以阻止其包装到Model
中:
def base_model(input=None):
input_layer = input or Input((10, ))
x = Dense(5)(input_layer)
output_layer = Dense(10)(x)
if input is None:
return Model(input_layer, output_layer)
return output_layer
# Then use it
# Add preprocessing layers
new_input = Input((10,))
x = BatchNormalization()(new_input)
x = base_model(x)
# Change the model to residual modeling with a subtract layer
new_output = Subtract()([new_input, x])
new_model = Model(new_input, new_output)
如果传递现有图层,则不会包装,如果不传递,则会返回一个Model
实例。