Python 尝试合并两个模型的输入和输出时出现问题
我正在尝试合并两个使用不同数据集和不同类数训练的模型,以获得具有唯一输入和唯一输出的最终模型 最终结果应该是这样的:Python 尝试合并两个模型的输入和输出时出现问题,python,tensorflow,keras,conv-neural-network,Python,Tensorflow,Keras,Conv Neural Network,我正在尝试合并两个使用不同数据集和不同类数训练的模型,以获得具有唯一输入和唯一输出的最终模型 最终结果应该是这样的: [...] stuffs with imports, tensorboard and imageDataGenerator [...] model_simple = load_model("model_simple.h5") model_simple.name = 'model_simple' for layer in model_simple.layers:
[...]
stuffs with imports, tensorboard and imageDataGenerator
[...]
model_simple = load_model("model_simple.h5")
model_simple.name = 'model_simple'
for layer in model_simple.layers:
layer.trainable = False
layer.name = layer.name + str("_simple")
model_complexe = load_model("model_complexe.h5")
model_complexe.name = 'model_complexe'
for layer in model_complexe.layers:
layer.trainable = False
layer.name = layer.name + str("_complexe")
model_simple.layers.pop(0)
model_complexe.layers.pop(0)
input_common = Input(shape=(299, 299, 3), name="input_common")
model_simple_output = model_simple(input_common)
model_complexe_output = model_complexe(input_common)
x = concatenate([model_simple_output, model_complexe_output])
x = Dense((2 * NB_CLASSES), activation='relu')(x)
x = Dense((2 * NB_CLASSES)*2, activation='relu')(x)
x = Dense((2 * NB_CLASSES)*2, activation='relu')(x)
x = Dense(NB_CLASSES, activation='relu')(x)
output = Dense(NB_CLASSES, activation='sigmoid')(x)
model = Model(inputs=input_common, outputs=output)
model.compile(optimizer=Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, epsilon=1e-8, amsgrad=True), loss='categorical_crossentropy', metrics=['acc'])
model.fit_generator(
train_generator,
steps_per_epoch=NB_FIC_TRAIN // BATCH_SIZE,
epochs=1,
validation_data=validation_generator,
validation_steps=NB_FIC_VAL // BATCH_SIZE,
callbacks = [tensorboard]
)
model.save("modele_final.h5")
实际上我的代码是这样的:
[...]
stuffs with imports, tensorboard and imageDataGenerator
[...]
model_simple = load_model("model_simple.h5")
model_simple.name = 'model_simple'
for layer in model_simple.layers:
layer.trainable = False
layer.name = layer.name + str("_simple")
model_complexe = load_model("model_complexe.h5")
model_complexe.name = 'model_complexe'
for layer in model_complexe.layers:
layer.trainable = False
layer.name = layer.name + str("_complexe")
model_simple.layers.pop(0)
model_complexe.layers.pop(0)
input_common = Input(shape=(299, 299, 3), name="input_common")
model_simple_output = model_simple(input_common)
model_complexe_output = model_complexe(input_common)
x = concatenate([model_simple_output, model_complexe_output])
x = Dense((2 * NB_CLASSES), activation='relu')(x)
x = Dense((2 * NB_CLASSES)*2, activation='relu')(x)
x = Dense((2 * NB_CLASSES)*2, activation='relu')(x)
x = Dense(NB_CLASSES, activation='relu')(x)
output = Dense(NB_CLASSES, activation='sigmoid')(x)
model = Model(inputs=input_common, outputs=output)
model.compile(optimizer=Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, epsilon=1e-8, amsgrad=True), loss='categorical_crossentropy', metrics=['acc'])
model.fit_generator(
train_generator,
steps_per_epoch=NB_FIC_TRAIN // BATCH_SIZE,
epochs=1,
validation_data=validation_generator,
validation_steps=NB_FIC_VAL // BATCH_SIZE,
callbacks = [tensorboard]
)
model.save("modele_final.h5")
当我启动它时,它不会崩溃,它正在训练,但当我仔细观察时,它似乎是一团混乱(当我试图将它转换为.pb时,它抛出了错误,表示该模型有0个张量输入)
最后一个文件的大小几乎与model_simple.h5文件相同,当我使用netron查看该文件时,不同的部分(2个模型和密集层)似乎没有连接:
(简单模型的图层在左边,“复杂”模型的图层在右边)
连接层将模型作为输入,而不是模型输出:
如果我像那样使用“.output”也是一样的:
[...]
model_simple_output = model_simple(input_common)
model_complexe_output = model_complexe(input_common)
new_model_simple = Model(input_common, model_simple_output)
new_model_complexe = Model(input_common, model_complexe_output)
x = concatenate([new_model_simple.output, new_model_complexe.output])
[...]
我认为我做错了什么,但我不知道是什么:/我尝试使用VGG16和VGG19创建您的用例,如下所示:
from keras.layers import *
from keras.models import *
from keras.applications.vgg16 import VGG16
from keras.applications.vgg19 import VGG19
model_1 = VGG16(include_top=True, weights='imagenet')
model_2 = VGG19(include_top=True, weights='imagenet')
然后我用你脚本的一部分来制作模型
NB_CLASSES = 73
input_common = Input(shape=(224, 224, 3), name="input_common")
model_simple_output = model_1(input_common)
model_complexe_output = model_2(input_common)
x = concatenate([model_simple_output, model_complexe_output])
x = Dense((2 * NB_CLASSES), activation='relu')(x)
x = Dense((2 * NB_CLASSES)*2, activation='relu')(x)
x = Dense((2 * NB_CLASSES)*2, activation='relu')(x)
x = Dense(NB_CLASSES, activation='relu')(x)
output = Dense(NB_CLASSES, activation='sigmoid')(x)
model = Model(inputs=input_common, outputs=output)
以保存模型。如果只使用model.save
,它也应该可以工作。但是您也可以尝试将模型保存为json,使用json将模型保存为字符串。它不会保存您的权重,如果您想单独保存权重,请使用model.save_weights
model.summary()
model.save('model.h5')
model_json = model.to_json()
with open("model.json", "w") as json_file:
json_file.write(model_json)
我可能使用了相同的文件将.h5
文件转换为您使用的.pb
git clone https://github.com/amir-abdi/keras_to_tensorflow.git
python keras_to_tensorflow/keras_to_tensorflow.py --input_model=model.h5 \
--input_model_json=model.json \
--output_model=model.pb
keras_to_tensorflow.py
也可以在不使用--输入模型\u json=model.json的情况下工作,因为model.h5
同时包含模型和权重。但对于您的情况,我更愿意使用——input\u model\u json
。我认为它应该适合您。我尝试使用VGG16和VGG19创建您的用例,如下所示:
from keras.layers import *
from keras.models import *
from keras.applications.vgg16 import VGG16
from keras.applications.vgg19 import VGG19
model_1 = VGG16(include_top=True, weights='imagenet')
model_2 = VGG19(include_top=True, weights='imagenet')
然后我用你脚本的一部分来制作模型
NB_CLASSES = 73
input_common = Input(shape=(224, 224, 3), name="input_common")
model_simple_output = model_1(input_common)
model_complexe_output = model_2(input_common)
x = concatenate([model_simple_output, model_complexe_output])
x = Dense((2 * NB_CLASSES), activation='relu')(x)
x = Dense((2 * NB_CLASSES)*2, activation='relu')(x)
x = Dense((2 * NB_CLASSES)*2, activation='relu')(x)
x = Dense(NB_CLASSES, activation='relu')(x)
output = Dense(NB_CLASSES, activation='sigmoid')(x)
model = Model(inputs=input_common, outputs=output)
以保存模型。如果只使用model.save
,它也应该可以工作。但是您也可以尝试将模型保存为json,使用json将模型保存为字符串。它不会保存您的权重,如果您想单独保存权重,请使用model.save_weights
model.summary()
model.save('model.h5')
model_json = model.to_json()
with open("model.json", "w") as json_file:
json_file.write(model_json)
我可能使用了相同的文件将.h5
文件转换为您使用的.pb
git clone https://github.com/amir-abdi/keras_to_tensorflow.git
python keras_to_tensorflow/keras_to_tensorflow.py --input_model=model.h5 \
--input_model_json=model.json \
--output_model=model.pb
keras_to_tensorflow.py
也可以在不使用--输入模型\u json=model.json的情况下工作,因为model.h5
同时包含模型和权重。但对于您的情况,我更愿意使用——input\u model\u json
。我想它应该适合你。你打印了你的model.summary()
?只需使用3个非常简单的模型进行实验,并检查summary()
。也许您应该使用连接([第一,第二])
层。我不确定这是否有区别。您的最终模型现在肯定没有连接。对于model.summary(),结果如下:我尝试使用keras.layers.Concatenate这样:x=Concatenate()([model\u simple\u output,model\u complexe\u output])
但结果是一样的:/这些形状正是您所期望的吗?是的,我觉得很对,仅连接的输入应该是两个模型的输出,但这应该是:model\u simple\u output=model\u simple(input\u common)
no?是否打印了model.summary()
?只需使用3个非常简单的模型进行实验,并检查summary()
。也许您应该使用连接([第一,第二])
层。我不确定这是否有区别。您的最终模型现在肯定没有连接。对于model.summary(),结果如下:我尝试使用keras.layers.Concatenate这样:x=Concatenate()([model\u simple\u output,model\u complexe\u output])
但结果是一样的:/这些形状正是您所期望的吗?是的,我觉得很对,仅仅是concatenate的输入应该是这两个模型的输出,但这应该是这样的:model\u simple\u output=model\u simple(input\u common)
no?这很奇怪,它似乎适用于VGG16和VGG19,但不适用于InceptionV3和InceptionResNetV2,这会使转换脚本冻结,.h5文件大小看起来非常小。当构建模型的脚本保存它时,似乎出现了问题。你认为可能是虫子吗?或者可能是因为VGG是序列图,而不是接收图,它们不能以相同的方式进行操作?我也不知道为什么,但当我使用你给出的代码,但使用2 VGG16而不是VGG16和VGG19时,我在使用转换脚本时出现了这个错误,这很奇怪,它似乎与VGG16和VGG19一起工作,但与InceptionV3和InceptionResNetV2不一起工作,它使转换脚本冻结,.h5文件大小看起来非常小。当构建模型的脚本保存它时,似乎出现了问题。你认为可能是虫子吗?或者可能是因为VGG是序列图,而不是接收图,它们不能以相同的方式进行操作?我也不知道为什么,但当我使用你给出的代码,但使用2 VGG16而不是VGG16和VGG19时,我在使用转换脚本时出现了这个错误