在Tensorflow中(从v1.2.1开始),似乎有(至少)两个并行API来构建计算图.tf.nn中有函数,如conv2d,avg_pool,relu,dropout,然后在tf.layers,tf.losses和其他地方有类似的函数,如tf.layers.conv2d,tf.layers.dense,tf.layers.退出.
从表面上看,似乎这种情况只会引起混淆:例如,tf.nn.dropout使用"保持率",而tf.layers.dropout使用"丢弃率"作为参数.
这种区别对最终用户/开发人员有什么实际意义吗?如果没有,是否有任何清理API的计划?
Tensorflow,一方面提出了一种低层次的API( tf.
,tf.nn.
...),而在另一方面,更高层次的API( tf.layers.
,tf.losses.
,...).
更高级API的目标是提供大大简化最常见神经网络设计的功能.较低级别的API适用于有特殊需求的人,或者希望更好地控制正在发生的事情的人.
但情况有点混乱,因为某些函数具有相同或相似的名称,而且,没有明确的方法可以区分哪个命名空间对应于API的哪个级别.
现在,让我们看看conv2d
例如.之间的显着差异tf.nn.conv2d
,并tf.layers.conv2d
是,后来发生需要重量和偏见的所有变量的照顾.单行代码,瞧,你刚刚创建了一个卷积层.有了tf.nn.conv2d
,你必须在将权重变量传递给函数之前自己声明权重变量.至于偏见,实际上它们甚至都没有处理过:你需要在以后自己添加它们.
除此之外,tf.layers.conv2d
还建议在同一个函数调用中添加正则化和激活,您可以想象当更高级别的API涵盖了需求时,这可以减少代码大小.
更高级别也会默认做出一些可被视为最佳实践的决策.例如,默认情况下会将损失tf.losses
添加到tf.GraphKeys.LOSSES
集合中,这使得各种组件的恢复和求和变得容易且有些标准化.如果您使用较低级别的API,则需要自己完成所有这些操作.显然,当你开始在那里混合低级和高级API函数时,你需要小心.
更高级别的API也可以满足那些在其他框架中被用于类似高级功能的人们的巨大需求.当考虑构建在tensorflow之上的替代更高级API的数量时,这是相当明显的,例如keras 2(现在是官方tensorflow API的一部分),slim(in tf.contrib.slim
),tflearn,tensorlayer等.
最后,如果我可以添加一个建议:如果你开始使用tensorflow并且没有对特定API的偏好,我个人会鼓励你坚持使用tf.keras.*
API:
它的API很友好,至少与构建在低级tensorflow API之上的其他高级API一样好
它在tensorflow中有一个清晰的命名空间(尽管它可以 - 有时应该 - 与其他命名空间中的部分一起使用,例如tf.data
)
它现在是张量流的一等公民(过去曾经tf.contrib.keras
),并且注意使新的张量流特征(例如eager
)与keras兼容.
它的通用实现可以使用其他工具包,如CNTK,因此不会将您锁定到tensorflow.