От Андреса Альтены, консультанта по науке о данных
Добро пожаловать во вторую часть нашей серии, посвященной различным режимам обучения, доступным в 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 г.