Тензор потока - функция карты - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть вопрос относительно функции отображения tf. Я сталкиваюсь со странным поведением с этой функцией. Если я сделаю, как указано в руководстве

label_tensor # shape [150, 1]
y = tf.map_fun(lambda x: x*x, label_tensor)
#  returns y as a tensor with label_tensor x^2

однако, если я хочу реализовать свою собственную функцию, она, похоже, не работает. Он просто всегда передает тензор в указанную функцию, которая не предназначена для работы с тензорами.

y = tf.map_fn(special_fun, label_tensor)

def special_fun(key):
    return int(2000 * round(float(key)/2000))

#  TypeError: float() argument must be a string or a number, not 'Tensor'

Я как-то не вижу проблемы здесь. Также, если я попробую что-то вроде: tmp_label_list = tf.Session (). run (label_tensor) печать (tmp_label_list) # распечатывает оцененный список, [1, 2, 3, 3, 1, 2, 2, ...] Но если я затем передам [special_fun(i) for i in tmp_label_list], то снова возникнет ошибка типа, что ожидалось, что нет 'Tensor'

Что я пропускаю или делаю неправильно? Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Они key аргумент, переданный вашему special_fun, будет тензорным. Вы не можете использовать приведение типов Python для тензоров, так как они являются только символическими во время выполнения кода, поэтому Python не знает, что с ними делать. Сбой происходит в float(), но то же самое произойдет и для round(), а также int(). То, что вы ищете, скорее всего

def special_fun(key):
    return tf.cast(2000 * tf.round(tf.cast(key, tf.float32)/2000), tf.int32)

То есть мы используем собственные функции Tensorflow для выполнения приведения / округления. Имейте в виду, что Tensorflow определяет некоторые перегруженные операторы (например, +, -, *), но в глубине это просто вызовы tf.add, tf.multiply и т. Д. В общем случае вы не можете использовать встроенные операторы / функции Python для Tensors.

0 голосов
/ 10 сентября 2018

В tf.map_fn ожидается, что данная функция будет принимать тензоры той же формы, что и данный тензор, но удаляя первое измерение (то есть функция будет принимать каждый элемент в качестве тензора). В любом случае, то, что вы пытаетесь сделать, может быть сделано напрямую (и более эффективно) без использования tf.map_fn:

y = tf.cast(2000 * tf.round(tf.cast(key, tf.float32) / 2000), tf.int32)

tf.map_fn обычно зарезервировано для особых случаев, когда векторизация невозможна. Однако, если вы хотите использовать его в любом случае, вам придется сделать что-то вроде этого:

y = tf.map_fn(special_fun, label_tensor)

def special_fun(key):
    return tf.cast(2000 * tf.round(tf.cast(key, tf.float32) / 2000), tf.int32)

Существует также tf.py_func, который позволяет применять обычную функцию Python к тензору (не к каждому из его элементов в данном случае, а к тензору в целом, заданному как NumPy). массив). Это также может быть полезно для конкретных случаев, но вам следует избегать его использования, когда это возможно, так как он менее эффективен и не может быть сериализован.

...