Если тогда внутри пользовательского не обучаемого слоя керас - PullRequest
0 голосов
/ 06 марта 2020

У меня есть пользовательский слой Keras, который я хочу вернуть заданным c выводом из указанных c входов. Я не хочу, чтобы он был обучаемым.

Слой должен сделать следующее

if input = [1,0] then output = 1
if input = [0,1] then output = 0

Вместо этого он всегда выдает -1, значение, которое я устанавливаю, если есть проблема.

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

if(test_mask_1_result_count == 2)

Вот пользовательский слой:

class my_custom_layer(layers.Layer):

    def __init__(self, **kwargs):
        super(my_custom_layer, self).__init__(**kwargs)

    def call(self, inputs,training=None):

        def encode():

            # set up the test mask:
            test_mask_1 = np.array([0,1],dtype=np.int32)
            k_test_mask_1 = backend.variable(value=test_mask_1)

            # test if the input is equal to the test mask
            test_mask_1_result = backend.equal(inputs,k_test_mask_1)

            # add up all the trues
            test_mask_1_result_count = tf.reduce_sum(tf.cast(test_mask_1_result, tf.int32))

            # return if we've found the right mask
            if(test_mask_1_result_count == 2):
                res = np.array([0]).reshape((1,)) #top left
                k_res = backend.variable(value=res)
                return k_res

            # set up to test the second mask
            test_mask_2 = np.array([1,0],dtype=np.int32)
            k_test_mask_2 = backend.variable(value=test_mask_2)

            # test if the input is equal to the test mask
            test_mask_2_result = backend.equal(inputs,k_test_mask_2)

            # add up all the trues
            test_mask_2_result_count = tf.reduce_sum(tf.cast(test_mask_2_result, tf.int32))

            # return if we've found the right mask
            if(test_mask_2_result_count == 2):
                res = np.array([1]).reshape((1,)) #top left
                k_res = backend.variable(value=res)
                return k_res


            # if we've got here we're in trouble:
            res = np.array([-1]).reshape((1,)) #top left
            k_res = backend.variable(value=res)
            return k_res


        return encode()

    def compute_output_shape(self, input_shape):
        return (input_shape[0],1) 

Почему if никогда не появляется триггер?

Я также создал MWE, используя керары вне сети. Кажется, это работает как задумано:

mask_1 = np.array([1,0],dtype=np.int32)
k_mask_1 = backend.variable(value=mask_1)

input_1 = np.array([1,0],dtype=np.int32)
k_input_1 = backend.variable(value=input_1)


mask_eq = backend.equal(k_input_1,k_mask_1)

mask_eq_sum = tf.reduce_sum(tf.cast(mask_eq, tf.int32))

# keras backend
sess = backend.get_session()

print(sess.run(mask_eq_sum))

Выходы 2

Я подозреваю, что есть нечто фундаментальное, чего я не понимаю.

1 Ответ

1 голос
/ 06 марта 2020

Я не уверен, в чем проблема с вашим кодом, но ваш уровень кажется гораздо сложнее, чем необходимо. Например,

my_custom_layer = layers.Lambda(lambda x: x[0])

должно соответствовать вашим требованиям. Если вы хотите, чтобы он был более надежным, вы можете использовать

my_custom_layer = layers.Lambda(lambda x: 1 if x == [1,0] else 0 if x == [0,1] else -1)

или

def mask_func(in_t):
    if in_t == [1,0]:
        return 1
    elif in_t == [0,1]:
        return 0
    else:
        return -1
my_custom_layer = layers.Lambda(mask_func)

. Предполагая, что вы используете TF2.0, пользовательские слои довольно мягки. Очевидно, что если вы используете это для обработки пакетов, вам нужно будет немного его изменить, но, надеюсь, вы поймете это.

...