Вычислить грады клонированного тензора Pytorch - PullRequest
0 голосов
/ 25 марта 2020

Мне сложно вычислить градиент с помощью 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 Ответ

0 голосов
/ 27 марта 2020

Основываясь на комментариях, проблема в том, что hidden_copy никогда не посещается во время обратного прохода.

Когда вы выполняете обратный цикл, следует за графом вычислений в обратном направлении, начиная с loss_T, и работает в обратном направлении ко всем листам. узлы. Он посещает только тензоры, которые были использованы для вычисления loss_T. Если тензор не является частью этого обратного пути, он не будет посещен и его grad член не будет обновлен. В основном, если создать копию тензора и затем не использовать ее для вычисления loss_T, это приводит к «тупику» в графе вычислений.

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

Обратите внимание: если мы пойдем по пути от loss_T к листьям, мы никогда не посетим hidden_conv. Обратите внимание, что лист - это тензор без потомков, и в этом случае input является единственным листом.

Это чрезвычайно упрощенный граф вычислений, используемый для демонстрации точки. Конечно, в действительности, вероятно, существует гораздо больше узлов между input и hidden и между hidden и output_T, а также другими листовыми тензорами, поскольку веса слоев почти наверняка равны листам.

...