Понимание того, когда использовать python list в Pytorch

#deep-learning #pytorch #backpropagation

#глубокое обучение #pytorch #обратное распространение

Вопрос:

В принципе, как здесь обсуждается в этом потоке, вы не можете использовать python list для переноса ваших подмодулей (например, ваших слоев); в противном случае Pytorch не собирается обновлять параметры подмодулей внутри списка. Вместо этого вы должны использовать nn.ModuleList для упаковки своих подмодулей, чтобы убедиться, что их параметры будут обновлены. Теперь я также видел коды, подобные следующему, где автор использует python list для вычисления потерь, а затем делает loss.backward() обновление (в алгоритме усиления RL). Вот код:

  policy_loss = []
    for log_prob in self.controller.log_probability_slected_action_list:
        policy_loss.append(- log_prob * (average_reward - b))
    self.optimizer.zero_grad()
    final_policy_loss = (torch.cat(policy_loss).sum()) * gamma
    final_policy_loss.backward()
    self.optimizer.step()
  

Почему использование списка в этом формате работает для обновления параметров модулей, но в первом случае не работает? Сейчас я очень смущен. Если я изменяю предыдущий код policy_loss = nn.ModuleList([]) , он выдает исключение, в котором говорится, что tensor float не является подмодулем.

Ответ №1:

Вы неправильно понимаете, что такое Module s. Module Хранит параметры и определяет реализацию прямого прохождения.

Вам разрешено выполнять произвольные вычисления с тензорами и параметрами, приводящими к другим новым тензорам. Modules необязательно знать об этих тензорах. Вам также разрешено хранить списки тензоров в списках Python. При вызове backward он должен быть в скалярном тензоре, таким образом, сумма конкатенации. Эти тензоры являются потерями, а не параметрами, поэтому они не должны быть атрибутами Module или обернуты в ModuleList .