人工智能(AI)已成为科技界的一个重要且热门的话题。 随着人工智能的发展,我们看到了不同类型的机器学习 (ML) 模型的出现。 一种方法称为 集成建模,已迅速受到数据科学家和从业者的关注。 在这篇文章中,我们讨论什么是集成模型以及为什么它们的使用是有益的。 然后,我们提供了一个示例,说明如何使用以下方法训练、优化和部署自定义集成: 亚马逊SageMaker.
集成学习是指使用多种学习模型和算法来获得比任何单个单独学习算法更准确的预测。 事实证明,它们在各种应用和学习环境中都非常高效,例如网络安全 [1] 和欺诈检测、遥感、预测金融决策、医疗诊断,甚至计算机视觉和自然语言处理 (NLP) 中的最佳后续步骤任务。 我们倾向于根据用于训练它们的技术、它们的组成以及它们将不同的预测合并为单个推理的方式对集合进行分类。 这些类别包括:
- 提高 – 按顺序训练多个弱学习器,其中序列中先前学习器的每个错误预测都会被赋予更高的权重并输入给下一个学习器,从而创建更强的学习器。 示例包括 AdaBoost、梯度提升和 XGBoost。
- 套袋 – 使用多个模型来减少单个模型的方差。 示例包括随机森林和额外树。
- 堆叠(混合) – 通常使用异构模型,其中每个估计器的预测堆叠在一起并用作处理预测的最终估计器的输入。 这个最终估计器的训练过程通常使用交叉验证。
有多种方法可以将预测组合成模型最终生成的单个预测,例如,使用线性学习器等元估计器、使用多个模型基于分类任务的多数投票进行预测的投票方法,或回归的集成平均。
尽管一些库和框架提供了集成模型的实现,例如 XGBoost、CatBoost 或 scikit-learn 的随机森林,但在本文中,我们重点关注引入您自己的模型并将它们用作堆叠集成。 然而,我们不是为每个模型使用专用资源(专用训练和调优作业以及每个模型的托管端点),而是使用单个 SageMaker 训练作业和单个调优作业来训练、调优和部署自定义集成(多个模型),然后部署到单个端点,从而降低可能的成本和运营开销。
BYOE:带上你自己的乐团
使用 SageMaker 训练和部署异构集成模型有多种方法:您可以在一个模型中训练每个模型。 单独的训练工作 并使用分别优化每个模型 Amazon SageMaker 自动模型调整。 托管这些模型时,SageMaker 提供了各种经济高效的方法来在同一租户基础设施上托管多个模型。 此类设置的详细部署模式可以在 Amazon SageMaker 中的模型托管模式,第 1 部分:在 Amazon SageMaker 上构建 ML 应用程序的常见设计模式。 这些模式包括使用多个端点(对于每个经过训练的模型)或单个端点 多模型端点,甚至单个 多容器端点 其中容器可以单独调用或链接在管道中。 所有这些解决方案都包含一个元估计器(例如在 AWS Lambda 函数)调用每个模型并实现混合或投票函数。
但是,运行多个训练作业可能会带来运营和成本开销,特别是当您的集成需要对相同数据进行训练时。 同样,在单独的端点或容器上托管不同的模型并组合其预测结果以获得更高的准确性需要多次调用,因此会引入额外的管理、成本和监控工作。 例如,SageMaker 支持 使用 Triton Inference Server 的集成 ML 模型,但此解决方案需要 Triton 后端支持模型或模型集成。 此外,客户还需要付出额外的努力来设置 Triton 服务器,并进行额外的学习以了解不同的 Triton 后端如何工作。 因此,客户更喜欢以更直接的方式来实施解决方案,他们只需将调用发送到端点一次,并可以灵活地控制如何聚合结果以生成最终输出。
解决方案概述
为了解决这些问题,我们通过一个使用单个训练作业进行集成训练的示例,优化模型的超参数并使用单个容器将其部署到无服务器端点。 我们的集成堆栈使用两种模型:CatBoost 和 XGBoost(两者都是增强集成)。 对于我们的数据,我们使用 糖尿病数据集 [2] 来自 scikit-learn 库:它由 10 个特征(年龄、性别、体重、血压和六种血清测量值)组成,我们的模型预测收集基线特征 1 年后的疾病进展(回归模型)。
完整的代码存储库可以在 GitHub上.
在单个 SageMaker 作业中训练多个模型
为了训练我们的模型,我们在脚本模式下使用 SageMaker 训练作业。 通过脚本模式,您可以在使用 SageMaker 框架容器时编写自定义训练(以及稍后的推理代码)。 框架容器使您能够使用由 AWS 管理的现成环境,其中包括所有必要的配置和模块。 为了演示如何自定义框架容器,作为示例,我们使用预构建的 SKLearn 容器,该容器不包含 XGBoost 和 CatBoost 包。 有两个选项可以添加这些包: 扩展内置容器 安装 CatBoost 和 XGBoost(然后部署为自定义容器),或使用 SageMaker 训练作业脚本模式功能,该功能允许您提供 requirements.txt
创建训练估计器时的文件。 SageMaker 训练作业将列出的库安装在 requirements.txt
运行时文件。 这样,您无需管理自己的 Docker 映像存储库,并且可以更灵活地运行需要额外 Python 包的训练脚本。
以下代码块显示了我们用于开始训练的代码。 这 entry_point
参数指向我们的训练脚本。 我们还使用 SageMaker SDK API 的两个引人注目的功能:
- 首先,我们在文件中指定源目录和依赖项的本地路径
source_dir
和dependencies
参数分别。 SDK会将这些目录压缩并上传到 亚马逊简单存储服务 (Amazon S3) 和 SageMaker 将在工作目录下的训练实例上提供它们/opt/ml/code
. - 二、我们使用SDK
SKLearn
estimator 对象具有我们首选的 Python 和框架版本,以便 SageMaker 拉取相应的容器。 我们还定义了一个自定义训练指标'validation:rmse
',这将在训练日志中发出并由 SageMaker 捕获。 稍后,我们在调优工作中使用该指标作为客观指标。
hyperparameters = {"num_round": 6, "max_depth": 5}
estimator_parameters = {
"entry_point": "multi_model_hpo.py",
"source_dir": "code",
"dependencies": ["my_custom_library"],
"instance_type": training_instance_type,
"instance_count": 1,
"hyperparameters": hyperparameters,
"role": role,
"base_job_name": "xgboost-model",
"framework_version": "1.0-1",
"keep_alive_period_in_seconds": 60,
"metric_definitions":[
{'Name': 'validation:rmse', 'Regex': 'validation-rmse:(.*?);'}
]
}
estimator = SKLearn(**estimator_parameters)
接下来,我们编写训练脚本(multi_model_hpo.py)。 我们的脚本遵循一个简单的流程: 捕获超参数 作业的配置和 训练 CatBoost 模型 和 XGBoost 模型。 我们还实施了 k折交叉 验证功能。 请看下面的代码:
if __name__ == "__main__":
parser = argparse.ArgumentParser() # Sagemaker specific arguments. Defaults are set in the environment variables.
parser.add_argument("--output-data-dir", type=str, default=os.environ["SM_OUTPUT_DATA_DIR"])
parser.add_argument("--model-dir", type=str, default=os.environ["SM_MODEL_DIR"])
parser.add_argument("--train", type=str, default=os.environ["SM_CHANNEL_TRAIN"])
parser.add_argument("--validation", type=str, default=os.environ["SM_CHANNEL_VALIDATION"])
.
.
.
"""
Train catboost
"""
K = args.k_fold
catboost_hyperparameters = {
"max_depth": args.max_depth,
"eta": args.eta,
}
rmse_list, model_catboost = cross_validation_catboost(train_df, K, catboost_hyperparameters)
.
.
.
"""
Train the XGBoost model
""" hyperparameters = {
"max_depth": args.max_depth,
"eta": args.eta,
"objective": args.objective,
"num_round": args.num_round,
} rmse_list, model_xgb = cross_validation(train_df, K, hyperparameters)
模型训练完毕后,我们计算 CatBoost 和 XGBoost 预测的平均值。 结果, pred_mean
,是我们整体的最终预测。 然后,我们确定 mean_squared_error
针对验证集。 val_rmse
用于训练期间整个集成的评估。 请注意,我们还以适合我们在中使用的正则表达式的模式打印 RMSE 值 metric_definitions
。 稍后,SageMaker 自动模型调整将使用它来捕获客观指标。 请看下面的代码:
pred_mean = np.mean(np.array([pred_catboost, pred_xgb]), axis=0)
val_rmse = mean_squared_error(y_validation, pred_mean, squared=False)
print(f"Final evaluation result: validation-rmse:{val_rmse}")
最后,我们的脚本将两个模型工件保存到位于以下位置的输出文件夹中: /opt/ml/model
.
训练作业完成后,SageMaker 会打包并复制训练作业的内容 /opt/ml/model
目录作为压缩 TAR 格式的单个对象复制到您在作业配置中指定的 S3 位置。 在我们的示例中,SageMaker 将两个模型捆绑在一个 TAR 文件中,并在训练作业结束时将其上传到 Amazon S3。 请看下面的代码:
model_file_name = 'catboost-regressor-model.dump'
# Save CatBoost model
path = os.path.join(args.model_dir, model_file_name)
print('saving model file to {}'.format(path))
model.save_model(path)
.
.
.
# Save XGBoost model
model_location = args.model_dir + "/xgboost-model"
pickle.dump(model, open(model_location, "wb"))
logging.info("Stored trained model at {}".format(model_location))
总之,您应该注意到,在此过程中,我们下载了一次数据并使用单个训练作业训练了两个模型。
自动集成模型调整
由于我们正在构建 ML 模型的集合,因此探索所有可能的超参数排列是不切实际的。 SageMaker 优惠 自动模型调整 (AMT),它通过关注您指定范围内最有希望的值组合来寻找最佳模型超参数(由您定义要探索的正确范围)。 SageMaker 支持多种优化方法 为您选择。
我们首先定义优化过程的两个部分:目标指标和我们想要调整的超参数。 在我们的示例中,我们使用验证 RMSE 作为目标指标,并调整 eta
和 max_depth
(其他超参数请参考 XGBoost超参数 和 CatBoost 超参数):
from sagemaker.tuner import (
IntegerParameter,
ContinuousParameter,
HyperparameterTuner,
) hyperparameter_ranges = {
"eta": ContinuousParameter(0.2, 0.3),
"max_depth": IntegerParameter(3, 4)
}
metric_definitions = [{"Name": "validation:rmse", "Regex": "validation-rmse:([0-9.]+)"}]
objective_metric_name = "validation:rmse"
我们还需要确保 训练脚本 我们的超参数不是硬编码的,而是从 SageMaker 运行时参数中提取的:
catboost_hyperparameters = {
"max_depth": args.max_depth,
"eta": args.eta,
}
SageMaker 还将超参数写入 JSON 文件并可从中读取 /opt/ml/input/config/hyperparameters.json
在训练实例上。
与 CatBoost 一样,我们也捕获 XGBoost 模型的超参数(请注意 objective
和 num_round
未调整):
catboost_hyperparameters = {
"max_depth": args.max_depth,
"eta": args.eta,
}
最后,我们使用这些配置启动超参数调整作业:
tuner = HyperparameterTuner(
estimator,
objective_metric_name,
hyperparameter_ranges,
max_jobs=4,
max_parallel_jobs=2,
objective_type='Minimize'
)
tuner.fit({"train": train_location, "validation": validation_location}, include_cls_metadata=False)
作业完成后,您可以检索最佳训练作业的值(具有最小 RMSE):
job_name=tuner.latest_tuning_job.name
attached_tuner = HyperparameterTuner.attach(job_name)
attached_tuner.describe()["BestTrainingJob"]
有关 AMT 的更多信息,请参阅 使用 SageMaker 执行自动模型调整.
部署
要部署自定义集成,我们需要提供一个脚本来处理推理请求并配置 SageMaker 托管。 在此示例中,我们使用了一个包含训练和推理代码的文件(multi_model_hpo.py)。 SageMaker 使用 if 下的代码 _ name _ == "_ main _"
用于培训和职能 model_fn
, input_fn
及 predict_fn
部署和服务模型时。
推理脚本
与训练一样,我们使用 SageMaker SKLearn 框架容器和我们自己的推理脚本。 该脚本将实现 SageMaker 所需的三种方法。
首先, model_fn
方法读取我们保存的模型工件文件并将它们加载到内存中。 在我们的例子中,该方法将我们的集合返回为 all_model
,这是一个 Python 列表,但您也可以使用以模型名称作为键的字典。
def model_fn(model_dir):
catboost_model = CatBoostRegressor()
catboost_model.load_model(os.path.join(model_dir, model_file_name))
model_file = "xgboost-model"
model = pickle.load(open(os.path.join(model_dir, model_file), "rb"))
all_model = [catboost_model, model]
return all_model
第二,该 input_fn
方法反序列化要传递给我们的推理处理程序的请求输入数据。 有关输入处理程序的更多信息,请参阅 调整您自己的推理容器.
def input_fn(input_data, content_type):
dtype=None
payload = StringIO(input_data)
return np.genfromtxt(payload, dtype=dtype, delimiter=",")
第三,该 predict_fn
方法负责从模型中获取预测。 该方法采用模型和从返回的数据 input_fn
作为参数并返回最终预测。 在我们的示例中,我们从模型列表第一个成员中获取 CatBoost 结果(model[0]
)和来自第二个成员的 XGBoost(model[1]
),我们使用一个混合函数返回两个预测的平均值:
def predict_fn(input_data, model):
predictions_catb = model[0].predict(input_data)
dtest = xgb.DMatrix(input_data)
predictions_xgb = model[1].predict(dtest,
ntree_limit=getattr(model, "best_ntree_limit", 0),
validate_features=False)
return np.mean(np.array([predictions_catb, predictions_xgb]), axis=0)
现在我们有了经过训练的模型和推理脚本,我们可以配置环境来部署我们的集成。
SageMaker 无服务器推理
虽然有 SageMaker 中有许多托管选项,在此示例中,我们使用无服务器端点。 无服务器端点自动启动计算资源并根据流量进行扩展和扩展。 这消除了管理服务器的繁重工作。 此选项非常适合在流量激增之间有空闲期并且可以容忍冷启动的工作负载。
配置无服务器端点非常简单,因为我们不需要选择实例类型或管理扩展策略。 我们只需要提供两个参数:内存大小和最大并发数。 无服务器端点自动分配与您选择的内存成比例的计算资源。 如果您选择更大的内存大小,您的容器可以访问更多的 vCPU。 您应始终根据型号大小选择端点的内存大小。 我们需要提供的第二个参数是最大并发数。 对于单个端点,此参数最多可设置为 200(截至撰写本文时,一个区域中无服务器端点的总数限制为 50)。 您应该注意,单个端点的最大并发数会阻止该端点占用您账户允许的所有调用,因为任何超出最大并发数的端点调用都会受到限制(有关每个区域的所有无服务器端点的总并发数的更多信息,请参阅 Amazon SageMaker终端节点和配额).
from sagemaker.serverless.serverless_inference_config import ServerlessInferenceConfig
serverless_config = ServerlessInferenceConfig(
memory_size_in_mb=6144,
max_concurrency=1,
)
现在我们配置了端点,我们终于可以部署在超参数优化作业中选择的模型了:
estimator=attached_tuner.best_estimator()
predictor = estimator.deploy(serverless_inference_config=serverless_config)
清理
尽管无服务器端点在不使用时的成本为零,但当您完成运行此示例时,您应该确保删除端点:
predictor.delete_endpoint(predictor.endpoint)
结论
在这篇文章中,我们介绍了一种训练、优化和部署自定义集成的方法。 我们详细介绍了使用单个训练作业训练多个模型的过程、如何使用自动模型调优来优化集成超参数,以及如何部署混合多个模型的推理的单个无服务器端点。
使用此方法可以解决潜在的成本和运营问题。 培训作业的成本取决于您在使用期间使用的资源。 通过仅下载一次数据来训练两个模型,我们将作业的数据下载阶段和存储数据的使用量减少了一半,从而降低了训练作业的总体成本。 此外,AMT 作业运行了四个训练作业,每个训练作业都减少了上述时间和存储空间,因此节省了 4 倍的成本! 对于无服务器端点上的模型部署,由于您还要按处理的数据量付费,因此两个模型仅调用一次端点,您只需支付一半的 I/O 数据费用。
尽管本文仅展示了两种模型的优势,但您可以使用此方法来训练、调整和部署大量集成模型,以看到更大的效果。
参考资料
[1] Raj Kumar,P. Arun; 塞尔瓦库马尔,S.(2011)。 “使用神经分类器集合进行分布式拒绝服务攻击检测”。 计算机通信。 34(11):1328-1341。 doi:10.1016/j.comcom.2011.01.012。
[2] Bradley Efron、Trevor Hastie、Iain Johnstone 和 Robert Tibshirani (2004)“最小角度回归”,统计年鉴(带讨论),407-499。 (https://web.stanford.edu/~hastie/Papers/LARS/LeastAngle_2002.pdf)
作者简介
李梅兰妮博士,是位于澳大利亚悉尼的 AWS 的高级 AI/ML 专家 TAM。 她帮助企业客户利用 AWS 上最先进的 AI/ML 工具构建解决方案,并提供有关使用最佳实践构建和实施机器学习解决方案的指导。 在业余时间,她喜欢到户外探索大自然,并与家人和朋友共度时光。
乌里·罗森博格 是欧洲、中东和非洲的人工智能和机器学习专家技术经理。 Uri 总部位于以色列,致力于帮助企业客户大规模设计、构建和运营 ML 工作负载。 在业余时间,他喜欢骑自行车、徒步旅行和最小化 RMSE。
- :具有
- :是
- :不是
- :在哪里
- ][p
- $UP
- 1
- 10
- 100
- 11
- 200
- 2011
- 50
- 60
- 7
- a
- 关于
- ACCESS
- 根据
- 账号管理
- 精准的
- 加
- 额外
- 另外
- 地址
- 非洲
- 后
- 驳
- 年龄
- AI
- AI / ML
- 算法
- 算法
- 所有类型
- 允许
- 允许
- 还
- 时刻
- Amazon
- 亚马逊SageMaker
- 亚马逊网络服务
- 其中
- 量
- an
- 和
- 任何
- 应用领域
- 的途径
- 保健
- 参数
- AS
- At
- 攻击
- 澳大利亚
- 自动表
- 自动
- 可使用
- 平均
- 远离
- AWS
- 后端
- 基于
- 底线
- BE
- 因为
- 成为
- 很
- 作为
- 有利
- 好处
- 最佳
- 最佳实践
- 更好
- 之间
- 超越
- 混纺
- 混纺
- 阻止
- 血液
- 血压
- 身体
- 提高
- 都
- 带来
- 瞻
- 建立
- 建筑物
- 内建的
- 捆绑
- 但是
- by
- 计算
- CAN
- 捕获
- 捕获
- 案件
- 类别
- 链接
- 收费
- 分类
- 码
- 冷
- 采集
- 组合
- 结合
- 相当常见
- 通信
- 社体的一部分
- 引人注目
- 完成
- 计算
- 一台
- 计算机视觉
- 关注
- 配置
- 配置
- 由
- 容器
- 集装箱
- 内容
- 控制
- 相应
- 价格
- 经济有效
- 覆盖
- 创造
- 习俗
- 顾客
- 合作伙伴
- 定制
- 网络安全
- data
- 决策
- 专用
- 默认
- 定义
- 定义
- 定义
- 演示
- 拒绝服务
- 根据
- 部署
- 部署
- 部署
- 设计
- 设计模式
- 详细
- 检测
- 确定
- 不同
- 目录
- 讨论
- 讨论
- 疾病
- 不同
- 码头工人
- 不会
- 别
- 下载
- 倾倒
- 为期
- ,我们将参加
- 每
- 东部
- 效果
- 高效
- 有效
- 工作的影响。
- 或
- 出现
- 授权
- enable
- 结束
- 端点
- 确保
- 企业
- 环境
- 环境中
- 特别
- 欧洲
- 评估
- 甚至
- 进化
- 例子
- 例子
- 探索
- 探索
- 额外
- 家庭
- 专栏
- 特征
- 文件
- 档
- 最后
- 终于
- 金融
- (名字)
- 高度灵活
- 流
- 专注焦点
- 聚焦
- 以下
- 如下
- 针对
- 森林
- 格式
- 发现
- 四
- 骨架
- 框架
- 骗局
- 欺诈检测
- 朋友
- 止
- ,
- 功能
- 功能
- 此外
- Gain增益
- 获得
- 生成
- 得到
- 越来越
- 特定
- 更大的
- 指导
- 半
- 处理
- 手柄
- 有
- he
- 重
- 举重
- 帮助
- 这里
- 更高
- 他的
- 主持人
- 托管
- 创新中心
- How To
- 但是
- HTML
- HTTP
- HTTPS
- 超参数优化
- 超参数调整
- 理想
- 空闲
- if
- 图片
- 实施
- 实施
- 器物
- 重要
- in
- 包括
- 包括
- 个人
- 个别地
- 信息
- 基础设施
- 输入
- 安装
- 例
- 代替
- 房源搜索
- 成
- 介绍
- 推出
- 调用
- 所调用
- 以色列
- 问题
- IT
- 工作
- 工作机会
- JPG
- JSON
- 键
- 类
- 已知
- 语言
- 大
- 后来
- 发射
- 学习
- 借力
- Li
- 库
- 自学资料库
- 翻新
- 极限
- 清单
- 已发布
- 负载
- 本地
- 位于
- 圖書分館的位置
- 记录
- LOOKS
- 爱
- 机
- 机器学习
- 主要
- 多数
- 使
- 管理
- 管理
- 颠覆性技术
- 经理
- 管理的
- 质量
- 最多
- 意味着
- 测量
- 医生
- 会员
- 内存
- 合并
- 方法
- 方法
- 公
- 中间
- 中东
- 可能
- 最小
- 最小化
- ML
- 时尚
- 模型
- 模型
- 模块
- 监控
- 更多
- 最先进的
- 多
- 姓名
- 名称
- 自然
- 自然语言处理
- 自然
- 必要
- 需求
- 下页
- NLP
- 注意..
- 数
- 众多
- 对象
- 目标
- of
- 优惠精选
- 经常
- on
- 一旦
- 一
- 仅由
- 操作
- 操作
- 优化
- 优化
- 追求项目的积极优化
- 附加选项
- 附加选项
- or
- OS
- 其他名称
- 我们的
- 输出
- 户外活动
- 产量
- 最划算
- 己
- 包
- 参数
- 参数
- 部分
- 部分
- 通过
- 径
- 模式
- 模式
- 为
- 期
- 相
- 管道
- 柏拉图
- 柏拉图数据智能
- 柏拉图数据
- 点
- 政策
- 热门
- 可能
- 帖子
- 潜力
- 做法
- 预测
- 预测
- 预测
- 预报器
- 预测
- 比较喜欢
- 首选
- 压力
- 防止
- 以前
- 打印
- 程序
- 过程
- 处理
- 处理
- 生产
- 级数
- 有希望
- 成熟
- 提供
- 提供
- 蟒蛇
- 随机
- 急速
- 阅读
- 减少
- 减少
- 减少
- 指
- 视
- 正则表达式
- 地区
- 远程
- 知识库
- 代表
- 请求
- 必须
- 需要
- 资源
- 分别
- 提供品牌战略规划
- 导致
- 成果
- 回报
- 回报
- 右
- ROBERT
- 角色
- 运行
- 运行
- s
- sagemaker
- SageMaker 自动模型调整
- 同
- 保存
- 保存
- 鳞片
- 缩放
- 科学家
- scikit学习
- 脚本
- SDK
- 其次
- 看到
- 看到
- 选
- 提交
- 前辈
- 分开
- 序列
- 精華
- 无服务器
- 服务器
- 服务
- 特色服务
- 服务
- 集
- 设置
- 几个
- 性生活
- 她
- 应该
- 显示
- 作品
- 同样
- 简易
- 单
- SIX
- 尺寸
- So
- 方案,
- 解决方案
- 解决
- 来源
- 专家
- 具体的
- 指定
- 花
- 堆
- 堆叠
- 堆叠
- 斯坦福
- 开始
- 启动
- 国家的最先进的
- 统计
- 步骤
- 存储
- 存储
- 商店
- 简单的
- 强
- 这样
- 概要
- 支持
- 支持
- 肯定
- 悉尼
- 需要
- 服用
- 目标
- 任务
- 文案
- 技术
- 专业技术
- 承租人
- 比
- 这
- 其
- 他们
- 然后
- 那里。
- 从而
- 因此
- 博曼
- 他们
- Free Introduction
- 那些
- 虽然?
- 三
- 通过
- 次
- 时
- 至
- 一起
- 工具
- 主题
- 合计
- 牵引
- 交通
- 培训
- 熟练
- 产品培训
- 树
- 特雷弗
- 海卫一
- 二
- 类型
- 下
- 理解
- 用法
- 使用
- 用过的
- 使用
- 运用
- 验证
- 折扣值
- 价值观
- 各个
- 版本
- 愿景
- 体积
- 表决
- 想
- 是
- 方法..
- 方法
- we
- 卷筒纸
- Web服务
- 重量
- 为
- 什么是
- ,尤其是
- 这
- 而
- 全
- 为什么
- 将
- 中
- 工作
- 加工
- 合作
- 写
- 写作
- XGBoost
- 年
- 完全
- 您一站式解决方案
- 和风网
- 零