Владислав Калачев

Пишем простую нейронку ML на JS

65

Когда я впервые решил написать нейронную сеть на JavaScript, мне казалось, что это будет не самая очевидная задача. Обычно мы ассоциируем машинное обучение с языками вроде Python, который славится своим экосистемой и библиотеками для ML. Но как frontend-разработчику с опытом в JavaScript, мне было интересно посмотреть, насколько этот язык справляется с задачами машинного обучения. Вот мой путь, опыт, и мысли о том, кому стоит попробовать повторить этот эксперимент.

Почему я решил использовать JavaScript?

Для меня всё началось с чистого любопытства. Я хотел изучить основы машинного обучения (ML) и понять, как работает нейросеть на практике. Python был бы очевидным выбором благодаря библиотекам вроде TensorFlow и PyTorch, но я решил пойти другим путём. Почему? Во-первых, я знал JavaScript гораздо лучше, и мне было проще начать именно с него. Во-вторых, мне хотелось проверить, насколько этот язык может справиться с реальными задачами ML, и что предлагают такие инструменты, как TensorFlow.js.

Начало: TensorFlow.js и моя первая нейронка

Для первого шага я выбрал TensorFlow.js — библиотеку, которая позволяет запускать модели машинного обучения прямо в браузере. Она хорошо интегрируется с JavaScript и предоставляет те же возможности, что и её более известный «старший брат» на Python. Моя цель была проста: создать простую нейронную сеть для классификации данных.

Задача: Предсказание класса по простым числовым данным

Предположим, у нас есть набор данных, где каждое наблюдение — это массив чисел, и мы хотим, чтобы нейросеть классифицировала их на несколько классов. Мы создадим простую нейронную сеть, которая будет состоять из нескольких полносвязных слоев, и обучим её на таких данных.

Шаг 1: Установка TensorFlow.js

Для начала нужно установить библиотеку TensorFlow.js. Если ты используешь Node.js:

npm install @tensorflow/tfjs

Если ты работаешь прямо в браузере, просто подключи скрипт:

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>

Шаг 2: Подготовка данных

Предположим, у нас есть данные для классификации с двумя признаками (фичами). Например, каждый объект описан двумя числами, и мы хотим классифицировать их в три разных класса.

const trainingData = {
  inputs: [
    [0.1, 0.2],  // class 0
    [0.2, 0.3],  // class 0
    [0.4, 0.6],  // class 1
    [0.6, 0.5],  // class 1
    [0.9, 0.7],  // class 2
    [0.8, 0.9]   // class 2
  ],
  labels: [
    [1, 0, 0],  // class 0 (one-hot encoding)
    [1, 0, 0],  // class 0
    [0, 1, 0],  // class 1
    [0, 1, 0],  // class 1
    [0, 0, 1],  // class 2
    [0, 0, 1]   // class 2
  ]
};

Что здесь происходит:

— Мы создаем inputs — это наши обучающие данные, где каждый элемент массива представляет два признака (например, рост и вес).

labels — это классы, к которым относится каждый набор признаков. Используем one-hot encoding, где каждый класс представлен как массив с одним «1» и двумя «0». Например, [1, 0, 0] для класса 0, [0, 1, 0] для класса 1 и так далее.

Шаг 3: Создание модели нейронной сети

Теперь создадим простую нейронную сеть с использованием TensorFlow.js.

const model = tf.sequential();  // Создаем последовательную модель

// Добавляем первый полносвязный слой с 16 нейронами, функцией активации ReLU и входной формой [2] (два признака).
model.add(tf.layers.dense({ units: 16, activation: 'relu', inputShape: [2] }));

// Добавляем еще один скрытый слой с 8 нейронами и ReLU.
model.add(tf.layers.dense({ units: 8, activation: 'relu' }));

// Выходной слой с тремя нейронами (по одному на каждый класс) и softmax для классификации.
model.add(tf.layers.dense({ units: 3, activation: 'softmax' }));

// Компилируем модель: используем оптимизатор Adam и функцию потерь categoricalCrossentropy.
model.compile({
  optimizer: 'adam',
  loss: 'categoricalCrossentropy',
  metrics: ['accuracy']
});

Что здесь происходит:

Создание модели: Мы создаем модель с помощью tf.sequential(). Это означает, что наша модель будет состоять из слоев, расположенных один за другим.

Первый слой: tf.layers.dense — это полносвязный (dense) слой. Мы задаем 16 нейронов в этом слое и используем функцию активации ReLU (relu). Форма входных данных — [2], так как у нас два признака.

Второй слой: Этот слой также полносвязный, но с 8 нейронами.

