Как сделать так, чтобы включение данного слоя в модели керас было доступным для обучения? - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть следующая сиамская модель:

enter image description here

Я хотел бы сделать включение / отключение слоев a-L1 и b-L1 обучаемыми,то есть: a-L1 и / или b-L1 должны быть прозрачными (не используются или отключены) для текущего входа, если это необходимо.Итак, модель после обучения узнает, когда она должна включать / отключать один или оба слоя a-L1 и b-L1.
Мне удалось обучить эту модель четырем случаям, поэтому я получила 4 разные модели соответственно:

  • модель-1: без a-L1 и b-L1
  • модель-2: без a-L1
  • модель-3: без b-L1
  • модель-4: с a-L1 и b-L1

характеристики этих моделей дополняют друг друга, и я хотел бы объединить их.У вас есть предложения, пожалуйста?

1 Ответ

0 голосов
/ 26 ноября 2018

Предположим, вы обучили четыре модели, и назовем их m1, m2, m3 и m4

. Сначала определим входной слой, общий для всех из них.

inputs = Input(shape=your_inputs_shape)

model_1_output = m1(inputs)
model_2_output = m2(inputs)
model_3_output = m3(inputs)
model_4_output = m4(inputs)
merged_layer = Concatenate(axis=your_concatanation_axis)([model_1_output, model_2_output, model_3_output,model_4_output)
new_model = Model(inputs=inputs, outputs=merged_layer)

Я надеюсь, что это решит вашу проблему.

РЕДАКТИРОВАТЬ:

Чтобы ответить на ваш вопрос в комментариях, можно объединить только слои до L2.Но вы должны решить, какие слои модели, начиная с L2, вы собираетесь использовать (поскольку вы не комбинируете слои, начиная с L2).Предположим, вы хотите использовать слои модели m1 после L2.Кроме того, я хочу добавить механизм взвешивания, который я указал выше в комментариях к ответу.

Сначала давайте определим новые модели с общими новыми входами

new_inputs = Input(shape=(inputs_shape))
new_m1 = keras.models.Model(inputs = new_inputs, outputs = m1(new_inputs))
new_m2 = keras.models.Model(inputs = new_inputs, outputs = m2(new_inputs))
new_m3 = keras.models.Model(inputs = new_inputs, outputs = m3(new_inputs))
new_m4 = keras.models.Model(inputs = new_inputs, outputs = m4(new_inputs))

Теперь получим слой L2 для всех моделей

model1_l2 = new_m1.layers[1].get_layer("L2").output
model2_l2 = new_m2.layers[1].get_layer("L2").output
model3_l2 = new_m3.layers[1].get_layer("L2").output
model4_l2 = new_m4.layers[1].get_layer("L2").output

взвешенное слияние

merged = Concatenate(axis=your_concatanation_axis)([model1_l2, model2_l2, model3_l2,model4_l2])
merged_layer_shape = merged.get_shape().as_list()

# specify number of channels you want the output to have after merging

desired_output_channels = 32

new_trainable_weights =  keras.backend.random_normal_variable(shape=(merged_layer_shape[-1], desired_output_channels),mean=0,scale=1)
weighted_output = keras.backend.dot(merged,new_trainable_weights)

теперь соедините слой model1 (m1) рядом с L2 с этим новым weighted_output

# I'm using some protected properties of layer. But it is not recommended way to do it.
# get the index of l2 layer in new_m1
for i in range(len(new_m1.layers[1].layers)):
    if new_m1.layers[1].layers[i].name=="L2":
        index = i
x = weighted_output
for i in range(index+1, len(new_m1.layers[1].layers)):
    x = new_m1.layers[1].layers[i](x)

new_model = keras.models.Model(inputs=new_inputs, outputs=x)
...