Развертывание MobileNet с использованием TensorFlow.js и Flask

JavaScriptJavaScriptBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом проекте вы познакомитесь с процессом развертывания предварительно обученной модели MobileNetV2 с использованием TensorFlow.js в веб-приложении на Flask. MobileNetV2 - это легкая глубокая нейронная сеть, используемая в основном для классификации изображений. TensorFlow.js позволяет запускать модели машинного обучения непосредственно в браузере, что позволяет создавать интерактивные веб-приложения. Flask, веб-фреймворк на Python, будет用作后端 для размещения нашего приложения. В конце этого проекта у вас будет работающее веб-приложение, которое классифицирует изображения в режиме реального времени с использованием модели MobileNetV2.

👀 Предпросмотр

🎯 Задачи

В этом проекте вы научитесь:

  • Экспортировать предварительно обученную модель MobileNetV2 из Keras в формат, совместимый с TensorFlow.js.
  • Создавать простое веб-приложение на Flask для обслуживания веб-контента и модели.
  • Разрабатывать HTML-страницу для загрузки и отображения изображений для классификации.
  • Использовать TensorFlow.js для загрузки экспортированной модели в браузере.
  • Предварительно обрабатывать изображения в браузере, чтобы соответствовать требованиям ввода MobileNetV2.
  • Запускать модель в браузере для классификации изображений и отображения результатов.

🏆 Достижения

После завершения этого проекта вы сможете:

  • Преобразовать предварительно обученную модель Keras в формат, который можно использовать с TensorFlow.js, что позволяет запускать модели машинного обучения в браузере.
  • Установить веб-приложение Flask и обслуживать HTML-контент и статические файлы.
  • Интегрировать TensorFlow.js в веб-приложение для выполнения задач машинного обучения на стороне клиента.
  • Предварительно обрабатывать изображения на JavaScript, чтобы они соответствовали требованиям ввода глубоких нейронных моделей.
  • Получать предсказания с использованием глубокой нейронной модели в браузере и динамически отображать результаты на веб-странице.

Подготовка проекта и файлов

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

Во - первых, ознакомьтесь с исходной структурой проекта. В вашей рабочей директории уже есть следующие файлы и папки:

tree

Результат:

.
├── app.py
├── model_convert.py
├── static
│ ├── imagenet_classes.js
│ ├── tfjs.css
│ └── tfjs.js
└── templates
└── tfjs.html

2 directories, 6 files

Структура вашего проекта состоит из нескольких важных компонентов, каждый из которых играет важную роль при развертывании веб - приложения для классификации изображений с использованием модели MobileNetV2 с TensorFlow.js и Flask. Ниже представлен обзор каждой директории и файла в вашем проекте:

  • app.py: Это главный Python - файл для вашего веб - приложения на Flask. Он инициализирует приложение Flask, настраивает маршрутизацию для вашей веб - страницы и включает любую необходимую бэкенд - логику для обслуживания модели TensorFlow.js и веб - контента.
  • model_convert.py: Этот Python - скрипт отвечает за загрузку предварительно обученной модели MobileNetV2 и ее преобразование в формат, совместимый с TensorFlow.js. Эта конвертация является важной для того, чтобы модель могла работать в веб - браузере.
  • static/: Эта директория хранит статические файлы, которые требуются вашим веб - приложением. Они включают в себя:
    • imagenet_classes.js: JavaScript - файл, содержащий классы ImageNet. Этот файл используется для сопоставления числовых предсказаний модели с именами классов, понятными человеку.
    • tfjs.css: Новый файл, этот файл Cascading Style Sheets (CSS) используется для стилизации пользовательского интерфейса веб - приложения. Он определяет визуальные аспекты вашего приложения, такие как макеты, цвета и шрифты, обеспечивая более привлекательный и удобный для пользователя интерфейс.
    • tfjs.js: Еще один новый файл, этот JavaScript - файл, вероятно, содержит логику для загрузки модели TensorFlow.js, обработки изображений и выполнения предсказаний в браузере. Этот скрипт является центральным для интерактивности вашего приложения, обрабатывая операции на стороне клиента, связанные с моделью TensorFlow.js.
  • templates/: Эта директория содержит HTML - файлы, которые определяют структуру и макет вашего веб - приложения. В данном случае это включает:
    • tfjs.html: Основной HTML - шаблон для вашего приложения, tfjs.html содержит необходимые разметки для отображения изображений, результатов предсказаний и, возможно, элементов взаимодействия с пользователем, таких как кнопки для загрузки файлов. Он интегрирует модель TensorFlow.js, используя скрипт tfjs.js для функциональностей, связанных с моделью, и tfjs.css для стилизации.

