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

1. Обзор

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

Чему вы научитесь

Вы научитесь:

  • Импортируйте модель TensorFlow в реестр моделей Vertex AI.
  • Получайте онлайн-прогнозы
  • Обновите функцию обслуживания TensorFlow.

Общая стоимость запуска этой лабораторной работы в Google Cloud составляет около 1 доллара .

2. Введение в Vertex AI

В этой лабораторной работе используется новейший продукт для искусственного интеллекта, доступный в Google Cloud. Vertex AI интегрирует предложения машинного обучения в Google Cloud в единый процесс разработки. Ранее модели, обученные с помощью AutoML, и пользовательские модели были доступны через отдельные сервисы. Новое предложение объединяет оба варианта в единый API, а также включает другие новые продукты. Вы также можете перенести существующие проекты в Vertex AI.

Vertex AI предлагает множество различных продуктов для поддержки комплексных рабочих процессов машинного обучения. В этой лабораторной работе мы сосредоточимся на продуктах, перечисленных ниже: Predictions и Workbench.

Обзор продукции Vertex

3. Обзор вариантов использования

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

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

4. Настройте свою среду.

Для выполнения этого практического задания вам потребуется проект Google Cloud Platform с включенной оплатой. Чтобы создать проект, следуйте инструкциям здесь .

Шаг 1: Включите API Compute Engine.

Перейдите в раздел Compute Engine и выберите «Включить», если эта функция еще не включена.

Шаг 2: Включите API Vertex AI

Перейдите в раздел Vertex AI в вашей облачной консоли и нажмите «Включить API Vertex AI» .

Панель мониторинга Vertex AI

Шаг 3: Создайте экземпляр Vertex AI Workbench.

В разделе Vertex AI вашей облачной консоли нажмите на Workbench:

Меню Vertex AI

Включите API для блокнотов, если он еще не включен.

Notebook_api

После включения нажмите «УПРАВЛЯЕМЫЕ ЗАПИСНЫЕ КНИЖКИ» :

Notebooks_UI

Затем выберите «Создать новый блокнот» .

новый_ноутбук

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

создать_блокнот

Выберите «Расширенные настройки» .

В разделе «Безопасность» выберите «Включить терминал», если он еще не включен.

enable_terminal

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

Далее нажмите «Создать» . Создание экземпляра займет несколько минут.

После создания экземпляра выберите «ОТКРЫТЬ JUPYTERLAB» .

open_jupyterlab

5. Регистровая модель

Шаг 1: Загрузите модель в облачное хранилище.

Перейдите по этой ссылке на страницу TensorFlow Hub, посвященную модели MobileNet V1, обученной на наборе данных ImagNet.

Выберите «Загрузить» , чтобы скачать сохраненные артефакты модели.

download_model

В разделе «Облачное хранилище» консоли Google Cloud выберите «СОЗДАТЬ».

создать_бакет

Присвойте своему хранилищу имя и выберите регион us-central1. Затем нажмите «СОЗДАТЬ».

указать_корзину

Загрузите скачанную вами модель TensorFlow Hub в хранилище. Перед этим обязательно распакуйте архив.

gcs_model

Ваше ведро должно выглядеть примерно так:

imagenet_mobilenet_v1_050_128_classification_5/
  saved_model.pb
  variables/
    variables.data-00000-of-00001
    variables.index

Шаг 2: Импортируйте модель в реестр

Перейдите в раздел реестра моделей Vertex AI в консоли Cloud.

модель_регистрация

Выберите ИМПОРТ

Выберите «Импортировать как новую модель» , а затем укажите имя для вашей модели.

имя_и_регион

В разделе «Настройки модели» укажите самый последний предварительно собранный контейнер TensorFlow. Затем выберите путь в Cloud Storage, где вы сохранили артефакты модели.

select_container

Раздел «Объясняемость» можно пропустить.

Затем выберите ИМПОРТ

После импорта вы увидите свою модель в реестре моделей.

импортированная_модель

6. Модель развертывания

В реестре моделей выберите три точки справа от модели и нажмите «Развернуть на конечную точку» .

deploy_model

В разделе «Определение конечной точки» выберите «Создать новую конечную точку» , а затем дайте ей имя.

