Проблема при попытке объединить входы и выходы 2 моделей - PullRequest
1 голос
/ 09 апреля 2019

Я пытаюсь объединить 2 модели, обученные с разными наборами данных и количеством классов, чтобы получить окончательную модель с уникальным входом и уникальным выходом.

Окончательный результат должен быть примерно таким:

схема окончательной модели

На самом деле мой код такой:

[...]
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])

[...]

Я думаю, что делаю что-то не так, но я не знаю, что: /

1 Ответ

0 голосов
/ 09 апреля 2019

Я попытался создать ваш сценарий использования, используя 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, используя model.to_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 также работает без --input_model_json=model.json, поскольку model.h5 содержит как модель, так и веса.Но для вашего случая я бы предпочел использовать с --input_model_json.Я думаю, что это должно работать для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...