В этой главе представлен краткий обзор механизма динамического графа PyTorch и механизма статического графа Tensorflow (последняя версия TF также поддерживает динамические графы).
1 Предварительный вывод динамического графа
- Вычислительные графы используются для описания операцийНаправленный ациклический граф
- Вычислительный граф имеет два основных элемента: Node и Edge;
- Узел представляет данные, такие как векторы, матрицы и тензоры;
- Ребра представляют операции, такие как сложение, вычитание, умножение и деление, свертка и т. д.;
Приведенный выше рисунок представлен вычислительным графиком:
Из их,, , , (a и b являются чем-то вроде промежуточных переменных.)
Когда Pytorch вычисляет, он сохраняет процесс расчета с динамическим графиком, как указано выше. Теперь давайте вычислим градиент y относительно w:
(В приведенном выше расчете w=1, x=2)
Теперь мы используем код Pytorch для реализации этого процесса:
import torch
w = torch.tensor([1.],requires_grad = True)
x = torch.tensor([2.],requires_grad = True)
a = w+x
b = w+1
y = a*b
y.backward()
print(w.grad)
Полученные результаты:
2 конечных узла динамических графов
Листовые узлы этого графа, w и x, являются основой всего вычислительного графа. Причина, по которой используется концепция листовых узлов, состоит в том, чтобыУменьшите объем памяти, после завершения обратного распространения будут освобождены градиенты нелистовых узлов., мы по-прежнему используем приведенный выше пример для объяснения:
import torch
w = torch.tensor([1.],requires_grad = True)
x = torch.tensor([2.],requires_grad = True)
a = w+x
b = w+1
y = a*b
y.backward()
print(w.is_leaf,x.is_leaf,a.is_leaf,b.is_leaf,y.is_leaf)
print(w.grad,x.grad,a.grad,b.grad,y.grad)
Результат бега таков:
Вы можете видеть, что только x и w являются конечными узлами, и после обратного распространения вычисляется градиент (.backward()
позже) сохраняются только градиенты конечных узлов.
Конечно, вы также можете.retain_grad()
чтобы сохранить значения градиента непроизвольных узлов.
import torch
w = torch.tensor([1.],requires_grad = True)
x = torch.tensor([2.],requires_grad = True)
a = w+x
a.retain_grad()
b = w+1
y = a*b
y.backward()
print(w.is_leaf,x.is_leaf,a.is_leaf,b.is_leaf,y.is_leaf)
print(w.grad,x.grad,a.grad,b.grad,y.grad)
результат операции:
3. grad_fn
torch.tensor
имеет атрибутgrad_fn
,grad_fn
Функция предназначена для записи функции, используемой для создания тензора, который будет использоваться при обратном распространении этого свойства. Например, в приведенном выше примереy.grad_fn=MulBackward0
, что указывает на то, что y получается умножением. Итак, когда вы занимаетесь выводом, вы используете выводное правило умножения. такой же,a.grad=AddBackward0
Указывает, что a получается сложением с использованием правила вывода сложения.
import torch
w = torch.tensor([1.],requires_grad = True)
x = torch.tensor([2.],requires_grad = True)
a = w+x
a.retain_grad()
b = w+1
y = a*b
y.backward()
print(y.grad_fn)
print(a.grad_fn)
print(w.grad_fn)
Результат бега таков:
листовой узел.grad_fn
Нет.
4 Статическое изображение
Разницу между ними можно выразить одним предложением:
- Динамический график: используется pytorch, работа и построение выполняются одновременно; гибкий и простой в настройке.
- Статический граф: используется старым тензорным потоком, сначала строится граф, а затем выполняется операция, он эффективен и негибок.
Для статических графов нам нужно сначала определить поток алгоритма. Например, мы сначала даем
, ,
Затем сохраните приведенный выше поток операций, а затем поместите w=1, x=2 в позицию входа вышеуказанного рабочего кадра для работы. Динамический граф должен напрямую работать с назначенными w и x, а затем изменять операцию для построения графа операций.
в курсеНа данный момент 231 вы.Стэнфорд.Сумма/слайды/2018…
Этот код из Tensorflow, При построении операции сначала создайте кадр операции, а затем поместите в него конкретные числа. Весь процесс похож на обучение нейронной сети, нам нужно построить структуру модели, а затем в процессе обучения занести данные в модель. Это похоже на то, как когда мы путешествуем, мы заранее определяем дневной маршрут, а затем каждый день действуем по маршруту.
Динамический граф предназначен для непосредственной работы с данными, а затем для динамического построения графа операций. Это соответствует нашим вычислительным привычкам.
Разница между ними в том, что статический график сначала объясняет, как рассчитываются данные, а затем размещает данные. Предполагая, что необходимо ввести 50 наборов данных, график операций строится заранее, поэтому каждый раз градиент рассчитывается быстро и эффективно; график операций динамического графа строится одновременно с расчетом данных, принимая что необходимо ввести 50 наборов данных, то необходимо сгенерировать 50 графов операций. Это не так эффективно. так называемыйдинамическое изображение.
Хотя динамические графы не так эффективны, их преимущества заключаются в следующем:
- Легче отлаживать.
- Динамические вычисления больше подходят для обработки естественного языка. (Это может быть связано с тем, что ввод обработки естественного языка часто имеет переменную длину?)
- Динамические графы больше подходят для объектно-ориентированного программирования, и мы будем чувствовать себя более естественно.