TensorFlow.js предоставляет мощные средства для работы с многомерными массивами данных — тензорами. Эффективное использование индексации и срезов позволяет манипулировать данными без копирования, оптимизируя производительность и упрощая код.
Тензор — это многомерный массив с фиксированным типом данных
(float32, int32, bool). Каждый
тензор имеет:
shape) — массив, задающий
количество элементов по каждой оси, например [3, 4] для
матрицы 3×4.rank) — число осей
тензора.dtype) — определяет, какой
тип значений хранится в тензоре.Примеры создания тензоров:
const t1 = tf.tensor([1, 2, 3, 4]); // Вектор
const t2 = tf.tensor([[1, 2], [3, 4]]); // Матрица 2x2
const t3 = tf.tensor([[[1],[2]],[[3],[4]]]); // Тензор 3D
Индексация в TensorFlow.js работает схоже с JavaScript-массивами, но с некоторыми отличиями:
arraySync() или dataSync() для синхронного
получения массива или array() и data() для
асинхронного.Пример доступа к элементу:
const t = tf.tensor([[10, 20], [30, 40]]);
const arr = t.arraySync();
console.log(arr[0][1]); // 20
Непосредственная индексация через get:
console.log(t.get(1, 0)); // 30
Метод get принимает количество аргументов, равное рангу
тензора.
slice)Срезы позволяют извлекать подмассивы тензоров без явного копирования данных:
const t = tf.tensor([[1, 2, 3], [4, 5, 6]]);
const slice1 = t.slice([0, 1], [2, 2]); // начиная с [0,1], размер 2x2
slice1.print();
Примеры срезов:
// Срез по строкам
const rows = t.slice([1, 0], [1, 3]); // Вторая строка
rows.print();
// Срез по столбцам
const cols = t.slice([0, 0], [2, 2]); // Первые два столбца
cols.print();
tf.tensor1d и tf.tensor2d для индексацииДля одномерных и двумерных данных полезно применять специализированные методы:
const vec = tf.tensor1d([10, 20, 30, 40]);
const subVec = vec.slice(1, 2); // элементы с индекса 1, длина 2
subVec.print(); // [20, 30]
const mat = tf.tensor2d([[1,2,3],[4,5,6]]);
const subMat = mat.slice([0,1],[2,2]); // срез 2x2
subMat.print(); // [[2,3],[5,6]]
Для выбора элементов на основе условий используется
tf.booleanMaskAsync:
const t = tf.tensor([1, 2, 3, 4, 5]);
const mask = tf.tensor([true, false, true, false, true]);
tf.booleanMaskAsync(t, mask).then(result => result.print()); // [1,3,5]
Особенности:
gather
и gatherNDМетоды gather и gatherND позволяют
извлекать элементы по индексам:
const t = tf.tensor([[10, 20], [30, 40], [50, 60]]);
const indices = tf.tensor1d([0,2], 'int32');
const result = tf.gather(t, indices);
result.print(); // [[10,20],[50,60]]
gatherND используется для выборки элементов или
подтензоров по многомерным индексам:
const t = tf.tensor([[1,2],[3,4]]);
const indices = tf.tensor2d([[0,0],[1,1]], [2,2], 'int32');
const result = tf.gatherND(t, indices);
result.print(); // [1,4]
split и
unstackМетоды split и unstack позволяют разбивать
тензор на несколько частей:
const t = tf.tensor2d([[1,2,3],[4,5,6]]);
const [a, b] = tf.split(t, 2, 1); // разрез по оси 1 на 2 части
a.print(); // [[1,2],[4,5]]
b.print(); // [[3],[6]]
unstack превращает тензор в массив тензоров вдоль
указанной оси:
const t = tf.tensor2d([[1,2],[3,4]]);
const unstacked = tf.unstack(t, 0);
unstacked[0].print(); // [1,2]
unstacked[1].print(); // [3,4]
slice используется для извлечения подтензоров по
позициям и размерам.get позволяет получить отдельные элементы.gather обеспечивают выборку по условиям
и индексам.split и unstack удобны для разбиения
данных на части.Эффективная индексация и срезы позволяют работать с большими массивами данных, оптимизируя вычисления и сохраняя чистоту кода при построении нейронных сетей и обработке данных.