我想对3个训练有素的模型进行加权平均合奏。因此,我想先将一个模型的softmax输出(逐个元素)乘以一个向量,然后对3个模型的3个加权输出求平均值。
我使用以下代码将第一个模型的输出乘以其权重向量:
from keras.layers import Multiply, Average
resnet_weights = np.asarray([[0.91855, 0.99485, 0.89065, 0.96525, 0.98005,
0.93645, 0.6149, 0.934, 0.92505, 0.785, 0.85]], np.float32)
resnet_weight_tensor=tf.constant(resnet_weights, np.float32)
sess = tf.InteractiveSession()
print(resnet_weight_tensor.eval())
sess.close()
resnet_weighted = Multiply()([finetuned_model.layers[-1].output, resnet_weight_tensor])
print(resnet_weighted)
new_model=Model(model.input, resnet_weighted)
但是,我遇到以下错误:
我该怎么办?
使用Lambda
代替Multiply
,用K.constant
代替tf.constant
(与后端无关:
import keras.backend as K
from keras.layers import Lambda
resnet_weights = np.asarray([[0.91855, 0.99485, 0.89065, 0.96525, 0.98005,
0.93645, 0.6149, 0.934, 0.92505, 0.785, 0.85]])
resnet_weight_tensor=K.constant(resnet_weights, 'float32')
out = finetuned_model.layers[-1].output
resnet_weighted = Lambda(lambda x: x * resnet_weight_tensor)(out)
print(resnet_weighted)
new_model = Model(model.input, resnet_weighted)
平均,您可以这样做:
from keras.layers import concatenate, GlobalAveragePooling1D
preout = concatenate([model_1.layers[-1],
model_2.layers[-1],
model_3.layers[-1]], axis=-1)
preout = GlobalAveragePooling1D()(preout)
out = Dense(num_classes, activation=your_activation)(preout)
ensemble_model = Model(ensemble_model.input, out)
可能是GlobalAveragePooling2D
,具体取决于您的尺寸-仅确保进行平均(和级联)与模型输出一起(即avg([0,0], [2,4]) == [1, 2]
,而不是==3
,它会被平均化) 。
该错误可能是由于kears api和tensorflow api的混合引起的,因为resnet_weight_tensor
是来自tensorflow api的张量,而finetuned_model.layers[-1].output
是来自keras层的输出。一些讨论可以在这里看到issue 7362
一种走动就是将resnet_weight_tensor
包装到keras Input
层中。
from keras.layers import Multiply, Average, Input
resnet_weights = np.asarray([[0.91855, 0.99485, 0.89065, 0.96525, 0.98005,
0.93645, 0.6149, 0.934, 0.92505, 0.785, 0.85]], np.float32)
resnet_weight_tensor=tf.constant(resnet_weights, np.float32)
resnet_weight_input = Input(tensor=resnet_weight_tensor)
sess = tf.InteractiveSession()
print(resnet_weight_tensor.eval())
sess.close()
resnet_weighted = Multiply()([finetuned_model.layers[-1].output, resnet_weight_input])
print(resnet_weighted)
new_model=Model([model.input, resnet_weight_input], resnet_weighted)