В разделе «Настройки модели» установите максимальное количество вычислительных узлов равным 1, тип машины — n1-standard-2 , а все остальные настройки оставьте без изменений. Затем нажмите «РАЗВЕРНУТЬ» .

endpoint_settings

После развертывания статус изменится на «Развернуто на Vertex AI» .

deploy_status

7. Получите прогнозы

Откройте блокнот Workbench, созданный вами на этапах настройки. В панели запуска создайте новый блокнот TensorFlow 2.

tf_nb

Выполните следующую ячейку для импорта необходимых библиотек.

from google.cloud import aiplatform

import tensorflow as tf
import numpy as np
from PIL import Image

Модель MobileNet, которую вы скачали из TensorFlow Hub, была обучена на наборе данных ImageNet. Выходные данные модели MobileNet представляют собой число, соответствующее метке класса в наборе данных ImageNet. Чтобы преобразовать это число в строковую метку, вам потребуется загрузить метки изображений.

# Download image labels

labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())

Для обращения к конечной точке необходимо определить ресурс конечной точки. Обязательно замените {PROJECT_NUMBER} и {ENDPOINT_ID} .

PROJECT_NUMBER = "{PROJECT_NUMBER}"
ENDPOINT_ID = "{ENDPOINT_ID}"

endpoint = aiplatform.Endpoint(
    endpoint_name=f"projects/{PROJECT_NUMBER}/locations/us-central1/endpoints/{ENDPOINT_ID}")

Номер вашего проекта можно найти на главной странице консоли.

номер_проекта

А также идентификатор конечной точки в разделе «Конечные точки » Vertex AI.

endpoint_id

Далее вы проверите свою конечную точку.

Сначала загрузите следующее изображение и загрузите его в свой экземпляр.

тестовое изображение

Откройте изображение с помощью PIL. Затем измените его размер и масштаб в 255 раз. Обратите внимание, что ожидаемый моделью размер изображения можно найти на странице модели в TensorFlow Hub.

IMAGE_PATH = "test-image.jpg"
IMAGE_SIZE = (128, 128)

