Дифференциальное и матричное исчисление

Матричное дифференцирование

Четыре формулы, которые нужны постоянно, и соглашение о layout, которое портит половину выкладок

Шаг 29 из 117 · ~32 мин

Сначала про соглашение

Прежде чем считать, нужно договориться, как располагать результат. Есть два соглашения, и они дают транспонированные друг другу ответы.

  • Numerator layout (он же якобианов): индекс выхода нумерует строки. Тогда y/x\partial \mathbf{y}/\partial \mathbf{x} для yRm\mathbf{y} \in \R^m, xRn\mathbf{x} \in \R^n имеет форму m×nm \times n — это якобиан из прошлого урока.
  • Denominator layout (он же градиентный): индекс входа нумерует строки. Та же производная получает форму n×mn \times m.
производнаяформы операндовформа результата
∂f/∂xf скаляр, x из Rⁿ1 × n (строка)
∂y/∂xy из Rᵐ, x из Rⁿm × n
∂(Ax)/∂xA размера m × nA
∂f/∂Wf скаляр, W размера m × nn × m
Выход нумерует строки. Скалярная функция даёт строку, и правило цепочки читается слева направо как обычное умножение матриц: J_f · J_g. Так пишут в учебниках по анализу.

Практическое правило: в машинном обучении почти всегда denominator layout, потому что градиент должен иметь ту же форму, что параметр — иначе шаг wwηf\mathbf{w} \leftarrow \mathbf{w} - \eta\nabla f не записать. В учебниках по анализу и в теоретических статьях чаще numerator.

Как жить с этим: не запоминать соглашение, а проверять формы. Если в вашей выкладке градиент по WW имеет форму WW — вы в denominator layout и всё сойдётся с кодом. Дальше в этом уроке используется он.

Формула первая: линейное отображение

(Ax)x=A\frac{\partial (A\mathbf{x})}{\partial \mathbf{x}} = A^\top

Проверяется по элементам: (Ax)i=jAijxj(A\mathbf{x})_i = \sum_j A_{ij}x_j, значит (Ax)i/xj=Aij\partial (A\mathbf{x})_i/\partial x_j = A_{ij}. В denominator layout строки нумеруются входом jj, поэтому на месте (j,i)(j, i) стоит AijA_{ij} — это и есть AA^\top.

Это тот же факт, что «якобиан линейного отображения равен самому отображению», записанный в другом соглашении.

Формула вторая: квадратичная форма

xxAx=(A+A)x\frac{\partial}{\partial \mathbf{x}}\htmlData{k=q}{\mathbf{x}^\top A \mathbf{x}} = \htmlData{k=g}{(A + A^\top)\mathbf{x}}

Для симметричной AA это 2Ax2A\mathbf{x} — прямой аналог (x2)=2x(x^2)' = 2x. Гессианы и ковариационные матрицы симметричны, поэтому на практике встречается почти всегда эта форма.

Вывод стоит проделать один раз по индексам: xAx=i,jAijxixj\mathbf{x}^\top A\mathbf{x} = \sum_{i,j}A_{ij}x_ix_j, и при дифференцировании по xkx_k переменная xkx_k встречается дважды — в роли ii и в роли jj. Отсюда и сумма двух слагаемых. Это ровно та «сумма по путям» из урока про правило цепочки.

Формула третья: наименьшие квадраты

xAxb2=2A(Axb)\frac{\partial}{\partial \mathbf{x}}\|A\mathbf{x} - \mathbf{b}\|^2 = 2A^\top(A\mathbf{x} - \mathbf{b})

Самая используемая формула блока. Вывод — цепочка из двух звеньев: внешнее r2\|\mathbf{r}\|^2 даёт 2r2\mathbf{r}, внутреннее r=Axb\mathbf{r} = A\mathbf{x}-\mathbf{b} даёт AA^\top (первая формула).

Приравняв нулю, получаем AAx=AbA^\top A\mathbf{x} = A^\top \mathbf{b} — нормальное уравнение из практики блока 1. Тогда мы вывели его геометрически, через ортогональность остатка; теперь он же получается дифференцированием. Два разных пути к одному ответу — хороший признак, что вы поняли оба.

Формула четвёртая: производная по матрице

Для слоя y=Wx\mathbf{y} = W\mathbf{x} и скалярного лосса LL:

LW=Lyx\frac{\partial L}{\partial W} = \frac{\partial L}{\partial \mathbf{y}}\,\mathbf{x}^\top

Внешнее произведение вектора градиента на вектор входа. Проверка форм: если L/y\partial L/\partial \mathbf{y} это m×1m \times 1, а x\mathbf{x}^\top это 1×n1 \times n, произведение даёт m×nm \times n — форму самой WW, как и требуется.

И симметрично, для передачи градиента ниже по сети:

Lx=WLy\frac{\partial L}{\partial \mathbf{x}} = W^\top \frac{\partial L}{\partial \mathbf{y}}

Эти две строки — целиком backward для линейного слоя. Всё, что делает nn.Linear.backward, здесь написано.

Как проверять выкладки

Три приёма, которые ловят почти все ошибки:

  1. Формы. Каждый промежуточный результат должен иметь осмысленную форму, а финальный градиент — форму параметра. Транспонирование, поставленное не туда, почти всегда ломает размерности.
  2. Скалярный случай. Подставьте n=m=1n = m = 1: матрицы станут числами, и формула должна превратиться в знакомое одномерное правило. 2A(Axb)2A^\top(A x - b) становится 2a(axb)2a(ax-b) — верно.
  3. Численная проверка. Сравните с центральной разностью. Это то, что делают в реальности, и то, чем мы закроем блок.

Из этих трёх второй недооценивают чаще всего, а он самый быстрый: скалярный случай проверяется в голове.

Источники

Проверки

0 из 2
  1. Формы и соглашения

    Слой y=Wx\mathbf{y} = W\mathbf{x}, где WW имеет форму m×nm \times n, лосс LL скалярный. Используется denominator layout. Отметьте все верные утверждения.

  2. Градиент квадрата невязки

    Реализуйте lsq_gradient(a, x, b) — градиент Axb2\|A\mathbf{x} - \mathbf{b}\|^2 по x\mathbf{x}:

    2A(Axb)2A^\top(A\mathbf{x} - \mathbf{b})

    a — матрица списком строк, x и b — списки. Верните список длины, равной длине x.

    Порядок действий тот же, что в формуле: посчитайте невязку r=Axb\mathbf{r} = A\mathbf{x} - \mathbf{b}, затем умножьте на AA^\top и на 2. Транспонировать матрицу целиком не обязательно — достаточно просуммировать a[i][j] * r[i] по строкам.

    Проверьте формы: если a имеет размер m×nm \times n, то r\mathbf{r} длины mm, а результат — длины nn.

    функция lsq_gradient

    Загрузка редактора…

    Ctrl/⌘ + Enter