Tensorflow - функция карты

У меня вопрос относительно функции карты 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 (). запустить (label_tensor) печать (tmp_label_list) # выводит оцененный список, [1, 2, 3, 3, 1, 2, 2, ...] Но если я затем пропущу [special_fun(i) for i in tmp_label_list], он снова вызовет Type-Error, что он не ожидал, что 'Tensor'

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

3
0
4 622
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В 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). Это также может быть полезно в определенных случаях, но вам следует по возможности избегать его использования, поскольку он менее эффективен и не может быть сериализован.

спасибо за ваш ответ, я выберу tf.py_func, потому что операция раунда - это лишь одна из четырех операций, которые я собираюсь выполнить. Спасибо, что указали мне на tf.py_func.

Hans T 10.09.2018 12:19

Аргумент 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.

спасибо, что указали на это. Я ценю, что вы преобразовали мою функцию в синтаксис tf. поскольку мне нужно больше операций, выполняемых в special_fun, я намерен вызвать tf.py_func, как указано @jdehesa

Hans T 10.09.2018 12:23

Другие вопросы по теме