TensorFlow.js — это библиотека JavaScript для обучения и развертывания моделей машинного обучения (ML) в браузере (на стороне клиента) и в Node.js (на стороне сервера). В этой статье я хочу рассказать о своем опыте создания приложения (которое я недавно опубликовал в Google Play Store ) с этой библиотекой javascript ML.
Тем не менее, вместо того, чтобы просто перейти к тому, как я создал это приложение с помощью TensorFlow.js, я хочу сначала описать условия / потребности, которые привели к этому выбору. Я также хочу немного коснуться некоторых других подходов, которые, как я понял, могут оказаться возможными при создании приложения, использующего машинное обучение. Наконец, я хочу оставить некоторые уроки, которые я извлек из этого опыта, и мне бы очень понравились ваши мысли, если вы экспериментировали с ML в приложениях.
Почему
Когда мы думаем о машинном обучении, мы часто думаем об очень больших наборах данных, сложных алгоритмах и огромных вычислительных мощностях. Конечно, некоторые реальные случаи действительно огромны (например, примеры использования в здравоохранении и науке), но определенно неверно говорить, что если оно невелико, то это не машинное обучение. Дело в том, что возможны варианты использования с небольшими наборами данных и ограниченным числом функций, которые еще можно отнести к сценариям использования ML.
[A] В этом случае рассматриваемое приложение работает с небольшим вариантом использования, относящимся к изучению предпочтений человека на основе очень небольшого количества функций. |
Другое распространенное мнение о процессе машинного обучения заключается в том, что для разумного изучения требуются сотни и тысячи итераций, что равносильно очень длительным часам обучения . Такой длительный процесс обучения часто выполняется на больших серверах в фоновом режиме, что делает его непригодным для использования в интерактивном режиме. Хотя это в основном верно, могут быть процессы, которые могут быть короче и управляемее, не влияя на взаимодействие с пользователем (если оно правильно спроектировано).
[B] В моем случае я надеялся действительно доказать, что при оптимальных гиперпараметрах модель можно эффективно обучить с меньшим количеством итераций и можно сохранить локально на самом мобильном устройстве. |
Наконец, одна из проблем ML связана с безопасностью и конфиденциальностью данных. Если данные огромны, а для обучения модели требуются огромные вычислительные ресурсы и время, наиболее очевидным средством решения этой ситуации является перемещение данных. Это требует всевозможных технических требований, затрат и соответствия требованиям.
[C] Одной из важных задач, которые я хотел решить, было предотвращение любого перемещения данных за пределы стандартной архитектуры приложения. |
Итак, подведем итог: я хотел создать приложение, которое может эффективно работать с небольшими наборами данных [A], минимальными итерациями обучения, то есть с более коротким временем обучения [B], и где мне не нужно было перемещать данные за пределы моей стандартной архитектуры приложения только для обучение [с].
Приложение: заголовки
Заголовки — это новостное приложение, которое узнает от пользователя его симпатии и антипатии и в конечном итоге начинает выяснять, какие новостные статьи могут понравиться пользователю. В частности, приложение предоставляет заголовки новостей из нескольких источников по нескольким темам. Например, приложение предоставляет заголовки новостей от таких издателей, как CNN, TechCrunch, Bloomberg и т. Д. По таким темам, как бизнес, развлечения, наука, здравоохранение, технологии и т. Д.
Основная идея
Заголовки позволяют оценить новости, представленные в наборе данных двумя метками — «Нравится» и «Не нравится». Основываясь на рейтингах, собранных по нескольким новостным заголовкам, основная идея состоит в том, чтобы предсказать рейтинг нового заголовка и даже отсортировать заголовки новостей в порядке вероятности совпадения.
Такая рекомендация генерируется на основе изучения предпочтений новостей для каждого человека отдельно. Можно утверждать, что лучшее обучение может происходить в более широком наборе данных, состоящем из предпочтений всех пользователей. Однако, чтобы иметь возможность использовать такую модель, эта модель также должна учитывать сходства и различия в профилях пользователей. Это было отменено на потом. Надеемся, что это даст гораздо лучший набор данных и лучшие вероятностные результаты, основанные на более широком обучении.
Как
Учитывая, что теперь мы знаем наши цели (перечислены как [A], [B] и [C]) и понимаем, что ожидается от приложения Headline (предоставляя пользователю наиболее релевантные заголовки новостей), мы теперь немного погрузимся глубже в механику разработки модели ML. Здесь мы рассмотрим основные аспекты дизайна модели ML (а не самого приложения).
Dataset
Основной набор данных, относящийся к обучению этой модели, — это записи о новостях, которые ему нравятся или не нравятся. Фокусировка только на данных конкретного пользователя приводит к меньшему количеству управляемых фрагментов нормализованных данных, которые поддерживают согласованный пользовательский контекст и, следовательно, представляют собой более богатый набор данных для обучения.
Характеристики
Что касается полезных функций в наборе данных, я сосредоточился на паре атрибутов, которые обеспечивают полезный и дифференцируемый контекст для каждого заголовка новости. Источник публикации новостей (например, CNN, TechCrunch, Bloomberg и т. Д.) И категория новостей (например, «Бизнес», «Наука», «Здравоохранение», «Технологии» и т. Д.), Похоже, хорошо это отражали. В дополнение к этим категориальным функциям я также сделал выбор добавить функцию с непрерывным числовым значением. Для этого мы создаем функцию, используя оценку анализа настроений заголовка новости между -1.0 и 1.0. Вам следует взглянуть на эту страницу из ускоренного курса машинного обучения Google, где рассказывается о некоторых достоинствах функции . Чтобы не сказать больше о целевых ярлыках, они простоодно горячее закодированное значение 1,0 (представляющее «Мне нравится») и 0,0 (представляющее «Нравится»).
Нейронная сеть и обучение
Основываясь на функциях, обсужденных выше, в нашей глубокой нейронной сети, по крайней мере, мы могли бы быстро определить, что у нее будет входной слой из 3 узлов и выходной слой из 2 узлов. Проектирование остальных скрытых слоев и узлов в каждом скрытом слое — это место, где наука встречается с искусством. Здесь происходит много экспериментов. Настройка нейронной сети и запуск обучения — итеративный процесс.
Добавьте гиперпараметры, такие как скорость обучения , размер пакета, эпохи и т. Д., И различные оптимизаторы, которые оценивают потери на каждой итерации — это, по сути, ваши ручки для управления процессом обучения.
Есть много отличных статей по каждой из этих тем, поэтому я немного стесняюсь освещать их в этой статье. Тем не менее, вот глоссарий наиболее распространенных терминов, используемых в машинном обучении.
Что касается конструкции кода, TensorFlow.js использует конструкцию, подобную Keras, для построения нейронной сети. Как упоминалось в начале, код TensorFlow.js может быть записан как в клиентских файлах JavaScript, так и в модуле Node.js на стороне сервера, и конструкция кода одинакова в любом случае.
Ниже приведен отрывок из кода, использованного в приложении Headlines для построения модели …
// -- build model
let model = tf.sequential();
let optimizer = tf.train.rmsprop(0.01);// RMSProp optimizer with learning rate of 0.01
let epochs = 32;
let batchSize = 96;
// Input layer
model.add(tf.layers.dense({ units: 5, inputDim: 3, activation: 'relu' }));
// Hidden layer
model.add(tf.layers.dense({ units: 2, activation: 'relu' }));
// Output layer
model.add(tf.layers.dense({ units: 2, activation: 'softmax' }));
// Compile the model with optimizer and loss function
model.compile({ optimizer: 'sgd', loss: 'categoricalCrossentropy', metrics: ['accuracy'] });
… и тренировать модель.
// -- train
model.fit(
// X tensors
tf.cast(tf.tensor2d(data), "float32"),
// Y tensors
tf.cast(tf.oneHot(labels, 2), "float32"), {
epochs: epochs,
batchSize: batchSize,
callbacks: {
onEpochEnd: async (n, logs) => {
logs.acc = parseFloat((logs.acc * 100).toFixed(2));
logs.loss = parseFloat((logs.loss * 100).toFixed(3));
console.log({
epochs: { current: n + 1, total: epochs },
batchSize: batchSize,
loss: logs.loss,
accuracy: logs.acc });
} // onEpochEnd
} // callback
}).then((history) => {
// -- save model in localStorage
model.save('localstorage://MLModel').then(() => {})
.catch((err) => console.log(err));
});
прогнозирование
Как вы можете видеть выше, все обучение (вызываемое методом .fit () ) происходит на самом устройстве. Кроме того, после завершения обучения мы сохраняем обученную модель в localStorage, откуда она может быть загружена позже при прогнозировании.
// -- predict
return new Promise((resolve, reject) => {
// Load model from localStorage
tf.loadModel('localstorage://MLModel')
.then((savedModel) => {
let score = savedModel.predict(
tf.cast(tf.tensor2d([[cat, src, senti]]), "float32"))
['dataSync'](); // dataSync extracts values from tensor
resolve({
dislike: score[0],
like: score[1],
verdict: score[0] > score[1] ? 'dislike' : 'like' });
}).catch((err) => reject(err));
}); // Promise
Непрерывное обучение (трансферное обучение / точная настройка?)
Возвращаясь к первоначальным целям сохранения меньшего размера набора данных для каждого последующего обучения, мы можем использовать трансферное обучение, когда часть существующей модели и ее предварительно обученные веса используются для обучения нового набора данных. У Google есть отличный пример обучения передачи с использованием сверточных нейронных сетей (CNN) на изображениях. В нашем примере здесь ранее обученную модель можно использовать в качестве предварительно обученной модели для новых входных данных, сгенерированных с момента последнего обучения. Я не рассматриваю эту часть здесь только потому, что логика приложения для управления дельтой между последним обучением и новыми данными имеет отношение к основной теме этой статьи.
Вывод
Моя основная мотивация для написания этой статьи была основана на том, как я начал изучать машинное обучение. Большинство примеров, как правило, единичны, и процесс разработки моделей ML кажется сам по себе. Машинное обучение не должно быть изолированной задачей. Он может быть интегрирован в основной процесс разработки приложений.
Во-вторых, я считаю, что умение тренироваться на стороне клиента — очень полезная концепция. Однако я хотел бы предупредить, что, поскольку обучение моделей ML само по себе является ресурсоемкой задачей , необходимо убедиться, что сценарий использования оправдывает такой подход.
Гибридный вариант, при котором обучение может проводиться в облаке, в то время как модель может быть загружена с устройства облачного хранения, также является отличным подходом.
Еще один крайний подход заключается в обучении модели в облаке и использовании возможности прогнозирования в качестве конечной точки API. Это отличный подход для предоставления машинного обучения в виде черного ящика или MLaaS (машинное обучение как услуга). Google, AWS и многие другие облачные провайдеры уже предоставляют эту услугу в таких распространенных случаях, как обнаружение изображений, извлечение текста, перевод, анализ настроений и т. Д.
В целом, машинное обучение является очень широкой и глубокой областью изучения. Однако, с помощью многих современных инструментов, таких как TensorFlow.js, применение машинного обучения в повседневной жизни становится возможным. Практически, предел неба для того, что может быть задумано с ML.