Уникальное переименование ВСЕХ слоев в модели Keras («ValueError: Все имена слоев должны быть уникальными.») - PullRequest
0 голосов
/ 30 апреля 2020

Python Версия: 3.6.10
Версия Tensorflow: 1.15.0
Версия Keras: 2.3.1

Я пытаюсь создать модель Keras, которая объединяет выходные данные нескольких функции экстракторов. Все экстракторы функций уникальны и обучаются отдельно, и каждый из них сохраняется в своем собственном уникальном файле. Я полагаю, что я даю каждому слою в каждом экстракторе объектов уникальное имя:

Features = keras.applications.vgg16.VGG16(

    input_shape = IMAGE_SIZE,
    weights = "imagenet",
    pooling = FEATURE_POOLING,
    include_top = False

)

for i, layer in enumerate(Features.layers):
    layer._name = "Features_" + FEATURE_EXTRACTOR + "_" + image_type + str(i) + "_" + layer.name
        # ^ DON'T EVER SET layer.name EVEN IN OLD VERSIONS OF TENSORFLOW / KERAS,
        # EVEN IF COPYING AND PASTING SUPPOSEDLY FUNCTIONAL CODE FROM OFFICIAL DOCS.
        # ALWAYS SET layer._name INSTEAD!!!

Я считаю, что я также даю каждому слою в родительской модели экстрактора объектов уникальное имя:

img = keras.models.Input(shape = IMAGE_SIZE)
x = Features(img)
# Many layers removed for simplicity, doesn't change error
x = keras.layers.Dense(1)(x)

parent_model = keras.models.Model(inputs = img, outputs = x, name = FEATURE_EXTRACTOR + "_" + image_type + "_parent")

for i, layer in enumerate(parent_model.layers):
    layer._name = FEATURE_EXTRACTOR + "_" + image_type + str(i) + "_" + layer.name

Когда я загружаю эти родительские модели в ubermodel, я полагаю, что я также даю каждому из них и всем их слоям уникальные имена:

def headless(weights_path, image_type):

    json_path = weights_path[:-3] + ".json"
    model_structure = json.load(open(json_path, "r"))
    full_model = keras.models.model_from_json(model_structure, custom_objects = {"mish": mish})
    full_model.load_weights(weights_path)

    headless_model = keras.models.Model(

        inputs = full_model.input,
        outputs = full_model.get_layer(index = -2).output,
        name = FEATURE_EXTRACTOR + "_headless_" + image_type

    )

    for i, layer in enumerate(headless_model.layers):
        layer._name = "Headless_" + FEATURE_EXTRACTOR + "_" + image_type + str(i) + "_" + layer.name

    return headless_model

models_list = []
combo_name = FEATURE_EXTRACTOR + "_"
for image_type in INCLUDED_IMAGES:
    models_list.append(headless(os.path.sep.join([my_path, "models", FEATURE_EXTRACTOR + "_" + image_type + ".h5"]), image_type))
    combo_name += image_type + "_"

И я считаю, что я даю каждый слой в ubermodel имеет уникальное имя:

concatenated_inputs = list(map(lambda z: z.input, models_list))
concatenated_outputs = list(map(lambda z: z.output, models_list))

x = keras.layers.concatenate(concatenated_outputs)
# Many layers removed for simplicity, doesn't change error
x = keras.layers.Dense(1, kernel_initializer = INITIALIZER, activation = "linear")(x)

ubermodel = keras.models.Model(inputs = concatenated_inputs, outputs = x, name = FEATURE_EXTRACTOR + "_combo_parent")

for i, layer in enumerate(ubermodel.layers):
    layer._name = combo_name + str(i) + "_" + layer.name

Теперь вы можете подумать про себя: «Боже мой, какого черта он переименовывает абсолютно все везде ?!» Ну, сначала я этого не делал, но всякий раз, когда я пытался запустить скрипт ubermodel, я получал ValueError: The name "input_2" is used 5 times in the model. All layer names should be unique. Так что я подумал: «Хорошо, я просто дам каждому слою в моей ubermodel уникальное имя» и попытался Сделай так. Это не сработало. Та же ошибка. Поэтому я подумал: «Может быть, подмоделям - то есть моделям как слоям - нужно также переименовать все их слои?» Я попытался это сделать. Это не сработало. Та же ошибка. Поэтому я подумал: «Ну, ладно, у этих подмоделей также есть субподмодели - то есть у субмоделей также есть модели в виде слоев - может быть, мне тоже нужно переименовать все эти слои ??» Я попытался это сделать. Это не сработало. Та же ошибка.

Есть ЛЮБОЙ СПОСОБ просто сказать Керасу: «Хорошо, я использую эту модель. Пожалуйста, рассматривайте ее как уникальную и отделенную от всего остального, и позвольте мне использовать ее, не жалуясь на имена. " Имейте в виду, что я даже не пытаюсь использовать одну и ту же модель дважды внутри ubermodel - то есть я не делаю модель "общего видения" или что-то в этом роде. Все решения, которые я нашел в StackOverflow и в других местах на inte rnet, просто рекомендуют переименовать все слои в ваших моделях. Ну, насколько я могу судить, каждая из моих моделей, подмоделей и подмоделей имеет все свои слои, уникально переименованные в wazoo, в дополнение к тому, что они обучаются отдельно и сохраняются отдельно, каждый в свой собственный файл. Как я могу заставить Keras просто позволить мне использовать модели?!

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