python 调用dll时function not found_TensorFlow 2.0 中的 tf.function 和 AutoGraph

本文介绍了 TensorFlow 2.0 中的 `tf.function` 和 AutoGraph,它们如何整合 Eager Execution 的易用性和 TensorFlow 1.0 的强大功能。`tf.function` 可将 Python 代码转换为高性能图形,AutoGraph 自动将 Python 控制流转换为 TensorFlow 操作。通过示例展示了如何使用 `tf.function` 和 AutoGraph 实现神经网络层、控制流和训练循环等功能。
摘要由CSDN通过智能技术生成

TensorFlow 2.0 整合了 Eager Execution 的简易性和 TensorFlow 1.0 的强大功能。这种整合的核心是 tf.function,方便您将 Python 语法子集转换为便携的高性能 TensorFlow 图形。

AutoGraph 是 tf.function 的一项出色新功能,让您可以使用自然的 Python 语法编写图形代码。如需可以与 AutoGraph 搭配使用的 Python 功能列表,请参阅 AutoGraph 功能和限制。如需有关 tf.function 的更多详细信息,请参阅 RFC TensorFlow 2.0:函数,而非会话。如需有关 AutoGraph 的更多详细信息,请参阅 tf.autograph。

注:AutoGraph 功能和限制 链接

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/LIMITATIONS.md

RFC TensorFlow 2.0:函数,而非会话 链接

https://github.com/tensorflow/community/blob/master/rfcs/20180918-functions-not-sessions-20.md

本教程将向您介绍 tf.function 和 AutoGraph 的基本功能。

设置

导入 TensorFlow 2.0 Preview Nightly 并启用 TensorFlow 2.0 模式:

from __future__ import absolute_import, division, print_function, unicode_literals
import numpy as np

!pip install -q tensorflow==2.0.0-alpha0
import tensorflow as tf

安装临时补丁程序以启用一些额外的 TensorFlow 2.0 升级。我们很快会移除此程序。

from tensorflow.python.ops import control_flow_util
control_flow_util.ENABLE_CONTROL_FLOW_V2 = True

tf.function 装饰器

使用 tf.function 注释函数时,您仍可像调用任何其他函数一样调用该函数。不过,系统会将其编译成图形,这可为您带来以下好处:加快执行速度、在 GPU 或 TPU 上运行,或导出至 SavedModel。

@tf.function
def simple_nn_layer(x, y):
  return tf.nn.relu(tf.matmul(x, y))
x = tf.random.uniform((3, 3))
y = tf.random.uniform((3, 3))
simple_nn_layer(x, y)

array([[0.29528466, 0.70377195, 0.581679  ],

       [0.0462185 , 0.38763517, 0.50960624],

       [0.30035543, 1.0594532 , 0.91603595]], dtype=float32)>

如果我们检查注释结果,就会发现这是一个特殊的可调用函数,能够处理与 TensorFlow 运行时的所有交互。

simple_nn_layer

如果您的代码使用多个函数,则您无需对全部函数进行注释,因为从已注释函数调用的任何函数也将以图形模式运行。

def linear_layer(x):
  return 2 * x + 1
@tf.function
def deep_net(x):
  return tf.nn.relu(linear_layer(x))
deep_net(tf.constant((1, 2, 3)))

使用 Python 控制流

在 tf.function 中使用依赖数据的控制流时,您可以使用 Python 控制流语句,AutoGraph 会将其转换为相应的 TensorFlow 操作。例如,如果 if 语句依赖 Tensor,则这些语句将会转换为 tf.cond()。

在下方示例中,x 是 Tensor,但 if 语句按预期运行:

@tf.function
def square_if_positive(x):
  if x > 0:
    x = x * x
  else:
    x = 0
  return x
print('square_if_positive(2) = {}'.format(square_if_positive(tf.constant(2))))
print('square_if_positive(-2) = {}'.format(square_if_positive(tf.constant(-2))))

square_if_positive(2) = 4

square_if_positive(-2) = 0

