Тонкая настройка обнаружения объектов GluonCV - выберите, какие слои будут изменены (остальное заморозить)

У меня вопрос о процедуре тонкой настройки предварительно обученной модели обнаружения объектов с помощью GluonCV, описанной в этом руководстве.

Насколько я понимаю, описанная процедура изменяет все значения веса в модели. Я хотел только настроить полностью подключенный слой в конце сети и заморозить остальные веса.

Я предполагаю, что я должен указать, какие параметры я хочу изменить при создании трейнера:

trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.001, 'wd': 0.0005, 'momentum': 0.9})

поэтому вместо net.collect_params() я должен перечислить параметры, которые мне нужны для обучения, и запустить остальную часть процесса в обычном режиме. Однако я не знаю, как точно выделить эти параметры... Я попробовал распечатать:

params = net.collect_params()

но из этого списка я не знаю, какие из них соответствуют последним слоям FC. Какие-либо предложения?

1 ответ

Допустим, у нас есть предварительно обученная глюонная модель для задачи классификации:

      >>> import mxnet as mx
>>> net = mx.gluon.nn.HybridSequential()
>>> net.add(mx.gluon.nn.Conv2D(channels=6, kernel_size=5, padding=2, activation='sigmoid'))
>>> net.add(mx.gluon.nn.MaxPool2D(pool_size=2, strides=2))
>>> net.add(mx.gluon.nn.Flatten())
>>> net.add(mx.gluon.nn.Dense(units=10))
>>> net.collect_params()
hybridsequential0_ (
  Parameter conv0_weight (shape=(6, 0, 5, 5), dtype=<class 'numpy.float32'>)
  Parameter conv0_bias (shape=(6,), dtype=<class 'numpy.float32'>)
  Parameter dense0_weight (shape=(1, 0), dtype=float32)
  Parameter dense0_bias (shape=(1,), dtype=float32)
)

Чтобы точно настроить эту сверточную сеть, мы хотим заморозить все блоки, кроме.

Во-первых, напомним, что метод принимает строку регулярного выражения для выбора конкретных параметров блока по их именам (или префиксам; prefix параметр, Dense, или любой другой глюонный (гибридный) блок). По умолчанию префиксы являются именами классов, т.е. если блок Conv2D тогда префикс conv0_ или же conv1_ и т.д. Кроме того, возвращает экземпляр mxnet.gluon.parameter.ParameterDict, у которого есть setattr метод.

Решение:

      >>> conv_params = net.collect_params('(?!dense).*')
>>> conv_params.setattr('grad_req', 'null')

или просто

      >>> net.collect_params('(?!dense).*').setattr('grad_req', 'null')

Здесь мы исключаем все совпадающие параметры, чтобы получить только convблоки и установите их атрибуты на. Теперь обучаем модель net с mxnet.gluon.Trainer будет обновлять только dense параметры.


Более удобно иметь предварительно обученную модель с отдельными атрибутами, указывающими определенные блоки, например, блок функций, генераторы привязок и т. Д. В нашем случае у нас есть сверточная сеть, которая извлекает признаки и передает их в выходной блок.

      class ConvNet(mx.gluon.nn.HybridSequential):
    def __init__(self, n_classes, params=None, prefix=None):
        super().__init__(params=params, prefix=prefix)

        self.features = mx.gluon.nn.HybridSequential()
        self.features.add(mx.gluon.nn.Conv2D(channels=6, kernel_size=5, padding=2,
                          activation='sigmoid'))
        self.add(mx.gluon.nn.MaxPool2D(pool_size=2, strides=2))
        self.add(mx.gluon.nn.Flatten())

        self.output = mx.gluon.nn.Dense(units=n_classes)

    def hybrid_forward(self, F, x):
        x = self.features(x)
        return self.output(x)

С этим объявлением convnet нам не нужно использовать регулярные выражения для доступа к необходимым блокам:

      >>> net = ConvNet(n_classes=10)
>>> net.features.collect_params().setattr('grad_req', 'null')

Модели Gluon CV следуют именно этой схеме. Посмотрите документацию на нужную модель и выберите блоки, которые вы хотите заморозить. Если документы пусты, запустите collect_params чтобы увидеть все параметры и отфильтровать с помощью регулярного выражения те, которые нужно настроить, и установить возвращаемые параметры ' grad_req к 'null'.

Другие вопросы по тегам