Невозможно объединить слои Keras Lambda

Мне нужно обработать некоторые слои по-другому, выполняя некоторые операции OR. Я нашел, как это сделать, я создаю Lambda Layer и обрабатываю данные с помощью keras.backend.any . Я также делаю раскол, потому что мне нужно управлять 2, разделяя группы с моим логическим ИЛИ.

def logical_or_layer(x):
    """Processing an OR operation"""
    import keras.backend
    #normalized to 0,1 
    aux_array = keras.backend.sign(x)
    aux_array = keras.backend.relu(aux_array)
    # OR operation
    aux_array = keras.backend.any(aux_array)
    # casting back the True/False to 1,0
    aux_array = keras.backend.cast(aux_array, dtype='float32')

    return aux_array

Затем я создаю свои слои следующим образом:

#this is the input tensor
inputs = Input(shape=(inputSize,))

#this is the Neurule layer
x = Dense(neurulesQt, activation='softsign')(inputs)
#after each neurule layer, the outputs need to be put into SIGNUM (-1 or 1)
x = Lambda(signumTransform, output_shape=lambda x:x, name='signumAfterNeurules')(x)

#separating into 2 (2 possible outputs)
layer_split0 = Lambda( lambda x: x[:, :end_output0], output_shape=(11, ), name='layer_split0')(x)
layer_split1 = Lambda( lambda x: x[:, start_output1:end_output1], output_shape=(9,), name='layer_split1')(x)

#this is the OR layer
y_0 = Lambda(logical_or_layer, output_shape=(1,), name='or0')(layer_split0)
y_1 = Lambda(logical_or_layer, output_shape=(1,), name='or1')(layer_split1)

Просто FYI: Нейрулы - нейроны, созданные на основе правил IF-THEN, это один проект для работы с нейронами, которые прошли обучение с помощью TruthTable, представляя Expert Knowledge.

Теперь, когда я пытаюсь вернуть сломанные слои так:

y = concatenate([y_0,y_1])

Эта ошибка возникает:

ValueError: Can't concatenate scalars (use tf.stack instead) for 'concatenate_32/concat' (op: 'ConcatV2') with input shapes: [], [], [].

Тогда хорошо, давайте используем tf.stack как было предложено:

y = keras.backend.stack([y_0, y_1])

Тогда он больше не может использоваться как результат в модели, когда я пытаюсь:

model = Model(inputs=inputs, outputs=y)

Приходит ошибка:

ValueError: Output tensors to a Model must be the output of a Keras `Layer` (thus holding past layer metadata). Found: Tensor("stack_14:0", shape=(2,), dtype=float32)

Проверка с помощью функции keras.backend.is_keras_tensor(y) дает мне False , но со всеми остальными слоями она дает мне True

Как я должен конкатенировать его правильно?

EDIT: после ответа от @today я смог создать новый Lambda Layer со stack заключенным внутри него. Но выходы изменяются, он должен быть (None,2) и он (2,None,1) здесь является результатом model.summary() :

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_90 (InputLayer)           (None, 24)           0                                            
__________________________________________________________________________________________________
dense_90 (Dense)                (None, 20)           500         input_90[0][0]                   
__________________________________________________________________________________________________
signumAfterNeurules (Lambda)    (None, 20)           0           dense_90[0][0]                   
__________________________________________________________________________________________________
layer_split0 (Lambda)           (None, 11)           0           signumAfterNeurules[0][0]        
__________________________________________________________________________________________________
layer_split1 (Lambda)           (None, 9)            0           signumAfterNeurules[0][0]        
__________________________________________________________________________________________________
or0 (Lambda)                    (None, 1)            0           layer_split0[0][0]               
__________________________________________________________________________________________________
or1 (Lambda)                    (None, 1)            0           layer_split1[0][0]               
__________________________________________________________________________________________________
output (Lambda)                 (2, None, 1)         0           or0[0][0]                        
                                                                 or1[0][0]                        
==================================================================================================
Total params: 500
Trainable params: 0
Non-trainable params: 500
__________________________________________________________________________________________________

Как я должен определить output_shape в слоях, чтобы пакет все еще присутствовал в конце?

EDIT2: Следуя советам от @today, я сделал следующее:

#this is the input tensor
inputs = Input(shape=(inputSize,))

#this is the Neurule layer
x = Dense(neurulesQt, activation='softsign')(inputs)
#after each neuron layer, the outputs need to be put into SIGNUM (-1 or 1)
x = Lambda(signumTransform, output_shape=lambda x:x, name='signumAfterNeurules')(x)
#separating into 2 (2 possible outputs)
layer_split0 = Lambda( lambda x: x[:, :end_output0], output_shape=[11], name='layer_split0')(x)    
layer_split1 = Lambda( lambda x: x[:, start_output1:end_output1], output_shape=[9], name='layer_split1')(x)
#this is the OR layer
y_0 = Lambda(logical_or_layer, output_shape=(1,), name='or0')(layer_split0)
y_1 = Lambda(logical_or_layer, output_shape=(1,), name='or1')(layer_split1)

y = Lambda(lambda x: K.stack([x[0], x[1]]),output_shape=(2,),  name="output")([y_0, y_1])

Теперь, кажется, он работает правильно, model.summary() ниже:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 24)           0                                            
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 20)           500         input_1[0][0]                    
__________________________________________________________________________________________________
signumAfterNeurules (Lambda)    (None, 20)           0           dense_1[0][0]                    
__________________________________________________________________________________________________
layer_split0 (Lambda)           (None, 11)           0           signumAfterNeurules[0][0]        
__________________________________________________________________________________________________
layer_split1 (Lambda)           (None, 9)            0           signumAfterNeurules[0][0]        
__________________________________________________________________________________________________
or0 (Lambda)                    (None, 1)            0           layer_split0[0][0]               
__________________________________________________________________________________________________
or1 (Lambda)                    (None, 1)            0           layer_split1[0][0]               
__________________________________________________________________________________________________
output (Lambda)                 (None, 2)            0           or0[0][0]                        
                                                                 or1[0][0]                        
==================================================================================================
Total params: 500
Trainable params: 0
Non-trainable params: 500
__________________________________________________________________________________________________

Всего 1 ответ


Оберните K.stack внутри слоя Lambda следующим образом:

from keras import backend as K

y = Lambda(lambda x: K.stack([x[0], x[1]]))([y_0, y_1])

Есть идеи?

10000