Выходной слой: В этом слое у нас три нейрона (так как три класса). Функция активации softmax используется для того, чтобы результат был вероятностями принадлежности к каждому из классов.

Компиляция модели: Мы выбираем оптимизатор Adam и функцию потерь categoricalCrossentropy для многоклассовой классификации. В метриках указываем accuracy (точность), чтобы отслеживать, как хорошо модель обучается.

Шаг 4: Подготовка данных к обучению

TensorFlow.js работает с объектами tf.tensor, так что нужно преобразовать наши данные в тензоры:


const xs = tf.tensor2d(trainingData.inputs);  // Преобразуем входные данные в тензор
const ys = tf.tensor2d(trainingData.labels);  // Преобразуем метки в тензор

Шаг 5: Обучение модели

Теперь мы можем обучить нашу нейронную сеть. Поскольку данных немного, мы установим количество эпох небольшим — например, 100.


model.fit(xs, ys, {
  epochs: 100,   // Количество эпох (итераций обучения)
  shuffle: true  // Перемешиваем данные для лучшего обучения
}).then((history) => {
  console.log('Model trained!');
});

Что здесь происходит:

model.fit() — это функция, которая обучает модель. Мы передаем ей входные и выходные данные (тензоры xs и ys), а также указываем количество эпох и параметры обучения.

epochs: 100 означает, что сеть пройдет через данные 100 раз.

shuffle: true помогает модели лучше обучаться, так как данные будут перемешиваться перед каждой эпохой.

Шаг 6: Использование модели для предсказаний

После того как модель обучена, мы можем использовать её для предсказания классов для новых данных:


const testInput = tf.tensor2d([[0.3, 0.4]]);  // Новый набор данных для предсказания
model.predict(testInput).print();  // Выводим результат предсказания

Что здесь происходит:

— Мы создаем новый тензор testInput, содержащий данные для предсказания (например, [0.3, 0.4]).

model.predict() возвращает тензор с вероятностями принадлежности к каждому классу. Например, [0.8, 0.1, 0.1] означает, что сеть предсказывает с вероятностью 80%, что это класс 0.

Шаг 7: Сохранение модели

Если тебе нужно сохранить модель, чтобы потом её использовать, можно сделать так:


model.save('localstorage://my-model');  // Сохраняем модель в локальное хранилище браузера

Что здесь происходит:
— Модель можно сохранить в локальном хранилище браузера, чтобы использовать её позже без повторного обучения.

Кому это может быть полезно?

На основании своего опыта могу сказать, что написание нейронных сетей на JavaScript имеет свои плюсы и минусы. Вот кому и в каких случаях стоит попробовать ML на JS:

Frontend-разработчикам. Если вы уже занимаетесь frontend-разработкой и хотите расширить свои знания в сторону машинного обучения, TensorFlow.js — это отличная возможность. Вы можете разрабатывать и тестировать модели прямо в браузере, без необходимости осваивать новый язык программирования.

Тем, кто хочет встроить ML в веб-приложения. TensorFlow.js хорош для интеграции нейросетей в браузерные приложения. Если у вас есть задача, которая требует предсказания на клиентской стороне — например, обработка изображений или текстов — JavaScript станет хорошим выбором.

Тем, кто только начинает с машинным обучением. Использование знакомого языка может сделать обучение ML менее пугающим. Вы сможете сконцентрироваться на теоретических аспектах нейросетей, не тратя время на изучение синтаксиса нового языка.

Реалтайм-приложениям. Если вы хотите использовать машинное обучение для задач, которые требуют мгновенной обработки данных на клиенте — например, игры, интерактивные инструменты, — JavaScript с TensorFlow.js идеально подойдут.

Кому это может не подойти?

Однако, стоит понимать, что нейронные сети на JavaScript не всегда являются лучшим решением. Если ваша задача требует серьезных вычислительных мощностей и огромных объемов данных, JavaScript вряд ли справится с такой нагрузкой так же эффективно, как Python с его богатыми возможностями оптимизации и мощными библиотеками. В таких случаях лучше использовать традиционные инструменты для ML.

Заключение

Мы рассмотрели, как с помощью JavaScript и TensorFlow.js можно создать простую нейронную сеть для задачи классификации. На практике, использовать JavaScript для таких задач удобно, если вы хотите интегрировать ML непосредственно в веб-приложения. Этот подход может быть полезен фронтенд-разработчикам и тем, кто хочет внедрять машинное обучение в браузер.

Хотя JavaScript вряд ли заменит Python для более сложных и ресурсоёмких задач в ML, для небольших и средних проектов это отличный способ учиться и создавать полезные модели прямо в браузере.

Комментарии:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *