学习笔记02--Eager Execution

TensorFlow 的 Eager Execution 是一种命令式编成环境,可立即评估运算,无需构建计算图:运算会返回具体的值,而非构建供销后运行的计算图。

设置和基本用法

在 Tensorflow 2.0及以后版本中,默认启用 Eager Execution。

import os
import tensorflow as tf
import cProfile
print(tf.__version__)
print(tf.executing_eagerly())

2.3.0
True

现在运行 TensorFlow 运算,结果将立即返回:

x = [[2.]]
m = tf.matmul(x, x)
print("hello,{}".format(m))

2021-05-26 10:29:20.521627: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcublas.so.10
hello,[[4.]]

启用 Eager Execution 会改变 TensorFlow 运算的行为方式—现在它们会立即评估并将值返回给 Python。tf.Tensor 对象会引用具体值,而非指向计算图中节点的符号句柄。由于无需构建计算图并稍后在会话中运行,可以轻松使用print() 或调试程序检查结果。评估、输出和检查张量值不会中断计算梯度的流程。

Eager Execution 可以很好地配合 NumPy 使用。

a = tf.constant([[1, 2], [3, 4]])
print(a)

输出a是一个tensor

tf.Tensor(
[[1 2]
[3 4]], shape=(2, 2), dtype=int32)

NumPy 运算接受 tf.Tensor 参数,TensorFlow tf.math 运算会将 Python 对象和 NumPy 数组转换为 tf.Tensor 对象。tf.Tensor.numpy 方法会以 NumPy ndarray 的形式返回该对象的值。

print(a.numpy())

[[1 2]
[3 4]]

动态控制流

counter = tf.constant(0)
max_num = 15
max_num = tf.convert_to_tensor(max_num)
for num in range(1, max_num.numpy() + 1):
    num = tf.constant(num)
    if int(num % 3) == 0 and int(num % 5) == 0:
        print('FizzBuzz')
    elif int(num % 3) == 0:
        print('Fizz')
    elif int(num % 5) == 0:
        print('Buzz')
    else:
        print(num.numpy())
    counter += 1

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz

这段代码具有依赖于张量值的条件语句并会在运行时输出这些值。

Eager 训练

  • 计算梯度
    在Eager Execution 期间,使用tf.GradientTape()来跟踪运算一边稍后计算梯度。由于在每次调用期间都可能进行不同运算,所有前向传递的运算都会记录到tape中,tf.GradientTape 只能计算一个梯度。
w = tf.Variable([[1.0]])
with tf.GradientTape() as tape:
    loss = w * w

grad = tape.gradient(loss, w)
print(grad)

tf.Tensor([[2.]], shape=(1, 1), dtype=float32)

  • 训练模型
(mnist_images, mnist_labels), _ = tf.keras.datasets.mnist.load_data()
dataset = tf.data.Dataset.from_tensor_slices(
  (tf.cast(mnist_images[...,tf.newaxis]/255, tf.float32),
   tf.cast(mnist_labels,tf.int64)))
dataset = dataset.shuffle(1000).batch(32)
mnist_model = tf.keras.Sequential([
  tf.keras.layers.Conv2D(16,[3,3], activation='relu', input_shape=(None, None, 1)),
  tf.keras.layers.Conv2D(16,[3,3], activation='relu'),
  tf.keras.layers.GlobalAveragePooling2D(),
  tf.keras.layers.Dense(10)
])

即使没有训练,也可以在 Eager Execution 中调用模型并检查输出:

for images,labels in dataset.take(1):
  print("Logits: ", mnist_model(images[0:1]).numpy())
optimizer = tf.keras.optimizers.Adam()
loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

loss_history = []

虽然tf.keras模型有内置训练循环(fit方法),但有时需要进行更多自定义训练。下面是一个使用 Eager Execution 实现训练循环的示例:

def train_step(images, labels):
    with tf.GradientTape() as tape:
        logits = mnist_model(images, training=True)
        tf.debugging.assert_equal(logits.shape, (32, 10))
        loss_value = loss_object(labels, logits)

    loss_history.append(loss_value.numpy().mean())
    grads = tape.gradient(loss_value, mnist_model.trainable_variables)
    optimizer.apply_gradients(zip(grads, mnist_model.trainable_variables))

def train(epochs):
    for epoch in range(epochs):
        for(batch, (images, labels)) in enumerate(dataset):
            train_step(images, labels)
        print('Eporch {} finished.'.format(epoch))

train(epochs=3)

Epoch 0 finished
Epoch 1 finished
Epoch 2 finished在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值