9.3 KiB
Дифференциальное и матричное исчисление
Зачем это нужно
Обучение модели обычно означает минимизацию функции потерь. Производная отвечает на локальный вопрос: как изменится результат при малом изменении параметра? Градиент обобщает ответ на много параметров, а матричное исчисление позволяет записать вычисление без циклов по каждому весу.
Предел, производная и локальная линейность
Производная функции f:\mathbb{R}\to\mathbb{R} в точке x:
f'(x)=\lim_{h\to0}\frac{f(x+h)-f(x)}{h}.
Это не просто наклон касательной. Если производная существует, то при малом
h
f(x+h)=f(x)+f'(x)h+o(h),
где o(h)/h\to0. Главная идея — гладкая функция локально ведёт себя как
линейная. Например, для f(x)=x^2:
\frac{(x+h)^2-x^2}{h}
=\frac{2xh+h^2}{h}=2x+h\to2x.
Отсюда d(x^2)/dx=2x.
Правила дифференцирования
(f+g)'=f'+g',\qquad
(fg)'=f'g+fg',\qquad
\left(\frac fg\right)'=\frac{f'g-fg'}{g^2}.
Для композиции y=f(g(x)) правило цепочки:
\frac{dy}{dx}
=\frac{df}{dg}\frac{dg}{dx}.
Пример: L(w)=(wx-y)^2. Введём r=wx-y, тогда
\frac{dL}{dw}
=\frac{d(r^2)}{dr}\frac{dr}{dw}
=2r\,x
=2(wx-y)x.
Промежуточная переменная делает структуру обратного распространения явной: локальные производные перемножаются от выхода к входу.
Частные производные и градиент
Для f:\mathbb{R}^d\to\mathbb{R} частная производная меняет одну координату,
фиксируя остальные. Градиент собирает их:
\nabla_{\mathbf{x}}f=
\begin{bmatrix}
\partial f/\partial x_1\\
\cdots\\
\partial f/\partial x_d
\end{bmatrix}.
Дифференцируемость означает
f(\mathbf{x}+\Delta\mathbf{x})
=f(\mathbf{x})
+\nabla f(\mathbf{x})^\top\Delta\mathbf{x}
+o(\|\Delta\mathbf{x}\|).
По неравенству Коши—Буняковского изменение первого порядка максимально при
\Delta\mathbf{x} в направлении градиента. Поэтому
-\nabla f — направление быстрейшего локального убывания при евклидовой
норме.
Якобиан и многомерное правило цепочки
Для (\mathbf{g}:\mathbb{R}^d\to\mathbb{R}^m)
якобиан имеет размер m\times d:
(\mathbf{J}_{\mathbf{g}})_{ij}
=\frac{\partial g_i}{\partial x_j}.
Если L=f(\mathbf{g}(\mathbf{x})), где f:\mathbb{R}^m\to\mathbb{R}, то
\nabla_{\mathbf{x}}L
=\mathbf{J}_{\mathbf{g}}(\mathbf{x})^\top
\nabla_{\mathbf{g}}f.
Размерности дают проверку:
(d\times m)(m\times1)=d\times1.
Гессиан и кривизна
Гессиан содержит вторые производные:
\mathbf{H}_f=\nabla^2f,\qquad
f(\mathbf{x}+\Delta)
\approx f(\mathbf{x})+\nabla f^\top\Delta
+\frac12\Delta^\top\mathbf{H}_f\Delta.
Если \mathbf{H}_f\succeq0 во всей области, гладкая функция выпукла.
В стационарной точке положительно определённый гессиан указывает на строгий
локальный минимум, отрицательно определённый — на максимум, смешанные знаки
собственных значений — на седловую точку.
Дифференциалы и матрицы
Дифференциал удобен тем, что подчиняется обычной алгебре:
d(\mathbf{A}\mathbf{X}\mathbf{B})
=\mathbf{A}\,d\mathbf{X}\,\mathbf{B}
для постоянных \mathbf{A},\mathbf{B}, а
d(\mathbf{X}^\top)=d\mathbf{X}^\top.
Для скалярной f(\mathbf{X}) приводим дифференциал к форме
df=\operatorname{tr}\left(
(\nabla_{\mathbf{X}}f)^\top d\mathbf{X}\right).
Полезны свойства следа:
\operatorname{tr}(\mathbf{A}\mathbf{B})
=\operatorname{tr}(\mathbf{B}\mathbf{A}),\qquad
\operatorname{tr}(\mathbf{A}^\top d\mathbf{X})
=\langle\mathbf{A},d\mathbf{X}\rangle_F.
Вывод градиента линейной регрессии
Пусть
L(\mathbf{w})
=\frac{1}{2n}\|\mathbf{X}\mathbf{w}-\mathbf{y}\|_2^2.
Обозначим \mathbf{r}=\mathbf{X}\mathbf{w}-\mathbf{y}. Тогда
L=\frac1{2n}\mathbf{r}^\top\mathbf{r}.
Последовательно:
dL
=\frac1{2n}\left(d\mathbf{r}^\top\mathbf{r}
+\mathbf{r}^\top d\mathbf{r}\right)
=\frac1n\mathbf{r}^\top d\mathbf{r}.
Поскольку d\mathbf{r}=\mathbf{X}\,d\mathbf{w},
dL
=\frac1n\mathbf{r}^\top\mathbf{X}\,d\mathbf{w}
=\left(\frac1n\mathbf{X}^\top\mathbf{r}\right)^\top d\mathbf{w}.
Следовательно,
\boxed{\nabla_{\mathbf{w}}L
=\frac1n\mathbf{X}^\top(\mathbf{X}\mathbf{w}-\mathbf{y})}.
Ещё одно дифференцирование даёт
\nabla^2L=\mathbf{X}^\top\mathbf{X}/n\succeq0, поэтому задача выпукла.
Производные часто встречающихся выражений
\nabla_{\mathbf{x}}(\mathbf{a}^\top\mathbf{x})=\mathbf{a},
\qquad
\nabla_{\mathbf{x}}(\mathbf{x}^\top\mathbf{A}\mathbf{x})
=(\mathbf{A}+\mathbf{A}^\top)\mathbf{x}.
Для симметричной \mathbf{A} последнее равно 2\mathbf{A}\mathbf{x}.
d\log\det\mathbf{X}
=\operatorname{tr}(\mathbf{X}^{-1}d\mathbf{X}),
\qquad
\nabla_{\mathbf{X}}\log\det\mathbf{X}
=\mathbf{X}^{-\top}.
Последняя формула требует обратимой матрицы; для вещественного логарифма
обычно предполагают \mathbf{X}\succ0.
Разобранный пример
Пусть
\mathbf{X}=\begin{bmatrix}1&2\\2&0\end{bmatrix},\quad
\mathbf{w}=\begin{bmatrix}1\\-1\end{bmatrix},\quad
\mathbf{y}=\begin{bmatrix}0\\1\end{bmatrix}.
Предсказания: \mathbf{Xw}=(-1,2)^\top, остаток
\mathbf{r}=(-1,1)^\top, n=2. Тогда
L=\frac1{4}(1+1)=0.5,
\nabla L
=\frac12\mathbf{X}^\top\mathbf{r}
=\frac12
\begin{bmatrix}1&2\\2&0\end{bmatrix}
\begin{bmatrix}-1\\1\end{bmatrix}
=\begin{bmatrix}0.5\\-1\end{bmatrix}.
import numpy as np
X = np.array([[1.0, 2.0], [2.0, 0.0]])
w = np.array([1.0, -1.0])
y = np.array([0.0, 1.0])
r = X @ w - y
loss = r @ r / (2 * len(y))
grad = X.T @ r / len(y)
print(loss) # 0.5
print(grad) # [ 0.5 -1. ]
Численная проверка градиента
Центральная разность
\frac{\partial f}{\partial x_j}
\approx\frac{f(\mathbf{x}+h\mathbf{e}_j)
-f(\mathbf{x}-h\mathbf{e}_j)}{2h}
имеет ошибку усечения порядка O(h^2), но слишком малое h усиливает
ошибку округления.
def finite_difference(f, x, h=1e-5):
grad = np.zeros_like(x, dtype=float)
for j in range(x.size):
step = np.zeros_like(x, dtype=float)
step[j] = h
grad[j] = (f(x + step) - f(x - step)) / (2 * h)
return grad
f = lambda v: np.sum(v**2)
print(finite_difference(f, np.array([1.0, -3.0])))
Типичные ошибки
- Производная по вектору должна иметь проверяемую размерность.
- Поэлементное
*не заменяет матричное@. \nabla(\mathbf{x}^\top\mathbf{A}\mathbf{x})=2\mathbf{Ax}только при симметричной\mathbf{A}.- Нулевой градиент не гарантирует минимум.
- Градиент зависит от выбранной геометрии; утверждение о быстрейшем спуске выше относится к евклидовой норме.
- Численная производная служит проверкой, а не точной заменой аналитической.
Резюме
Производная — коэффициент локального линейного приближения. Градиент задаёт чувствительность скаляра ко всем координатам, якобиан — чувствительность вектора, гессиан — кривизну. Дифференциалы, след и контроль размерностей дают надёжный способ выводить матричные градиенты.