Функция повтора TensorFlow завершается с ошибкой ValueError: ни одно из значений не поддерживается - PullRequest
1 голос
/ 02 марта 2020

Я реализовал следующие пользовательские Layer, которые изменяют размер обучаемого параметра seed_vectors при вызове в соответствии с размером ввода x, используя функцию repeat.

import tensorflow as tf
from tensorflow.keras.layers import Dense
from tensorflow import repeat
from tensorflow.keras.layers import LayerNormalization


class PoolingMultiHeadAttention(tf.keras.layers.Layer):

    def __init__(self, d, k, h):
        """
        Arguments:
            d: an integer, input dimension.
            k: an integer, number of seed vectors.
            h: an integer, number of heads.
        """
        super(PoolingMultiHeadAttention, self).__init__()
        self.seed_vectors = self.add_weight(initializer='uniform',
                                            shape=(1, k, d),
                                            trainable=True)

    def call(self, z):
        """
        Arguments:
            z: a float tensor with shape [b, n, d].
        Returns:
            a float tensor with shape [b, k, d]
        """
        b = z.shape[0]
        s = self.seed_vectors
        s = repeat(s, (b), axis=0, name='rep')  # shape [b, k, d]
        return s*z


# Dimensionality test    
z = tf.random.normal(shape=(10, 2, 9))
pma = PoolingMultiHeadAttention(d=9, k=2, h=3)
pma(z)

Я проверил размерность ввода / вывода в модульных тестах, и он работает нормально, но, к сожалению, если я использую этот слой внутри модели, он завершается с ошибкой:


    <ipython-input-4-89023d123369>:110 call  *
        s = repeat(s, (b), axis=0, name='rep')  # shape [b, k, d]
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/array_ops.py:5616 repeat  **
        return repeat_with_axis(input, repeats, axis, name)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/array_ops.py:5478 repeat_with_axis
        repeats = convert_to_int_tensor(repeats, name="repeats")
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/array_ops.py:5388 convert_to_int_tensor
        tensor = ops.convert_to_tensor(tensor, name=name, preferred_dtype=dtype)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py:1341 convert_to_tensor
        ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/constant_op.py:317 _constant_tensor_conversion_function
        return constant(v, dtype=dtype, name=name)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/constant_op.py:258 constant
        allow_broadcast=True)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/constant_op.py:296 _constant_impl
        allow_broadcast=allow_broadcast))
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/tensor_util.py:439 make_tensor_proto
        raise ValueError("None values not supported.")

    ValueError: None values not supported.

Эта ошибка, похоже, связана с отсутствием output (или output - None) [что я знаю, что это не тот случай, так как я проверил функцию в активном режиме, и она работает] или по какой-то причине backprop не работает с этой операцией (repeat). Я не знаю ни одного альтернативного способа изменить размер этого параметра во время выполнения + (почти) тот же код работает нормально, используя Pytorch (https://github.com/TropComplique/set-transformer/blob/master/blocks.py) Спасибо

1 Ответ

0 голосов
/ 02 марта 2020

Исправление должно быть довольно простым: вместо этого используйте b = tf.shape(z)[0]. Объяснение:

Проблема в том, что вы пытаетесь повторить b раз, что (я полагаю) является переменным размером пакета. Когда не работает в нетерпеливом режиме, это представлено значением None в форме. Таким образом, вы пытаетесь повторить «Ни разу», что приводит к крэ sh.

Важно то, что Tensor.shape возвращает форму тензора stati c, т.е. все, что известно во время компиляции. Это включает None для неизвестных размеров, как отмечено выше.
tf.shape(tensor) вместо этого возвращает форму dynamici c, т.е. это будет оцениваться только при запуске модели. В это время размер партии, если он, конечно, известен (поскольку вы помещаете что-то в модель), и поэтому это будет конкретное значение, которое можно поместить в repeat, в отличие от None, который мы получили выше. .

...