请注意:上方示例使用带有标量值的简单条件句。批处理通常用于实际代码。

AutoGraph 支持常见的 Python 语句,例如 while、for、if、break、continue 和 return,并支持嵌套。这意味着您可以在 while 和 if 语句的条件下使用 Tensor 表达式,或在 for 循环中迭代 Tensor。

@tf.function
def sum_even(items):
  s = 0
  for c in items:
    if c % 2 > 0:
      continue
    s += c
  return s
sum_even(tf.constant([10, 12, 15, 20]))

AutoGraph 还为高级用户提供低级 API。例如,我们可以使用 AutoGraph 查看所生成的代码。

print(tf.autograph.to_code(sum_even.python_function, experimental_optional_features=None))

from __future__ import print_function

def tf__sum_even(items):

  do_return = False

  retval_ = None

  s = 0

  def loop_body(loop_vars, s_2):

    c = loop_vars

    continue_ = False

    cond = c % 2 > 0

    def if_true():

      continue_ = True

      return continue_

    def if_false():

      return continue_

    continue_ = ag__.if_stmt(cond, if_true, if_false)

    cond_1 = ag__.not_(continue_)

    def if_true_1():

      s_1, = s_2,

      s_1 += c

      return s_1

    def if_false_1():

      return s_2

    s_2 = ag__.if_stmt(cond_1, if_true_1, if_false_1)

    return s_2,

  s, = ag__.for_stmt(items, None, loop_body, (s,))

  do_return = True

  retval_ = s

  return retval_

tf__sum_even.autograph_info__ = {}

下面是一个更复杂的控制流示例:

@tf.function
def fizzbuzz(n):
  msg = tf.constant('')
  for i in tf.range(n):
    if tf.equal(i % 3, 0):
      msg += 'Fizz'
    elif tf.equal(i % 5, 0):
      msg += 'Buzz'
    else:
      msg += tf.as_string(i)
    msg += '\n'
  return msg
print(fizzbuzz(tf.constant(15)).numpy().decode())

Fizz

1

2

Fizz

4

Buzz

Fizz

7

8

Fizz

Buzz

11

Fizz

13

14

Keras 和 AutoGraph

您也可以使用采用对象方法的 tf.function。例如,通常您可以通过注释模型的 call 函数来装饰您的自定义 Keras 模型。如需了解详细信息,请参阅 tf.keras。

class CustomModel(tf.keras.models.Model):
  @tf.function
  def call(self, input_data):
    if tf.reduce_mean(input_data) > 0:
      return input_data
    else:
      return input_data // 2
model = CustomModel()
model(tf.constant([-2, -4]))

副作用

与在 Eager 模式下一样,您可以使用带有副作用的操作,例如通常位于 tf.function 中的 tf.assign 或 tf.print,且 tf.function 会插入必要的控制依赖项以确保这些操作按顺序执行。

v = tf.Variable(5)
@tf.function
def find_next_odd():
  v.assign(v + 1)
  if tf.equal(v % 2, 0):
    v.assign(v + 1)
find_next_odd()
v

示例:训练简单模型

您还可以使用 AutoGraph 在 TensorFlow 中移动更多计算。例如,训练循环只是控制流,因此实际上您可以将其引入 TensorFlow。

下载数据

def prepare_mnist_features_and_labels(x, y):
  x = tf.cast(x, tf.float32) / 255.0
  y = tf.cast(y, tf.int64)
  return x, y
def mnist_dataset():
  (x, y), _ = tf.keras.datasets.mnist.load_data()
  ds = tf.data.Dataset.from_tensor_slices((x, y))
  ds = ds.map(prepare_mnist_features_and_labels)
  ds = ds.take(20000).shuffle(20000).batch(100)
  return ds
train_dataset = mnist_dataset()

Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz

11493376/11490434 [==============================] - 0s 0us/step

定义模型

model = tf.keras.Sequential((
    tf.keras.layers.Reshape(target_shape=(28 * 28,), input_shape=(28, 28)),
    tf.keras.layers.Dense(100, activation='relu'),
    tf.keras.layers.Dense(100, activation='relu'),
    tf.keras.layers.Dense(10)))
