很多时候,托管式的服务能够帮我们省很多事。从应用开发到部署,到后续运维;从机器学习模型的创建到训练,再到最终运行……这些环节中,很多步骤都可以选择托管式云服务来帮助我们降低开发成本和工作量,让自己更专注于真正重要的任务。

今天,我们就一起来看看机器学习过程中的数据处理和模型评估,如果这些任务也能借助托管式服务搞定,那是不是感觉又轻松了一大截!

隆重推荐:Amazon SageMaker Processing

Amazon SageMaker Processing 已于近期正式上线,这是 Amazon SageMaker 的一项新功能,可以帮助用户在完全托管的基础设施上轻松运行数据预处理、后处理和模型评估等工作负载。

毕竟大家都知道,训练一个准确的机器学习(ML)模型需要很多繁琐的步骤,但没什么比预处理数据集更重要,例如:

  • 将数据集转换为所用 ML 算法期望的输入格式;
  • 将现有功能转换为更具表现力的表示形式,例如一键编码分类功能;
  • 重新调整或归一化数值特征;
  • 设计高级功能,例如用 GPS 坐标替换邮寄地址;
  • 为自然语言处理应用程序清理和标记文本;
  • ……

这些任务包括在数据集上运行定制脚本,并保存处理后的版本,以供后续训练作业使用。可想而知,对 ML 团队来说,手动运行它们,或必须构建和扩展自动化工具,这类做法的前景让人堪忧。对于后处理作业(筛选、整理等)和模型评估作业(针对不同测试集对模型评分)而言也是如此。
为解决此问题,AWS 构建了 Amazon SageMaker Processing。

Amazon SageMaker Processing 到底是什么

Amazon SageMaker Processing 新增的 Python 开发工具包,使得数据科学家和 ML 工程师可以轻松地在 Amazon SageMaker 上运行预处理、后处理和模型评估工作负载。

该开发工具包使用 SageMaker 的内置容器来进行 scikit-learn,这可能是最受欢迎的数据集转换库之一。

如果还需要其他工具,那么大家也可以使用自己的 Docker 映像,而不必遵循任何 Docker 映像规范:这为用户提供了最大的灵活性,无论是在 SageMaker Processing 还是在 Amazon ECS 和 Amazon Elastic Kubernetes Service 之类的 AWS 容器服务上,甚至在内部,均是如此。

接下来我们将使用 scikit-learn 进行一个快速演示,随后将简要讨论如何使用自己的容器。完整示例请访问 GitHub。

使用内置的 Scikit-Learn 容器预处理数据

以下是使用 SageMaker Processing 开发工具包来运行 scikit-learn 作业的方法。
首先,让我们创建一个 SKLearnProcessor 对象,传递要使用的 scikit-learn 版本以及对托管基础设施的要求:

from sagemaker.sklearn.processing import SKLearnProcessorsklearn_processor = SKLearnProcessor(framework_version='0.20.0',                                     role=role,                                     instance_count=1,                                     instance_type='ml.m5.xlarge')

然后,我们可以像下面这样运行预处理脚本(稍后将介绍更多有关该操作的内容):

  • 数据集(dataset.csv)将自动复制到目标目录(/input)下的容器内。如果需要,也可以添加其他输入。
  • 这是 Python 脚本(preprocessing.py)读取它的位置,我们也可以将命令行参数传递给脚本。
  • 脚本对命令行进行预处理,将其分为三种方式,然后将文件保存在容器中的/opt/ml/processing/output/train、/opt/ml/processing/output/validation和/opt/ml/processing/output/test下。
  • 作业完成后,所有输出将自动复制到 S3 中的默认 SageMaker 存储桶。
from sagemaker.processing import ProcessingInput, ProcessingOutputsklearn_processor.run(    code='preprocessing.py',    # arguments = ['arg1', 'arg2'],    inputs=[ProcessingInput(        source='dataset.csv',        destination='/opt/ml/processing/input')],    outputs=[ProcessingOutput(source='/opt/ml/processing/output/train'),        ProcessingOutput(source='/opt/ml/processing/output/validation'),        ProcessingOutput(source='/opt/ml/processing/output/test')])

就这么简单!让我们通过查看预处理脚本的框架将所有内容放在一起:

import pandas as pdfrom sklearn.model_selection import train_test_split# Read data locally df = pd.read_csv('/opt/ml/processing/input/dataset.csv')# Preprocess the data setdownsampled = apply_mad_data_science_skills(df)# Split data set into training, validation, and testtrain, test = train_test_split(downsampled, test_size=0.2)train, validation = train_test_split(train, test_size=0.2)# Create local output directoriestry:    os.makedirs('/opt/ml/processing/output/train')    os.makedirs('/opt/ml/processing/output/validation')    os.makedirs('/opt/ml/processing/output/test')except:    pass# Save data locallytrain.to_csv("/opt/ml/processing/output/train/train.csv")validation.to_csv("/opt/ml/processing/output/validation/validation.csv")test.to_csv("/opt/ml/processing/output/test/test.csv")print('Finished running processing job')

快速浏览 S3存储桶,确认文件已成功处理并保存。现在,我可以将它们直接用作 SageMaker 训练作业的输入。

$ aws s3 ls --recursive s3://sagemaker-us-west-2-123456789012/sagemaker-scikit-learn-2019-11-20-13-57-17-805/output2019-11-20 15:03:22 19967 sagemaker-scikit-learn-2019-11-20-13-57-17-805/output/test.csv2019-11-20 15:03:22 64998 sagemaker-scikit-learn-2019-11-20-13-57-17-805/output/train.csv2019-11-20 15:03:22 18058 sagemaker-scikit-learn-2019-11-20-13-57-17-805/output/validation.csv

使用自己的容器处理数据

那么又该如何使用自己的容器来处理数据?例如想使用热门的 spaCy 库预处理文本数据。此时可以使用以下方法为其定义一个普通 Docker 容器。

FROM python:3.7-slim-buster# Install spaCy, pandas, and an english language model for spaCy.RUN pip3 install spacy==2.2.2 && pip3 install pandas==0.25.3RUN python3 -m spacy download en_core_web_md# Make sure python doesn't buffer stdout so we get logs ASAP.ENV PYTHONUNBUFFERED=TRUEENTRYPOINT ["python3"]

随后即可构建 Docker 容器在本地进行测试,然后将其推送到托管的Docker注册表服务 Amazon Elastic Container Registry。

接下来可以使用 ScriptProcessor 对象配置处理作业,并传递您已构建和推送的容器的名称。

from sagemaker.processing import ScriptProcessorscript_processor = ScriptProcessor(image_uri='123456789012.dkr.ecr.us-west-2.amazonaws.com/sagemaker-spacy-container:latest',                role=role,                instance_count=1,                instance_type='ml.m5.xlarge')

最后,可以像前面的示例一样运行该作业:

script_processor.run(code='spacy_script.py',    inputs=[ProcessingInput(        source='dataset.csv',        destination='/opt/ml/processing/input_data')],    outputs=[ProcessingOutput(source='/opt/ml/processing/processed_data')],    arguments=['tokenizer', 'lemmatizer', 'pos-tagger'])

其余过程与上述过程完全相同:将输入复制到容器内部,将输出从容器复制到 S3。

很简单对吧!需要注意的是,本文重点讨论了数据的预处理,但实际上大家也可以通过这种方式运行类似的任务进行后处理和模型评估。更多案例可参阅 GitHub 中的示例。

Amazon SageMaker Processing 现已在提供 Amazon SageMaker 的所有商业区域中推出。欢迎大家亲自体验!