Такая структура создана для разделения задач, делая ваш проект модульным и легким в управлении. Директории static и templates стандартны для веб - приложений на Flask, помогающие организовать статические ресурсы и HTML - шаблоны соответственно. Разделение скрипта конвертации модели (model_convert.py) от основной бизнес - логики приложения (app.py) повышает модульность и поддерживаемость вашего кода.

Далее, установите необходимые пакеты:

## Install the required Python packages
pip install tensorflow==2.14.0 tensorflowjs==4.17.0 flask==3.0.2 flask - cors==4.0.0

Пакеты включают в себя TensorFlow для машинного обучения, TensorFlow.js для конвертации модели для использования в веб - окружении, Flask для создания веб - сервера и Flask - CORS для обработки кросс - origine запросов, которые часто встречаются в веб - приложениях.

Экспорт предварительно обученной модели MobileNetV2 в формат TensorFlow.js

Для использования модели MobileNetV2 в браузере, сначала необходимо экспортировать ее из Keras в формат, который может понять TensorFlow.js.

## Complete the model_convert.py

## Экспорт модели MobileNetV2
import tensorflowjs as tfjs
from tensorflow.keras.applications.mobilenet_v2 import MobileNetV2

## Загрузка предварительно обученной модели MobileNetV2
model = MobileNetV2(weights='imagenet')

## Конвертация и сохранение модели в формате TensorFlow.js
tfjs.converters.save_keras_model(model,'static/model/')

В этом шаге вы используете библиотеки TensorFlow и TensorFlow.js для загрузки предварительно обученной модели MobileNetV2 и ее преобразования в формат, совместимый с TensorFlow.js.

В качестве модели выбирается MobileNetV2 за ее эффективность и относительно небольшой размер, что делает ее подходящей для веб - развертывания. Эта конвертация обязательна, так как исходный формат модели, используемый в Python - версии TensorFlow, не может быть непосредственно использован в веб - окружении. Функция tfjs.converters.save_keras_model берет модель Keras и сохраняет ее в директории, структурированной таким образом, чтобы TensorFlow.js могла легко загрузить ее позже в веб - приложении.

Затем вы можете запустить:

python model_convert.py

Конвертированная модель будет сохранена в папку static/model/:

ls static/model

## group1-shard1of4.bin  group1-shard2of4.bin  group1-shard3of4.bin  group1-shard4of4.bin  model.json

Этот процесс включает сохранение весов модели и архитектуры в серии файлов - чанков и файл model.json соответственно.

✨ Проверить решение и практиковаться

Создание веб - приложения на Flask

Теперь мы настроим простое веб - приложение на Flask для обслуживания нашей веб - страницы и модели TensorFlow.js.

## Complete the app.py

## Настройка веб - приложения на Flask
from flask import Flask, render_template
from flask_cors import CORS

app = Flask(__name__)
cors = CORS(app)  ## Включение Cross - Origin Resource Sharing

