Ошибка при попытке изменить форму тензора в модели керас - PullRequest
1 голос
/ 11 апреля 2019

Я хочу изменить форму и содержание тензора в модели кераса. Тензор является выходом слоя и имеет

shape1=(batch_size, max_sentences_in_doc, max_tokens_in_doc, embedding_size)

и я хочу конвертировать в

shape2=(batch_size, max_documents_length, embedding_size)

подходит для ввода следующего слоя. Здесь предложения состоят из токенов и дополняются нулями, поэтому каждое предложение имеет length=max_tokens_in_sentence. Подробно:

  1. Я хочу объединить все предложения пакета, взяв только ненулевую часть предложений;
  2. затем я обнуляю эту конкатенацию до length=max_document_length.

Таким образом, переход от shape1 к shape2 является не только изменением формы, поскольку в нем задействованы математические операции.

Я создал функцию embedding_to_docs(x), которая перебирает тензор shape1, чтобы преобразовать его в shape2. Я вызываю функцию с использованием лямбда-слоя в модели, она работает в режиме отладки с вымышленными данными, но когда я пытаюсь вызвать ее во время построения модели, возникает ошибка:

Tensor objects are only iterable when eager execution is enabled. To iterate over this tensor use tf.map_fn.

def embedding_to_docs(x):
    new_output = []
    for doc in x:
        document = []
        for sentence in doc:
            non_zero_indexes = np.nonzero(sentence[:, 0])
            max_index = max(non_zero_indexes[0])
            if max_index > 0:
                document.extend(sentence[0:max_index])
        if MAX_DOCUMENT_LENGTH-len(document) > 0:
            a = np.zeros((MAX_DOCUMENT_LENGTH-len(document), 1024))
            document.extend(a)
        else:
            document = document[0:MAX_DOCUMENT_LENGTH]
        new_output.append(document)

    return np.asarray(new_output)

...

# in the model:
tensor_of_shape2 = Lambda(embedding_to_docs)(tensor_of_shape1)

Как это исправить?

1 Ответ

0 голосов
/ 12 апреля 2019

Вы можете использовать py_function, что позволяет вам переключаться из графического режима (используемого Keras) в активный режим (где можно перебирать тензоры, как в вашей функции).

def to_docs(x):
  return tf.py_function(embedding_to_docs, [x], tf.float32)

tensor_of_shape2 = Lambda(to_docs)(tensor_of_shape1)

Обратите внимание, что код, выполняемый в вашем embedding_to_docs, должен быть написан в tenorflow eager вместо numpy. Это означает, что вам нужно будет заменить некоторые из простых вызовов вызовами tenorflow. Вам обязательно нужно заменить обратную строку на:

return tf.convert_to_tensor(new_output)

Использование массивов-пустышек остановит вычисление градиента, но вы, вероятно, не интересуетесь градиентом, текущим через входные данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...