TensorFlow 1.0中的API相对于之前版本有一些改变,不是全部向后兼容。也就是说,使用TensorFlow 0.n的TensorFlow程序不一定适用于TensorFlow 1.0。
本指南将引导您:了解API的主要更改以及如何自动升级到TensorFlow 1.0,并解释为什么我们做出这些更改。
如何升级
如果你想自动将你的代码移植到1.0,你可以试试我们的tf_upgrade.py脚本。虽然此脚本处理许多情况,但有时也需要手动更改。从这里GitHub树获取上述脚本。
要将单个0.n TensorFlow源文件转换为1.0,请输入以下命令:
$ python tf_upgrade.py --infile InputFile --outfile OutputFile
例如,以下命令转换名为test.py的0.n TensorFlow程序到1.0 TensorFlow程序,并命名为test_1.0.py:
$ python tf_upgrade.py --infile test.py --outfile test_1.0.py
该tf_upgrade.py脚本还会生成一个名为report.txt的文件,其中详细介绍了所做的更改,并提出了可能需要手动进行更改的建议。
要将0.n TensorFlow程序的整个目录升级到1.0,请输入以下命令:
$ python tf_upgrade.py --intree InputDir --outtree OutputDir
例如,以下命令将转换/home/user/cool目录中所有0.n TensorFlow程序转为1.0版本:
$ python tf_upgrade.py --intree /home/user/cool --outtree /home/user/cool_1.0
限制
有几件事要注意,特别是:
- 您必须手动修复任何
tf.reverse()实例。该tf_upgrade.py脚本会在stdout和在report.txt文件输出关于tf.reverse()的警告。 tf_upgrade.py不会自动更改实际的参数顺序。tf.get_variable_scope().reuse_variables()可能不能正常工作。我们建议您删除这些行并用以下行替换它们:
with tf.variable_scope(tf.get_variable_scope(), reuse=True):
...
- 类似于
tf.pack和tf.unpack,我们重命名TensorArray.pack和TensorArray.unpack至TensorArray.stack和TensorArray.unstack。然而,由于TensorArray.pack和TensorArray.unpack间接与tf命名空间相关,所以不能被检测出来, 例如:foo = tf.TensorArray(); foo.unpack()
手动升级代码
除了使用tf_upgrade.py脚本,您也可以手动升级代码。本文档的其余部分提供了TensorFlow 1.0中所有向后不兼容更改的列表。
变量
变量函数已经变得更加一致,更不容易混淆。
tf.VARIABLES- 应该改名
tf.GLOBAL_VARIABLES
- 应该改名
tf.all_variables- 应该改名
tf.global_variables
- 应该改名
tf.initialize_all_variables- 应该改名
tf.global_variables_initializer
- 应该改名
tf.initialize_local_variables- 应该改名
tf.local_variables_initializer
- 应该改名
tf.initialize_variables- 应该改名
tf.variables_initializer
- 应该改名
Summary函数
Summary函数已经合并到tf.summary命名空间。
tf.audio_summary- 应该改名
tf.summary.audio
- 应该改名
tf.contrib.deprecated.histogram_summary- 应该改名
tf.summary.histogram
- 应该改名
tf.contrib.deprecated.scalar_summary- 应该改名
tf.summary.scalar
- 应该改名
tf.histogram_summary- 应该改名
tf.summary.histogram
- 应该改名
tf.image_summary- 应该改名
tf.summary.image
- 应该改名
tf.merge_all_summaries- 应该改名
tf.summary.merge_all
- 应该改名
tf.merge_summary- 应该改名
tf.summary.merge
- 应该改名
tf.scalar_summary- 应该改名
tf.summary.scalar
- 应该改名
tf.train.SummaryWriter- 应该改名
tf.summary.FileWriter
- 应该改名
数值差异
整数除法tf.floordiv现在使用flooring语义。这是为了让np.divide和np.mod跟tf.divide和tf.mod分别保持一致。另外我们改变了使用的舍入算法tf.round,以便匹配NumPy。
-
tf.div-
tf.divide除法的语义已经完全改变为符合Python语义。也就是说,/这个除法在Python 3中,以及Python 2的未来模式中,都会产生浮点数,而//向下取整。例如:3.0 / 2 = 1.5 3.0 // 2 = 1.0但是,即使
tf.div将产生向下取整除法,要强制C-style截断语义,您必须使用tf.truncatediv。 -
可以考虑更改您的代码以使用
tf.divide,它遵循Python语义进行推广。
-
-
tf.modtf.mod的语义已经改变为匹配Python语义。如果您想要使用C-style截断模式(余数),可以使用tf.truncatemod
可以用这个表来总结除法的新旧行为:
| EXPR | TF 0.11(py2) | TF 0.11(py3) | TF 1.0(py2) | TF 1.0(py3) |
|---|---|---|---|---|
| tf.div(3,4) | 0 | 0 | 0 | 0 |
| tf.div(-3,4) | 0 | 0 | -1 | -1 |
| tf.mod(-3,4) | -3 | -3 | 1 | 1 |
| -3/4 | 0 | -0.75 | -1 | -0.75 |
| -3 /4tf.divide(-3,4) | N /A | N /A | -0.75 | -1 |
四舍五入的新旧行为可以概括如下:
| 输入 | Python | NumPy | C++ round() | TensorFlow 0.11(floor(x + .5)) | TensorFlow 1.0 |
|---|---|---|---|---|---|
| -3.5 | -4 | -4 | -4 | -3 | -4 |
| -2.5 | -2 | -2 | -3 | -2 | -2 |
| -1.5 | -2 | -2 | -2 | -1 | -2 |
| -0.5 | 0 | 0 | -1 | 0 | 0 |
| 0.5 | 0 | 0 | 1 | 1 | 0 |
| 1.5 | 2 | 2 | 2 | 2 | 2 |
| 2.5 | 2 | 2 | 3 | 3 | 2 |
| 3.5 | 4 | 4 | 4 | 4 | 4 |
匹配NumPy的命名
许多功能已被重命名,以便匹配NumPy。这样做是为了使NumPy和TensorFlow之间的转换尽可能简单。还有许多功能不匹配的情况,但是已经删除了几个常见的不一致。
tf.inv- 应该改名
tf.reciprocal - 这样做是为了避免与NumPy的矩阵逆
np.inv相混淆
- 应该改名
tf.list_diff- 应该改名
tf.setdiff1d
- 应该改名
tf.listdiff- 应该改名
tf.setdiff1d
- 应该改名
tf.mul- 应该改名
tf.multiply
- 应该改名
tf.neg- 应该改名
tf.negative
- 应该改名
tf.select- 应该改名
tf.where tf.where现在有3个参数或1个参数,就像np.where
- 应该改名
tf.sub- 应该改名
tf.subtract
- 应该改名
匹配NumPy参数
某些TensorFlow 1.0方法的参数现在可以匹配某些NumPy方法中的参数。为了实现这一点,TensorFlow 1.0已经改变了关键字参数并重新排序了一些参数。值得注意的是,TensorFlow 1.0现在使用axis而不是dimension。 TensorFlow 1.0在修改Tensors的操作中会保持tensor参数排在前面。 (见tf.concat更改)。
tf.argmax- 关键字参数
dimension应该改名axis
- 关键字参数
tf.argmin- 关键字参数
dimension应该改名axis
- 关键字参数
tf.concat- 关键字参数
concat_dim应该改名axis - 参数已被重新排列
tf.concat(values, axis, name='concat')。
- 关键字参数
tf.count_nonzero- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.expand_dims- 关键字参数
dim应该改名axis
- 关键字参数
tf.reduce_all- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.reduce_any- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.reduce_join- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.reduce_logsumexp- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.reduce_max- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.reduce_mean- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.reduce_min- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.reduce_prod- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.reduce_sum- 关键字参数
reduction_indices应该改名axis
- 关键字参数
tf.reversetf.reverse之前使用1D的bool张量来控制哪些维度被reverse。现在我们使用axis索引的张量。- 例如
tf.reverse(a, [True, False, True])现在一定是tf.reverse(a, [0, 2])
tf.reverse_sequence- 关键字参数
batch_dim应该改名batch_axis - 关键字参数
seq_dim应该改名seq_axis
- 关键字参数
tf.sparse_concat- 关键字参数
concat_dim应该改名axis
- 关键字参数
tf.sparse_reduce_sum- 关键字参数
reduction_axes应该改名axis
- 关键字参数
tf.sparse_reduce_sum_sparse- 关键字参数
reduction_axes应该改名axis
- 关键字参数
tf.sparse_split- 关键字参数
split_dim应该改名axis - 参数已被重新排列
tf.sparse_split(keyword_required=KeywordRequired(), sp_input=None, num_split=None, axis=None, name=None, split_dim=None)。
- 关键字参数
tf.split- 关键字参数
split_dim应该改名axis - 关键字参数
num_split应该改名num_or_size_splits - 参数已被重新排列
tf.split(value, num_or_size_splits, axis=0, num=None, name='split')。
- 关键字参数
tf.squeeze- 关键字参数
squeeze_dims应该改名axis
- 关键字参数
tf.svd- 参数已被重新排列
tf.svd(tensor, full_matrices=False, compute_uv=True, name=None)。
- 参数已被重新排列
简化的数学变换
批量版数学运算已被删除,现在只有非批量版本。同样的,tf.complex_abs变为tf.abs
tf.batch_band_part- 应该改名
tf.band_part
- 应该改名
tf.batch_cholesky- 应该改名
tf.cholesky
- 应该改名
tf.batch_cholesky_solve- 应该改名
tf.cholesky_solve
- 应该改名
tf.batch_fft- 应该改名
tf.fft
- 应该改名
tf.batch_fft3d- 应该改名
tf.fft3d
- 应该改名
tf.batch_ifft- 应该改名
tf.ifft
- 应该改名
tf.batch_ifft2d- 应该改名
tf.ifft2d
- 应该改名
tf.batch_ifft3d- 应该改名
tf.ifft3d
- 应该改名
tf.batch_matmul- 应该改名
tf.matmul
- 应该改名
tf.batch_matrix_determinant- 应该改名
tf.matrix_determinant
- 应该改名
tf.batch_matrix_diag- 应该改名
tf.matrix_diag
- 应该改名
tf.batch_matrix_inverse- 应该改名
tf.matrix_inverse
- 应该改名
tf.batch_matrix_solve- 应该改名
tf.matrix_solve
- 应该改名
tf.batch_matrix_solve_ls- 应该改名
tf.matrix_solve_ls
- 应该改名
tf.batch_matrix_transpose- 应该改名
tf.matrix_transpose
- 应该改名
tf.batch_matrix_triangular_solve- 应该改名
tf.matrix_triangular_solve
- 应该改名
tf.batch_self_adjoint_eig- 应该改名
tf.self_adjoint_eig
- 应该改名
tf.batch_self_adjoint_eigvals- 应该改名
tf.self_adjoint_eigvals
- 应该改名
tf.batch_set_diag- 应该改名
tf.set_diag
- 应该改名
tf.batch_svd- 应该改名
tf.svd
- 应该改名
tf.complex_abs- 应该改名
tf.abs
- 应该改名
其他各种变更
一些其他变化,包括:
tf.image.per_image_whitening- 应该改名
tf.image.per_image_standardization
- 应该改名
tf.nn.sigmoid_cross_entropy_with_logits- 参数已被重新排列
tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None)。
- 参数已被重新排列
tf.nn.softmax_cross_entropy_with_logits- 参数已被重新排列
tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)。
- 参数已被重新排列
tf.nn.sparse_softmax_cross_entropy_with_logits- 参数已被重新排列
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None)。
- 参数已被重新排列
tf.ones_initializer- 应该改为函数调用,即
tf.ones_initializer()
- 应该改为函数调用,即
tf.pack- 应该改名
tf.stack
- 应该改名
tf.roundtf.round的语义现在是四舍五入。
tf.unpack- 应该改名
tf.unstack
- 应该改名
tf.zeros_initializer- 应该改为函数调用,即
tf.zeros_initializer()
- 应该改为函数调用,即
