У меня проблемы с вычислением градиента с использованием PyTorch.
У меня есть выходы и скрытые состояния последнего временного шага T
RNN.
Я хотел бы клонировать свои скрытые состояния и вычислить их градиент после обратного распространения, но это не работает.
После прочтения pytorch, как вычислить градиент после клонирования тензора, я безуспешно использовал retain_grad()
.
Вот мой код
hidden_copy = hidden.clone()
hidden.retain_grad()
hidden_copy.retain_grad()
outputs_T = outputs[T]
targets_T = targets[T]
loss_T = loss(outputs_T,targets_T)
loss_T.backward()
print(hidden.grad)
print(hidden_copy.grad)
hidden_grad
дает массив, а hidden_copy.grad
дает None
.
Почему hidden_copy.grad
дает None
? Есть ли способ вычислить градиенты клонированного тензора?
1 ответ
Судя по комментариям, проблема в том, что hidden_copy
никогда не посещается во время обратного прохода.
Когда вы выполняете обратную операцию, pytorch следует графу вычислений в обратном направлении, начиная с loss_T
, и работает в обратном направлении ко всем листовым узлам. Он посещает только те тензоры, которые использовались для вычисления loss_T
. Если тензор не является частью этого обратного пути, он не будет посещен, и его элемент grad
не будет обновлен. По сути, создание копии тензора, а затем не использование его для вычисления loss_T
приводит к «тупику» в графе вычислений.
Для иллюстрации взгляните на эту диаграмму, представляющую упрощенный вид графа вычислений. Каждый узел в графе представляет собой тензор, ребра которого указывают на прямых потомков.
Обратите внимание, что если мы идем по обратному пути от loss_T
к листьям, мы никогда не посещаем hidden_conv
. Обратите внимание, что лист — это тензор без потомков, и в этом случае input
— единственный лист.
Это чрезвычайно упрощенный график вычислений, используемый для демонстрации точки. Конечно, на самом деле между input
и hidden
и между hidden
и output_T
, вероятно, гораздо больше узлов, а также других тензоров листьев, поскольку веса слоев почти наверняка равны листьям. .
hidden_1 = hidden
, а затем переназначаете hidden
чему-то новому, hidden_1
по-прежнему указывает на исходный тензор hidden
, а hidden
теперь ссылается на другой тензор. В основном попробуйте удалить .clone()
и посмотрите, как это работает.
Похожие вопросы
Связанные вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.
hidden_copy
для вычисленияoutputs_T
? Если нет, то имеет смысл, что он не получит градиент, посколькуloss_T
не зависит от него.