Я пытаюсь объединить 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])
[...]
Я думаю, что я делаю что-то не так, но я не узнаю, что :/
Также, возможно, вам стоит использовать слой Concatenate([first, second])
. Не уверен, что это имеет значение. Ваша окончательная модель определенно не подключена прямо сейчас.
для model.summary() вот результат: i.gyazo.com/38b06fa4c449779d3683f145e6d412b8.png Я пробовал с keras.layers.Concatenate вот так: x = Concatenate()([model_simple_output, model_complexe_output])
но результат тот же :/
Являются ли формы именно такими, как вы ожидали?
Да, мне это кажется правильным, просто входные данные конкатенации должны быть выходными данными двух моделей, но это должно дать это: model_simple_output = model_simple(input_common)
нет?
Я не понимаю, в чем на самом деле проблема или вопрос, вы говорите, что он тренируется, но затем вы получаете ошибки (какие?), а затем вы используете какой-то инструмент для визуализации, но затем видите бессмысленные результаты (может быть, инструмент сломан?). Резюме вашей модели выглядит правильно, поэтому я вообще не вижу проблемы.
Ах, может быть, я неправильно истолковал проблему, да, когда я пытаюсь преобразовать окончательную модель, она также говорит, что указанный входной файл содержит только веса, но я думал, что это вызвано неправильной структурой, потому что я использую model.save("")
, а не model.save_weights("")
. Вот полная ошибка: i.gyazo.com/c51c82f839607bc2653c85fec99c3588.jpg
@EnzoDutra Итак, как вы показали ошибку, ваш вопрос заключается в том, как преобразовать файл .h5 в файл .pb или какой-то другой вопрос? Потому что model.summary()
выглядит нормально. С вашей моделью проблем нет, она идеально сцеплена.
Я не знаю, потому что у меня никогда не было проблем с преобразованием файла .h5 в файл .pb, я просто преобразовал другую модель, чтобы быть уверенным, и она работает отлично, но, похоже, есть проблема с моделью, которую я создаю здесь. Может быть, это сохраняет структуру плотных слоев, которые я добавляю, но не структуру двух моделей? У меня также есть странная структура графа на тензорной доске, где все части не кажутся связанными. (вот файл, который я получаю, если вы хотите проверить его desfichesdescartes.fr/projet/modele_total_3.h5)
@EnzoDutra, я думаю, у вас есть некоторые пользовательские вещи внутри вашей модели, которые создают проблему, может быть какой-то пользовательский слой. Это правильно или нет?
Я так не думаю, я пробовал с 2 официальными моделями Inception V3, которые у меня есть, например, i.gyazo.com/5adf6927c143461fed17a0c5367f078b.png, и проблемы точно такие же. Вот полная версия приведенного выше кода, если вы хотите попробовать pastebin.com/uqChMnVc
Я попытался создать ваш вариант использования с помощью 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
. Я думаю, это должно сработать для вас.
Странно, кажется, что он работает с VGG16 и VGG19, но не с InceptionV3 и InceptionResNetV2, из-за этого скрипты преобразования зависают, а размер файла .h5 кажется очень маленьким. Похоже, есть проблема, когда скрипт, который строит модель, сохраняет ее. Как вы думаете, это может быть ошибка? Или, может быть, это потому, что VGG - это последовательные графики, а не начальные, и ими нельзя манипулировать одинаково?
Также я не знаю почему, но когда я использую код, который вы дали, но с 2 VGG16 вместо VGG16 и VGG19, у меня возникает эта ошибка при использовании скрипта преобразования i.gyazo.com/68970e4bec3b6f52584f15142027f0cb.png
Вы распечатали свой
model.summary()
? Просто попробуйте поэкспериментировать с 3 очень простыми моделями и проверьтеsummary()
.