im = Image.open(IMAGE_PATH)
im = im.resize(IMAGE_SIZE
im = np.array(im)/255.0

Далее преобразуйте данные NumPy в список, чтобы их можно было отправить в теле HTTP-запроса.

x_test = im.astype(np.float32).tolist()

Наконец, выполните запрос на прогнозирование к конечной точке, а затем найдите соответствующую строковую метку.

# make prediction request
result = endpoint.predict(instances=[x_test]).predictions

# post process result
predicted_class = tf.math.argmax(result[0], axis=-1)
string_label = imagenet_labels[predicted_class]

print(f"label ID: {predicted_class}")
print(f"string label: {string_label}")

8. [Необязательно] Используйте TF Serving для оптимизации прогнозов.

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

Шаг 1: Изменить функцию подачи.

Откройте новый блокнот TensorFlow и импортируйте необходимые библиотеки.

from google.cloud import aiplatform

import tensorflow as tf

Вместо загрузки сохраненных артефактов модели, на этот раз вы загрузите модель в TensorFlow, используя hub.KerasLayer , который оборачивает TensorFlow SavedModel в качестве слоя Keras. Для создания модели вы можете использовать API Keras Sequential с загруженной моделью TF Hub в качестве слоя и указать форму входных данных для модели.

tfhub_model = tf.keras.Sequential(
    [hub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v1_050_128/classification/5")]
)
tfhub_model.build([None, 128, 128, 3])

Укажите URI для созданного вами ранее хранилища.

BUCKET_URI = "gs://{YOUR_BUCKET}"
MODEL_DIR = BUCKET_URI + "/bytes_model"

Когда вы отправляете запрос на онлайн-сервер прогнозирования, запрос принимается HTTP-сервером. HTTP-сервер извлекает запрос прогнозирования из тела HTTP-запроса. Извлеченный запрос прогнозирования перенаправляется в функцию обслуживания. Для предварительно созданных контейнеров прогнозирования Vertex AI содержимое запроса передается в функцию обслуживания в виде tf.string .

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

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

Для решения этой проблемы необходимо определить функцию обслуживания ( serving_fn ) и прикрепить её к модели в качестве этапа предварительной обработки. Добавьте декоратор @tf.function , чтобы функция обслуживания была интегрирована в базовую модель (вместо того, чтобы обрабатываться на ЦП).

CONCRETE_INPUT = "numpy_inputs"


def _preprocess(bytes_input):
    decoded = tf.io.decode_jpeg(bytes_input, channels=3)
    decoded = tf.image.convert_image_dtype(decoded, tf.float32)
    resized = tf.image.resize(decoded, size=(128, 128))
    return resized


@tf.function(input_signature=[tf.TensorSpec([None], tf.string)])
def preprocess_fn(bytes_inputs):
    decoded_images = tf.map_fn(
        _preprocess, bytes_inputs, dtype=tf.float32, back_prop=False
    )
    return {
        CONCRETE_INPUT: decoded_images
    }  # User needs to make sure the key matches model's input


@tf.function(input_signature=[tf.TensorSpec([None], tf.string)])
def serving_fn(bytes_inputs):
    images = preprocess_fn(bytes_inputs)
    prob = m_call(**images)
    return prob


m_call = tf.function(tfhub_model.call).get_concrete_function(
    [tf.TensorSpec(shape=[None, 128, 128, 3], dtype=tf.float32, name=CONCRETE_INPUT)]
)

tf.saved_model.save(tfhub_model, MODEL_DIR, signatures={"serving_default": serving_fn})

При отправке данных для прогнозирования в виде HTTP-запроса, данные изображения кодируются в формате base64, но модель TensorFlow принимает на вход данные в формате numpy. Ваша функция обработки данных выполнит преобразование из base64 в массив numpy.

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

loaded = tf.saved_model.load(MODEL_DIR)

serving_input = list(
    loaded.signatures["serving_default"].structured_input_signature[1].keys()
)[0]
print("Serving function input name:", serving_input)

Шаг 2: Импорт в реестр и развертывание.

В предыдущих разделах вы узнали, как импортировать модель в реестр моделей Vertex AI через пользовательский интерфейс. В этом разделе вы увидите альтернативный способ с использованием SDK. Обратите внимание, что при желании вы можете использовать и пользовательский интерфейс.

model = aiplatform.Model.upload(
    display_name="optimized-model",
    artifact_uri=MODEL_DIR,
    serving_container_image_uri="us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest",
)

print(model)

Также вы можете развернуть модель, используя SDK, а не пользовательский интерфейс.

endpoint = model.deploy(
     deployed_model_display_name='my-bytes-endpoint',
     traffic_split={"0": 100},
     machine_type="n1-standard-4",
     accelerator_count=0,
     min_replica_count=1,
     max_replica_count=1,
   )

Шаг 3: Тестирование модели

Теперь вы можете протестировать конечную точку. Поскольку мы изменили функцию обслуживания, на этот раз вы можете отправлять изображение напрямую (в кодировке base64) в запросе, вместо предварительной загрузки изображения в NumPy. Это также позволит вам отправлять изображения большего размера, не превышая лимит размера, установленный Vertex AI Predictions.

Загрузите подписи к изображениям еще раз.

import numpy as np
labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())

Закодируйте изображение в формате Base64.

import base64

with open("test-image.jpg", "rb") as f:
    data = f.read()
b64str = base64.b64encode(data).decode("utf-8")

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

instances = [{serving_input: {"b64": b64str}}]

# Make request
result = endpoint.predict(instances=instances).predictions

# Convert image class to string label
predicted_class = tf.math.argmax(result[0], axis=-1)
string_label = imagenet_labels[predicted_class]

print(f"label ID: {predicted_class}")
print(f"string label: {string_label}")

🎉 Поздравляем! 🎉

Вы научились использовать Vertex AI для:

  • Разместите и разверните предварительно обученную модель.

Чтобы узнать больше о различных компонентах Vertex, ознакомьтесь с документацией .

9. Уборка

Поскольку управляемые Vertex AI Workbench ноутбуки имеют функцию автоматического завершения работы в режиме ожидания, нам не нужно беспокоиться о выключении экземпляра. Если вы хотите выключить экземпляр вручную, нажмите кнопку «Стоп» в разделе Vertex AI Workbench консоли. Если вы хотите полностью удалить ноутбук, нажмите кнопку «Удалить».

Остановить экземпляр

Чтобы удалить сегмент хранилища, воспользуйтесь меню навигации в консоли Cloud Console, перейдите в раздел «Хранилище», выберите свой сегмент и нажмите «Удалить».

Удалить хранилище