Мне нужно обработать некоторые слои по-другому, выполняя некоторые операции 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])