Tensorflow CIFAR-10 教程中的布尔表达式
Boolean expression in Tensorflow CIFAR-10 tutorial
我正在 https://github.com/tensorflow/models/blob/master/official/resnet/cifar10_main.py 上阅读有关 cifar10 的 TF 官方示例的代码
我有一些问题:
- 在函数
input_fn
中, 是做什么的
num_images = is_training and _NUM_IMAGES['train'] or
_NUM_IMAGES['validation']
...是什么意思?如何通过这个函数在训练和验证的时候得到合适大小的数据?
- 在函数
main
中有一个类似的
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
我正在 https://github.com/tensorflow/models/blob/master/official/resnet/cifar10_main.py 上阅读有关 cifar10 的 TF 官方示例的代码 我有一些问题:
- 在函数
input_fn
中, 是做什么的
num_images = is_training and _NUM_IMAGES['train'] or _NUM_IMAGES['validation']
...是什么意思?如何通过这个函数在训练和验证的时候得到合适大小的数据?
- 在函数
main
中有一个类似的
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