keras compute_output_shape не работает для пользовательского слоя - PullRequest
0 голосов
/ 24 сентября 2019

Я настроил слой, объединил batch_size и первое измерение, остальные измерения остались неизменными, но compute_output_shape, похоже, не оказал никакого влияния, в результате чего последующий слой не смог получить точную информацию о форме, что привело к ошибке.Как заставить compute_output_shape работать?

import keras
from keras import backend as K

class BatchMergeReshape(keras.layers.Layer):
    def __init__(self, **kwargs):
        super(BatchMergeReshape, self).__init__(**kwargs)

    def build(self, input_shape):
        super(BatchMergeReshape, self).build(input_shape)  

    def call(self, x):
        input_shape = K.shape(x)
        batch_size, seq_len = input_shape[0], input_shape[1]
        r = K.reshape(x, (batch_size*seq_len,)+input_shape[2:])
        print("call_shape:",r.shape)
        return r

    def compute_output_shape(self, input_shape):
        if input_shape[0] is None:
            r = (None,)+input_shape[2:]
            print("compute_output_shape:",r)
            return r
        else:
            r = (input_shape[0]*input_shape[1],)+input_shape[2:]
            return r

a = keras.layers.Input(shape=(3,4,5))
b = BatchMergeReshape()(a)
print(b.shape)

# call_shape: (?, ?)
# compute_output_shape: (None, 4, 5)
# (?, ?)

Мне нужно получить (Нет, 4,5), но получить (Нет, Нет), почему compute_output_shape не работает.Моя версия keras - 2.2.4

1 Ответ

0 голосов
/ 24 сентября 2019

Проблема, вероятно, в том, что K.shape возвращает тензор , а не кортеж.Вы не можете сделать (batch_size*seq_len,) + input_shape[2:].Это смешивает много вещей, тензоров и кортежей, результат, безусловно, будет неправильным.

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

Lambda(lambda x: K.reshape(x, (-1,) + other_dimensions_tuple))

Если нет, то:

input_shape = K.shape(x)
new_batch_size = input_shape[0:1] * input_shape[1:2] #needs to keep a shape of an array   
                 #new_batch_size.shape = (1,)
new_shape = K.concatenate([new_batch_size, input_shape[2:]]) #this is a tensor   
                                                             #result of concatenating 2 tensors   

r = K.reshape(x, new_shape)

Обратите внимание, что это работает в Tensorflow, но может не работать в Theano.

Также обратите внимание, что Keras потребует, чтобы размер партии на выходе модели был равен размеру партии на входах модели.Это означает, что вам нужно будет восстановить исходный размер партии до конца модели.

...