我创建了一个模型,它接受一个输入层并生成两个输出层。
model = Model(inputs=efficient_net.input, outputs=[reg_pred, class_pred])
我正在训练模型,接收结果并将模型的两个实例保存到两个.h5文件中。
然后,我将这两个模型放入一个列表中:
model_weights = []for item in os.listdir(packages_root): if ".h5" in item: model_weights.append(item)
所以,我有 ['model_2.h5', 'model_1.h5']
现在,我正在尝试进行集成:
def ensemble(models, model_input): Models_output = [model(model_input) for model in models] Avg = Average()(Models_output) ensemble = Model(inputs=model_input, outputs=Avg, name='ensemble') ensemble.summary() ensemble.compile(Adam(lr=.0001), loss=loss, metrics=metrics) return ensemble
然后我做:
model_input = Input(shape=models[0].input_shape[1:])
这会得到: <KerasTensor: shape=(None, 32, 32, 3) dtype=float32 (created by layer 'input_12')>
和:
ensemble_model = ensemble(models, model_input)
这会给我:
ValueError: A merge layer should be called on a list of inputs.
在这一行: Avg = Average()(Models_output)
。
所以,我尝试这样做:
def ensemble(models, model_input): Models_output = [] for model in models: Models_output.append(model(model_input)) # 连接两个输出层 Conc = Concatenate()([Models_output[0], Models_output[1]) Avg = Average()(Conc) ensemble = Model(inputs=model_input, outputs=Avg, name='ensemble') ensemble.summary() ensemble.compile(Adam(lr=.0001), loss=loss, metrics=metrics) return ensemble
这现在会给我:
ValueError: A
Concatenate layer should be called on a list of at least 2 inputs
请注意, print(Models_output)
,会得到:
[[<KerasTensor: shape=(None, 4) dtype=float32 (created by layer 'model_1')>, <KerasTensor: shape=(None, 2) dtype=float32 (created by layer 'model_1')>], [<KerasTensor: shape=(None, 4) dtype=float32 (created by layer 'model_2')>, <KerasTensor: shape=(None, 2) dtype=float32 (created by layer 'model_2')>]]
回答:
错误的原因是你对一个列表的列表而不是一个张量列表调用了Average
层。这是因为你的模型产生了两个输出(reg_pred
, class_pred
)。
你可以通过简单地构建两个Average
层来解决这个问题:一个用于回归输出,另一个用于分类输出
这是一个虚拟示例,我们训练两个模型以产生两个输出:
X = np.random.uniform(0,1, (64,28,28,1))y = np.random.randint(0,2, 64)def get_model(): inp = Input((28,28,1)) reg_pred = Dense(1)(inp) class_pred = Dense(2, activation='softmax')(Flatten()(inp)) model = Model(inp, [reg_pred, class_pred]) model.compile('adam', ['mse', 'sparse_categorical_crossentropy']) return modelmodel1 = get_model()model1.fit(X,[X,y])model2 = get_model()model2.fit(X,[X,y])
你的集成函数会产生错误:
def ensemble(models, model_input): Models_output = [model(model_input) for model in models] Avg = Average()(Models_output) ensemble = Model(inputs=model_input, outputs=Avg, name='ensemble') ensemble.compile('adam', ['mse', 'sparse_categorical_crossentropy']) return ensemblemodel_input = Input((28,28,1))models = [model1, model2]model_ensemble = ensemble(models, model_input)
如何修复它:
def ensemble(models, model_input): output_reg = [] output_class = [] for model in models: out_reg, out_class = model(model_input) output_reg.append(out_reg) output_class.append(out_class) avg_reg = Average()(output_reg) avg_class = Average()(output_class) ensemble = Model(inputs=model_input, outputs=[avg_reg, avg_class], name='ensemble') ensemble.compile('adam', ['mse', 'sparse_categorical_crossentropy']) return ensemblemodel_input = Input((28,28,1))models = [model1, model2]model_ensemble = ensemble(models, model_input)