tf.py_function
Оборачивает функцию Python в операцию TensorFlow, которая выполняет её в eager-режиме.
tf.py_function(
func=None, inp=None, Tout=None, name=None
)
Используется в блокнотах
| Используется в руководстве | Используется в учебных материалах |
|---|---|
Использование tf.py_function внутри tf.function позволяет выполнять функцию Python в eager-режиме внутри графа tf.function. Это имеет два основных последствия:
- Это позволяет использовать код TensorFlow nofunc=None, inp=None, Tout=None внутри
tf.function. - Это позволяет выполнять управляющую логику Python в
tf.function, не полагаясь наtf.autographдля преобразования кода с целью использования управляющей логики TensorFlow (tf.cond, tf.while_loop).
Обе эти возможности могут быть полезны при отладке.
Поскольку tf.py_function работает с Tensors, для неё по-прежнему доступно дифференцирование (один раз).
Эту функцию можно использовать двумя способами:
В качестве декоратора
Используйте tf.py_function в качестве декоратора, чтобы функция всегда выполнялась в eager-режиме.
При использовании tf.py_function в качестве декоратора:
- необходимо задать
Tout - можно задать
name - нельзя задавать
funcилиinp
Например, можно использовать tf.py_function для реализации функции log huber.
@tf.py_function(Tout=tf.float32)
def py_log_huber(x, m):
print('Running with eager execution.')
if tf.abs(x) <= m:
return x**2
else:
return m**2 * (1 - 2 * tf.math.log(m) + tf.math.log(x**2))В eager-режиме функция работает обычным образом:
x = tf.constant(1.0) m = tf.constant(2.0) print(py_log_huber(x,m).numpy()) Running with eager execution. 1.0
Внутри tf.function tf.py_function не преобразуется в tf.Graph:
@tf.function
def tf_wrapper(x):
print('Tracing.')
m = tf.constant(2.0)
return py_log_huber(x,m)tf.py_function выполняется только в eager-режиме и только при вызове tf.function:
print(tf_wrapper(x).numpy()) Tracing. Running with eager execution. 1.0 print(tf_wrapper(x).numpy()) Running with eager execution. 1.0
Градиенты работают так, как и ожидалось:
with tf.GradientTape() as t: t.watch(x) y = tf_wrapper(x) Running with eager execution. t.gradient(y, x).numpy() 2.0
На месте
Можно также отказаться от декоратора и использовать tf.py_function непосредственно. Этот вариант — удобное сокращение, если у вас нет доступа к исходному коду функции, но он сложнее для чтения.
# No decorator
def log_huber(x, m):
if tf.abs(x) <= m:
return x**2
else:
return m**2 * (1 - 2 * tf.math.log(m) + tf.math.log(x**2))
x = tf.constant(1.0)
m = tf.constant(2.0)
tf.py_function(func=log_huber, inp=[x, m], Tout=tf.float32).numpy()
1.0Дополнительная информация
Также можно использовать tf.py_function для отладки моделей во время выполнения с помощью инструментов Python: можно выделить части кода, которые требуется отладить, обернуть их в функции Python и при необходимости вставить точки трассировки pdb или инструкции print, а затем обернуть эти функции в tf.py_function.
Дополнительные сведения о выполнении в eager-режиме см. в руководстве по eager-режиму.
tf.py_function по своей сути похожа на tf.numpy_function, но, в отличие от последней, позволяет использовать операции TensorFlow в обёрнутой функции Python. В частности, tf.compat.v1.py_func выполняется только на CPU и оборачивает функции, принимающие массивы NumPy в качестве входных данных и возвращающие массивы NumPy, тогда как tf.py_function можно размещать на GPU; она оборачивает функции, принимающие тензоры на вход, выполняющие операции TensorFlow в своём теле и возвращающие тензоры.
Примечание: Рекомендуем не использовать tf.py_function за пределами прототипирования и экспериментов из-за следующих известных ограничений:
Вызов
tf.py_functionприводит к захвату глобальной блокировки интерпретатора Python (GIL), которая позволяет выполнять только один поток в любой момент времени. Это препятствует эффективному распараллеливанию и распределённому выполнению программы.Тело функции (то есть
func) не сериализуется вGraphDef. Поэтому не следует использовать эту функцию, если необходимо сериализовать модель и восстановить её в другой среде.Операция должна выполняться в том же адресном пространстве, что и программа Python, вызывающая
tf.py_function(). При использовании распределённого TensorFlow необходимо запуститьtf.distribute.Serverв том же процессе, что и программа, вызывающаяtf.py_function(), и привязать созданную операцию к устройству на этом сервере (например, с помощьюwith tf.device():).В настоящее время
tf.py_functionнесовместима с XLA. Вызовtf.py_functionвнутриtf.function(jit_compile=True)приведёт к ошибке.
| Аргументы | |
|---|---|
func | Функция Python, принимающая inp в качестве аргументов и возвращающая значение (или список значений), тип которого описан в Tout. Не задавайте func при использовании tf.py_function в качестве декоратора. |
inp | Входные аргументы для func. Список, элементы которого являются Tensors или CompositeTensors (например, tf.RaggedTensor); либо одиночный Tensor или CompositeTensor. Не задавайте inp при использовании tf.py_function в качестве декоратора. |
Tout | Тип или типы значений, возвращаемых func. Возможны следующие варианты.
|
name | Имя операции (необязательно). |
| Возвращаемое значение | |
|---|---|
|
© 2022 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 4.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/api_docs/python/tf/py_function