alterna ai
ALTERNA AI / ГЛАВА 02 · 02

02.2 Два преобразования подряд

На предыдущей странице: матрица меняет пространство.

Применим одно правило, затем другое. Общая таблица может заменить оба шага, но порядок действий важен.

Сначала поворот, затем растяжение.

Произведение возникает из композиции функций

Пусть сначала применяется BB, затем AA:

z=Bx,y=Az=A(Bx).z=Bx, \qquad y=Az=A(Bx).

Хотим заменить два последовательных оператора одним CC, чтобы y=Cxy=Cx. Подставим

zr=∑j=1nBrjxjz_r=\sum_{j=1}^{n}B_{rj}x_j

в формулу для yiy_i:

yi=∑r=1kAirzr=∑r=1kAir∑j=1nBrjxj=∑j=1n(∑r=1kAirBrj)xj.y_i=\sum_{r=1}^{k}A_{ir}z_r =\sum_{r=1}^{k}A_{ir}\sum_{j=1}^{n}B_{rj}x_j =\sum_{j=1}^{n}\left(\sum_{r=1}^{k}A_{ir}B_{rj}\right)x_j.

Следовательно,

A∈Rm×k,B∈Rk×n,C=AB∈Rm×n,Cij=∑r=1kAirBrj.A\in\mathbb R^{m\times k}, \quad B\in\mathbb R^{k\times n}, \quad C=AB\in\mathbb R^{m\times n}, \quad C_{ij}=\sum_{r=1}^{k}A_{ir}B_{rj}.

Внутренняя размерность kk должна совпасть, потому что она перечисляет компоненты промежуточного вектора zz. Внешние размеры m,nm,n остаются размерами итогового оператора.

Row-column trace без скрытого шага

Возьмём

A=[2101],B=[0−110].A=\begin{bmatrix}2&1\\0&1\end{bmatrix}, \qquad B=\begin{bmatrix}0&-1\\1&0\end{bmatrix}.

Каждая ячейка ABAB является dot строки AA и столбца BB:

AB=[2⋅0+1⋅12⋅(−1)+1⋅00⋅0+1⋅10⋅(−1)+1⋅0]=[1−210].AB=\begin{bmatrix} 2\cdot0+1\cdot1 & 2\cdot(-1)+1\cdot0\\ 0\cdot0+1\cdot1 & 0\cdot(-1)+1\cdot0 \end{bmatrix} =\begin{bmatrix}1&-2\\1&0\end{bmatrix}.

Например, элемент (0,1)(0,1) равен −2-2, а не произведению A01B01=−1A_{01}B_{01}=-1. Покомпонентное произведение Адамара и matmul являются разными операциями даже для одинаковых shapes.

Порядок операторов читается справа налево

В выражении (AB)x(AB)x первым действует BB. При x=[1,2]Tx=[1,2]^T:

Bx=[−2,1]T,A(Bx)=[−3,1]T.Bx=[-2,1]^T, \qquad A(Bx)=[-3,1]^T.

Обратный порядок даёт

BA=[0−121],BAx=[−2,4]T.BA=\begin{bmatrix}0&-1\\2&1\end{bmatrix}, \qquad BAx=[-2,4]^T.

Значит, AB≠BAAB\ne BA. Геометрически «сначала повернуть, затем выполнить shear/scale» обычно не равно «сначала деформировать, затем повернуть».

Ассоциативность не означает коммутативность

При совместимых shapes

A(BC)=(AB)C.A(BC)=(AB)C.

Обе стороны описывают одну композицию трёх функций в одном порядке. Скобки меняют только то, какое промежуточное произведение вычисляется первым. Для размеров [m,k][k,n][n,p][m,k][k,n][n,p] стоимость может заметно отличаться:

cost⁡((AB)C)∼mkn+mnp,cost⁡(A(BC))∼knp+mkp.\operatorname{cost}((AB)C)\sim mkn+mnp, \qquad \operatorname{cost}(A(BC))\sim knp+mkp.

В точной арифметике результаты равны. В floating-point изменение порядка суммирования может дать небольшое расхождение округления. Это не отменяет алгебраическую ассоциативность, но требует допуска при численном сравнении.

Identity удовлетворяет AI=IA=AAI=IA=A. Нулевая матрица подходящего shape уничтожает результат. Транспонирование обращает порядок:

(AB)T=BTAT.(AB)^T=B^TA^T.

Последнее равенство можно проверить по индексам и оно станет важным для backward pass.

Прямой алгоритм произведения [m,k]×[k,n][m,k]\times[k,n] требует mknmkn умножений. Параллельное устройство меняет организацию вычислений и движение данных, но не формулу ячейки. В лаборатории выбирайте одну ячейку trace и проверяйте два произведения до сравнения полных ABAB и BABA.

A, B = [[2, 1], [0, 1]], [[0, -1], [1, 0]]
C = [[sum(A[i][r] * B[r][j] for r in range(2))
      for j in range(2)] for i in range(2)]
assert C == [[1, -2], [1, 0]]

Код повторяет только что разобранные операции. Полный проверяемыйPython-пример главы доступен отдельным файлом; показанный короткий фрагмент не заменяет его реализацию.

Если поменять порядок, получится другое преобразование. Это важно и для порядка слоёв нейросети.

Когда теряется направление. Как этот вопрос продолжает полученный результат?

Python-примеры главы 02 Академическая база →