目录:
一、自动转换脚本
二、高级别behavioral changes
三、让代码2.0本土化
四、改变模型
五、训练
This doc for users of low level TensorFlow APIs. If you are using the high level APIs (tf.keras
) there may be little or no action you need to take to make your code fully TensorFlow 2.0 compatible:
该文档是为低级的Tensorflow API。如果你使用的上高级API(tf.keras),可能只有一点或者根本不用做任何改变。
- Check your optimizer's default learning rate.
- Note that the "name" that metrics are logged to may have changed.
It is still possible to run 1.X code, unmodified (except for contrib), in TensorFlow 2.0:
当然,在tensorflow2.0你可以直接使用tensorflow1.0的代码而不做任何改变(除了contrib):
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
However, this does not let you take advantage of many of the improvements made in TensorFlow 2.0. This guide will help you upgrade your code, making it simpler, more performant, and easier to maintain.
但是,这并不能很好的兼容tensorflow2.0的运行环境,例如GPU版本?
一、自动转换脚本
The first step, before attempting to implement the changes described in this doc, is to try running the upgrade script.
第一步,尝试一下自动转换脚本。
This will do an initial pass at upgrading your code to TensorFlow 2.0. But it can't make your code idiomatic to 2.0. Your code may still make use of tf.compat.v1 endpoints to access placeholders, sessions, collections, and other 1.x-style functionality.
这仅仅是初始化的步骤。并不符合2.0的习惯。你的代码可能依然是在使用tf.compat.v1来调用placeholders,sessions,collections,和其他1.x风格的函数功能。
二、高级别behavioral changes
If your code works in TensorFlow 2.0 using tf.compat.v1.disable_v2_behavior()
, there are still global behavioral changes you may need to address. The major changes are:
如果你的代码是使用tf.compat.v1.disable_v2_behavior()在tensorflow2.0中工作,那么依然有一些全局的行为需要改变。这些主要改变是:
- Eager execution, v1.enable_eager_execution() : Any code that implicitly uses a tf.Graph will fail. Be sure to wrap this code in a with tf.Graph().as_default() context.
饥饿执行,v1.enable_eager_execution():任何代码使用tf.Graph都会失败。确保使用tf.Graph().as_default()上下文将代码包裹。
- Resource variables, v1.enable_resource_variables(): Some code may depends on non-deterministic behaviors enabled by TF reference variables. Resource variables are locked while being written to, and so provide more intuitive consistency guarantees.
资源变量,v1.enable_resource_variables():有些代码可能依赖于TF引用变量启用的非确定性行为。资源变量在写入时被锁定,因此提供了更直接的一致性保证。
This may change behavior in edge cases.
This may create extra copies and can have higher memory usage.
This can be disabled by passing use_resource=False
to the tf.Variable
constructor.
- Tensor shapes, v1.enable_v2_tensorshape(): TF 2.0 simplifies the behavior of tensor shapes. Instead of t.shape[0].value you can say t.shape[0]. These changes should be small, and it makes sense to fix them right away. See TensorShape for examples.
张量的形状,v1.enable_v2_tensorshape():TF2.0简化了张量形状的行为。替代t.shape[0].value,你可以说t.shape[0]。这些改变应该很小,而且修正它们是好懂的。
- Control flow, v1.enable_control_flow_v2(): The TF 2.0 control flow implementation has been simplified, and so produces different graph representations. Please file bugs for any issues.
控制流,v1.enable_control_flow_v2():TF2.0控制流已经简化了,并且因此产生了不同的图形表示。
三、让代码2.0本土化
This guide will walk through several examples of converting TensorFlow 1.x code to TensorFlow 2.0. These changes will let your code take advantage of performance optimizations and simplified API calls.
该指导将通过几个例子,展示从tensorflow1.x到tensorflow2.0的转换。这些改变将会使你的代码充分利用性能优化和简化的API调用。
In each case, the pattern is:
在每种情况下,模式是:
1. Replace v1.Session.run calls
取代v1.Session
Every v1.Session.run call should be replaced by a Python function.
每一个v1.Session.run命令都应该更换为Python函数。
The feed_dict and v1.placeholders become function arguments.
feed_dict和v1.placeholders变成函数参数。
The fetches become the function's return value.
fetches变成函数的返回值。
During conversion eager execution allows easy debugging with standard Python tools like pdb.
饥饿模式允许轻松的调试,例如pdb。
After that add a tf.function decorator to make it run efficiently in graph. See the Autograph Guide for more on how this works.
在那之后添加一个tf.function修饰词,使它在graph里有效地运行。查看Autograph Guide查看更多。
Note that:注意:
Unlike v1.Session.run a tf.function has a fixed return signature, and always returns all outputs. If this causes performance problems, create two separate functions.
不像v1.Session.run,tf.function有固定的返回标志,而且总是返回所有的输出。如果这引起表现问题,创建两个分开的函数。
There is no need for a tf.control_dependencies or similar operations: A tf.function behaves as if it were run in the order written. tf.Variable assignments and tf.asserts, for example, are executed automatically.
对tf.control_dependencies或类似的操作没有必要:tf.function表现得就像它运行在写定的顺序里。例如,tf.Variable赋值和tf.asserts,自动执行。
2. Use Python objects to track variables and losses
使用Python对象跟踪变量和损失
All name-based variable tracking is strongly discouraged in TF 2.0. Use Python objects to to track variables.
在tf2.0中,强烈不推荐所有基于名称的变量跟踪。使用Python对象跟踪变量。
Use tf.Variable instead of v1.get_variable.
使用tf.Variable而不是v1.get_variable。
Every v1.variable_scope should be converted to a Python object. Typically this will be one of:
每个v1.variable_scope都应转换为Python对象。通常这将是:
If you need to aggregate lists of variables (like tf.Graph.get_collection(tf.GraphKeys.VARIABLES)), use the .variables and .trainable_variables attributes of the Layer and Model objects.
如果需要聚合变量列表(比如tf.Graph.get_collection(tf.GraphKeys.VARIABLES)),使用层和模型对象的.variables和.trainable_variables属性。
These Layer and Model classes implement several other properties that remove the need for global collections. Their .losses property can be a replacement for using the tf.GraphKeys.LOSSES collection.
这些Layer和Model类实现了几个其它的属性,移除了全局collection的需要。它们的.losses属性可以取代tf.GraphKeys.LOSSES集合的使用需要。
有关详细信息,请参见keras指南。
3. Upgrade your training loops
升级你的训练环
Use the highest level API that works for your use case. Prefer tf.keras.Model.fit over building your own training loops.
使用适用于您的用例的最高级别的API。更喜欢tf.keras.Model.fit建立自己的训练循环。
These high level functions manage a lot of the low-level details that might be easy to miss if you write your own training loop. For example, they automatically collect the regularization losses, and set the training=True argument when calling the model.
这些高级函数管理许多低级的细节,如果您编写自己的训练循环,这些细节可能很容易遗漏。例如,它们自动收集正则化损失,并在调用模型时设置training=True参数。
4. Upgrade your data input pipelines
升级数据输入管道
Use tf.data datasets for data input. These objects are efficient, expressive, and integrate well with tensorflow.
使用tf.data用于数据输入的数据集。这些对象效率高、表现力强,并且与tensorflow很好地集成在一起。
They can be passed directly to the tf.keras.Model.fit method.
它们可以直接传递给tf.keras.Model.fit方法。
model.fit(dataset, epochs=5)
它们可以直接在标准Python代码上迭代:
for example_batch, label_batch in dataset:
break
5. Migrate off compat.v1 symbols
迁移除compat.v1符号
The tf.compat.v1 module contains the complete TensorFlow 1.x API, with its original semantics.
这个tf.compat.v1模块包含完整的TensorFlow 1.x API及其原始语义。
The TF2 upgrade script will convert symbols to their 2.0 equivalents if such a conversion is safe, i.e., if it can determine that the behavior of the 2.0 version is exactly equivalent (for instance, it will rename v1.arg_max to tf.argmax, since those are the same function).
如果这种转换是安全的,即如果它能够确定2.0版本的行为完全等效(例如,它将把v1.arg_max重命名为tf.argmax公司,因为它们是相同的函数)。
After the upgrade script is done with a piece of code, it is likely there are many mentions of compat.v1. It is worth going through the code and converting these manually to the 2.0 equivalent (it should be mentioned in the log if there is one).
在用一段代码完成升级脚本后,很可能会有很多次提到compat.v1。仔细检查代码并将其手动转换为2.0等效版本是值得的(如果有,应该在日志中提到)。
四、改变模型
1.Setup
设置
import tensorflow as tf
import tensorflow_datasets as tfds
2.Low-level variables & operator execution
Examples of low-level API use include:
低级API的使用示例包括:
- using variable scopes to control reuse
- creating variables with
v1.get_variable
. - accessing collections explicitly
-
accessing collections implicitly with methods like :
-
using
v1.placeholder
to set up graph inputs -
executing graphs with
Session.run
-
initializing variables manually
转换之前:
这里是Tensorflow 1.x里可能看上去的:
in_a = tf.placeholder(dtype=tf.float32, shape=(2))
in_b = tf.placeholder(dtype=tf.float32, shape=(2))
def forward(x):
with tf.variable_scope("matmul", reuse=tf.AUTO_REUSE):
W = tf.get_variable("W", initializer=tf.ones(shape=(2,2)),
regularizer=tf.contrib.layers.l2_regularizer(0.04))
b = tf.get_variable("b", initializer=tf.zeros(shape=(2)))
return W * x + b
out_a = forward(in_a)
out_b = forward(in_b)
reg_loss=tf.losses.get_regularization_loss(scope="matmul")
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
outs = sess.run([out_a, out_b, reg_loss],
feed_dict={in_a: [1, 0], in_b: [0, 1]})
转换之后:
转换后的代码:
- The variables are local Python objects.
- The
forward
function still defines the calculation. - The
Session.run
call is replaced with a call toforward
- The optional
tf.function
decorator can be added for performance. - The regularizations are calculated manually, without referring to any global collection.
- No sessions or placeholders.
W = tf.Variable(tf.ones(shape=(2,2)), name="W")
b = tf.Variable(tf.zeros(shape=(2)), name="b")
@tf.function
def forward(x):
return W * x + b
out_a = forward([1,0])
print(out_a)
tf.Tensor( [[1. 0.] [1. 0.]], shape=(2, 2), dtype=float32)
out_b = forward([0,1])
regularizer = tf.keras.regularizers.l2(0.04)
reg_loss=regularizer(W)
3. Models based on tf.layers
基于tf.layers的模型
The v1.layers module is used to contain layer-functions that relied on v1.variable_scope to define and reuse variables.
v1.layers模块用于包含依赖v1.variable_作用域定义和重用变量的层函数。
转换之前
def model(x, training, scope='model'):
with tf.variable_scope(scope, reuse=tf.AUTO_REUSE):
x = tf.layers.conv2d(x, 32, 3, activation=tf.nn.relu,
kernel_regularizer=tf.contrib.layers.l2_regularizer(0.04))
x = tf.layers.max_pooling2d(x, (2, 2), 1)
x = tf.layers.flatten(x)
x = tf.layers.dropout(x, 0.1, training=training)
x = tf.layers.dense(x, 64, activation=tf.nn.relu)
x = tf.layers.batch_normalization(x, training=training)
x = tf.layers.dense(x, 10)
return x
train_out = model(train_data, training=True)
test_out = model(test_data, training=False)
转换之后
- The simple stack of layers fits neatly into
tf.keras.Sequential
. (For more complex models see custom layers and models, and the functional API.) - The model tracks the variables, and regularization losses.
- The conversion was one-to-one because there is a direct mapping from
v1.layers
totf.keras.layers
.
大多数参数没有改变。但请注意不同之处:
- The
training
argument is passed to each layer by the model when it runs. - The first argument to the original
model
function (the inputx
) is gone. This is because object layers separate building the model from calling the model.
还请注意:
- If you were using regularizers of initializers from
tf.contrib
, these have more argument changes than others. - The code no longer writes to collections, so functions like
v1.losses.get_regularization_loss
will no longer return these values, potentially breaking your training loops.
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, 3, activation='relu',
kernel_regularizer=tf.keras.regularizers.l2(0.04),
input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dropout(0.1),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Dense(10)
])
train_data = tf.ones(shape=(1, 28, 28, 1))
test_data = tf.ones(shape=(1, 28, 28, 1))
train_out = model(train_data, training=True)
print(train_out)
tf.Tensor([[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]], shape=(1, 10), dtype=float32)
test_out = model(test_data, training=False)
print(test_out)
tf.Tensor( [[-0.11456077 -0.3126101 0.13154565 -0.50197905 -0.02416557 0.36460522 -0.24887308 -0.37784547 0.05524942 0.01696768]], shape=(1, 10), dtype=float32)
# Here are all the trainable variables.
len(model.trainable_variables)
8
# Here is the regularization loss. model.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.077528305>]
4. Mixed variables & v1.layers
混合变量和v1.layers
Existing code often mixes lower-level TF 1.x variables and operations with higher-level v1.layers.
现有代码通常将较低级别的tf1.x变量和操作与较高级别的v1.layers混合在一起。
转换之前:
def model(x, training, scope='model'):
with tf.variable_scope(scope, reuse=tf.AUTO_REUSE):
W = tf.get_variable(
"W", dtype=tf.float32,
initializer=tf.ones(shape=x.shape),
regularizer=tf.contrib.layers.l2_regularizer(0.04),
trainable=True)
if training:
x = x + W
else:
x = x + W * 0.5
x = tf.layers.conv2d(x, 32, 3, activation=tf.nn.relu)
x = tf.layers.max_pooling2d(x, (2, 2), 1)
x = tf.layers.flatten(x)
return x
train_out = model(train_data, training=True)
test_out = model(test_data, training=False)
转换之后:
To convert this code, follow the pattern of mapping layers to layers as in the previous example.
要转换此代码,请按照将层映射到上一个示例中的层的模式。
一般模式是:
- Collect layer parameters in
__init__
. - Build the variables in
build
. - Execute the calculations in
call
, and return the result.
The v1.variable_scope is essentially a layer of its own. So rewrite it as a tf.keras.layers.Layer. See the guide for details.
v1.variable_作用域本质上是它自己的一个层。作为重写tf.keras.layer.Layer。有关详细信息,请参阅指南。
# Create a custom layer for part of the model
class CustomLayer(tf.keras.layers.Layer):
def __init__(self, *args, **kwargs):
super(CustomLayer, self).__init__(*args, **kwargs)
def build(self, input_shape):
self.w = self.add_weight(
shape=input_shape[1:],
dtype=tf.float32,
initializer=tf.keras.initializers.ones(),
regularizer=tf.keras.regularizers.l2(0.02),
trainable=True)
# Call method will sometimes get used in graph mode,
# training will get turned into a tensor
@tf.function
def call(self, inputs, training=None):
if training:
return inputs + self.w
else:
return inputs + self.w * 0.5
custom_layer = CustomLayer() print(custom_layer([1]).numpy()) print(custom_layer([1], training=True).numpy())
[1.5] [2.]
train_data = tf.ones(shape=(1, 28, 28, 1))
test_data = tf.ones(shape=(1, 28, 28, 1))
# Build the model including the custom layer
model = tf.keras.Sequential([
CustomLayer(input_shape=(28, 28, 1)),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
])
train_out = model(train_data, training=True)
test_out = model(test_data, training=False)
注意事项:
-
Subclassed Keras models & layers need to run in both v1 graphs (no automatic control dependencies) and in eager mode
- Wrap the
call()
in atf.function()
to get autograph and automatic control dependencies
- Wrap the
-
Don't forget to accept a
training
argument tocall
.- Sometimes it is a
tf.Tensor
- Sometimes it is a Python boolean.
- Sometimes it is a
-
Create model variables in constructor or
Model.build
usingself.add_weight()
.- In
Model.build
you have access to the input shape, so can create weights with matching shape. - Using
tf.keras.layers.Layer.add_weight
allows Keras to track variables and regularization losses.
- In
-
Don't keep
tf.Tensors
in your objects.- They might get created either in a
tf.function
or in the eager context, and these tensors behave differently. - Use
tf.Variable
s for state, they are always usable from both contexts tf.Tensors
are only for intermediate values.
- They might get created either in a
5. A note on Slim & contrib.layers
关于Slim&贡献层
A large amount of older TensorFlow 1.x code uses the Slim library, which was packaged with TensorFlow 1.x as tf.contrib.layers. As a contrib module, this is no longer available in TensorFlow 2.0, even in tf.compat.v1. Converting code using Slim to TF 2.0 is more involved than converting repositories that use v1.layers. In fact, it may make sense to convert your Slim code to v1.layers first, then convert to Keras.
大量较旧的TensorFlow1.x代码使用Slim库,该库与TensorFlow1.x打包为tf.contrib.layers公司. 作为一个contrib模块,这在TensorFlow 2.0中不再可用,即使在tf.compat公司.1版。使用Slim将代码转换为tf2.0比转换使用v1.layers的存储库要复杂得多。事实上,首先将Slim代码转换为v1.layers,然后再转换为Keras可能是有意义的。
- Remove
arg_scopes
, all args need to be explicit - If you use them, split
normalizer_fn
andactivation_fn
into their own layers - Separable conv layers map to one or more different Keras layers (depthwise, pointwise, and separable Keras layers)
- Slim and
v1.layers
have different arg names & default values - Some args have different scales
- If you use Slim pre-trained models, try out Keras's pre-traimed models from
tf.keras.applications
or TF Hub's TF2 SavedModels exported from the original Slim code.
Some tf.contrib layers might not have been moved to core TensorFlow but have instead been moved to the TF add-ons package.
一些出资人层可能没有被移到核心TensorFlow,而是被移到了TF add-ons包中。
五、训练
There are many ways to feed data to a tf.keras model. They will accept Python generators and Numpy arrays as input.
有很多种方法将数据喂给tf.keras模型。它们将会接受Python生成器和Numpy数组作为输入。
The recommended way to feed data to a model is to use the tf.data package, which contains a collection of high performance classes for manipulating data.
向模型喂数据的推荐方法是使用tf.data包。它包含用于操作数据的高性能类的集合。
If you are still using tf.queue, these are now only supported as data-structures, not as input pipelines.
如果你还在用tf.队列,这些现在只支持作为数据结构,而不是作为输入管道。
1.Using Datasets
使用数据集
The TensorFlow Datasets package (tfds) contains utilities for loading predefined datasets as tf.data.Dataset objects.
TensorFlow Datasets包(tfds)包含加载预定义数据集作为tf.data.Dataset物体的公用程序。
For this example, load the MNISTdataset, using tfds:
对于本例,使用tfds加载MNISTdataset:
datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets['train'], datasets['test']
Downloading and preparing dataset mnist/3.0.1 (download: 11.06 MiB, generated: 21.00 MiB, total: 32.06 MiB) to /home/kbuilder/tensorflow_datasets/mnist/3.0.1... Warning:absl:Dataset mnist is hosted on GCS. It will automatically be downloaded to your local data directory. If you'd instead prefer to read directly from our public GCS bucket (recommended if you're running on GCP), you can instead pass `try_gcs=True` to `tfds.load` or set `data_dir=gs://tfds-data/datasets`. Dataset mnist downloaded and prepared to /home/kbuilder/tensorflow_datasets/mnist/3.0.1. Subsequent calls will reuse this data.
Then prepare the data for training:
然后准备训练数据:
- Re-scale each image.
- Shuffle the order of the examples.
- Collect batches of images and labels.
BUFFER_SIZE = 10 # Use a much larger value for real code. BATCH_SIZE = 64 NUM_EPOCHS = 5 def scale(image, label): image = tf.cast(image, tf.float32) image /= 255 return image, label
To keep the example short, trim the dataset to only return 5 batches:
要使示例保持简短,修剪数据集以仅返回5个批:
train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE) test_data = mnist_test.map(scale).batch(BATCH_SIZE) STEPS_PER_EPOCH = 5 train_data = train_data.take(STEPS_PER_EPOCH) test_data = test_data.take(STEPS_PER_EPOCH)
image_batch, label_batch = next(iter(train_data))
2. Use Keras training loops
使用Keras训练循环
If you don't need low level control of your training process, using Keras's built-in fit, evaluate, and predict methods is recommended. These methods provide a uniform interface to train the model regardless of the implementation (sequential, functional, or sub-classed).
如果你不使用低水平的控制你的训练过程,建议使用Keras的内置的拟合、评估和预测方法。这些方法提供了统一的接口来训练模型,而不管实现是(序列的,函数的,或者子类的)。
The advantages of these methods include:
这些方法的优点包括:
- They accept Numpy arrays, Python generators and,
tf.data.Datasets
- They apply regularization, and activation losses automatically.
- They support
tf.distribute
for multi-device training. - They support arbitrary callables as losses and metrics.
- They support callbacks like
tf.keras.callbacks.TensorBoard
, and custom callbacks. - They are performant, automatically using TensorFlow graphs.
Here is an example of training a model using a Dataset. (For details on how this works see tutorials.)
下面是一个使用数据集训练模型的示例。(有关如何工作的详细信息,请参见教程。)
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, 3, activation='relu',
kernel_regularizer=tf.keras.regularizers.l2(0.02),
input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dropout(0.1),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Dense(10)
])
# Model is the full model w/o custom layers
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.fit(train_data, epochs=NUM_EPOCHS)
loss, acc = model.evaluate(test_data)
print("Loss {}, Accuracy {}".format(loss, acc))
Epoch 1/5 5/5 [==============================] - 0s 6ms/step - loss: 1.5323 - accuracy: 0.5063 Epoch 2/5 5/5 [==============================] - 0s 6ms/step - loss: 0.4105 - accuracy: 0.9219 Epoch 3/5 5/5 [==============================] - 0s 7ms/step - loss: 0.2495 - accuracy: 0.9531 Epoch 4/5 5/5 [==============================] - 0s 6ms/step - loss: 0.1806 - accuracy: 0.9875 Epoch 5/5 5/5 [==============================] - 0s 6ms/step - loss: 0.1416 - accuracy: 0.9937 5/5 [==============================] - 0s 4ms/step - loss: 1.5655 - accuracy: 0.6469 Loss 1.565544605255127, Accuracy 0.6468750238418579
3. Write your own loop
书写你自己的循环
If the Keras model's training step works for you, but you need more control outside that step, consider using the tf.keras.Model.train_on_batch method, in your own data-iteration loop.
如果Keras模型的训练步骤适合你,但是你需要在步骤之外更多控制,考虑使用tf.keras.Model.train_on_batch方法,在你自己的数据迭代循环中。
Remember: Many things can be implemented as a tf.keras.callbacks.Callback.
记住:很多事情都可以作为tf.keras.callbacks.Callback实现。
This method has many of the advantages of the methods mentioned in the previous section, but gives the user control of the outer loop.
本方法具有之前所提到的所有的方法的优点,但是又给了用户外部控制循环的能力。
You can also use tf.keras.Model.test_on_batch or tf.keras.Model.evaluate to check performance during training.
你也可以使用tf.keras.Model.test_on_batch或者tf.keras.Model.evaluate来检查训练过程中的性能。
Note: train_on_batch and test_on_batch, by default return the loss and metrics for the single batch. If you pass reset_metrics=False they return accumulated metrics and you must remember to appropriately reset the metric accumulators. Also remember that some metrics like AUC require reset_metrics=False to be calculated correctly.
注:在“批上训练”和“批量测试”,默认情况下返回单个批次的损失和指标。如果传递reset_metrics=False,则返回累积的度量值,并且必须记住适当地重置度量值累加器。还请记住,某些指标(如AUC)需要reset_metrics=False才能正确计算。
To continue training the above model:
要继续训练上述模型:
# Model is the full model w/o custom layers
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
for epoch in range(NUM_EPOCHS):
#Reset the metric accumulators
model.reset_metrics()
for image_batch, label_batch in train_data:
result = model.train_on_batch(image_batch, label_batch)
metrics_names = model.metrics_names
print("train: ",
"{}: {:.3f}".format(metrics_names[0], result[0]),
"{}: {:.3f}".format(metrics_names[1], result[1]))
for image_batch, label_batch in test_data:
result = model.test_on_batch(image_batch, label_batch,
# return accumulated metrics
reset_metrics=False)
metrics_names = model.metrics_names
print("
eval: ",
"{}: {:.3f}".format(metrics_names[0], result[0]),
"{}: {:.3f}".format(metrics_names[1], result[1]))
train: loss: 0.122 accuracy: 0.984 train: loss: 0.133 accuracy: 0.984 train: loss: 0.164 accuracy: 0.969 train: loss: 0.167 accuracy: 0.969 train: loss: 0.161 accuracy: 0.984 eval: loss: 1.583 accuracy: 0.669 train: loss: 0.074 accuracy: 1.000 train: loss: 0.090 accuracy: 1.000 train: loss: 0.089 accuracy: 1.000 train: loss: 0.095 accuracy: 1.000 train: loss: 0.090 accuracy: 1.000 eval: loss: 1.567 accuracy: 0.747 train: loss: 0.065 accuracy: 1.000 train: loss: 0.068 accuracy: 1.000 train: loss: 0.056 accuracy: 1.000 train: loss: 0.069 accuracy: 1.000 train: loss: 0.067 accuracy: 1.000 eval: loss: 1.545 accuracy: 0.772 train: loss: 0.053 accuracy: 1.000 train: loss: 0.063 accuracy: 0.984 train: loss: 0.050 accuracy: 1.000 train: loss: 0.051 accuracy: 1.000 train: loss: 0.049 accuracy: 1.000 eval: loss: 1.520 accuracy: 0.778 train: loss: 0.049 accuracy: 1.000 train: loss: 0.046 accuracy: 1.000 train: loss: 0.044 accuracy: 1.000 train: loss: 0.045 accuracy: 1.000 train: loss: 0.044 accuracy: 1.000 eval: loss: 1.494 accuracy: 0.791
4. Customize the training step
自定义培训步骤
If you need more flexibility and control, you can have it by implementing your own training loop. There are three steps:
如果你需要更多的弹性和控制,你可以通过实现你自己的训练循环拥有它。这里是三个步骤:
- Iterate over a Python generator or
tf.data.Dataset
to get batches of examples. - Use
tf.GradientTape
to collect gradients. - Use one of the
tf.keras.optimizers
to apply weight updates to the model's variables.
记得:
- Always include a
training
argument on thecall
method of subclassed layers and models. - Make sure to call the model with the
training
argument set correctly. - Depending on usage, model variables may not exist until the model is run on a batch of data.
- You need to manually handle things like regularization losses for the model.
请注意相对于v1的简化:
- There is no need to run variable initializers. Variables are initialized on creation.
- There is no need to add manual control dependencies. Even in
tf.function
operations act as in eager mode.
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, 3, activation='relu',
kernel_regularizer=tf.keras.regularizers.l2(0.02),
input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dropout(0.1),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Dense(10)
])
optimizer = tf.keras.optimizers.Adam(0.001)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
@tf.function
def train_step(inputs, labels):
with tf.GradientTape() as tape:
predictions = model(inputs, training=True)
regularization_loss=tf.math.add_n(model.losses)
pred_loss=loss_fn(labels, predictions)
total_loss=pred_loss + regularization_loss
gradients = tape.gradient(total_loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
for epoch in range(NUM_EPOCHS):
for inputs, labels in train_data:
train_step(inputs, labels)
print("Finished epoch", epoch)
Finished epoch 0 Finished epoch 1 Finished epoch 2 Finished epoch 3 Finished epoch 4
5. New-style metrics and losses
新风格的指标和损失
In TensorFlow 2.0, metrics and losses are objects. These work both eagerly and in tf.functions.
在TensorFlow2.0中,度量和损失是对象。这两种方法工作起来都很饥饿而且在tf.functions中.
A loss object is callable, and expects the (y_true, y_pred) as arguments:
loss对象是可调用的,并期望(y_true,y_pred)作为参数:
cce = tf.keras.losses.CategoricalCrossentropy(from_logits=True) cce([[1, 0]], [[-1.0,3.0]]).numpy()
4.01815
A metric object has the following methods:
度量对象具有如下方法:
Metric.update_state()
— add new observationsMetric.result()
—get the current result of the metric, given the observed valuesMetric.reset_states()
— clear all observations.
The object itself is callable. Calling updates the state with new observations, as with update_state, and returns the new result of the metric.
对象本身是可调用的。调用用新的观察值更新状态,就像update_state一样,并返回度量的新结果。
You don't have to manually initialize a metric's variables, and because TensorFlow 2.0 has automatic control dependencies, you don't need to worry about those either.
您不必手动初始化度量的变量,而且由于TensorFlow2.0具有自动控制依赖关系,因此您也不必担心这些变量。
The code below uses a metric to keep track of the mean loss observed within a custom training loop.
下面的代码使用一个度量来跟踪在定制训练循环中观察到的平均损失。
# Create the metrics
loss_metric = tf.keras.metrics.Mean(name='train_loss')
accuracy_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')
@tf.function
def train_step(inputs, labels):
with tf.GradientTape() as tape:
predictions = model(inputs, training=True)
regularization_loss=tf.math.add_n(model.losses)
pred_loss=loss_fn(labels, predictions)
total_loss=pred_loss + regularization_loss
gradients = tape.gradient(total_loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
# Update the metrics
loss_metric.update_state(total_loss)
accuracy_metric.update_state(labels, predictions)
for epoch in range(NUM_EPOCHS):
# Reset the metrics
loss_metric.reset_states()
accuracy_metric.reset_states()
for inputs, labels in train_data:
train_step(inputs, labels)
# Get the metric results
mean_loss=loss_metric.result()
mean_accuracy = accuracy_metric.result()
print('Epoch: ', epoch)
print(' loss: {:.3f}'.format(mean_loss))
print(' accuracy: {:.3f}'.format(mean_accuracy))
Epoch: 0 loss: 0.175 accuracy: 0.994 Epoch: 1 loss: 0.149 accuracy: 0.991 Epoch: 2 loss: 0.133 accuracy: 0.991 Epoch: 3 loss: 0.113 accuracy: 0.997 Epoch: 4 loss: 0.101 accuracy: 0.997
6. Keras metric names
Keras度量名字
In TensorFlow 2.0 keras models are more consistent about handling metric names.
在TensorFlow 2.0中,keras模型在处理度量名称方面更加一致。
Now when you pass a string in the list of metrics, that exact string is used as the metric's name. These names are visible in the history object returned by model.fit, and in the logs passed to keras.callbacks. is set to the string you passed in the metric list.
现在,当您在度量列表中传递一个字符串时,该字符串将用作度量的名称。这些名称在返回的历史对象中可见模型.拟合,并在传递给keras.回调. 设置为在度量列表中传递的字符串。
model.compile(
optimizer = tf.keras.optimizers.Adam(0.001),
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics = ['acc', 'accuracy', tf.keras.metrics.SparseCategoricalAccuracy(name="my_accuracy")])
history = model.fit(train_data)
5/5 [==============================] - 0s 6ms/step - loss: 0.1076 - acc: 0.9969 - accuracy: 0.9969 - my_accuracy: 0.9969
history.history.keys()
dict_keys(['loss', 'acc', 'accuracy', 'my_accuracy'])
This differs from previous versions where passing metrics=["accuracy"] would result in dict_keys(['loss', 'acc'])
这与以前的版本不同,在以前的版本中,传递metrics=[“accuracity”]将导致dict_键(['loss','acc'])
7. Keras optimizers
Keras优化器
The optimizers in v1.train, like v1.train.AdamOptimizer and v1.train.GradientDescentOptimizer, have equivalents in tf.keras.optimizers.
v1.train中的优化器,比如v1.train.AdamOptimizer和v1.train.GradientDescentOptimizer,在tf.keras.optimizers拥有相同的功能.
Convert v1.train to keras.optimizers
将v1.train转换为keras.optimizers
Here are things to keep in mind when converting your optimizers:
这里是你在转换优化器时需要记住的几点:
- Upgrading your optimizers may make old checkpoints incompatible.
- All epsilons now default to
1e-7
instead of1e-8
(which is negligible in most use cases). v1.train.GradientDescentOptimizer
can be directly replaced bytf.keras.optimizers.SGD
.v1.train.MomentumOptimizer
can be directly replaced by theSGD
optimizer using the momentum argument:tf.keras.optimizers.SGD(..., momentum=...)
.v1.train.AdamOptimizer
can be converted to usetf.keras.optimizers.Adam
. Thebeta1
andbeta2
arguments have been renamed tobeta_1
andbeta_2
.v1.train.RMSPropOptimizer
can be converted totf.keras.optimizers.RMSprop
. Thedecay
argument has been renamed torho
.v1.train.AdadeltaOptimizer
can be converted directly totf.keras.optimizers.Adadelta
.tf.train.AdagradOptimizer
can be converted directly totf.keras.optimizers.Adagrad
.tf.train.FtrlOptimizer
can be converted directly totf.keras.optimizers.Ftrl
. Theaccum_name
andlinear_name
arguments have been removed.- The
tf.contrib.AdamaxOptimizer
andtf.contrib.NadamOptimizer
, can be converted directly totf.keras.optimizers.Adamax
andtf.keras.optimizers.Nadam
. Thebeta1
, andbeta2
arguments have been renamed tobeta_1
andbeta_2
.
New defaults for some tf.keras.optimizers
一些tf.keras.optimizers新的默认值
警告:如果您看到模型的收敛行为发生了变化,请检查默认的学习速率。
There are no changes for optimizers.SGD, optimizers.Adam, or optimizers.RMSprop.
没有更改优化器.SGD, 优化器.Adam,或优化器.RMSprop.
The following default learning rates have changed:
以下默认学习率已更改:
optimizers.Adagrad
from 0.01 to 0.001optimizers.Adadelta
from 1.0 to 0.001optimizers.Adamax
from 0.002 to 0.001optimizers.Nadam
from 0.002 to 0.001
8. TensorBoard
TensorFlow 2 includes significant changes to the tf.summary API used to write summary data for visualization in TensorBoard. For a general introduction to the new tf.summary, there are several tutorials available that use the TF 2 API. This includes a TensorBoard TF 2 Migration Guide
TensorFlow 2包括对tf.总结用于在TensorBoard中编写可视化摘要数据的API。对于新的tf.总结,有几个教程可以使用tf2api。这包括一个TensorBoard TF2迁移指南
使代码2.0原生化:
1.替换tf.Session.run调用
2.使用Python对象来跟踪变量和损失
3.升级您的训练循环
4.升级数据输入管道
https://www.mashangxue123.com/tensorflow/tf2-guide-migration_guide.html
https://tensorflow.google.cn/beta/guide/migration_guide
https://github.com/mashangxue/tensorflow2-zh/edit/master/r2/guide/migration_guide.md