欢迎光临散文网 会员登陆 & 注册

【TF/Guide笔记】 05. Modules, layers and models

2022-02-28 18:00 作者:纪一希  | 我要投稿

    前面看到的那些Tensor,Variable,Graph之类的东西,都是比较直接的对应到底层实现的,这些东西很可能是直接从c++代码pybind过来的。

    到了module这一层,基本上就是利用python在用户一层的封装了,为的都是怎么更方便的调用底层代码。

    例如只要继承了tf.Module类,内部声明的Variable都会被记录下来,可以通过trainable_variables查看,类似的功能我们以前也做过,不过由于不熟悉python特性,所以写的比较丑陋。从原理上推测,虽然Module是可以递归的检查出sub module内的Variable的,但真正的实现应该还是累加式的而不是真的递归去找的。

    文档里有说,Module子类关于计算图声明的部分,并不一定要写在__call__下,文档自己为了看着舒服才这么写的,从这儿也能看出Module最重要的功能还是管理内部的Variable,管理则是为了在后面方便你做统一的IO。

    Module规定了一套统一的输出格式,metadata里放的是模型结构,data里放的是Variable的值,这个结构是在应用层规定的,而不是底层必须的,也就是说你自己展开来写py的话,完全可以把需要的东西存成其他格式(虽然没必要)。

    由于eager execution相当于脚本语言,所以module恢复的也是脚本语言,如果使用tf.function,也就是建立计算图的话,那么你的环境里只需要有tf最核心的代码就可以运行这个模型,所谓的平台之间迁移,无非是因为他们最底下共用的东西是一样的。

    但是tf.function的多态是在python层面做的,如果只load上来计算图的话,就没有东西去兼容不同格式的输入了。关于多态还有个小问题,文档里样例代码使用的输入都是数组而非Variable,这就导致你把[2, 2, 2]换成[2, 3, 3]都会触发多态。


    Keras模块下的代码估计都是针对python层面的封装,继承自keras.layers.Layer的子类就不能再随意给计算图的函数起名了,这里必须使用call。

    build函数相当于把前面提过的if判断帮你省略了,独立出声明Variable的过程也许还有其他好处,不过这里其实隐式的假设了只能有一个tensor变量作为输入,大数据下的确是这样没错,只是多少有点跟前面的文档脱节。

    keras和module是不能混用的,没法递归里面的Variable。

    可以先声明计算图,然后直接用输入和输出构造一个keras.Model,这里可以看出,keras内部关于计算图的部分是默认带tf.function修饰的,并非eager execution。这种脱离输入数据的声明可以用keras.Input作为placeholder,不确定的维度填None,不过这里的维度要比x少一位,首位被默认填了None,因为通常第一维都是数据行数,这个肯定是无法提前确定的。

    keras也可以通过tf.saved_model读写,但这并不是因为tf.saved_model是个万能IO模块,而是因为tf.saved_model是针对tf.Module实现的,而keras又是基于tf.Module实现的,所以两者可以混用罢了。

【TF/Guide笔记】 05. Modules, layers and models的评论 (共 条)

分享到微博请遵守国家法律