От Андреса Альтены, консультанта по науке о данных

Добро пожаловать во вторую часть нашей серии, посвященной различным режимам обучения, доступным в AWS Sagemaker. Если вы пропустили, часть 1 (где мы рассмотрели встроенные алгоритмы SageMaker) доступна здесь.

В этой части мы рассмотрим режим сценария, который для многих является методом «златовласки» для настройки учебного задания, балансируя между гибкостью и требуемыми усилиями:

Режим сценария

Режим сценария предлагает нам средний уровень усилий и свободы.

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

Он также поддерживает несколько фреймворков, и их число постоянно увеличивается:

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

Демо

Мы разделим эту демонстрацию на два основных раздела: определение оценщика и сценарий точки входа.

Определение оценщика

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

from sagemaker.inputs import TrainingInput

from sagemaker.xgboost.estimator import XGBoost

session = sagemaker.Session()

script_path = "script_mode.py"

# Create Estimator

xgb_estimator = XGBoost(

##################################

entry_point=script_path, # Path to script containing training and deployment code

source_dir=source_directory, # Path to directory

dependencies=["my_custom_library"] # Custom libraries

##################################

framework_version="1.5-1", # Note: framework_version is mandatory

hyperparameters=hyperparams,

role=role, # Defined as sagemaker.get_execution_role()

instance_count=1,

instance_type=instance_type,

output_path=output_path,

)

# Convert data stored in S3 to TrainingInput type

train_input = TrainingInput(

"s3://{}/{}/{}/".format(bucket, prefix, "train"), content_type=content_type

)

validation_input = TrainingInput(

"s3://{}/{}/{}/".format(bucket, prefix, "validation"), content_type=content_type

)

# Train model

xgb_estimator.fit({"train": train_input, "validation": validation_input})

Вы заметите, что мы определили не только entry_point, но также source_dir и зависимости:

  • entry_point — путь к скрипту, содержащему модель. Через некоторое время мы рассмотрим сам сценарий.
  • исходный_каталог (необязательно) — если вы хотите разбить свой код на несколько файлов и импортировать необходимые функции в вашу entry_point. Это указывает на каталог, в котором хранятся все остальные файлы.
  • зависимости (необязательно) — режим сценария поддерживает добавление пользовательских библиотек, и эти библиотеки не обязательно должны находиться в том же каталоге, что и ваш сценарий Python точки входа. Вам просто нужно указать пользовательскую библиотеку или другие зависимости при определении оценщика обучения SageMaker.

Скрипт точки входа

В этом скрипте есть несколько ключевых частей, и мы рассмотрим каждую из них в порядке выполнения:

  • Основное защитное предложение: содержит обучающий код.
  • Model_fn: загружает модель, сохраненную после обучения.
  • Input_fn: десериализация входных данных
  • Predict_fn: применение прогнозов модели к входным данным.
  • Output_fn: сериализовать выходные данные.

Основная защитная оговорка: содержит обучающий код

Поскольку SageMaker импортирует ваш обучающий сценарий, вам следует поместить обучающий код в основную защиту ( if __name__=='__main__':), если вы используете тот же сценарий для размещения своей модели, чтобы SageMaker непреднамеренно не запускал обучающий код в неправильной точке выполнения.

Есть три вещи, которые вы хотите, чтобы эта «функция» делала: анализировала аргументы, обучала модель, сериализовала и сохраняла модель, чтобы она была готова для вывода. Глядя на код ниже, мы видим, как мы разделили эту основную функцию. Мы рассмотрим каждую из отдельных функций отдельно.

if__name__ == "__main

args, _ = parse_args()

model = train()

save_model(model)

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

Затем это анализируется ниже в строке:

parser.add_argument("--train", type=str,

default=os.environ.get("SM_CHANNEL_TRAIN") )

def parse_args():

"""

Parse arguments passed from the SageMaker API

to the container

"""

parser = argparse.ArgumentParser()

# Hyperparameters sent by the client are passed as command-line arguments to the script

parser.add_argument("--num_round", type=int, default=os.environ.get("SM_HP_num_round"))

parser.add_argument("--max_depth", type=int, default=5)

parser.add_argument("--eta", type=float, default=0.2)

parser.add_argument("--objective", type=str, default="reg:squarederror")

parser.add_argument("--K", type=int, default=os.environ.get("SM_HP_K"))

# Data directories

parser.add_argument("--train", type=str, default=os.environ.get("SM_CHANNEL_TRAIN"))

