当前位置: 首页>>技术教程>>正文


迁移到TensorFlow 1.0版本

qingchuan 技术教程 , 去评论

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.packtf.unpack,我们重命名TensorArray.packTensorArray.unpackTensorArray.stackTensorArray.unstack。然而,由于TensorArray.packTensorArray.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.dividenp.modtf.dividetf.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.mod

    • tf.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.reverse
    • tf.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.round
    • tf.round的语义现在是四舍五入。
  • tf.unpack
    • 应该改名tf.unstack
  • tf.zeros_initializer
    • 应该改为函数调用,即tf.zeros_initializer()

参考资料

本文由《纯净的天空》出品。文章地址: https://vimsky.com/article/3622.html,未经允许,请勿转载。