В TensorFlow.js обработка и подготовка данных для обучения моделей
осуществляется через объект tf.data.Dataset. Этот объект
позволяет создавать конвейеры данных, обеспечивающие эффективную
загрузку, трансформацию и нормализацию данных. Датасеты могут быть
построены из массивов, файлов или потоков данных, а также
комбинироваться и преобразовываться с использованием встроенных
методов.
const xs = tf.tensor2d([[1], [2], [3], [4]]);
const ys = tf.tensor2d([[1], [3], [5], [7]]);
const dataset = tf.data.array([{x: xs, y: ys}]);
Метод tf.data.array позволяет преобразовать массив
объектов JavaScript в последовательность данных, готовую для подачи в
модель. Датасеты поддерживают ленивую загрузку и трансформации, что
критически важно для работы с большими объемами данных.
Нормализация — это процесс приведения данных к
единому масштабу, что улучшает сходимость градиентного спуска и качество
обучения моделей. В TensorFlow.js данные чаще всего нормализуются к
диапазону [0, 1] или стандартизируются с нулевым средним и
единичной дисперсией.
Простейшая форма нормализации — деление всех значений на максимальное значение:
function normalize(tensor) {
const maxVal = tensor.max();
const minVal = tensor.min();
return tensor.sub(minVal).div(maxVal.sub(minVal));
}
const normalizedXs = normalize(xs);
tensor.sub(minVal) — смещает все значения так, чтобы
минимальное стало равным нулю.div(maxVal.sub(minVal)) — масштабирует значения до
диапазона [0, 1].Стандартизация перемещает данные так, чтобы их среднее было равно 0, а стандартное отклонение — 1:
function standardize(tensor) {
const mean = tensor.mean();
const std = tensor.sub(mean).square().mean().sqrt();
return tensor.sub(mean).div(std);
}
const standardizedXs = standardize(xs);
tensor.sub(mean) смещает данные относительно
среднего.div(std) масштабирует данные с учетом дисперсии,
улучшая стабильность обучения.Для работы с конвейерами данных нормализация выполняется через метод
map объекта Dataset. Это позволяет
автоматически преобразовывать каждую партию данных перед подачей в
модель:
const normalizedDataset = dataset.map(({x, y}) => {
const xNorm = normalize(x);
const yNorm = y; // целевые значения могут оставаться без изменений
return {x: xNorm, y: yNorm};
});
Метод map поддерживает ленивую трансформацию, что
позволяет эффективно обрабатывать большие массивы данных без загрузки
всего датасета в память.
Обучение модели становится более устойчивым при разбиении данных на
батчи и их перемешивании. Для этого используются методы
batch и shuffle:
const batchedDataset = normalizedDataset.shuffle(100).batch(16);
shuffle(bufferSize) случайным образом перемешивает
элементы в пределах указанного буфера.batch(batchSize) объединяет элементы в группы
указанного размера, оптимизируя работу GPU или CPU.Нормализованный и разбитый на батчи датасет подается в метод
fit модели:
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});
await model.fitDataset(batchedDataset, {
epochs: 50
});
Использование fitDataset вместо fit
позволяет работать с потоковыми датасетами, интегрируя нормализацию и
батчинг без необходимости держать весь массив в памяти.
map.
Можно одновременно применять нормализацию, аугментацию и
фильтрацию.shuffle перед
batch. Это улучшает качество обучения за счет
случайного порядка данных.min, max и mean позволяют
убедиться в корректности преобразований.Для изображений нормализация часто производится делением на 255,
переводя пиксели в диапазон [0, 1]:
const imageDataset = tf.data.array([imageTensor1, imageTensor2]);
const normalizedImages = imageDataset.map(img => img.div(255));
При этом можно комбинировать нормализацию с аугментацией:
const augmentedDataset = normalizedImages.map(img => tf.image.randomFlipLeftRight(img));
Таким образом, TensorFlow.js позволяет создавать гибкие и эффективные конвейеры данных, где нормализация интегрирована на уровне датасета, обеспечивая стабильность и высокую производительность обучения.