Операции над тензорами: сложение, умножение, транспонирование

В Keras.js тензоры представляют собой многомерные массивы данных, аналогичные ndarray в NumPy или Tensor в TensorFlow.js. Основные операции над тензорами включают арифметические операции, линейную алгебру и трансформации размерностей, что критически важно для построения нейронных сетей и обработки данных.


Создание тензоров

Тензоры создаются с использованием массива JavaScript или TypedArray и объекта конфигурации. Простейший пример:

const K = require('keras-js');

const tensor = new K.Tensor([1, 2, 3, 4], [2, 2]); // данные и форма

Здесь [1, 2, 3, 4] — одномерный массив данных, [2, 2] — форма тензора (2 строки, 2 столбца).

Ключевые моменты:

  • shape — массив чисел, задающий размерность тензора.
  • dtype по умолчанию — float32.
  • Tензоры в Keras.js immutable: операции создают новые тензоры, не изменяя исходные данные.

Сложение тензоров

Сложение тензоров выполняется поэлементно. Размерности тензоров должны совпадать либо быть совместимы через broadcasting.

const A = new K.Tensor([1, 2, 3, 4], [2, 2]);
const B = new K.Tensor([5, 6, 7, 8], [2, 2]);

const C = K.add(A, B);
console.log(C.data); // [6, 8, 10, 12]

Broadcasting позволяет выполнять сложение тензоров разной размерности, расширяя меньший тензор до размера большего:

const X = new K.Tensor([1, 2], [2, 1]);
const Y = new K.Tensor([10, 20], [1, 2]);

const Z = K.add(X, Y);
console.log(Z.data); // [11, 21, 12, 22]

Особенности:

  • Поддерживаются как бинарные, так и сложные выражения (K.add(K.add(A, B), C)).
  • Внутренние операции оптимизированы под WebGL, что ускоряет вычисления.

Умножение тензоров

Поэлементное умножение:

const A = new K.Tensor([1, 2, 3, 4], [2, 2]);
const B = new K.Tensor([2, 0, 1, 3], [2, 2]);

const C = K.mul(A, B);
console.log(C.data); // [2, 0, 3, 12]

Матрица умножение (dot product):

const A = new K.Tensor([1, 2, 3, 4], [2, 2]);
const B = new K.Tensor([5, 6, 7, 8], [2, 2]);

const C = K.dot(A, B);
console.log(C.data); // [19, 22, 43, 50]
  • K.mul выполняет поэлементное умножение.
  • K.dot выполняет классическое матричное умножение.
  • Для тензоров размерности > 2 K.dot выполняет батчевое умножение, автоматически обрабатывая старшие оси как отдельные батчи.

Транспонирование тензоров

Транспонирование меняет порядок осей тензора. Для 2D-тензоров это эквивалентно повороту матрицы:

const A = new K.Tensor([1, 2, 3, 4], [2, 2]);
const B = K.transpose(A);
console.log(B.data); // [1, 3, 2, 4]

Для тензоров большей размерности можно указать порядок осей:

const A = new K.Tensor([1, 2, 3, 4, 5, 6], [2, 1, 3]);
const B = K.transpose(A, [2, 0, 1]); // новая последовательность осей

Примечания:

  • Транспонирование часто используется для согласования размерностей перед матричным умножением.
  • Keras.js поддерживает ленивое вычисление, поэтому операции с большими тензорами остаются эффективными.

Смешанные операции и цепочки

Часто операции комбинируются для построения сложных вычислительных графов:

const A = new K.Tensor([1, 2, 3, 4], [2, 2]);
const B = new K.Tensor([5, 6, 7, 8], [2, 2]);
const C = new K.Tensor([2, 2, 2, 2], [2, 2]);

const D = K.add(K.mul(A, B), C);
console.log(D.data); // [7, 14, 23, 34]
  • Здесь сначала выполняется поэлементное умножение A * B, затем к результату прибавляется C.
  • Такой подход позволяет строить вычислительные графы, аналогичные слоям нейронных сетей.

Оптимизация и производительность

  • Использование WebGL-бэкенда в Keras.js обеспечивает ускорение операций с тензорами на GPU.
  • Для больших массивов рекомендуется минимизировать копирование данных и использовать цепочки операций без промежуточного извлечения data.
  • Поддерживаются операции с Float32Array, что обеспечивает точность вычислений и совместимость с нейронными сетями Keras.

Итоговые рекомендации по работе с тензорами

  • Следить за совместимостью размерностей и использовать K.transpose для согласования осей.
  • Использовать K.add и K.mul для поэлементных операций, K.dot для матричных.
  • Строить цепочки операций для оптимизации производительности и сокращения промежуточных тензоров.
  • Применять broadcasting, когда возможно, чтобы упростить вычисления с различными формами данных.