Amazon SageMaker - это платформа для непрерывного машинного обучения (ML). Он поддерживает как обучение, так и размещение моделей машинного обучения в облаке. Ниже приводится общий обзор процедуры SageMaker.

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

В этом посте я буду использовать SageMaker для развертывания модели классификации автомобилей и вызова конечной точки модели с помощью API Gateway и AWS Lambda.

Создание экземпляра записной книжки Amazon SageMaker

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

Подготовить обучающие данные

Вы можете использовать инструменты AWS Ground Truth для маркировки собственных наборов данных. В этом примере я использую Набор данных автомобилей из Стэнфорда.

Набор данных Cars содержит 16 185 изображений 196 классов автомобилей. Данные разделены на 8 144 обучающих изображения и 8 041 тестовое изображение, где каждый класс разделен примерно на 50–50 частей. Классы обычно находятся на уровне марки, модели, года, например. Tesla Model S 2012 года или купе BMW M3 2012 года.

Скачать данные

Давайте создадим новый экземпляр записной книжки и откроем Jupyter, затем загрузим набор данных,

import os
import urllib.request
def download(url):
    filename = url.split("/")[-1]
    if not os.path.exists(filename):
        urllib.request.urlretrieve(url, filename)
download('http://imagenet.stanford.edu/internal/car196/cars_train.tgz')
download('https://ai.stanford.edu/~jkrause/cars/car_devkit.tgz')

… И распаковать их.

%%bash
tar -xzf car_devkit.tgz
tar -xzf cars_train.tgz

Обратите внимание, что аннотация имеет формат «.mat» (файл Matlab). Мы должны преобразовать его в массив со следующими значениями: имя изображения, идентификатор категории изображения, метка обучения / проверки.

import scipy.io as sio
def readClasses(matFile):   
    content = sio.loadmat(matFile)
    classes = [(_[0]) for _ in content['class_names'][0]]
    return classes    

def readAnnotations(matFile):   
    content = sio.loadmat(matFile)
    return content['annotations'][0]

Подготовить данные аннотации

Алгоритм обнаружения объектов Amazon SageMaker поддерживает форматы RecordIO и Image & JSON, я использую приведенный ниже сценарий для преобразования массива в файл JSON в качестве ввода аннотаций:

from imageio import imread

categories = readClasses("devkit/cars_meta.mat")
annotations = readAnnotations("devkit/cars_train_annos.mat")

for img in images :
    shape = imread('cars_train/{}'.format(img)).shape
    jsonFile = img.split('.')[0]+'.json'
    
    line = {}
    line['file'] = img
    line['image_size'] = [{
        'width':int(shape[1]),
        'height':int(shape[0]),
        'depth':3
    }]
     
    line['annotations'] = []
    line['categories'] = [] 
    #print(annotations)
    for anno in annotations:
         if(anno[5][0]==img):
            #print(anno) 
            line['annotations'].append({
                    'class_id':int(fix_index_mapping(anno[4][0][0])),
                    'top':int(anno[1][0][0]),
                    'left':int(anno[0][0][0]),
                    'width':abs(int(anno[2][0][0])- int(anno[0][0][0])),
                    'height':abs(int(anno[3][0][0]) -int(anno[1][0][0])),
                })
            class_name = ''
            for ind,cat in enumerate(categories, start=1):
                if int(anno[4][0][0]) == ind:
                    class_name = str(cat)
            assert class_name is not ''
            line['categories'].append({
                'class_id':int(anno[4][0][0]),
                'name':class_name
            })
   
    if line['annotations']:
        with open(os.path.join('car-generated', jsonFile),'w') as p:
            json.dump(line,p)

Ниже приведен пример файла .json.

{"file": "00001.jpg", "image_size": [{"width": 600, "height": 400, "depth": 3}], "annotations": [{"class_id": 13, "top": 116, "left": 39, "width": 530, "height": 259}], "categories": [{"class_id": 14, "name": "Audi TTS Coupe 2012"}]}

Загрузить в S3

