Как исправить размеры слоя активации для LSTM в keras с замаскированным слоем

Посмотрев на следующую суть и проведя некоторые базовые тесты, я пытаюсь создать NER система с использованием LSTM в keras. Я использую генератор и вызываю fit_generator.

Вот моя базовая модель keras:

model = Sequential([
    Embedding(input_dim=max_features, output_dim=embedding_size, input_length=maxlen, mask_zero=True),
    Bidirectional(LSTM(hidden_size, return_sequences=True)),
    TimeDistributed(Dense(out_size)),
    Activation('softmax')
])
model.compile(loss='binary_crossentropy', optimizer='adam')

Мой входной размер кажется правильным:

>>> generator = generate()
>>> i,t = next(generator)
>>> print( "Inputs: {}".format(model.input_shape))
>>> print( "Outputs: {}".format(model.output_shape))
>>> print( "Actual input: {}".format(i.shape))
Inputs: (None, 3949)
Outputs: (None, 3949, 1)
Actual input: (45, 3949)

Однако, когда я звоню:

model.fit_generator(generator, steps_per_epoch=STEPS_PER_EPOCH, epochs=EPOCHS)

Кажется, я получаю следующую ошибку:

ValueError: 
  Error when checking target: 
    expected activation_1 to have 3 dimensions, 
    but got array with shape (45, 3949)

Я видел несколько других примеров похожие проблемы, из-за чего я считаю, что мне нужно Flatten() вводить данные до Activation(), но если я это сделаю, я получу следующую ошибку.

Layer flatten_1 does not support masking, 
but was passed an input_mask: 
    Tensor("embedding_37/NotEqual:0", shape=(?, 3949), dtype=bool)

Как и в предыдущих вопросах, мой генератор функционально эквивалентен:

def generate():
    maxlen=3949
    while True:
        inputs = np.random.randint(55604, size=maxlen)
        targets = np.random.randint(2, size=maxlen)
        yield inputs, targets

Я не предполагаю, что мне нужно Flatten, и я открыт для дополнительных предложений.


person Nathan McCoy    schedule 01.11.2017    source источник
comment
Не могли бы вы предоставить нам код generator?   -  person Marcin Możejko    schedule 01.11.2017
comment
Я обновил вопрос с помощью генератора, который генерирует случайные массивы одинаковых размеров.   -  person Nathan McCoy    schedule 02.11.2017


Ответы (1)


Вам либо нужно вернуть только последний элемент последовательности (return_sequences=False):

model = Sequential([
    Embedding(input_dim=max_features, output_dim=embedding_size, input_length=maxlen, mask_zero=True),
    Bidirectional(LSTM(hidden_size)),
    Dense(out_size),
    Activation('softmax')
])

Или удалите маскировку (mask_zero=False), чтобы иметь возможность использовать Flatten:

model = Sequential([
    Embedding(input_dim=max_features, output_dim=embedding_size, input_length=maxlen),
    Bidirectional(LSTM(hidden_size, return_sequences=True)),
    TimeDistributed(Dense(out_size)),
    Flatten(),
    Activation('softmax')
])

* Будьте осторожны, вывод будет out_size x maxlen.

И я думаю, что вы хотите первый вариант.

Редактировать 1: Глядя на примерную диаграмму, она делает прогноз для каждого временного шага, поэтому также требуется активация softmax TimeDistributed. Целевой размер должен быть (None, maxlen, out_size):

model = Sequential([
    Embedding(input_dim=max_features, output_dim=embedding_size, input_length=maxlen, mask_zero=True),
    Bidirectional(LSTM(hidden_size, return_sequences=True)),
    TimeDistributed(Dense(out_size)),
    TimeDistributed(Activation('softmax'))
])
person Julio Daniel Reyes    schedule 02.11.2017
comment
Если я попытаюсь сделать первый вариант и удалить return_sequences=True и TimeDistributed, то я получу Error when checking target: expected activation_1 to have shape (None, 1) but got array with shape (45, 3949) - person Nathan McCoy; 02.11.2017
comment
В ошибке говорится, что ваш вывод равен (None, 1), но ваш целевой размер равен (None, 3949), при условии, что out_size = 1 и maxlen = 3949, я думаю, у вас есть второй вариант out_size x maxlen. Также вы уверены, что хотите активировать softmax? Извините, я не знаком с системами NER, однако я могу помочь вам получить правильные результаты, если у вас есть схема вашей сети. - person Julio Daniel Reyes; 02.11.2017
comment
маскированные значения необходимы, поскольку переданные векторы padded, как показано в примере здесь. - person Nathan McCoy; 02.11.2017
comment
Обновил мой ответ, обязательно проверьте целевую форму (maxlen, out_size) - person Julio Daniel Reyes; 02.11.2017