Tensorflow Keras реализация многоэкземплярной задачи обучения - PullRequest
1 голос
/ 11 июля 2019

Я пытаюсь реализовать модель обучения с несколькими экземплярами с помощью TensorFlow Keras API.Предположим, что входной тензор имеет форму (None, 18, 10, 300), и мне нужно выполнить многоэкземплярное обучение с submodel вдоль axis=1.Таким образом, ввод для submodel должен быть (None, 10, 300).Предположим, что форма выходного тензора для одного submodel равна (None, 100), затем результат submodel s объединяется, таким образом, создается выходная форма (None, 18, 100).

Я реализовал этот механизм двумя способами, они должны быть функционально равными, однако при обучении модели точность второй реализации на 20% выше, чем у первой реализации (хотя обе не достаточно хороши).Интересно, есть ли функциональная разница между двумя реализациями?Если обе эти реализации не то, что я имею в виду, не могли бы вы дать правильную реализацию?

Реализация 1. В этой реализации разделить входной тензор со слоем keras Lambda, выполнить submodel,разверните размер результата в axis=1, затем объедините результат по axis=1.

def get_branch_model(input_shape, submodel, args={}):
    model_input = tf.keras.Input(input_shape)
    sliced_inputs = [tf.keras.layers.Lambda(lambda x: x[:,i])(model_input) 
                     for i in range(input_shape[0])]
    sub_instance = submodel(**args)
    branch_models = [sub_instance(sliced_inputs[i]) for i in range(input_shape[0])]
    expand_layer = tf.keras.layers.Lambda(lambda x: tf.keras.backend.expand_dims(x, axis=1))
    expanded_outputs = [expand_layer(branch_models[i]) for i in range(input_shape[0])]
    concated_layer = tf.keras.layers.Concatenate(axis=1)(expanded_outputs)
    return tf.keras.Model(model_input, concated_layer)

Реализация 2. Эта реализация использует tf.slice, чтобы разделить входной тензор, выполнить submodel, развернутьИзмерение результата в axis=1, затем объединить результат по axis=1.

def __get_filter_layer(total_dim, target_dim, index):
    def tensor_filter(tensor_in):
        nonlocal index
        begin = [0 if i != target_dim else index for i in range(total_dim)]
        size = [-1 if i != target_dim else 1 for i in range(total_dim)]
        return tf.squeeze(tf.slice(tensor_in, begin, size), axis=target_dim)
    return tf.keras.models.Sequential([
        tf.keras.layers.Lambda(tensor_filter)
    ])

def get_branch_model(input_shape, branch_index, output_shape, submodel, args={}):
    model_input = tf.keras.Input(input_shape)
    sliced_inputs = [__get_filter_layer(len(input_shape) + 1, branch_index, i)(model_input) 
                     for i in range(input_shape[branch_index - 1])]
    sub_instance = submodel(**args)
    branch_models = [sub_instance(sliced_inputs[i]) 
                     for i in range(input_shape[branch_index - 1])]
    expand_layer = tf.keras.layers.Lambda(lambda x: tf.keras.backend.expand_dims(x, axis=1))
    expanded_outputs = [expand_layer(branch_models[i]) for i in range(input_shape[0])]
    concated_layer = tf.keras.layers.Concatenate(axis=1)(expanded_outputs)
    return tf.keras.Model(model_input, concated_layer)

Вход для аргумента input_shape равен (18, 10, 300), а branch_index равен 1.submodel является последовательной моделью, такой как tf.keras.Sequential([tf.keras.layers.Dense(...)]).

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