使用 Data Version Control 和 Amazon SageMaker Experiments PlatoBlockchain Data Intelligence 端到端跟踪您的 ML 实验。 垂直搜索。 哎。

使用 Data Version Control 和 Amazon SageMaker Experiments 端到端跟踪您的 ML 实验

数据科学家经常致力于了解各种数据预处理和特征工程策略与不同模型架构和超参数相结合的效果。这样做需要您迭代地覆盖较大的参数空间,并且在保持实验可重复性的同时跟踪以前运行的配置和结果可能会让人不知所措。

这篇文章将引导您通过一个示例来了解如何使用以下方法跨代码、数据、工件和指标跟踪实验 Amazon SageMaker实验 和这个结合 数据版本控制 (DVC)。我们展示了如何同时使用 DVC 和 亚马逊SageMaker 加工和培训工作。我们在加州住房数据集上训练不同的 CatBoost 模型 StatLib 存储库,并更改保留策略,同时使用 DVC 跟踪数据版本。在每个单独的实验中,我们使用 SageMaker Experiments 跟踪输入和输出工件、代码和指标。

SageMaker实验

SageMaker Experiments 是一项用于跟踪机器学习 (ML) 实验的 AWS 服务。这 SageMaker 实验 Python SDK 是此服务的高级接口,可帮助您使用 Python 跟踪实验信息。

SageMaker Experiments 的目标是尽可能简单地创建实验、填充试验、添加跟踪和沿袭信息以及跨试验和实验运行分析。

在讨论 SageMaker 实验时,我们引用以下概念:

  • 实验 – 相关试验的集合。您可以将试验添加到要一起比较的实验中。
  • 审讯 – 多步骤 ML 工作流程的描述。工作流程中的每个步骤均由试用组件描述。
  • 试用组件 – 机器学习工作流程中单个步骤的描述,例如数据清理、特征提取、模型训练或模型评估。
  • 跟踪 – 用于记录有关单个试用组件的信息(例如参数、指标或工件)的 Python 上下文管理器。

数据版本控制

数据版本控制 (DVC) 是一种新型数据版本控制、工作流程和实验管理软件,它构建于 混帐 (尽管它可以独立工作)。 DVC 缩小了现有工程工具集与数据科学需求之间的差距,使您能够利用新的工具集 功能 同时重用现有的技能和直觉。

数据科学实验共享和协作可以通过常规的 Git 流程(提交、分支、标记、拉取请求)来完成,就像软件工程师的工作方式一样。借助 Git 和 DVC,数据科学和机器学习团队可以对实验进行版本控制、管理大型数据集并使项目可重复。

DVC具有以下特点:

  • DVC 是一个 免费, 开源 命令行 工具。
  • DVC 在 Git 存储库之上工作,并具有与 Git 类似的命令行界面和流程。 DVC 也可以独立工作,但无需 版本 功能。
  • 通过用小文件替换大文件、数据集目录、ML 模型等来启用数据版本控制 元文件 (易于使用 Git 处理)。这些占位符指向原始数据,与源代码管理解耦。
  • 您可以使用本地或云存储将项目的数据与其代码库分开存储。这就是数据科学家传输大型数据集或与其他人共享 GPU 训练模型的方式。
  • DVC 通过创建轻量级数据使数据科学项目可重复 管道 使用隐式依赖图,并编码所涉及的数据和工件。
  • DVC 与平台无关。它可以在所有主要操作系统(Linux、macOS 和 Windows)上运行,并且独立于编程语言(Python、R、Julia、shell 脚本等)或 ML 库(Keras、TensorFlow、PyTorch、Scipy 和更多)在项目中使用。
  • DVC 快速 安装 不需要特殊的基础设施,也不依赖 API 或外部服务。它是一个独立的 CLI 工具。

SageMaker 实验和 DVC 示例

下列 GitHub 示例 展示如何在 SageMaker 环境中使用 DVC。特别是,我们研究了如何构建默认安装的 DVC 库的自定义映像,以便为数据科学家提供一致的开发环境 亚马逊SageMaker Studio,以及如何将 DVC 与 SageMaker 托管基础设施一起运行以进行处理和培训。此外,我们还展示了如何使用 DVC 中的数据版本控制信息来丰富 SageMaker 跟踪信息,并在 Studio 控制台中将其可视化。

