Об autograd в pyorch, добавлении новых пользовательских слоев, как мне обновить его параметры? - PullRequest
0 голосов
/ 28 декабря 2018

каждый!

Мое требование - это проблема, связанная с генерацией оптического потока.У меня есть два необработанных изображения и данные оптического потока в качестве наземной истины, теперь мой алгоритм состоит в том, чтобы генерировать оптический поток с использованием необработанных изображений, а евклидово расстояние между генерацией оптического потока и наземной истиной можно определить как величину потерь, поэтому он может реализоватьобратное распространение для обновления параметров.

Я воспринимаю это как проблему регрессии, и теперь у меня есть идеи:

Я могу установить каждый параметр как (required_grad = true) и вычислить убыток, затемЯ могу использовать loss.backward () для получения градиента, но я не знаю, как добавить эти параметры в оптимизатор для их обновления.

Я пишу свой алгоритм в качестве модели.Если я проектирую «пользовательскую» модель, я могу инициализировать несколько слоев, таких как nn.Con2d (), nn.Linear () в def init (), и я могу обновить параметры такими методами, как (torch.optim.Adam (model.parameters).())), но если я определяю новые слои самостоятельно, как мне добавить параметры этого слоя в обновление коллекции параметров ???

Эта проблема смутила меня несколько дней.Есть ли хорошие методы для обновления пользовательских параметров?Буду очень признателен, если вы дадите мне несколько советов!

1 Ответ

0 голосов
/ 28 декабря 2018

Тензорным значениям рассчитывают свои градиенты, если они

  1. Имеют requires_grad == True
  2. Используются для вычисления некоторого значения (обычно потери), для которого вы вызываете .backward().

Затем градиенты будут накапливаться в их параметре .grad.Вы можете использовать их вручную для выполнения произвольных вычислений (включая оптимизацию).Предопределенные оптимизаторы принимают итерацию с параметрами , а model.parameters() делает именно это - возвращает итерируемые параметры.Если у вас есть некоторые пользовательские «плавающие» параметры, вы можете передать их как

my_params = [my_param_1, my_param_2]
optim = torch.optim.Adam(my_params)

, а также объединить их с итерациями других параметров, как показано ниже:

model_params = list(model.parameters())
my_params = [my_param_1, my_param_2]
optim = torch.optim.Adam(model_params + my_params)

На практикеоднако, вы можете обычно структурировать свой код, чтобы избежать этого.Есть класс nn.Parameter, который упаковывает тензоры.Все подклассы nn.Module имеют свои __setattr__ переопределенные, так что всякий раз, когда вы назначаете экземпляр nn.Parameter в качестве его свойства, он становится частью итераций Module .parameters().Другими словами,

class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.my_param_1 = nn.Parameter(torch.tensor(...))
        self.my_param_2 = nn.Parameter(torch.tensor(...))

позволит вам написать

module = MyModule()
optim = torch.optim.Adam(module.parameters())

и иметь optim update module.my_param_1 и module.my_param_2.Это предпочтительный способ, так как он помогает сохранить ваш код более структурированным

  1. Вам не нужно будет вручную включать все ваши параметры при создании оптимизатора
  2. Вы можете вызвать module.zero_grad() и обнуляем градиент для всех его дочерних элементов nn.Parameter с.
  3. Вы можете вызывать такие методы, как module.cuda() или module.double(), который, опять же, работает на всех дочерних элементах nn.Parameter s вместо необходимости вручную выполнять их итерацию.
...