在TensorFlow 2.0中,仍然可以运行未经修改的1.x代码(contrib除外):
1import tensorflow.compat.v1 as tf
2tf.disable_v2_behavior()
但是,这并不能让您利用TensorFlow2.0中的许多改进。本指南将帮助您升级代码,使其更简单、更高效、更易于维护。
第一步是尝试运行升级脚本.
这将在将您的代码升级到TensorFlow 2.0时执行初始步骤。但是它不能使您的代码适合TensorFlowF 2.0。您的代码仍然可以使用tf.compat.v1
接口来访问占位符,会话,集合和其他1.x样式的功能。
本指南将介绍将TensorFlow 1.x代码转换为TensorFlow 2.0的几个示例。这些更改将使您的代码利用性能优化和简化的API调用。 在每一种情况下,模式是:
tf.Session.run
调用每个tf.Session.run
调用都应该被Python函数替换。
feed_dict
和`tf.placeholder'成为函数参数。fetches
成为函数的返回值。您可以使用标准Python工具(如pdb
)逐步调试和调试函数
如果您对它的工作感到满意,可以添加一个tf.function
装饰器,使其在图形模式下高效运行。有关其工作原理的更多信息,请参阅Autograph Guide。
使用tf.Variable
而不是tf.get_variable
。
每个variable_scope
都可以转换为Python对象。通常这将是以下之一:
tf.keras.layers.Layer
tf.keras.Model
tf.Module
如果需要聚合变量列表(如 tf.Graph.get_collection(tf.GraphKeys.VARIABLES)
),请使用Layer
和Model
对象的.variables
和.trainable_variables
属性。
这些Layer
和Model
类实现了几个不需要全局集合的其他属性。他们的.losses
属性可以替代使用tf.GraphKeys.LOSSES
集合。
有关详细信息,请参阅keras指南。
警告:许多tf.compat.v1
符号隐式使用全局集合。
使用适用于您的用例的最高级API。首选tf.keras.Model.fit
构建自己的训练循环。
如果您编写自己的训练循环,这些高级函数可以管理很多可能容易遗漏的低级细节。例如,它们会自动收集正则化损失,并在调用模型时设置training = True
参数。
使用tf.data
数据集进行数据输入。这些对象是高效的,富有表现力的,并且与张量流很好地集成。
它们可以直接传递给tf.keras.Model.fit
方法。
xxxxxxxxxx
11model.fit(dataset, epochs=5)
它们可以直接在标准Python上迭代:
xxxxxxxxxx
21for example_batch, label_batch in dataset:
2 break
x1from __future__ import absolute_import, division, print_function, unicode_literals
2import tensorflow as tf
3
4import tensorflow_datasets as tfds
低级API使用的示例包括:
使用变量范围来控制重用
用tf.get_variable
创建变量。
显式访问集合
使用以下方法隐式访问集合:
tf.global_variables
tf.losses.get_regularization_loss
使用tf.placeholder
设置图输入
用session.run
执行图形
手动初始化变量
以下是使用TensorFlow 1.x在代码中看起来像这些模式的内容:
xxxxxxxxxx
201in_a = tf.placeholder(dtype=tf.float32, shape=(2))
2in_b = tf.placeholder(dtype=tf.float32, shape=(2))
3
4def forward(x):
5 with tf.variable_scope("matmul", reuse=tf.AUTO_REUSE):
6 W = tf.get_variable("W", initializer=tf.ones(shape=(2,2)),
7 regularizer=tf.contrib.layers.l2_regularizer(0.04))
8 b = tf.get_variable("b", initializer=tf.zeros(shape=(2)))
9 return W * x + b
10
11out_a = forward(in_a)
12out_b = forward(in_b)
13
14reg_loss = tf.losses.get_regularization_loss(scope="matmul")
15
16with tf.Session() as sess:
17 sess.run(tf.global_variables_initializer())
18 outs = sess.run([out_a, out_b, reg_loss],
19 feed_dict={in_a: [1, 0], in_b: [0, 1]})
20
在转换后的代码中:
forward
函数仍定义计算。sess.run
调用被替换为对'forward`的调用tf.function
装饰器以提高性能。xxxxxxxxxx
91W = tf.Variable(tf.ones(shape=(2,2)), name="W")
2b = tf.Variable(tf.zeros(shape=(2)), name="b")
3
4function .
5def forward(x):
6 return W * x + b
7
8out_a = forward([1,0])
9print(out_a)
xxxxxxxxxx
41out_b = forward([0,1])
2
3regularizer = tf.keras.regularizers.l2(0.04)
4reg_loss = regularizer(W)
tf.layers
的模型tf.layers
模块用于包含依赖于tf.variable_scope
来定义和重用变量的层函数。
xxxxxxxxxx
141def model(x, training, scope='model'):
2 with tf.variable_scope(scope, reuse=tf.AUTO_REUSE):
3 x = tf.layers.conv2d(x, 32, 3, activation=tf.nn.relu,
4 kernel_regularizer=tf.contrib.layers.l2_regularizer(0.04))
5 x = tf.layers.max_pooling2d(x, (2, 2), 1)
6 x = tf.layers.flatten(x)
7 x = tf.layers.dropout(x, 0.1, training=training)
8 x = tf.layers.dense(x, 64, activation=tf.nn.relu)
9 x = tf.layers.batch_normalization(x, training=training)
10 x = tf.layers.dense(x, 10, activation=tf.nn.softmax)
11 return x
12
13train_out = model(train_data, training=True)
14test_out = model(test_data, training=False)
tf.keras.Sequential
中。 (对于更复杂的模型,请参见 自定义层和模型 ,以及 函数式API 两个教程)tf.layers
到tf.keras.layers
的直接映射。大多数参数保持不变,但注意区别:
x
)消失,这是因为层将构建模型与调用模型分开了。同时也要注意:
tf.contrib
的初始化器的正则化器,它们的参数变化比其他变量更多。tf.losses.get_regularization_loss
这样的函数将不再返回这些值,这可能会破坏您的训练循环。xxxxxxxxxx
141model = tf.keras.Sequential([
2 tf.keras.layers.Conv2D(32, 3, activation='relu',
3 kernel_regularizer=tf.keras.regularizers.l2(0.04),
4 input_shape=(28, 28, 1)),
5 tf.keras.layers.MaxPooling2D(),
6 tf.keras.layers.Flatten(),
7 tf.keras.layers.Dropout(0.1),
8 tf.keras.layers.Dense(64, activation='relu'),
9 tf.keras.layers.BatchNormalization(),
10 tf.keras.layers.Dense(10, activation='softmax')
11])
12
13train_data = tf.ones(shape=(1, 28, 28, 1))
14test_data = tf.ones(shape=(1, 28, 28, 1))
xxxxxxxxxx
21train_out = model(train_data, training=True)
2print(train_out)
xxxxxxxxxx
21test_out = model(test_data, training=False)
2print(test_out)
xxxxxxxxxx
21# 以下是所有可训练的变量。
2len(model.trainable_variables)
xxxxxxxxxx
21# 这是正规化损失。
2model.losses
现存的代码通常将较低级别的TF 1.x变量和操作与较高级的 tf.layers
混合。
xxxxxxxxxx
181def model(x, training, scope='model'):
2 with tf.variable_scope(scope, reuse=tf.AUTO_REUSE):
3 W = tf.get_variable(
4 "W", dtype=tf.float32,
5 initializer=tf.ones(shape=x.shape),
6 regularizer=tf.contrib.layers.l2_regularizer(0.04),
7 trainable=True)
8 if training:
9 x = x + W
10 else:
11 x = x + W * 0.5
12 x = tf.layers.conv2d(x, 32, 3, activation=tf.nn.relu)
13 x = tf.layers.max_pooling2d(x, (2, 2), 1)
14 x = tf.layers.flatten(x)
15 return x
16
17train_out = model(train_data, training=True)
18test_out = model(test_data, training=False)
要转换此代码,请遵循将图层映射到图层的模式,如上例所示。
一般模式是:
__init__
中收集图层参数。build
中构建变量。call
中执行计算,并返回结果。tf.variable_scope
实际上是它自己的一层。所以把它重写为tf.keras.layers.Layer
。
有关信息请参阅 指南
xxxxxxxxxx
201# Create a custom layer for part of the model
2class CustomLayer(tf.keras.layers.Layer):
3 def __init__(self, *args, **kwargs):
4 super(CustomLayer, self).__init__(*args, **kwargs)
5
6 def build(self, input_shape):
7 self.w = self.add_weight(
8 shape=input_shape[1:],
9 dtype=tf.float32,
10 initializer=tf.keras.initializers.ones(),
11 regularizer=tf.keras.regularizers.l2(0.02),
12 trainable=True)
13
14 # 调用方法有时会在图形模式下使用,训练会变成一个张量
15 function .
16 def call(self, inputs, training=None):
17 if training:
18 return inputs + self.w
19 else:
20 return inputs + self.w * 0.5
xxxxxxxxxx
31custom_layer = CustomLayer()
2print(custom_layer([1]).numpy())
3print(custom_layer([1], training=True).numpy())
xxxxxxxxxx
141train_data = tf.ones(shape=(1, 28, 28, 1))
2test_data = tf.ones(shape=(1, 28, 28, 1))
3
4# 构建包含自定义层的模型
5model = tf.keras.Sequential([
6 CustomLayer(input_shape=(28, 28, 1)),
7 tf.keras.layers.Conv2D(32, 3, activation='relu'),
8 tf.keras.layers.MaxPooling2D(),
9 tf.keras.layers.Flatten(),
10])
11
12train_out = model(train_data, training=True)
13test_out = model(test_data, training=False)
14
需要注意以下几点:
子类化的Keras模型和层需要在v1图(没有自动控制依赖关系)和eager模式下运行
将call()
包装在tf.function()
中以获取自动图和自动控制依赖关系
不要忘了调用时需要一个训练参数( tf.Tensor
或Python布尔值)
使用self.add_weight()
在构造函数或def build()
中创建模型变量
build
中,您可以访问输入形状,因此可以创建具有匹配形状的权重。tf.keras.layers.Layer.add_weight
允许Keras跟踪变量和正则化损失。不要在对象中保留tf.Tensors
。
tf.function
中或在 eager 的上下文中创建,并且这些张量的行为也不同。tf.Variable
s作为状态,它们总是可用于两种情况tf.Tensors
仅适用于中间值。大量较旧的TensorFlow 1.x代码使用 Slim 库,与TensorFlow 1.x一起打包为tf.contrib.layers
。作为contrib
模块,TensorFlow 2.0中不再提供此功能,即使在tf.compat.v1
中也是如此。使用Slim转换为TF 2.0比转换使用tf.layers
的存储库更复杂。事实上,首先将Slim代码转换为tf.layers
然后转换为Keras可能是有意义的。
arg_scopes
,所有args都需要显式normalizer_fn
和 activation_fn
拆分为它们自己的图层tf.layers
具有不同的arg名称和默认值tf.keras.applications
或 TFHub一些tf.contrib
图层可能没有被移动到核心TensorFlow,而是被移动到了 TF附加组件包.
有很多方法可以将数据提供给tf.keras
模型。他们将接受Python生成器和Numpy数组作为输入。
将数据提供给模型的推荐方法是使用tf.data
包,其中包含一组用于处理数据的高性能类。
如果您仍在使用tf.queue,则仅支持这些作为数据结构,而不是数据管道。
TensorFlow数据集包 (tfds
) 包含用于将预定义数据集加载为 tf.data.Dataset
对象的使用程序。
对于此示例,使用 tfds
加载MNIST数据集:
xxxxxxxxxx
21datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
2mnist_train, mnist_test = datasets['train'], datasets['test']
然后为训练准备数据:
xxxxxxxxxx
101BUFFER_SIZE = 10 # 实际代码中使用更大的值
2BATCH_SIZE = 64
3NUM_EPOCHS = 5
4
5
6def scale(image, label):
7 image = tf.cast(image, tf.float32)
8 image /= 255
9
10 return image, label
要使示例保持简短,请修剪数据集以仅返回5个批次:
xxxxxxxxxx
71train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE).take(5)
2test_data = mnist_test.map(scale).batch(BATCH_SIZE).take(5)
3
4STEPS_PER_EPOCH = 5
5
6train_data = train_data.take(STEPS_PER_EPOCH)
7test_data = test_data.take(STEPS_PER_EPOCH)
xxxxxxxxxx
11image_batch, label_batch = next(iter(train_data))
如果你不需要对训练过程进行低级别的控制,建议使用Keras内置的fit、evaluate和predict方法,这些方法提供了一个统一的接口来训练模型,而不管实现是什么(sequential、functional或子类化的)。
这些方法的有点包括:
tf.data.Datasets
tf.distribute
tf.keras.callbacks.TensorBoard
和自定义回调以下是使用数据集训练模型的示例:
xxxxxxxxxx
211model = tf.keras.Sequential([
2 tf.keras.layers.Conv2D(32, 3, activation='relu',
3 kernel_regularizer=tf.keras.regularizers.l2(0.02),
4 input_shape=(28, 28, 1)),
5 tf.keras.layers.MaxPooling2D(),
6 tf.keras.layers.Flatten(),
7 tf.keras.layers.Dropout(0.1),
8 tf.keras.layers.Dense(64, activation='relu'),
9 tf.keras.layers.BatchNormalization(),
10 tf.keras.layers.Dense(10, activation='softmax')
11])
12
13# 模型是没有自定义图层的完整模型
14model.compile(optimizer='adam',
15 loss='sparse_categorical_crossentropy',
16 metrics=['accuracy'])
17
18model.fit(train_data, epochs=NUM_EPOCHS)
19loss, acc = model.evaluate(test_data)
20
21print("Loss {}, Accuracy {}".format(loss, acc))
如果Keras模型的训练步骤适合您,但您需要在该步骤之外进行更多的控制,请考虑在您自己的数据迭代循环中使用 tf.keras.model.train_on_batch
方法。
记住:许多东西可以作为 tf.keras.Callback
的实现。
此方法具有上一节中提到的方法的许多优点,但允许用户控制外循环。
您还可以使用 tf.keras.model.test_on_batch
或 tf.keras.Model.evaluate
来检查训练期间的性能。
注意:train_on_batch
和test_on_batch
,默认返回单批的损失和指标。如果你传递reset_metrics = False
,它们会返回累积的指标,你必须记住适当地重置指标累加器。还要记住,像 AUC
这样的一些指标需要正确计算 reset_metrics = False
。
继续训练上面的模型:
xxxxxxxxxx
251# 模型是没有自定义图层的完整模型
2model.compile(optimizer='adam',
3 loss='sparse_categorical_crossentropy',
4 metrics=['accuracy'])
5
6metrics_names = model.metrics_names
7
8for epoch in range(NUM_EPOCHS):
9 #Reset the metric accumulators
10 model.reset_metrics()
11
12 for image_batch, label_batch in train_data:
13 result = model.train_on_batch(image_batch, label_batch)
14 print("train: ",
15 "{}: {:.3f}".format(metrics_names[0], result[0]),
16 "{}: {:.3f}".format(metrics_names[1], result[1]))
17 for image_batch, label_batch in test_data:
18 result = model.test_on_batch(image_batch, label_batch,
19 # return accumulated metrics
20 reset_metrics=False)
21 print("\neval: ",
22 "{}: {:.3f}".format(metrics_names[0], result[0]),
23 "{}: {:.3f}".format(metrics_names[1], result[1]))
24
25
如果您需要更多的灵活性和控制,可以通过实现自己的训练循环来实现,有三个步骤:
记住:
请注意相对于v1的简化:
上面的模型:
xxxxxxxxxx
311model = tf.keras.Sequential([
2 tf.keras.layers.Conv2D(32, 3, activation='relu',
3 kernel_regularizer=tf.keras.regularizers.l2(0.02),
4 input_shape=(28, 28, 1)),
5 tf.keras.layers.MaxPooling2D(),
6 tf.keras.layers.Flatten(),
7 tf.keras.layers.Dropout(0.1),
8 tf.keras.layers.Dense(64, activation='relu'),
9 tf.keras.layers.BatchNormalization(),
10 tf.keras.layers.Dense(10, activation='softmax')
11])
12
13optimizer = tf.keras.optimizers.Adam(0.001)
14loss_fn = tf.keras.losses.SparseCategoricalCrossentropy()
15
16function .
17def train_step(inputs, labels):
18 with tf.GradientTape() as tape:
19 predictions = model(inputs, training=True)
20 regularization_loss = tf.math.add_n(model.losses)
21 pred_loss = loss_fn(labels, predictions)
22 total_loss = pred_loss + regularization_loss
23
24 gradients = tape.gradient(total_loss, model.trainable_variables)
25 optimizer.apply_gradients(zip(gradients, model.trainable_variables))
26
27for epoch in range(NUM_EPOCHS):
28 for inputs, labels in train_data:
29 train_step(inputs, labels)
30 print("Finished epoch", epoch)
31
在TensorFlow 2.0中,metrics是对象,Metrics对象在eager和tf.functions中运行,一个metrics具有以下方法:
update_state()
– 添加新的观察结果result()
– 给定观察值,获取metrics的当前结果reset_states()
– 清除所有观察值对象本身是可调用的,与 update_state
一样,调用新观察更新状态,并返回metrics的新结果。
你不需要手动初始化metrics的变量,而且因为TensorFlow 2.0具有自动控制依赖项,所以您也不需要担心这些。
下面的代码使用metrics来跟踪自定义训练循环中观察到的平均损失:
xxxxxxxxxx
341# 创建metrics
2loss_metric = tf.keras.metrics.Mean(name='train_loss')
3accuracy_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')
4
5function .
6def train_step(inputs, labels):
7 with tf.GradientTape() as tape:
8 predictions = model(inputs, training=True)
9 regularization_loss = tf.math.add_n(model.losses)
10 pred_loss = loss_fn(labels, predictions)
11 total_loss = pred_loss + regularization_loss
12
13 gradients = tape.gradient(total_loss, model.trainable_variables)
14 optimizer.apply_gradients(zip(gradients, model.trainable_variables))
15 # 更新metrics
16 loss_metric.update_state(total_loss)
17 accuracy_metric.update_state(labels, predictions)
18
19
20for epoch in range(NUM_EPOCHS):
21 # 重置metrics
22 loss_metric.reset_states()
23 accuracy_metric.reset_states()
24
25 for inputs, labels in train_data:
26 train_step(inputs, labels)
27 # 获取metric结果
28 mean_loss = loss_metric.result()
29 mean_accuracy = accuracy_metric.result()
30
31 print('Epoch: ', epoch)
32 print(' loss: {:.3f}'.format(mean_loss))
33 print(' accuracy: {:.3f}'.format(mean_accuracy))
34
TensorFlow 2.0使用基于对象的检查点。
如果小心的话,仍然可以加载旧式的基于名称的检查点,代码转换过程可能会导致变量名的更改,但是有一些变通的方法。
最简单的方法是将新模型的名称与检查点的名称对齐:
tf.name_scope
函数可用于设置变量名称前缀,这与 tf.variable_scope
非常不同,它只影响名称,不跟踪变量和重用。如果这不适合您的用例,请尝试使用 tf.compat.v1.train.init_from_checkpoint
函数,它需要一个 assignment_map
参数,该参数指定从旧名称到新名称的映射。
注意:与基于对象的检查点(可以延迟加载不同,基于名称的检查点要求在调用函数时构建所有变量。某些模型推迟构建变量,直到您调用 build
或在一批数据上运行模型。
对于保存的模型没有明显的兼容性问题:
TensorFlow 2.0支持Estimators,使用Estimators时,可以使用TensorFlow
1.x中的 input_fn()
、tf.extimatro.TrainSpec
和 tf.estimator.EvalSpec
。
以下是使用 input_fn
和train以及evaluate的示例:
xxxxxxxxxx
231# 定义一个estimator的input_fn
2def input_fn():
3 datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
4 mnist_train, mnist_test = datasets['train'], datasets['test']
5
6 BUFFER_SIZE = 10000
7 BATCH_SIZE = 64
8
9 def scale(image, label):
10 image = tf.cast(image, tf.float32)
11 image /= 255
12
13 return image, label[..., tf.newaxis]
14
15 train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
16 return train_data.repeat()
17
18# 定义 train & eval specs
19train_spec = tf.estimator.TrainSpec(input_fn=input_fn,
20 max_steps=STEPS_PER_EPOCH * NUM_EPOCHS)
21eval_spec = tf.estimator.EvalSpec(input_fn=input_fn,
22 steps=STEPS_PER_EPOCH)
23
在TensorFlow2.0中如何构建estimators存在一些差异。
我们建议您使用Keras定义模型,然后使用 tf.keras.model_to_estimator
将您的模型转换为estimator。下面的代码展示了如何在创建和训练estimator时使用这个功能。
xxxxxxxxxx
121def make_model():
2 return tf.keras.Sequential([
3 tf.keras.layers.Conv2D(32, 3, activation='relu',
4 kernel_regularizer=tf.keras.regularizers.l2(0.02),
5 input_shape=(28, 28, 1)),
6 tf.keras.layers.MaxPooling2D(),
7 tf.keras.layers.Flatten(),
8 tf.keras.layers.Dropout(0.1),
9 tf.keras.layers.Dense(64, activation='relu'),
10 tf.keras.layers.BatchNormalization(),
11 tf.keras.layers.Dense(10, activation='softmax')
12 ])
xxxxxxxxxx
111model = make_model()
2
3model.compile(optimizer='adam',
4loss='sparse_categorical_crossentropy',
5metrics=['accuracy'])
6
7estimator = tf.keras.estimator.model_to_estimator(
8keras_model = model
9)
10
11tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
model_fn
如果您需要维护现有的自定义估算器 model_fn
,则可以将 model_fn
转换为使用Keras模型。
但是出于兼容性原因,自定义 model_fn
仍将以1.x样式的图形模式运行,这意味着没有eager execution,也没有自动控制依赖。
在自定义 model_fn
中使用Keras模型类似于在自定义训练循环中使用它:
trainable_variables
显示传递给优化器但相对于自定义循环,存在重要差异:
tf.keras.Model.get_losses_for
提取损失,而不是使用 model.losses
tf.keras.Model.get_updates_for
提取模型的更新注意:“更新”是每批后需要应用于模型的更改。例如,tf.keras.layers.BatchNormalization
层中均值和方差的移动平均值。
以下代码从自定义model_fn
创建一个估算器,说明所有这些问题。
xxxxxxxxxx
321def my_model_fn(features, labels, mode):
2 model = make_model()
3
4 optimizer = tf.compat.v1.train.AdamOptimizer()
5 loss_fn = tf.keras.losses.SparseCategoricalCrossentropy()
6
7 training = (mode == tf.estimator.ModeKeys.TRAIN)
8 predictions = model(features, training=training)
9
10 reg_losses = model.get_losses_for(None) + model.get_losses_for(features)
11 total_loss = loss_fn(labels, predictions) + tf.math.add_n(reg_losses)
12
13 accuracy = tf.compat.v1.metrics.accuracy(labels=labels,
14 predictions=tf.math.argmax(predictions, axis=1),
15 name='acc_op')
16
17 update_ops = model.get_updates_for(None) + model.get_updates_for(features)
18 minimize_op = optimizer.minimize(
19 total_loss,
20 var_list=model.trainable_variables,
21 global_step=tf.compat.v1.train.get_or_create_global_step())
22 train_op = tf.group(minimize_op, update_ops)
23
24 return tf.estimator.EstimatorSpec(
25 mode=mode,
26 predictions=predictions,
27 loss=total_loss,
28 train_op=train_op, eval_metric_ops={'accuracy': accuracy})
29
30# Create the Estimator & Train
31estimator = tf.estimator.Estimator(model_fn=my_model_fn)
32tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
这个类被简化为保存int
s,而不是tf.compat.v1.Dimension
对象。所以不需要调用.value()
来获得int
。
仍然可以从tf.TensorShape.dims
访问单个tf.compat.v1.Dimension
对象。
以下演示了TensorFlow 1.x和TensorFlow 2.0之间的区别。
xxxxxxxxxx
41# 创建一个shape并选择一个索引
2i = 0
3shape = tf.TensorShape([16, None, 256])
4shape
TF 1.x 运行:
xxxxxxxxxx
11value = shape[i].value
TF 2.0 运行::
xxxxxxxxxx
21value = shape[i]
2value
TF 1.x 运行::
xxxxxxxxxx
31for dim in shape:
2 value = dim.value
3 print(value)
TF 2.0 运行::
xxxxxxxxxx
21for value in shape:
2 print(value)
在TF 1.x(或使用任何其他维度方法)中运行:
xxxxxxxxxx
21dim = shape[i]
2dim.assert_is_compatible_with(other_dim)
TF 2.0运行:
xxxxxxxxxx
81other_dim = 16
2Dimension = tf.compat.v1.Dimension
3
4if shape.rank is None:
5 dim = Dimension(None)
6else:
7 dim = shape.dims[i]
8dim.is_compatible_with(other_dim) # or any other dimension method
xxxxxxxxxx
51shape = tf.TensorShape(None)
2
3if shape:
4 dim = shape.dims[i]
5 dim.is_compatible_with(other_dim) # or any other dimension method
如果等级已知,则 tf.TensorShape
的布尔值为“True”,否则为“False”。
xxxxxxxxxx
81print(bool(tf.TensorShape([]))) # 标量 Scalar
2print(bool(tf.TensorShape([0]))) # 0长度的向量 vector
3print(bool(tf.TensorShape([1]))) # 1长度的向量 vector
4print(bool(tf.TensorShape([None]))) # 未知长度的向量
5print(bool(tf.TensorShape([1, 10, 100]))) # 3D tensor
6print(bool(tf.TensorShape([None, None, None]))) # 3D tensor with no known dimensions
7print()
8print(bool(tf.TensorShape(None))) # 未知等级的张量
您可能会遇到TensorFlow 2.0中的一些其他行为变化。
TensorFlow 2.0默认创建ResourceVariables
,而不是RefVariables
。
ResourceVariables
被锁定用于写入,因此提供更直观的一致性保证。
use_resource = False
传递给tf.Variable
构造函数来禁用它。控制流op实现得到了简化,因此在TensorFlow 2.0中生成了不同的图。
回顾一下本节内容:
tf.keras
或tf.estimator
培训和评估循环。将代码转换为TensorFlow 2.0需要一些工作,但会有以下改变:
最新版本:https://www.mashangxue123.com/tensorflow/tf2-guide-migration_guide.html 英文版本:https://tensorflow.google.cn/beta/guide/migration_guide 翻译建议PR:https://github.com/mashangxue/tensorflow2-zh/edit/master/r2/guide/migration_guide.md