Влияет ли способ, которым я создаю и сохраняю слои в подклассах Keras `Model`? - PullRequest
0 голосов
/ 27 сентября 2019

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?Как мне убедиться, что эти магические операции выполнены правильно?

1 Ответ

1 голос
/ 28 сентября 2019

Заказ не имеет значения.Что действительно меняет вашу модель, так это метод call.Здесь хранится порядок операций (даже если бы порядок весов был переменным, они были бы применены на том же графике с теми же функциями)

Теперь, если вы подозреваете, что не используете «свойство»,но, используя другой тип хранилища для слоев, по какой-то причине не зарегистрирует слой, вы можете проверить дважды:

print(len(resnet.trainable_weights))

Количество должно быть 6 * PART_COUNT:

  • 2 тензора для слоев конвона (ядро и смещение)
  • 4 тензора для слоев пакетной нормализации (среднее значение, дисперсия, масштаб и смещение)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...