使用 Google AutoML 进行自动机器学习
Google 表格数据的 AutoML 简介
为什么是 AutoML?
如今,表格数据无处不在,可以为我们提供对业务和工程问题的有意义的见解。提取这些见解的一种常见方法是对这些数据应用机器学习(ML)技术。将 ML 应用于数据集的过程由各种步骤组成,*例如,*数据预处理、特征工程和超参数优化,这些步骤中的每一个通常都是耗时的反复试验过程。此外,一个人需要成为 ML 领域的专家,以便在这些步骤中的每一步都高效和有效。对于一个组织来说,要么从外部找到这些领域专家,要么在内部培养这种专业技能,这可能需要相当长的时间。
进入谷歌的 AutoML 平台,,该平台使开发者(具有有限的 ML 专业知识)能够针对他们的需求训练高质量的模型。作为谷歌统一 ML 平台 Vertex AI 的一部分,它提供了在视觉(图像和视频)、文本和结构化数据上自动训练模型的能力。在本教程中,我们将使用结构化数据的 AutoML 表格来训练预测加州房价、的模型。关于本文讨论主题的更多细节,我们参考顶点人工智能文档。该文档非常广泛,还包含其他 AutoML 产品的指南,即培训视觉和文本模型。
数据准备
在开始培训之前,我们必须确保培训数据采用平台支持的格式。AutoML 表格支持两种导入培训数据的方式;如果我们已经在使用 Google 的 BigQuery 平台,我们可以直接从 BigQuery 表中导入数据,或者上传一个逗号分隔值(CSV)文件到云存储中。对于本教程,我们将通过第二种方法。我们在下表中总结了 CSV 文件的要求。
AutoML 表格培训数据格式摘要(图片由作者提供)
创建数据集
可以通过谷歌云平台(GCP)控制台导入数据集。在顶点人工智能部分有一个数据集页面,我们可以在那里管理我们的数据集。在这里,我们可以创建一个表格数据集,并为该数据集选择一个数据源。一旦提供了数据源,将显示一个显示数据一般统计信息的页面。这些步骤如下图所示;左边是数据集创建,中间是数据源选择,右边是统计视图。对于我们的例子,我们上传了包含加州房价数据集的 housing.csv 。
顶点人工智能数据集创建、源选择和统计页面(图片由作者提供)
训练模型
一旦数据集被创建,我们就可以开始训练我们的第一个模型。
训练方法选择对话(图片由作者提供)
我们通过点击统计页面上的训练一个新模型来启动这个过程。然后,我们会看到一个对话框,允许我们选择培训目标,以及我们是使用 AutoML 来培训模型,还是使用定制的培训解决方案。对于我们的示例,我们选择回归作为训练目标,选择 AutoML 作为训练方法。
模型细节对话(图片由作者提供)
接下来,我们被要求选择我们想要训练我们的模型来预测的目标变量/列。在高级选项下,我们还可以控制如何在训练集、验证集和测试集之间拆分数据。
这种拆分可以通过随机分配、手动分配和基于所选列的按时间顺序分配来完成。对于我们的示例,我们选择中值房屋价值作为目标,并保留高级选项的默认值。
培训选项对话(图片由作者提供)
之后,系统会提示我们检查 AutoML 为我们的数据推断的数据类型。对于每一列,我们可以选择一个转换,即数据类型(分类、文本、时间戳或数字),以及我们是否希望它被 包含在训练过程中。在高级选项下,我们可以额外选择一个列,我们希望将其用作行的权重和优化目标。对于回归,这些目标包括 RMSE、MAE 和 RMSLE。任何额外的预处理和/或特征工程最好留给 AutoML。
对于我们的数据集,推断的数据类型是正确的。我们还在培训过程中包括所有列,并保留高级选项的默认值。
培训预算对话(图片由作者提供)
基于数据集大小的建议训练次数(图片由作者提供)
最后,要求提供培训预算、,即用于培训的最大节点小时数。我们根据谷歌建议的培训时间来选择我们的培训预算。培训预算设定后,培训过程将开始,并可通过 GCP Vertex AI 部分的培训页面进行监控。培训时间可能会比设定的培训预算长,但是,您将只需支付实际节点时间的费用,该时间受您设定的预算限制。一旦训练过程完成,最终的模型将出现在 Vertex AI 的模型页面上。从那里我们可以观察到各种性能指标和最终模型的特性的重要性,如下图所示。可以检查特性重要性图,以确保最重要的特性对我们的数据/业务问题有意义。
根据表格数据训练的自动回归模型的模型概述(图片由作者提供)
对于我们的例子,我们可以看到均方根误差约为 48.000,这看起来似乎很多,但实际上可以与人类训练的模型的性能相媲美(数据集非常旧,不包含最佳特征集)。在性能指标下面,我们可以看到每一列的分数,表明它在进行预测时的重要性。我们可以看到, total_rooms 和 population 列被模型视为两个最重要的特性。
部署、测试和可解释性
然后,由 AutoML 生成的训练模型可以以两种方式部署;我们可以将模型导出为保存的 TensorFlow (TF)模型,然后我们可以在 Docker 容器中为自己服务,或者我们可以将模型直接部署到 GCP 端点。这两个选项都可以在模型页面上的部署和测试选项卡下找到。
(图片由作者提供)
我们将示例中的模型部署到 GCP 端点,以便通过 GCP 控制台进一步测试它。一旦模型部署完毕,我们就可以开始通过 GCP 提供的不同方式之一进行测试。我们使用了 GCP 控制台提供的 web 界面,它可以在前面提到的部署和测试选项卡的底部找到。在那里,我们可以处理模型的输入值,并观察它做出的预测。
部署的 AutoML 模型预测+解释(图片由作者提供)
有趣的是,这个 web 界面不仅显示预测,还通过局部特征重要性值提供解释。对于 AutoML 表格(分类和回归)模型,使用采样 Shapley 方法计算这些值。这些解释值也可以在 GCP 控制台之外通过使用 Vertex AI 的解释 API 来请求。
摘要
在本文中,我们展示了如何使用 Google AutoML 来训练、测试和部署一个 ML 模型,而不需要很多 ML 领域的专业知识。这使得 ML 民主化,允许 ML 专业知识有限的团队将 ML 应用到他们的数据中,并毫不费力地将结果模型部署到生产中。对于经验丰富的 ML 从业者,Google 的 AutoML 提供了有趣的高级配置选项,可以用来简化现有的 ML 工作流程。
使用可变自动编码器进行实际异常检测
使用贝叶斯式重构方法检测表格数据中的异常
Pawel Czerwinski 在 Unsplash 上的照片
一.导言
异常检测是机器学习产生如此影响的领域之一,以至于今天几乎不用说,异常检测系统必须基于某种形式的自动模式学习算法,而不是基于一组规则或描述性统计(尽管许多可靠的异常检测系统使用这种方法非常成功和有效地运行)。
事实上,在过去十年左右的时间里,各种异常检测的 ML 方法变得越来越流行。一些方法,如一类 SVM,试图识别数据分布的维度空间中的“正常”区域或平面,然后将位于该区域之外的任何样本标记为异常。其他方法试图估计代表训练数据的分布(或混合分布)的参数,然后将任何看起来不太可能出现异常的样本指定为异常。每种方法都有自己的假设和需要考虑的弱点,这也是为什么测试异常检测算法并使其适合特定领域很重要的部分原因。
另一种流行的异常检测方法是基于 r 重建方法,随着深度学习变得更加广泛,这种方法已经获得了很大的吸引力。潜在的想法是基于这样的假设,如果模型可以学习压缩和重建正常数据的函数,那么当遇到异常数据时,它将无法这样做,因为它的函数只在正常数据上训练。因此,重建数据的失败,或者更准确地说,重建误差的范围,可以表示异常数据的存在。
已经使用深度自动编码器(AE)实施了异常检测的重建方法,并取得了非常好的结果,尽管越来越多的文献表明使用更复杂的概率变分自动编码器可以改善结果,该编码器首先由 Diederik Kingma 和 Max Welling (2014 年)提出。尽管 VAEs 主要是作为图像和文本生成的生成模型而设计的,但是我们将会看到它们的一些特性也可以在异常检测领域得到利用。
有很多关于 VAEs 理论和数学的文章。然而,这篇文章的目的是采取一种更实际的或动手操作的方法,使读者只需要一点背景知识和一些代码就可以快速地构建一个可测试的模型。完整的实现链接在一个使用 KDDCup99 数据集的可复制笔记本中,该数据集通常用作异常检测文献中的基准,并显示接近 SOTA 的结果。
文章如下:第二部分非常简要地讨论了自动编码器和异常检测的重构方法。请注意,本部分旨在快速复习,并假设读者了解自动编码器的工作原理。如果没有,我不久前写了一篇关于自动编码器的短文,作为开始可能会有帮助。第三节集中在变型自动编码器和它们与传统自动编码器之间的区别。第四节深入研究了代码和实现细节。第五节得出结论。
二。自动编码器和异常检测
自动编码器是一种深度学习模型,通常基于两个主要组件:学习输入数据的低维表示的编码器,以及试图使用编码器生成的低维表示以原始维度再现输入数据的解码器。
来源:https://towardsdatascience . com/generating-images-with-auto encoders-77fd 3a 8 DD 368
这种架构的基本思想与图像压缩非常相似:一个训练有素的编码器学会以这样一种方式对输入数据进行编码,这种方式将捕获它包含的最重要的信息,从而足以(或尽可能接近足以)由解码器再现它。
AE 通过尝试最小化再现误差或原始输入向量与解码器从编码数据再现的输出向量之间的差异来学习对输入数据进行编码。如下图所示,尽管使用自动编码器重新生成的图像缺少一些细节,但其总体形状得以保留,这意味着编码器至少捕获了输入图像中包含的一些重要信息。
来源:https://en.wikipedia.org/wiki/Autoencoder
这和异常检测有什么关系?简单明了的答案是,如果我们的 AE 经过充分训练,能够很好地再现其接受训练的输入数据,并且假设它接受了足够多的数据训练,那么当它被输入了与其接受训练的数据“相似”的数据时,它会产生或多或少稳定且最小的再现误差。然而,这也意味着不寻常的或极端的再现错误可能意味着 AE 遇到了与它被训练的输入非常不同的输入向量,因此它不能正确地再现它。如果显示给我们的 AE 的数据应该与它被训练的数据相似,那么产生极端再现误差的输入很可能是异常。
例如,如果我们在猫的图像上训练 AE,那么它可能很难再现大象的图像,并且如果这种大象的图像将被提供给在猫的图像上训练的 AE,那么它可能产生相对较高的再现误差,这可能正确地指示异常。当数据的维度很高,并且很难识别正常数据的行为以及哪些行为过于极端而不能被视为正常时,这种方法的最大好处就来了。
三。可变自动编码器
AE 以它认为最有效的方式将输入数据编码到潜在空间中,以便再现它。简而言之,编码器学习一个“函数”,该函数获取大小为 n 的向量,并输出大小为 m 的向量(使得m<n),解码器函数可以容易地使用该向量来再现原始输入向量。这意味着,例如,即使两个数据点非常相似,编码器也可以选择将它们放置在潜在空间中彼此相对较远的位置,如果这样可以最小化重建损失的话。这种架构中的编码器功能的输出产生非常离散的潜在空间,并且通常类似于过度拟合的模型。因此,虽然 AE 可以形成一个潜在空间,使其能够非常准确地完成任务,但对于它所产生的潜在空间的分布和拓扑结构,或者数据在那里是如何组织的,我们没有多少可以假设的。
在 VAE 中,编码器类似地学习将大小为 n. 的向量作为其输入的函数,然而,VAE 学习生成两个向量(大小为 m) ,这两个向量表示分布的参数(均值和方差),从该分布中对潜在向量进行采样,并且解码器函数可以将其转换回原始输入向量,而不是像传统 AEs 那样学习如何生成解码器函数可以再现的潜在向量。简而言之,AE 的学习任务是学习将数据转换为解码器可以轻松再现的潜在向量的函数,而 VAE 的学习任务是学习生成分布参数的函数,解码器可以轻松再现的潜在向量可以从该分布参数中进行采样 d。更具体地说:
**In an AE**: (*) *encoder*(input_vector[]) => latent_v[]latent_v[] is our latent features vector**In a VAE**: (*) *encoder*(input_vector[]) => latent_v_mu[], latent_v_lvar[]So that - latent_v[0] ~ N(latent_v_mu[0], latent_v_lvar[0])and latent_v[1] ~ N(latent_v_mu[1], latent_v_lvar[1])As the other elements in the latent feature vector, latent_v[0] is sampled from a distribution parameterized by the mean and variance produced by the encoder (and which are forced by the KL loss function to be closer to N(0, 1))
因此,VAE 的潜在空间实际上是从编码器为每个潜在特征学习的分布中采样的。上面没有提到的另一个重要细节是,VAE 使用由两个部分组成的损失函数:(1)一个重建损失部分——它迫使编码器生成最小化重建损失的潜在特征,就像 AE 一样,否则它会受到惩罚;(2)KL 损失分量——其迫使编码器生成的分布类似于假设为正态的输入向量的先验概率,并因此将潜在特征空间推向正态。
来源:维基百科—https://en.wikipedia.org/wiki/Variational_autoencoder
因此,VAE 产生的潜在空间更加“驯服”并趋于正常。因为编码器被高度正则化以生成正态分布,并且潜在向量本身是从正态分布采样的,所以潜在空间将更加连续和平滑。下图清楚地显示了(1)编码器的潜在空间,该编码器仅基于重建损失产生潜在空间;(2)仅试图最小化 KL 损失并对分布(即,均值 0 和 var 1)施加正态性的编码器,这就是为什么所有数据点都被分组在相同的中间区域周围;(3)结合了重建损失和 KL 损失的 VAE 的潜在空间。
鸣谢:Irhum Shafkat,来源:https://towards data science . com/直观-理解-变分-自动编码器-1bfe67eb5daf
所有这些并不一定意味着 VAE 在每个异常检测任务中都会比人工智能表现得更好。vae 主要作为生成模型而闪耀,但是生成平滑且连续的潜在空间的优点对于异常检测任务来说也是有价值的,因为它的结果将以这种任务通常要求的方式更加稳定和可预期。
四。履行
这一部分的目的是快速探究可以检测异常的 VAE 的实现代码。我使用了 KDDCup99 cup 异常检测数据集,它经常被用作异常检测文献中的基准。这里我展示了代码的主要部分,而完整的实现可以在链接的笔记本中找到。
对于这个实现,我基本上遵循了 VAE 上的 Keras 博客中的代码示例,并进行了一些调整。我们将从模型的实现开始,然后寻找异常。
VAE 模式
编码器:第一个重要的部分是编码器,它将大小为 n 的向量作为输入,并生成潜在向量( z )。然而,回想一下,在 VAE 中,编码器首先学习构成潜在向量的分布的参数,然后通过从该分布中采样来生成潜在向量 z 。如下图所示(第 5–6 行),编码器首先学习 z 分布的均值和(对数)方差(即分别为 z_mean 和 z_log_var)。然后,它使用 lambda 层从该分布中采样 z ,调用函数 sample(z_mean,z_log_var) ,我们稍后将看到该函数,它返回采样向量 z 。
sample() 函数的目的是通过返回正态分布的 z 的平均值+sigma*ε来对其进行采样。正如 Francois Chollet 所解释的,ε的作用是确保潜在空间的连续性:
因为 epsilon 是随机的,这个过程确保了靠近你对输入向量进行编码的潜在位置的每一个点都可以被解码成类似于[输入向量]的东西,从而迫使潜在空间持续有意义。潜在空间中的任意两个接近点将解码为高度相似的图像。连续性与潜在空间的低维度相结合,迫使潜在空间中的每个方向对数据变化的有意义的轴进行编码,使得潜在空间非常结构化,因此非常适合于通过概念向量进行操作(使用 Python 的深度学习,第 2 版。).
Chollet 显然试图让事情变得简单,尽管没有过多地进入理论(我自己也不完全理解),但据称ε引入的正态随机性对于网络通过反向传播不断校正其参数也是必不可少的。
解码器:解码器相当简单。就像在传统的自动编码器中一样,它将采样的潜在向量 z 作为其输入,并试图再现它,只是在 VAE 的情况下,它实际上是生成组件。
以及最终的模型。
VAE 的主要组成部分之一是损失函数,如上所述,该函数试图在两个优化任务之间取得平衡:(1)最小化重建误差——这可以通过误差项来实现,例如我在下面使用的 MSE,或者通过其他差分函数来实现;(2)最小化 KL 散度——这实质上迫使 z 的分布趋于正态(例如,参见这里的)。这可能是您希望根据结果进行调整的参数。两者之间的适当平衡将迫使 z 中的分布趋于常态,同时还确保网络能够再现输入向量。这将确保我们创建一个平滑和连续的潜在空间(由于强加的正态性),并形成我们可以用来检测异常和测量相似性的数据的准确表示。
然后,我们用组合损失函数拟合模型。
发现异常
异常检测的重建方法通过其相对较高的重建误差来识别异常。因此,当模型可以首先根据正常数据或大部分正常数据进行定型时,这些方法最有效。这样,我们可以增加我们的信心,即相对较高的重建误差是由真正的异常引起的。
具体来说,以下通常是一个良好的开端:
- 测量原始训练(干净/正常)集和模型输出之间的误差,并生成表示每个样本的误差项的误差向量。
- 在向量上找到一个相对极端的值作为你的误差阈值。假设一些异常可能会在训练集中引入一些噪声,因此选择 99%作为阈值(而不是最大的极值)是一个好主意。
- 在测试或真实数据上运行模型,其中异常数据可能与正常数据混合在一起。
- 测量重建误差并将表现出高于误差阈值的误差项的样本标记为异常。
正如您在下面所看到的,在 KDDCup99 数据集上使用这个非常简单明了的模型产生了一个非常令人印象深刻的结果(其中一些与该数据集的 SOTA 结果相差不远)。
我们还可以通过仅使用编码器模型而不使用解码器来检查编码器生成的潜在空间。
from sklearn.decomposition import PCAX_encoded = encoder.predict(X_test)pca = PCA(n_components=2)
X_transform = pca.fit_transform(X_encoded)
下图显示了编码器生成的潜在空间的散点图(在减暗至 2 暗后)。每个点的颜色反映了其相关的重建误差项(在 mae_vector 中)。暗点意味着更大的误差项。我们可以清楚地看到一大群看起来很正常的点(误差项相对较小),被 3 个误差项相对较大的主要点群所包围。
我们可以用下面的图来证实这一点,该图在将每个超过误差阈值的点标记为异常(橙色)后,绘制了上面相同的点。
最后,我们可以将上面的图与下面的真实图进行比较,后者实际上显示了数据的真实标签。也就是说,图中橙色的点实际上是异常点——网络攻击期间发送的网络数据包。我们可以看到,虽然我们正确识别了绝大多数异常(98%),但仍有一小部分我们未能识别,如图所示,这可能是因为与正常点有些相似。
动词 (verb 的缩写)摘要
变型自动编码器被广泛认为对各种机器学习任务极其有效。有很多关于变分自动编码器的文章,但是在异常检测领域没有太多的实际例子。这篇文章的目的是通过提供一个简单的例子来帮助填补这个空白,这个例子可以用来原型化和测试它。
VAEs 的最大优点来自于对生成的潜在空间施加的正则化。使用更平滑、更连续的向量空间的能力可以产生更稳定、更准确的结果,因为它可以确保相似的数据点靠得更近,并使相似性度量更可靠。在提出一个简单的架构后,我展示了 VAE 网络的这些特性如何通过相对较少的调整产生令人印象深刻的结果,尽管我试图强调如果结果不令人满意,需要在哪里进行调整和实验。
我认为,在异常检测领域,能够试验和有效测试不同的方法是非常重要的,因为每个领域都有自己的“特征”,有时允许我们做出某些假设,有时禁止我们做出其他假设。我希望这篇文章能让一些人在他们的工具箱中添加另一个工具,并鼓励更丰富的实验。
可复制笔记本可在我的 git 上获得此处
一些非常好的参考资料:
[1]原论文:迪德里克·P·金马,马克斯·韦林,自动编码变分贝叶斯(2014)【https://arxiv.org/abs/1312.6114
[2]https://towards data science . com/understanding-variable-auto encoders-vaes-f 70510919 f 73
[3]https://www.jeremyjordan.me/variational-autoencoders/
[4]https://towards data science . com/直观-理解-变分-自动编码器-1bfe67eb5daf
[5]https://wise odd . github . io/tech blog/2016/12/10/variation-auto encoder/
使用 Python 通过深度学习实践气候时间序列分类
下面介绍如何用几行代码构建一个深度神经网络进行时间序列分类
时间序列是我们生活中很大的一部分。基本上一切都可以被建模为随着时间增加(在 x 轴上)而变化的某个量(在 y 轴上)。
另一方面,分类是机器学习的一个重要应用。事实上,我们很容易将许多目标视为分类任务。
把这两件事结合在一起我们就有了**时间序列分类。**我们的目标很容易确定:
我们想要一个模型,给定一个时间序列(即一个随时间变化的量),能够输出一个类。
有大量的文章解释了这个目标背后的理论(在我看来,Marco Del Pra 在这篇文章中做得非常好)。本文不会关注理论,但会给出一个实用指南关于如何对现实世界的时间序列进行分类,使用 Python 从头开始构建你的分类器。
在我们的具体例子中,我们希望根据温度的时间序列来区分一个国家的大陆(欧洲、亚洲或非洲)。
所以让我们开始吧!
请注意:本文意在跟随您,循序渐进,走向解决方案。如果您对预处理部分、不感兴趣,请直接跳到机器学习模型部分或结果部分。
0.图书馆
我们首先要做的是打电话求助一些朋友:)
下面是我们完成工作所需的东西:
1.数据集
在我们的实验中,我使用了一个我非常熟悉的数据集,它可以用于我们的目标。这是一个由各国收集的地表温度数据组成的时间序列。
这里有一个直接来自英国的例子:
英国时间序列。[图片由作者使用 Python 制作]
2.数据预处理
现在您已经下载了您的。csv 该看了,有熊猫。
通过查看第一行,我们有一些东西需要考虑:
A.**我们还没有“大陆”信息,**我们想称之为“目标”
B. 我们必须处理平均温度列上的一些 NaN 值,这是我们将认为是时间序列的 y 轴的值
让我们一步一步地解决这些问题。
我们首先要用的是我们导入的一个魔法库,即 pycountry_convert 。
通过下面几行代码,我们能够从一个国家名称中获取“大陆”:
country_code = pc.country_name_to_country_alpha2(c, cn_name_format="default")
continent_name = pc.country_alpha2_to_continent_code(country_code)
但是,遗憾的是,这并不适用于整个数据集,我们可以从这些代码在我们的数据上的应用中看到:
很多国家不被 pycountry_convert 识别,所以我自己手动添加了大洲(稍后感谢;) ):
我们可以看到,现在所有国家都有一个相关的洲,这就解决了一个点!
一些国家来自南极洲,但它们形成了一个非常小的数量,在这个阶段,与添加到我们的数据集无关(顺便说一下,确定一个国家是否在南极洲是非常容易的,不是吗?).
所以我们最终需要将这些国家从我们的数据集中剔除。此外,我们还有那个问题要解决。我们就用神奇的 pd.fill_na() 函数来做!
代码如下:
而且它解决了 B 问题! 不幸的是,我们还没有完成。我们需要确保每个国家在时间序列中有相同数量的条目。在我们的数据集中,有些国家以 1743 为元年,有些国家以 1948 为元年。我们必须将数据集标准化到相同的起始年,以便拥有相同数量的条目。特别是,我们将使用最近的年份作为整个数据集的起始年份。
这是我们标准化之前的条目数:
这是标准化代码和标准化数据集:
这是标准化后的条目数直方图:
好了,让我们来看看我们的类:
让我们考虑三个人口最多的阶层:欧洲,亚洲和非洲。此外,让我们收集数据集的所有标签:
另外,让我们介绍一些我们将用来绘制数据的函数:
通过绘制我们三个国家的数据可以看出,我们的任务一点也不轻松!
最后,让我们为机器学习模型准备数据集:
3.机器学习模型
该模型是一个 1D 卷积神经网络。该结构非常容易理解,并且计算量小。此外,其细节由 Keras 在这里提供。
这里是模型:
及其摘要:
我们来训练模型:
4.结果是:
已经获得了 79%的准确度;
以下是其他指标:
这里是混淆矩阵:
最终考虑:
虽然越来越大的模型通常是为了解决难以置信的复杂问题而构建的,但有时一个相当小的神经网络能够在有限的计算资源下获得可接受的结果。
如果你喜欢这篇文章,你想知道更多关于机器学习的知识,或者你只是想问我一些你可以问的问题:
A.在 Linkedin 上关注我,在那里我发布我所有的故事
B .订阅我的 简讯 。这会让你了解新的故事,并给你机会发短信给我,让我收到你所有的更正或疑问。
C .成为 推荐会员 ,这样你就不会有任何“本月最大数量的故事”,你可以阅读我(以及成千上万其他机器学习和数据科学顶级作家)写的关于最新可用技术的任何内容。
带代码示例的 Git 实践工作流
通过动手实践一步一步地完成 Git 工作流(代码示例)
继之前的Git 和 Github 初学者入门 之后,今天我们将亲自动手。这个故事将通过实际的代码示例向您展示 Git 工作流程。由于 Github 是托管 Git 库的最受欢迎的网站,我们将用它作为例子。我们将使用 Git 的命令行界面,因此不考虑 Github CLI。
先决条件
从 Github 克隆存储库
有两种方法可以获得一个资源库,创建你自己的或者从 Github 或者类似的地方获得。我们将在这里着重从 Github 克隆一个。如果您对如何在自己的项目中启用 Git 并将其发布在 Github 上感兴趣,这是一篇帮助您做到这一点的优秀文章。
您首先需要转到您希望在终端中放置存储库的目录。假设我们想把它放在主目录的文档下。当你进入 Github 的一个资源库时,你可以在“”标签下找到一个彩色的“代码”底部。在那下面,有三个选项,HTTPS、SSH 和 Github CLI。这是您可以克隆存储库的三种不同方式。
语法是相同的,它们都是选项中的git clone
+URL。
$cd ~/Documents/# HTTPS
$git clone https://github.com/<USERNAME>/<REPO NAME># SSH
$git clone git@github.com:<USERNAME>/<REPO NAME>.git
区别在于您的本地机器如何访问远程存储库。如果您选择“HTTPS ”,当您与远程数据库交互(如拉、推、取等)时,如果它是一个私有存储库,系统会提示您键入用户凭据。另一方面,通过 SSH 访问可以省去很多麻烦,尤其是当存储库是私有的时候。但是您必须将本地机器的 SSH 密钥添加到您的 Github 帐户中。
将存储库克隆到本地机器上之后,您需要创建自己的分支来工作。
创建新分支
让我们首先通过运行git status
来检查状态。
$git status
>>On branch master
Your branch is up to date with 'origin/master'.nothing to commit, working tree clean
现在我们可以从这个最新的主分支(主要是开发分支)中分支出来。要实现,我们需要git branch
命令。
$git checkout -b "new_branch_name"
>>Switched to a new branch 'new_branch_name'
显然,您可以随意更改分支的名称。
现在,您已经建立了您的分支,您可以开始工作了,您想改变文件。
重设基础并提交
一旦你做好了一切准备提交你的作品,一定要记得调整基础。为了重新基于最新的主或者开发分支,我们需要首先获取最新的版本。
# Commit your changes first
$git add (this step is called staging, to add changes to the commit)
$git commit -a -m "Your commit message"# Switch to develop/master branch
$git checkout develop>>Switched to branch 'master'
Your branch is up to date with 'origin/master'.# Use 'fetch' to check (just check, we haven't pulled yet)if there are updates in remote
$git fetch# If nothing comes out, your develop is up to date. If there are updates, pull those updates to your local machine
$git pull
现在我们本地机器上的 develop/master 分支是最新的。然后,我们可以在这个分支上重新建立基础
$git checkout new_branch_name
>>Switch to branch 'new_branch_name'$git rebase -i develop
推至远程
回想一下,到目前为止,我们只在本地机器上创建了分支,在远程机器上没有这样的“new_branch_name”分支。如果您只是运行git push
,您将得到以下消息的错误:
fatal: The current branch test has no upstream branch.
To push the current branch and set the remote as upstream, use git push --set-upstream origin new_branch_name
这个错误消息抱怨说,它找不到一个远程分支,将您的提交推送到这个分支。解决方案很简单,完全按照它建议你做的去做:
$git push --set-upstream origin new_branch_name
这一行将在 remote 上创建一个分支,并将当前分支(包括所有提交)推送到 remote。
创建拉式请求
最后要做的事情是创建一个拉请求。一般的做法是在 Github 上创建一个 pull 请求,这里的界面比使用 CLI 更容易创建 PR。您可以在团队中指定一个特定的人来审核您的 PR,将它作为一个 PR 草案,以便您可以继续处理它,并审核您在此 PR 中所做的所有更改。
我的 Git 系列故事:
Git 和 Github 初学者入门
Rebase 和 Merge 的区别
我发现最有用的 5 个 Git 实践
解决了!谷歌的文本到文本转换转换器(T5)瓶颈
作者图片
探索极限:
使用 Spark NLP
我用 Google 的 T5 探索 NLP 已经有一段时间了。所以我决定更进一步。在这篇文章中,我简要介绍了 Google 的 T5,解决了围绕其繁重的资源需求和的挑战,如何使用最先进的自然语言处理库 Spark NLP 来克服这一障碍。
那么让我们来看第一个问题:
这篇文章是给我的吗?
这篇文章是写给任何想构建一个简单、高性能和精确的 NLP 管道,并能在分布式环境中轻松扩展的研究人员、数据科学家或学生的。
现在,我试图让这篇文章对初学者友好,但是,我建议你参考 Spark NLP 文档或滚动到这篇文章的末尾,阅读博士维塞尔·科贾曼关于 Spark NLP 的介绍性文章,如果你不熟悉 Spark NLP 环境,否则,拉把椅子,拿些爆米花,享受阅读的乐趣。
简介:统一文本到文本转换转换器的兴起(T5)
让我们回到那个我们可以握手问候的时代。2019 年,谷歌的一组研究人员通过引入一个统一的框架,将所有基于文本的语言问题转换为文本到文本格式,探索了 NLP 的迁移学习技术的前景。该模型在 GLUE 、 SQuAD 和 CNN/Daily Mail 数据集上展示了最先进的性能;并且在强力胶语言基准测试中获得了令人印象深刻的 88.9 分——仅比人类基准的 89.8 分差一点点。
但是真正将 T5 与 BERT 风格的模型区分开来的区别在于,它不输出标签或输入句子的输入范围,而是输出文本字符串**。**
Gif 作者http://arxiv.org/abs/1910.10683
这篇论文背后的团队在过去十年中极其努力地评估和过滤各种 NLP 研究和论文,这些研究和论文基本上代表了相同的想法:在大量未标记的文本上训练大型神经网络,然后针对非常具体的任务在标记的文本上对它们进行微调。
他们的实验包括一些有趣的观察结果:
- M *模型架构:*他们发现编码器-解码器模型通常优于“只有解码器”的语言模型
- P *重新训练目标:*他们确认填空式去噪目标(训练模型以恢复输入中缺失的单词)效果最佳,并且最重要的因素是计算成本
- u*n 标记的数据集:*他们表明对域内数据的训练可能是有益的,但对较小数据集的预训练可能会导致有害的过度拟合
- T *培训策略:*他们发现,多任务学习可以与先训练后微调的方法相媲美,但需要仔细选择模型在每项任务上的训练频率
- S cale: 他们比较了模型规模、训练时间和集合模型的数量,以确定如何充分利用固定的计算能力[2]
问题:这项研究的难点在哪里?
这就是事情变得有趣的地方。这个研究有一个巨大的瓶颈。从研究人员和学生的角度来看,他们想利用这个辉煌的模型的力量,它的大小是一个巨大的障碍。这个庞大的模型是像 BERT 这样的通用 NLP 模型的 30 多倍,这些早期的模型已经足够昂贵,可以在商用 GPU 硬件上使用!
解决方案:我们如何解决这个问题?
这就是 Spark NLP 介入的地方,它为文本到文本转换转换器(T5) 提供了广泛的功能,并能够快速有效地处理它,因为它从其基础 Apache Spark 中借用了并行性、并发性和分布式计算。
由于 Spark NLP 使用 Tensorflow 进行各种操作,它还利用了更强大的硬件提供的性能优势。相比之下,其他遗留库可能需要重写才能达到同样的效果。[5]
现在事不宜迟,让我们潜入 Spark NLP 的世界,征服 Google 的 T5。
实现:Google 的 T5 如何配合 Spark NLP 使用?
首先,Spark NLP 有各种型号的 T5,如谷歌 T5(文本到文本转换转换器)底座和谷歌 T5(文本到文本转换转换器)小型。
T5 模型在 18 个不同任务的几个数据集上进行训练,这些任务主要分为 8 类。
- 文本摘要
- 问题回答
- 翻译
- 情感分析
- 自然语言推理
- 共指消解
- 句子完成
- 词义消歧
每个 T5 任务都有解释
Google T5 的 NLP 任务
因此,让我们快速获取一个任务,并在 Spark NLP 中分解它的代码。
可乐——如果一个句子语法正确,就分类
可乐涉及到对一个给定的句子在语法和句法上是否可接受进行分类。语言可接受性语料库(CoLA)由 23 种语言学出版物中的 10657 个句子组成,由原作者对可接受性(语法性)进行了专业注释。
以下是您如何在 Spark NLP 中实现它:
作者图片
迷茫?😛
别担心,我会支持你的,
让我们来分解一下:
➡In Spark NLP,文件汇编员是我们最好的朋友*。*它是一个关键的转换器,作为任何 Spark 数据帧的 Spark NLP 的初始入口点。
(Psst…转换器是一种可以将一个数据帧转换为另一个数据帧的算法)
➡:然后,我们有一个t5 变压器,它从我们的文件汇编器获取输出documents
,并将其通过我们预先训练好的 T5。就像我之前说的, Spark NLP 对于 T5 有各种型号,为了这个教程我选择了 T5 小。
➡我还使用了任务参数设置器.setTask('cola sentence:')
来为 T5 指定我们的任务,在本例中是可乐。
➡现在,我们通过指定 Spark NLP 流水线的组件,如文档组装器和 T5 来构建它。
(Psst…管道只是按顺序执行的一系列步骤)
➡:然后,我们定义我们的数据,用列text
创建我们的 Spark 数据框架。这个text
专栏将会反馈给我们的朋友文档汇编者。
人们可以查看 Spark NLP 参考资料,了解 Spark NLP 世界的更多信息。我已经在这篇文章的末尾链接了它们。
➡接下来,我们用 spark 数据帧(df)
在流水线上.fit()
。这是我们的变压器与 spark 数据框架的融合。
最后,我们得到以下输出!
瞧啊。我们刚刚学习了如何使用谷歌的 T5 和 Spark NLP。
类似地,使用 Spark NLP 库,只需调整任务类型和输出列,就可以完成其他任务。
关于从导入库和启动 spark 会话到用 Spark NLP 实现所有 18 个可用的 Google T5 任务的完整代码,请参考这个笔记本。
参考文献
- [1] Raffel,c .,Shazeer,n .,Roberts,a .,Lee,k .,Narang,s .,Matena,m .,周,y .,Li,w .,& Liu,P. J. (2020)。用统一的文本到文本转换器探索迁移学习的极限。 ArXiv:1910.10683 [Cs,Stat] 。
- [2] 用 T5 探索迁移学习:文本到文本的迁移转换器
- [3] Spark NLP 文档:Google T5(文本到文本转换转换器)库
- [4] Spark NLP Docs: Google T5(文本到文本转换转换器)Small
- [5]Spark NLP 的优势
我为那些希望开始使用 Spark NLP 并通过这个艺术图书馆探索自然语言处理的无限可能性的人提到了一些资源。
SparkNLP 资源
- Spark NLP 文档和快速入门指南
- Spark NLP 简介:基础和基本组件
- Spark NLP 简介:安装和入门
- Spark NLP 101:文档汇编器
- Spark NLP 101:光管道
- 使用 Bert 和通用语句编码器在 Spark NLP 中进行文本分类
- Spark NLP 中带 BERT 的命名实体识别(NER)
感谢您的阅读,祝您咖啡愉快!☕
实践如何对时间序列预测模型进行基准测试
利用时间卷积网络(TCN)预测风速的个例研究
乔纳森·博尔巴在 Unsplash 上的照片
确定你的模型性能有多好的标准是非常重要的。我们通常用于回归情况的标准之一是均方根绝对误差(MAE)。在本文的其余部分,我们将使用 MAE。
标准取决于我们建模的案例。首先,标准取决于案例的可能值的范围。我们不能一概而论,认为 MAE 的某个值是绝对好的,而不管我们建模的情况如何。例如,当我们想要预测每天的温度和降雨量时。它们的可能值的范围是不同的,即雅加达的日温度可以从 25 度变化到 36 度(注意:实际上我不知道,这只是为了举例),但是对于降雨量,在极端天气的情况下,它可以从 0 度变化到 100 度甚至 200 度。
如果您想在不考虑范围值的情况下轻松确定模型的性能,只需将值的范围重新调整到您想要的比例即可。通常,你只用这个公式
其中,μ是数据集的平均值,σ是数据集的标准差。这个公式假设我们的数据集是正态分布的,因此 MAE like 1 或以上是一个非常糟糕的分数,不管范围值如何。您必须调整模型的超参数或使用数据集。
第二,标准取决于你案件的可预见性。不同的情况有不同的可预测性水平。像风速预测这样的现实世界案例(我们将在本文中演示的案例)往往具有较低的可预测性,因为现实世界是混乱的。可预测性是一个抽象的概念,我们无法得到可预测性水平的真实值。例如,在一种情况下,假设我们使用第一个公式重新调整数据集,MAE 为 0.2 是可以的,但在另一种情况下,这是一个糟糕的分数。为什么我们会得出这样的结论?用与现有模型或方法进行比较。这就是我们所说的标杆管理。而这正是我们讨论的重点。所有的数据集和代码都在下面。
https://github.com/genomexyz/benchmark_timeseries
在我之前的文章这里中,我已经演示了如何使用数据集的参数(平均值、中值、modus)对我们的模型进行基准测试。这一次,我们将尝试对时间序列模型进行基准测试。我们将尝试建模的是风速预测。事实上,当这篇文章写出来的时候,还没有现有的标准模型或方法(除了使用数值天气预报)来预测风速。因此,为了确定“现有模型或方法”的角色,让我们看一下我们的数据集。这些是大量的风速时间序列数据。
Kecepatan angin 是风速,arah angin 是风向,waktu 是时间。风速单位为米/秒。图片由作者提供
如您所见,相邻时间段的风速值相似。因此,我们可以选择的“现有模式或方法”是
未来的风速与当前条件下的风速相同
例如,现在的风速是 5 米/秒,那么未来 30 分钟的风速(我们的数据集具有 30 分钟的时间分辨率)也是 5 米/秒。
我们将评估的模型是时间卷积网络(TCN)。因此,首先我们将重建数据集的维度形状,以将其提供给 TCN。我们将数据分为两组,即训练数据和测试数据,就像任何其他 ML 模型一样。这是代码。
从这段代码中,我们将得到这样一个 excel 文件。
作者图片
作者图片
这里我没有重新调整我的数据集,这里显示的是风预测的真实值。让我们计算所有的误差,误差平均值,并绘制出来
误差平均值。作者图片
无论是从误差平均值还是从图表来看,我们的模型性能看起来都不错。这样真的好吗?让我们运行我们的基准模型并进行比较。
将benchmark_error_wind.xlsx
中的内容复制并粘贴到wind.xlsx
中,以便我们进行比较。
作者图片
这里是误差平均值
作者图片
整个情节。作者图片
由此我们知道,我们只提高了基准模型的精度(缩小误差平均值)大约 9.3% ,也就是不太好。看起来我们需要再次调整 TCN 的超参数或者重新排列我们的数据集。
这就是如何测试你的模型。这次我们的讨论很短,因为讨论的内容实际上很简单,但在我看来这很重要,所以我把它放在一篇单独的文章里。下一篇文章再见。
手动马尔可夫链示例,使用 Python
马库斯·斯皮斯克在 Unsplash 上的照片
一次解开一行代码中的马尔可夫链。
刚开始学物理的时候,我不喜欢概率这个概念。这个想法让我很兴奋,用物理可以模拟整个世界,不确定性的想法让我很愤怒:)
事实是,当我们想要研究真实的现象时,我们迟早必须处理一定程度的不确定性。处理它的唯一方法是获得一个精确的概率估计,这个概率决定了我们的过程。
马尔可夫链是一个很好的方法。马尔可夫链背后的思想非常简单:
未来会发生的一切只取决于现在正在发生的事情
用数学术语来说,我们说有一个随机变量序列 X_0,X_1,…,X_n 可以取某个集合 a 中的值。然后我们说,如果一个事件的序列是一个马尔可夫链,我们有:
我使用乳胶生成的图像
这听起来可能很复杂,但它只不过是上面表达的概念。
另一个假设是,该方程对每一步都有效(不仅仅是最后一步),并且概率总是相同的(即使形式上,这只对齐次马尔可夫链成立)。
现在,可能状态 A 的集合通常表示为样本空间 S,你可以用所谓的转移概率来描述从 S 中的状态 x 到 S 中的状态 y 的概率。
但是我向您保证,这将是一篇“动手”文章,所以让我们开始将这些概念形象化吧!
公平地说,Python 并不是执行数值模拟的最佳环境。专业研究人员使用更复杂的语言,在某种程度上也更可靠,比如 C 语言或 Fortran 语言。
尽管如此,这个博客的目标是介绍一些非常简单的概念,使用 Python 可以使这个学习过程更容易。
所以让我们开始吧:这是你需要的:
所以就是一堆主流库像 pandas , matplotlib,seaborn,numpy。
让我们从最简单的场景开始:
1.随机漫步
简单随机漫步是随机漫步的一个极其简单的例子。
第一个状态是 0,然后你以概率 0.5 从 0 跳到 1,以概率 0.5 从 0 跳到-1。
我用 Power Point 制作的图像
然后你对 x_1,x_2,…,x_n 做同样的事情。
你认为 S_n 是 n 时刻的状态。
有可能证明(其实很容易)在 t+1 时刻处于某个状态的概率,即一个整数 x,只取决于 t 时刻的状态,简而言之,就是一个马尔可夫链。
这是如何产生它的:
结果是:
现在随机漫步的想法是模拟如果我们决定从一个点开始,通过投掷一枚完美的硬币随机选择向上或向下会发生什么。
这个过程非常简单,但就其理论应用和性质而言,却非常有趣。
这个过程的第一个合理的扩展是考虑一个随机行走,但是使用一个不完美的硬币。意思是上升的概率和下降的概率不一样。这被称为有偏见的随机漫步。
让我们考虑以下几个概率:
[0.1,0.9] , [0.2,0.8], [0.4,0.6], [0.6,0.4], [0.8,0.2],[0.9,0.1]
所以我们有 6 种可能的随机漫步。请注意,概率必须为 1,因此考虑“向上”或“向下”的概率就足够了。
以下是您的操作方法:
这就是我们想象它时发生的事情。
2.赌徒的破产链
扩展随机漫步的另一个简单方法是赌徒的破产链。
从概念上讲,它非常类似于随机漫步:你从一个状态 x 出发,你可以以概率 p 到达一个状态 y=x+1,或者以概率 1-p 到达一个状态 y=x-1
我用 Power Point 制作的图像
有趣的是,当你到达 1 或 N 时,你基本上被卡住了。除了永远保持那种状态,你什么也做不了。
这个函数,给定:
- a 起点(例如 3)
- 第一个可能值(例如 0)
- 以及最后一个可能值(例如 5)
- 步数(如 10000)
给你最后的状态:
现在,在尝试这个功能之前,让我们考虑一个更有趣的情况。
假设我们从状态 3 开始。两步后进入状态 5 的概率是多少?
这是从状态 3 到状态 4,然后从状态 4 到状态 5 的概率:
我用乳胶制作的图像
在我们的例子中,它只是 0.25。
如果现在我们问这个等式:
假设我们从状态 3 开始。两步后结束于状态 1 的概率是多少?
同样,它是从状态 3 到状态 2,然后从状态 2 到状态 1 的概率:
我用乳胶制作的图像
同样,在我们的例子中,它只是 0.25。
唯一的另一种选择是在两步之后从状态 3 进入状态 3。我们可以用一种非常简单的方法来计算这个概率。由于总概率必须为 1,因此:
我用乳胶制作的图像
如果 p=0.5,它也是 0.5
同样,概率的概念是,如果我们重复一个实验无限次,我们应该能够验证概率值所暗示的事件。
3.自定义马尔可夫链
前面的模型是众所周知的,并被用作马尔可夫链的介绍性例子。让我们发挥创意,建造一个全新的非现有模型,就像下图中的一样。
我用 Power Point 制作的图像
我画画很糟糕,但模型本身很简单。
当你看到两个节点(比如 A 和 B)之间有一个箭头时,这意味着你可以从节点 A 开始到节点 B,这个箭头用黑色表示。
例如,从状态 A 到状态 B 的概率为 0.5
一个重要的概念是,模型可以用转移矩阵来概括,这解释了你的马尔可夫链中可能发生的一切。这是我们模型的转换矩阵:
如果你仔细观察这个模型,你会发现一些非常特别的东西。假设你从状态 2 跳到状态 3。你能回到状态 2 吗?答案是否定的。
这同样适用于状态 3 和状态 1。状态 1、3 和 2 因此被定义为瞬态。
另一方面,如果你从状态 4 开始,总有可能在某个时候,你会回到状态 4。这同样适用于状态 5。这些状态被称为循环状态。
让我们做些实验,以便能正确理解这个概念。
直观上,我们可以看到,从状态 2 开始不回到状态 2 的概率,随着步数趋于无穷大而趋于 0。
事实上,从状态 2 开始,经过 N 步后,我们发现自己处于状态 2 的概率如下:
我用乳胶制作的图像
事实上,如果我们从状态 2 到状态 3,我们不可能回到状态 2。让我们将这个理论函数定义为 t(N ),并绘制成图:
现在,让我们使用马尔可夫链,看看我们是否验证了同样的结果。
我们从状态 2 开始,并在 N 步后验证处于状态 2 的概率。**概率,在这种情况下,就是最终状态的 2 的个数和出现次数的比值。**为了保持一致,出现的次数需要趋于无穷大。让我们考虑 1000 次测试。
这是我们将要使用的函数:
让我们对不同的 N 使用这个函数,称之为 p(N):
可以看到,我们使用了转移矩阵来进行模拟。我们可以使用转移矩阵来评估我们正在考虑的马尔可夫链的所有属性。
4.结论
在这本笔记本中,我们已经看到了非常著名的模型,如随机漫步和赌徒的毁灭链。然后,我们创建了我们自己的全新模型,并对其进行了一点小小的改动,发现了一些重要的概念,如转换矩阵、循环状态和瞬态。最重要的是,我们已经看到了如何使用 Python 和众所周知的库以非常简单的方式验证这些概念。
如果你喜欢这篇文章,你想知道更多关于机器学习的知识,或者你只是想问我一些你可以问的问题:
A.在 Linkedin 上关注我,我在那里发布我所有的故事
B .订阅我的 简讯 。这会让你了解新的故事,并给你机会发短信给我,让我收到你所有的更正或疑问。
C .成为 推荐会员 ,这样你就不会有任何“本月最大数量的故事”,你可以阅读我(以及成千上万其他机器学习和数据科学顶级作家)写的任何关于现有最新技术的文章。
再见:)
实践:优化和基准身体姿势估计模型
Nvidia Body Pose Net 与 OpenPifPaf 模型
来自 Pexels 的 ThisIsEngineering 摄影
伊西多拉·斯坦科维奇,内韦娜·米勒托维奇,戈兰·贝纳克**,**德贝马尔亚·比斯瓦斯— 瑞士达尔文边缘
摘要 。Nvidia 最近宣布推出 2D 身体姿势估计模型 作为迁移学习工具包 3.0 的一部分。在本文中,我们提供了一个详细的教程来训练和优化模型。我们进一步提供了另一个广泛用于感知任务的开源模型的基准测试结果:OpenPifPaf——允许您决定何时使用哪个模型。
在之前的一篇文章[4]中,我们通过将身体姿势模型应用于现实生活中的医疗保健应用程序,展示了它的实际效用。该应用程序在病人家中监控病人,并在有人从床上摔下来、发生事故等情况时发出警报。这对于医院和养老院的居民来说是个大问题。
实践中的身体姿态检测(图片由作者提供)
训练身体姿态网络模型
在本节中,我们将介绍训练和优化 Nvidia 身体姿势网络模型所需的所有步骤。该模型使用 TAO Toolkit 进行训练,TAO Toolkit 使用预训练的模型和自定义数据集来构建新的 AI 模型[1]。
第一步是安装和运行 TAO 工具包。遵循此链接中的步骤:
登录到 NGC docker 注册表后,运行以下命令:
mkdir Programs
cd Programs/
wget -O ngccli_linux.zip [https://ngc.nvidia.com/downloads/ngccli_linux.zip](https://ngc.nvidia.com/downloads/ngccli_linux.zip) && unzip -o ngccli_linux.zip && chmod u+x ngc
mkdir ngccli_linux
cd ngccli_linux/
chmod u+x ngc
echo "export PATH=\"\$PATH:$(pwd)\"" >> ~/.bash_profile && source ~/.bash_profile
cd ..
ngc config set
ngc registry model list
我们使用 conda 虚拟环境(按照链接中的步骤安装 Anaconda)。要创建并激活虚拟环境,请运行以下两个命令:
conda create -n 'env_name' python=3.7
conda activate 'env_name'
该工具包现在可以使用了,培训准备工作可以继续进行。在这一页中,解释了强制步骤。第一步是环境设置,其中下载了最新的示例(用于设置培训的配置文件),设置了 env 变量并创建了挂载文件。最后,安装所需的依赖项。下一步是下载预先训练好的模型。
用来训练这个模型的数据集是 COCO 数据集,它是从这个链接下载的。
应该是这样组织的:
<user>
├──tlt-experiments
├──bpnet
├──data
├──annotations
├──test2017
├──train2017
└──val2017
数据集需要为训练做准备,因此分段掩码与 tfrecords 一起生成。配置文件和所用命令的详细解释可在这里找到。
下一步是为训练配置 spec 文件,它包含六个组件:训练器、数据加载器、增强、标签处理器、模型和优化器。我们使用默认的规范文件,即/workspace/examples/BP net/specs/BP net _ train _ m1 _ coco . YAML。
现在可以开始训练了。
我们在 Nvidia GeForce RTX 2080 GPU 上的培训过程持续了 104 个小时。
用于评估模型的度量是精确度和召回率。这些值按以下方式计算:
其中 TP 是真阳性的数量,FP 是假阳性的数量,FN 是假阴性的数量。针对交集/并集(IoU)的不同阈值计算精度和召回率。IoU 是基于预测边界框和地面真实边界框之间的重叠计算的参数。
例如,如果 IoU 阈值为 0.5,并且用于预测的 IoU 值为 0.7,则该预测被分类为真阳性。反之,如果 IoU 为 0.3,则归类为假阳性。假阴性是未能预测图像中的对象的预测。
在评估结果中,IoU 阈值为 0.5:0.95。这意味着精度和召回率是通过对 0.5 和 0.95 之间的不同阈值以特定步长平均精度和召回率来计算的。
我们在验证集上得到的准确率和召回率是:
最佳化
使用 TAO Toolkit 对模型进行的优化在此处解释。优化模型的一种方法是修剪。它消除了低量级的权重,从而产生压缩模型,占用较少的内存资源[2]。
修剪后的准确率和召回率不明显降低,因此使用修剪模型是合理的。
修剪后,建议重新训练模型,因为修剪会导致精度下降。在同一个 GPU 和数据集上的再训练持续了 99 个小时。重新训练模型的评估结果是:
OpenPifPaf 基准测试
OpenPifPaf [3]是一种通用的神经网络架构,它使用复合场来实时检测和构建时空姿态。我们使用自然人体运动的几何学来计算和检测预先确定的感兴趣区域中的身体位置,以检测一个人是否站着、坐着、躺着、摔倒等。
OpenPifPaf 和 Body Pose Net 模型都是自底向上的实现,这意味着它们检测图像中的所有关节,然后将属于不同人的部分关联起来。另一方面,自上而下的方法首先检测人,然后对每个人执行单人姿势估计以预测人体关节[5]。
自下而上的方法更适合有人群的图像,以及复杂的姿势和人们互相遮挡的情况。
OpenPifPaf 模型也在 COCO 数据集上进行了训练。评估是在与身体姿态网络模型相同的验证集上进行的。以下是我们在相同输入量下得到的结果:
用于训练 OpenPifPaf 模型的参数与用于身体姿势网络的参数略有不同。学习率是 0.001,而在身体姿势网络模型中,基本学习率是 2e-5,最小学习率是 8e-8。动量为 0.95,而 BP 网络使用 0.9。最后,批量大小是 8,而不是 BP 网络中的 10。
事实证明,OpenPifPaf 模型为每个 IoU 阈值提供了更好的结果。IoU=0.5:0.95 的平均精度是 0.621,而身体姿势网络模型中的相同度量是 0.487。
结果
为了模型的视觉比较,我们使用了新的数据集— Halpe 全身人体关键点 数据集。
此处描述的两个模型从未见过该数据集。选择某个子集来可视化这些模型提供的预测结果。
Nvidia Body Pose Net 与 OpenPifPaf 的基准测试
参考
[2]开尔文。通过修剪进行模型压缩。https://towards data science . com/model-compression-via-pruning-ac9b 730 a 7 c 7 b
[3]克里斯、贝尔托尼和阿拉希:OpenPif-Paf: 语义关键点检测和时空关联的复合字段。arXiv,abs/2103.02440,2021。
[4] M. Vuletic 等人。艾尔。面向医疗保健应用的 Edge AI 框架。2021 年 8 月,关于人工智能用于老龄化、康复和智能辅助生活的第四届 IJCAI 研讨会( ARIAL )。https://medium . com/Darwin-edge-ai/edge-ai-framework-for-rapid-prototyping-and-deployment-cabf 466 DD def
[5] 深度学习的人体姿态估计概述——beyond minds
动手操作 PostgreSQL:基本查询
世界上最先进的开源关系数据库
SQL 提供了许多函数和方法来管理以表格形式存储的数据。关系数据库管理系统(RDBMS)是一个使用 SQL 来管理存储在关系数据库中的数据的程序。
关系数据库包含许多通过共享列相互关联的表。有许多不同的 RDBMSs,如 MySQL、PostgreSQL、SQL Server 等等。
我之前写了一篇文章作为对 PostgreSQL 的介绍,解释了如何设置 PostgreSQL 数据库和创建表。在本文中,我们将讨论几个演示如何查询关系数据库的例子。
第一步是创建一个我们可以查询的表。一种选择是创建表,并使用 insert 语句手动填充它。更实用的方法是从 csv 文件中复制数据。
我有一个 csv 文件,其中包含了 Kaggle 上提供的墨尔本住房数据集的一些列。我们需要在从文件上传数据之前创建表。
CREATE TABLE houses ( HouseId SERIAL, Type VARCHAR(20), Date date, Rooms INT, Distance real, Landsize real, Price real, PRIMARY KEY (HouseId) );
表格中的列必须与 csv 文件中的列兼容。第一个字表示列名,第二个字表示数据类型。
我们现在可以将 csv 文件中的数据复制到 houses 表中。
\COPY houses(HouseId, Type, Date, Rooms, Distance, Landsize, Price) FROM '/Users/sonery/Downloads/melb_sql/houses.csv' DELIMITER ',' CSV HEADER;
第一行包括表名和列名。然后,我们写入将用于复制数据的文件的路径。最后两行是关于 csv 文件的特征。
我们现在可以开始查询 houses 表。让我们首先检查表中有多少观察值(即行)。
SELECT COUNT(1) FROM houses;count
-------
13580(1 row)
我们使用 count 函数来计算行数。因为每一列都包含相同数量的行,所以我们可以将任何一列传递给 count 函数。
我们可以通过显示前 5 行来看看这个表。
SELECT * FROM houses LIMIT 5;
(图片由作者提供)
SQL 也可以被认为是一种数据分析工具。它提供了多种过滤、分析和转换数据的功能和方法。
例如,我们可以查看价格超过 100 万英镑的房屋数量。我们只需要使用 where 语句添加一个条件。
SELECT COUNT(1) FROM houses
WHERE price > 1000000;count
-------
5743(1 row)
where 语句接受多个条件。我们来求 h 型,距离大于 2 的房子的最高价。
SELECT MAX(price) FROM houses WHERE distance > 2 AND type = 'h';max
-------
9000000(1 row)
我们在价格列上使用 max 函数。过滤条件与“and”关键字相结合。
SQL 函数提供了极大的灵活性和多功能性。考虑前面的例子。结果集中的聚合列显示了函数名,但实际上并没有告诉我们它代表什么。
“as”关键字可用于为聚合列分配别名。我们也可以用 1000000 除以百万来表示价格。
SELECT MAX(price / 1000000) AS price_million FROM houses WHERE distance > 2 AND type = 'h';price_million
---------------
9(1 row)
数据分析中常用的函数是 group by。它根据列中的不同值对行进行分组,然后允许对数值执行聚合。
例如,我们可以计算每种房屋类型的平均价格。
SELECT type, AVG(price) AS avg_price FROM houses GROUP BY type;type | avg_price
-----+-------------------
t | 933735.0538599641
h | 1242664.761138745
u | 605127.4845873384(3 rows)
该查询的作用是选择 type 和 price 列,然后根据 type 列中的类别对行进行分组。avg 函数计算每个类别的平均房价。
我们还可以使用 order by 语句对结果集中的值进行排序。我们来看看最近公布的 5 栋房子的身份证号码。为了使情况稍微复杂一点,我们还将在距离列上添加一个条件进行过滤。
SELECT houseid, date FROM houses
WHERE distance BETWEEN 2 AND 3
ORDER BY date desc
LIMIT 5;houseid | date
--------+------------
10879 | 2017-12-08
10880 | 2017-12-08
10877 | 2017-12-08
10878 | 2017-12-08
10973 | 2017-12-08(5 rows)
我们首先实现过滤条件,然后对结果进行排序。默认情况下,order by 语句按升序对结果进行排序。我们可以用 desc 关键字改变它的行为。
结论
我们已经做了几个例子来演示如何编写基本查询来从表中检索数据。全面理解基本 SQL 语句至关重要。高级查询是在基本查询的基础上创建的。
我计划通过逐渐增加复杂性来写更多关于 PostgreSQL 的文章。敬请关注更多内容!
感谢您的阅读。如果您有任何反馈,请告诉我。
实践强化学习课程:第 1 部分
实践教程
从零到英雄,一步一个脚印。
凯(图片作者提供)
欢迎来到我的强化学习课程!❤️
让我们一步一步地走在这条从基础到前沿强化学习(RL)的美丽道路上,一起用 Python 编写代码示例和教程吧!
这第一部分涵盖了开始这一旅程所需的最基本的概念和理论。然后,在接下来的每一章中,我们将解决一个不同的问题,难度越来越大。
最终,最复杂的 RL 问题涉及强化学习算法、优化和深度学习的混合。
您不需要了解深度学习(DL)来学习本课程。我会给你足够的背景,让你熟悉 DL 哲学,并理解它如何成为现代强化学习的一个重要组成部分。
第一部分
在第一课中,我们将通过例子、数学和一点 Python 知识来讲述强化学习的基础。
内容
- 什么是强化学习问题?🤔
- 政策👮🏽和值函数。
- 如何生成训练数据?📊
- Python 样板代码。🐍
- 重述✨
- 家庭作业📚
- 下一步是什么?❤️
开始吧!
1.什么是强化学习问题?🤔
强化学习(RL)是机器学习(ML)中与学习问题相关的一个领域,其中
一个智能代理 🤖需要学习,通过试错,如何采取 行动 内心和 环境 🌎为了最大限度地获得的累计奖励。
强化学习是最接近人类和动物学习方式的一种机器学习。
什么是代理?还有一个环境?代理可以采取的具体行动是什么?奖励呢?为什么说累积奖励?
如果你问自己这些问题,你就在正确的轨道上。
我刚刚给出的定义引入了一堆你可能不熟悉的术语。其实他们是故意暧昧的。这种普遍性使得 RL 适用于广泛的看似不同的学习问题。这是数学建模背后的哲学,它停留在 RL 的根源。
让我们来看看几个学习问题,并通过强化学习的视角来看待它们🔍。
例子 1:学习走路🚶🏽♀️🚶🏿🚶♀️
作为一个刚刚开始走路的孩子的父亲,我不禁问自己,他是怎么学会的?
凯和保罗(图片由作者提供)
作为一名机器学习工程师,我幻想着用软件和硬件来理解和复制那条不可思议的学习曲线。
让我们尝试使用 RL 成分来模拟这个学习问题:
- 经纪人是我的儿子凯。他想站起来走路。他的肌肉在这个时候足够强壮,有机会尝试。对他来说,学习的问题是:如何顺序调整他的身体位置,包括他的腿、腰、背和手臂上的几个角度,以平衡他的身体,不摔倒。
- 环境是他周围的物理世界,包括物理定律。其中最重要的是重力。如果没有重力,学会走路的问题将会彻底改变,甚至变得无关紧要:为什么你想要在一个你可以简单地飞翔的世界里行走?这个学习问题中的另一个重要定律是牛顿第三定律,用简单的话来说就是,如果你摔倒在地板上,地板将以同样的力度回击你。哎哟!
- 动作是这些身体角度的所有更新,当他开始追逐周围的东西时,这些角度决定了他的身体位置和速度。当然,他可以同时做其他事情,比如模仿奶牛的声音,但这些可能不会帮助他实现他的目标。我们在我们的框架中忽略了这些动作。添加不必要的动作不会改变建模步骤,但是会使问题以后更难解决。
- 他收到的奖励是来自大脑的刺激,让他快乐或感到痛苦。当他摔倒在地板上时,会有负面的回报,那就是身体上的疼痛,随后可能会感到沮丧。另一方面,有几件事对他的快乐有积极的影响,比如更快到达目的地的快乐👶🚀或者是当我和我的妻子贾戈达说“干得好”时的外部刺激。或 Bravo!“对每一次尝试和边际改善他都表现出来。
一个重要的(也是显而易见的)备注是,Kai 不需要学习牛顿的物理学来站立和行走。他将通过观察环境的状态来学习,采取行动,并从这个环境中收集奖励。他不需要学习环境的模型来实现他的目标。
关于奖励的更多信息💰
奖励对凯来说是一个信号,他一直在做的事情对他的学习是好是坏。随着他采取新的行动,经历痛苦或快乐,他开始调整自己的行为,收集更多积极的反馈,减少消极的反馈。换句话说,他学会了
有些动作在开始时对宝宝来说可能看起来很有吸引力,比如试着奔跑来获得刺激。然而,他很快了解到,在一些(或大多数)情况下,他最终摔倒在地,并经历了一段时间的痛苦和眼泪。这就是为什么聪明的代理人最大化累积报酬,而不是边际报酬。他们用长期回报换取短期回报。一个能立即得到回报,但却让我的身体处于即将倒下的位置的行动,并不是一个最佳的行动。
巨大的快乐伴随着更大的痛苦并不是长期幸福的秘诀。这是婴儿通常比我们成年人更容易学会的东西。
奖励的频率和强度是帮助代理学习的关键。很少(稀疏)的反馈意味着更难学习。想想看,如果你不知道你做的是好是坏,你怎么能学习呢?这是为什么有些 RL 问题比其他问题难的主要原因之一。
对于许多现实世界的 RL 问题来说,奖励塑造是一个艰难的建模决策。
示例 2:学习像职业玩家一样玩大富翁游戏🎩🏨💰
小时候,我花了很多时间和朋友、亲戚玩大富翁。谁没有呢?这是一个令人兴奋的游戏,结合了运气(你掷骰子)和策略。
大富翁是一款两人至八人的房地产棋盘游戏*。你掷两个骰子在棋盘上走来走去,购买和交易房产,开发房子和酒店。你从你的对手那里收取租金,目的是让他们破产。***
图片来自 Pexels
如果你对这个游戏如此着迷,以至于你想找到玩这个游戏的聪明方法,你可以使用一些强化学习。
4 RL 成分是什么?
- 经纪人是你,一个想在大富翁游戏中获胜的人。
- 你的动作就是你在下面这张截图上看到的动作:
垄断中的行动空间。 阿勒夫·阿塞法
- 环境是游戏的当前状态,包括每个玩家拥有的财产、位置和现金数量的列表。还有对手的策略,这是你无法预测的,也是你无法控制的。
- 而奖励是 0,除了你最后一步棋,如果你赢了游戏就是+1,如果你破产就是-1。这种奖励方式有道理,但却让问题难以解决。我们上面说过,更稀疏的奖励意味着更难的解决方案。正因为如此,才有了 其他方式 来塑造奖励,让它们更吵但不那么稀疏。
当你和另一个人玩“大富翁”时,你不知道她或他会怎么玩。你能做的就是和自己玩。当你学着玩得更好时,你的对手也一样(因为是你),迫使你提高游戏水平以保持胜利。你可以看到正反馈循环。
这一招叫自玩。它为我们提供了一条无需使用专家玩家的外部建议就能引导智能的途径。
自玩是 AlphaGo 和 AlphaGo Zero 的主要区别,这两个由 DeepMind 开发的模型比任何人类都玩围棋。
示例 3:学习驾驶🚗
几十年后(也许更短),机器将驱动我们的汽车、卡车和公共汽车。
但是,如何?
学开车不容易。司机的目标很明确:从 A 点到 B 点,让她和车上的乘客都感到舒适。
对驾驶员来说,有许多外部因素使驾驶变得具有挑战性,包括:
- 其他驾驶员行为
- 交通标志
- 行人行为
- 路面状况
- 天气状况。
- …甚至燃料优化(谁愿意在这上面多花钱?)
我们如何用强化学习来解决这个问题?
- 代理人是想舒适地从 A 地到达 B 地的司机。
- 驾驶员观察到的环境的状态有很多东西,包括汽车的位置、速度和加速度、所有其他汽车、乘客、路况或交通标志。可以想象,将如此巨大的输入向量转化为适当的行动是多么具有挑战性。
- 动作基本就是三个:方向盘方向、油门力度、刹车力度。
- 每次行动后的奖励是驾驶时你需要平衡的不同方面的加权总和。到 B 点的距离减少会带来积极的回报,而增加则会带来消极的回报。为了确保不发生碰撞,与另一辆车,甚至行人靠得太近(甚至碰撞)应该有非常大的负面奖励。此外,为了鼓励平稳驾驶,速度或方向的急剧变化会导致负面奖励。
在这 3 个例子之后,我希望 RL 元素的以下表示以及它们如何一起发挥作用是有意义的:
强化学习成分(图片由作者提供)
既然我们知道了如何用公式表示一个 RL 问题,我们需要解决它。
怎么会?
继续读下去!
2.政策和价值函数
政策
代理根据环境的当前状态选择她认为最好的操作。
这就是代理人的策略,通常被称为代理人的政策。
一个 策略 是一个从状态到动作的学习映射。
解决强化学习问题意味着找到最佳策略。
策略或者是确定性的,当它们将每个状态映射到一个动作时,
或者当他们将每个状态映射到所有可能行为的概率分布时,称为随机。
随机是你在机器学习中经常读到和听到的一个词,本质上是指不确定、随机。在具有高度不确定性的环境中,比如你正在掷骰子的垄断,随机政策比确定性政策更好。
存在几种方法来实际计算这个最优策略。这些被称为策略优化方法。
价值函数
有时,根据问题的不同,可以尝试找到与最优策略相关的值函数,而不是直接尝试找到最优策略。
但是,什么是价值函数?
在那之前,
在这个上下文中,价值是什么意思?
值 是与环境的每个状态相关联的数字,用于估计代理处于状态有多好。**
从状态开始,根据策略****【π】选择动作时,代理收集的累计奖励。
价值函数是从状态到价值的学习映射。
政策的价值函数通常表示为
值函数也可以将(动作、状态)对映射到值。在这种情况下,它们被称为 q 值函数。
最优值函数(或 q 值函数)满足一个数学方程,称为贝尔曼方程**。**
这个方程是有用的,因为它可以被转换成一个迭代过程来寻找最佳值函数。
但是,为什么价值函数有用?
因为你可以从一个最优 q 值函数中推断出一个最优策略。**
如何?
最优策略是在每个状态 s 时,代理选择使 q 值函数最大化的动作 a 的策略。
所以,你可以从最优策略跳到最优 q 函数,反之亦然😎。
有几种 RL 算法专注于寻找最佳 q 值函数。这些被称为Q-学习方法**。**
强化学习算法的动物学🐘🐅🦒
有许多不同的 RL 算法。一些人试图直接找到最优策略,另一些人试图找到 q 值函数,还有一些人试图同时找到两者。
RL 算法的动物学是多样的,有点吓人。
谈到 RL 算法,没有“一刀切”的。每次你解决一个 RL 问题时,你都需要尝试其中的一些方法,看看哪种方法适合你的情况。
在学习本课程的过程中,您将实现其中的几种算法,并深入了解在每种情况下什么效果最好。
3.如何生成训练数据?📊
强化学习代理非常需要数据。
为了解决 RL 问题,你需要大量的数据。
克服这一障碍的方法是使用模拟环境。编写模拟环境的引擎通常比解决 RL 问题需要更多的工作。此外,不同引擎实现之间的变化会使算法之间的比较变得毫无意义。
这就是为什么 OpenAI 的家伙们在 2016 年发布了 健身房工具包 。OpenAIs 的 gym 为不同问题的环境集合提供了一个标准化的 API,包括
- 经典的雅达利游戏,
- 机械臂
- 或者登月(嗯,一个简化的)
也有专有环境,像 MuJoCo ( 最近被 DeepMind 收购)。MuJoCo 是一个你可以在 3D 中解决连续控制任务的环境,比如学习走路👶。
OpenAI Gym 还定义了一个标准的 API 来构建环境,允许第三方(比如您)创建您的环境并让其他人可以使用。
如果你对自动驾驶汽车感兴趣,那么你应该看看卡拉,这是最受欢迎的开放式城市驾驶模拟器。
4.Python 样板代码🐍
你可能会想:
到目前为止,我们讨论的内容很有趣,但是我如何用 Python 来写这些内容呢?
我完全同意你的观点😊
让我们看看这一切在 Python 中是怎样的。
有没有发现这段代码有什么不清楚的地方?
23 号线呢?这个ε是什么?
不要惊慌。我以前没有提到这一点,但我不会没有解释就离开你。
Epsilon 是一个关键参数,确保我们的代理在得出每个状态下最佳行动的明确结论之前,充分探索环境。
它是一个介于 0 和 1 之间的值,代表代理选择随机行动而不是她认为最好的行动的概率。
探索新策略和坚持已知策略之间的权衡被称为探索-开发问题**。这是 RL 问题中的一个关键因素,也是 RL 问题与监督机器学习的区别。**
从技术上讲,我们希望代理找到全局最优,而不是局部最优。
良好的做法是以较大的值(例如 50%)开始训练,并在每次训练后逐渐减少。通过这种方式,代理在开始时探索了很多,随着她策略的完善,探索的越来越少。
5.重述✨
第一部分的关键要点是:
- 每个 RL 问题都有一个代理(或多个代理)、环境、动作、状态和奖励。
- 代理人依次采取行动,目标是最大化总报酬。为此,她需要找到最佳策略。
- 价值函数是有用的,因为它们为我们提供了寻找最优策略的另一种途径。
- 在实践中,您需要针对您的问题尝试不同的 RL 算法,看看什么效果最好。
- RL 代理需要大量的训练数据来学习。OpenAI gym 是一个很好的工具,可以重复使用和创建你的环境。
- 在训练 RL 代理时,探索与利用是必要的,以确保代理不会陷入局部最优。
6.家庭作业📚
没有一点家庭作业的课程就不是课程。
我想让你选择一个你感兴趣的现实世界的问题,你可以用强化学习来建模和解决。
挑一个你关心的问题。这些是你想把宝贵的时间花在上面的。
定义什么是代理、行动、状态和奖励。
如果您有任何问题,请随时在【plabartabajo@gmail.com】给我发电子邮件,我会给您反馈。
7.下一步是什么?
在 第二部分 中,我们使用 Q-learning 解决了第一个强化学习问题。
那里见!
想支持我吗?
你喜欢阅读和学习关于 ML、AI 和数据科学的知识吗?
无限制地访问我在 Medium 上发布的所有内容,并支持我的写作。
👉🏽今天使用我的 推荐链接 成为会员。
**https://pau-labarta-bajo.medium.com/membership
👉🏽订阅 datamachines 简讯 。
👉🏽给我很多掌声👏🏿👏🏽👏在下面
祝你愉快🤗
避寒胜地**
实践强化学习课程:第 2 部分
实践教程
表格 Q 学习
来自 Pexels 的海伦娜·扬科维奇
欢迎来到我的强化学习课程❤️
这是我强化学习实践课程的第二部分,带你从零到英雄🦸♂️.
如果您错过了 part 1 ,请阅读它,以便将强化学习术语和基础知识掌握到位。
今天我们要解决第一个学习问题…
我们将训练一名代理人驾驶出租车🚕🚕🚕!
嗯,一个简化版的出租车环境,但是一天结束的时候出租车。
我们将使用 Q-learning,这是最早和最常用的 RL 算法之一。
当然,还有 Python🐍。
本课所有代码在 本 Github repo 中。 Git 克隆它,跟随今天的问题。
第二部分
内容
- 出租车驾驶问题🚕
- 环境、行动、状态、奖励
- 随机代理基线🤖🍷
- q-学习代理🤖🧠
- 超参数调谐🎛️
- 重述✨
- 家庭作业📚
- 下一步是什么?❤️
1.出租车驾驶问题🚕
我们将使用强化学习来教一个智能体驾驶出租车。
首先,在现实世界中驾驶出租车是一项非常复杂的任务。因此,我们将在一个简化的环境中工作,该环境包含一名优秀出租车司机所做的三件重要事情,即:
- 接载乘客并把他们送到他们想要的目的地。
- 安全驾驶,意味着没有碰撞。
- 在尽可能短的时间内驾驶它们。
我们将使用 OpenAI Gym 中的一个环境,称为[**Taxi-v3**](https://gym.openai.com/envs/Taxi-v3/)
环境。
出租车环境(图片由作者提供)
在网格世界中有四个指定的位置,分别用 R(ed)、G(reen)、Y(ellow)和 B(lue)表示。
当这一集开始时,出租车在一个随机的广场出发,乘客在一个随机的位置(R,G,Y 或 B)。
出租车开到乘客所在地,接乘客,开到乘客的目的地(四个指定地点中的另一个),然后让乘客下车。在这样做的时候,我们的出租车司机需要小心驾驶,以避免撞到任何墙壁,标记为 | 。一旦乘客下车,这一集就结束了。
这就是我们今天将构建的 q-learning 代理如何驱动:
优秀的出租车司机
在我们到达那里之前,让我们很好地理解什么是这个环境的行动、状态和回报。
2.环境、行动、状态、奖励
👉🏽notebooks/00 _ environment . ipynb
让我们首先加载环境:
在每个步骤中,代理可以选择哪些操作?
0
往下开1
开车过来2
向右行驶3
向左行驶4
搭载乘客5
让乘客下车
表示?
- 25 个可能的滑行位置,因为世界是一个 5x5 的网格。
- 乘客的 5 个可能位置,即 R、G、Y、B,加上乘客在出租车中的情况。
- 4 个目的地位置
这给了我们 25×5×4 = 500 个状态
那么奖励呢?
- -1 默认每步奖励。
为什么-1,而不是简单的 0?因为我们希望通过惩罚每一个额外的步骤来鼓励代理花费最短的时间。这就是你对出租车司机的期望,不是吗? - +20 将乘客送到正确目的地的奖励。
- -10 在错误地点执行取货或卸货的奖励。
可以从env.P.
读取奖励和环境转换*(状态,动作)→ next_state*
顺便说一句,你可以在每个状态下渲染环境来仔细检查这个env.P
向量是否有意义:
来自state=123
州= 123
代理向南移动action=0
到达state=223
州=223
奖励是-1,因为这一集既没有结束,也没有司机错误地选择或放弃。
3.随机代理基线🤖🍷
👉🏽notebooks/01 _ random _ agent _ baseline . ipynb
在您开始实现任何复杂的算法之前,您应该总是建立一个基线模型。
这个建议不仅适用于强化学习问题,也适用于一般的机器学习问题。
直接跳到复杂/花哨的算法中是非常有诱惑力的,但是除非你真的很有经验,否则你会失败得很惨。
让我们使用一个随机代理🤖🍷作为基准模型。
我们可以看到这个代理对于给定的初始state=198
的表现
3804 步很多!😵
请在此视频中亲自观看:
行动中的随机代理
为了获得更有代表性的性能度量,我们可以重复相同的评估循环n=100
次,每次从随机状态开始。
如果你画出timesteps_per_episode
和penalties_per_episode
,你可以观察到它们都没有随着代理完成更多的剧集而减少。换句话说,代理没有学到任何东西。
如果您想要性能的汇总统计,您可以取平均值:
实现代理学习是强化学习的目标,也是本课程的目标。
让我们使用 Q-learning 实现我们的第一个“智能”代理,Q-learning 是现存的最早和最常用的 RL 算法之一。
4.q-学习代理🤖🧠
Q-learning (by 克里斯·沃金斯 🧠和 彼得·达扬 🧠)是一种寻找最优 q 值函数的算法。
正如我们在第 1 部分中所说的,与策略 π 相关联的 Q 值函数 Q(s,a) 是代理人在状态 s 采取行动 a 并随后遵循策略 π 时期望得到的总报酬。
最优 Q 值函数 Q(s,a)* 是与最优策略 π*相关联的 Q 值函数。
如果你知道 Q(s,a)* 你可以推断π*:也就是说,你选择一个最大化当前状态 s 的 Q*(s,a)的动作作为下一个动作。
Q-learning 是一种迭代算法,从任意初始猜测 Q⁰(s,a) 开始,计算最佳 q 值函数 Q(s,a)* 的越来越好的近似值
在类似于Taxi-v3
的表格环境中,状态和动作的数量有限,q 函数本质上是一个矩阵。它的行数与状态数一样多,列数与动作数一样多,即 500 x 6。
好的,但是你如何准确地从 Q⁰(s,a)计算下一个近似值 Q (s,a)?
这是 Q-learning 的关键公式:
q-学习公式(图片由作者提供)
当我们的 q-agent 导航环境并观察下一个状态***s’***和奖励 r 时,你用这个公式更新你的 q-值矩阵。
这个公式中的学习率 𝛼 是多少?
学习率(通常在机器学习中)是一个小数字,它控制 q 函数的更新量。你需要调整它,因为太大的值会导致不稳定的训练,太小的值可能不足以避开局部最小值。
还有这个折现因子 𝛾 ?
折扣因子是一个介于 0 和 1 之间的(超)参数,它决定了相对于近期的回报,我们的代理人对远期回报的关心程度。
- 当𝛾=0 时,代理人只关心眼前报酬的最大化。正如生活中发生的那样,最大化眼前回报并不是获得最佳长期结果的最佳方法。这也发生在 RL 特工身上。
- 当𝛾=1 时,代理人根据其所有未来报酬的总和来评估其每一个行为。在这种情况下,代理人同等重视眼前的回报和未来的回报。
折扣因子通常是中间值,例如 0.6。
总而言之,如果你
- 训练足够长的时间
- 有着不错的学习率和折扣系数
- 代理在状态空间中探索了足够多的时间
- 你用 Q 学习公式更新 Q 值矩阵
你的初始近似最终会收敛到最优 q 矩阵。瞧啊。
那么让我们为 Q-agent 实现一个 Python 类。
Q-agent 的 API
它的 API 与上面的RandomAgent
相同,但是多了一个方法update_parameters()
。该方法采用转移向量(state, action, reward, next_state)
,并使用上面的 Q 学习公式更新 Q 值矩阵近似值self.q_table
。
现在,我们需要将这个代理插入到一个训练循环中,并在代理每次收集新的经验时调用它的update_parameters()
方法。
此外,记住我们需要保证代理充分探索状态空间。还记得我们在第一部分中谈到的勘探-开采参数吗?这就是epsilon
参数进入游戏的时候。
让我们为n_episodes = 10,000
培训代理,并使用epsilon = 10%
还有剧情timesteps_per_episode
和penalties_per_episode
不错!这些图表看起来比RandomAgent
好得多。这两个指标都随着训练而下降,这意味着我们的代理正在学习🎉🎉🎉。
我们实际上可以看到代理是如何从与我们用于RandomAgent
相同的state = 123
开始驱动的。
好棒的车!
如果你想比较硬数字,你可以评估 q-agent 的性能,比如说,100 个随机事件,并计算时间戳和招致的惩罚的平均数。
一点点关于ε贪婪政策
评估代理时,使用正的epsilon
值而不是epsilon = 0.
值仍然是一个好的做法
为什么会这样?我们的特工不是训练有素吗?为什么我们在选择下一个行动时需要保留这种随机性的来源?
原因是防止过度拟合。即使对于这样一个小州,在Taxi-v3
(即 500 x 6)中的行动空间,很可能在培训期间我们的代理没有访问足够的特定州。
因此,它在这些状态下的性能可能不是 100%最佳的,导致代理“陷入”次优操作的几乎无限循环中。
如果 epsilon 是一个小正数(例如 5%),我们可以帮助代理摆脱这些次优行为的无限循环。
通过在评估时使用小ε,我们采用了所谓的ε贪婪策略。
让我们使用epsilon = 0.05.
来评估我们在n_episodes = 100
上训练过的代理,观察这个循环看起来几乎与上面的训练循环完全一样,但是没有调用update_parameters()
这些数字看起来比RandomAgent.
好得多
我们可以说我们的代理已经学会开出租车了!
q 学习为我们提供了一种计算最优 q 值的方法。但是,超参数 alpha
、gamma
和epsilon
呢?
我为你选择了它们,相当随意。但是在实践中,您将需要针对您的 RL 问题来调整它们。
让我们探索它们对学习的影响,以获得对正在发生的事情的更好的直觉。
5.超参数调谐🎛️
👉🏽notebooks/03 _ q _ agent _ hyperparameters _ analysis . ipynb
让我们使用不同的值alpha
(学习率)和gamma
(折扣因子)来训练我们的 q-agent。至于 T2,我们保持在 10%。
为了保持代码整洁,我将 q-agent 定义封装在[src/q_agent.py](https://github.com/Paulescu/hands-on-rl/blob/50c61a385bbd511a6250407ffb1fcb59fbfb983f/01_taxi/src/q_agent.py#L4)
中,并将训练循环封装在[src/loops.py](https://github.com/Paulescu/hands-on-rl/blob/50c61a385bbd511a6250407ffb1fcb59fbfb983f/01_taxi/src/loops.py#L9)
的train()
函数中
让我们为每个超参数组合绘制每集的timesteps
。
这张图看起来很艺术,但有点太吵杂了😵。
不过你可以观察到,当alpha = 0.01
时,学习速度变慢。alpha
(学习率)控制我们在每次迭代中更新多少 q 值。值太小意味着学习速度较慢。
让我们放弃alpha = 0.01
,对每个超参数组合进行 10 次训练。我们使用这 10 次运行,对从 1 到 1000 的每个剧集编号的timesteps
进行平均。
我在src/loops.py
中创建了函数[train_many_runs()](https://github.com/Paulescu/hands-on-rl/blob/50c61a385bbd511a6250407ffb1fcb59fbfb983f/01_taxi/src/loops.py#L121)
来保持笔记本代码的整洁:
看起来alpha = 1.0
是效果最好的值,而gamma
似乎影响较小。
恭喜你!🥳,你已经在本课程中调整了你的第一个学习率
调整超参数既费时又乏味。有一些优秀的库可以自动完成我们刚刚完成的手动过程,比如【Optuna】,但是这是我们将在课程的后面部分使用的。暂时享受一下我们刚刚发现的训练提速。
等等,我告诉你要相信我的这个epsilon = 10%
怎么了?
现在的 10%值是最好的吗?
我们自己检查一下。
我们选择找到的最好的alpha
和gamma
,即
alpha = 1.0
gamma = 0.9
(我们也可以选择0.1
或0.6
)
和训练用不同的epsilons = [0.01, 0.1, 0.9]
并绘制产生的timesteps
和penalties
曲线:
如你所见,epsilon = 0.01
和epsilon = 0.1
似乎都工作得很好,因为它们在勘探和开发之间取得了恰当的平衡。
另一方面,epsilon = 0.9
是一个太大的值,导致训练过程中“太多”的随机性,并阻止我们的 q 矩阵收敛到最优值。观察性能如何稳定在每集大约250 timesteps
的水平。
一般来说,选择epsilon
超参数的最佳策略是渐进ε衰变。也就是说,在训练开始时,当代理对其 q 值估计非常不确定时,最好访问尽可能多的州,为此,大的epsilon
是很好的(例如 50%)
随着训练的进行,代理改进了它的 q 值估计,探索那么多不再是最佳的。相反,通过减少epsilon
,代理可以学习完善和微调 q 值,使它们更快地收敛到最优值。太大的epsilon
会导致我们看到的epsilon = 0.9
的收敛问题。
我们会在课程中不断调整,所以我暂时不会坚持太多。再次,享受我们今天所做的。这是非常了不起的。
B-R-A-V-O!(图片由作者提供)
6.重述✨
恭喜你(可能)解决了你的第一个强化学习问题。
这些是我希望你能记住的关键知识:
- 强化学习问题的难度与可能的动作和状态的数量直接相关。
Taxi-v3
是一个表格环境(即有限数量的状态和动作),所以它是一个简单的环境。 - Q-learning 是一种学习算法,非常适合表格环境。
- 无论您使用什么 RL 算法,都有一些超参数需要调整,以确保您的代理了解最佳策略。
- 调整超参数是一个耗时的过程,但必须确保我们的代理了解。随着课程的进展,我们会在这方面做得更好。
7.家庭作业📚
这是我要你做的:
- Git 克隆 把 repo 到你的本地机器上。
- 设置 本课的环境
01_taxi.
- 打开
[01_taxi/otebooks/04_homework.ipynb](https://github.com/Paulescu/hands-on-rl/blob/main/01_taxi/notebooks/04_homework.ipynb)
并尝试完成 2 个挑战。
我称之为挑战(不是练习),因为它们并不容易。我希望你尝试它们,弄脏你的手,并且(可能)成功。
在第一个挑战中,我谅你也不敢更新train()
函数src/loops.py
来接受一个依赖于剧集的 epsilon。
在第二个挑战中,我希望您升级 Python 技能并实现并行处理,以加快超参数实验。
像往常一样,如果你遇到困难,需要反馈,请给我写信plabartabajo@gmail.com.
我将非常乐意帮助你。
8.下一步是什么?❤️
在下一部分,我们将解决一个新的 RL 问题。
更难的一个。
使用新的 RL 算法。
有很多蟒蛇。
还会有新的挑战。
而且好玩!
回头见!
想支持我吗?
你喜欢阅读和学习关于 ML、AI 和数据科学的知识吗?
无限制地访问我在 Medium 上发布的所有内容,并支持我的写作。
👉🏽今天使用我的 推荐链接 成为会员。
https://pau-labarta-bajo.medium.com/membership
👉🏽订阅 datamachines 简讯 。
👉🏽 跟着我 上媒。
👉🏽给我很多掌声👏🏿👏🏽👏在下面
祝你愉快🤗
避寒胜地
实践强化学习课程:第 3 部分
表格 SARSA
贝尔格莱德萨瓦马拉(图片由作者提供)
欢迎来到我的强化学习课程❤️
这是我强化学习实践课程的第三部分,带你从零到英雄🦸♂️.
我们仍处于旅程的起点,解决相对容易的问题。
在第 2 部分中,我们实现了离散 Q 学习来训练Taxi-v3
环境中的代理。
今天,我们将进一步解决MountainCar
环境问题🚃使用 SARSA 算法。
让我们帮助这辆可怜的车赢得对抗地心引力的战斗!
本课所有代码都在 本 Github repo 中。 Git 克隆它,跟随今天的问题。
第三部分
内容
- 山地汽车问题🚃
- 环境、行动、状态、奖励
- 随机代理基线🚃🍷
- 萨尔萨特工🚃🧠
- 停下来喘口气,⏸🧘
- 重述✨
- 家庭作业📚
- 下一步是什么?❤️
1.山地汽车问题🚃
山地汽车问题是一个重力存在的环境(多么令人惊讶),目标是帮助一辆可怜的汽车赢得与它的战斗。
汽车需要逃离它被困的山谷。这辆车的引擎不够强大,无法单程爬上山,所以唯一的办法就是来回行驶,建立足够的动力。
让我们来看看它的实际应用:
你刚刚看到的视频对应于我们今天要建造的SarsaAgent
。
很有趣,不是吗?
你可能想知道。这个看起来很酷,但是当初为什么会选择这个问题呢?
为什么会有这个问题?
本课程的理念是逐步增加复杂性。循序渐进。
与第 2 部分中的Taxi-v3
环境相比,今天的环境在复杂性方面有了微小但相关的增加。
但是,这里到底什么更难?
正如我们在 第二部分 中看到的,一个强化学习问题的难度与问题的大小直接相关
- 行动空间:代理在每一步可以选择多少个行动?
- 状态空间:代理可以在多少种不同的环境配置中找到自己?
对于动作和状态数量有限的小环境,我们有强有力的保证像 Q-learning 这样的算法能够很好地工作。这些被称为表格或离散环境。
q 函数本质上是一个矩阵,其行数与状态数相同,列数与动作数相同。在这些小的世界里,我们的代理人可以轻松地探索各州并制定有效的政策。随着状态空间和(尤其是)动作空间变得更大,RL 问题变得更难解决。
今天的环境是不是表格化的。但是,我们将使用一个离散化“技巧”将其转换为表格形式,然后求解。
我们先熟悉一下环境吧!
2.环境、行动、状态、奖励
👉🏽notebooks/00 _ environment . ipynb
让我们加载环境:
并绘制一帧:
两个数字决定了汽车的状态:
- 其位置范围从 -1.2 到 0.6
- 其速度范围从 -0.07 到 0.07 。
状态由两个连续的数字给出。这是Taxi-v3
环境与第二部分的显著区别。我们将在后面看到如何处理这个问题。
有哪些动作?
有 3 种可能的操作:
0
向左加速1
无所事事2
向右加速
而奖励?
- 如果汽车位置小于 0.5,则奖励-1。
- 一旦汽车的位置高于 0.5,或者达到最大步数,本集就结束:
n_steps >= env._max_episode_steps
默认的负奖励-1 鼓励汽车尽快逃离山谷。
总的来说,我建议你直接在 Github 中检查开放 AI 健身房环境的实现,以了解状态、动作和奖励。
该代码有很好的文档记录,可以帮助您快速了解开始 RL 代理工作所需的一切。MountainCar
的实现是这里以为例。
很好。我们熟悉了环境。
让我们为这个问题建立一个基线代理!
3.随机代理基线🚃🍷
👉🏽notebooks/01 _ random _ agent _ baseline . ipynb
强化学习问题很容易变得复杂。结构良好的代码是控制复杂性的最佳盟友。
今天我们将提升我们的 Python 技能,并为我们所有的代理使用一个BaseAgent
类。从这个BaseAgent
类,我们将派生出我们的RandomAgent
和SarsaAgent
类。
父类和子类(图片由作者提供)
BaseAgent
是我们在[src/base_agent.py](https://github.com/Paulescu/hands-on-rl/blob/main/02_mountain_car/src/base_agent.py)
中定义的一个抽象类
它有 4 种方法。
它的两个方法是抽象的,这意味着当我们从BaseAgent:
派生出RandomAgent
和SarsaAgent
时,我们必须实现它们
get_action(self, state)
→根据状态返回要执行的动作。update_parameters(self, state, action, reward, next_state)
→根据经验调整代理参数。这里我们将实现 SARSA 公式。
其他两种方法允许我们将经过训练的代理保存到磁盘或从磁盘加载。
save_to_disk(self, path)
load_from_disk(cls, path)
随着我们开始实现更复杂的模型和训练时间的增加,在训练期间保存检查点将是一个很好的主意。
下面是我们的BaseAgent
类的完整代码:
从这个BaseAgent
类,我们可以将RandomAgent
定义如下:
让我们评估一下这个RandomAgent
而不是n_episodes = 100
,看看它的表现如何:
而我们RandomAgent
的成功率是…
0% 🤭…
我们可以用下面的直方图来看代理在每集中走了多远:
在这些100
运行中,我们的RandomAgent
没有越过 0.5 标记。一次都没有。
当你在本地机器上运行这段代码时,你会得到稍微不同的结果,但是在任何情况下,0.5 以上的完成剧集的百分比都不会是 100%。
你可以使用[src/viz.py](https://github.com/Paulescu/hands-on-rl/blob/37fbac23d580a44d46d4187525191b324afa5722/02_mountain_car/src/viz.py#L52-L61)
中的show_video
功能观看我们悲惨的RandomAgent
行动
一个随机的代理不足以解决这种环境。
让我们试试更聪明的方法😎…
4.萨尔萨特工🚃🧠
👉🏽notebooks/02 _ sarsa _ agent . ipynb
SARSA (由 Rummery 和 Niranjan 提出)是一种通过学习最优 q 值函数来训练强化学习代理的算法。
它于 1994 年出版,是 Q-learning(由克里斯·沃金斯和彼得·达扬出版)的两年后。
SARSA 代表 S 状态 A 动作Re 前进 S 状态 A 动作。
SARSA 和 Q-learning 都利用贝尔曼方程来迭代地寻找最佳 Q 值函数的更好的近似 Q(s,a)*
但是他们的做法略有不同。
如果您还记得第 2 部分,Q-learning 的更新公式是
这个公式是一种计算 q 值的新估计值的方法
这个数量是一个目标🎯我们想把原来的估计修正为。这是我们应该瞄准的最佳 q 值的估计,它随着我们训练代理和我们的 q 值矩阵的更新而改变。
强化学习问题通常看起来像有监督的 ML 问题,但是带有移动的目标🏃 🎯
SARSA 有一个类似的更新公式,但有一个不同的目标
SARSA 的目标
也取决于代理将在下一个状态s’采取的动作a’**。这是非典A’**s 中最后一个 A 的名字。
如果你探索足够的状态空间并用 SARSA 更新你的 q 矩阵,你将得到一个最优策略。太好了!
你可能会想…
Q-learning 和 SARSA 在我看来几乎一模一样。有什么区别?🤔
有一个关键区别:
- SARSA 的更新取决于下一个动作a’,并因此取决于当前策略。随着您的训练和 q 值(以及相关策略)的更新,新策略可能会针对相同的状态s’产生不同的下一个动作a’。你不能用过去的经验 (s,a,r,s’,a’)来提高你的估计。取而代之的是,你用一次经历来更新 q 值,然后把它扔掉。因此,SARSA 被称为基于策略的方法。
- 在 Q-learning 中,更新公式不依赖于下一个动作a’,,而只依赖于 (s,a,r,s’)。您可以重用使用旧版本策略收集的过去经验 (s,a,r,s’),,以提高当前策略的 q 值。Q-learning 是一种非政策方法。
策略外的方法比策略内的方法需要更少的经验来学习,因为您可以多次重用过去的经验来改进您的估计。他们更样高效。
然而,当状态、动作空间增长时,非策略方法具有收敛到最优 Q 值函数 Q*(s,a)的问题。他们可能很狡猾,而且不稳定。
当我们进入深度 RL 领域时,我们将在课程的后面遇到这些权衡🤓。
回到我们的问题…
在MountainCar
环境中,状态不是离散的,而是一对连续的值(位置s1
,速度s2
)。
连续在这个上下文中实质上是指无限可能的值。如果有无限个可能的状态,不可能把它们都访问一遍来保证 SARSA 收敛。
为了解决这个问题,我们可以使用一个技巧。
让我们把状态向量离散成一组有限的值。本质上,我们并没有改变环境,而是改变了代理用来选择其动作的状态的表示。
我们的SarsaAgent
通过将位置[-1.2 … 0.6]
四舍五入到最近的0.1
标记,将速度[-0.07 ...0.07]
四舍五入到最近的0.01
标记,将状态(s1, s2)
从连续离散化。
该函数正是这样做的,将连续状态转化为离散状态:
一旦代理使用离散化状态,我们可以使用上面的 SARSA 更新公式,随着我们不断迭代,我们将更接近最佳 q 值。
这是SarsaAgent
的全部实现
注意👆q 值函数是一个 3 维矩阵:2 维表示状态(位置、速度),1 维表示动作。
让我们选择合理的超参数,并为n_episodes = 10,000
训练这个SarsaAgent
让我们用它们的 50 集移动平均线(橙色线)来绘制rewards
和max_positions
(蓝色线)
超级!看起来我们的SarsaAgent
正在学习。
在这里你可以看到它的作用:
如果你观察上面的max_position
图表,你会意识到汽车偶尔无法爬山。
这种情况多长时间发生一次?让我们评价一下1,000
随机集上的代理:
并计算成功率:
95.2% 还算不错。尽管如此,并不完美。请记住这一点,我们将在本课程的稍后部分回来。
**注意:**当您在您的终端上运行这段代码时,您会得到稍微不同的结果,但是我敢打赌您不会得到 100%的性能。
干得好!我们实现了一个SarsaAgent
来学习🤟
这是一个暂停的好时机…
5.停下来喘口气,⏸🧘
👉🏽notebooks/03 _ momentum _ agent _ baseline . ipynb
如果我告诉您,MountainCar
环境有一个更简单的解决方案会怎么样…
100%的时间都有效?😅
要遵循的最佳政策很简单。
跟着势头走:
- 当汽车向右移动时向右加速
velocity > 0
- 当汽车向左移动时,向左加速
velocity <= 0
这个策略看起来像这样:
这是你如何用 Python 写这个MomentumAgent
:
你可以仔细检查它是否完成了每一集。百分之百的成功率。
另一方面,如果你画出受过训练的SarsaAgent
的政策,你会看到这样的东西:
这与完美的MomentumAgent
策略有 50%的重叠
这意味着我们的SarsaAgent
只有 50%的时间是正确的*。*
这很有意思……
为什么 **SarsaAgent**
经常出错却仍能取得好成绩?
这是因为MountainCar
仍然是一个小环境,所以 50%的时候做出错误的决定并不那么关键。对于更大的问题,经常犯错不足以构建智能代理。
你会买一辆 95%都正确的自动驾驶汽车吗?😱
另外,你还记得我们用来应用 SARSA 的离散化技巧吗?这是一个对我们帮助很大的技巧,但也给我们的解决方案带来了错误/偏见。
我们为什么不提高对状态和速度离散化的分辨率,以获得更好的解呢?
这样做的问题是状态数量的指数增长,也称为维数灾难。随着每个状态分量分辨率的增加,状态总数呈指数增长。状态空间增长太快,SARSA 代理无法在合理的时间内收敛到最优策略。
好吧,但是有没有其他的 RL 算法可以完美解决这个问题?
是的,有。我们将在接下来的课程中讨论它们。总的来说,对于 RL 算法,没有一种方法是万能的,因此您需要针对您的问题尝试几种算法,看看哪种效果最好。
在MountainCar
环境中,完美的策略看起来如此简单,以至于我们可以尝试直接学习它,而不需要计算复杂的 q 值矩阵。一种策略优化方法可能效果最好。
但是我们今天不打算这样做。如果您想使用 RL 完美地解决这种环境,请按照课程进行操作。
享受你今天的成就。
谁在找乐子?(图片由作者提供)
6.重述✨
哇!我们今天讨论了很多事情。
这是 5 个要点:
- SARSA 是一种基于策略的算法,可以在表格环境中使用。
- 使用状态的离散化,可以将小型连续环境视为表格,然后使用表格 SARSA 或表格 Q-learning 进行求解。
- 由于维数灾难,更大的环境不能被离散化和求解。
- 对于比
MountainCar
更复杂的环境,我们将需要更先进的 RL 解决方案。 - 有时候 RL 并不是最佳方案。当你试图解决你关心的问题时,请记住这一点。不要和你的工具结婚(在这种情况下是 RL),而是专注于找到一个好的解决方案。不要只见树木不见森林🌲🌲🌲。
7.家庭作业📚
👉🏽notebooks/04 _ homework . ipynb
这是我要你做的:
- Git 克隆repo 到你的本地机器。
- 设置 本课的环境
02_mountain_car
- 打开
[02_mountain_car/notebooks/04_homework.ipynb](http://02_mountain_car/notebooks/04_homework.ipynb)
并尝试完成 2 个挑战。
在第一个挑战中,我要求你调整 SARSA 超参数alpha
(学习率)和gamma
(折扣系数)以加速训练。可以从第二部中得到启发。
在第二个挑战中,尝试提高离散化的分辨率,并使用表格 SARSA 学习 q 值函数。就像我们今天做的一样。
让我知道,如果你建立一个代理,实现 99%的性能。
8.下一步是什么?❤️
在下一课中,我们将进入强化学习和监督机器学习交叉的领域🤯。
我保证会很酷的。
在那之前,
在这个叫做地球的神奇星球上多享受一天吧🌎
爱❤️
不断学习📖
如果你喜欢这门课程,请分享给你的朋友和同事。
你可以通过plabartabajo@gmail.com
找到我。我很乐意联系。
回头见!
你想成为(甚至)更好的数据科学家,接触关于机器学习和数据科学的顶级课程吗?
👉🏽订阅 datamachines 简讯 。
👉🏽 跟着我 上媒。
祝你愉快,🧡❤️💙
避寒胜地
第一手评论:BYOL
最近,自我监督学习方法已经成为无监督视觉表征学习的基石。最近推出的一个这样的方法BootstrapYourOwnLatent(BYOL)在这篇文章中被评论。我已经介绍了其他有趣的基于对比学习的自我监督学习方法,这些方法出现在 BYOL 之前,如 SimCLR,MoCo 等。在另一个职位彻底,并应考虑理解这个职位的基本原则。请在这里找到它们。
与其他对比学习方法不同,BYOL 在不使用任何负面样本的情况下实现了最先进的性能。基本上,像一个连体网络,BYOL 使用两个相同的编码器网络,称为在线和目标网络,用于获得表示,并减少两个表示之间的对比损失。
网络架构
BYOL 网络的架构如下所示。θ和ϵ分别代表在线和目标网络参数,f_θ和 f_ϵ分别是在线和目标编码器。目标网络权重是在线网络权重的缓慢移动平均值,即
想法是在第一步中训练在线网络 f_θ,并在第二步中使用这些学习到的表示用于下游任务,并使用标记的数据进一步微调它们。第一步,即 BYOL,可以总结为以下 5 个简单的步骤。
- 给定输入图像 x,通过对 x 应用两个随机增强,生成同一图像 v 和 v’的两个视图
- 给定在线编码器和目标编码器的 v 和 v ’,得到矢量表示 y_θ和 y’_ϵ。
- 现在,这些表示被投影到另一个子空间 z。这些投影的表示在下图中由 z_θ和 z’_ϵ表示。
- 因为目标网络是在线网络的慢速移动平均,所以在线表示应该是目标表示的预测,即 z_θ应该预测 z’_ϵ,因此另一个预测器(q_θ)被放在 z_θ之上。
- <q_ z=“”>之间的对比损失减少。</q_>
图片来源: Grill,Jean-Bastien 等人,“引导你自己的潜能:自我监督学习的新方法”arXiv 预印本 arXiv:2006.07733 (2020)。
数学上,对比损耗计算为 q_θ(z_θ)和 z’_ϵ.之间的均方误差在计算均方误差之前,标签 z’_ϵ和目标 q_θ(z_θ)是 L2 归一化的。等式是,
对比损失
z_ϵ棒是 L2 归一化的 z
_ϵ,而 q_θ(z_θ)棒是 L2 归一化的 q_θ(z_θ)。
为什么是 BYOL?
第一个问题是,为什么以及在哪里应该使用 BYOL?
BYOL 方法有助于学习各种下游计算机视觉任务的有用表示,如对象识别、对象检测、语义分割等。一旦以 BYOL 方式学习了这些表示,它们可以与任何标准的对象分类模型一起使用,例如 Resnet、VGGnet,或者任何语义分割网络,例如 FCN8s、deeplabv3 等,或者任何其他特定于任务的网络,并且它可以获得比从头开始训练这些网络更好的结果。这是 BYOL 受欢迎的主要原因。下图显示了使用 Imagenet 图像学习的 BYOL 表示击败了所有以前的无监督学习方法,并在线性评估协议下使用 Resnet50 实现了 74.1%的分类准确度。如果你不确定线性评估协议,它在我的上一篇帖子中有详细描述。
线性评估方案下的 BYOL 结果。图片来源:烧烤店,让-巴斯蒂恩
在密集的预测任务中,BYOL 的能力得到了更有效的利用,由于数据标注任务复杂且成本高昂,因此通常只有少数几个标注可用。当 BYOL 用于一个这样的任务,即使用带有 FCN8s 网络和 Resnet50 主干的 cityscapes 数据集的语义分割时,它优于从零开始训练的网络版本,即具有随机权重。下图比较了 cityscapes 数据集上 3 个主要网络的性能。
- Resnet50 根据 Imagenet 权重进行训练,并使用 3k 城市风景标记的图像(红色虚线)进行微调。
- 仅使用 3k 城市风景图像(黑色虚线)从随机权重训练 Resnet50。
- Resnet50 使用 20k 未标记的城市景观图像在 BYOL 上进行预训练,然后使用 3k 城市景观图像(蓝色实线)进行微调。
下图清楚地显示了 BYOL 极大地有助于学习该任务的有用表示,并提示它应被视为其他计算机视觉工业应用的预训练步骤,在这些应用中,由于许可法规而不能使用 Imagenet 权重,并且存在大量未标记的数据用于无监督训练。
BYOL 增益(图表由作者提供)
实施细则
对于图像放大,使用以下一组放大。首先,从图像中选择一个随机裁剪,并将其大小调整为 224x224。然后应用随机水平翻转,接着是随机颜色失真和随机灰度转换。随机色彩失真由亮度、对比度、饱和度和色调调整的随机序列组成。以下代码片段在 PyTorch 中实现了 BYOL 增强管道…
from torchvision import transforms as tfmsbyol_tfms = tfms.Compose([
tfms.RandomResizedCrop(size=512, scale=(0.3, 1)),
tfms.RandomHorizontalFlip(),
tfms.ToPILImage(),
tfms.RandomApply([
tfms.ColorJitter(0.4, 0.4, 0.4, 0.1)
], p=0.8),
tfms.RandomGrayscale(p=0.2),
tfms.ToTensor()])
在实际的 BYOL 实现中,Resnet50 被用作编码器网络。对于投影 MLP,首先利用批范数将 2048 维的特征向量投影到 4096 维的向量空间,然后进行 ReLU 非线性激活,最后将特征向量缩减到 256 维。预测器网络使用相同的架构。以下 PyTorch 代码片段实现了基于 Resnet50 的 BYOL 网络,但它也可以与任何任意编码器网络结合使用,如 VGG、InceptionNet 等。没有任何重大变化。
BYOL 的运作方式
另一个有趣的事实是,虽然为 BYOL 策划的任务存在一个崩溃的解决方案,但该模型安全地避免了它,其实际原因是未知的。塌陷的解决方案意味着,模型可能通过学习任何图像的任何视图的恒定向量而逃脱,并且达到零损失,但是它没有发生。
原始论文[1]的作者推测,这可能是由于主干中使用的复杂网络(具有跳跃连接的深度 Resnet ),该模型从未得到直接的折叠解决方案。但是在 SimSiam[2] Chen、Xineli 和 He 最近发表的另一篇论文中,他们发现不是复杂的网络结构,而是“停止梯度”操作使模型避免了折叠表示。“停止梯度”意味着网络永远不会直接通过梯度来更新目标网络的权重,因此永远不会得到崩溃的解决方案。他们还表明,没有必要使用动量目标网络来避免折叠表示,但如果使用的话,它肯定会为下游任务提供更好的表示。
这是对 BYOL 和 PyTorch 代码的简要总结。如需全面实施,可参考 https://github.com/nilesh0109/self-supervised-sem-seg 的 GitHub 回购。
下面是这篇文章中使用的参考文献列表。
- 引导你自己的潜能:自我监督学习的新方法。 arXiv 预印本 arXiv:2006.07733 (2020)。
- 陈、和何。"探索简单的暹罗表象学习."arXiv 预印本 arXiv:2011.10566 (2020)。
实践逐步指导增加你的工作机会
职业建议
如何战略性地利用 Meetup 会议获得你梦寐以求的数据科学工作
图片来自 Pixabay 的 Gerd Altmann
你是一名有抱负的数据科学家,你会努力遵循更有经验的同事给出的所有建议。
- 你正在用所有推荐的免费和付费在线书籍和课程学习数据科学。
- 你可以阅读所有最新的数据科学博客。
- 你钻研所有被推荐的研究论文。
- 你参加了卡格尔比赛。
- 你建立了一个 GitHub 项目组合。
- 你浏览所有张贴的面试问题。
但是当你最终申请工作时,你会面临许多拒绝。你写了 100 多份申请,如果有一次你得到了一些关于你为什么没有得到这份工作的反馈,那就是“我们决定和另一个更适合的候选人一起前进。”
这是许多有抱负的数据科学家面临的常见情况。他们经常把这当成比赛的一部分,像往常一样前进。
在我的职业生涯中,我参加过数百次面试。未被选中的原因通常分为以下两类。
- 技能,以及
- 不适合这个团队。
本文将重点放在第二个方面,因为这一点不太明确,而且经常不被考虑。
许多候选人都在问,他们必须改变什么才能成为一个合适的人,他们应该参加什么课程。但这部分和技术技能无关。这是关于对你的看法。
- 那个人给我们团队带来了什么精神?
- 员工喜欢和她/他一起工作吗?
- 我们信任这个人吗?
这种“不适合团队”的原因不能通过参加另一个在线课程和自己做另一个项目来消除。你无法改变人们在面试中对你的看法。
但可以改变的是,你会找到适合你的团队和公司。
要解决它们,你需要走出你孤立的自学世界,与外面的环境联系起来。你必须在申请工作之前解决这个问题。
随着疫情和越来越多的远程工作,数据科学职位的竞争加剧。
另一方面,还有 Oscar,一个有经济学背景,只有一点编程知识的数据治理专家。不久前,他搬进了一家跨国公司的数据科学部门,开始了他的数据科学之旅。
他没有申请招聘广告。他没有令人讨厌的招聘流程,你最终听不到任何反馈,而是直接通过主要的招聘步骤。
奥斯卡是真实的。我雇了他。
区别在于对网络的战略性使用。得到一份数据科学的工作,不仅仅是知识、技能、证书。它是一个网络的集成。
嵌入这样一个网络并解决拒绝原因的一个简单且负担得起的选择是 Meetup 会议。
所以,让我们来分解一下战略性地使用 Meetups 找工作的过程,这样你也可以应用它。
Meetup 会议的秘密
什么是 Meetup 会议?
Meetup 是一个为兴趣小组提供在线服务的平台。个人可以创建对特定主题感兴趣的团体,他们组织面对面或虚拟的活动。活动包括人们展示项目的会议、技术会议、徒步旅行、语言课、创业推介等。它是所有数据科学主题的完美平台,因此,可以找到数千个与数据科学相关的群组。
在数据科学领域寻找 Meetup 群组时,搜索以下关键词。
- 数据科学
- 机器学习
- 深度学习
- AI 或人工智能
- 自然语言处理
- 物联网、云、边缘计算
- 金融科技、教育科技、医疗科技等等
- 人工智能开发者
- 编程;编排
- Python、Julia、Java、Js、KNIME、C/C++等等
- 等等
你可以从你的位置选择半径,你会发现所有的团体靠近你的地方。
作者截图:搜索半径的选择
Pro tip : 特别是在疫情期间,许多 Meetup 会议转变为在线会议,你可以在全球范围内参加。因此,选择“任何距离”,然后在全球范围内寻找虚拟会议。
自从疫情启动以来,我在硅谷参加了许多(在线)会议,并结识了几个新的商业伙伴。我现在有项目合作,甚至和斯坦福大学合作。一家大型科技公司也联系了我,让我出演一个角色。
谁会参加聚会?
80%的参与者希望进入数据科学领域,或者是数据分析师、业务分析师、有抱负的数据科学家、学生、学者以及没有团队领导角色的经验丰富的数据科学家。20%的与会者是担任团队领导职务的高级数据科学家、招聘经理和首席数据科学家。
为什么你既需要 80%又需要 20%的网络?
那 80%可以算是“同行”同行是必不可少的,原因有三:
- 为了你的未来。你们一起成长,你们将独立经历相同的发展步骤和相似的职业水平。这些同事支持你在五年、十年或十五年内从一个职位或公司转到另一个职位或公司。它们是你今天投资的关系资本的利息。
- 讨论方法、项目挑战以及何时需要数据科学相关问题的意见。这不仅仅是你作为初学者的时间。此外,当数据科学领导者面临尚未找到解决方案的问题时,他们也会这样做。
- 为团队和公司打开大门。当人们熟悉你和你的技能并信任你时,他们愿意为你辩护。许多公司都有所谓的推荐计划,这意味着如果一名现有员工推荐了一名候选人,而这名候选人被录用了,她/他就可以获得一笔可观的现金奖励。
这 20%是你短期和中期工作目标的机会。他们雇人,并且雇佣他们信任的人。他们需要熟悉你。
和金融投资一样,你应该两者都投资。平均来说,你应该用 50%的时间与每个小组交流。
你应该多久参加一次?
参加聚会和建立关系网是销售。你推销自己。销售研究表明,一个人至少要有八次互动才能达成交易。所以,和一个人见一两次面并不会给你带来工作机会。你必须参加许多 Meetup 会议才能见到同一个人至少八次,尤其是一位有其他任务的资深科学家。
但是在你停止阅读之前,请等待。Meetup 的诀窍是建立一个连接,让你能够在 Meetup 平台之外建立关系网。我稍后将回到如何做这件事。
有哪些类型的 Meetup 会议?
在研究数据科学领域时,我将它们大致分为:
- 申请,即来自不同行业和公司的从业者的项目演示。
- 研究,即最新的机器学习或 AI 研究和方法。
- 软件公司/工具提供商,也就是说,他们通常会亲自动手,在指导下对工具进行测试
- 特定技术和主题,如 Kubernetes、加密、云计算等。
- 编程类,例如 Python 或 C/C++ / live 编码类。
- 将多样性引入技术领域的团队,例如数据科学/机器学习领域的女性。
- 特定行业会议,即技术、数据和数字化会议,关注特定行业。
- 初创企业推介,即初创企业可以向投资者或正在寻找联合创始人的初创企业推介。
你有各种各样的会议,你可以随时找到你感兴趣的会议。
建立你的 Meetup 组合
如何决定参加哪个 Meetup 会议?
关于如何选择会议,又有两个选项:主题或行业,以及公司相关。
首先,按主题呈现,即主题或行业。如果你想进入物联网相关的数据科学或客户分析,请选择物联网相关或客户分析聚会。如果你想进入制药和生命科学领域,选择一个有生命科学和健康数据科学主题的专业。
在这样的聚会上,你会找到在那个领域工作的人。
在第二种情况下,你的目标是扩大你的关系网,以便有一个专家交流或潜在的职位,提出的主题是次要的。
然后,您可以根据主持人、与会人员和召开 Meetup 会议的公司来选择会议。
看看演讲者来自哪家公司,如果是与公司合作完成的,看看他们是否是学者。找出聚会的地点。当一家公司举办这种活动时,通常会有不少员工参加。
根据您希望加入的行业或主办公司选择 Meetup 会议。
专业提示:如果主持人是年长的,可以预期观众也是年长的。让几个合适的人参加聚会比尽可能多的人参加更重要。
如何充分利用聚会?
参加之前要做好准备!
许多人没有任何准备就参加会议。他们很少了解演讲者或主持的公司——只知道这是一个众所周知的品牌或话题,会议结束后,他们很失望,因为他们没有从那次会议中受益。
我如何准备 Meetup 会议?
我为主持人做研究:LinkedIn、Google 和其他搜索工具。
- 谁是主持人,他们的职业道路是什么?
- 他们在公司中扮演什么角色?
- 他们是否已经有了其他演讲,主题是什么?
- 他们在这个话题上有多资深,在这次会议上听众有什么期望?
- 他们的网络是什么样的?我认识与他们有联系的人吗?我在哪里可以找到他们?
我了解这个话题,以便进行有意义的讨论。
- 它是做什么用的?在哪些行业或公司?
- 主题是独特的还是标准的?它是否提出了重大问题的解决方案?
通过对这两个问题的分析,你可以深入了解从事相同主题工作的其他公司将会参加哪些会议。
- 该领域常用的方法是什么?
- 还有哪些问题和那个话题有关?
你不需要写一篇关于这个的论文,但是你需要基本的知识来进行(积极的)持久的互动。
我收集关于公司的信息。
- 公司是做什么的?(如果不是知名品牌。)
- 我认识那家公司的人吗?(**专业提示:**检查你在 LinkedIn 上的关系。)
- 公司招人吗?他们招聘什么职位?(看对应的招聘广告。)
- 那家公司的战略主题是什么?提出的案例是其中之一吗?
这样,你就可以评估该公司的切入点可能在哪里。
然后,我查看其他已经注册的参与者。您点击一个 Meetup 事件,然后您可以向下滚动并查看与会者列表。
然后,我查看他们的个人资料——并非所有人都输入了个人资料信息或看到了全名,但这让我第一次看到了谁在参加。如果有全名,我会在 LinkedIn 上寻找潜在的附加信息。
你应该和谁交往?
如上所述,你应该用一半的时间和可以被视为同事的人交往,用另一半的时间和负责招聘的人交往。所以,你应该和所有可能的人交往。
基于对简介的回顾,你对受众有一个大致的了解。如果你想和某个特定的人交谈,你可以特别留意这个人。
你不需要整个晚上都和一个人呆在一起。进行自然的讨论,询问她/他为什么参加,这个人在哪个领域工作,如果你对更深入的讨论不感兴趣,你可以继续。
我通常会告诉对方,我要开始另一场讨论了,但还是要感谢他们有趣的谈话,祝他们有一个愉快的夜晚,并说“我们希望在下次聚会时再见。”敞开大门是很重要的,因为情况可能会改变,这个人以后可能会对你至关重要。
如果你对一个人感兴趣,想进行后续互动,你可以问她/他是否在 LinkedIn 上,或者可以分享联系方式。我还会问一个人多久参加一次 Meetup 会议,参加哪些会议,是否已经有参加下一次会议的计划。然后,你知道在哪里可以再遇到那个人。
专业提示:我建议和主办方谈谈。也可以在活动页面上找到它们。他们有一个广泛的网络,因为活动和知道许多人参加,并可以指出你的人来讨论。而且他们往往在一个公司里处于领导地位。他们是建立你的社交网络的倍增器。
最后,与演讲者建立联系。不管你是不是绝对的初学者。有意义的讨论是必要的,为此,你做了准备。
你可以通过让演示者知道你是一个初学者,但阅读了这个主题来开始讨论。你可以就此引用一两点,并就如何进一步深入这个主题征求意见。你可以询问是否有可用的数据集,以便你可以尝试这些方法,或者她/他是否最终有一些代码示例。你可以进一步问这个话题对她/他的公司是否重要,有多少人在做这个,以及他们正在做的其他事情。
如果你表现出真诚的兴趣,你就会建立信任,人们会回答你的问题并支持你。当你们进行这样的对话时,你也可以询问联系方式,以及是否有可能进行跟进。大多数情况下,当你准备充分时,他们会支持你。
会后你应该做什么?
答案很简单:人脉,人脉,人脉。
你之前读到过你至少需要八次互动。那么,你如何得到它们呢?
如果你知道这个人的名字,而且他在 LinkedIn 上,那就联系他/她。重要事项:添加一条信息,如“我们在 XYZ 见过面,我想再次感谢您的有趣讨论,”或“感谢您在 XYZ 的有趣讨论,正如所讨论的,我想跟进 ABC,”这样,对方会觉得已经熟悉您了。然后你可以用准备好的问题继续跟进。但是至少要等两个星期。没有比两天后再发一条信息而被人忽视更大的机会了,除非你已经同意了。
如果你和一个人分享了联系方式,你也应该看看 LinkedIn。利用这些联系,进一步拓展人脉。
您还可以在 Meetup 平台上向 Meetup 成员发送消息。在 Meetup 会员名称的右侧,您可以查看是否可以发送消息。组织者通常会在个人资料中提供更多的联系方式。
使用此功能联系其他参与者。
作者截图:启用消息传递的成员
**亲提示:**部分会员已禁用消息功能。然而,在 LinkedIn 上可以找到很多。然后,我在 LinkedIn 上联系他们,在联系邀请中添加一条之前看到的信息,因为——同样——你需要与这个人建立信任。
我在 LinkedIn 上收到很多邀请,大多数情况下,我不认识那个人。每当有人写一条短信,比如“我已经读过你写的 XYZ 关于数据科学的文章”或者“我们都参加了 ABC 会议”,那么在几秒钟内,我就接受了邀请。
另一方面,为了让别人能够联系到你,选择相应的设置。
作者截图:其他成员联系的设置
做完所有这些,你就可以开始自然而有规律的互动了。
如何在网络活动中建立关系网?
在网络事件中建立关系网确实有点困难,但是用一些技巧,还是可以的。
在大多数活动中,在线活动期间可以看到与会者。所以,我做了一个参与者名单的截图。我记下是谁在问什么问题,以便联系。
如果你觉得舒服,你可以问一个问题,或者对之前的一个回答或问题进行评论。如果我对与一个特定的人建立关系感兴趣,并且那个人问了一个问题,我会问一个我可以向他提及的问题,比如“我发现这是一个很好的问题,但是在 ABC 的情况下我们会有什么?”有时,甚至有可能在活动中以这种方式与他人联系。
组织者和演讲者通常都有详细的联系方式,如上所述,你可以在会后与他们联系。在大多数情况下,他们主动向他们伸出援手,他们会有所回应。
然后,我像上面提到的那样表演:我在 LinkedIn 上和他们联系,给他们发消息。
如何让你的互动增加 10 倍?
组织 Meetup 会议!
你可以选择演讲者,这应该是有策略的。问问那些你想在哪里找到工作的人。作为组织者,你有一连串的互动:最初的接触(社交媒体、电子邮件),关于会议主题和期望的简报,在他们陈述之前和陈述期间的帮助,活动结束后的感谢电子邮件,简报,以及最终对其中一个主题的个人跟进。通过自然地这样做,你可以很快产生六到十次互动。
回到奥斯卡,他完全做到了这些。他还借此机会组织了一次 Meetup 会议,在会上他联系我做了一个演示。通过所有的互动,我熟悉了他的技能和潜力。互动是建立在信任的基础上的。
将所有这些整合在一起
Meetup 会议是最被低估的机会,它能让你在求职中获得竞争优势。
战略性地使用它们来与你想工作的公司建立关系,与同行建立信任的交流,并建立你未来的机会。
也要做好准备,人们也可能会接近你。不要因为一个人的知识比你少而拒绝他。作为一名数据科学家,我并不是仅仅通过向他人学习而成长起来的;我最大的收获是给予。
你应该什么时候开始参加 Meetup 会议?从您踏上数据科学之旅的第一步开始!
成功的数据科学家并不是技术更好,也不是证书更多。他们有一个更大的网络。
你喜欢我的故事吗?在这里你可以找到更多。
</10-mistakes-you-should-avoid-as-a-data-science-beginner-ec1b14ea1bcd> [## 作为数据科学初学者应该避免的 10 个错误
towardsdatascience.com](/10-mistakes-you-should-avoid-as-a-data-science-beginner-ec1b14ea1bcd) </5-concrete-real-world-projects-to-build-up-your-data-science-portfolio-ef44509abdd7>