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

1. Обзор

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

Что вы узнаете

Вы узнаете, как:

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

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

2. Знакомство с Vertex AI

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

Vertex AI включает в себя множество различных продуктов для поддержки комплексных рабочих процессов машинного обучения. Эта лабораторная работа будет сосредоточена на продуктах, перечисленных ниже: Прогнозы и 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 в облачной консоли и нажмите «Включить Vertex AI API» .

Панель управления Vertex AI

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

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

Меню вершинного AI

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

Notebook_api

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

Ноутбуки_UI

Затем выберите НОВЫЙ НОУТБУК .

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

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

create_notebook

Выберите Дополнительные настройки .

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

Enable_terminal

Все остальные дополнительные настройки вы можете оставить как есть.

Далее нажмите Создать . Подготовка экземпляра займет пару минут.

После создания экземпляра выберите OPEN JUPYTERLAB .

open_jupyterlab

5. Зарегистрируйте модель

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

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

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

скачать_модель

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

create_bucket

Дайте своему сегменту имя и выберите в качестве региона us-central1. Затем нажмите СОЗДАТЬ

указать_бакет

Загрузите загруженную вами модель концентратора TensorFlow в корзину. Обязательно сначала распакуйте файл.

gcs_model

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

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

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

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

model_registry

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

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

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

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

select_container

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

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

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

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

6. Развертывание модели

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

развертывание_модель

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

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

endpoint_settings

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

развертывание_статус

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».

конечная_точка_id

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

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

test_image

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

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 , который оборачивает SavedModel TensorFlow как слой Keras. Чтобы создать модель, вы можете использовать Keras Sequential API с загруженной моделью 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 .

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

Поскольку развернутая модель ожидает входные данные в виде необработанных (несжатых) байтов, вам необходимо убедиться, что данные, закодированные в формате Base 64, преобразуются обратно в необработанные байты (например, 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 принимает нулевые входные данные. Ваша обслуживающая функция выполнит преобразование из 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. Если вы хотите полностью удалить блокнот, нажмите кнопку «Удалить».

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

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

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