Изменение формы: reshape, expandDims, squeeze

Работа с многомерными массивами данных в TensorFlow.js требует умения управлять формой тензоров. Операции изменения формы позволяют адаптировать данные под требования модели, упрощают вычисления и повышают читаемость кода. Ключевыми функциями для изменения формы являются reshape, expandDims и squeeze.


reshape

Функция reshape используется для изменения размеров существующего тензора без изменения его данных. Она создаёт новый тензор с указанной формой.

Синтаксис:

tf.reshape(tensor, shape)

Параметры:

  • tensor — исходный тензор.
  • shape — массив чисел, определяющий новую форму. Один из элементов может быть -1, что позволяет TensorFlow автоматически вычислить размер соответствующего измерения.

Примеры:

const x = tf.tensor([1, 2, 3, 4, 5, 6]);
const reshaped = tf.reshape(x, [2, 3]);
// Результат: [[1, 2, 3], [4, 5, 6]]

const autoReshape = tf.reshape(x, [3, -1]);
// Результат: [[1, 2], [3, 4], [5, 6]]

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

  • Новая форма должна содержать такое же количество элементов, что и исходный тензор.
  • Поддержка -1 позволяет гибко изменять форму, не вычисляя размер измерения вручную.

expandDims

Функция expandDims добавляет новое измерение в тензор, что часто требуется при подготовке данных для нейронных сетей. Чаще всего используется для добавления оси батча или канала.

Синтаксис:

tf.expandDims(tensor, axis)

Параметры:

  • tensor — исходный тензор.
  • axis — позиция, где будет добавлено новое измерение (по умолчанию 0).

Примеры:

const x = tf.tensor([1, 2, 3]);
const expanded = tf.expandDims(x, 0);
// Результат: [[1, 2, 3]] (форма [1, 3])

const expandedEnd = tf.expandDims(x, 1);
// Результат: [[1], [2], [3]] (форма [3, 1])

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

  • Добавление размерности не изменяет данные, но меняет форму тензора.
  • Полезно при работе с моделями, ожидающими определённое количество измерений (например, сверточные слои).

squeeze

Функция squeeze удаляет оси размерности 1 из тензора, упрощая его структуру. Часто применяется для удаления лишнего измерения после операций вроде expandDims или векторазации данных.

Синтаксис:

tf.squeeze(tensor, axis)

Параметры:

  • tensor — исходный тензор.
  • axis — необязательный параметр, массив индексов осей, которые нужно удалить. Если не указан, удаляются все оси размерности 1.

Примеры:

const x = tf.tensor([[1, 2, 3]]);
const squeezed = tf.squeeze(x);
// Результат: [1, 2, 3] (форма [3])

const x2 = tf.tensor([[[1], [2], [3]]]);
const squeezedAxis = tf.squeeze(x2, [2]);
// Результат: [[1, 2, 3]] (форма [1, 3])

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

  • Использование axis позволяет точно контролировать, какие размерности будут удалены.
  • Функция возвращает новый тензор, исходный остаётся без изменений.

Практическое применение

  1. Подготовка данных для модели:

    • Изменение формы батча: reshape([batchSize, height, width, channels]).
    • Добавление оси канала: expandDims(tensor, -1) для grayscale изображений.
  2. Преобразование выходов модели:

    • Удаление лишних осей из предсказаний: squeeze(output, [1]).
  3. Совмещение с другими операциями:

    • Использование reshape после конкатенации или транспонирования для приведения к нужной форме.
    • Добавление и удаление измерений при работе с RNN или CNN.

Важные моменты

  • Любая операция изменения формы создаёт новый тензор, что важно для управления памятью.
  • Ошибки при несоответствии количества элементов возникают часто при использовании reshape и требуют внимательного подсчёта элементов.
  • Последовательное использование expandDims и squeeze позволяет гибко управлять размерностью, облегчая интеграцию с моделями разной архитектуры.