В этой части вы увидите, как запустить свой собственный алгоритм, а не использовать встроенные алгоритмы SageMaker. Хотя SageMaker предоставляет встроенные алгоритмы для практически любого вида задач, много раз мы хотим запустить нашу собственную модель, используя силу SageMaker. Мы можем сделать это эффективно, если у нас есть рабочие знания о Docker и практических знаниях Python.
Мы создадим пользовательскую модель случайного леса для нашего набора данных Big Mart. Мы будем развернуть контейнер в ECR, а затем тренировать модель, используя SageMaker. Затем мы будем использовать модель для вывода в режиме реального времени, а также понять, как делается пакетная трансформация.
Заявление о проблеме
Проблема состоит в том, что мы попытаемся предсказать продажи фирмы электронной коммерции, используя алгоритм случайного леса (один из алгоритмов под наблюдением ансамбля обучения). Поскольку это проблема регрессии, мы будем использовать класс Randomforestregressor в пакете Scikit-Learn.
Мы уже исследовали набор данных во второй части: обработка данных в AWS SageMaker (https://dev.to/aws-builders/data-processing-in-aws-sagemaker-20gi).
Запуск модели
Прежде чем перейти к применению модели в среде SageMaker, давайте сначала запустим алгоритм локально, в наборе данных, который мы подготовили, и проверим общую потерю, которая была понесена.
from sklearn.ensemble import RandomForestRegressor rfc = RandomForestRegressor(n_estimators=500)
В предыдущем коде мы инициализировали алгоритм randomforestregressor и попросили объединить выходы 500 отдельных деревьев решений. Как только мы инициализировали алгоритм, мы можем начать обучение модели.
rfc.fit(X_train, y_train)
Предыдущий код начнет обучение модели. Теперь мы можем использовать обученную модель, чтобы сделать прогнозы на наборе тестирования.
predictions = rfc.predict(X_test)
Все прогнозы не хранятся в переменных прогнозах. Давайте рассчитаем среднюю квадратичную ошибку в квадрате модели, которую мы создали.
from sklearn.metrics import mean_squared_error np.sqrt(mean_squared_error(predictions, y_test))
Преобразование кода для использования ресурсов SageMaker
Ниже приведены шаги для запуска пользовательской модели в SageMaker:
- Храните данные в S3.
- Создайте обучающий сценарий и назовите его.
Создайте сценарий вывода, который поможет в прогнозах. Мы будем называть это Predictor.py.
Установите файлы так, чтобы это помогло в генерации конечных точек.
Создайте DockerFile, который поможет в создании изображения, внутри которого будет работать весь код.
Создайте сценарий, чтобы подтолкнуть изображение Docker в реестр Elastic Contastic Contastic (ECR).
Используйте API Sagemaker и Boto3, чтобы тренировать и проверить модель.
Создание учебного сценария
Первое, что следует иметь в виду, это то, что сценарий будет работать внутри контейнера. Таким образом, может возникнуть проблема синхронизации, так как сценарий находится внутри, в то время как данные поступают из ковша S3, которое находится за пределами контейнера. Кроме того, результаты алгоритма также должны быть сохранены в ведре S3. Мы должны помнить все это, когда мы создаем тренировочный сценарий.
Первое, что мы должны знать, это то, что внутри контейнера, независимо от того, каковы данные, которые входят, он хранится в папке/Opt/Ml. Поэтому данные от S3 будут загружены из этой папки. Итак, в этой папке мы должны создать три папки:
Один, чтобы сохранить вход, один для хранения вывода, а один для хранения моделей. Это можно определить с помощью следующего сценария:
prefix = '/opt/ml/' input_path = prefix + 'input/data' output_path = os.path.join(prefix, 'output') model_path = os.path.join(prefix, 'model')
В папке данных мы можем иметь несколько файлов, таких как обучение, проверка или тестирование. У нас также есть отдельные файлы, вносящие вклад в один файл обучения. Следовательно, мы можем сделать такой сегрегацию. Для нас у нас есть только один файл: файл обучения. Итак, мы будем использовать только один канал.
channel_name='training' training_path = os.path.join(input_path, channel_name)
Это готовит наш учебный скрипт для обработки данных. Следующим является сам тренировочный сценарий. Данные будут поступать от S3. Сначала мы должны прочитать это.
input_files = [ os.path.join(training_path, file) for file in os.listdir(training_path) ] raw_data = [ pd.read_csv(file) for file in input_files ] data = pd.concat(raw_data)
Этот скрипт также помогает, если у вас есть несколько листов CSV для чтения. Но в этом случае не забудьте сохранить параметр. Теперь, когда мы прочитали данные, мы можем начать учебный процесс. Ниже приведен весь сценарий для обучения:
def train(): print('Starting the training.') try: # Take the set of files and read them all into a single pandas dataframe input_files = [ os.path.join(training_path, file) for file in os.listdir(training_path) ] if len(input_files) == 0: raise ValueError(('There are no files in {}.\n' + 'This usually indicates that the channel ({}) wasincorrectly specified,\n' + 'the data specification in S3 was incorrectly specified orthe role specified\n' + 'does not have permission to access the data.').format(training_path, channel_name)) raw_data = [ pd.read_csv(file) for file in input_files ] data = pd.concat(raw_data) data = data.sample(frac=1) for i in data.Item_Type.value_counts().index: data.loc[(data['Item_Weight'].isna()) & (data['Item_Type'] == i), ['Item_Weight']] = \ data.loc[data['Item_Type'] == 'Fruits and Vegetables', ['Item_Weight']].mean()[0] cat_data = data.select_dtypes(object) num_data = data.select_dtypes(np.number) cat_data.loc[(cat_data['Outlet_Size'].isna()) & (cat_data['Outlet_Type'] == 'Grocery Store'), ['Outlet_Size']] = 'Small' cat_data.loc[(cat_data['Outlet_Size'].isna()) & (cat_data['Outlet_Type'] == 'Supermarket Type1'), ['Outlet_Size']] = 'Small' cat_data.loc[(cat_data['Outlet_Size'].isna()) & (cat_data['Outlet_Type'] == 'Supermarket Type2'), ['Outlet_Size']] = 'Medium' cat_data.loc[(cat_data['Outlet_Size'].isna()) & (cat_data['Outlet_Type'] == 'Supermarket Type3'), ['Outlet_Size']] = 'Medium' cat_data.loc[cat_data['Item_Fat_Content'] == 'LF' , ['Item_Fat_Content']] = 'Low Fat' cat_data.loc[cat_data['Item_Fat_Content'] == 'reg' , ['Item_Fat_Content']] = 'Regular' cat_data.loc[cat_data['Item_Fat_Content'] == 'low fat' , ['Item_Fat_Content']] = 'Low Fat' le = LabelEncoder() cat_data = cat_data.apply(le.fit_transform) ss = StandardScaler() num_data = pd.DataFrame(ss.fit_transform(num_data.drop(['Item_Outlet_Sales'], axis=1)), columns = num_data.drop(['Item_Outlet_Sales'],axis=1).columns) cat_data = pd.DataFrame(ss.fit_transform(cat_data.drop(['Item_Identifier'], axis=1)), columns = cat_data.drop(['Item_Identifier'], axis=1).columns) final_data = pd.concat([num_data,cat_data],axis=1) X = final_data y = data['Item_Outlet_Sales'] from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.1, random_state=5) from sklearn.ensemble import RandomForestRegressor rfc = RandomForestRegressor(n_estimators=500) clf = rfc.fit(X_train, y_train) # save the model with open(os.path.join(model_path, 'randomForest-tree-model.pkl'), 'w') as out: pickle.dump(clf, out) print('Training complete.') except Exception as e: trc = traceback.format_exc() with open(os.path.join(output_path, 'failure'), 'w') as s: s.write('Exception during training: ' + str(e) + '\n' + trc) print('Exception during training: ' + str(e) + '\n' + trc, file=sys.stderr) sys.exit(255)
Мы будем хранить весь сценарий внутри функции под названием Train (). Прочитав лист CSV, мы будем следовать той же процедуре, которую мы видели в главе 5. Позже мы поместим модель случайного леса на данных, которые мы запустили в предыдущем разделе.
После всего этого мы должны сохранить эту модель, потому что позже нам придется делать прогнозы, используя модель. Чтобы сохранить модель, мы сначала сериализуем ее, используя Pickle, а затем сохраните ее в месте модели. Позже эта модель будет сохранена в S3. Наконец, мы можем запустить весь сценарий.
if __name__ == '__main__': train() sys.exit(0)
Мы должны использовать sys.exit (0), поскольку он отправляет сообщение SageMaker, что обучение успешно завершено. Сохраните файл с помощью поезда имени и без расширения.
Создание сценария вывода
Сценарий обучения используется для обучения модели. Но как только модель обучена, мы должны делать прогнозы, будь то с выводом в реальном времени. Мы сохраним сценарий вывода в файле с именем Predictor.py.
Файл предиктора состоит из следующих компонентов:
- ScoringService () класс
метод ping ()
Метод преобразования ()
Любая другая требуемая функция помощника
Класс ScoringService () состоит из двух функций. Первая функция, get_model (), загружает и десериализует модель, в то время как второй метод, прогноз (), отвечает за прогнозы.
class ScoringService(object): model = None @classmethod def get_model(cls): if cls.model == None: with open(os.path.join(model_path, 'randomForest-tree-model. pkl'), 'r') as inp: cls.model = pickle.load(inp) return cls.model @classmethod def predict(cls, input): clf = cls.get_model() return clf.predict(input)
Метод ping () просто используется для проверки того, является ли контейнер Docker, в котором работает код здоровым. Если это не здорово, то это дает ошибку 404, иначе 202.
@app.route('/ping', methods=['GET']) def ping(): status = 200 if health else 404 return flask.Response(response='\n', status=status, mimetype='application/json')
Transformation () — это метод, который отвечает за чтение тестового файла и вызов необходимых методов и классов. Здесь можно понять, что весь этот процесс генерации конечных точек — не что иное, как создание API. Как только API создается, данные отправляются в качестве запроса POST, а затем мы получаем прогнозы в качестве ответа. Вся эта архитектура построена с использованием фламбной структуры.
Данные отправляются с использованием метода POST, поэтому для его прочтения нам нужен метод stringio () для декодирования данных. Как только данные декодированы, мы можем прочитать их с помощью нашего обычного метода Pandas. Функция Transformation () отправляет данные в функцию Predict () Class ScoringService (). Метод отправляет выход обратно в функцию Transformation ().
Этот вывод прогноза отправляется обратно на хост, откуда называется API с помощью функции Stringio (). Это заканчивает весь цикл конечных точек. Ниже приведено код преобразования ():
@app.route('/invocations', methods=['POST']) def transformation(): data = None if flask.request.content_type == 'text/csv': data = flask.request.data.decode('utf-8') s = StringIO.StringIO(data) data = pd.read_csv(s, header=None) else: return flask.Response(response='This predictor only supports CSV data', status=415, mimetype='text/plain') # Do the prediction predictions = ScoringService.predict(data) # Convert from numpy back to CSV out = StringIO.StringIO() pd.DataFrame({'results':predictions}).to_csv(out, header=False, index=False) result = out.getvalue() return flask.Response(response=result, status=200, mimetype='text/csv')
Настройка файлов генерации конечных точек
Чтобы успешно запустить сервер вывода, нам нужно настроить следующие файлы:
- nginx.conf файл
- подавать файл
- WSGI.py File
Файл NGINX используется для раскрытия сервера и создания соединения между контейнерами Docker, развернутыми на экземплярах EC2, и клиентом вне или внутри сети SageMaker. Nginx использует Python Framework, называемую стрелобником, которая помогает настроить HTTP -сервер.
Подача использует работающий сервер стренолина, чтобы установить соединение между различными ресурсами. В частности, он используется для следующих целей:
- Эффективно, используя количество процессоров для запуска модели
- Определение тайм -аута сервера
Генерирующие журналы
Запуск сервера с помощью nginx и стрелканга
Остановка сервера, если что -то не происходит, как ожидалось
Наконец, файл wsgi.py используется для сообщения сервера о нашем файле Predictor.py.
Настройка Dockerfile
Теперь, когда все наши файлы сценария готовы, мы должны создать изображение Docker, чтобы его можно было загрузить в ECR, а затем SageMaker может получить доступ к нынешнему коду и запустить его в прикрепленном экземпляре EC2.
Теперь мы должны создать сценарий DockerFile, который будет запущен для создания изображения. Затем мы будем использовать файл build_and_push.sh, чтобы подтолкнуть изображение в ECR.
Это те шаги, за которыми мы будем выполнять в Dockerfile:
- Загрузите изображение из Dockerhub, в котором будет иметь нашу операционную систему. Мы скачаем минимальную версию Ubuntu, чтобы наш код мог работать внутри него. Для этого мы будем использовать следующий скрипт:
FROM ubuntu:16.04
- Назовите человека или организацию, которая поддерживает и создает это изображение.
MAINTAINER <>
- Запустите некоторые команды Ubuntu, чтобы мы могли настроить среду Python и обновить файлы операционной системы. Мы также загрузим файлы сервера, которые будут использоваться для запуска конечных точек вывода. Вы должны быть знакомы с командами Linux, чтобы понять скрипт.
RUN apt-get -y update && apt-get install -y --no-install- recommends \ wget \ python \ nginx \ ca-certificates \ && rm -rf /var/lib/apt/lists/*
- После того, как настройка будет сделана, мы можем использовать PIP из Python для установки важных пакетов Python.
RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && \ pip install numpy==1.16.2 scipy==1.2.1 scikit-learn==0.20.2 pandas flask gevent gunicorn && \ (cd /usr/local/lib/python2.7/dist-packages/scipy/.libs; rm *; ln ../../numpy/.libs/* .) && \ rm -rf /root/.cache
- Установите переменные среды, чтобы Python знал, что такое папка по умолчанию, которая будет содержать код. Кроме того, мы установим некоторые функции Python. Сначала мы удостоверимся, что своевременные сообщения журнала должны быть получены из контейнера, а затем следим за тем, чтобы, как только какой -либо модуль импортирован в Python, его файл .pyc не создается. Это делается с использованием переменных PythoNununbuffered и PythondontWriteByteCode, соответственно.
ENV PYTHONUNBUFFERED=TRUE ENV PYTHONDONTWRITEBYTECODE=TRUE ENV PATH="/opt/program:${PATH}"
- Наконец, экземпляр будет указать скопировать наши файлы каталога данных в каталог работы по умолчанию, а затем мы изменим каталог работы по умолчанию.
COPY Data /opt/program WORKDIR /opt/program
Нажатие изображения Docker к ECR
Мы создадим файл скрипта оболочки, который будет использоваться сначала для создания изображения из DockerFile, который мы создали в предыдущем разделе, а затем для подтолкну изображения в ECR. Давайте посмотрим на пошаговую процедуру этого:
- Назовите изображение. Мы сохраним имя в переменной.
algorithm_name=sagemaker-random-forest
- Дайте полное чтение и запись разрешения на поезд и подайте файлы, чтобы после начала контейнера не было никакого доступа к ошибкам.
chmod +x Data/train chmod +x Data/serve
- Получите конфигурации AWS, чтобы не было остановки, когда изображение нажимается. Мы определим учетную запись и регион нашего AWS. Помните, что, поскольку мы будем запускать этот код изнутри SageMaker, информация может быть автоматически извлечена. Если мы запускаем это из вашей локальной системы или где -либо за пределами AWS, нам придется дать пользовательские значения.
account=$(aws sts get-caller-identity --query Account --output text) region=$(aws configure get region) region=${region:-us-east-2}
- Дайте путь и имя в контейнер. Мы будем использовать то же имя, которое было дано на первом шаге. Мы будем использовать этот путь позже, чтобы натолкнуть изображение.
fullname="${account}.dkr.ecr.${region}.amazonaws.com/${algorithm_name}:latest"
- Проверьте, существует ли изображение. Если это не так, то будет создано новое изображение; В противном случае, то же изображение будет обновлено.
aws ecr describe-repositories --repository-names "${algorithm_name}" > /dev/null 2>&1 if [ $? -ne 0 ] then aws ecr create-repository --repository-name "${algorithm_name}" > /dev/null fi
- Получите учетные данные для входа в учетную запись AWS.
$(aws ecr get-login --region ${region} --no-include-email)
- Создайте изображение с уже решением имени, переименование его с полным именем, которое мы определили, которое содержит адрес ECR, а затем, наконец, нажмите код.
docker build -t ${algorithm_name} . docker tag ${algorithm_name} ${fullname} docker push ${fullname}
Как только этот шаг будет сделан, мы должны перейти на терминал, займите в каталог, где присутствует ваш Dockerfile, а затем введите следующее:
sh build_and_push.sh
Это начнет запускать сценарий и успешно загрузит изображение в ECR. Затем вы можете перейти к ECR и проверить, существует ли изображение.
Это завершает процесс создания докера.
Обучение модели
import boto3 import re import os import numpy as np import pandas as pd from sagemaker import get_execution_role import sagemaker as sage role = get_execution_role() sess = sage.Session() account = sess.boto_session.client('sts').get_caller_identity()['Account'] region = sess.boto_session.region_name data_location = 's3://slytherins-test/Train.csv' image = '{}.dkr.ecr.{}.amazonaws.com/sagemaker-random-forest:latest'.format(account, region) tree = sage.estimator.Estimator(image, role, 1, 'ml.m4.xlarge', output_path="s3://{}/output".format("slytherins-test"), sagemaker_session=sess) tree.fit(data_location)
Это начнет обучающую работу, а затем, как только работа будет закончена, это также сообщит вам общее время.
Развертывание модели
Теперь, когда мы успешно обучили модель, мы можем развернуть ее, используя следующую линию скрипта:
from sagemaker.predictor import csv_serializer predictor = tree.deploy(1, 'ml.m4.xlarge', serializer=csv_serializer)
Потребуется некоторое время, чтобы раскрутить экземпляр, и тогда пришло время начать нашу вывод.
Делать вывод в реальном времени
Давайте используем тестовый набор данных набора данных Big Mart и сделаем прогнозы, используя живую конечную точку, на которой мы только что развернули модель.
predictions = predictor.predict(test_data.values).decode('utf-8')
использованная литература
Книга: Практическое машинное обучение в AWS
Часть 1: https://dev.to/aws-builders/intro-to-amazon-sagemaker-3gp5
Часть 2: https://dev.to/aws-builders/data-processing-in-aws-sagemaker-20gi
Часть 3: https://dev.to/aws-builders/building-deploying-a-machine-learning-model-using-linear-learner-3p7c
Часть 4: https://dev.to/aws-builders/building-deploying-lobing-text-model-in-aws-sagemaker-1lca
Часть 5: https://dev.to/aws-builders/building-deploying-image-classification-in-aws-sagemaker-4l4e
Часть 6: https://dev.to/salah856/building-seqtoseq-model-in-aws-sagemaker-4m22
Часть 7: https://dev.to/aws-builders/using-cloudwatch-in-sagemaker-pm7
Оригинал: «https://dev.to/aws-builders/running-custom-algorithm-in-aws-sagemaker-4jdf»