Amazon SageMaker ожидает, что набор данных будет доступен в корзине S3. Нам нужно загрузить JSON-файлы изображений и аннотаций в корзину S3.

%%time
prefix = "prefix = 'car-Detection'"
train_channel = prefix + '/car-train'
validation_channel = prefix + '/car-validation'
train_annotation_channel = prefix + '/train_annotation'
validation_annotation_channel = prefix + '/validation_annotation'
sess.upload_data(path='car-train', bucket=bucket, key_prefix=train_channel)
sess.upload_data(path='car-validation', bucket=bucket, key_prefix=validation_channel)
sess.upload_data(path='car-train_annotation', bucket=bucket, key_prefix=train_annotation_channel)
sess.upload_data(path='car-validation_annotation', bucket=bucket, key_prefix=validation_annotation_channel)
s3_train_data = 's3://{}/{}'.format(bucket, train_channel)
s3_validation_data = 's3://{}/{}'.format(bucket, validation_channel)
s3_train_annotation = 's3://{}/{}'.format(bucket, train_annotation_channel)
s3_validation_annotation = 's3://{}/{}'.format(bucket, validation_annotation_channel)
s3_output_location = 's3://{}/{}/output'.format(bucket, prefix)

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

Обучить и построить модель

В этом примере мы используем встроенный алгоритм Object Detection для обучения нашей модели. Вы можете увидеть всю записную книжку в этом репозитории Github. Соответствующий код для обучающих данных выглядит следующим образом:

Если процесс обучения пройдет успешно, у нас будет наша модель, и она будет загружена в выходной блок s3. Модель можно увидеть в Консоли AWS и командной строке AWS:

$aws sagemaker list-training-jobs --region ap-southeast-2

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

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

object_detector = od_model.deploy(initial_instance_count = 1,                                  instance_type = 'ml.m4.xlarge')

Вы можете проверить конфигурацию и состояние конечной точки, перейдя на вкладку «Конечные точки» в консоли Amazon SageMaker.

Создайте бессерверный REST API

После создания конечной точки Sagemaker вы можете использовать конечную точку для вывода из записной книжки. Команда AWS предоставляет образец сценария для простой визуализации результатов обнаружения. Вы можете визуализировать прогнозы с высокой степенью достоверности с помощью ограничивающей рамки, отфильтровав обнаружения с низкой степенью достоверности с помощью следующего скрипта:

Отлично, это работает! Я хочу сделать его доступным для внешнего мира, поэтому нам придется создать API. Этого легко добиться с помощью Serverless Framework.

Начать работу с Serverless Framework

Во-первых, вам нужно установить Serverless Framework

$sls create --template aws-python3 --path car-classification

Созданный каталог включает два файла - handler.py - это функция Lambda. Файл serverless.yml, этот файл нужен для настройки поведения нашего приложения:

Обратите внимание, что ресурс политики Allow - это параметр SSM (AWS Systems Manager Agent). Чтобы сохранить значение в SSM, мне нужно выполнить следующую команду:

$aws ssm put-parameter --name sagemakerarn --type String --value arn:aws:sagemaker:ap-southeast-2:YOUR_ACCOUNT_ID:endpoint/object-detection-2019-06-01-04-13-54-575 --region ap-southeast-2D

Добавить лямбда-функцию

Теперь давайте обновим наш handler.py для вызова конечной точки SageMaker. Вот так выглядит файл handler.py:

Развернуть API

Чтобы развернуть свой API, запустите следующее:

$ serverless deploy -v

Протестируйте API

Мы подошли к концу нашего пути! Теперь мы можем вызывать развернутые конечные точки бессерверного API с помощью CURL:

$curl -d '{"img_url":"https://bit.ly/2IbFF70"}' -H "Content-Type: application/json" -X POST https://xxxx.execute-api.ap-southeast-2.amazonaws.com/dev/sagemaker

Вот и все! Надеюсь, вы нашли эту статью полезной. Вы можете найти полный проект в моем репозитории GitHub.