代码之家  ›  专栏  ›  技术社区  ›  LOST

我在子类Keras'Model'中创建和存储层的方式有什么影响吗?

  •  0
  • LOST  · 技术社区  · 7 年前

    又名凯拉斯 Model 亚类化魔法。

    在和凯拉斯玩的时候,我注意到 ResNetBlock.layers 在我将层的新实例放入以前放入自定义模型的集合时填充。

    class ResNetBlock(Model):
        PART_COUNT = 3
    
        def __init__(self, kernel_size, filters):
            super().__init__()
            self.convs = []
            self.batchNorms = []
    
            for part in range(ResNetBlock.PART_COUNT):
                if part == 1:
                    conv = Conv2D(filters[part], kernel_size=kernel_size, padding="same")
                else:
                    conv = Conv2D(filters[part], kernel_size=(1,1))
                self.convs.append(conv)
                self.batchNorms.append(BatchNormalization())
    
    resnet = ResNetBlock(1, [1, 2, 3])
    print(resnet.layers) # actually prints non-empty list
                         # filled with Conv2Ds and BNs from above
    

    摘自官方教程: https://www.tensorflow.org/beta/tutorials/eager/custom_layers

    对TensorFlow源的一些挖掘表明,通过 __setattr__ 在里面 Network 班

    现在,代码并不琐碎,缺少文档,而且似乎不清楚创建新层/将它们添加到各自集合的顺序是否重要?如果我先填写 convs 收集,然后 batchNorms 收藏,还是同一款吗?

    在大多数教程中,每个层实际上都被放入自己的属性中。

    问题是:为什么这样做是含蓄的?这种魔力有点打破了人们的座右铭,即更喜欢显性而不是隐性。如果出于某种原因,我需要使用非派生自的自定义集合类型,该怎么办 list ? 我该如何确保这些神奇的操作得到正确执行?

    0 回复  |  直到 7 年前
        1
  •  2
  •   Daniel Möller    7 年前

    顺序无关紧要。真正改变你的模型的是 call 方法这将存储操作的顺序(即使权重的顺序是可变的,它们也将应用于具有相同函数的同一图形中)

    现在,如果您怀疑不使用“属性”,而是为层使用另一种存储,由于某种原因无法注册层,您可以再次检查:

    print(len(resnet.trainable_weights))
    

    伯爵应该是 6 * PART_COUNT :

    • conv层的2个张量(核和偏置)
    • 4个标准化层的张量(均值、方差、比例和偏移)