AKA Keras Model
магия подклассов.
Во время игры с Keras я заметил, что 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
collection, будет ли она по-прежнему той же моделью?
В большинстве учебных пособий каждый слой фактически вставляется в свой собственный атрибут.
Бонусный вопрос: почему это делается неявно?Этот вид магии как бы ломает девиз, отдавая предпочтение явному, а не неявному.Что если по какой-то причине мне понадобится использовать пользовательский тип коллекции, не производный от list
?Как мне убедиться, что эти магические операции выполнены правильно?