Проблема с использованием Elmo из хаба tensorflow в качестве настраиваемого слоя tf.keras во время прогнозирования

Я пытаюсь использовать Elmo из концентратора тензорного потока с tf.keras для выполнения NER. С тренировкой все в порядке, потери уменьшаются, тестовый набор тоже дает хорошие результаты. Но я не могу предсказать, так как получаю следующую ошибку:

2019-05-02 15:41:42.785946: I tensorflow/stream_executor/dso_loader.cc:152] successfully opened CUDA library libcublas.so.10.0 locally
Traceback (most recent call last):
  File "elmo_eva_brain.py", line 668, in <module>
    np.array([['hello', 'world'] + ['--PAD--'] * 18])))
  File "/home/ashwanipandey/eva_ml/experimental/eva_brain/venv/lib64/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1113, in predict
    self, x, batch_size=batch_size, verbose=verbose, steps=steps)
  File "/home/ashwanipandey/eva_ml/experimental/eva_brain/venv/lib64/python3.6/site-packages/tensorflow/python/keras/engine/training_arrays.py", line 329, in model_iteration
    batch_outs = f(ins_batch)
  File "/home/ashwanipandey/eva_ml/experimental/eva_brain/venv/lib64/python3.6/site-packages/tensorflow/python/keras/backend.py", line 3076, in __call__
    run_metadata=self.run_metadata)
  File "/home/ashwanipandey/eva_ml/experimental/eva_brain/venv/lib64/python3.6/site-packages/tensorflow/python/client/session.py", line 1439, in __call__
    run_metadata_ptr)
  File "/home/ashwanipandey/eva_ml/experimental/eva_brain/venv/lib64/python3.6/site-packages/tensorflow/python/framework/errors_impl.py", line 528, in __exit__
    c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: len(seq_lens) != input.dims(0), (256 vs. 1)
         [[{{node Embed/elmo/elmo_module_apply_tokens/bilm/ReverseSequence}}]]
         [[{{node Tag/t_output/transpose_1}}]]

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

Я много пытался искать в Интернете, но все было напрасно. Любая помощь горячо приветствуется. Я определенно могу получить прогнозы, если повторю свой вектор 256 раз и установлю batch_size равным 256 во время прогнозирования. Но, как видите, это очень неэффективный обходной путь.

Вот код для настраиваемого слоя

class ElmoEmbeddingLayer(keras.layers.Layer):
    def __init__(self, dimensions=1024, batch_size=512, word_size=20, **kwargs):
        self.dimensions = 1024
        self.trainable = True
        self.batch_size = _BATCH_SIZE
        self.word_size = _WORD_SIZE
        super().__init__(**kwargs)

    def build(self, input_shape):
        self.elmo = hub.Module('https://tfhub.dev/google/elmo/2', trainable=self.trainable,
                               name=f"{self.name}_module")
        super().build(input_shape)

    def call(self, x, mask=None):
        result = self.elmo(inputs={
            "tokens": K.cast(x, tf.string),
            "sequence_len": K.constant(self.batch_size*[self.word_size], dtype=tf.int32)
        },
            as_dict=True,
            signature='tokens',
        )['elmo']
        return result

    def compute_mask(self, inputs, mask=None):
        return K.not_equal(inputs, '--PAD--')

    def compute_output_shape(self, input_shape):
        return (None, self.word_size, self.dimensions)

    def get_config(self):
        config = {
            'dimensions': self.dimensions,
            'trainable': self.trainable,
            'batch_size': self.batch_size,
            'word_size': self.word_size
        }
        base_config = super().get_config()
        return dict(list(base_config.items()) + list(config.items()))

Вот моя архитектура модели: архитектура модели


person Ashwan1    schedule 02.05.2019    source источник


Ответы (2)


У меня была такая же проблема с вами, работая над моделью pos-tagger RNN ELMo. Наконец, я следил за решением, прогнозирующим партиями и сохраняющим тестовый образец, который мне нужен:

model.predict([X_test[:split_te]], batch_size=256)[0]

Дополнительные идеи (например, копирование весов) см. здесь!

person Stamatis Outsios    schedule 03.05.2019
comment
Я применил метод копирования весов, и он сработал. Спасибо. - person Ashwan1; 06.05.2019

Количество образцов (в поезде, а также в тестовом наборе) должно делиться на batch_size. В противном случае последняя партия в keras нарушит архитектуру. Так, например, решение состоит в том, чтобы использовать образцы до split_tr для обучения и split_te для прогнозирования:

split_tr = (X_train.shape[0]//BATCH_SIZE)*BATCH_SIZE
split_te = (X_test.shape[0]//BATCH_SIZE)*BATCH_SIZE
model.fit(X_train_text[:split_tr], y_train[:split_tr], batch_size=BATCH_SIZE, epochs=15, validation_data=(X_test_text[:split_te], y_test[:split_te]), verbose=1)
person Stamatis Outsios    schedule 02.05.2019
comment
У меня нет проблем во время тренировки или тестирования. Они работают нормально. Моя проблема в прогнозировании. И при прогнозировании я хочу прогнозировать только одно предложение, а не весь пакет. Я отредактировал свой вопрос, чтобы более четко передать это намерение. - person Ashwan1; 03.05.2019