@app.route("/")
def hello():
    ## Отдача HTML - страницы
    return render_template('tfjs.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port='8080', debug=True)

В этом шаге мы настраиваем базовый веб - сервер Flask. Flask - это микрофреймворк для веб - приложений, написанный на Python, который известен своей простотой и удобством использования.

Вы начинаете с импорта Flask и CORS (Cross - Origin Resource Sharing) из соответствующих библиотек. CORS необходим для веб - приложений, которые запрашивают ресурсы из разных доменов, обеспечивая безопасность запросов веб - приложения к серверу Flask.

Вы определяете простой маршрут ("/"), который отдает HTML - страницу (tfjs.html), которая будет содержать код TensorFlow.js на стороне клиента. Веб - приложение Flask настроено на запуск на локальном компьютере (host='0.0.0.0') и прослушивание порта 8080. Настройка debug=True полезна при разработке, так как она предоставляет детальные сообщения об ошибках и автоматически перезагружает сервер при обнаружении изменений в коде.

Теперь вы можете запустить веб - приложение Flask:

python app.py
## * Serving Flask app 'app'
## * Debug mode: on
## WARNING: This is a development server. Do not use it in a production ## deployment. Use a production WSGI server instead.
## * Running on all addresses (0.0.0.0)
## * Running on http://127.0.0.1:8080
## * Running on http://172.18.0.7:8080
## Press CTRL+C to quit
✨ Проверить решение и практиковаться

Подготовка HTML - структуры

Теперь нам нужно создать HTML - структуру нашего приложения в templates/tfjs.html. Это включает в себя макет для загрузки изображений, предпросмотра и отображения результатов предсказания.

<!-- HTML - структура для приложения Image Prediction -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Image Prediction</title>
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css"
      rel="stylesheet"
    />
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
    <link rel="stylesheet" href="static/tfjs.css" />
  </head>
  <body class="flex flex-col items-center justify-center min-h-screen">
    <div class="card bg-white p-6 rounded-lg max-w-sm">
      <h1 class="text-xl font-semibold mb-4 text-center">Image Prediction</h1>
      <div class="flex flex-col items-center">
        <label
          for="imageUpload"
          class="button-custom cursor-pointer mb-4 flex items-center justify-center"
        >
          <span>Upload Image</span>
          <input
            type="file"
            id="imageUpload"
            class="file-input"
            accept="image/*"
          />
        </label>
        <div
          id="imagePreviewContainer"
          class="mb-4 w-56 h-56 border border-dashed border-gray-300 flex items-center justify-center"
        >
          <img
            id="imagePreview"
            class="max-w-full max-h-full"
            style="display: none"
          />
        </div>
        <h5 id="output" class="text-md text-gray-700">
          Upload an image to start prediction
        </h5>
        <script type="module" src="static/tfjs.js"></script>
      </div>
    </div>
  </body>
</html>

В этом шаге мы создаем базовую структуру нашего веб - приложения с использованием HTML. Мы определяем тип документа как HTML и задаем атрибут языка на английский.

В разделе head мы включаем метаданные, такие как кодировка символов и настройки viewport для адаптивного дизайна. Мы также подключаемся к библиотеке Tailwind CSS, чтобы использовать ее утилитарные классы для стилизации нашего приложения. В разделе body содержится элемент div с классом card, который служит контейнером для содержимого нашего приложения.

Внутри этого контейнера у нас есть тег h1 для названия приложения, элемент label для кнопки загрузки изображения (который стилизуется, чтобы выглядеть как кнопка с использованием Tailwind CSS и пользовательских классов), и элемент div, который служит контейнером для предпросмотра изображения. Элемент input типа file скрыт и активируется при нажатии на метку, позволяя пользователю загрузить изображение. Элемент div с id imagePreviewContainer будет отображать загруженное изображение, а тег h5 будет использоваться для отображения сообщений пользователю.

✨ Проверить решение и практиковаться

Добавление стилизации

В этом шаге мы добавим базовую стилизацию с использованием Tailwind CSS для макета и эстетики в static/tfjs.css, а также некоторые настраиваемые стили для нашего приложения.

body {
  background-color: #f0f2f5;
}
.card {
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.button-custom {
  background-color: #4f46e5; /* Indigo 600 */
  color: white;
  padding: 0.5rem 1.5rem;
  border-radius: 0.375rem; /* rounded-md */
  transition: background-color 0.2s;
}
.button-custom:hover {
  background-color: #4338ca; /* Indigo 700 */
}
.file-input {
  opacity: 0;
  position: absolute;
  z-index: -1;
}

В этом шаге мы добавляем настраиваемые CSS - стили, чтобы улучшить внешний вид нашего веб - приложения.

Мы задаем цвет фона тела на светый серый для нейтрального фона. Класс card добавляет тень для создания эффекта похожего на карточку для контейнера. Класс button - custom стилизует кнопку загрузки с фоном индиго, белым текстом, отступами и закругленными углами.

Мы также включаем эффект наведения, чтобы немного изменить цвет фона кнопки при наведении на нее, обеспечивая визуальную обратную связь для пользователя. Класс file - input используется для скрытия фактического элемента ввода файла, сделав настраиваемую метку главным интерактивным элементом для загрузки файлов.

✨ Проверить решение и практиковаться

Загрузка модели TensorFlow

В оставшихся шагах мы завершим файл templates/tfjs.js.

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

import { IMAGENET_CLASSES } from "./imagenet_classes.js";

const outputDiv = document.getElementById("output");
let model;

async function loadModel() {
  try {
    outputDiv.textContent = "Loading TF Model...";
    model = await tf.loadLayersModel(
      "https://****.labex.io/static/model/model.json"
    ); // Update URL
    outputDiv.textContent = "TF Model Loaded.";
  } catch (error) {
    outputDiv.textContent = `Error loading model: ${error}`;
  }
}

loadModel();

Примечание: Вы должны заменить URL в tf.loadLayersModel на URL текущей среды. Вы можете найти его, перейдя в вкладку Web 8080.

Диаграмма загрузки модели TensorFlow

В этом шаге мы добавляем TensorFlow.js в наш проект, включив его тег - скрипт в наш HTML - документ.

Затем мы пишем JavaScript - код для асинхронной загрузки предварительно обученной модели TensorFlow. Мы используем функцию tf.loadLayersModel, передавая ей URL нашего JSON - файла модели. Эта функция возвращает промис, который разрешается с загруженной моделью. Мы обновляем текстовое содержимое outputDiv, чтобы информировать пользователя о статусе загрузки модели. Если модель загружается успешно, мы отображаем "TF Model Loaded."

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

✨ Проверить решение и практиковаться

Обработка загрузки и предпросмотра изображений

В этом шаге мы создаем функциональность для пользователей, чтобы они могли загружать изображения и видеть предпросмотр перед проведением предсказания. Мы будем использовать FileReader для чтения загруженного файла и его отображения.

// Продолжайте в static/tfjs.js
const imageUpload = document.getElementById("imageUpload");
const imagePreview = document.getElementById("imagePreview");

imageUpload.addEventListener("change", async (e) => {
  const file = e.target.files[0];
  if (file) {
    const reader = new FileReader();
    reader.onload = (e) => {
      const img = new Image();
      img.src = e.target.result;
      img.onload = async () => {
        imagePreview.src = img.src;
        imagePreview.style.display = "block";
        const processedImage = await preprocessImage(img);
        makePrediction(processedImage);
      };
    };
    reader.readAsDataURL(file);
  }
});

В этом шаге мы настраиваем слушатель событий для элемента ввода загрузки изображения.

Когда пользователь выбирает файл, мы используем FileReader для чтения файла в виде Data URL. Затем мы создаем объект Image и задаем его атрибут src результатом из FileReader, тем самым фактически загружая изображение в браузер. Как только изображение загружено, мы отображаем его внутри контейнера imagePreview, установив атрибут src imagePreview равным src изображения и делая элемент imagePreview видимым.

Затем изображение предварительно обрабатывается и предсказывается нашей моделью, мы завершим эти функции в последующих шагах.

✨ Проверить решение и практиковаться

Предварительная обработка изображения для предсказания

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

// Продолжайте в static/tfjs.js
async function preprocessImage(imageElement) {
  try {
    let img = tf.browser.fromPixels(imageElement).toFloat();
    img = tf.image.resizeBilinear(img, [224, 224]);
    const offset = tf.scalar(127.5);
    const normalized = img.sub(offset).div(offset);
    const batched = normalized.reshape([1, 224, 224, 3]);
    return batched;
  } catch (error) {
    outputDiv.textContent = `Error in model prediction: ${error}`;
  }
}

Прежде чем сделать предсказание, нам нужно предварительно обработать загруженное изображение, чтобы оно соответствовало формату ввода, ожидаемому нашей моделью TensorFlow. Эта предварительная обработка включает в себя изменение размера изображения до требуемых размеров (в данном случае 224x224 пикселей) и нормализацию значений пикселей.

Мы используем операции TensorFlow.js, такие как tf.browser.fromPixels, чтобы преобразовать изображение в тензор, tf.image.resizeBilinear для изменения размера и арифметические операции для нормализации значений пикселей. Затем предварительно обработанное изображение преобразуется в пакет размером один (чтобы соответствовать ожидаемой форме ввода модели), готовя его к предсказанию.

✨ Проверить решение и практиковаться

Сделать предсказание

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

// Продолжайте в static/tfjs.js
async function makePrediction(processedImage) {
  try {
    const prediction = model.predict(processedImage);
    const highestPredictionIndex = await tf.argMax(prediction, 1).data();
    const label = IMAGENET_CLASSES[highestPredictionIndex];
    outputDiv.textContent = `Prediction: ${label}`;
  } catch (error) {
    outputDiv.textContent = `Error making prediction: ${error}`;
  }
}

В этом шаге мы используем функцию model.predict(processedImage) для подачи предварительно обработанного изображения в модель TensorFlow. Функция tf.argMax(prediction, 1).data() используется для нахождения индекса наибольшего значения в массиве предсказаний, который соответствует наиболее вероятному классу метки для изображения. Затем эта метка отображается для пользователя.

Переключитесь на вкладку "Web 8080" и перезагрузите веб - страницу, чтобы увидеть следующие эффекты.

✨ Проверить решение и практиковаться

Резюме

В этом проекте вы узнали, как использовать предварительно обученную модель MobileNetV2 в веб - приложении на Flask с использованием TensorFlow.js. Мы начали с установки необходимых зависимостей. Затем экспортировали модель MobileNetV2 в формат, совместимый с TensorFlow.js, и настроили веб - приложение Flask для обслуживания нашей веб - страницы. Наконец, мы создали HTML - страницу, которая использует TensorFlow.js для классификации изображений в браузере с использованием нашей модели MobileNetV2. Следуя этим шагам, вы создали веб - приложение, которое использует глубокое обучение для реального времени классификации изображений.

Этот проект демонстрирует силу комбинации традиционных веб - технологий с передовыми моделями машинного обучения для создания интерактивных и интеллектуальных веб - приложений. Вы можете расширить этот проект, добавив больше функций, таких как возможность загружать разные изображения, улучшить пользовательский интерфейс или даже интегрировать более сложные модели для различных задач.