使用半监督学习为结构化数据训练更好的深度学习模型
利用未标记的样本来提高神经网络的性能。
众所周知,深度学习在应用于文本、音频或图像等非结构化数据时效果很好,但在应用于结构化或表格数据时,有时会落后于梯度增强等其他机器学习方法。
在这篇文章中,我们将使用半监督学习来提高深度神经模型在低数据区应用于结构化数据时的性能。我们将展示,通过使用无监督的预训练,我们可以使神经模型的性能优于梯度推进。
这篇文章基于两篇论文:
我们实现了一个深度神经架构,类似于 AutoInt 论文中介绍的内容,我们使用多头自我关注和特征嵌入。预训练部分摘自 Tabnet 论文。
方法描述:
我们将研究结构化数据,即可以写成包含列(数字、分类、序数)和行的表格的数据。我们还假设我们有大量的未标记样本可以用于预训练,少量的标记样本可以用于监督学习。在接下来的实验中,我们将模拟这个设置来绘制学习曲线,并在使用不同大小的标记集时评估该方法。
数据准备:
让我们用一个例子来描述我们如何在将数据输入神经网络之前准备数据。
在本例中,我们有三个样本和三个特征{ F1 、 F2 、 F3 },以及一个目标。 F1 为分类特征,而 F2 和 F3 为数值特征。
我们将为 F1 的每个模态 X 创建一个新特征 F1_X ,如果 F1 == X 为 1,否则为 0。
转换后的样本将被写入一组(特征名,特征值)。
例如:
第一个样本- > {( F1_A ,1)、( F2 ,0.3)、( F3 【T10,1.3)}
第二个样本- > {( F1_B ,1)、( F2 ,0.4)、( F3 ,0.9)}
第三个样本- >
特征名称将被送入嵌入层,然后与特征值相乘。
型号:
这里使用的模型是一系列多头注意力块和逐点前馈层。在训练时,我们也使用注意力集中跳过连接。多头注意力块允许我们对特征之间可能存在的交互进行建模,而注意力集中跳过连接允许我们从特征嵌入集合中获得单个向量。
简化模型-作者图片
预训练:
在预训练步骤中,我们使用完整的未标记数据集,我们输入特征的损坏版本,并训练模型来预测未损坏的特征,类似于在去噪自动编码器中所做的。
监督训练:
在训练的监督部分,我们在编码器部分和输出之间添加跳过连接,并尝试预测目标。
简化模型-作者图片
实验:
在下面的实验中,我们将使用四个数据集,两个用于回归,两个用于分类。
- Sarco :约有 50k 个样本,21 个特征,7 个连续目标。
- 在线新闻:约有 40k 个样本,61 个特征,1 个连续目标。
- 成人普查:约有 40k 个样本,15 个特征,1 个二元目标。
- 森林覆盖:约有 50 万个样本,54 个特征,1 个分类目标。
我们将比较预先训练的神经模型和从零开始训练的神经模型,我们将关注低数据状态下的性能,这意味着几百到几千个标记样本。我们还将与一种流行的梯度增强实现进行比较,这种实现叫做 lightgbm 。
森林覆盖:
成人人口普查:
对于这个数据集,我们可以看到,如果训练集小于 2000,预训练是非常有效的。
在线新闻:
对于在线新闻数据集,我们可以看到预训练神经网络非常有效,甚至超过了所有样本大小 500 或更大的梯度提升。
对于 Sarco 数据集,我们可以看到预训练神经网络非常有效,甚至超过了所有样本大小的梯度提升。
附注:重现结果的代码
重现结果的代码可从这里获得:https://github.com/CVxTz/DeepTabular
使用它你可以很容易地训练一个分类或回归模型->
**import** pandas **as** pd
**from** sklearn.model_selection **import** train_test_split**from** deeptabular.deeptabular **import** DeepTabularClassifier**if** __name__ == **"__main__"**:
data = pd.read_csv(**"../data/census/adult.csv"**) train, test = train_test_split(data, test_size=0.2, random_state=1337) target = **"income"**num_cols = [**"age"**, **"fnlwgt"**, **"capital.gain"**, **"capital.loss"**, **"hours.per.week"**]
cat_cols = [
**"workclass"**,
**"education"**,
**"education.num"**,
**"marital.status"**,
**"occupation"**,
**"relationship"**,
**"race"**,
**"sex"**,
**"native.country"**,
] **for** k **in** num_cols:
mean = train[k].mean()
std = train[k].std()
train[k] = (train[k] - mean) / std
test[k] = (test[k] - mean) / std train[target] = train[target].map({**"<=50K"**: 0, **">50K"**: 1})
test[target] = test[target].map({**"<=50K"**: 0, **">50K"**: 1}) classifier = DeepTabularClassifier(
num_layers=10, cat_cols=cat_cols, num_cols=num_cols, n_targets=1,
) classifier.fit(train, target_col=target, epochs=128) pred = classifier.predict(test) classifier.save_config(**"census_config.json"**)
classifier.save_weigts(**"census_weights.h5"**) new_classifier = DeepTabularClassifier() new_classifier.load_config(**"census_config.json"**)
new_classifier.load_weights(**"census_weights.h5"**) new_pred = new_classifier.predict(test)
结论:
已知无监督预训练可以提高计算机视觉或自然语言领域中神经网络的性能。在这篇文章中,我们证明了它在应用于结构化数据时也可以工作,使其与其他机器学习方法(如低数据区的梯度推进)相竞争。
训练效率使用自定义数据集检测对象模型
在具有不同类别数量的自定义对象检测任务上训练和使用 EfficientDet 的教程。我们还在博客上发布了 如何在你自己的数据集 上训练效率。
-
- *注:YOLOv5 已出版。如果您特别是为了效率而来到这里,请为效率而停留。否则考虑在 Colab 中运行 YOLOv5 PyTorch 教程。在几分钟内,您将拥有一个基于自定义数据的高性能、训练有素的 YOLOv5 模型。训练 YOLOv5 。
谷歌大脑团队最近发表了 EfficientDet,重新思考卷积神经网络的模型缩放。在本帖中,我们提供了一个教程,教你如何在你自己的数据上训练和使用 EfficientDet,使用不同数量的类。
原文:请看这篇关于如何训练效率的博文。
如果你想直接进入代码实现,跳到我们的 EfficientDet Training Colab 笔记本。Colab 可以免费使用,并提供了一个配有 GPU 计算资源的 python 编程环境。
在我们已经看到的任务中(截至 2020 年 4 月), EfficientDet 在对象检测模型架构中以最少的训练周期实现了最佳性能,使其成为高度可扩展的架构,尤其是在计算能力有限的情况下。这与 EfficientDet 作者发表的结果一致。
EfficientDet 在速度和准确性方面都非常高效( Source )
EfficientDet 是 EfficientNet 的对象检测版本,基于 EfficientNet 在图像分类任务中取得的成功。EfficientNets 来自一系列模型,这些模型在基准任务上实现了高性能,同时控制了许多效率参数,如模型大小和 FLOPS。该网络以一系列型号 d0-d7 交付,基本型号被认为比型号更小的 YOLOv3 性能更好(不久将推出更多)。
在这篇文章中,我们探索了在自定义数据集上实现 EfficientNet 的 PyTorch,演示了如何对自己的数据集做同样的事情。
我们的示例数据集
我们的数据集包含棋盘上 292 个棋子的图像。每个棋子都标有一个描述棋子类别{白骑士、白卒、黑皇后……}的边界框。我们的自定义数据集总共有 12 个类,这与进行培训的 COCO 中的类的数量不匹配。别担心!模型架构将无缝地适应您的定制数据集包含的类的数量。
roboflow.ai 公共数据集中的标签图像
准备数据
直接从数据收集到模型训练会导致次优的结果。数据可能有问题。即使没有,应用图像增强也会扩展数据集并减少过度拟合。
为对象检测准备图像包括但不限于:
- 验证您的注释是否正确(例如,图像中没有任何注释超出框架)
- 确保图像的 EXIF 方向正确(即图像在磁盘上的存储方式不同于您在应用程序中查看的方式,查看更多信息)
- 调整图像大小并更新图像注释以匹配新调整的图像大小
- 各种可以提高模型性能的颜色校正,如灰度和对比度调整
- 格式化注释以匹配模型输入的需求(例如,为 TensorFlow 生成 TFRecords,或者为 YOLO 的某些实现生成一个平面文本文件)。
与表格数据类似,清理和扩充图像数据比模型中的架构更改更能提高最终模型的性能。
Roboflow Organize 专为无缝解决这些挑战而构建。事实上,Roboflow Organize 将您需要编写的代码减少了一半,同时为您提供了更多的预处理和增强选项。
对于我们特定的国际象棋问题,我们已经预处理过的国际象棋数据可以在 Roboflow 上获得。
要么将此数据集下载到您的免费 Roboflow 帐户,要么创建 COCO JSON 格式的下载。
在 Roboflow 的数据集上点击“下载”允许我们选择任何注释输出格式。
在选择了我们的注释格式之后,Roboflow 提供了一个 curl 脚本(“Show Download Code”),我们可以在其中访问我们的数据集。
然后,我们可以使用这个 curl 脚本将数据导入到我们正在使用的 Colab 笔记本中。Colab 是一个由 Google 提供的 Jupyter 笔记本 python 编程环境,提供免费的 GPU 使用。Colab 可以免费启动,但是如果您的笔记本闲置 15 分钟左右,可能会超时。
跳到我们的 EfficientDet Colab 笔记本。
一旦我们的数据下载完毕,我们将检查文件夹结构。Coco json 数据来自我们在 Roboflow 中设置的数据中确定的训练、验证和测试分割。检查 train 文件夹,我们看到我们的数据以一组图像和一个注释文件的形式保存下来。然后,我们以我们的模型所期望的方式创建文件结构,但是不需要额外的数据清理!
培养
对于培训,我们通过 signatrix 导入了 EfficientDet 的 pytorch 实现。我们的实现使用 EfficientDet-d0 的基本版本。我们从 EfficientNet 基础主干进行训练,不使用网络检测器部分的预训练检查点。我们在训练集中训练了 20 个纪元。实现自然地适应训练类的数量,这与 TensorFlow 中最初的网络版本相比是一个很好的对比。
训练收敛:这个网络的自动性质甚至为你调整学习速度!
推理
在训练期间,我们的模型保存。onnx 文件,可以在推理时轻松调用。我们调用这些文件来设置一个推断检测器,并简单地将一个图像、我们的类列表和一个预测阈值传递给我们的推断器。预测阈值可以根据您的使用情况动态调整,以控制精确度和召回率。
我们见证了快速的推理时间,根据一些测试图像,看起来网络很快适应了我们的自定义图像检测问题!
EfficientDet 模型似乎很快就推广到了国际象棋
减轻我们的体重
我们输出训练过的模型。onxx 文件到 Google Drive 以备将来使用。您可以简单地将这些文件拉回来,并为您的应用程序重新构建推理器!
在笔记本的底部,我们提供了一个示例,说明如何将训练好的模型权重拉回来,并在您的应用程序中使用它们进行推理。在以后的文章中,我们将提供更多关于如何在您的应用程序中使用 EfficientDet 的细节。
这就是您所拥有的——一种快速而简单的方法,可以根据您自己的数据,针对您自己的定制用例,使用不同数量的类,开始构建 EffienctDet 原型。
后续步骤
在未来的博客文章中,我们将对 EfficientDet 模型和 YoloV3 进行更细致的评估,包括训练时间、模型大小、内存占用和推理时间。我们还计划分解 EfficientDet 的架构,以便更好地理解魔法是如何发生的。
在亚马逊 SageMaker 上训练机器学习模型
说到 SageMaker
短暂的集群、实验、可视化等等
用 SageMaker 实验可视化深度学习模型
现在是午夜。你已经花了几个小时来微调你的脚本,并且你正在赶在明天的截止日期之前把它放到服务器上。你正在你的大规模 for 循环中构建朴素贝叶斯、逻辑回归、XGBoost、KNN 和任何模型。您终于解决了本地机器上的问题,并准备扩展您宝贵的脚本,但是当它开始运行时,您会看到…到底发生了什么?随机打印报表?你怎么知道它起作用了?如果它坏了你会怎么做?你怎么知道你的模特在做你想让她们做的事?
现实是,你不需要单干。有成千上万的其他数据科学家和机器学习工程师与你走在同一条路上,幸运的是,在你追求目标的过程中,你可以利用桌面上的相当多的技术。
在这里,我将带你在 Amazon SageMaker 上训练机器学习模型,这是一个完全托管的解决方案,用于构建、训练和部署机器学习模型,由 Amazon Web Services 精心开发。我们将介绍如何在 SageMaker 上引入您自己的模型,用调试器分析培训作业,用实验管理项目,以及在多个 EC2 实例上扩展作业。
让我们跳进来吧!谁知道呢,在本教程结束的时候,你甚至可以用你自己的巧妙的可视化来展示它。
建立亚马逊 SageMaker 工作室
Studio 将开发与计算分离
首先,让我们来设置您的环境。SageMaker Studio 是一个完全集成的机器学习 IDE。它将开发与计算分离开来,让您在维护 IDE 的同时,轻松地单独修改和配置 EC2 实例。你可以用 IAM 或者 SSO 凭证设置工作室,更多详情请点击这里。
克隆存储库
接下来,为 SageMaker 示例克隆 Github 存储库。打开 Studio,创建一个新的终端,然后运行这个命令。
git clone [https://github.com/awslabs/amazon-sagemaker-examples.git](https://github.com/awslabs/amazon-sagemaker-examples.git)
接下来,导航到这个目录:Amazon-sage maker-examples/sage maker-debugger/mnist _ tensor _ plot
然后打开笔记本!
使用 SageMaker 调试器可视化深度学习模型
让我们一起来解决这个问题。马上,确保您添加了一些依赖项。
! python -m pip install plotly
! python -m pip install smdebug
!pip install sagemaker
!pip install awscli
!pip install nbformat==4.2.0
一旦您安装好这些,我们就可以开始您的工作了!
这些第一行非常普通,你会在 SageMaker-Examples 中看到它们中的大部分。我们正在导入 SageMaker Python SDK ,然后指向新的 SageMaker 调试器库。这既有一个调试器钩子配置,也有一个集合配置。这两样我们都需要。
接下来,让我们设置我们的估计!
评估员是我们在 SageMaker 上配置培训工作的方式。您已经得到了具有运行作业权限的执行角色,然后是 EC2 实例配置。看到这有多小了吗?只需要 2 行代码来指定你需要一个ml . M4 . xlarge。****
接下来,我们要指向我们的 入口点脚本 。这是您的示例附带的文件;它使用 MXNet 估算器 来完成 Docker 文件的抽象。
记住,只要你能在 Docker 上运行你的代码,你就能在 SageMaker 上运行。
在这里,我们使用所谓的脚本模式,或者使用短暂集群在 SageMaker 上扩展你自己的模型脚本的能力。这些是 EC2 实例,它们在您的作业开始时加速,在您的作业结束时减速。这使得它们更易于扩展、保护和支付。
定义了模型之后,连同框架的版本,我们准备添加 调试器钩子配置 。这告诉 SageMaker that)我们想给我们的工作添加调试器,以及(B)我们想让它做什么。在这种情况下,我们抓住所有的张量。
SageMaker 调试器去神秘化
不要被名字误导,SageMaker 调试器是非常先进的解决方案!网络是,你要在你的深度学习模型中收集张量。然后,你要分析那些。SageMaker 调试器 自带 18 条规则**,你可以通过零代码修改 **将这些应用到你的深度学习模型中。也就是说,只要你在使用 SageMaker 深度学习容器,你就不需要修改你的脚本就可以开始使用 SageMaker 调试器。
启动您的培训工作
现在,适合你的模型,我们出发去比赛!
在亚马逊 SageMaker 上创建一个新的培训职位
如果你是一个精明的 AWS 用户,你会知道回到 AWS 控制台调查你的培训工作。导航至 SageMaker 登录页面左侧的培训**,然后选择**培训工作。****
这将打开你工作的视野!您将看到从开始的状态显示,以及关于您的数据在哪里、您正在使用的图像、您的模型工件要去哪里以及日期和时间的所有细节。**
请记住,默认情况下,您在 SageMaker 中的所有作业都会被存储和记录。
这意味着不仅可以在作业运行时监控作业,还可以返回到您停止的地方,甚至是几个月前,重新开始一个模型,这应该非常简单。
现在我们去找那些张量。
将张量从你的模型复制到你的本地工作室实例中
接下来,运行一个快速命令来获取存储张量数据的 S3 路径。
接下来,运行命令将数据从 S3 复制到本地 Studio 实例。
我不得不承认,这两行很可能是我在 AWS cloud 上最喜欢的命令。它们如此简单,却又如此有效。!aws s3 cp
和!aws s3 sync
我们所做的就是将我们的数据从 S3 转移到 Studio 上的代码中。它非常有效。
可视化你的深度学习模型
现在,有趣的部分来了。让我们用一个叫做tensor_plot
的软件包来建立一个你的网络的交互式可视化!
我们正指向一个名为debug-output
的文件夹,你要确定那是你从 S3 复制张量的地方。
使用 SageMaker 调试器为任何深度学习模型创建交互式视觉
相当牛逼!记住, 你可以为你在 SageMaker 上训练的任何深度学习模型设置这种可视化。 你只需要添加那个调试钩子配置。也可以在 XGBoost 模型上运行这个!
使用 SageMaker 实验管理项目
接下来,我们将学习如何使用 SageMaker 实验来管理我们的项目。
我将带您浏览一下这个笔记本中的一些代码片段,可以在这里找到。
[amazon-sagemaker-examples](https://github.com/awslabs/amazon-sagemaker-examples)/[sagemaker-experiments](https://github.com/awslabs/amazon-sagemaker-examples/tree/master/sagemaker-experiments)/mnist-handwritten-digits-classification-experiment.ipynb
用 SageMaker 实验管理机器学习项目
首先,了解这在 SageMaker 中是如何组织的很有帮助。你有实验、试验和试验组件。实验是你正在进行的总体学习项目,就像你的计算机视觉解决方案,或者你正在构建的预测模型。
SageMaker 实验故障
这个实验将被分解成多个试验,每个试验将大致对应一个培训工作。因此,如果你正在为一个分类项目测试 XGBoost、KNN、逻辑回归和 SVM,你会把每个尝试列为一个试验。当然,您可以为这些试验指定您感兴趣的对象指标。
**接下来,**每个试验将有一个试验组件。这些将是那个试验的步骤,比如你应用的预处理技术, SageMaker 处理 你运行的作业,或者训练作业。
这就是你如何追溯你的结果。在你找到一个合理的模型后,只要它通过实验被追踪,你可以毫不夸张地 跟随那个模型 的血统在下游再造它。
这里有一些代码片段,以及漂亮的实验图像!
为 SageMaker 实验安装依赖项
首先,确保安装了依赖项。
接下来,设置您的导入,以及您的 SageMaker 凭证。
现在,让我们通过 SDK 创建一个实验!一些需要注意的事情。(1)这实际上只有 4 行代码。(2)你有一次命名的机会。如果你像我一样,尝试了几次,得到了你真正想要的版本,你会想要开发一个命名版本策略。
version_num = ‘v1’my_experiment = Experiment.create(
experiment_name=”my-model-{}”.format(version_num),
description=”My first experiment”,
sagemaker_boto_client=sm)
接下来,让我们给你的实验添加预处理步骤。这里,我们将记录我们设置的参数。在这种情况下,这就是我们将用于标准化的平均值和标准偏差。
请注意,您可以在这里记录您正在设置的参数。运行 SageMaker 自动驾驶 作业时,可以看到如何记录 SageMaker 处理作业,将您的特征工程步骤与模型训练关联起来。
用 SageMaker 实验记录参数
按照笔记本创建评估者。在这个例子中,你实际上是要遍历一个潜在隐藏层的列表来构建你的网络。
一旦你创建了评估器,下面是我们如何添加一个实验配置。
estimator.fit(
inputs={‘training’: inputs},
job_name=cnn_training_job_name,
experiment_config={
“TrialName”: cnn_trial.trial_name,
“TrialComponentDisplayName”: “Training”,
}
在调用estimator.fit()
时,您添加了将此培训工作与您的实验相关联所需的其余组件,即将其作为试验记录。
现在,单击左侧的实验选项卡,然后右键单击您的实验,以在试验组件详细视图中查看。**
SageMaker Experiments 为试验组件提供了视觉效果
**相当花哨!请记住,**每次您在 Studio 中创建一个实验,包括使用 SDK,它都会显示在 Experiments 选项卡中。要查看试用组件列表,只需点击右键。
接下来,突出显示其中一个试验,右键单击在试验详情中打开。
这将为您提供针对具体工作的培训。
一旦您进入试验细节视图,您就可以通过直接引用培训工作和预处理步骤来检查您项目的血统。****
除此之外,您可以创建图表来分析您的模型在特定试验中的性能。
使用 SageMaker 实验可视化结果
就这样结束了!我希望你喜欢这个教程。请记住,您可以在我们的 Github 页面上找到更多示例 ,或者在这里找到我们的其他 开发者资源。****
直接从 GitHub 训练 ML 模型
在这篇文章中,我将向您展示如何直接从 GitHub 训练机器学习模型。我最初在 GitHub Satelite 2020 上展示了这个研讨会,你现在可以观看录音。
我们都知道软件 CI/CD。你编码,你构建,你测试,你发布。与机器学习类似,但也有很大不同。你从数据开始,你将做一些数据验证,数据处理和数据分析。然后,在远程 GPU 或您拥有的特定集群上训练该模型。运行模型验证,部署模型,进行预测。一旦您的模型部署到生产中,您就可以监控预测。如果模型显示出性能漂移的迹象,您甚至可以基于此重新训练模型。我们在这篇文章中建议的是一种直接从 GitHub 训练模型的简单方法。换句话说,这是一个 GitHub 加 MLOps 的解决方案。
什么是 MLOps?
MLOps(“机器学习”和“运营”的复合)是数据科学家和运营专业人员之间进行协作和沟通的实践,以帮助管理生产机器学习生命周期。类似于软件开发领域的 DevOps 术语,MLOps 希望提高自动化程度并改善生产 ML 的质量,同时还关注业务和法规要求。MLOps 适用于整个 ML 生命周期——从与模型生成(软件开发生命周期、持续集成/持续交付)、编排和部署的集成,到健康、诊断、治理和业务指标。
如何从 GitHub
训练你的 ML 模型为了建立这种直接从 GitHub 训练模型的能力,我们使用了 GitHub Actions——一种自动化开发工作流的方式,下面是它的工作方式:一旦你写好了代码,你就把它推到 GitHub 的一个特定分支。你创建一个拉取请求,并在你的 PR 中评论“ /train ”之后,它将触发使用 cnvrg.io CORE 的模型训练,这是一个你可以在你自己的 Kubernetes 上免费部署的社区 ML 平台。就这样,该命令将自动提供资源并启动培训管道。
此模型训练管道在远程 GPU 上训练 TensorFlow 模型。它正在 Kubernetes 上进行模型部署,并最终将其指标发布回 GitHub。
上面是一个我们构建的 GitHub 动作如何工作的真实例子。所以,如你所见,我把新代码放进了 GitHub。然后 leah4kosh,我同事对我的拉请求做了 /train 评论,触发了模型训练,把结果推回到这个拉请求。
这是 cnvrg.io 中训练管道的样子。正如你所看到的,在管道的末端,它将结果推回到 GitHub 在执行期间,cnvrg.io 跟踪所有不同的模型、参数和指标,并将其发送回触发模型训练的同一个 PR。
为了构建这个 GitHub 动作,我们使用了 ChatOps 来跟踪和监听对 pull 请求的不同评论。我们使用 Ruby 安装 cnvrg CLI ,然后使用 cnvrg CLI 训练机器学习管道。
现在你知道了!这就是你如何直接从 GitHub 训练一个 ML 模型。
不平衡数据的训练模型
了解阶级不平衡,并学习如何规避它
Elena Mozhvilo 在 Unsplash 上拍摄的照片
类别不平衡是指数据中不同类别的样本数量不同。在机器学习的实际应用中,经常会遇到具有不同程度类别不平衡的数据集:从中度不平衡(例如,医学图像中 10%被诊断患有疾病,90%没有)到极端不平衡(例如,工厂中的异常检测,其中可能有 1/10,000 批次失败)。
大多数根据不平衡数据训练的模型会偏向于预测较大的类别,并且在许多情况下,可能会完全忽略较小的类别。当训练数据中存在类别不平衡时,由于较大类别的先验概率增加,机器学习模型通常会对较大类别进行过度分类。
结果,属于较小类的实例通常比属于较大类的实例更经常被错误分类。在许多用例中,例如医疗诊断,这与我们想要实现的正好相反,因为罕见类别(例如疾病)是正确预测的最重要类别是很常见的。为了实现这一点,我们需要在训练模型时以某种方式处理类的不平衡。
今天我们将复习:
- 阶级失衡的症状是什么;
- 类别不平衡如何影响模型性能;
- 处理不平衡数据的可能解决方案是什么,以及每种方法的优缺点;
- 在这种情况下,评估模型时首选哪些度量。
识别阶层失衡
通过查看数据中目标类的分布,很容易识别类不平衡。在 Peltarion 平台中,直方图显示分布,位于数据集视图中每列的上方。
如果您注意到您希望模型预测的列的非均匀分布,那么您有一个不平衡的类问题,需要采取一些措施来处理它。
图 1:不平衡的阶级分布的例子。图片来自 Peltarion 平台。
图 2 :(相当)平衡的阶级分布的例子。图片来自 Peltarion 平台。
它如何影响模型性能
在每个类别的比例显著不同的情况下进行分类是有问题的,因为预测模型通常可以通过简单地“猜测”所有新的示例属于在训练数据中观察到的最常见的类别来达到高精度。由于准确性是我们通常优化的目标——通常通过分类交叉熵损失间接实现——我们经常会发现琐碎的多数猜测模型。例如,如果只有 5%的房屋受到水毁的影响,我们可以构建一个模型,猜测没有房屋受到水毁,但仍然获得 95%的准确性。虽然 95%是一个令人愉快的高比例,但该模型可能不会达到预期效果,即很好地区分受到水损害的房屋和没有受到水损害的房屋。
从神经网络的角度来看,这可以通过以下替代方式来理解。如果在上述 95/5 水损害案例中,我们的批量为 20,则平均只有一个样本来自阳性类别。所述批次的梯度更新将“看到”19 个负样本和一个正样本,使得一个正样本很难影响梯度的方向。
如何解决阶层失衡
有不同的方法可以用来处理阶级不平衡的问题。它们通常可以分为数据级和算法级方法。
数据级方法修改训练分布,降低不平衡程度。平均而言,这使得梯度更新能够从每个类中“看到”相似数量的示例。
- 欠采样丢弃从较大类别中随机选择的样本。这会导致信息丢失,因为一些样本被从训练数据中移除,并且模型不能利用这些样本中包含的信息。
- 过采样从较小的类中复制随机选择的样本,这导致多次显示学习算法完全相同的样本。这有过度拟合这些稀有样本的风险。
- 或者,您可以将数据扩充与过采样结合使用,以降低过度拟合的风险。数据扩充包括通过模仿观察到的类别分布来构建合成训练样本。对于图像,你可以使用这些技术进行放大。
算法级方法调整学习过程,以便在训练期间增加较小类的重要性。一种常见的方法是在损失函数中使用类权重。
在模型训练期间,计算每批的总损失,然后在减少该损失的方向上迭代更新模型参数。损失是实际值和模型预测值之间的误差,是该批次中所有样本的总和。默认情况下,每个样本同等计入总损失。然而,使用类别加权,总和被调整为加权总和,使得每个样本对损失的贡献与样本的类别权重成比例。
这样,属于较小类别的样本可以对总损失做出较大的贡献。这反过来意味着,当执行参数更新时,学习算法将更加关注它们。回头参考上面给出的以神经网络为中心的解释,正类的高类权重将为批中的单个正样本提供影响梯度更新的“能力”。
一种常见的方法是分配与训练数据中的类频率成反比的类权重。平均而言,这相当于在梯度更新上给予所有类别同等的重要性,而不管我们从训练数据中的每个类别获得多少样本。这反过来防止模型简单地基于它们增加的先验概率对较大的类进行过度分类。
Peltarion 平台支持类别加权,即根据上述策略设置权重。这是您需要做的来启用它:在建模视图中,点击您的目标块,然后选中“使用类权重”复选框。就是这样!
如何衡量绩效
在处理不平衡数据时,我们不建议将分类准确性作为主要评估标准。当测试在非常不平衡的数据上训练的分类模型时,观察到高的评估准确度并不罕见。在这种情况下,精确度仅仅反映了底层的类别分布。你要避免这种情况!
在这种情况下,区分微观平均和宏观平均是有用的。这些是衡量绩效的非常有用的概念。所以我们开始了【1】:
- 某个度量的微平均值将集合所有类的贡献来计算平均度量。
- 某个度量的宏观平均值将为每个类独立计算度量,然后取平均值。
因此,微观平均赋予每个样本同样的重要性,这意味着,样本数量越多,相应类别对最终得分的影响越大,从而有利于大多数类别。相反,宏平均值赋予每个类相同的重要性,因此可以更好地反映模型的性能——考虑到您的目标是拥有一个对所有类(包括少数类)都性能良好的模型。
除了准确性,研究社区还经常使用其他衡量标准来评估基于不平衡数据训练的模型,即精确度、召回率和 F1 分数【T0【2】。如前所述,优先考虑宏观平均精度、召回率和 F1 分数,而不是微观平均分数。特别是对于二元分类问题,利用 ROC-AUC 分数或者更适合不平衡数据集的 PR-AUC 分数【3】。在 Peltarion 平台中,您可以在评估视图中检查所有这些测量,以评估您的模型。
最后,混淆矩阵是这类问题的基本评估工具。参见下面的混淆矩阵,其评估了在具有来自不同音乐风格的歌词的数据集上训练的 BERT 分类模型,用于上面所示的直方图:在图 3 中,模型在原始数据上训练(其明显不平衡),而在图 4(平台外)中,过采样用于在模型训练之前平衡类别。请注意,不平衡数据中的大多数类别“摇滚”是如何主导预测的。在对相当平衡的数据训练模型之后,混淆矩阵呈现出更强的对角线,表明处理数据不平衡提高了整体分类性能。
图 3:不平衡类别分布的混淆矩阵。图片来自 Peltarion 平台。
图 4 :(相当)平衡的类分布的混淆矩阵。图片来自 Peltarion 平台。
总结
现在,您已经准备好:
- 向世界解释为什么在不平衡数据上训练 ML 模型往往不是小事;
- 确定你自己的数据集有多倾斜;
- 调整你的数据或你的学习算法以避免不平衡;
- 最后,采用正确的评估方法来比较您的模型。
干杯!
参考文献
[1] M. Sokolova,G. Lapalme,分类任务的性能测量的系统分析 (2009),信息处理&管理
[2] H .何, E. A .加西亚,从不平衡数据中学习 (2009),IEEE 知识与数据工程汇刊
[3] J. Davis,M. Goadrich,精确召回与 ROC 曲线的关系 (2006),ICML 06:第 23 届机器学习国际会议论文集
带进度条的培训模型
如何跟踪您的 ML 实验的进展
tqdm
是一个用于添加进度条的 Python 库。它允许您配置并显示一个进度条,其中包含您想要跟踪的指标。其易用性和多功能性使其成为跟踪机器学习实验的完美选择。
我将本教程分为两部分。我将首先介绍tqdm,
,然后展示一个机器学习的例子。对于本文中的每个代码片段,我们将从 Python 的time
库中导入sleep
函数,因为它将让我们减慢程序速度以查看进度条更新。
from time import sleep
Tqdm
可以用pip install tqdm
安装 tqdm。这个库附带了各种迭代器,每个迭代器都有我将要介绍的特定用途。
tqdm
是默认的迭代器。它接受一个迭代器对象作为参数,并在遍历该对象时显示一个进度条。
输出是
100%|█████████████████████████████████| 5/5 [00:00<00:00, 9.90it/s]
您可以看到带有9.90it/s
的漂亮输出,意味着每秒 9.90 次迭代的平均速度。迭代的“it”可以被配置成其他的东西,这就是我们将在下一个例子中看到的。
trange
遵循与 Python 中的range
相同的模板。例如,给trange
迭代次数。
Proving P=NP: 100%|████████████| 20/20 [00:02<00:00, 9.91carrots/s]
在这个例子中,你可以看到我们添加了一个(笑话)描述,描述了我们正在做的事情以及每次迭代的单元。
在执行过程中更新进度栏
tqdm
有两个方法可以更新进度条中显示的内容。
要使用这些方法,我们需要将tqdm
迭代器实例赋给一个变量。这可以通过 Python 中的=
操作符或with
关键字来完成。
例如,我们可以用数字i
的除数列表来更新后缀。让我们用这个函数来得到除数的列表
这是我们带有进度条的代码。
如果你觉得自己是一个杰出的 Python 程序员,你可以像这样使用with
关键字
使用with
会自动调用块末尾的pbar.close()
。
这里是显示在i=6
的状态。
Testing even number 6: 70%|██████████████▋ | 7/10 [00:03<00:01, 1.76carrots/s, divisors=[1, 2, 3]]
跟踪损失和准确性
在本节中,我们使用 PyTorch 编写的神经网络,并使用tqdm
对其进行训练,以显示损失和准确性。这是模型
这是一个简单的感知器模型,我们可以用它来处理和分类 MNIST 数据集中的数字图像。以下加载 MNIST 数据集的代码灵感来自于 PyTorch 示例。
我们刚刚加载了数据,定义了模型和设置,现在可以运行训练实验了。
我再次使用sleep
功能暂停程序,这样我们就可以看到进度条的更新。正如你所看到的,我们只是应用了我们之前在这里学到的东西,特别是用tepoch.set_postfix
和tepoch.set_description
让你更新进度条显示的信息。下面是程序运行时的输出截图
Epoch 1: 15%|▉ | 142/937 [00:16<01:32, 8.56batch/s, accuracy=89.1, loss=0.341]
这给了我们如何在实际中使用tqdm
的想法。
结论
你可以用tqdm
实现更多,比如让它适应 Jupyter 笔记本,精细配置进度条更新或嵌套进度条,所以我推荐你阅读文档了解更多:https://github.com/tqdm/tqdm
感谢您的阅读!
原载于 2020 年 10 月 12 日https://adamoudad . github . io。
训练网络识别 X 射线与肺炎
迁移学习如何在有限的数据和时间内领先
编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
2020 年,新冠肺炎疫情爆发,整个世界陷入停滞。科学界一直致力于在潜在的治疗方法上取得医学突破。这已经成为与这种病毒快速传播的竞赛,这也是为什么我们看到有史以来进展最快的临床试验。世界各地的数据科学家一直在通过利用数据来帮助这一过程。但是新冠肺炎患者的数据收集是一个持续的过程。
来源:吉菲。
有限的时间和数据是当今的一个挑战,迁移学习似乎是一个很好的解决方案。它将使我们能够使用根据具有相似结构的数据预先训练的模型。例如,使用已经在患有类似疾病的患者身上预先训练的模型。这也让我们有机会利用深度神经网络的学习能力,如果从头开始训练,将需要大量的数据和计算资源。
关于数据
数据来源于 Kaggle 。它包含从广州市妇女儿童医疗中心的 1 至 5 岁儿童患者回顾队列中选择的胸部 X 射线图像(前-后)。目标是将这些 x 光图像分类为肺炎正常或阳性。
数据集目录结构。来源:作者。
使用 Kaggle API 将全部数据直接导入 Google Colaboratory。所有的分析都是在相同的 GPU 上完成的。代码可以在这里找到。
从训练集中随机选择的患者的 x 射线。来源: Kaggle 。
了解剩余网络或 resnet
残差网络(ResNets)是卷积网络,它是作为使用“普通”卷积网络时通常面临的退化问题的解决方案而引入的。网络使用“跳过”连接来跳过深层网络的层。
网络就像天桥连接。来源:照片由贾里德·默里在 Unsplash 上拍摄
跳过连接也可以被视为将先前层的输出添加到后面层的身份映射或功能。在前向传播中,ResNets 将被跳过的子网的输出(称为“残余”)推至零(T15)。这使得真实输出几乎等于从其开始跳跃连接的子网的输出,从而由于更深的架构而减少了可观的信息损失。
ResNets 的一个额外的好处是,在反向传播期间,跳跃连接也传播梯度流。跳过具有非线性激活函数的层使得初始梯度(来自较高层)更快地到达较早的层,这解决了消失梯度的问题。
本项目实施了 ResNet50。
ResNet 50 架构:ResNet 50 是一个 50 层的 ResNet,使用了“瓶颈设计”来提高计算效率。瓶颈设计表明他们使用 3 层堆栈。这三层分别是 1x1,3x3,1x1 卷积。两侧的 1x1 回旋用于减小然后恢复尺寸。因此,3x3 层变得像一个具有较小输入&输出尺寸的瓶颈。ResNet50 拥有超过 2300 万个可训练参数。该网络已经在由 1000 个类组成的 ImageNet 数据集上、在 128 万幅图像的训练数据集上进行了预训练,在 50k 幅图像上进行了验证,并在另外 100k 幅图像上进行了测试。
【跳过】到建模…
资料来源: GIPHY
调整数据集的预训练模型
这些数据呈现出二元分类问题,具有以下两个类别:正常 & 肺炎。由于最初的 ResNet50 网络用于将图像分类到 1000 个类别中的一个,为了利用预先训练的架构及其权重,该网络的顶部被移除。因此,最初的全连接图层被替换为全局平均池图层,随后是全连接图层密集图层和输出图层。尝试了其他组合,但这给出了最好的测试集性能。
调整后的模型架构。来源:作者。
模型预处理
增加更多通道: 使用 Keras 中的图像数据生成器函数对图像进行预处理。数据的胸部 X 射线图像是灰度图像,其由单个通道组成。而 ResNet50 模型是在具有 3 个通道的 ImageNet 数据集的 RGB 图像上训练的。使用生成器函数的颜色模式参数,灰度图像被转换为具有 3 个通道。
更多图像变换: 此外,使用水平翻转、缩放、高度/宽度移动和剪切变换来增强训练集中的图像。ResNet50 预处理功能也应用于增强的训练图像、原始验证&测试图像。
训练集的 9 幅增强图像的样本。注意颜色的变化。来源:作者。
使用上述模型,达到的最佳测试精度为 83% !
进一步微调
- ****Keras 中批处理规范化的争论:一些文献表明,由于 Keras 中的批处理规范化层在训练和推理阶段的工作方式不同,它可能会造成准确性度量的差异。因此,通过冻结除 ResNet50 基础模型的批标准化层之外的所有层,模型被训练。然后训练所有剩余的未冻结层(批量标准化层&附加层)。
base_model = ResNet50(weights='imagenet',include_top=False,input_shape=(150,150,3))x = base_model.output #adding the resnet model# freezing all layers except the batch normalization layers
for layer in base_model.layers:
if isinstance(layer, BatchNormalization):
layer.trainable = True
else:
layer.trainable = False
- ****超参数的调整:为了改善初始模型中的缓慢收敛,尝试了 Adam 优化器的不同学习速率和β_ 1 值。选择 0.01 的学习率和 0.9 的β_ 1。查看批量大小,尝试了 2 的不同幂。32 的批量给出了最好的测试结果。
- ****自定义回调函数:此外,观察到当训练模型期间的验证损失低于 0.1 时,模型给出最佳测试精度。为了实现这一点,创建了一个自定义回调函数来训练模型,直到验证损失降到 0.1 以下,耐心参数为 2。
#early stopping with custom call back
class EarlyStoppingByLossVal(Callback):
def __init__(self, monitor=['val_loss'],patience=0, value=0.00001, verbose=0):
super(Callback, self).__init__()
self.monitor = monitor
self.value = value
self.verbose = verbose
self.patience = patience def on_train_begin(self, logs=None):
# the number of epoch the model has waited when loss is below the required value
self.wait = 0 def on_epoch_end(self, epoch, logs={}):
current = logs.get(self.monitor)
if current is None:
warnings.warn("Early stopping requires %s available!" % self.monitor, RuntimeWarning)
if current < self.value:
self.wait +=1
if self.wait >= self.patience:
if self.verbose > 0:
print("Epoch %05d: early stopping" % epoch)
self.model.stop_training = True
微调后达到的最佳测试精度为 93.75% 。AUROC 曲线为 0.98 。
最佳测试集性能的混淆矩阵和 ROC 曲线。来源:作者。
未来范围
同时,该模型在测试集上表现良好,增加了代表不同地区和人口统计学的患者数据,并且进一步的超参数调整可以改善模型结果。使用专门针对 X 射线图像预先训练的模型,如 ChestXNet 也可以给出更好的结果。这个项目的目的不是做出任何官方声明,而是帮助未来的研究。任何诊断都只能由专业医疗人员做出!
资料来源:吉菲。
TL;速度三角形定位法(dead reckoning)
根据世界卫生组织的消息,“重症新冠肺炎患者最常见的诊断是重症肺炎”。本文展示了一个与新冠肺炎相关的迁移学习的使用案例。一个预先训练的 ResNet 模型已被用于将患者的 x 光片分类为“正常”或感染了肺炎。
使用神经网络读取时钟
神经网络可以从模拟时钟图像中检测时间吗?
照片由壁纸照明弹
我对一个想法非常感兴趣,那就是使用神经网络从模拟时钟图像中读取时间。为了完成这个任务,我需要一个包含时钟图像的数据集,但是 web 上没有任何可用的数据集。另一种方法是从网上下载时钟图像,并手动标记它们。这是一个相当耗时的过程。
最后,我决定编写一个 python 脚本来生成动画时钟图像和它们各自的标签。以下是由脚本生成的时钟图像的几个示例。
生成的时钟图像
这些图像不像真实世界的时钟图像那样逼真,但如果能看到神经网络也能在这些图像上进行训练,那将是非常令人兴奋的。
以下是数据集的链接,可以在 Kaggle 上找到。
该数据集包含 50K 个生成的模拟时钟图像。
www.kaggle.com](https://www.kaggle.com/shivajbd/analog-clocks)
在设计神经网络之前,让我们看看如何从时钟中读取时间。
我们如何阅读时间?
一只钟
为了从时钟中读取时间,我们需要两个值,一个小时和一个分钟。一个小时可以取 0 到 11 之间的值,其中 0 只不过是 12 点。同样,一分钟可以取 0-59 之间的值。时针的长度小于分针。这就是我们区分分针和时针的方式。最重要的是,时钟中至少有一个标记(顶部 12 点)。
现在让我们设计一个可以类似地读取时间的神经网络。
设计神经网络
如你所知。我们的目标是将时钟图像输入神经网络,并从中获取时间值。因此,网络必须输出 2 个值,小时、分钟和分钟。让我们一个一个地介绍每个案例。
小时值
小时值可以从 0 到 11。我们可以把这看作是一个分类任务,我们总共有 12 个类。并且网络必须选择其中一个类别。
微小价值
分钟值可以从 0 到 59。这意味着有 60 个可能的值。明智的做法是将它视为一项回归任务。因为在这种情况下,我们希望尽可能接近地预测分钟值。
现在让我们看看下面的架构图,它解释了完整的网络架构。
时间阅读器神经网络
一开始,网络包含卷积层,它将从图像中提取有用的特征。在卷积层之上,有两个分支的全连接层。一个分支用于检测小时,一个分支用于检测分钟。
因为预测小时值是一项分类任务。在小时分支中将有 12 个输出节点。我们在输出节点的顶部应用了一个 Softmax 激活。
在分支中,只有一个输出节点激活了线性,因为在回归中我们只需要一个值。线性激活本质上就是不激活。这里我就不赘述分类回归的细节了。
整个网络准备就绪,可以从时钟图像读取时间。下面是在 Keras 中创建这个网络的代码。
Keras 中的神经网络
训练网络
我们已经设计了网络架构,并在 Keras 中创建了它。是时候把数据输入网络并训练它了。我们来快速讨论一下网络的输入和目标。
投入
我的时钟数据集包含(300300)大小的 RGB 图像。在将图像传送到网络之前,我将所有图像转换为灰度,并将尺寸缩小到(100100)。我这样做是为了在更少的内存中加载图像,并使训练更快。另一方面,由于分辨率低,我们可能会丢失一些信息。
目标
目标是小时和分钟的值。我将分钟值除以 60,使其保持在(0–1)的范围内。神经网络在小范围输出上表现更好。
培养
我已经在 40K 时钟图像上训练了 10 个时期的网络。在培训期间,我不断降低学习速度,增加批量。500 张测试图像的最终结果如下。
Hour, accuracy: ~99.00Minute, Mean Absolute Error: ~3.5
平均而言,网络能够读出接近 3.5 分钟的时间。不费吹灰之力就让人印象深刻。
下面是我的 Jupyter 笔记本的一个片段,显示了网络阅读时间。
网络阅读时间
以下是这个完整项目的 GitHub 链接。我还在回购中保存了训练好的模型。感谢阅读。
该软件使用卷积神经网络从时钟图像中读取时间。语言:Python 3.6…
github.com](https://github.com/shivaverma/Clock-Reader)
仅在 7 个细胞中使用 PyTorch 从头开始训练神经网络
神经网络
MNIST 手数字识别使用 PyTorch 在短短 7 个细胞使用神经网络(多层感知器)从零开始
用 PyTorch 进行 MNIST 手形数字识别
博客内容:
- 安装和导入模块
- 重新处理和加载数据集
- 设计模型
- 训练模型
- 可视化输出
安装:
**先做第一件事。**无论操作系统如何,只需运行下面的命令,该命令将安装运行下面代码片段所需的所有模块。如果你使用 anaconda,那么你也可以用 conda 命令安装它。
pip install torch torchvision numpy matplotlibconda install torch torchvision numpy matplotlib
导入语句:
import torch
用于添加构建神经网络的所有必要模块,而torchvision
用于添加其他功能,如数据的预处理和转换。numpy
用于处理图像数组,matplotlib
用于显示图像。
import torch
import torchvision
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
from torch import optim
import numpy as np
%matplotlib inline
PyTorch 拥有transform
模块,可以将图像转换为张量,并预处理每幅图像,使其标准化,标准偏差为 1。torchvison
有内置的数据集MNIST
手形数字,我将用它来进一步解释下面所有的代码片段。DataLoader
是 PyTorch 模块,将图像和它对应的标签组合在一个包中。所以我们可以很容易地同时访问这两个东西。请注意,我们将batch_size
添加为 64,以便在一次迭代中创建一批 64 个图像。
transform = transforms.Compose([
transforms.ToTensor(),
# transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
trainset = torchvision.datasets.MNIST('~/.pytorch/MNIST_data/', train=True, transform=transform, download=True)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
来源:男高音
要训练任何神经网络,首先我们必须了解图像的输入大小、输出类别的数量以及神经网络的隐藏层。因此检查trainloader.dataset.train_data.shape
我们将得到 64,1,28,28,这表示 64 幅图像,高度和宽度为 28,通道 1 为灰度图像。
**输入尺寸:**所以输入尺寸是 784,是图像的高(28)和宽(28)的乘积。图像只有一个通道,所以不需要在输入尺寸中添加它。
**输出大小:**我们有从 0 到 9 的数字,因此共有 10 个可能的类别选项。因此,输出大小为 10
**隐藏层:**输入层和输出层之间的层基本上称为隐藏层。在我们的例子中,我们有一个 784 个节点的输入图像,输出大小为 10,因此在两者之间,我们添加了 128 和 64 层。因此,我们的网络将从 784 扩展到 128,再扩展到 64 到 10。
input_size = trainloader.dataset.train_data.shape[1] * trainloader.dataset.train_data.shape[2]
hidden_layers = [128,64]
output_size = 10
用于手数字 MNIST 分类的简单神经网络(多层感知器)
torchvision
具有nn
模块,该模块具有构建神经网络的所有功能。最初,将输入大小添加到第一个隐藏层,即 784 到 128,然后是 ReLU(激活函数)。从 128 到 64 具有相同的 ReLU 激活功能,而 64 到 10 在最后一层。为了得到概率分布,我们添加了最后一层LogSoftmax
,维度= 1,因为我们有 64 个图像批次,所以它将在输出中给出 64x10 的结果。
为了计算神经网络的误差和错误,我们添加了NLLLoss
交叉熵损失(负对数似然损失)作为标准(误差函数),优化器作为学习率为 0.003 的SGD
(随机梯度下降)。
model = nn.Sequential(
nn.Linear(input_size, hidden_layers[0]),
nn.ReLU(),
nn.Linear(hidden_layers[0], hidden_layers[1]),
nn.ReLU(),
nn.Linear(hidden_layers[1], output_size),
nn.LogSoftmax(dim=1)
)
print(model)
criterion = nn.NLLLoss()
optimizer = optim.SGD(model.parameters(), lr=0.003)
培训:
现在,我们通过传递图像和相应的标签,成功地定义了模型及其训练模型的时间。但在此之前,我们将图像从 28x28 展平到 784x1,并将所有梯度设置为零,以训练模型的权重和偏差。
最后model(images)
将训练模型,criterion
将计算损失。loss.backward()
用于反向传播,optimizer.step()
将根据反向传播的权重和偏差更新权重。
我们把损失印在每个训练时期。只要确保你的训练损失会随着纪元的增加而减少。如果你没有在每个时期减少损失,那么你在代码中犯了一些错误。
epochs = 5
for e in range(epochs):
running_loss = 0
for images, labels in trainloader:
# Flatten the Image from 28*28 to 784 column vector
images = images.view(images.shape[0], -1)
# setting gradient to zeros
optimizer.zero_grad()
output = model(images)
loss = criterion(output, labels)
# backward propagation
loss.backward()
# update the gradient to new gradients
optimizer.step()
running_loss += loss.item()
else:
print("Training loss: ",(running_loss/len(trainloader)))
可视化:
在神经网络的预测阶段,我们将图像及其概率分布传递给可视化图像。ax1
是任意数字的原始图像,ax2
是概率分布。只需将 xlabel 和 ylabel 设置在 0–9 和地块标题之间。
def view_classify(img, ps):
ps = ps.data.numpy().squeeze()
fig, (ax1, ax2) = plt.subplots(figsize=(6,9), ncols=2)
ax1.imshow(img.resize_(1, 28, 28).numpy().squeeze())
ax1.axis('off')
ax2.barh(np.arange(10), ps)
ax2.set_aspect(0.1)
ax2.set_yticks(np.arange(10))
ax2.set_yticklabels(np.arange(10))
ax2.set_title('Class Probability')
ax2.set_xlim(0, 1.1)
plt.tight_layout()
预测:
关闭梯度,因为我们使用相同的模型,这将开始训练,所以我们关闭所有的梯度,并获得测试图像的概率分布。所有的概率都是对数,所以我们将其转换为 0–1,并使用该函数可视化图像。
# Getting the image to test
images, labels = next(iter(trainloader))# Flatten the image to pass in the model
img = images[0].view(1, 784)# Turn off gradients to speed up this part
with torch.no_grad():
logps = model(img)# Output of the network are log-probabilities, need to take exponential for probabilities
ps = torch.exp(logps)
view_classify(img, ps)
使用 PyTorch,您可以在 MNIST 手数字识别数据集上从头开始训练一个神经网络。
现在,是庆祝的时候了,因为你实现了!!!
来源:男高音
谢谢你阅读我的博客,感谢我的努力。请随时评论和提问,并提出您的建议。你可以在 LinkedIn 、 Twitter 和我的网站上与我联系,了解更多深度学习项目。快乐学习!!!
用 PyTorch 训练 Leela Zero 神经网络
用 PyTorch、PyTorch Lightning 和 Hydra 为 Leela Zero 实现了一个简单的培训管道
闪电和九头蛇(?)— 来源
最近,我一直在寻找加快我的研究和管理我的实验的方法,特别是围绕编写训练管道和管理实验配置,我发现了这两个新项目,分别名为 PyTorch Lightning 和 Hydra 。PyTorch Lightning 帮助您快速编写培训管道,而 Hydra 帮助您以干净的方式管理配置。
为了在更真实的环境中练习使用它们,我决定为围棋引擎 Leela Zero 编写一个训练管道。我选择这样做是因为这是一个范围很广的项目,具有有趣的技术挑战,涉及使用多个 GPU 在大数据集上训练巨大的网络。此外,我以前很喜欢为国际象棋实现 AlphaGo 的小版本,所以我认为这将是一个有趣的附带项目。
在这个博客中,我将解释这个项目的主要细节,这样你就可以很容易地理解我做了什么。你可以在这里阅读我的代码:https://github.com/yukw777/leela-zero-pytorch
莉拉·零
第一步是弄清楚 Leela Zero 神经网络的内部工作方式。我大量参考了 Leela Zero 的文档及其 Tensorflow 培训管道。
神经网络体系结构
Leela Zero 的神经网络由一个 ResNet“塔”组成,有两个“头”,策略头和值头,如 AlphaGo Zero 论文中所述。所有卷积滤波器都是 3x3,除了在策略和值头开头的滤波器是 1x1,如本文中所示。游戏和棋盘特征被编码为形状张量[批量大小、棋盘宽度、棋盘高度、特征数量],并首先通过 ResNet 塔传送。然后,该塔提取抽象特征,并通过每个头来计算下一步行动的策略概率分布和游戏的价值,以预测游戏的赢家。
您可以在下面的代码片段中找到网络的实现细节。
Leela 零神经网络在 PyTorch 中的实现
权重格式
Leela Zero 使用一个简单的文本文件来保存和加载网络权重。文本文件中的每一行都有一系列数字,代表网络每一层的权重。先有残塔,后有政策头,再有价值头。
卷积层有 2 个权重行:
- 形状卷积权重[输出、输入、过滤器大小、过滤器大小]
- 渠道偏差
Batchnorm 层有 2 个权重行:
- 批处理方式
- 批次方差
内部产品(完全连接)层有 2 个重量行:
- 形状的层权重[输出,输入]
- 输出偏差
我编写了单元测试来确保我的权重文件是正确的。我使用的另一个简单的健全性检查是计算层数,并将其与加载我的权重文件后 Leela Zero 所说的进行比较。层数的公式为:
n_layers = 1 (version number) +
2 (input convolution) +
2 (input batch norm) +
n_res (number of residual blocks) *
8 (first conv + first batch norm +
second conv + second batch norm) +
2 (policy head convolution) +
2 (policy head batch norm) +
2 (policy head linear) +
2 (value head convolution) +
2 (value head batch norm) +
2 (value head first linear) +
2 (value head second linear)
到目前为止,这似乎很简单,但是有一个奇怪的实现细节需要注意。Leela Zero 实际上使用卷积层的偏差来表示下一批范数层的可学习参数(gamma
和beta
)。这样做是为了在添加批次标准图层时,权重文件的格式(只有一行用于图层权重,另一行用于偏差)不必更改。
目前,Leela Zero 仅使用批次定额的beta
项,并将gamma
设置为 1。那么,实际上如何使用卷积偏差来产生与应用 batch norm 中的可学习参数相同的结果呢?让我们先来看看批量定额的等式:
y = gamma * (x — mean)/sqrt(var — eps) + beta
由于莉拉零点将gamma
设为 1,等式变成:
y = (x — mean)/sqrt(var — eps) + beta
现在,假设x_conv
是没有偏差的卷积层的输出。然后,我们要给x_conv
增加一些偏差,这样当你在没有beta
的情况下通过批范数运行它时,结果和在上面提到的只有beta
的情况下通过批范数方程运行x_conv
是一样的。以方程式的形式:
(x_conv + bias — mean)/sqrt(var — eps) =
(x_conv — mean)/sqrt(var — eps) + beta x_conv + bias — mean =
x_conv — mean + beta * sqrt(var — eps) bias = beta * sqrt(var — eps)
因此,如果我们在权重文件中将卷积偏差设置为beta * sqrt(var — eps)
,我们将获得所需的输出,这就是 LeelaZero 所做的。
那么,我们实际上如何实现这一点呢?在 Tensorflow 中,您可以通过调用tf.layers.batch_normalization(scale=False)
来告诉 batch norm 层只忽略gamma
项,并完成它。不幸的是,在 PyTorch 中你不能设置批处理规范化层只忽略gamma
;将affine
参数设置为False
: BatchNorm2d(out_channels, affine=False)
只能忽略gamma
和beta
。所以,我设置批处理规范化来忽略这两者,然后简单地在后面添加一个张量,它代表beta
。然后,我使用公式bias = beta * sqrt(var — eps)
计算权重文件的卷积偏差。
培训渠道
在弄清楚 Leela Zeros 的神经网络的细节后,是时候解决训练管道了。正如我提到的,我想练习使用两个工具——py torch Lightning 和 Hydra——来加速编写训练管道和干净地管理实验配置。让我们深入了解我如何使用它们的细节。
PyTorch 闪电
编写培训管道是迄今为止我最不喜欢的研究部分:它涉及大量重复的样板代码,并且很难调试。正因为如此,PyTorch 闪电对我来说就像一股清新的空气。它是一个轻量级的库,在 PyTorch 之上没有很多辅助的抽象,在编写训练管道时负责大部分样板代码。它允许您关注培训管道中更有趣的部分,如模型架构,并使您的研究代码更加模块化和可调试。此外,它支持开箱即用的多 GPU 和 TPU 培训!
为了将 PyTorch Lightning 用于我的训练管道,我必须做的最多的编码工作就是编写一个类,我称之为NetworkLightningModule
,它继承了LightningModule
来指定我的训练管道的细节,并将其传递给Trainer
。你可以遵循 PyTorch Lightning 官方文档,了解如何编写自己的LightningModule
的细节。
水螅
我一直在寻找好的解决方案的另一部分研究是实验管理。当你进行研究时,不可避免地要运行无数的实验变量来测试你的假设,以一种可扩展的方式跟踪它们是极其重要的。到目前为止,我一直依靠配置文件来管理我的实验变体,但是使用平面配置文件很快变得难以管理。模板是解决这个问题的一种方法。然而,我发现模板最终也会变得混乱,因为当您覆盖多层值文件来呈现您的配置文件时,很难跟踪哪个值来自哪个值文件。
另一方面,Hydra 是一个基于组合的配置管理系统。您可以组合多个较小的配置文件来构成最终配置,而不是使用单独的模板和值文件来呈现最终配置。它不如基于模板的配置管理系统灵活,但是我发现基于组合的系统在灵活性和可维护性之间取得了很好的平衡。Hydra 就是这样一个系统,它是专门为研究脚本定制的。它的调用有点笨拙,因为它要求您将它用作脚本的主入口点函数的装饰器,但我实际上认为这种设计选择使它易于与您的训练脚本集成。此外,它允许您通过命令行手动覆盖配置,这在运行您的实验的不同变体时非常有用。我使用 Hydra 来管理不同规模的网络架构和培训管道配置。
估价
为了评估我训练过的网络,我用 GoMill 来运行围棋比赛。这是一个在 GTP 引擎之间运行比赛的库,Leela Zero 就是其中之一。你可以在这里找到我用的的锦标赛配置。
结论
通过使用 PyTorch-Lightning 和 Hydra,我能够大大加快编写训练管道的速度,并有效地管理实验配置。我希望这个项目和博客帖子也能帮助你的研究。你可以在这里查看代码:【https://github.com/yukw777/leela-zero-pytorch
用张量流训练神经网络进行价格预测
了解如何使 DNN 更有效地解决回归问题:TensorFlow 和 Keras 实用指南。
模型学习曲线的演变
使用深度神经网络来解决回归问题可能看起来有些矫枉过正(而且经常如此),但对于一些拥有大量高维数据的情况,它们可以胜过任何其他 ML 模型。
当你学习神经网络时,你通常会从一些图像分类问题开始,如 MNIST 数据集——这是一个显而易见的选择,因为高维数据的高级任务是 dnn 真正蓬勃发展的地方。
令人惊讶的是,当你试图将你在 MNIST 学到的东西应用到回归任务中时,你可能会挣扎一段时间,直到你的超级先进的 DNN 模型比基本的随机森林回归器更好。有时候你可能永远也到不了那个时刻…
在本指南中,我列出了使用 DNN 解决回归问题时学到的一些关键技巧和诀窍。该数据是一组近 50 个要素,描述了华沙的 25k 处房产。我在上一篇文章中描述了特征选择过程:处理空间数据时的特征选择和错误分析因此,现在我们将重点关注使用所选特征创建预测每平方米房价的最佳模型。
本文使用的代码和数据源可以在 GitHub 上找到。
1.入门指南
当训练深度神经网络时,我通常遵循以下关键步骤:
- A) 选择默认架构——层数、神经元数、激活
- B) 正则化模型
- C) 调整网络架构
- D) 调整学习率和时期数
- 使用回调提取最佳模型
通常创建最终的模型需要几遍所有这些步骤,但是要记住的一件重要的事情是:一次做一件事。不要试图同时改变架构、规则和学习速度,因为你不知道什么是真正有效的,可能要花几个小时在原地打转。
在你开始为回归任务构建 dnn 之前,有 3 件关键的事情你必须记住:
- 将你的数据标准化,让训练更有效率
- 对所有隐藏层使用 RELU 激活功能——使用默认的 sigmoid 激活,你将一事无成
- 对单神经元输出层使用线性激活函数
另一个重要的任务是选择损失函数。均方误差或平均绝对误差是两种最常见的选择。我的目标是最小化平均百分比误差,并在 5%的误差范围内最大化所有建筑的份额,我选择 MAE,因为它对异常值的惩罚更少,也更容易解释——它几乎可以告诉你每个报价平均每平方米偏离实际值多少美元。
还有一个与我的目标直接相关的函数——平均绝对百分比误差,但是在用 MAE 测试它之后,我发现训练效率较低。
2.基本 DNN 模型
我们从一个具有 5 个隐藏层的基本网络开始,每隔一层神经元的数量递减。
tf.keras.backend.clear_session()
tf.random.set_seed(60)model=keras.models.Sequential([
keras.layers.Dense(512, input_dim = X_train.shape[1], activation='relu'),
keras.layers.Dense(512, input_dim = X_train.shape[1], activation='relu'),
keras.layers.Dense(units=256,activation='relu'),
keras.layers.Dense(units=256,activation='relu'),
keras.layers.Dense(units=128,activation='relu'),
keras.layers.Dense(units=1, activation="linear"),],name="Initial_model",)model.summary()
我们使用 Adam optimizer,并从训练每个模型 200 个时期开始——模型配置的这一部分将保持不变,直到
点 7。
optimizer = keras.optimizers.Adam()model.compile(optimizer=optimizer, warm_start=False,
loss='mean_absolute_error')history = model.fit(X_train, y_train,
epochs=200, batch_size=1024,
validation_data=(X_test, y_test),
verbose=1)
初始模型学习曲线
初始模型学习曲线(从时期 10 开始)
我们的第一个模型被证明是相当失败的,我们在训练数据上有惊人的过度拟合,并且我们的验证损失在纪元 100 之后实际上在增加。
3.辍学正规化
退出可能是 DNN 正则化的最佳答案,适用于各种规模和架构的网络。在训练期间,应用 Dropout 会在每个时期随机丢弃层中的一部分神经元,这将迫使剩余的神经元更加通用-这将减少过度拟合,因为一个神经元不再能够映射一个特定的实例,因为它在训练期间不会总是在那里。
我建议阅读原始论文,因为它很好地描述了这个想法,并且不需要多年的学术经验来理解它——辍学:防止神经网络过度拟合的简单方法
tf.keras.backend.clear_session()
tf.random.set_seed(60)model=keras.models.Sequential([
keras.layers.Dense(512, input_dim = X_train.shape[1], activation='relu'),
**keras.layers.Dropout(0.3),**
keras.layers.Dense(512, activation='relu'),
** keras.layers.Dropout(0.3),**keras.layers.Dense(units=256,activation='relu'),
**keras.layers.Dropout(0.2),**
keras.layers.Dense(units=256,activation='relu'),
**keras.layers.Dropout(0.2),**
keras.layers.Dense(units=128,activation='relu'),
keras.layers.Dense(units=1, activation="linear"),],name="Dropout",)
Dropout 后的(0.x)指定了您想要丢弃的神经元份额,这转化为您想要正则化的程度。我通常在最大的层中从大约(0.3–0.5)的下降开始,然后在更深的层中降低其刚性。这种方法背后的想法是,更深层次网络中的神经元往往有更具体的任务,因此丢弃太多会增加太多的偏差。
辍学模型学习曲线
辍学模型学习曲线(从第 10 个时期开始)
分析修改后模型的学习曲线,我们可以看到我们正朝着正确的方向前进。首先,我们设法从先前模型的验证损失中取得进展(由灰色阈值线标记),其次,我们似乎用轻微的欠拟合来代替过拟合。
4.用批处理规范化处理濒死/爆炸神经元
当使用 RELU 激活的几个层工作时,我们有很大的神经元死亡的风险,这对我们的性能有负面影响。这可能导致我们在之前的模型中看到的拟合不足,因为我们可能实际上没有使用我们神经元的大部分,这基本上将它们的输出减少到 0。
批量标准化是处理这一问题的最佳方式之一,当应用时,我们对每一批的每一层的激活输出进行标准化,以减少极端激活对参数训练的影响,从而降低消失/爆炸梯度的风险。描述该解决方案的原始论文比参考的前一篇论文更难阅读,但我仍然建议尝试一下— 批量标准化:通过减少内部协变量转移来加速深度网络训练
tf.keras.backend.clear_session()
tf.random.set_seed(60)model=keras.models.Sequential([
keras.layers.Dense(512, input_dim = X_train.shape[1], activation='relu'),
** keras.layers.BatchNormalization(),**
keras.layers.Dropout(0.3),
keras.layers.Dense(512, activation='relu'),
** keras.layers.BatchNormalization(),**
keras.layers.Dropout(0.3),keras.layers.Dense(units=256,activation='relu'),
** keras.layers.BatchNormalization(),**
keras.layers.Dropout(0.2),
keras.layers.Dense(units=256,activation='relu'),
** keras.layers.BatchNormalization(),**
keras.layers.Dropout(0.2),
keras.layers.Dense(units=128,activation='relu'),
keras.layers.Dense(units=1, activation="linear"),],name="Batchnorm",)
BatchNorm 模型学习曲线
BatchNorm 模型学习曲线(从第 10 个时期开始)
添加批量标准化有助于我们让一些神经元复活,这增加了我们的模型方差,将欠拟合变为轻微的过拟合——训练神经网络通常是一场猫捉老鼠的游戏,在最佳偏差和方差之间进行平衡。
另一个好消息是,我们仍在改进验证错误。
5.将激活函数改为漏 RELU
漏 RELU 激活函数是对 RELU 函数的轻微修改,它允许一些负面激活漏过,进一步降低了神经元死亡的风险。漏 RELU 通常需要更长的时间来训练,这就是为什么我们将训练这个模型另外 100 个纪元。
漏 RELU 激活
tf.keras.backend.clear_session()
tf.random.set_seed(60)model=keras.models.Sequential([
keras.layers.Dense(512, input_dim = X_train.shape[1]),
** keras.layers.LeakyReLU(),**
keras.layers.BatchNormalization(),
keras.layers.Dropout(0.3),
keras.layers.Dense(512),
**keras.layers.LeakyReLU(),**
keras.layers.BatchNormalization(),
keras.layers.Dropout(0.3),keras.layers.Dense(units=256),
** keras.layers.LeakyReLU(),**
keras.layers.BatchNormalization(),
keras.layers.Dropout(0.2),
keras.layers.Dense(units=256),
** keras.layers.LeakyReLU(),**
keras.layers.BatchNormalization(),
keras.layers.Dropout(0.2),
keras.layers.Dense(units=128),
**keras.layers.LeakyReLU(),**
keras.layers.Dense(units=1, activation="linear"),],name="LeakyRELU",)
泄漏 ReLU 模型学习曲线
泄漏 ReLU 模型学习曲线(从第 10 个时期开始)
似乎漏 RELU 减少了过度拟合,并给了我们一个更健康的学习曲线,即使在 300 个时代后,我们也可以看到改进的潜力。我们几乎达到了以前模型的最低误差,但我们设法做到了这一点,而没有过度拟合,这给我们留下了增加方差的空间。
6.用具有 1024 个神经元的附加隐藏层扩展网络
在这一点上,我对基本模型感到足够满意,可以通过添加另一个具有 1024 个神经元的隐藏层来使网络变得更大。新的层次也有最高的辍学率。由于整体架构的变化,我还对较低级别的辍学率进行了实验。
tf.keras.backend.clear_session()
tf.random.set_seed(60)model=keras.models.Sequential([
**keras.layers.Dense(1024, input_dim = X_train.shape[1]),
keras.layers.LeakyReLU(),
keras.layers.BatchNormalization(),
keras.layers.Dropout(0.4),**
keras.layers.Dense(512),
keras.layers.LeakyReLU(),
keras.layers.BatchNormalization(),
keras.layers.Dropout(0.3),keras.layers.Dense(512),
keras.layers.LeakyReLU(),
keras.layers.BatchNormalization(),
keras.layers.Dropout(0.3),
keras.layers.Dense(units=256),
keras.layers.LeakyReLU(),
keras.layers.BatchNormalization(),
keras.layers.Dropout(0.2),
keras.layers.Dense(units=256),
keras.layers.LeakyReLU(),
keras.layers.BatchNormalization(),
**keras.layers.Dropout(0.01),**keras.layers.Dense(units=128),
keras.layers.LeakyReLU(),
**keras.layers.Dropout(0.05),**
keras.layers.Dense(units=1, activation="linear"),],name="Larger_network",)
更大的网络模型学习曲线
更大的网络模型学习曲线(从时期 10 开始)
扩展网络架构似乎正朝着正确的方向发展,我们略微增加了方差以获得学习曲线,这接近最优平衡。我们还设法使我们的验证损失几乎与过度拟合的 BatchNorm 模型持平。
7.学习率下降,训练效率提高
一旦我们对网络架构满意了,学习率就是最重要的超参数,需要调优。我决定使用学习率衰减,这允许我在开始时更快地训练我的模型,然后随着更多的时期降低学习率,以使训练更加精确。
**optimizer = keras.optimizers.Adam(lr=0.005, decay=5e-4)**
选择正确的起始速率和衰减具有挑战性,需要反复试验。在我的例子中,事实证明 Keras 中默认的 Adam 学习率(0.001)有点高。我开始时的学习率是 0.005,经过 400 多次后,学习率降到了 0.001。
学习率在 400 个时期内衰减
学习率衰减模型学习曲线
学习率衰减模型学习曲线(从时期 10 开始)
调整学习率帮助我们最终改善了验证误差结果,同时仍然保持学习曲线健康,没有过度拟合的太大风险——甚至可能还有一些空间来为另一个 100 个时期训练模型。
8.使用回调在最佳时期停止训练
在选择我们的最佳模型之前,剩下的最后一项任务是使用回调在最佳时期停止训练。这允许我们在达到最小误差的精确时期检索模型。这种解决方案的最大优点是,如果你想训练 300 或 600 个纪元,你真的不需要担心——如果你的模型开始过度拟合,回调会让你回到最佳纪元。
checkpoint_name = 'Weights\Weights-{epoch:03d}--{val_loss:.5f}.hdf5'
checkpoint = ModelCheckpoint(checkpoint_name, monitor='val_loss', verbose = 1, save_best_only = True, mode ='auto')
callbacks_list = [checkpoint]
您需要定义您的回调:checkpoint_name 指定您希望在哪里以及如何保存每个纪元的权重,checkpoint 指定回调应该如何表现——我建议监视 val_loss 以进行改进,并且仅当纪元在这方面取得一些进展时才进行保存。
history = model.fit(X_train, y_train,
epochs=500, batch_size=1024,
validation_data=(X_test, y_test),
**callbacks=callbacks_list,**
verbose=1)
然后你需要做的就是在拟合你的模型的同时添加回调。
回调模型学习曲线
回调模型学习曲线(从第 10 个时期开始)
使用回调允许我们检索在第 468 个时期训练的最佳模型——接下来的 30 个时期没有改善,因为我们开始过度适应训练集。
9.模型进化总结
比较模型之间的验证损失
为了达到期望的模型输出,我们花了 7 个步骤。当我们的主要目标是减少过度拟合时,我们设法在几乎每一步都有改进,在 batch_norm 和 1024_layer 模型之间有一个平台。老实说,提炼这 7 个步骤,可能花了我 70 个步骤,所以请记住,训练 DNNs 是一个迭代的过程,如果你的进步停滞了几个小时,不要推迟。
10.DNN vs 兰登森林
最后,与之前的文章中基于相同数据训练的基本随机森林回归器相比,我们的最佳 DNN 表现如何?
在两个关键 KPI 中我们的随机森林得分如下:
- 绝对误差在 5%以内的预测份额= 44.6%
- 平均百分比误差= 8.8%
我们最好的深度神经网络得分:
- 绝对误差在 5%以内的预测份额= 43.3% (-1.3 个百分点)
- 平均百分比误差= 9.1% (+0.3 个百分点)
我们现在可以哭了吗?经过几个小时的精心训练,我们先进的神经网络怎么可能没有打败一个随机森林?老实说,有两个关键原因:
- 就训练 DNNs 而言,25k 记录的样本大小仍然很小,我选择尝试这种架构,因为我每个月都在收集新数据,我相信在几个月内,我将达到更接近 100k 的样本,这将为 DNN 带来所需的优势
- 随机森林模型的拟合度非常高,尽管在验证集上有很高的性能,但我不确定它是否也能很好地概括其他属性——在这一点上,我可能仍然会在生产中使用 DNN 模型,因为它更可靠。
总而言之,我建议不要从 DNN 开始解决回归问题。除非您在一个非常复杂的项目中使用数百个 k 样本,否则随机森林回归通常会更快地获得初始结果-如果结果证明是有希望的,您可以继续进行 DNN。训练有效的 DNN 需要更多的时间,如果您的数据样本不够大,它可能永远不会达到随机森林的性能。
[1]:尼提什·斯里瓦斯塔瓦。(2014 年 6 月 14 日)。辍学:防止神经网络过度拟合的简单方法
[2]:谢尔盖·约菲。(2015 年 3 月 2 日)。批量标准化:通过减少内部协变量转移加速深度网络训练
使用域随机化训练没有真实数据的对象检测器
在没有预算的情况下解决专用对象检测器的模拟 2 真实传输
深度学习最近已经成为解决物体检测问题的首选方法。然而,与这项技术的许多其他用途一样,注释训练数据既麻烦又耗时,尤其是如果您是一家有特定用例的小公司。在这篇文章中,我介绍了我们在物体检测的合成数据生成方面的一些工作,并展示了一些实例。
最近,许多研究论文和私营企业都将注意力集中在图像中的自动目标检测上。金字塔滑动盒检测器的时代已经一去不复返,卷积神经网络的时代已经到来。世界各地的研究人员正在微调网络,并在他们的训练计划中添加铃铛和哨子,以提高大型数据集的分数,如帕斯卡 VOC 或可可。
但是如果你不想在申请中找到 COCO 提供的任何课程呢?通常情况下,您必须为所选感兴趣对象(OOI)的新数据集提供资金,这可能会非常昂贵和耗时,尤其是如果您是一家小公司。好的数据集从不同的角度、在不同的光照下显示你的 OOI,并且有许多额外的差异,使得检测器不会过度适应一个特定的版本;例如,在单个人身上训练人体探测器,或者在单个汽车模型上训练汽车探测器,都是适得其反的。
自从训练数据存在以来,随着噪声被添加到信号输入和图像区域上的黑盒,增强的训练数据一直是一件事情。随着对域随机化(DR) 的需求和引入,这种范式略有改变,这是一种用于改善机器人机动和需要大量训练数据的类似任务的强大工具。DR 依赖于对手头任务不重要的随机参数,这样网络就学会忽略这些参数。假设你想用相机检测一个树莓派。它们有不同的颜色,可以有不同的背景和照明环境。它们也可能被各种其他物体阻挡,并在许多方向上靠近或远离摄像机。这些是您想要随机化的参数。在这种情况下,你不希望随机化的一件事是物体的一般物理形状。
多亏了现代计算机图形学,我们可以控制这些参数,并在给定树莓的 3D 模型的情况下,连续渲染树莓的无限多种变化。这给我们留下两条路:使用良好的照明和真实的环境渲染图像,可能使用一些高级的 CG 编程方法,如光线跟踪,或者使用低细节和次优照明渲染更快的图像。
巧合的是,我们一直在用任意数量的随机参数对合成数据单独进行训练对象检测器的实验。我们在这方面的理念是,我们可以在更短的时间内提供越多不同的训练数据,我们的模型就可以更好、更快地学习概括。一个真实的、看起来自然的物体的图像突然变成了模型可能已经看到的另一个变体。
创建合成数据生成器
我们在实验室中选择了五个具有匹配 3D 模型的对象,并着手创建一个快速合成图像生成器。由于我以前使用 Unity 的经验和项目的规模,这是我们选择的引擎。系统的整体思路很简单;完全随机化对象及其环境的所有参数,这些参数对于确定其类别和位置并不重要。这主要是实验性的,为了观察完全域随机化提供的机会。
随机生成的 Unity3D 场景,包含光源、随机“垃圾”对象和感兴趣的对象。
我们将相机参数、材质颜色和其他材质属性、场景中灯光的强度、颜色和数量以及许多其他东西随机化,以便尽可能创建最多样的数据集。OOI 被随机缩放、旋转和定位。然后场景被渲染两次;一次用于生成图像,一次用于生成边界框。这里可以看到一个随机生成场景的例子。
下面,我展示了系统输出的一些奇怪的树莓图片。红框只是告诉我们边界框在哪里,当然不是训练数据的一部分。如您所见,输出看起来一点也不真实。事实上,很难立即看出它们代表了什么。然而,我可以在我的笔记本电脑上每小时生成几十万个这样的东西,这给了我们的模型一个很好的机会来学习物体的形状表示,我们假设,学习忽略其他一切。
用作训练数据的随机生成的树莓 Pi 图像的示例
我决定在 MobilenetV2 上训练单次多盒检测器(SSD)模型,因为我们对在移动应用中使用训练好的模型感兴趣。这意味着精度预计会比基于 VGG19 的模型略低,但该模型应该训练和运行得更快。我编写了一个快速脚本,从 Unity 应用程序中连续获取图像,并将它们写入 Tensorflow。记录文件。这允许我们使用带有 model_main.py 的迁移学习,这是一个 Tensorflow 脚本,它根据一些可配置的参数重新训练现有的模型。然后我们可以使用 Tensorboard 可视化结果。我还准备了一个使用标签标注的真实图像的小测试数据集。
在合成数据上训练对象检测器
这项努力向我们展示的一件事是,根据合成数据训练的模型往往非常不稳定。在验证步骤之间,损失和图结果波动很大。解决这个问题的一个关键是增加批量。此外,我们在没有硬示例挖掘的情况下测试训练,硬示例挖掘是在对象检测训练中已经成为标准的方法。这里的假设是,一些例子可能被赋予了很高的权重,以至于模型在评估时对它们进行了过度拟合。证据是,在每个验证步骤中,几个真实图像预测了在位置和大小上非常相似的边界框和类,尽管图像甚至不包含该类的对象。这方面的例子如下所示。
使用硬示例挖掘进行预测的示例。左:预测。右:地面真相。
培训损失和评估损失之间也有很大的差异。这是意料之中的,因为图像的类型并不相似。由于训练损失比评估损失收敛得快得多,后者很难随着前者的减缓而改善。额外的数据扩充技术和训练方法在这里派上用场;我们包括随机黑色斑块、像素偏移和高斯斑点,以进一步增加检测器的难度,并在网络中引入信号丢失。如果你试图在家里这样做,要小心;需要耐心。这个想法需要一段时间来“点击”探测器,此时地图得分将开始增加。一旦正则化损失开始持续下降,通常会出现“咔哒声”。在此之前,猜测可能看起来完全是随机的,损失可能会大幅波动。
结果和考虑
下面,我们展示了第 28,000 步的一些结果。训练如此多的迭代所需的图像数据量需要几个小时才能生成。这些图像来自 Tensorboard,显示了评估集的预测和实际边界框。
在第 28,000 步做出的正确预测。左:预测。右:地面真相。
这张图片展示了网络做出的一些不错的预测。尽管(很可能)从未接受过任何像这样逼真的训练,但该网络似乎能够相对准确地预测和分类树莓皮和钻头,即使在场景和 OOI 前面散布着随机物体。
此时,网络已经开始学习对象的强表示。然而,需要更多的数据来更好地区分实际物体和背景噪声。下面是一些例子。
在第 28,000 步做出的预测很差。左:预测。右:地面真相。
这些图像显示了在第 28000 步做出的一些错误预测。请注意,探测器仍然可以探测到物体的大致轮廓,只是不是正确的轮廓。它预测为 Raspberry Pi 的对象也是那里最详细的对象,这表明它已经以某种方式了解到许多线条和轮廓可能表示该类。还要注意,这些置信度明显低于先前图像中正确预测的类别,这表明在可视化期间稍高的阈值可能会减轻这个问题。
为了更好地显示结果,我向您展示运行在 android 的 TensorflowLite 对象检测器演示应用程序中的检测器。这些结果基于之前讨论的配置,即没有硬示例挖掘,但我让模型在几百万张图像上训练。在合成数据生成时间中,这大致相当于在你离开办公室时开始生成,而在你第二天早上上班时就完成了。
这个项目是一个有趣的实验,它向我们证明了合成数据是真实数据的一个可行的替代品,在时间和金钱方面的成本都要低得多。事实上,这个项目没花我们一分钱。所有的部分都是免费使用和开源的。这只是证明,无论你是业余爱好者,项目负责人,还是介于两者之间的任何人,你都有机会使用最新的深度学习来创建出色的软件,而不需要你付出任何成本,只需要一点努力。
我在 Alexandra Institute 的视觉计算实验室工作,这是一家丹麦非营利公司,专门研究最先进的 it 解决方案。在我们的实验室,我们专注于利用最新的计算机视觉和计算机图形研究。我们目前正在研究数据注释、生成和增强技术,以允许较小的公司和个人开始深度学习。我们永远欢迎合作!
使用 PyTorch XLA 在 TPU 上并行训练
立即使用所有 TPU 内核训练您的模型,速度快很多倍!
图片取自 TPUs 上的 Google cloud 博客
摘自卡格尔·TPU 文件:
现在可以在 Kaggle 上免费获得 TPU。TPU 是专门从事深度学习任务的硬件加速器。它们在 Tensorflow 2.1 中通过 Keras 高级 API 得到支持,在较低的级别上,在使用自定义训练循环的模型中得到支持。
您每周最多可以使用 30 小时的 TPU,一次最多可以使用 3 小时。
Kaggle 文档只提到了如何使用 Tensorflow 在 TPU 上训练模型,但我想使用 PyTorch 来完成。PyTorch 有 XLA,我们要用它来运行我们在 TPU 的代码。无论如何,我面临的问题是没有关于如何做的单一信息来源。到处都是!
我做了相当多的研究,发现了Abhishek tha kur的这个惊人的内核。他解释了如何在 TPU 8 核处理器上并行训练。他甚至有一个 youtube 视频,解释了在 TPU 上的训练。看看这里https://www.youtube.com/watch?v=2oWf4v6QEV8。
好吧,那我们开始吧!
首先,我们需要安装 torch xla,为此,您需要做的就是将这两行代码复制、粘贴到 colab 或 kaggle 上并运行它们:
接下来是重要的进口产品:
必需的 XLA 进口
所以,我用 TPU 训练我的模特去参加一个卡格尔比赛。很简单的一个叫:植物病理学 2020 。你可以去看看。我将跳过数据预处理、代码建模,因为这是另一篇博客的主题。这里,我们只关心在 TPU 上运行这个模型。我将为您附上完整的 Ipython 笔记本的链接。
所以直接跳到训练代码,我将强调并行运行模型所需的东西。第一件重要的事情是我们的数据加载器的分布式采样器:
xm.xrt_world_size()
检索参与复制的设备数量。(基本上是核心数)
xm.get_ordinal()
检索当前进程的复制序号。序数范围从 0 到xrt_world_size()-1
接下来是并行训练模型,传统的DataLoader
必须做成一个ParallelLoader
对象,然后传递给训练函数。为此我们这样做,pl.ParallelLoader(<your-dataloader>, [device])
这里的device
是device = xm.xla_device()
。我们只是简单地,指定我们发送我们的模型运行。在这种情况下,它是一个 TPU 或者 PyTorch 喜欢称之为 XLA 设备(如果你是 PyTorch 用户,那么你可以认为它类似于用于向 GPU 发送张量的torch.device('cuda')
)
Torch.xla 有自己特定的要求。你不能简单地用xm.xla_device()
做一个设备,然后把模型传给它。
有了这个:
- 优化器必须使用
xm.optimizer_step(optimizer)
步进。 - 你必须用
xm.save(model.state_dict(), '<your-model-name>)
保存模型 - 你得用
xm.master_print(...)
打印。 - 对于并行训练,我们首先定义分布式训练和有效采样器,然后我们将数据加载器包装在
torch_xla.distributed.parallel_loader(<your-data-loader>)
中,并创建一个torch_xla.distributed.parallel_loader
对象,如我上面所解释的。 - 在将它传递给训练和验证函数时,我们指定这个
para_loader.per_device_loader(device)
。这是您将在训练函数中迭代的内容,即我们传递一个并行加载器,而不是一个数据加载器(仅用于并行训练)。
有了所有的规范,现在你就可以在 kaggle 的 TPU 上训练你的模型了,不仅仅是 kaggle,还有 colab。我知道这不太合理。但这只是一个初步的解释给你,你可以来参考的细节。一旦你看到完整的代码,你就会明白一切。祝你好运!正如所承诺的,这里是我为 Kaggle 完成的内核:)
这里还有我的 Kaggle 内核链接https://www . ka ggle . com/abhiswain/py torch-TPU-efficient net-b5-tutorial-reference。如果你觉得这很有用,你可以投赞成票!你也可以去那里直接运行它,亲眼看看它的神奇之处。
让我告诉你一些事情,我做了这个作为自己的参考,但决定分享它。让这成为你深度学习之旅的一站:)
火炬 XLA 文件:T orch X LA
使用自定义数据集训练 Tensorflow 对象检测 API,以便在 Javascript 和 Vue.js 中工作
开场白
本文是 Gilbert Tanner 关于如何使用 Tensorflow 对象检测 API 创建自己的对象检测器的精彩教程的翻版。
我遵循完全相同的步骤,但有一些不同,并添加了一些我在设置和训练中遇到的事情。
我要感谢作者的原创内容,当然也要归功于他。
在这篇文章中,我们将使用 OS X + Anaconda 环境,这样就可以很容易地移植到谷歌云平台,例如,如果你愿意的话…另外使用 GPU 而不是 CPU 进行计算🚀
我还必须说,我是在我的研究时间里开发了这个实验的,我在 Manifiesto 工作,在那里我是一名前端/在线开发人员🤗。
设置工作 Python 环境
从:
https://www.anaconda.com/distribution/下载并安装 Anaconda(在我的例子中,Python 3.7 适用于 OS X)
对于我们马上要创建的新环境,我将使用实际的 Anaconda 安装附带的同一个 Python 版本。
要知道哪个版本只需运行:
conda info
然后创建并激活环境:
conda create --name tf-object-detection python=3.7.4
conda activate tf-object-detection
安装 Tensorflow 对象检测 API
安装 Tensorflow 模型和依赖关系
选择一个您想要工作的文件夹,并创建一个名为 tensorflow 的目录。我将在以下地点工作:
/Users/<username>/projects/tensorflow
然后克隆 Tensorflow 模型存储库,运行:
git clone https://github.com/tensorflow/models
现在您需要安装所有的依赖项:
conda install Cython
conda install contextlib2
conda install pillow
conda install lxml
conda install jupyter
conda install matplotlib
conda install tensorflow=1
安装 COCO API
为此,返回到您的项目文件夹,克隆 Github 项目库并执行以下命令:
git clone [https://github.com/cocodataset/cocoapi.git](https://github.com/cocodataset/cocoapi.git)
cd cocoapi/PythonAPI
make
cp -r pycocotools <path_to_tensorflow>/models/research
Protobuf 安装/编译
这是因为 Tensorflow 对象检测 API 的使用。proto 文件,这些文件需要编译成。py 文件,以便对象检测 API 正常工作。Protobuf 可以编译这些文件。
Protobuf 可以从:
https://github.com/protocolbuffers/protobuf/releases
将下载的文件放在你想要的任何地方,例如在项目文件夹中。
提取之后,你需要进入 models/research 并使用 protobuf 从 object_detection/protos 目录下的 proto 文件中提取 python 文件。
为此,我们将使用一个小脚本。
保存在 research 文件夹中,命名为 use_protobuf.py
import os
import sys
args = sys.argv
directory = args[1]
protoc_path = args[2]
for file in os.listdir(directory):
if file.endswith(".proto"):
os.system(protoc_path+" "+directory+"/"+file+" --python_out=.")
然后你可以使用它:
python use_protobuf.py <path_to_directory> <path_to_protoc_file># for example in our particular case
python use_protobuf.py object_detection/protos /Users/<username>/projects/protoc/bin/protoc
添加必要的环境变量
我们需要将 research 和 research/slim 文件夹添加到我们的环境变量中,并运行 setup.py 文件。
export PYTHONPATH=$PYTHONPATH:<PATH_TO_TF>/TensorFlow/models/researchexport PYTHONPATH=$PYTHONPATH:<PATH_TO_TF>/TensorFlow/models/research/object_detectionexport PYTHONPATH=$PYTHONPATH:<PATH_TO_TF>/TensorFlow/models/research/slim
注意:每次关闭 shell 会话或停用 Anaconda 环境时,都需要添加 $PYTHONPATH 环境变量。
现在导航到tensor flow/models/research并运行:
python setup.py build
python setup.py install
测试 Tensorflow 对象检测 API 安装完成后,我们可以通过从 object_detection 文件夹运行Object _ Detection _ tutorial . ipynb来测试一切是否正常。
注意:重要的是要考虑到本教程适用于 Tensorflow 2.0,并且您必须在您的环境中安装 tensor flow-如果没有,只需运行conda install tensor flow = 2
jupyter notebook
然后从浏览器窗口选择object _ detection _ tutorial . ipynb,按照说明操作即可。
您还可以通过在 python shell 中导入 object_detection 来检查一切是否正常:
import object_detection
如果没有错误,那么您可以假设一切都正常工作。
收集数据
出于我们的目的,我们将使用一组代表 Jagermeister 酒瓶的图像。为了尽快做到这一点,我们将使用 python 脚本来废弃 google images,以实现流程自动化。
脚本可以从
【https://github.com/hardikvasa/google-images-download】
下载,例如将下载的文件放在项目文件夹中,命名为 google-images-download 。
然后只需导航到 python 脚本所在的文件夹并执行:
python google_images_download.py --keywords "jagermeister bottle" --limit 100 --format jpg
因为图像的分辨率可能非常不同,有些可能相当大,我们希望缩放它们以更快地完成训练过程。
下面是一个小脚本:
from PIL import Image
import os
import argparsedef rescale_images(directory, size):
for img in os.listdir(directory):
im = Image.open(directory+img)
im_resized = im.resize(size, Image.ANTIALIAS)
im_resized.save(directory+img)if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Rescale images")
parser.add_argument('-d', '--directory', type=str, required=True, help='Directory containing the images')
parser.add_argument('-s', '--size', type=int, nargs=2, required=True, metavar=('width', 'height'), help='Image size')
args = parser.parse_args()
rescale_images(args.directory, args.size)
要使用该脚本,我们需要保存它,例如,用名称transform _ image _ resolution . py保存,然后进入命令行并键入:
python transform_image_resolution.py -d <image_dir>/ -s 800 600
注意: image_dir 文件夹中的图像将被覆盖,因此如果需要,请进行备份。
注意:重要的是要检查下载的图像文件夹,以避免重复和删除损坏的文件,如果有的话。
标签数据
现在,我们必须将大约 80%的图像移动到目标 _ 检测/图像/训练目录中,将另外 20%的图像移动到目标 _ 检测/图像/测试目录中。
为了标记我们的数据,我们需要某种标记软件。
在这个特殊的例子中,我们将使用 LabelImg。
就我们使用 Anaconda 而言,我们只需要遵循以下说明:
# install pyqt (version 5)
conda install pyqt# download LabelImg and place it in 'projects' folder
git clone [https://github.com/tzutalin/labelImg.git](https://github.com/tzutalin/labelImg.git)# navigate to labelImg directory
cd labelImg# execute labelImg.py
make qt5py3;./labelImg.py
打开每个训练和测试文件夹,然后使用“创建矩形盒”按钮标记每个图像,并点击保存。我们将为每个箱子使用“ *jagermeister 瓶”*标签。
保存后,您将看到一个 XML 文件出现在相同的目录中,与我们刚刚标记的图像同名。
为培训生成 TFRecords
为了创建 TFRecords,我们将使用 Dat Tran 的浣熊探测器中的两个脚本; xml_to_csv.py 和 generate_tfrecord.py 文件。
下载并放置在 object_detection 文件夹中。你可以去下面的参考资料部分,看看我是从哪里下载的。
我们现在需要修改 xml_to_csv.py 脚本,这样我们就可以正确地将创建的 xml 文件转换成 csv 文件。
# Old:
def main():
image_path = os.path.join(os.getcwd(), 'annotations')
xml_df = xml_to_csv(image_path)
xml_df.to_csv('raccoon_labels.csv', index=None)
print('Successfully converted xml to csv.')# New:
def main():
for folder in ['train', 'test']:
image_path = os.path.join(os.getcwd(), ('images/' + folder))
xml_df = xml_to_csv(image_path)
xml_df.to_csv(('images/'+folder+'_labels.csv'), index=None)
print('Successfully converted xml to csv.')
然后,我们可以使用脚本打开命令行并键入:
python xml_to_csv.py
正如您所看到的,在图像目录中创建了两个文件。一个名为 test_labels.csv 另一个名为 train_labels.csv
注:如果你得到“没有模块名为’熊猫’”的错误,只需做一个 conda 安装熊猫。
在将这些 csv 文件转换为 TFRecords 之前,我们需要更改 generate_tfrecords.py 脚本。
出发地:
# TO-DO replace this with label map
def class_text_to_int(row_label):
if row_label == 'raccoon':
return 1
else:
None
收件人:
def class_text_to_int(row_label):
if row_label == 'jagermeister bottle':
return 1
else:
None
现在,可以通过键入以下命令来生成 TFRecords:
# train tfrecord
python generate_tfrecord.py --csv_input=images/train_labels.csv --image_dir=images/train --output_path=train.record# test tfrecord
python generate_tfrecord.py --csv_input=images/test_labels.csv --image_dir=images/test --output_path=test.record
这两个命令生成一个训练记录和一个测试记录文件,可用于训练我们的目标探测器。
注意:如果得到“模块 tensorflow 没有属性 app”这样的错误是因为你在使用 Tensorflow 2.0 所以我们需要在 generate_tfrecord.py 文件中修改一行。
出发地:
# line 17
import tensorflow as tf
收件人:
# line 17
import tensorflow.compat.v1 as tf
或者,如果您愿意,可以回滚到 Tensorflow 1.0,而不是:
conda remove tensorflow
conda install tensorflow=1
配置培训
在开始培训之前,我们需要创建一个标签映射和一个培训配置文件。
创建标签映射
标签映射将 id 映射到名称。我们将把它放在位于 object_detection 目录下的一个名为 training 的文件夹中,文件名为 labelmap.pbtxt
item {
id: 1
name: 'jagermeister bottle'
}
每个项目的 id 号应该与 generate_tfrecord.py 文件中指定项目的 id 相匹配。
创建培训配置
现在我们需要创建一个培训配置文件。
我们将使用fast _ rcnn _ inception _ v2 _ coco模型,该模型可从:
https://github . com/tensor flow/models/blob/master/research/object _ detection/g3doc/detection _ model _ zoo . MD下载
下载并解压缩文件,将其放入 object_detection 文件夹。
文件夹名称看起来会像faster _ rcnn _ inception _ v2 _ coco _ 2018 _ 01 _ 28
我们将从名为faster _ rcnn _ inception _ v2 _ pets . config的示例配置文件开始,该文件可以在示例文件夹中找到。
可以从:
https://github . com/tensor flow/models/tree/master/research/object _ detection/samples/configs下载
保持相同的名称,将其保存到培训文件夹中,用文本编辑器打开,以便更改几行代码。
第 9 行 : 将类别数量更改为您想要检测的对象数量(在我们的示例中为 1)。
第 106 行:将微调检查点改为 model.ckpt 文件的路径
fine_tune_checkpoint:
"/Users/<username>/projects/tensorflow/models/research/object_detection/faster_rcnn_inception_v2_coco_2018_01_28/model.ckpt"
第 123 行:将 input_path 改为 train.record 文件的路径:
input_path:
"/Users/<username>/projects/tensorflow/models/research/object_detection/train.record
第 135 行:将输入路径改为测试记录文件的路径:
input_path:
"/Users/<username>/projects/tensorflow/models/research/object_detection/test.record
第 125-137 行:将标签地图路径改为标签地图文件的路径:
label_map_path:
"/Users/<username>/projects/tensorflow/models/research/object_detection/training/labelmap.pbtxt
第 130 行:将 num_example 更改为测试文件夹中图像的数量。
num_examples: 10
培训模式
我们将使用位于object _ detection/legacy文件夹中的 train.py 文件。我们将把它复制到 object_detection 文件夹中,然后在命令行中键入以下内容:
更新:或者我们可以使用 object_detection 文件夹中的 model_main.py 文件来代替。
python model_main.py --logtostderr --model_dir=training/ --pipeline_config_path=training/faster_rcnn_inception_v2_pets.config
如果一切都设置正确,训练应该很快开始。
注意:如果你得到一个类似“模块 tensorflow 没有属性 contrib”的错误是因为你正在使用 Tensorflow 2.0。有两种方法可以解决这个问题:
- 更新用于 Tensorflow 2.0 的脚本
- 回滚到 Tensorflow 1.0
最简单的方法是执行回滚,因此请执行以下操作
# uninstall Tensorflow 2.0
conda remove tensorflow# install Tensorflow 1.X
conda install tensorflow=1
培训模式进展
一旦训练开始,你会每隔 5 分钟左右(取决于你的硬件)看到当前的损失被记录到 Tensorboard。我们可以通过打开第二个命令行来打开 Tensorboard,导航到 object_detection 文件夹并键入:
tensorboard --logdir=training
现在在 localhost:6006 打开一个网页
你应该训练模型,直到它达到一个令人满意的损失。
按 Ctrl+C 可以终止训练过程
导出推理图
一旦模型被训练,我们需要生成一个推理图,它可以用来运行模型。为此,我们需要首先找出保存的最高步骤编号。
为此,我们需要导航到培训目录,寻找索引最大的 model.ckpt 文件。
然后,我们可以通过在命令行中键入以下命令来创建推理图:
python export_inference_graph.py --input_type image_tensor --pipeline_config_path training/faster_rcnn_inception_v2_pets.config --trained_checkpoint_prefix training/model.ckpt-XXXX --output_directory inference_graph
其中 XXXX 代表最高的数字。
将保存的模型转换为 TensorflowJS
首先,我们需要在我们的环境中安装 TensorflowJS。
通常我们会使用 conda 来安装包,但不幸的是在资源库中没有。
所以我们将通过 python pip 来使用它:
pip install tensorflowjs
安装完成后,我们可以执行以下命令,以便将我们保存的模型转换为 tensorfowjs 能够理解的内容:
tensorflowjs_converter --input_format=tf_saved_model <input_dir> <output_dir>
例如,如果我们在目录*/Users//projects/tensor flow/models/research/object _ detection*中,我们可以运行如下内容:
tensorflowjs_converter --input_format=tf_saved_model --output_node_names='detection_boxes,detection_classes,detection_features,detection_multiclass_scores,detection_scores,num_detections,raw_detection_boxes,raw_detection_scores' --saved_model_tags=serve --output_format=tfjs_graph_model inference_graph/saved_model inference_graph/web_model
请注意,转换选项是专门为转换对象检测 SavedModel 而设置的,并且已经使用 saved_model_cli 命令检索了 output_node_names 配置:
saved_model_cli show --dir inference_graph/saved_model --tag_set serve --signature_def serving_default#output will print something like this:
#detection_boxes
#detection_classes
#detection_features
#detection_multiclass_scores
#detection_scores
#num_detections
#raw_detection_boxes
#raw_detection_scores
在下面的参考部分中对要点进行了全面解释。
在 Vue.js 应用程序上测试模型
现在我们已经正确地转换了模型,我们可以在运行 Javascript 的 web 应用程序环境中使用它。
为了让事情变得更顺利,我们可以使用下面参考文献部分中列出的演示应用程序。
您正在寻找的存储库是adriagil/tfjs-vue-example
我必须停下来一会儿,感谢fresh someone分享这个伟大的 Vue.js 演示应用程序,它使用预先训练的 coco-ssd 模型,在浏览器中与网络摄像头一起使用。我刚刚修改了代码,以便与我训练过的模型一起工作,主要包括如何提供和加载模型,以及如何检索所需的张量来分析数据。
这里有原 app 如果你感兴趣https://github.com/freshsomebody/tfjs-coco-ssd-vue-example
只需导航到那里,并在您的首选位置克隆或下载。
然后将上一步转换后的模型复制到下载项目的根目录下, web_model 文件夹。
然后导航到应用程序根目录并运行:
npm install
完成后,在你选择的文本编辑器中打开 App.vue 文件。
您现在可以看到 web 应用程序的源代码了,太棒了!🍺
为了正确加载转换后的模型,我们需要通过 web 服务器来完成。
我们将使用一个节点包来完成所谓的 http-server 。
我们需要做的就是使用以下命令激活 web 服务器:
node_modules/http-server/bin/http-server -c1 --cors .
并且可以通过 http 在 访问模型 http://localhost:8081/web _ model/model . JSON加载到浏览器中。
最后但同样重要的是,我们需要编译或服务前端应用程序,用下面的命令测试一切:
*npm run serve*
在 http://localhost:8080 中,您现在应该会看到网络摄像头流和相应的包围红色 Jaggermeister 瓶子的边框。
太棒了,我们完成了!👏👏👏
万岁 90%的检测分数🎉
结论
尽管这次经历的结果还不错,但有 2 件重要的事情需要考虑。
第一,在 OS X 工作不是最好的选择。
我建议你转换到 Linux 或 Windows 环境,但前提是你要使用 GPU,否则也是一样的废话😅
一个更好的解决方案(我们知道合适的 GPU 卡非常昂贵)是在谷歌云平台上完成。他们提供了一个非常好的环境和免费的学分供你在任何训练实验中使用。
第二件糟糕的事情是,我们选择的初始模型是精确的,但是在电脑浏览器上非常慢,在移动设备上更差。所以我现在正在训练另一个基于 MobileNet 的模型,它应该会表现得更好🤞希望如此。
我的模型也没有优化,也许这有所帮助,但我需要做一些研究如何实现它。我们走着瞧。
如果你喜欢,想要更多这样的或有任何问题,请不要犹豫与我联系…如果你来到这里,你值得拥有它!再次感谢激励我写这篇文章的作者们。
那都是乡亲们!
【2020 年 2 月 24 日更新】
正如我之前所说,网络浏览器的性能对于实时视频分析来说是不可接受的,所以我决定做一些研究。
感谢 stackoverflow 社区,我找到了许多建议,比如优化模型或使用另一个模型再次返回培训流程。我决定尝试另一个模型,因为我训练的 rcnn-inception 模型非常精确,但并没有真正考虑到我需要的应用程序。
我这次挑的是 ssd_mobilenet_v2_coco 。
经过一个周末的模型训练和近 30000 步——我知道这对开发来说不是必需的,但值得在真实情况下尝试——是测试的时候了。结果远远好于我的第一次尝试,所以现在预测率几乎与可接受的帧速率流体。
所以吸取教训;在训练前选择合适的模型来满足你的需求。
参考
用 Vue.js 制作的演示应用程序,用于在浏览器中使用定制的 Tensorflow 图形模型…
github.com](https://github.com/adriagil/tfjs-vue-example)
将 TF 模型转换为 TFJS 模型的代码段
更新 Dez/2019:安装现已推出 Jupyter 笔记本。2019 年 11 月更新:试用 Tensorflow v2.0 和…
gilberttanner.com](https://gilberttanner.com/blog/installing-the-tensorflow-object-detection-api) [## 创建您自己的对象检测器
使用 Tensorflow 对象检测 API 创建您自己的对象检测器
towardsdatascience.com](/creating-your-own-object-detector-ad69dda69c85) [## datit ran/浣熊数据集
这是我收集的数据集,用于使用 TensorFlow 的对象检测 API 训练我自己的浣熊检测器。图像是…
github.com](https://github.com/datitran/raccoon_dataset) [## hardikvasa/Google-图片-下载
用于“搜索”和“下载”数百张谷歌图片到本地硬盘的 Python 脚本!这个程序让你…
github.com](https://github.com/hardikvasa/google-images-download) [## AttributeError:模块“tensorflow”没有属性“app”
感谢贡献一个堆栈溢出的答案!请务必回答问题。提供详细信息并分享…
stackoverflow.com](https://stackoverflow.com/questions/58258003/attributeerror-module-tensorflow-has-no-attribute-app) [## 模块“tensorflow”没有属性“contrib”
感谢贡献一个堆栈溢出的答案!请务必回答问题。提供详细信息并分享…
stackoverflow.com](https://stackoverflow.com/questions/55870127/module-tensorflow-has-no-attribute-contrib) [## 使用 Tensorflow.js 运行对象检测
我正在使用 Tensorflow.js 进行对象检测。我正在尝试在…中运行自定义对象检测 tensorflow.js 模型
stackoverflow.com](https://stackoverflow.com/questions/59719522/running-object-detection-using-tensorflow-js) [## 输入看起来形状错误问题#193 tensorflow/tfjs
要从社区获得帮助,请查看我们的 Google 群组。TensorFlow.js 版本通过 Yarn 安装。var 版本=…
github.com](https://github.com/tensorflow/tfjs/issues/193) [## 执行转换后的 SSD _ mobilenet _ v2 _ oid _ v4 _ 2018 _ 12 _ 12 模型时出现“输入张量计数不匹配”
解散 GitHub 是超过 4000 万开发者的家园,他们一起工作来托管和审查代码,管理项目,以及…
github.com](https://github.com/tensorflow/tfjs/issues/1683)*
训练一个神经网络做 18 种不同的事情。
卡通形象
卷积神经网络(CNN) 架构对于视觉任务来说是非常通用的。在本文中,我将讲述我在 18 个不同的分类任务中使用相同网络架构的经验。
分类任务包括面部特征,如下巴长度(3 个等级)、头发类型(111 种类型)和头发颜色(10 种头发颜色)等。
我将使用谷歌提供的 100k 图像数据集这里。我为这些实验编写的代码可以在这里找到。
对于这些实验,我使用了 10K 版本的数据集。在最初的探索中,数据集由 10 个文件夹组成。首要任务是从网站下载数据集并提取出来。您将看到这 10 个文件夹:
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
每个子文件夹中都有。png '图像文件和一个. csv 描述符文件。
['cs11502169095236683120.csv',
'cs11502169095236683120.png',
'cs11502298889929094331.csv',
'cs11502298889929094331.png',
'cs11502404786906647764.csv',
'cs11502404786906647764.png',
'cs11502407216397343631.csv',
'cs11502407216397343631.png',
'cs11502919926067511421.csv',
'cs11502919926067511421.png']
让我们做一个快速的可视化:(在 github 中检查我的代码)
有对应的。csv 文件(与图像同名),其描述格式如下:
“脸型”,4,7
“面部 _ 头发”,14,15
“头发”,29,111
“眼睛 _ 颜色”,2,5
…
这些描述中的每一个都可能是“特征”,我们可以沿着这些特征建立一个深度学习网络来对图像进行分类。根据数据集描述页面可知,“这些集合中的每个卡通人脸都由 18 个组件组成,这些组件在 10 个图稿属性、 4 个颜色属性、 4 个比例属性上有所不同。每个属性的选项数量(将成为每个模型的类)的范围是下巴长度 3,发型 111。
根据数据集设计页面,“这些组件中的每一个及其变化都是由同一个艺术家 Shiraz Fuman 绘制的,产生了大约 250 个卡通组件艺术品和 ~10^13 可能的组合”。
正如我所承诺的,我将建立总共 18 个网络,它们都应该被专门化(希望如此)为特征分类器。在随后的文章中,我将用迁移学习和多标签分类的几种不同方法来解决这个问题。
首先是网络定义:
我使用的神经网络的结构。我用 Keras 做了一个。你会注意到,在每一个卷积层之后,我都做了一个最大池化、一个批量归一化和一个丢弃。这些层的确切顺序实际上是一个见仁见智的问题,不应该影响性能。您可以颠倒 batch_norm 和 dropout 的顺序,看看它是否工作得更好。我的猜测是,无论如何都不会有太大的改变。注意只有最终的密集层对于不同的分类具有不同数量的节点。
各层的一点背景
卷积层帮助网络学习移位或空间不变特征,并将这种先验信念引入网络结构。从这个意义上说,卷积神经网络是神经网络的正则化版本,有助于大大减少学习的参数数量。如上图所示,这种网络结构需要训练的参数略多于一百万。
最大池层数 用于基于样本的离散化,目的是对输入表示进行下采样。您可以看到,要素地图从(256,256,3)的输入大小开始,由于最大池化图层和选定的跨距,随着它穿过网络,慢慢变得越来越窄和越来越深。
批量标准化 是一种将输入移至零均值和单位方差的方法。一个非常高层次的理解是,这有助于使数据跨功能进行比较。众所周知,它能提高学习速度(尽管对其有效性还有其他解释)。
最后, Dropout 是一种正则化技术,近似训练具有许多不同架构的大量神经网络。它通过随机丢弃每层中各种节点的激活来实现这一点(由丢弃概率指定)。效果是它在训练过程中引入了噪声,因此像任何正则化技术一样帮助网络更好地泛化。
现在,继续训练网络。为了快速迭代,我想利用 keras 'image _ dataset _ from _ directory,因为它负责图像大小转换、验证分割、插值和批处理。该函数产生一个张量流数据集,操作和处理起来非常简单。
train _ dataset = TF . keras . preprocessing . image _ dataset _ from _ directory(
training _ dir,
labels = " extruded ",
label_mode="int ",
class_names=None,
color_mode="rgb ",
batch_size=32,
image_size=(256,256),
shuffle=True,
seed=42,
validation_split=.2,【t
因此,为了方便起见,我编写了一个函数,将文件复制到一个缓存临时目录中。我使用了一个 SSD 位置来加速 IO。该功能是在 github repo 中提供的 copy_images_to_labels_folder。
此外,我设置了一个 tensorboard 回调来可视化损失。这是为分类“脸型”而构建的神经网络的可视化示例。
数据集中总共有 6 种脸型。神经网络的结构似乎很擅长区分脸型,这可以从训练和验证损失非常快地接近 0 看出。训练了 30 个时期的模型的最终准确度是 100%。有趣的是,验证损失比训练损失下降的速度快得多。这是因为训练是拖尾平滑的测量。
对于“面部颜色”检测器,网络显示过度拟合,如绿色(验证)和粉色(训练)度量之间的差异所示。这应该通过增加正则化参数(如退出概率)或通过获得更多的训练数据来减轻。最终网络获得了一个不错的准确度。或者可能在从 rgba 到 rgb 的转换过程中缺少 alpha 通道会把事情弄糟。
最后,下表显示了各种网络获得的精度。我用 NVIDIA 2080 Ti 训练了所有这些。
CNN 在相同架构上训练 30 个时期后获得的准确度。第一项是空白的,因为有一些损坏的数据。第二列表示每个面部维度的类别数。
第一次,我觉得一切都很好,但对于一些像“眼睫毛”这样的情况,网络之前没有收敛。具体来说,损失值为“nan ”,这表示爆炸梯度或消失梯度问题。以下是我发现的 nan 在训练 convnet 时出现的主要原因。这并不意味着是一份详尽的清单。
爆炸渐变——你的 LR 太大了
b) 故障损失函数 —您使用的是自定义损失,还是正确使用标准损失。有一次,我使用了一个节点数少于我预测的类数的输出层,结果一整天都是 nans。
c) 输入数据 —是否存在腐败实例?就像这里的第一个网络一样。
d) 超参数 —其中一些具有相互依赖性,因此在更改默认值之前,请查看文档。
e)LR 不合适 —尝试使用 Adam 这样的自适应技术,看看是否有帮助。
最后,可解释性。
我利用了一种技术,通过一种叫做综合梯度的过程,将深度网络的预测归因于其输入特征。下图可以解释为网络在做出决策时“关注”的地方。( github 页面用于代码和其他可视化)。参考页面了解更多信息。
下巴长度:97%
首先是下巴长度分类器:正常梯度和综合梯度似乎都发现了下巴曲率的重要性。然而,仍然没有完全磨练出来。
眼睛颜色:85%
眼睛颜色分类器。正常梯度看起来一点不错。你几乎要眯着眼看它。积分梯度没那么大。也许是因为我没有正确设置一些实现超参数。
眼眉距离:84%
这个是眉毛距离分类器。渐变是准确的。
眼镜颜色:54.66%
正常梯度看起来像他们在预期的位置。但是颜色区分绝对不是这个 CNN 的强项。你能猜到原因吗?(提示:考虑渠道信息—它们何时以及如何组合)。我将在以后的帖子中包括一个缓解策略。
面部颜色:26.04%
这又是一个与颜色分类有关的坏问题。CNN 似乎是色盲。(有些人会说,这并不总是坏事)。因此,只看梯度图也是一种了解神经网络是否至少在做直观的事情的好方法。(顺便说一下,这张图片被错误分类了)。
这是这次培训的情况:
训练显示了验证损失的剧烈变化,训练曲线相对平滑。也有迹象表明过度合身。考虑到我几乎完全关闭了退出(为了速度),并且依赖于批处理规范化所具有的一点点正则化效果,一个快速的补救实验将是使用一个合适的退出级别。
发色:96.13%
头发颜色分类器比预期的要好得多。
发型:99.70%
具有 111 个类别的发型分类器在仅 30 个时期内具有超过 99.7 %的验证准确度,并且表现得令人惊讶地好。
如果你想知道更多关于可解释性和可解释人工智能的一般子领域的信息,请看这篇帖子。
耗时分析:
我花了大约 3 个小时编写代码,所有 18 个模型在 NVIDIA 2080 Ti 上训练了 30 个时代。
结论:
在这篇文章中,我分享了我建立和训练 CNN 的经验,在没有任何干预和超参数调整的情况下,解决了 18 个不同的分类任务。这些网络的性能肯定可以通过利用更多数据、迁移学习、更健壮的架构或更仔细地选择超参数来提高,但这几乎不是重点。关键是,CNN 是相当通用的,现在做得很好,不需要花太多时间。
如果您觉得这篇文章或代码有帮助,或者有建议,让我们在评论部分继续讨论。
对计算机视觉、生成网络或强化学习感兴趣?未来的文章请关注我,并在 Link din上关注我。
用一行代码训练、跟踪、分析、解释和服务模型
贾斯汀·杰拉姆从 @jusspreme 拍摄的照片
自动化模型训练、跟踪、分析、解释和服务文件生成,每一项只需一行代码
作为一名数据科学家,快速实验极其重要。如果一个想法不起作用,最好是快速失败,尽早发现。
说到建模,快速实验已经相当简单了。所有模型实现都遵循相同的 API 接口,因此您所要做的就是初始化模型并训练它。当您必须解释、跟踪和比较每个模型时,问题就来了。
你是把你所有的模型做成一个大笔记本,然后上下滚动,还是用一个目录表来查看不同模型的结果?你会为每个型号创建不同的笔记本,然后在笔记本之间来回翻转吗?如果您开始调整参数,您如何跟踪模型的迭代?你把工件存放在哪里,以便日后再次访问或进一步分析?
我将通过训练多个模型来演示解决这些问题的方法,每个模型只有一行代码,轻松查看整体结果,分析模型,解释模型,在 MLFlow 中跟踪模型,并使用 Aethos 为它们提供服务。
准备数据
我们将使用 Aethos 快速准备数据。有关如何使用 Aethos 分析和转换数据集的更多信息,请点击这里查看我之前的博文。从 Aethos repo 载入泰坦尼克号的训练数据。
import aethos as at
import pandas as pddata = pd.read_csv('[https://raw.githubusercontent.com/Ashton-Sidhu/aethos/develop/examples/data/train.csv')](https://raw.githubusercontent.com/Ashton-Sidhu/aethos/develop/examples/data/train.csv')
将数据传入 Aethos。
df = at.Data(data, target_field='Survived')
这篇文章的重点是建模,所以让我们快速预处理数据。我们将使用幸存者、Pclass、性别、年龄、票价和上船特征。在此插入
df.drop(keep=['Survived', 'Pclass', 'Sex', 'Age', 'Fare', 'Embarked'])df.standardize_column_names()
替换“年龄”和“已装船”列中缺少的值。
df.replace_missing_median('age')
df.replace_missing_mostcommon('embarked')
对年龄和票价列中的值进行规范化,并对性别、阶级和上船特征进行编码。
df.onehot_encode('sex', 'pclass', 'embarked', keep_col=False)
df.normalize_numeric('fare', 'age')
使用 Aethos,转换器适合训练集并应用于测试集。只需一行代码,您的训练集和测试集就已经完成了转换。
系统模型化
来训练 Sklearn,XGBoost,LightGBM 等。使用 Aethos 的模型,首先从数据争论对象转换到模型对象。
model = at.Model(df)
模型对象的行为方式与数据对象相同,因此如果您有已经处理过的数据,您可以用与数据对象相同的方式启动模型对象。
接下来,我们将使用 MLFlow 启用实验跟踪。
at.options.track_experiments = True
现在一切都设置好了,训练模型并获得预测就像这样简单:
lr = model.LogisticRegression(C=0.1)
要使用 Gridsearch 使用最佳参数训练模型,请在初始化模型时指定gridsearch
参数。
lr = model.LogisticRegression(gridsearch={'C': [0.01, 0.1]}, tol=0.001)
这将返回具有由 Gridsearch 评分方法定义的最佳参数的模型。
最后,如果您想交叉验证您的模型,有几个选项:
lr = model.LogisticRegression(cv=5, C=0.001)
这将对您的模型执行 5 重交叉验证,并显示平均分数和学习曲线,以帮助衡量数据质量、过度拟合和欠拟合。
您也可以将它与 Gridsearch 一起使用:
lr = model.LogisticRegression(cv=5, gridsearch={'C': [0.01, 0.1]}, tol=0.001)
这将首先使用 Gridsearch 用最佳参数训练一个模型,然后交叉验证它。目前支持的交叉验证方法有 k-fold 和分层 k-fold。
要一次训练多个模型(串行或并行),在定义模型时指定run
参数。
lr = model.LogisticRegression(cv=5, gridsearch={'C': [0.01, 0.1]}, tol=0.001, run=False)
让我们再找几个模特来训练:
model.DecisionTreeClassification(run=False)
model.RandomForestClassification(run=False)
model.LightGBMClassification(run=False)
您可以通过运行以下命令来查看排队模型和定型模型:
model.list_models()
现在,默认情况下,并行运行所有排队的模型:
dt, rf, lgbm = model.run_models()
你现在可以去喝杯咖啡或吃顿饭,而你所有的模型同时接受训练!
分析模型
默认情况下,您训练的每个模型都有一个名称。这允许您使用相同的模型对象和 API 训练同一模型的多个版本,同时仍然可以访问每个单独模型的结果。在 Jupyter 笔记本中按下Shift + Tab
可以在功能头看到每个型号的默认名称。
您也可以通过在初始化函数时指定您选择的名称来更改模型名称。
首先,让我们比较一下我们训练过的所有模型:
model.compare_models()
您可以根据各种指标查看每个型号的性能。在数据科学项目中,有一些预定义的指标,您希望将模型与这些指标进行比较(如果没有,您应该这样做)。您可以通过选项来指定那些项目度量。
at.options.project_metrics = ['Accuracy', 'Balanced Accuracy', 'Zero One Loss']
现在,当您比较模型时,您将只看到项目度量。
model.compare_models()
您还可以通过运行以下命令来查看单个模型的指标:
dt.metrics() # Shows metrics for the Decision Tree model
rf.metrics() # Shows metrics for the Random Forest model
lgbm.metrics() # Shows metrics for the LightGBM model
您可以使用相同的 API 来查看每个模型的 RoC 曲线、混淆矩阵、错误分类预测的指数等。
dt.confusion_matrix(output_file='confusion_matrix.png') # Confusion matrix for the Decision Tree model
rf.confusion_matrix(output_file='confusion_matrix.png') # Confusion matrix for the random forest model
解释模型
Aethos 配备了自动 SHAP 用例来解释每个模型。您可以查看任何模型的 force、decision、summary 和 dependence 图,每个图都有可定制的参数来满足您的用例。
通过指定output_file
参数,Aethos 知道为特定的模型保存和跟踪这个工件。
lgbm.decision_plot(output_file='decision_plot.png')
lgbm.force_plot(output_file='force_plot.png')
lgbm.shap_get_misclassified_index()
# [2, 10, 21, 38, 43, 57, 62, 69, 70, 85, 89, 91, 96, 98, 108, 117, 128, 129, 139, 141, 146, 156, 165, 167, 169]
lgbm.force_plot(2, output_file='force_plot_2.png')
lgbm.summary_plot(output_file='summary_plot.png')
lgbm.dependence_plot('fare', output_file='dep_plot.png')
要获得更自动化的体验,请运行:
lgbm.interpret_model()
这将显示一个交互式仪表板,您可以在其中使用石灰、SHAP、莫里斯敏感度等来解释您的模型的预测。
在 MLFlow 中查看模型
当我们训练模型和查看结果时,我们的实验会被自动跟踪。如果从命令行运行aethos mlflow-ui
,将会启动一个本地 MLFlow 实例,供您查看实验的结果和工件。导航到 localhost:10000。
您的每个模型和任何保存的工件都被跟踪,并且可以从 UI 中查看,包括参数和度量!要查看和下载模型工件,包括特定模型的 pickle 文件,单击 date 列中的超链接。
您将获得模型的度量以及模型参数的详细分解,并且在底部,您将看到您为特定模型保存的所有工件。
注意:交叉验证学习曲线和平均分数图总是作为工件保存。
要更改实验的名称(默认为 my-experiment),请在启动模型对象(exp_name
)时指定名称,否则每个模型都将被添加到 my-experiment 中。
服务模型
一旦您决定了要用于预测的模型,您就可以使用 FastAPI 和 Gunicorn 通过 RESTful API 轻松地生成所需的文件来为模型提供服务。
dt.to_service('titanic')
如果您熟悉 MLFlow,您也可以随时使用它来服务您的模型。打开保存部署文件的终端。我建议将这些文件转移到 git 存储库中,以便对模型和服务文件进行版本控制。
按照说明构建 docker 容器,然后独立运行它。
docker build -t titanic:1.0.0 ./
docker run -d --name titanic -p 1234:80 titanic:1.0.0
现在导航到 localhost:1234/docs 来测试您的 API。现在,您可以通过向 127.0.0.1:1234/predict 发送 POST 请求来提供预测服务。
现在有一件重要的事情需要注意,这是运行默认配置,在没有保护它并为生产使用配置服务器之前,不应在生产中使用。在未来,我将自己添加这些配置,这样您就可以或多或少地将一个模型直接投入生产,只需进行最小的配置更改。
这个特性仍处于初级阶段,我将继续积极开发和改进它。
你还能做什么?
虽然这篇文章是一个半全面的 Aethos 建模指南,但您也可以运行统计测试,如 T-Test、Anovas,使用预训练的模型,如 BERT 和 XLNet 进行情感分析和问题回答,使用 TextRank 执行提取摘要,训练 gensim LDA 模型,以及聚类、异常检测和回归模型。
完整的例子可以看这里!
反馈
我鼓励所有关于这个帖子或 Aethos 的反馈。你可以在推特上给我发信息,或者在 sidhuashton@gmail.com 给我发电子邮件。
任何 bug 或功能请求,请在 Github repo 上创建问题。我欢迎所有功能请求和任何贡献。如果你想为一个开源项目做贡献,这个项目是一个很好的开端——如果你需要帮助,可以随时给我发消息。