model.build()
optimizer = tf.keras.optimizers.Adam()

定义训练循环

compute_loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
compute_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
def train_one_step(model, optimizer, x, y):
  with tf.GradientTape() as tape:
    logits = model(x)
    loss = compute_loss(y, logits)
  grads = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(grads, model.trainable_variables))
  compute_accuracy(y, logits)
  return loss
@tf.function
def train(model, optimizer):
  train_ds = mnist_dataset()
  step = 0
  loss = 0.0
  accuracy = 0.0
  for x, y in train_ds:
    step += 1
    loss = train_one_step(model, optimizer, x, y)
    if tf.equal(step % 10, 0):
      tf.print('Step', step, ': loss', loss, '; accuracy', compute_accuracy.result())
  return step, loss, accuracy
step, loss, accuracy = train(model, optimizer)
print('Final step', step, ': loss', loss, '; accuracy', compute_accuracy.result())

Step 10 : loss 1.84492886 ; accuracy 0.37

Step 20 : loss 1.07085669 ; accuracy 0.5415

Step 30 : loss 0.771448374 ; accuracy 0.613333344

Step 40 : loss 0.608694196 ; accuracy 0.67225

Step 50 : loss 0.508914351 ; accuracy 0.7084

Step 60 : loss 0.347155064 ; accuracy 0.7365

Step 70 : loss 0.374278426 ; accuracy 0.757142842

Step 80 : loss 0.457216293 ; accuracy 0.774375

Step 90 : loss 0.366965473 ; accuracy 0.787222207

Step 100 : loss 0.398182064 ; accuracy 0.7985

Step 110 : loss 0.210726 ; accuracy 0.808181822

Step 120 : loss 0.41397053 ; accuracy 0.817166686

Step 130 : loss 0.246230051 ; accuracy 0.824538469

Step 140 : loss 0.270531863 ; accuracy 0.831071436

Step 150 : loss 0.260166764 ; accuracy 0.835933328

Step 160 : loss 0.161626607 ; accuracy 0.841375

Step 170 : loss 0.101895899 ; accuracy 0.845647037

Step 180 : loss 0.365272254 ; accuracy 0.85

Step 190 : loss 0.363062441 ; accuracy 0.853421032

Step 200 : loss 0.238487661 ; accuracy 0.85685

Final step tf.Tensor(200, shape=(), dtype=int32) : loss tf.Tensor(0.23848766, shape=(), dtype=float32) ; accuracy tf.Tensor(0.85685, shape=(), dtype=float32)

批处理

在实际应用中,批处理对性能至关重要。转换为 AutoGraph 的最佳代码是在批处理层面决定控制流的代码。如果在单个示例层面作决定,请尝试使用批处理 API 维持性能。

例如,如果您在 Python 中有以下代码:

def square_if_positive(x):
  return [i ** 2 if i > 0 else i for i in x]
square_if_positive(range(-5, 5))

[-5, -4, -3, -2, -1, 0, 1, 4, 9, 16]

您可能想在 TensorFlow 中将其编写成如下形式(而这种方法有效!):

@tf.function
def square_if_positive_naive(x):
  result = tf.TensorArray(tf.int32, size=x.shape[0])
  for i in tf.range(x.shape[0]):
    if x[i] > 0:
      result = result.write(i, x[i] ** 2)
    else:
      result = result.write(i, x[i])
  return result.stack()
square_if_positive_naive(tf.range(-5, 5))

但在这种情况下,结果是您可编写如下代码:

def square_if_positive_vectorized(x):
  return tf.where(x > 0, x ** 2, x)
square_if_positive_vectorized(tf.range(-5, 5))

更多 AI 相关阅读:

  • TensorFlow Lite 对象检测

  • 标贝科技:TensorFlow 框架提升语音合成效果

  • 使用 TensorFlow Model Analysis 提升模型质量

7f50cad38e9623343410d287837435c7.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值