TensorFlow的即刻执行(Eager execution)是一个命令式的编程环境,它可以立即评估操作,而不必构建图:操作返回具体的值,而不是构建计算图以便以后运行。这使得开始使用TensorFlow和调试模型变得很容易,而且还减少了样板文件。
即刻执行:
即刻执行支持大多数TensorFlow操作和GPU加速。
自动微分对于实现机器学习算法(如训练神经网络的反向传播)是有用的。在即刻执行期间,使用 tf.GradientTape 以跟踪稍后计算梯度的操作。
由于在每次调用期间可能发生不同的操作,所有的前向传递操作都会被记录到一个“tape”中。要计算梯度,请向后播放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手写数字进行分类。
os.environ['CUDA_VISIBLE_DEVICES'] = '/gpu:0'
# Fetch and format the mnist data
(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)
# Build the model
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)
])
# 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 = []
def train_step(images, labels):
with tf.GradientTape() as tape:
logits = mnist_model(images, training=True)
# Add asserts to check the shape of the output.
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('Epoch {} finished'.format(epoch))
train(epochs=3)
plt.plot(loss_history)
plt.xlabel('Batch #')
plt.ylabel('Loss [entropy]')
tf.Variable 对象存储可变 tf.Tensor ——类似于在训练过程中获取的值,使自动区分变得更容易。
变量集合可以封装到层或模型中,以及对其进行操作的方法。层和模型之间的主要区别在于模型添加了如下方法 Model.fit, Model.evaluate 和 Model.save。
例如;
class Linear(tf.keras.Model):
def __init__(self):
super(Linear, self).__init__()
self.W = tf.Variable(5., name='weight')
self.B = tf.Variable(10., name='bias')
def call(self, inputs):
return inputs * self.W + self.B
# A toy dataset of points around 3 * x + 2
NUM_EXAMPLES = 2000
training_inputs = tf.random.normal([NUM_EXAMPLES])
noise = tf.random.normal([NUM_EXAMPLES])
training_outputs = training_inputs * 3 + 2 + noise
# The loss function to be optimized
def loss(model, inputs, targets):
error = model(inputs) - targets
return tf.reduce_mean(tf.square(error))
def grad(model, inputs, targets):
with tf.GradientTape() as tape:
loss_value = loss(model, inputs, targets)
return tape.gradient(loss_value, [model.W, model.B])
model = Linear()
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
print("Initial loss: {:.3f}".format(loss(model, training_inputs, training_outputs)))
steps = 300
for i in range(steps):
grads = grad(model, training_inputs, training_outputs)
optimizer.apply_gradients(zip(grads, [model.W, model.B]))
if i % 20 == 0:
print("Loss at step {:03d}: {:.3f}".format(i, loss(model, training_inputs, training_outputs)))
print("Final loss: {:.3f}".format(loss(model, training_inputs, training_outputs)))
print("W = {}, B = {}".format(model.W.numpy(), model.B.numpy()))
TensorBoard 是理解、调试和优化模型训练过程的可视化工具。它使用在执行程序时写入的Summaries事件。
可以用 tf.summary 在即刻执行中记录变量的 summaries。例如,每100个训练步骤记录一次损失摘要:
logdir = "./tb/"
writer = tf.summary.create_file_writer(logdir)
steps = 1000
with writer.as_default(): # or call writer.set_as_default() before the loop.
for i in range(steps):
step = i + 1
# Calculate loss with your real train function.
loss = 1 - 0.001 * step
if step % 100 == 0:
tf.summary.scalar('loss', loss, step=step)
https://tensorflow.google.cn/guide/eager?hl=zh_cn#advanced_automatic_differentiation_topics