下图说明了解决方案架构和工作流程。

构建已安装 DVC 的自定义 Studio 映像

GitHub存储库,我们解释了如何为已安装 DVC 的 Studio 创建自定义映像。创建映像并使其可供所有 Studio 用户使用的优点是,它为 Studio 用户创建了一致的环境,他们也可以在本地运行该环境。尽管该示例基于 AWS 云9,只要安装并运行 Docker,您也可以在本地计算机上构建容器。该示例基于以下内容 Dockerfile环境.yml。生成的 Docker 镜像存储在 Amazon Elastic Container注册 (Amazon EMR) 在您的 AWS 账户中。请看下面的代码:

# Login to ECR
aws --region ${REGION} ecr get-login-password | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom

# Create the ECR repository
aws --region ${REGION} ecr create-repository --repository-name smstudio-custom

# Build the image - it might take a few minutes to complete this step
docker build . -t ${IMAGE_NAME} -t ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom:${IMAGE_NAME}

# Push the image to ECR
docker push ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom:${IMAGE_NAME}

现在,您可以 创建一个新的 Studio 域 or 更新现有 Studio 域 可以访问新创建的 Docker 镜像。

我们使用 AWS云开发套件 (AWS CDK)通过创建以下资源 AWS CloudFormation:

  • 对新的或现有的 Studio 域具有正确权限的 SageMaker 执行角色
  • SageMaker 映像和来自 Docker 映像的 SageMaker 映像版本 conda-env-dvc-kernel 我们之前创建的
  • An AppImageConfig 指定如何配置内核网关
  • Studio 用户(data-scientist-dvc)具有正确的 SageMaker 执行角色和可用的自定义 Studio 映像

有关详细说明,请参阅 将自定义映像关联到 SageMaker Studio.

运行实验室

