作者:chen_h
微信号 & QQ:862251340
微信公众号:coderpai
TensorFlow 1.0 中的 API 不是完全的向后兼容的方式。也就是说,使用 TensorFlow 0.n 的 TensorFlow 程序不一定适用于 TensorFlow 1.0 版本。我们已经对其中一部分的 API 进行了更改,以确保内部 API 风格一致,并且不打算在整个 1.n 周期内做出任何反向变化。
本指南将引导你了解 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 程序转换为名为 test_1.0.py
的 1.0 TensorFlow 程序:
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 程序,在 /home/user/cool_1.0
目录中创建它们的 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_upgrade.py
尝试最小化需要调整的代码,因此无法自动更改实际的参数顺序。相反,tf_upgrade.py
通过引入关键字参数使得函数的调用变得独立。 - 像对
tf.get_variable_scope().reuse_variables()
这样的 API 进行重构可能不起任何作用,所以,我们建议删除这些函数,并且用以下的函数来替换它:
with tf.variable_scope(tf.get_variable_scope(), reuse=True):
...
- 类似于
tf.pack
和tf.unpack
,我们将TensorArray.pack
和TensorArray.unpack
重命名为TensorArray.unstack
。但是,TensorArray.pack
和TensorArray.unpack
不能被检测到,因为它们与tf
命名空间简介相关,例如foo = tf.TensorArray(); foo.unpack()
手动升级你的代码
除了运行 tf_upgrade.py
脚本,我们也可以手动来升级我们的代码。本文的其余部分提供了 TensorFlow 1.0 中所有向后不兼容更改的全面列表。
变量(Variables)
变量函数已经变得更加一致,更不容易混淆。
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 function)
汇总函数已经合并到 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
现在使用地板语义。这是为了使 np.divide
和 np.mod
的结构分别与 tf.divide
和 tf.mod
一致。另外我们改变了 tf.round
使用的摄入算法来匹配 NumPy
。
tf.div
tf.divide
划分的语义已经被改变,因为要完全匹配 Python 语义。也就是说,在 Python 3中/
将得到完整的数值,而在 Python 2 中只能得到整数部分,而//
将得到整数部分。然而,即使tf.div
也会产生地板整数除法。要强制 C 风格的截断语义,你必须使用tf.truncatediv
函数。- 考虑改变你的代码去使用
tf.divide
,这个函数遵循 Python 语义进行了升级。
tf.mod
tf.mod
的语义已经改变为匹配 Python 语义。特别地,地板语义用于整数。如果你想要 C 风格的截断 mod(余数),可以使用tf.truncatemod
。
可以用这个表来总结新旧函数:
四舍五入的新旧行为可以概括如下:
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 现在使用“轴”的概念而不是“维度”。TensorFlow 1.0 旨在保持张量参数首先修改 Tensors 的操作。(参见 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.reverse
- 以前
tf.reverse
使用一个一维的布尔类型的数组来控制转换的维度,现在我们使用张量的索引来控制。 - 比如,
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_matirces = False, compute_uv = True, name = None)
。
- 函数内部参数需要重新调整为
简化的数学变体
批量化的数学运算已被删除了。现在,功能包含在非批量化的版本中。同样,tf.complex_abs
已经将其功能移到了 tf.abs
。
tf.batch_hand_part
- 应该重命名为
tf.hand_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.round
tf.round
的语义现在与 Banker 的四舍五入相匹配。
tf.unpack
- 应该重命名为
tf.unstack
- 应该重命名为
tf.zeros_initializer
- 函数已经被修改为
tf.zeros_initializer()
- 函数已经被修改为
Reference: 官网