# Model directory: we will use the default set by SageMaker, /opt/ml/model

parser.add_argument("--model_dir", type=str, default=os.environ.get("SM_MODEL_DIR"))

return parser.parse_known_args()

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

def train():

"""

Train the XGBoost model

"""

K = args.K

hyperparameters = {

"max_depth": args.max_depth,

"eta": args.eta,

"objective": args.objective,

"num_round": args.num_round,

}

# the csv is saved in the training channel which is passed as an argument

train_df = pd.read_csv(f"{args.train}/train.csv", header=None)

# Define training

x_train, y_train = train_df.iloc[:, 1:], train_df.iloc[:, :1]

dtrain = xgb.DMatrix(data=x_train, label=y_train)

dvalidation = xgb.DMatrix(data=x_validation, label=y_validation)

# Train the model

model = xgb.train(

params=hyperparameters,

dtrain=dtrain,

evals=[(dtrain, "train")],

)

return model

Сериализация модели: после завершения обучения сохраните модель в правильном каталоге. Позже ваш скрипт загрузит модель из этого каталога, поэтому убедитесь, что вы сохраняете и загружаете его из одного и того же места (в идеале это должно быть указано в качестве аргумента ‘ model_dir’).

def save_model(model):

"""

Serialise the model and save at the model directory specified in the

args

"""

model_location = args.model_dir + "/xgboost-model"

pickle.dump(model, open(model_location, "wb"))

logging.info("Stored trained model at {}".format(model_location) )

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

model_fn: загружает модель

Загружает обученную модель из каталога моделей. Способ загрузки вашей модели будет зависеть от модели, которую вы используете. Эта функция должна быть простой, обычно достаточно 1 или 2 строк.

def model_fn(model_dir):

"""Deserialize and return fitted model.

Note that this should have the same name as the serialized model in the train function

"""

model_file = "xgboost-model"

model = pickle.load(open(os.path.join(model_dir, model_file), "rb"))

return model

input_fn: десериализует ввод

Функция input_fn отвечает за десериализацию входных данных, чтобы их можно было передать в модель. Он принимает входные данные и тип контента в качестве параметров и возвращает десериализованные данные.

Некоторые фреймворки будут иметь свою собственную функцию input_fn, но мне лично нравится определять эту функцию, чтобы точно знать, какие данные передаются в модель.

# Note this is not used for the xgboost example we have been looking at so far, as that is covered by the default input_fn

def input_fn(request_body, request_content_type):

"""

Deserialize and prepare the prediction input

"""

if request_content_type == "application/json":

request = json.loads(request_body)

train_inputs = torch.tensor(request)

return train_uts

else:

raise ValueError("Input type not supported")

Predict_fn: применяет прогнозы модели к входным данным.

Функция predict_fn отвечает за получение прогнозов от модели. Он принимает модель и данные, возвращенные из input_fn, в качестве параметров и возвращает прогноз. Для predict_fn нет реализации по умолчанию. Вы должны реализовать его самостоятельно.

def predict_fn(input_data, model):

"""

Apply model to incoming request

"""

return model.predict(input_data)

output_fn: сериализует выходные данные

Функция output_fn отвечает за сериализацию данных, которые функция predict_fn возвращает в качестве прогноза. Опять же, по умолчанию существует output_fn, но всегда полезно определить его самостоятельно, чтобы полностью понять, что представляют собой выходные данные модели.

# Note this is not used for the xgboost example we have been looking at so far, as that is covered by the default output_fn

def output_fn(prediction, response_content_type):

"""

Serialize and prepare the prediction output

"""

if response_content_type == "application/json":

response = str(prediction)

return response

else:

raise ValueError("Output type not supported")

Когда вы должны использовать их?

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

Почему бы вам не использовать его?

Вы хотите, чтобы ваши модели не зависели от платформы.

Выбранный вами фреймворк не поддерживается.

Модель, которую вы планируете использовать, предоставляется в виде встроенного алгоритма.

Заключение

На этом вторая часть нашего обзора различных режимов обучения, доступных в AWS SageMaker, завершается. Следите за последней частью нашей серии (и самой гибкой) — BYODC (Bring your own docker container), которая скоро появится.

А пока, если вы хотите обсудить эту серию, пожалуйста, свяжитесь с нами.

Первоначально опубликовано на https://www.crimsonmacaw.com 15 июня 2022 г.