Tensorflow CIFAR-10 教程中的布尔表达式

Boolean expression in Tensorflow CIFAR-10 tutorial

我正在 https://github.com/tensorflow/models/blob/master/official/resnet/cifar10_main.py 上阅读有关 cifar10 的 TF 官方示例的代码 我有一些问题:

num_images = is_training and _NUM_IMAGES['train'] or _NUM_IMAGES['validation']

...是什么意思?如何通过这个函数在训练和验证的时候得到合适大小的数据?

input_function = FLAGS.use_synthetic_data and get_synth_input_fn() or input_fn

同样,我不知道它是如何工作的。

这是在 python 中使用整数(或实际上任何对象)进行布尔运算的巧妙应用(有关详细信息,请参阅 this question)。示例:

>>> True and 10 or 20
Out[11]: 10
>>> False and 10 or 20
Out[12]: 20

>>> a = False and (lambda x: x) or (lambda x: 2*x)
>>> a(1)
Out[14]: 2

所以num_images的结果是一个整数(第一个或第二个取决于is_training),input_function的结果是一个函数(同样,第一个或第二个一个取决于标志 use_synthetic_data).

在这种情况下,您是 TensorFlow 错误代码风格的受害者。本教程是使用特定的 Python anti-trick 编写的,其中您使用 and 到 select 两个对象的最终对象,这些对象在布尔值中的计算结果为 True在第一个对象的计算结果为 False.

的情况下,您使用 or 到 select 最终对象

你可以通过一些更简单的例子更容易地看到它:

In [9]: 3 and "hello"
Out[9]: 'hello'

In [10]: 3 and False or "foobar"
Out[10]: 'foobar'

因此,这些行通过将这两个 anti-trick 链接在一起来 select 调整必要的功能或数据大小。

这会产生不必要的混淆和不可读的代码,一旦有人仅仅因为语言支持它就认为它没问题,或者 "it's Pythonic" 你就可以停止相信他们的建议了。

num_images = is_training and _NUM_IMAGES['train'] or _NUM_IMAGES['validation']

等同于

if is_training:
    num_images = _NUM_IMAGES['train']
else:
    num_images = _NUM_IMAGES['validation']

同理:

input_function = FLAGS.use_synthetic_data and get_synth_input_fn() or input_fn

相当于:

if FLAGS.use_synthetic_data:
   input_function = get_synth_input_fn()
else:
    input_function = input_fn()

虽然我给出的更详细的变体可能更具可读性,但原始的 tensorflow 版本更紧凑。

and 运算符短路,例如

(A and B)

B 仅在 A 为真时才计算。

这意味着在:

A and B or C

如果 A 为真,则计算 B 而 or 永远不会计算 C, 所以结果是 B。如果 A 为假,则永远不会计算 B,结果为 C.

有关更多信息,请研究文档:

https://docs.python.org/2/library/stdtypes.html#boolean-operations-and-or-not