要运行实验,请完成以下步骤:

  1. 在 Studio 域中,启动 Studio data-scientist-dvc 用户。
  2. 选择 Git 图标,然后选择 克隆存储库.
    克隆存储库
  3. 输入存储库的 URL (https://github.com/aws-samples/amazon-sagemaker-experiments-dvc-demo)并选择 克隆.克隆回购按钮
  4. 在文件浏览器中,选择 amazon-sagemaker-experiments-dvc-demo 库。
  5. 打开 dvc_sagemaker_script_mode.ipynb 笔记本电脑。
  6. 针对 自定义图像,选择镜像 conda-env-dvc-kernel。
  7. 选择.
    conda-env-dvc-内核

配置 DVC 以进行数据版本控制

我们创建一个子目录,用于准备数据:sagemaker-dvc-sample。在此子目录中,我们初始化一个新的 Git 存储库并将远程设置为我们在其中创建的存储库 AWS 代码提交。目标是在此存储库中对用于数据跟踪的 DVC 配置和文件进行版本控制。但是,Git 提供了通过 git 子模块和 git 子树等管理子项目的本机功能,您可以扩展此示例以使用最适合您的工作流程的任何上述工具。

在我们的案例中,将 CodeCommit 与 SageMaker 结合使用的主要优点是它与 AWS身份和访问管理 (IAM) 用于身份验证和授权,这意味着我们可以使用 IAM 角色来推送和拉取数据,而无需获取凭证(或 SSH 密钥)。对 SageMaker 执行角色设置适当的权限还允许 Studio 笔记本以及 SageMaker 训练和处理作业与 CodeCommit 安全交互。

尽管您可以将 CodeCommit 替换为任何其他源代码控制服务(例如 GitHub、Gitlab 或 Bitbucket),但您需要考虑如何处理系统的凭据。一种可能性是将这些凭据存储在 AWS机密管理器 并在运行时从 Studio 笔记本以及 SageMaker 处理和训练作业中获取它们。

初始化DVC

使用 DVC 和 SageMaker 进行处理和训练

在本节中,我们将探索两种不同的方法来解决我们的问题,以及如何根据我们之前向您展示的高级概念架构,使用 SageMaker Experiments 跟踪这两个测试。

设置 SageMaker 实验

为了在 SageMaker 中跟踪此测试,我们需要创建一个实验。我们还需要在实验中定义试验。为了简单起见,我们只考虑一次试验,但您可以在一个实验中进行任意数量的试验,例如,如果您想测试不同的算法。

我们创建一个名为 DEMO-sagemaker-experiments-dvc 经过两次试验, dvc-trial-single-filedvc-trial-multi-files,每个代表数据集的不同版本。

让我们创建 DEMO-sagemaker-experiments-dvc 实验:

from smexperiments.experiment import Experiment
from smexperiments.trial import Trial
from smexperiments.trial_component import TrialComponent
from smexperiments.tracker import Tracker

experiment_name = 'DEMO-sagemaker-experiments-dvc'

# create the experiment if it doesn't exist
try:
    my_experiment = Experiment.load(experiment_name=experiment_name)
    print("existing experiment loaded")
except Exception as ex:
    if "ResourceNotFound" in str(ex):
        my_experiment = Experiment.create(
            experiment_name = experiment_name,
            description = "How to integrate DVC"
        )
        print("new experiment created")
    else:
        print(f"Unexpected {ex}=, {type(ex)}")
        print("Dont go forward!")
        raise

测试 1:生成用于训练和验证的单个文件

在本节中,我们创建一个处理脚本,直接从 亚马逊简单存储服务 (Amazon S3)作为输入;对其进行处理以创建训练、验证和测试数据集;并使用 DVC 将结果存储回 Amazon S3。此外,我们还将展示如何在运行处理和训练作业时以及通过 SageMaker Experiments 跟踪 DVC 使用 SageMaker 生成的输出工件。

首先,我们创建 dvc-trial-single-file 试用并将其添加到 DEMO-sagemaker-experiments-dvc 实验。通过这样做,我们可以以有意义的方式组织与此测试相关的所有试验组件。

first_trial_name = "dvc-trial-single-file"

try:
    my_first_trial = Trial.load(trial_name=first_trial_name)
    print("existing trial loaded")
except Exception as ex:
    if "ResourceNotFound" in str(ex):
        my_first_trial = Trial.create(
            experiment_name=experiment_name,
            trial_name=first_trial_name,
        )
        print("new trial created")
    else:
        print(f"Unexpected {ex}=, {type(ex)}")
        print("Dont go forward!")
        raise

在 SageMaker 处理作业中使用 DVC 创建单个文件版本

在本节中,我们创建一个处理脚本,使用 SageMaker 的托管数据加载功能直接从 Amazon S3 获取原始数据作为输入;对其进行处理以创建训练、验证和测试数据集;并使用 DVC 将结果存储回 Amazon S3。非常重要的是要了解,当使用 DVC 将数据存储到 Amazon S3(或从 Amazon S3 提取数据)时,我们将失去 SageMaker 托管数据加载功能,这可能会对我们的处理和训练作业的性能和成本产生影响,尤其是在处理非常大的数据集时。有关不同 SageMaker 本机输入模式功能的更多信息,请参阅 访问培训数据.

最后,当通过 SageMaker Experiments 运行处理作业时,我们将 DVC 跟踪功能与 SageMaker 跟踪功能统一起来。

处理脚本需要 Git 存储库的地址以及我们要创建的分支来存储通过环境变量传递的 DVC 元数据。数据集本身由 DVC 存储在 Amazon S3 中。尽管环境变量在 SageMaker Experiments 中自动跟踪并在试验组件参数中可见,但我们可能希望用更多信息来丰富试验组件,然后使用跟踪器对象在 Studio UI 中进行可视化。在我们的例子中,试验组件参数包括以下内容:

  • DVC_REPO_URL
  • DVC_BRANCH
  • USER
  • data_commit_hash
  • train_test_split_ratio

预处理脚本克隆Git存储库;生成训练、验证和测试数据集;并使用 DVC 进行同步。如前所述,使用 DVC 时,我们无法利用本机 SageMaker 数据加载功能。除了我们在大型数据集上可能遭受的性能损失之外,我们还失去了输出工件的自动跟踪功能。然而,借助跟踪器和 DVC Python API,我们可以弥补这些缺点,在运行时检索此类信息,并将其存储在试用组件中,而无需花费太多精力。这样做的附加值是可以在单一视图中查看属于该特定处理作业的输入和输出工件。

完整的预处理 Python 脚本可在 GitHub回购.

with Tracker.load() as tracker:
    tracker.log_parameters({"data_commit_hash": commit_hash})
    for file_type in file_types:
        path = dvc.api.get_url(
            f"{data_path}/{file_type}/california_{file_type}.csv",
            repo=dvc_repo_url,
            rev=dvc_branch
        )
        tracker.log_output(name=f"california_{file_type}",value=path)

SageMaker 使我们能够在 AWS 管理的容器映像上运行处理脚本,这些映像经过优化可在 AWS 基础设施上运行。如果我们的脚本需要额外的依赖项,我们可以提供 requirements.txt 文件。当我们开始处理作业时,SageMaker 使用 pip-install 安装我们需要的所有库(例如,DVC相关库)。如果您需要对容器上安装的所有库进行更严格的控制,您可以在 SageMaker 中引入自己的容器,例如 处理 和培训。

我们现在拥有运行 SageMaker 处理作业的所有要素:

  • 可以处理多个参数的处理脚本(--train-test-split-ratio)和两个环境变量(DVC_REPO_URLDVC_BRANCH)
  • A requiremets.txt 文件
  • Git 存储库(在 CodeCommit 中)
  • SageMaker 实验和试用
from sagemaker.processing import FrameworkProcessor, ProcessingInput
from sagemaker.sklearn.estimator import SKLearn

dvc_repo_url = "codecommit::{}://sagemaker-dvc-sample".format(region)
dvc_branch = my_first_trial.trial_name

script_processor = FrameworkProcessor(
    estimator_cls=SKLearn,
    framework_version='0.23-1',
    instance_count=1,
    instance_type='ml.m5.xlarge',
    env={
        "DVC_REPO_URL": dvc_repo_url,
        "DVC_BRANCH": dvc_branch,
        "USER": "sagemaker"
    },
    role=role
)

experiment_config={
    "ExperimentName": my_experiment.experiment_name,
    "TrialName": my_first_trial.trial_name
}

然后我们运行处理作业 preprocessing-experiment.py 脚本, experiment_config, dvc_repo_urldvc_branch 我们之前定义过。

%%time

script_processor.run(
    code='./source_dir/preprocessing-experiment.py',
    dependencies=['./source_dir/requirements.txt'],
    inputs=[ProcessingInput(source=s3_data_path, destination="/opt/ml/processing/input")],
    experiment_config=experiment_config,
    arguments=["--train-test-split-ratio", "0.2"]
)

处理作业大约需要 5 分钟才能完成。现在您可以查看单个文件数据集的试验详细信息。

以下屏幕截图显示了您可以在 Studio 中找到存储的信息的位置。请注意以下值 dvc-trial-single-file in DVC_BRANCH, DVC_REPO_URLdata_commit_hash参数 标签。

SageMaker 实验参数选项卡

另请注意输入和输出的详细信息 文物 标签。

SageMaker 实验工件选项卡

创建估计器并使用单个文件数据版本拟合模型

要在 SageMaker 训练作业中使用 DVC 集成,我们传递一个 dvc_repo_urldvc_branch 创建 Estimator 对象时作为环境变量。

我们训练于 dvc-trial-single-file 先分行。

使用DVC拉取数据时,我们使用以下数据集结构:

dataset
    |-- train
    |   |-- california_train.csv
    |-- test
    |   |-- california_test.csv
    |-- validation
    |   |-- california_validation.csv

现在我们使用以下命令创建一个 Scikit-learn 估计器 SageMaker Python 开发工具包。这允许我们指定以下内容:

  • Python 源文件的路径,应作为训练的入口点运行。
  • 控制访问 Amazon S3 和 CodeCommit 数据以及运行 SageMaker 函数的权限的 IAM 角色。
  • 定义用于评估训练作业的指标的字典列表。
  • 训练实例的数量和类型。我们使用一个 ml.m5.large 实例。
  • 用于训练的超参数。
  • 训练作业期间使用的环境变量。我们用 DVC_REPO_URL, DVC_BRANCHUSER.
metric_definitions = [{'Name': 'median-AE', 'Regex': "AE-at-50th-percentile: ([0-9.]+).*$"}]

hyperparameters={ 
        "learning_rate" : 1,
        "depth": 6
    }
estimator = SKLearn(
    entry_point='train.py',
    source_dir='source_dir',
    role=role,
    metric_definitions=metric_definitions,
    hyperparameters=hyperparameters,
    instance_count=1,
    instance_type='ml.m5.large',
    framework_version='0.23-1',
    base_job_name='training-with-dvc-data',
    environment={
        "DVC_REPO_URL": dvc_repo_url,
        "DVC_BRANCH": dvc_branch,
        "USER": "sagemaker"
    }
)

experiment_config={
    "ExperimentName": my_experiment.experiment_name,
    "TrialName": my_first_trial.trial_name
}

我们使用之前定义的experiment_config调用Estimator的fit方法来开始训练。

%%time
estimator.fit(experiment_config=experiment_config)

训练作业大约需要 5 分钟才能完成。日志显示这些行,指示 DVC 提取的文件:

Running dvc pull command
A       train/california_train.csv
A       test/california_test.csv
A       validation/california_validation.csv
3 files added and 3 files fetched
Starting the training.
Found train files: ['/opt/ml/input/data/dataset/train/california_train.csv']
Found validation files: ['/opt/ml/input/data/dataset/train/california_train.csv']

测试 2:生成多个文件用于训练和验证

我们创建一个新的 dvc-trial-multi-files 试用并将其添加到当前 DEMO-sagemaker-experiments-dvc 实验。

second_trial_name = "dvc-trial-multi-files"
try:
    my_second_trial = Trial.load(trial_name=second_trial_name)
    print("existing trial loaded")
except Exception as ex:
    if "ResourceNotFound" in str(ex):
        my_second_trial = Trial.create(
            experiment_name=experiment_name,
            trial_name=second_trial_name,
        )
        print("new trial created")
    else:
        print(f"Unexpected {ex}=, {type(ex)}")
        print("Dont go forward!")
        raise

与第一个处理脚本不同,我们现在从原始数据集创建多个文件用于训练和验证,并将 DVC 元数据存储在不同的分支中。

您可以探索第二个预处理 Python 脚本 GitHub上.

%%time

script_processor.run(
    code='./source_dir/preprocessing-experiment-multifiles.py',
    dependencies=['./source_dir/requirements.txt'],
    inputs=[ProcessingInput(source=s3_data_path, destination="/opt/ml/processing/input")],
    experiment_config=experiment_config,
    arguments=["--train-test-split-ratio", "0.1"]
)

处理作业大约需要 5 分钟才能完成。现在您可以查看多文件数据集的试验详细信息。

以下屏幕截图显示了您可以在 SageMaker Experiments 中的何处找到存储的信息 试用组件 Studio UI 中的部分。请注意以下值 dvc-trial-multi-files in DVC_BRANCH, DVC_REPO_URLdata_commit_hash参数 标签。

SageMaker 多文件实验参数选项卡

您还可以查看输入和输出详细信息 文物 标签。

SageMaker 多文件实验工件选项卡

我们现在训练 dvc-trial-multi-files 分支。使用DVC拉取数据时,我们使用以下数据集结构:

dataset
    |-- train
    |   |-- california_train_1.csv
    |   |-- california_train_2.csv
    |   |-- california_train_3.csv
    |   |-- california_train_4.csv
    |   |-- california_train_5.csv
    |-- test
    |   |-- california_test.csv
    |-- validation
    |   |-- california_validation_1.csv
    |   |-- california_validation_2.csv
    |   |-- california_validation_3.csv

与之前类似,我们使用试验名称创建一个新的 Scikit-learn Estimator dvc-trial-multi-files 并开始训练工作。

%%time

estimator.fit(experiment_config=experiment_config)

训练作业大约需要 5 分钟才能完成。在输出到笔记本的训练作业日志中,您可以看到这些行,指示 DVC 拉取的文件:

Running dvc pull command
A       validation/california_validation_2.csv
A       validation/california_validation_1.csv
A       validation/california_validation_3.csv
A       train/california_train_4.csv
A       train/california_train_5.csv
A       train/california_train_2.csv
A       train/california_train_3.csv
A       train/california_train_1.csv
A       test/california_test.csv
9 files added and 9 files fetched
Starting the training.
Found train files: ['/opt/ml/input/data/dataset/train/california_train_2.csv', '/opt/ml/input/data/dataset/train/california_train_5.csv', '/opt/ml/input/data/dataset/train/california_train_4.csv', '/opt/ml/input/data/dataset/train/california_train_1.csv', '/opt/ml/input/data/dataset/train/california_train_3.csv']
Found validation files: ['/opt/ml/input/data/dataset/validation/california_validation_2.csv', '/opt/ml/input/data/dataset/validation/california_validation_1.csv', '/opt/ml/input/data/dataset/validation/california_validation_3.csv']

在 SageMaker 中托管您的模型

训练 ML 模型后,您可以使用 SageMaker 进行部署。为了部署一个持久的、实时的端点来一次做出一个预测,我们使用 SageMaker 实时托管服务.

from sagemaker.serializers import CSVSerializer

predictor = estimator.deploy(1, "ml.t2.medium", serializer=CSVSerializer())

首先,我们在 Studio 的开发笔记本上本地获取最新的测试数据集。为此,我们可以使用 dvc.api.read() 加载 SageMaker 处理作业存储在 Amazon S3 中的原始数据。

import io
import dvc.api

raw = dvc.api.read(
    "dataset/test/california_test.csv",
    repo=dvc_repo_url,
    rev=dvc_branch
)

然后我们使用 Pandas 准备数据,加载测试 CSV 文件,并调用 predictor.predict 使用数据调用之前创建的 SageMaker 端点并获取预测。

test = pd.read_csv(io.StringIO(raw), sep=",", header=None)
X_test = test.iloc[:, 1:].values
y_test = test.iloc[:, 0:1].values

predicted = predictor.predict(X_test)
for i in range(len(predicted)-1):
    print(f"predicted: {predicted[i]}, actual: {y_test[i][0]}")

删除端点

您应该在端点不再使用时将其删除,因为它们是按部署时间计费的(有关更多信息,请参阅 Amazon SageMaker定价)。请务必删除端点以避免意外成本。

predictor.delete_endpoint()

清理

在删除您创建的所有资源之前,请确保所有应用程序均已从 data-scientist-dvc 用户,包括所有 KernelGateway 应用程序以及默认的 JupiterServer 应用程序。

然后,您可以通过运行以下命令销毁 AWS CDK 堆栈:

cdk destroy

如果您使用现有域,还需运行以下命令:

# inject your DOMAIN_ID into the configuration file
sed -i 's/<your-sagemaker-studio-domain-id>/'"$DOMAIN_ID"'/' ../update-domain-no-custom-images.json
# update the sagemaker studio domain
aws --region ${REGION} sagemaker update-domain --cli-input-json file://../update-domain-no-custom-images.json

结论

在这篇文章中,您演练了一个示例,了解如何将 SageMaker 实验以及 SageMaker 处理和训练作业与 DVC 结合使用,跨代码、数据、工件和指标跟踪实验。我们创建了一个包含 DVC 的 Docker 映像,这是 Studio 作为开发笔记本所需的,并展示了如何通过 DVC 使用处理和训练作业。我们准备了两个版本的数据,并使用DVC和Git进行管理。然后,您使用 SageMaker Experiments 跟踪两个版本数据的处理和训练,以便在单一管理平台中获得参数、工件和指标的统一视图。最后,您将模型部署到 SageMaker 终端节点,并使用第二个数据集版本中的测试数据集来调用 SageMaker 终端节点并获取预测。

下一步,您可以扩展现有笔记本并引入您自己的特征工程策略,并使用 DVC 和 SageMaker 来运行您的实验。我们去建造吧!

如需进一步阅读,请参阅以下资源:


作者简介

保罗·迪·弗朗切斯科保罗·迪·弗朗切斯科 是 AWS 的解决方案架构师。 他在电信和软件工程方面拥有丰富的经验。 他对机器学习充满热情,目前专注于利用他的经验帮助客户在 AWS 上实现目标,特别是在围绕 MLOps 的讨论中。 工作之余,他喜欢踢足球和阅读。

埃坦·塞拉(Eitan Sela)埃坦·塞拉(Eitan Sela) 是 Amazon Web Services 的机器学习专家解决方案架构师。 他与 AWS 客户合作,提供指导和技术援助,帮助他们在 AWS 上构建和运行机器学习解决方案。 在业余时间,Eitan 喜欢慢跑和阅读最新的机器学习文章。

时间戳记:

更多来自 AWS机器学习