NeptuneAI-博客中文翻译-四-

NeptuneAI 博客中文翻译(四)

原文:NeptuneAI Blog

协议:CC BY-NC-SA 4.0

如何在 PyTorch 中跟踪实验

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-keep-track-of-experiments-in-pytorch-using-neptune

机器学习开发看起来很像传统的软件开发,因为它们都需要我们编写大量代码。但其实不是!让我们通过一些要点来更好地理解这一点。

  • 机器学习代码不会抛出错误(当然我说的是语义),原因是,即使你在一个神经网络中配置了一个错误的方程,它仍然会运行,但会打乱你的预期。用安德烈·卡帕西的话说,“神经网络无声无息地失灵”。
  • 机器学习代码/项目严重依赖结果的可重复性。这意味着如果一个超参数被推动或者训练数据发生变化,那么它会在许多方面影响模型的性能。这意味着你必须记下超参数和训练数据的每一个变化,以便能够重现你的工作。
    当网络很小的时候,这可以在一个文本文件中完成,但是如果是一个有几十或几百个超参数的大项目呢?文本文件现在不那么容易了吧!
  • 机器学习项目复杂性的增加意味着复杂分支的增加,必须对其进行跟踪和存储以供将来分析。
  • 机器学习也需要大量的计算,这是有代价的。你肯定不希望你的云成本暴涨。

有组织地跟踪实验有助于解决所有这些核心问题。海王星是一个完整的工具,帮助个人和团队顺利跟踪他们的实验。它提供了许多功能和演示选项,有助于更轻松地跟踪和协作。

https://web.archive.org/web/20221206010849if_/https://www.youtube.com/embed/he2KqU76ays?feature=oembed

视频

用海王星进行实验跟踪

传统的跟踪过程包括将日志对象保存为文本或 CSV 文件,这非常方便,但是对于与输出日志的混乱结构相关的未来分析没有用处。下图以图片的形式讲述了这个故事:

虽然可读,但你会很快失去兴趣。一段时间后,你也可能会丢失文件——没有人会预料到突然的磁盘故障或过度清理!

所以,总而言之,txt 的方式方便但不推荐。为了解决这个问题,Neptune 跟踪每个超参数,包括模型和训练程序的超参数,以便您可以有效地与您的团队交流,并在未来分析训练程序以进一步优化它们。

下面是一个类似的实验,但使用 Neptune 应用程序进行跟踪:

https://web.archive.org/web/20221206010849im_/https://neptune.ai/wp-content/uploads/Example-dashboard-metadata-structure.mp4

Example project metadata in Neptune

在 Pytorch 建立海王星实验

设置过程很简单。首先注册一个帐户 这里,这将创建一个唯一的 ID 和仪表板,在那里你可以看到你所有的实验。您可以随时添加您的团队成员,并在实验中进行合作。按照这些步骤获得您的唯一 id(设置时使用)。

为了在 python 的培训过程中使用这个仪表板,Neptune 开发人员开发了一个易于使用的包,您可以通过 pip 安装它:

pip install neptune-client

完成安装后,您需要像这样初始化 Neptune:

import neptune.new as neptune
from neptune.new.types import File

NEPTUNE_API_TOKEN = "<api-token-here>"
run = neptune.init(project='<username>/Experiment-Tracking-PyTorch',
                   api_token=NEPTUNE_API_TOKEN)

现在,让我们看看如何从 PyTorch 脚本中利用 Neptune 的仪表板。

基本指标集成

让我们从跟踪通常的度量开始,比如训练/测试损失、时期损失和梯度。为此,您只需将 run['metrics/train_loss']。log(loss ),其中“metrics”是可以存储所需参数的目录,“loss”是被跟踪的度量。在你的 PyTorch 训练循环中会是这样的:

def train(model, device, train_loader, optimizer, epoch):
   model.train()
   for batch_idx, (data, target) in enumerate(train_loader):
       data, target = data.to(device), target.to(device)

       optimizer.zero_grad()

       output = model(data)

       loss = F.nll_loss(output, target)
       loss.backward()

       optimizer.step()

       run['metrics/train_loss'].log(loss)

       if batch_idx % 100 == 0:
           print('Train Epoch: {} [{}/{} ({:.0f}%)]tLoss: {:.6f}'.format(
               epoch, batch_idx * len(data), len(train_loader.dataset),
               100. * batch_idx / len(train_loader), loss.item()))

运行上面的代码后,检查您的 Neptune 仪表板,您将看到跟踪和绘制的损失度量供您分析。

为了跟踪超参数(你应该,总是这样做!)你需要做的就是简单的给海王星的 run 对象添加这样的参数。

PARAMS = {'batch_size_train': 64,
         'batch_size_test': 1000,
         'momentum': 0.5,
         'learning_rate': 0.01,
         'log_interval' : 10,
         'optimizer': 'Adam'}

run['parameters'] = PARAMS 

使用这些更改再次运行实验后,您将在仪表板中看到所有参数,如下所示:

添加参数和标记的一个最大目的是将所有东西都插入一个仪表板,这样就可以在未来轻松地进行优化或特性更改分析,而不会消耗大量代码。

高级选项

Neptune 为您提供了许多定制选项,您可以简单地记录更多特定于实验的内容,如图像预测、模型权重、性能图表等等。

所有这些功能都可以很容易地集成到您当前的 PyTorch 脚本中,在下一节中,我将向您展示如何充分利用 Neptune。

运行实验时,您可以记录其他有用的信息:

  • 代码:快照脚本、jupyter 笔记本、配置文件等等
  • 超参数:日志学习率,历元数,以及其他
  • 属性:日志数据位置、数据版本或其他
  • 标签:添加“resnet50”或“无增强”等标签来组织您的跑步。
  • 名称:每个实验都应该有一个有意义的名称,所以我们不要每次都用“默认”

只需将这些作为参数传递给 init()函数,这很简单:

NEPTUNE_API_TOKEN = "<api-token-here>"
run = neptune.init(project='<username>/Experiment-Tracking-PyTorch',
                   api_token=NEPTUNE_API_TOKEN,
                  tags=['classification', 'pytorch', 'neptune'],
                   source_files=["**/*.ipynb", "*.yaml"]  
)

上面的代码摘录将上传您的属于正则表达式的代码文件,添加您可以在仪表板中识别的标签。现在,让我们看看如何记录其他实验特定的内容,如图像和模型重量文件:

记录图像

def train(model, device, train_loader, optimizer, epoch):
   model.train()
   for batch_idx, (data, target) in enumerate(train_loader):
       data, target = data.to(device), target.to(device)

       optimizer.zero_grad()

       output = model(data)

       loss = F.nll_loss(output, target)
       loss.backward()

       optimizer.step()

       run['metrics/train_loss'].log(loss)

       if batch_idx % 50 == 1:
           for image, prediction in zip(data, output):

               img = image.mul(255).add_(0.5).clamp_(0, 255).to('cpu', torch.uint8).numpy()
               img = Image.fromarray(img.reshape(28,28))
                     run["predictions/{}".format(batch_idx)].upload(File.as_image(img))

       if batch_idx % 100 == 0:
           print('Train Epoch: {} [{}/{} ({:.0f}%)]tLoss: {:.6f}'.format(
               epoch, batch_idx * len(data), len(train_loader.dataset),
               100. * batch_idx / len(train_loader), loss.item()))

在运行带有日志记录更改的代码后,您将在 Neptune 仪表板的“预测”目录中看到记录的图像。

通过左侧菜单中的“添加新仪表板”,您可以使用许多可用的小部件创建自己的定制仪表板。例如,您可以在一个屏幕上添加图像预测并进行分析!

在这里,我添加了其中的两个,你可以通过选择你更感兴趣的来扩展它。

你可以在实验中记录额外的东西

训练中可以记录很多有趣的信息。您可能对监控以下内容感兴趣:

  • 每个时期后的模型预测(考虑预测遮罩或覆盖的边界框)
  • 诊断图表,如 ROC AUC 曲线或混淆矩阵
  • 模型检查点或其他对象

例如,我们可以使用 torch.save()方法将模型权重和配置保存到本地磁盘以及 Neptune 的仪表板中:

torch.save(model.state_dict(), 'model_dict.ckpt')

run["model_checkpoints"].upload("model_dict.ckpt")

至于像 ROC 曲线和混淆矩阵这样的训练后分析,您可以使用您最喜欢的绘图库绘制它,并用 neptune.log_image()记录它

from scikitplot.metrics import plot_confusion_matrix
import matplotlib.pyplot as plt
...
fig, ax = plt.subplots(figsize=(16, 12))
plot_confusion_matrix(y_true, y_pred, ax=ax)
run["metrics/confusion_matrix"].upload(File.as_image(fig))

如果您希望看到这个令人敬畏的 API 的每一个功能,请前往包含代码示例的 Neptune 文档。

你已经到达终点了!

我们看到了为什么 实验跟踪 由于它们无声的脆弱性和未来的分析前景,在机器学习系统中是一种必需品。我们也看到了Neptune ai 如何证明是完成这项任务的合适工具。使用 Neptune 的 API:

  • 你可以监控和跟踪你的深度学习实验
  • 你可以很容易地与其他人分享你的研究
  • 您和您的团队可以访问实验元数据并更有效地协作。

你可以在这个笔记本中找到代码这里和海王星实验这里

目前就这些,敬请关注更多!再见!

如何学习机器学习:来自多年个人经验的完整指南

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-learn-machine-learning

根据《哈佛商业评论》,数据科学家是 21 世纪最性感的工作。随着每天生成的数据量呈指数级增长,世界需要能够从这些数据中提取价值的专家。

数据科学对许多行业产生了巨大影响,但机器学习一直是数字化转型和自动化的关键驱动力。

机器学习的职业看起来很有吸引力,尤其是当你看一些事实的时候:

机器学习现在在我们周围无处不在:在音乐医疗社交网络,甚至在象棋。应用程序的数量是巨大的,而且随着越来越多的行业采用这种技术来解决他们的问题,应用程序的数量还在不断增加。对机器学习专家的需求不断增长。

如果你不相信机器学习有多普遍,你可以看看一些顶级公司使用人工智能来改善他们的运营、服务和产品的例子。你会惊喜的。

成为快速增长的人工智能环境的一部分是一条有吸引力的职业道路,但你如何才能进入这条道路?

你可能已经听说过,机器学习工程师应该擅长数学和统计,懂得编程语言,有一点商业意识和扎实的研究技能。这都是事实,但不要让它压倒你。

你不必精通以上所有内容,就可以开始你的机器学习工程师生涯。满足所有的要求需要时间、努力和练习。

每个人都有不同的 ML 学习路径

我们每个人都有独特的背景、知识和经历。没有通用的方法让每个人学习机器学习。我的个人经验告诉我,有两种不同类型的学习者:

  • 那些有机会(和资源,尤其是时间和金钱)完全致力于学习的人。对于这样的学习者来说,这通常意味着获得一个学位并花费数年时间学习;
  • 那些缺乏获得学位资源的人。他们可能已经有了工作,有了家庭,可以理解的是,他们不能攻读全日制学位。这个群体还包括那些因为无法支付教育费用而无法获得学位的人。

如果你能负担得起一个学位(经济上和时间上),并且你对机器学习很感兴趣,那么就去做吧。你会享受新知识,练习新技能,顺利进入领域。显然,这是对你未来职业生涯和发展最便利的场景。

如果你买不起学位怎么办?不能成为机器学习工程师?我不这么认为,因为那也是我的情况。我自己的经历证明了这是可能的。我也有一个朋友,他做了很长时间的咖啡师,但后来决定成为一名机器学习工程师。他做到了!经过 11 个月的业余学习,在没有辞去全职工作的情况下,他获得了第一份 ML 工作邀请,并以一个新的理想角色加入了一家科技公司。

正如你所看到的,不管你的具体情况是什么,如果你专心致志,你都可以接受机器学习教育并进入这个领域。在本文中,我将为您提供一些屡试不爽的指导方针,让这种转变变得更加容易。

第一组学习者通常有一个精心设计的课程可以遵循,并有学术人员的广泛支持,但我们不会花太多时间来谈论它。我们将只略微涉及值得考虑的各种学位选项。

除此之外,我们将主要关注第二组学习者及其需求。这些学生通常遵循一条自己设计的学习路径,主要包括mooc、书籍和训练营。在这篇文章中,我们将指导你学习所有的选项。我们将考虑它们的利弊,并帮助您选择最适合您的学习风格和要求的格式。

毫不奇怪,大多数自学的学生面临的第一个问题是关于他们学习课程的设计。在高层次上,它通常指的是学习计划中的主题和科目。精心规划的教学大纲很重要,我们将讨论每个机器学习工程师必须学习和了解的主题。

除了直观的科目列表,还有另一个同样重要的概念,每个自学的学生都应该在他们的旅程开始时理解—你应该使用自上而下的方法学习,而不是自下而上。原因如下:

机器学习教育的自顶向下方法

自顶向下的方法是关于从高层次的解决方案到应用方法的本质。这与传统的学术学习方式截然相反,在传统的学术学习方式中,你首先学习理论原理,然后才进行实践。

相比之下,自上而下的方法不需要投入大量的时间来研究理论,然后再转向实践方面。相反,它是关于获得适当的工具(通常是你最喜欢的编程语言的库),并在了解一切是如何工作之前努力把事情做好。你的最终目标是使用你可用的高级工具和方法来解决一个切实的任务。

这种方法对许多决定放弃传统大学学位的学习者来说非常有效。你首先揭示什么是应用机器学习,对这个领域的机会感到兴奋,熟悉编程原则和使用的主要库。一旦你经历了这个过程,变得更加自信和有动力,只有这样你才能深入到理论层面,学习算法背后的数学概念。

自上而下的一个很好的例子是谷歌创建的机器学习速成班。它给你一个动手学习的方法。使用真实世界的案例场景、可视化和大量练习,学习者可以享受学习过程,而不会被复杂的数学概念淹没。它快速、有趣、高效,最重要的是,它是自学者熟悉机器学习的好方法。

大规模开放在线课程(MOOCs)

谷歌的机器学习速成课程就是 MOOC(大规模开放在线课程)的一个例子。网上有很多 MOOCs。有些是由顶尖大学设计的(查看本页浏览斯坦福大学的 MOOCs),有些是由个人贡献者甚至独立学校发布的。

从个人贡献者那里找到课程的最佳资源是 Udemy。它拥有世界上最大的课程选择,大约 130,000 个在线视频课程,每个月都有新的内容发布。机器学习区有大量的课程可供选择。价格非常实惠。每个课程都有一个评论和一个评分,帮助你做出正确的决定,并消除低质量的内容。

至于学校和大学,有很多选择可以考虑。学校和大学的 MOOCs 通常更贵。这完全可以理解:我们为经验丰富的学者创造的最高质量的学习材料付费。

教学大纲可能会保持不变,但通过学校或大学的 MOOC,你通常有机会获得对你工作的反馈。这通常意味着对项目的回顾,或者有机会向该领域的专家提出你的问题。一些地方甚至提供办公时间和工作人员的直播,这可能是非常有用的。

我最喜欢的学习机器学习的网站之一是 Udacity 。他们所谓的纳米学位是 3 到 6 个月的课程,有大量的实践和很好的、简明的理论来支持实践技能。 Praktikum 是另一个我个人喜欢的研究机器学习的好地方。

Udacity 和 Praktikum 只是数据科学学校的几个例子。Udemy 并不是由个人贡献者创建的 MOOCs 的唯一来源。斯坦福并不是唯一一所提供在线课程的大学。有许多其他学校、平台和大学向我们开放——几乎太多了,这可能会导致决策瘫痪或 FOMO。

因为有这么多好的资源,所以找到合适的学习地点的过程很有挑战性,也很耗时。希望现在你对 MOOC 提供商的不同之处以及应该寻找什么有了一个很好的认识。尽管 MOOC 是一种很好的学习形式,但它不是唯一的选择。

训练营

另一种学习机器学习的方式是通过训练营。参加训练营类似于参加马拉松比赛。这比常规的体育活动时间更长,强度更大,也更有身临其境的感觉。但是在你付钱之前要小心,因为训练营并不适合所有人。

就参与度而言,你在训练营获得的经验将类似于获得大学学位,因为训练营也需要对学习过程的全身心投入。

学位和训练营的主要区别在于完成它们需要的时间。整个训练营过程通常不超过 6 个月,平均 3-4 个月。一些训练营甚至保证他们的学生最终会得到一份工作。

训练营如何能带来和大学毕业一样的结果(一份工作)?即使你花在学习上的时间更少了(为此付出的代价也更少了),最终的结果还是一样的。不可疑吗?

嗯,这里的秘密是大多数训练营使用自上而下的方法进行教育。学生们在短时间内获得实用 技能,让他们在课程结束后获得一份工作机会,然后在工作中不断扩展他们的知识。

在价格方面,训练营通常比普通的 MOOCs 要贵一些。根据我的经验,我可以说,如果你有机会进入集训营的密集环境,你肯定会从中受益匪浅。

跳板是提供机器学习项目的训练营之一。该课程耗时 6 个月,每周需要 15-20 个小时才能完成。如果训练营提出的方法符合你的学习方式,我会推荐你看看这个训练营列表来浏览可用的项目。

机器学习教育的自下而上方法

或者,如果你有时间投入学习,有必要的财力,有耐心和渴望从最基础的开始学习一切,你应该考虑自下而上的方法。这将帮助你建立一个坚实的基础,确保顺利融入 ML 的劳动力。

自下而上是一种传统的学习方法。你先学理论部分,然后才慢慢走向实践方面。就机器学习而言,它意味着:

  • 获得扎实的数学背景(包括微积分、离散数学、线性代数、概率论和统计学);
  • 精通编程(通常是 Python 编程);
  • 学习后端/软件开发的核心原则;
  • 了解数据库、数据查询和处理;
  • 掌握数据抓取、清理、操作和探索的原理;

只有这样,你才可能转到某种“机器学习入门”课程,该课程将教你机器学习算法的基础知识。

需要时间吗?是的, 还有很多呢。至少要 3 年。

但是,你需要一个学位来获得工作机会,并开始机器学习的职业生涯吗?不,没有大学文凭你也能找到工作。

那么自下而上的 ML 教育有什么好处呢?会得到高深的知识吗?磨砺加速未来职业发展所需的技能?当然,是的!你的知识和技能将会全面而完整。这对你的事业会是一个促进。

你现在学到的基础知识会帮助你理解未来的 ML 发展吗?是啊!机器学习领域正在快速变化。从大学教育中获得的坚实基础将帮助你走在进步的前沿。

自我设计一个涵盖进入机器学习领域所需的所有方面的全日制教学大纲可能非常困难。没有合适的背景和有经验的员工的支持,对一些人来说是不可能的。这就是为什么大多数选择自下而上的学习方法的学习者,坚持传统的学术道路并获得学位。

在线硕士学位

我不会花太多时间用常规的课堂来谈论大学学位。你们大多数人都很清楚它是什么,以及它是如何工作的。相反,我想谈谈在线教育。最近,这一潮流有了很大的发展,为学生提供了很多新的机会。以下是在线教育的一些好处:

  • 它模糊了边界。只要能上网,就能获得世界顶尖大学的最好教育项目;
  • 性价比高。与传统的、全日制的、现场的形式相比,获得学位的价格要便宜得多;
  • 所有的决定都取决于你。学生可以灵活安排时间。你决定何时学习,学习多长时间,在哪里学习;
  • 方便。不需要花时间通勤和闲聊,你可以专注于学习。大多数工作资料都是数字格式的(电子书、视频、小测验、练习测试),所以你可以随时回顾和更新。

在线教育的优势显而易见。我们都希望付出更少,知道更多,更有效率,有更多属于自己的时间。在线教育给了我们这些机会。

重要的是,转到在线课程不会影响课程质量,也不会导致有限的沟通和工作人员的支持。相比之下,在线学生对与同学和教学人员的联系感到更满意。转为在线形式的全日制学生在教育项目方面没有看到任何变化。

我个人喜欢在线获取学位的新方式。这里有几个建议,你可以从中寻找适合自己的在线学位:

许多其他大学和学院提供在线学位。花点时间浏览可用的程序,选择符合您要求的程序。这个排名对你来说可能是一个很好的起点。

机器学习概念和要学习的主题

你现在应该很好地理解如何学习机器学习。但是你到底应该关注什么?这就是我们在本章要讨论的内容。

正如你所料,遵循自上而下方法的学生的关注点不同于那些自下而上方法的学生。让我们看看这两类学生的教学大纲是什么样的。

自下而上的 ML 课程

对于采用自下而上方法的人来说,传统的教学大纲可能是这样的:

  • 数学:

    • 结石
    • 线性代数
    • 离散数学
    • 概率论
    • 描述和推断统计
  • 编程:

    • 基本 Python
    • 高级 Python (OOP,主要库如 Pandas,Numpy,Matplotlib 等…)
    • 算法
    • 结构化查询语言
    • 第二编程语言:C++或 R(可选)
  • 机器学习:

    • 监督算法(回归、分类)
    • 无监督和半监督算法(聚类、降维、基于图形的算法)
    • 深度学习(CNN 和 RNNs)
    • 强化学习(动态规划、蒙特卡罗方法、启发式方法)
  • 不同任务的机器学习算法:

    • 计算机视觉(例如:分类、物体检测、语义分割)
    • 自然语言处理(例如:文本分类、情感分析、语言建模、机器翻译)
    • 推荐系统
    • 经典机器学习

课程中的主题可能会有所不同,但上述计划结构是相当普遍和完善的。

自上而下的 ML 课程

自上而下的实践者应该仔细考虑他们的大纲。他们的时间宝贵,资源有限。至关重要的是,只针对那些将最大化最终结果的部分。

根据你最终想从事的职业,你的学习计划会有所不同。永远记住你的最终目标是什么:快速有效地完成工作。它将始终帮助你专注于最终结果,并相应地调整你的学习路径。

对于自上而下的从业者,我建议以下学习计划:

  1. 定义您感兴趣的机器学习流;
  2. 理解给定流程中问题的结构;
  3. 寻找最佳实践,并尝试在高层次上理解它们;
  4. 找到一个应用这些最佳实践可以解决的问题。求解时使用高级工具。

例如,你喜欢处理数字,并希望将机器学习应用于此。在这种情况下,经典的机器学习是你的选择。

作为第一步,你做简单的研究,找出在你的问题域(数域)中性能最好的方法/算法,并把这个算法应用到你的问题中。

如果你在工作中没有问题,可以在最大的机器学习社区之一-ka ggle找到它。它有一个竞赛列表,上面列有你可以解决的问题。当问题被定义和明确后,寻找 Python 库,从中可以导入性能最佳的算法,并将它们应用到您的问题中。

再比如。你喜欢处理图像和视频,所以你想学习机器学习并将其与你的数字激情联系起来。鉴于此,计算机视觉工程是你的 ML 流的选择。谷歌计算机视觉工程师解决的问题。从高层次上理解这些问题是什么,以及哪些算法可以解决它们。在 github 上找到这些算法(那里有许多开源解决方案),并将其应用于 kaggle 的一个问题。

在你前进的道路上,你会面临许多陷阱。不要因此而感到沮丧。相反,我建议做以下事情:

  • 了解是什么阻止你解决问题;
  • 尝试找到一个快速的解决方案;
  • 如果没有,找一个合适的课程,帮助你更好地准备你所面临的问题。

让我们用图像和视频继续我们的第二个例子。经过研究,你发现自己从事计算机视觉工作。你知道计算机视觉工程师可以解决多个问题:他们可以对图像进行分类,检测图像中的对象,还可以从图像中语义分割对象。

你觉得分类问题没有其他问题复杂,所以你想从它开始。你没有工作上的问题,所以你去了 kaggle.com 寻找灵感。经过更多的研究,你注意到一个有趣的项目:创建一个图像分类器来区分狗和猫。

您寻找图像分类的最佳实践,这将您引向卷积神经网络(CNN)。你开始看 CNN 是什么,发现它们相当复杂。知道 CNN 是你需要的东西,你找到一个免费的在线课程解释 CNN 是什么。稍后,有了关于 CNN 的知识,您现在就可以获取所有信息并创建一个想要的分类器。

我希望你现在对你的工作流程应该如何设计有一个感觉。

结论

互联网上有许多信息来源可供我们使用。如果你浏览网页,大多数旨在为你的机器学习生涯做准备的指南要么只是关于自下而上的方法,要么只是你可以学习的特定学校的广告。这两种信息来源都不应该被认真对待。

在这篇文章中,我强调了有两种不同的方法可以用来实现机器学习:

  • 自上而下(问题->实践->理论),
  • 自下而上(理论->实践->问题)。

我的建议是基于在机器学习领域多年的经验和团队合作。我希望您能从我的建议中受益,并选择最适合您需求的方法。

祝你好运!

如何让一个机器学习项目更有可能成功?

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-make-machine-learning-project-more-likely-to-succeed

创新的速度是极端的。似乎每天你都会听到人工智能扰乱另一个行业或职业。先说项目管理遇到人工学习会怎么样。

与标准产品和服务不同,产品化的解决方案(如作为产品的人工智能软件)永远不会完成或完全移交给客户。它们是正在进行的项目,不断改进以满足用户不断变化的需求。

产品化的解决方案较少依赖于传统的基于项目的交付方法,而更多地依赖于基于产品开发的方法。灵活性和适应性对于满足客户需求至关重要。人工智能可以简化整个过程,并使最新的信息随时可用,有助于快速决策和加快交付。

AI 使项目经理能够通过自动化日常任务(如绩效报告)转变为促进型领导者。AI 可以从数据中检测和发现你看不到的模式,然后将这些信息与你的数据结合起来,就你想要创造的新产品做出更好的决策。

人工智能可以简化利益相关者参与的许多方面,如持续的电子邮件沟通和反馈。它还可以监控互动,以促进更好的沟通和知识转移。人工智能提高了生产率,分散了运营。

可以使用 AI 监控流程,以确保遵守协议,检查分配任务时的资源可用性,提供实时报告,以及管理各种程序。为了让组织保持敏捷和高效,他们需要将日常任务交给人工智能,接受新的管理实践,并给予员工更多的创造性自由。

人工智能可以帮助你预测可能错过的截止日期、团队成员的生产力、紧急风险和质量水平。这些预测通过以下方式指导更好的决策:

  • 排班计划,
  • 交付时间概率,
  • 预算监控,
  • 人员委派和任务跟踪,
  • 风险评估。

企业面临激烈的竞争,因此他们努力实现最高的运营效率和效益。人工智能运营和项目有不同的可交付成果,但结构相似。

可预测性创造可扩展性,可扩展性带来增长。如果项目可以被分解成可预测的过程,那么它们就可以被自动化并被扩展成可预测的收入流。因此,组织可以利用人工智能来产生可预测的结果,并在避免项目瓶颈的同时发展得更大更快。

操作化人工智能

国际分析研究所(International Institute for Analytics)在 2019 年发布的一份白皮书估计,当时只有不到 10%的人工智能试点项目达到了全面生产。生产阶段可能是最复杂的,但它通常在人工智能项目中被低估。运营人工智能仅仅意味着管理一个人工智能项目的完整端到端生命周期。

在这种方法中,各种实验被应用于真实的业务问题,并以一定的规模和速度进行复制。AI 的项目开发工作流程不同于传统的应用开发工作流程。

除了构建-测试-部署-管理的流程顺序之外,它还有两个不同的操作阶段:

训练阶段是人工智能算法从数据中学习模式和趋势,并建立模型的阶段。推理阶段使用构建的模型对新的、看不见的数据(真实世界的数据)进行预测/归纳。本质上,训练阶段发生在组织的“实验”中,而推理阶段发生在“现实世界”中。

采用人工智能是一些行业的优先事项,但它有许多潜在的应用,最终可能会被广泛使用。需要认识到一种系统化的方法来操作人工智能,以可重复、及时的方式构建人工智能产品,以缩短流程,降低开销,减少风险。

为了创建具有真实规模实现和真实世界应用的成功人工智能产品,对组织结构、资源、客户需求、预算和内部工作流程的正确理解至关重要。运作人工智能的标准化方法包括范围、理解、构建、部署、管理和信任,传播协作流程。

人工智能生命周期的各个阶段

企业需要一种系统化的方法来管理 AI 产品的端到端生命周期。如前所述,该生命周期由 5 个阶段组成,通常定义如下:

  • 范围:为了防止误解并为各自的目标问题构建正确的解决方案,利益相关者和人工智能专业团队需要减少模糊性。这是通过界定用例请求的范围并根据痛点对 AI 产品功能进行优先排序来实现的。在业务涉众和技术团队之间保持一致的沟通和透明度,以及成功的业务和技术成果的详细定义是至关重要的。就关键性能指标(KPI)和解决方案预期的质量标准达成一致是项目成功和性能评审的关键。范围要求理解业务问题,并要求涉众和技术团队把握业务机会和潜在影响。这个阶段是一个协作过程,以了解问题的难点,并建立同理心,以充分了解可能的用户需求。通过利益相关者和技术团队之间的共享语言,对难点和选项进行优先排序,以制定关于特定人工智能任务的行动计划,从而解决和指示实施环境。范围界定阶段指导项目目标的定义和与团队业务目标一致的远景。在此阶段,需要识别和记录隐含的风险和假设。这个阶段有助于开发风险评估策略,并定义最小可行产品。

  • 明白:人工智能并不是一个神奇的解决方案,所以如果没有意图的建造它也不会有什么帮助。开发阶段由“训练”和“干扰”组成,数据至关重要。没有数据就没有人工智能项目,格言“垃圾进,垃圾出”是构建成功人工智能项目的核心。这个阶段探索和理解数据源、元数据、沿袭、与其他数据集的关系、数据质量度量,并为业务机会范围内的治理建立适当的规则和策略。这一阶段仅仅是开发相应人工智能计划所需的数据采集策略和管理。

  • 构建:人工智能不是铁板一块,因为它创造的巨大价值来自各种人工智能能力。这个阶段是一系列迭代,专注于构建人工智能模型所必需的特定功能:数据探索、数据标记、准备、特征工程、模型构建、测试以及预测行为或发现见解。这一协作过程涉及各种工具、技术和框架,这些工具、技术和框架可以是开源的,也可以是专有的。构建阶段最好作为一系列敏捷冲刺来进行。每个 sprint 都有一个明确的 ROI 目标和结果。这组冲刺的数量和持续时间由项目经理决定。每个 sprint 应该产生一个最终可交付物的原型。

  • 部署:部署阶段代表全面的人工智能能力,其中使用现实生活中的数据来解决现实生活中的问题。这一步只是开发现实生活中使用的模型,将概念验证(POC)推向生产。它具有更高的复杂性,取决于公司结构、提议的客户、公司规模、内部工作流程、道德规范、基础设施需求、数据管理、知识、预算和现实生活条件。这个阶段定义了特定系统的数据部署策略,因为人工智能模型可以部署在许多系统和接口上。使用 AI 模型的平台对于部署细节是唯一的,并且取决于用例。从“构建”到“部署”的结构化方法被称为 MLOps(机器学习操作),因为它建立了一个将资产从开发环境转移到生产环境的管道。将资产从开发转移到生产需要一系列的步骤,这些步骤引导到持续集成/持续部署(CI/CD)范例中,并由 CI/CD 管道来支持。下图显示了使用 CI/CD 的 AI 管道的健壮实现,它具有自动化 ML 管道设置特征以及自动化 CI/CD 例程。

这个 CI/CD 为整个 AI 生命周期提供了一个结构和优化的工作流程。因此,最终目标可以很容易地作为成功的基准,并实现迭代改进。

  • 管理和信任: AI 项目需要资源的高效管理和性能优化的支持。就像杰森·塔玛拉说的,“在一个问题上投入更多的资源并不能得到正确的答案;这反而会让你更快找到错误的答案。”随着时间的推移,部署模型的性能会降低,因为新的模式和新的客户意图会受到现实环境的影响。这种退化是由于训练阶段超出了现实生活中这些新变化的范围。这个阶段监控模型性能指标,并根据定义的阈值评估这些指标。评估过程可以触发重新训练模型或者警告开发团队的自动化请求。调整各种性能指标和业务 KPI 改善了涉众之间的共享语言,并增加了对计划的信任。全面采用人工智能解决方案有助于增加信任和透明度。评估模型的可解释性、公平性和偏见是很重要的。负责任的人工智能是人工智能生态系统中一个快速发展的领域,它研究并提出了有助于信任人工智能部署的框架。公平性监控和偏见缓解是各种指导性政策规定的关键要求。模型结果的可解释性培养了信任,因为与黑盒范式相比,它理解决策是如何做出的。可解释性提高了人工智能过程的透明度,模型特征的量化使根本原因分析变得容易。

特定的机器学习挑战:项目启动

了解机器学习团队

机器学习团队可能不同于普通的软件开发团队成员。随着组织努力为成功构建人工智能做好准备,他们需要考虑和理解谁参与这个过程的问题。应该建立的最终组是领导、分析和工程、数据和治理以及设计和可视化。点击阅读更多

业务接受和采用

在大多数情况下,业务客户会到您的团队寻求帮助,以满足他们的业务目标,并对在他们的领域引入机器学习感到兴奋。但很少有人理解自动化当前业务流程和使用复杂算法来做出人类当前正在做出的决策的后果。这就像商业客户过去每天开车去上班一样。而现在,机器学习团队告诉他们,他们必须使用自动驾驶汽车,并接受它会工作得更好。将这些预测模型部署到您公司内部的实际生产中需要与业务客户进行坦率的讨论,确保他们了解如何推广该模型,以便其团队接受、采用并充分利用该模型。

缺乏项目章程

对于机器学习项目来说,有一个项目章程是很有帮助的,即使方法是敏捷的。这将有助于聚焦业务问题,并给出工作愿景。项目章程至少应该有项目范围、数据来源、业务度量和利益相关者列表。许多公司组建了数据科学或机器学习团队,因为他们知道这是一种竞争优势。尽管如此,他们可能很难获得实际的商业价值。创建项目章程将引出业务度量并计算模型提升(模型改善当前情况的数量)。这个项目章程定义了项目的愿景,并使机器学习团队专注于业务目标。

特定的机器学习挑战:项目规划

缺乏全面的项目计划

机器学习项目的推荐最佳实践是使用某种形式的敏捷方法。完整的项目计划将有助于团队集中精力,并向利益相关者提供切实可行的交付成果和时间表。这个综合计划的一个推荐模板是CROSSIindustrySstandardPprocess forDATAMining(CRISP-DM)过程模型。这是一个六阶段护栏,以帮助规划,组织和实施人工智能项目。这是一个为数据挖掘开发的标准,它紧密地转化为执行 AI/ML 项目所需的步骤。

CRISP-DM 方法的组成部分可以作为项目中的主要支柱和功能特性。让我们进行一个简短的演练:

  1. 业务理解

这一步着重于理解项目的高层需求、目标和定义业务度量。此步骤还评估资源可用性、风险和意外情况,并进行成本效益分析。此外,选择要使用的技术和工具也可以在这里讨论,项目章程的签署也可以在这个阶段交付。虽然许多团队匆匆忙忙地完成了这个阶段,但是建立一个坚实的业务理解对于构建项目的基础是必不可少的。

  1. 数据理解

数据是任何机器学习项目的主要部分。没有数据可以学习,模型就无法存在。不幸的是,在许多公司中,由于法规和程序的原因,访问数据和使用数据可能非常耗时。这一步的重点是识别、探索、收集和分析数据集,以帮助完成项目目标。这一步包括定义数据源、访问数据、创建数据存储环境和初步数据分析。

  1. 数据准备:

即使获得了您需要的数据,当它在企业中传播时,也可能需要一些清理或转换。这一步为建模准备数据集;它包括选择数据、清理数据、格式化数据、集成数据和构建数据的子任务。这个阶段包括为 ETL(提取、转换、加载)创建数据管道。数据会被修改几次。理解建议的子任务数据准备中涉及的过程对于有效的模型构建是必不可少的。点击阅读更多

  1. 建模:

在数据准备之后,是时候基于几种不同的建模技术来构建和评估各种模型了。这一步包括选择建模技术、特征工程、生成测试设计、构建和评估模型。CRISP-DM 指南建议“重复建模和评估,直到你坚信你已经找到了最好的模型。”

  1. 评价:

之前介绍的评估和评价主要集中在技术模型评估上。评估阶段更广泛,因为它评估哪个模型最符合业务目标和定义的基线。此阶段的子任务是评估结果(模型提升、性能指标)、审查流程和确定后续步骤。

  1. 部署:

根据不同的需求,部署阶段可以简单到生成一个报告,也可以复杂到在整个企业中实现一个可重复的数据挖掘过程–CRISP-DM 指南。这一步的复杂性取决于部署策略。这一步包括规划部署、监控和维护、生成最终报告以及审查。建议的子任务包括创建调用应用程序、部署到质量保证(QA)、自动化数据管道、集成测试和部署到生产。

  1. 建立敏捷框架:

有效的沟通是成功的项目管理和交付的关键组成部分。项目状态报告是根据项目计划定期正式报告项目进展情况。作为项目经理,状态报告将是您工作的一部分。对于 JIRA 或 TFX 这样的工具,充分的规划和结构是必不可少的。

首先,定义项目中每个利益相关者的角色。明确谁将扮演项目负责人的角色,scrum master,发布培训工程师,谁是你团队的技术领导。

接下来,想想大局。这个模型项目是一个独立的不连贯的工作吗?大概不是在一个组织良好的团队里。工程师和数据科学家创建几个较小的模型,然后一起使用它们来解决不同的业务问题。很有可能,目前的模式是一个更大愿景的一部分。

与技术主管交谈,了解该模型将如何开发和使用。如果模型是当前工作的一部分,您可能想要将这个项目添加到最近的敏捷发布系列(art)中,如果它有意义并且得到团队的同意。另一件要考虑的事情是设置您的敏捷板,以便轻松地与其他机器学习项目一起进入项目或投资组合视图。创建项目组合级别的仪表板在与执行经理交流时非常有用,并让您快速查看整个团队的健康状况。

定义您的计划或功能,它们是您想要实现的主要业务里程碑。您可以从我们在项目计划中定义的子任务开始特性列表。您应该与产品负责人和技术负责人一起验证这些特性,然后与同样的人一起确定它们的优先级,并保持一致的结构。

在吉拉或您可能想要使用的其他工具中设置一个一致的结构,可以更容易地创建自动化的指标和报告。此外,就方法、流程以及如何使用必要的工具对团队进行培训。

为您的第一个产品增量(PI)或发布计划做准备。一旦你有了一个计划和一些定义好的特性,和你的团队建立一个待办事项梳理会议,开始在每个特性下创建一些故事。当你的待办事项达到一定规模时,建立你的第一个 PI 计划。我的建议是要有一个明确的议程,你要提前与产品负责人和技术负责人沟通并检查它。该计划旨在用故事填充接下来的冲刺,并定义足够多的功能。它将标志着项目实现的开始和实际开发工作的开始。

特定的机器学习挑战:项目执行

团队的敏捷成熟度

开发团队可能对敏捷方法没有经验,因此引入敏捷概念应该逐步进行,并且应该根据需要提供培训。在许多情况下,您可以为团队安排有趣且相关的培训课程。一旦工作开始,团队就会熟悉这个过程,在你开始引入更严格的敏捷控制和生成有意义的度量标准之前,需要两到三次冲刺。

数据探索

没有大量数据就没有机器学习,在许多公司中,在允许技术团队处理数据之前,从一个地方获取数据需要打开访问凭证,遵循严格的法规或政策,甚至需要参加数据安全课程。这就是项目的数据探索阶段的持续时间难以预测的原因。

留出大量时间,从一开始就尽可能清楚地了解每个所需的数据源,这样您就可以为这个阶段做最好的准备。您可能会花一到两个 sprint 进行数据访问,另外两到三个 sprint 进行数据探索。

创建你的故事和敏捷来说明这种类型的工作;否则,你会得到一个看起来像一条扁平线的烧毁的图表。考虑在数据访问和数据探索中使用技术尖峰,或者如果您的团队能够处理的话,甚至可以在项目的这个阶段使用看板。当您为这个项目阶段创建故事时,尝试按数据源、按环境、甚至按团队成员将用户故事分割成垂直的片段;敏捷中巧妙的小而具体的故事会更好地展示工作的进展。

建模迭代

这是对项目经理的另一个挑战,因为会有未知和不确定性。技术团队无法估计建模工作需要多长时间,直到他们尝试不同的算法并多次调整功能。允许项目计划中的迭代。当你建立 sprint 并做计划时,创建足够小的用户故事,以便在一个 sprint 中完成,但最终建立更大的目标。

功能验证

当工程师定义数据中的特性时,他们很可能会使用这些特性,请确保您向业务客户验证了这一点。开发团队对事物只有技术上的看法。尽管如此,你还是要确保你的商业客户对他们认为有价值的特性有发言权。

模型可解释性

即使对开发者来说,机器学习中的算法也可能是一个黑盒。这个模型不能用通常的方法测试,因为没有我们可以遵循的规则。相反,机器基于不可重复的复杂计算来确定结果。这将使许多企业主不高兴,你的法律和监管部门将希望确保该模型没有任何偏见。有一些技术方法,比如使用特定的代码库,可以为模型提供足够的可解释性。

工作状态的可见性

企业主对机器学习项目的一个重要抱怨是缺乏对工作的可见性。这是因为这项工作的技术性很强。提供可见性的一种方法是使用敏捷度量来显示有多少特性正在进行,有多少被延迟,以及我们是否实现了我们对每个迭代或 PI 周期的承诺。

业务交付成果

确保在整个敏捷过程中,你和你的利益相关者有明确的检查点。让他们参加所有的关键会议,更重要的是,确保开发团队在项目的每个主要阶段结束时都有一个业务可交付成果,在那里他们做一个 sprint 演示并向业务客户展示他们的发现。作为项目经理,这是密切关注项目如何发展的一个很好的方法,特别是如果建模阶段的发现将促使项目范围发生变化。

特定的机器学习挑战:项目监控

设置 Agile 指标

最佳实践是始终记录敏捷指标。这些可以从基本速度计算、燃尽图和累积流程图开始。当团队刚刚形成并学习如何计划和评估他们的工作时,这些基本的度量标准在一开始就足够了。然而,随着项目的进展,团队习惯了敏捷过程,您可以创建更复杂的度量来帮助您提高团队的绩效和产出。吉拉和其他工具已经纳入了几份报告;如果没有可用的,将原始数据、epic 的故事和任务导出到 Excel 中,并创建您的报告和图表。我建议为执行管理层创建一个仪表板,以查看整个投资组合健康状况的高层次图片,然后根据需要深入每个艺术或项目查看细节。

设置业务和分析指标

正如我在项目启动和规划期间提到的,确保您的业务客户能够为您的项目定义他们的业务度量和成功标准。什么会让他们说这个项目给我们带来了很多价值。是销售额的增加,利润的增加,甚至是客户流失的减少?随着项目的发展,做好度量它的准备,甚至在模型投入生产之后,也有更多来自模型的技术度量,称为分析度量。

特定的机器学习挑战:项目结束

部署后的挑战

随着项目的结束和模型的上线,这需要一个清晰的所有权定义。现在谁拥有这个模型?仍然是您的团队,还是业务客户?期望业务客户知道如何拥有和维护模型通常是不合理的。然而,他们应该具有拥有调用应用程序或包装器的专业知识。

因此,当项目结束时,维护阶段就开始了。在这个阶段,作为项目经理,您应该向您的业务客户提供业务和分析指标,以确保模型按预期执行。这是创建变更控制过程的理想方法,因为模型可能会随着时间的推移而出现恶化的迹象。

也许网站上的情况发生了变化,现在模型功能不太好用了。也许最近数据发生了变化。不管是什么原因,有人(比如变更控制委员会)应该定期检查模型度量和性能,并决定是否应该重新培训或重新部署模型。

结论

我们已经探索了人工智能在项目管理中的某些方面,以及管理特定 ML 项目挑战的最佳实践。我希望你能从这篇文章中学到一些新的东西。感谢阅读!

如何让您的 TensorBoard 项目易于共享和协作

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-make-your-tensorboard-projects-easy-to-share-and-collaborate-on

我们都知道团队合作是每个机器学习项目的重要组成部分。尽管每个工程师都有自己的项目工作,但他们仍然需要与团队分享他们的成果,并对合作持开放态度。

因此,在本文中,您将学习如何使您的 ML 项目易于共享和协作,以及使之成为可能的工具。

我们将重点关注 TensorFlow/Keras 框架,该框架被全球的机器学习工程师广泛接受。我们将探讨 TensorBoard 的利弊,这是一种用于结果跟踪的基本工具。我们还会将其与更先进、更强大的竞争对手进行比较,看看他们能否帮助我们克服 TensorBoard 的局限性。

到本文结束时,您会知道:

  • 为什么只需不到一分钟的时间就能与队友分享您的整个 ML 工作流程;
  • 如何扩展可以共享的东西,开始记录和共享模型属性(参数、检查点)、输入数据、图像、度量、图表、硬件消耗等很多有趣的东西;
  • 如果您的项目在 Jupyter 笔记本中,您如何共享和协作;
  • 如何让您的同事访问您的实验运行结果,并让他们以编程方式下载您的项目结果、数据或模型属性,以便他们能够独立工作。

你想知道更多吗?拿起你的爆米花,继续阅读!

通过 TensorBoard 记录

回归基础总是好的,在我们的情况下,它是 tensor board——我们大多数人都喜欢使用的古老、但仍然可靠和方便的工具。

让我告诉你这不会是另一篇关于 TensorBoard 及其功能无聊 文章。我们都知道 TensorBoard 是什么。我不会再重复了。

相反,我想分享我在 TensorBoard 工作中获得的经验和知识,并向您展示使用它的最佳案例以及局限性。

为了让它更有趣,我将把我的推理基于现实生活中的机器学习项目:让我们建立一个图像分类器,它告诉我们图像的方向输入。有四个选项可用,如下图所示:

Image orientation options

Four potential orientation options of an image.
We want to build a classifier to predict orientation.

我们有很多方法可以做到这一点。为了简单起见,我决定微调基于 ResNet50 的模型来解决这个问题。由于我们使用 TensorFlow/Keras 框架,我使用下面的代码片段创建了我的模型架构:

backbone = ResNet50(include_top = False,
                    input_shape = input_shape,
                    pooling = 'avg')

n_classes = 4

model = Sequential()
model.add(backbone)

dense_count = 256
model.add(Dense(dense_count))
model.add(LeakyReLU())
model.add(BatchNormalization())

model.add(Dense(n_classes))
model.add(Softmax())

在我定义模型架构的地方截取代码

我不会花太多时间解释我选择模型参数的理由,因为它不在今天的议程上(如果你真的感兴趣,请参考这篇文章)。

快速提醒:如何启用 TensorBoard 并让其负责跟踪模型日志?

首先,我定义了一个目录的路径,我的日志将存储在这个目录中。然后我创建一个 TensorBoard 回调对象。它会将日志存储在先前指定的目录中。

logdir = './logs_import/'
os.makedirs(logdir, exist_ok = True)

tbCallBack = keras.callbacks.TensorBoard(log_dir = logdir,
                                         histogram_freq = 0,
                                         write_graph = False,
                                         write_images = False)

发起张量板回调

有了上面的代码片段,我未来的模型日志将被存储在./logs_import/,这是我刚刚通过.makedirs()函数创建的,可以在 os 库中找到。

为了启动 TensorBoard,我打开了一个新的终端窗口,并导航到我的项目目录。从那里,我执行以下命令:

tensorboard --logdir=./logs_import

TensorBoard 现在将在我默认的网络浏览器的新标签页中自动启动。它现在是空的,因为我们还没有开始伐木。为了开始日志记录,我拟合了模型并开始训练工作,如下面的代码片段所示。

model.fit_generator(generator = train_generator,
                    steps_per_epoch = training_steps_per_epoch,
                    epochs = 100,
                    validation_data = validation_generator,
                    validation_steps = validation_steps_per_epoch,
                    callbacks = [rLrCallBack,
                                 tbCallBack,
                                 mcCallBack_loss,
                                 mcCallBack_acc,
                                 esCallBack],
                    use_multiprocessing = True,
                    workers = 8
                   )

安装我的模型开始训练

请注意,之前启动的 TensorBoard 回调是作为参数在其他回调中传递的。

在 GPU 上运行了大约一个小时和 20 个周期后,我的模型完成了训练。让我们看看 TensorBoard 为我们准备了什么。为此,我返回到之前打开的浏览器选项卡,我看到记录了 5 个标量:

  • epoch_lossepoch_val_loss 分别是训练集和验证集的模型损失函数值;
  • epoch _ spare _ categorial _ accuracyepoch _ val _ spare _ categorial _ accuracy分别是训练集和验证集的模型度量值;
  • epoch_lr 是优化器在整个训练过程中使用的学习率值。因为它会随时间变化,所以会被记录下来。

Tensorboard logs

Outlined in red are logs that TensorBoard keeps track of and displays in its UI.

除了标量,我们还可以用 TensorBoard 跟踪其他一些东西。看看下面的 TensorBoard 用户界面截图,看看我们还能追踪什么:

Tensorboard tracking

Outlined in red are things you can track with TensorBoard.

这是一个简短的提醒,告诉你可以用 TensorBoard 做什么。现在我们来看看它在结果分享方面是否有局限性。

问题陈述

你有没有想过用 TensorBoard 和你的团队分享和讨论工作进展?有几种方法可以做到这一点。

首先,TensorFlow 有自己的工具包( TensorBoard.dev )用于 TensorBoard 分享。这是一个值得考虑的好选择,但是请记住你的 TensorBoard 将会公开可见,并且你无法管理对它的访问。此警告来自 TensorBoard 官方文档:

"……您上传的 TensorBoard 将公开可见,因此请勿上传敏感数据。

*所以对于任何非开源的项目,你可能需要一个更安全的选择。

其次,我们过去可以使用一种叫做 Aughie Boards 的第三方服务。这篇文章的中描述了它的分享方式,但不幸的是,这项服务被暂停,不可用。

第三, Neptune.ai 有一个完善的共享实验结果的解决方案——你只需复制一个链接。您可以通过管理访问限制来控制隐私。与我们选择的框架(TensorFlow/Keras)的集成是完全支持的,所以没有必要改变我们已经建立的工作流程。

海王星似乎是解决我们的进步共享问题的最合理的选择。让我们看看如何将它集成到我们的项目中。

海王星集成

幸运的是,与海王星融合是一个平稳的过程。有两个选项可以考虑:

  1. 通过直接导入张量板日志:

这个选项 在你的模型已经被训练过并且所有必要的日志都已经存储在你的日志目录中的时候特别方便。我们只是想上传我们的结果,让他们可以分享。

当我把我的日志转换成海王星实验时,我得到了以下结果:

Tensorboard Neptune import logs

Logs imported to Neptune

看一看,我的项目空间里出现了两行(实验)。当我们仔细观察时,我们看到第一行代表训练集日志,第二行代表验证日志。从实验 ID 旁边的标签或/和 tf/run/path 属性可以看出这一点。

让我们检查一下我的导入是否成功。为此,我单击所选实验的 ID 。这是里面的内容:

Tensorboard Neptune display logs

Training scalar logs imported to Neptune and displayed as plots

描述每个训练时期的模型损失和准确性(选定指标)的两个图表。

有几种方法可以检查图表。我可以改变轴刻度:在 y 轴的线性或对数刻度之间切换,或者/和在 x 轴的时间或历元数之间交换。TensorBoard 的常见功能,如图表平滑和缩放,也是可用的。

海王星为我们的日志扮演一个主人的角色。如果这是您想要的,让我向您展示如何将您的日志导入到 Neptune。有几个简单的步骤:

  • 获取 Python 3.x 和以下库:
    • 海王星-张量板;
    • 张量板。

通过执行以下 bash 命令来安装它们:

pip install tensorboard==2.4.0 neptune-tensorboard==0.5.1
  • 获取您的 API 令牌并将其设置为 NEPTUNE_API_TOKEN:
    • 对于 Linux/iOS 用户,用于 api 令牌设置的 bash 命令是:
export NEPTUNE_API_TOKEN='YOUR_API_TOKEN'
set NEPTUNE_API_TOKEN="YOUR_API_TOKEN"
  • 在海王星托管您的 TensorBoard 日志:
    • 导航到您的 TensorBoard 日志目录并运行:
neptune tensorboard --project USER_NAME/PROJECT_NAME
  • 或者,您可以将 Neptune 指向您的 TensorBoard 日志目录:
neptune tensorboard /PATH/TO/TensorBoard_logdir
--project  USER_NAME/PROJECT_NAME

如果你需要更多的细节,你可以观看 Jakub Czakon 的视频指南(点击下图获得视频链接),了解如何将 TensorBoard 日志导入 Neptune:

  1. 通过与 TensorFlow/Keras 框架的集成:

刚刚开始你的项目,你想把 Neptune 整合到你的工作流程中?我强烈建议使用这种集成方法。

这个方法只需要几行额外的代码就可以提供更高级的功能。你会喜欢你的实验/日志是如何被组织、存储和分享的。

让我们从头开始我的分类项目,但现在我将借助第二种积分方法积分海王星。集成后,与第一种方法相比,我项目的实验页面发生了有趣的变化:

Neptune Tensorboard integration

Experiment results displayed after using the second integration method

看看它有多方便,不仅可以看到实验及其结果,还可以看到从实验 ID 向右走的一些参数(像 dense_layer骨干batch_size 等参数……)。

如果你展示十几个实验会怎么样?在我个人的实践中,当处理多个实验,试图比较它们或找到一个特殊的实验时,每个实验旁边的这种详细信息可以节省时间。

点击实验 ID 显示出与我们之前看到的几乎相同的图表,但是现在我们在一个实验 ID 下有训练和验证图。保持这种方式很方便,因为验证和训练图都引用一个特定的运行。

Tensorflow Neptune integration charts

Charts for the experiment created by integrating Neptune with TensorFlow/Keras

除了图表,我们还可以在海王星做其他事情。让我们看看参数选项卡:

Neptune Tensorflow parameters

Parameters of a model associated with a given experiment. Also hosted at Neptune

海王星已经存储了一些与当前实验相关的模型参数。这些确切的参数显示在我们之前看到的实验 ID 旁边。

海王星是如何捕捉到这些参数的?稍后我会告诉你细节,现在我只想给你一个工具的高级概述。

让我们继续,打开监控选项卡:

Neptune Tensorflow resource utilization

Resource utilization displayed within Neptune for the training job associated with a given experiment

CPU 和 GPU 利用率显示为一个示例。

我们可以监视整个实验过程中资源利用率是如何变化的。我们可以观察 CPU 和 GPU 负载,以及内存消耗。当你的模型正在训练时,这种信息流动是实时的,所有这些信息都可以在一个单独的实验页面上看到,非常简洁。

让我向您展示我是如何获得上述信息的,以及实际的集成是如何工作的,这样您就可以自己完成了:

您可以通过执行以下 bash 命令轻松安装它们:

pip install tensorflow==2.3.1 neptune-contrib==0.4.129 neptune-client==0.25.0
  • 通过向您工作的脚本或 Jupyter 笔记本添加初始化代码片段来初始化 Neptune。下面是我的项目中初始化是如何完成的:
import neptune
import neptune_tensorboard as neptune_tb

token = '**********' 

neptune.init(project_qualified_name='anton-morgunov/image-orientation-detection-method',
             api_token=token)

neptune_tb.integrate_with_tensorflow()

在项目中初始化 Neptune 的代码片段

请注意,我故意模糊了我的令牌,因为它是我的帐户的私有令牌。当您在 Neptune 网站上注册帐户时,您的个人令牌将出现在您的个人资料页面中。

此外,请注意我在第 10 行中应用的.integrate_with_tensorflow()方法,它在我的工作空间中实现了与 TensorFlow/Keras 的实际集成。

  • 我的项目代码的其余部分和以前一样,除了我拟合模型的方式。现在看起来是这样的:
params = {
    'backbone': backbone.name,
    'dense_layer': dense_count,
    'batch_size_train': batch_train,
    'lr': learning_rate,
    'input_shape': input_shape
}

with neptune.create_experiment(name='resnet50_finetuning', params=params):
    model.fit_generator(generator = train_generator,
                        steps_per_epoch = training_steps_per_epoch,
                        epochs = 100,
                        validation_data = validation_generator,
                        validation_steps = validation_steps_per_epoch,
                        callbacks = [rLrCallBack,
                                     tbCallBack,
                                     mcCallBack_loss,
                                     mcCallBack_acc,
                                     esCallBack],
                        use_multiprocessing = True,
                        workers = 8
                       )

当您需要与 Neptune 集成时模型拟合的代码片段

您可以看到,在我的 Jupyter 笔记本的第一个单元格中,我创建了一个字典来指定一组与当前实验相关的参数。在下一个单元格中,我在创建实验时传递了这些参数。这就是 Neptune 如何将一组参数与给定的实验运行相关联。

模型拟合与我们通常在 TensorFlow/Keras 中所做的相似,唯一的区别是在第 2 行,我们指定了一个实验创建。

这就是在项目中集成 Neptune 和 TensorFlow/Keras 所需了解的全部内容。相当简单的过程,只需要你一点点时间。

分享您的作品

现在,当你把你的实验上传到海王星的时候,我们可以讨论结果共享。

根据您为项目设置的隐私级别,共享方法会有所不同。Neptune 有两个项目隐私选项:公开私有

共享公共项目:

鉴于你的项目没有任何限制,Neptune 提供了分享你的结果的最简单的方法:从你想要分享的网页上复制一个 URL。

以下是您可以通过 URL 分享的内容:

  • 你实验的细节,包括图表和二进制模型;
  • 为要比较的不同实验覆盖的比较图表;
  • Jupyter 笔记本,包括多个笔记本版本之间的检查点和差异。例如,为我分享的项目检查一个完整的笔记本。

您可以在帐户的“项目”选项卡中找到您的项目隐私级别:

Neptune project privacy

Project privacy level outlined in red for each of the projects in my workspace.
Some of them are public, some are private.

共享私人项目:

要对您的项目启用受限访问,您可以将其设置为私有。如果你想让你的工作保密,海王星让你管理谁有权访问和他们能做什么。

为此,您可以邀请队友加入您的团队工作区。受邀成员将被称为工作区内的“团队”。每个成员可以有一个选择的角色:所有者贡献者查看者

To do that, you can invite teammates to your teamworkspace. Invited members will be called a “team” within the workspace. Each member can have one of the selected roles: owner, contributor or viewer.

Neptune private projects

New team member invitation and role assignment within the workspace in Neptune

根据您分配给团队成员的访问级别,您可以限制给定用户可以执行的操作,从监控项目工作流到在同一工作区内启动他们自己的实验。

要了解更多细节,请观看一个简短的介绍视频,了解一个有组织的团队工作空间是什么样子的。

研究和非营利组织可以免费使用 Neptune 团队计划,但每个人都可以尝试一下。记住,你可以随心所欲地使用海王星个人计划(工作、研究、个人项目)。

你可以记录和分享的其他事情

机器学习工程师通常会测试多种方法来解决特定的技术任务。

每次训练是如何结束的?我们有最好的模型检查点,在单独的数据集上的性能结果,我特别喜欢做的是构建一些图表,帮助我直观地了解我的模型的功能。

将这些信息保存在一个与实验运行相关的地方不是很好吗?听起来是我理想的工作场所。

幸运的是,所有这些在海王星都有。因此,让我们利用它,并在我们的实验运行中包含一些额外的信息。

首先,我想上传我的模型的最佳检查点。方法如下:

将特定实验运行的模型最佳检查点上传到 Neptune

from sklearn.metrics import confusion_matrix
import scikitplot as skplt
from itertools import chain
import seaborn as sns
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)

path2best_ckpt = './checkpoints/epoch_16-val_loss-0.0019-val_acc_1.0000_import.hdf5'
best_ckpt_basename = os.path.basename(path2best_ckpt)
neptune.log_artifact(path2best_ckpt,
                     os.path.join('model_checkpoints/', best_ckpt_basename)
                    )

现在,在我的项目工作区的“工件”选项卡中,我看到了一个上传的检查点:

Now, within the “Artifacts” tab of my project workspace, I see an uploaded checkpoint:

Neptune Tensorboard artifacts

Uploaded checkpoint displayed and available within the Artifacts tab of my project workspace

现在,我将在测试集上评估我的训练模型。为此,我简单地做了以下事情:

在测试集上评估我的训练模型

p = eval_model.predict_generator(test_generator)

由于我在研究一个分类器,我想通过观察混淆矩阵和 ROC-AUC 曲线来评估它。让我们创建它们并将其附加到我们的实验中:

Since I worked on a classifier, I’d like to evaluate it by looking at the confusion matrix and at the ROC-AUC curve. Let’s create them and attach them to our experiment:

fig_roc, ax = plt.subplots(1, 1)
skplt.metrics.plot_roc_curve(y_true, np.flip(p, axis=0), ax=ax)

fig_cm = plt.figure()
sns.heatmap(conf_matrix, annot=True)

neptune.log_image('confusion matrix', fig_cm, image_name='conf_matrix')
neptune.log_image('roc_auc', fig_roc, image_name='roc_auc')

Neptune Tensorboard confusion matrix

Evaluating Models via ROC-AUC and Confusion Matrix plots
Uploading them to the workspace

以下是上传到我的工作空间的图:

Here are the plots uploaded to my workspace:

Neptune Tensorboard plots

Plots uploaded to the workspace become available at Logs tab

有很多事情你可以记录、跟踪,并在以后分享。检查该页面以查看还支持什么。

更酷的是,你的队友可以通过编程获取你上传的所有数据,以一种简单方便的方式

结论

TensorFlow 和 Keras 框架被广泛传播,工作共享和协作的问题对于我们这些在 ML 团队中工作的人来说是非常重要的。像 TensorBoard 这样的基本工具做得很好,但主要是针对独立工作。其他解决方案要么停止,要么缺乏适当的隐私管理。

Neptune 开发的解决方案很好地集成了 TensorFlow/Keras,并为我们的实验跟踪提供了丰富的功能。我们可以用我们选择的日志来补充每个实验,所以它被很好地描述并且容易理解。

我相信这个工具将有助于许多机器学习工程师寻找一个方便的实验跟踪和结果共享的解决方案。这对我很有帮助。

I believe that this tool will be helpful for many machine learning engineers looking for a convenient solution for experiment tracking and result sharing. It definitely helps me.*

如何管理深度强化学习研究团队——第 1 部分

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-manage-a-deep-reinforcement-learning-research-team-part-1

这篇博文是管理研究工作系列的开始。在里面,你会看到我如何维护一个有用的任务列表,如何管理我的团队完成这些任务

在我们作为研究人员的职业生涯中的某个时刻,我们中的许多人不得不从一个人的军队工作模式转变为管理一个研究员团队。不幸的是,我们中的许多人没有管理教育或经验。

在这个场景中出现的第一个问题是如何以一种有用的方式组织积压的任务,这样每个人都知道该做什么,以及他们的工作如何适应更大的图景(这是激励你的团队的一个重要部分)。

根据我的经验,我将向您展示如何创建并保存一个任务列表,让研究团队有时间完成工作。

但首先,让我们谈谈生产力。

生产率被高估了

《好到他们不能忽视你》和《深度工作》的作者卡尔·纽波特教授曾经写道,“的生产力被高估了”。他认为富有成效和有成就并不需要同时存在。

这似乎是真的。你可能认识一些非常有成就的人,尽管他们不是生产力大师。你可能就是其中之一。

像我父亲一样——他经常被电话分心,不得不工作到很晚才能完成任何事情。然而,他仍然经营着一家成功的企业,并照顾好家庭。

至于我,我是一个生产率极客。在大学期间,我阅读了所有关于生产力的书籍,比如“把事情做完”,然后组织了我自己的生产力系统。

它减轻了我的压力,让我有更多的时间与朋友和家人在一起。但这不是一个神奇的解决方案,也不是帮助我实现目标的东西。对我帮助最大的是坚持和努力完成项目的意愿,即使这会伤到我的大脑。

有成就的人和忙碌的人的区别在于他们痴迷于完成项目,尤其是那些难以完成的项目。

这是我将向你展示的任务管理系统的关键——关注结果和完成。

管理强化学习项目页面

我从加州大学纽波特分校的《完成的艺术:如何从忙碌到完成》 中学到了这个技巧。如果你对这些感兴趣,我绝对可以推荐整本书。

项目,而不是任务

从现在开始没有任务,只有项目。任务是你做的小事。项目是你实现的目标,这非常非常重要。

你可以花一整周的时间检查任务,感觉很棒,却在周五发现你什么也没完成。

项目不一定要很大,比如在一周内完成一整篇包含潜在研究和实验的论文。一个项目是一个原子的结果,就像“找出反向传播在深度学习中是如何工作的”。

如果你把这个分成小任务(在 backprop 上找学习资料,打印学习资料等等。),你可能会在一周内完成很多任务,但仍然不知道 backprop 是如何工作的。

过于专注于任务,比如寻找和阅读材料,你可能会错过你真正应该做的事情。你应该戴上耳机,钻研你能找到的任何关于反向传播的文献,做笔记并与同事讨论,以挑战你的理解。

要完成任务,你和你的团队必须专注于项目,而不是任务。你工作周的目标不是做任务,而是完成一个项目。

这可能现在看起来很明显,但它真的能抓住你。我还记得有一次我有一个项目要实现一个 SqueezeNet 深度神经网络。经过一周的工作,我发现自己深陷在 TensorFlow 文档中,阅读关于 softmax 实现的基本细节。

当然,没有任何工作代码。哪里出了问题?如果这还不够的话,原来我的队友放弃了等我,使用了开源代码。我太专注于我的任务,以至于我对我的团队来说变得毫无用处!

结果

好了,现在你知道项目及其结果比任务更重要。但是你如何定义一个好的结果,尤其是如果你没有管理经验的话?我准备了一些范例项目和它们可能的结果,让你有个概念。

项目

结果

| |

–找到一个特定问题的答案,比如“backprop。算法的工作原理”,并理解它。注意,仅仅阅读 backprop 是不够的!你必须产生一个结果,比如一个详细的笔记,或者向一个朋友解释。如果我研究更大的东西,我喜欢为我的团队安排一个研讨会。这样我们就有时间分享知识了。还有,我的笔记对以后修改题目很有用。如果你不喜欢写作,你可以准备一个演讲,或者制作一个视频,或者一个播客。对学习的结果要有创造性和明确性。
——你连自己不知道的都不知道(或者你在做一件叫“批阅论文”的事情)?然后你的结果是创建一个问题/难题/方法/结果等的列表。然后,如果你需要,你可以把每个问题作为一个项目来解决。你可以决定什么是最有意义的,以什么样的顺序完成。

|
| --- | --- |
| –找到特定问题的答案,如“背面如何投影”。算法的工作原理”,并理解它。注意,光看 backprop 是不够的!你必须产生一个结果,比如一个详细的笔记,或者向一个朋友解释。如果我研究更大的东西,我喜欢为我的团队安排一个研讨会。这样我们就有时间分享知识了。还有,我的笔记对以后修改题目很有用。如果你不喜欢写作,你可以准备一个演讲,或者制作一个视频,或者一个播客。对学习的结果要有创造性和明确性。
——你连自己不知道的都不知道(或者你在做一件叫“批阅论文”的事情)?然后你的结果是创建一个问题/难题/方法/结果等的列表。然后,如果你需要,你可以把每个问题作为一个项目来解决。你可以决定什么是最有意义的,以什么样的顺序完成。 | |
| –尽可能清晰地陈述一个假设,设计一个可以帮助你确认、拒绝,甚至无法确认/拒绝的实验(所有结果都一样好)。你的目标是通过每次实验,在你正在解决的研究问题上取得一点点进步。请注意,您可能会发现自己被困在磨砺完美实现的日子里,这根本不是实验的重点!每个实验结果都应该是你对你的问题所获得的一些知识。专注于此 | |
| –从一个空白文档开始,你的目标是简单地完成一个段落或一个(子)部分。不一定要完美。它必须足够好,才能推进到下一步:把它送给主管、顾问或你的队友审阅。得到当前版本的反馈后,你的目标是修改你的文本。还是那句话,不一定要完美。阅读它,尽你所能修复它。只迭代到足够好的那一点,进一步改进的代价太大(还有别的事要做)。
——注意,如果你从一开始就专注于完善整篇论文,并把它分成一个非常长的原子任务列表,那你将一事无成。您可能会在上面停留几天或几周,而迭代方法让您的工作更加灵活。你可以留下一个空白,写点别的东西,一旦你做了足够多的实验,再回来填补这个空白。这样,当你感到停滞不前时,你可以用写作来推动你的项目朝着正确的方向发展! | |

将项目放在页面上

现在,您可以创建一个包含您的项目的页面。下面是我的一个预测足球比赛比分的项目中的一个例子,使用了谷歌研究足球模拟器作为数据源和测试平台。@UW 和@PG 是两个团队成员的虚构姓名首字母。

@UW 在纸上写下了根据手工制作的特征预测预期分数的结果。

@PG cleaned Transformer 端到端解决方案代码发布在 GitHub 上。

  • XX 准备了应用程序来运行每种方法的预测,并与蒙特卡罗估计进行比较。
  • @PG 使用 Simple115 观察格式运行第一个变压器端到端解决方案培训。
  • @PG 对一批数据过度拟合了一个较小的端到端模型。
  • @UW 在足球比赛比分预测情境中了解变形金刚训练。
    • @UW 用“统计学习入门”这本书作为思考的食粮,对这个项目进行了深入思考,为下一步产生新的想法。
  • 上面你可以看到分配给两个团队成员的以过去简单时态描述的项目列表(这是可选的)。请注意,每个项目都清楚地陈述了我们的目标结果。划掉的位置是已完成的项目,XX 表示未分配的项目。

这个列表告诉团队已经做了什么,每个人目前在做什么,以及我们下一步要做什么。

现在让我们讨论如何使用这个页面。

轮毂和辐条

中枢辐射式办公室或工作安排告诉你,团队成员应该定期接触中枢中的想法,但要保持一种辐射,以便深入研究他们遇到的问题。

你的团队成员应该能够随心所欲地完成他们的项目。不要微观管理他们,这是行不通的。特别是在研究中,没有办法强行得出一个结果。

以教练的身份为队友服务,而不是指挥官。如果事情没有如你所愿,清楚地告诉你的队友应该改变什么,并提供帮助。

我发现一个很好的方法是建立一个类似 Scrum 的每日会议。在其中,我从查看项目页面开始。然后,我们谈论自上次会议以来所做的事情,我们发现的问题以及如何解决它们,我们更新我们的项目页面。

通常我们可能会重新分配项目,或者将它们分成更小的子项目,并重新安排它们的顺序。我们根据团队获得的新数据进行调整。

开会的一些小技巧

我们目前正处于冠状病毒疫情,这迫使我们只能在网上见面。如今,远程工作已经相当普遍,所以你可能在某种程度上已经做到了,甚至在疫情之前。随着时间的推移,我学到了一些关于组织在线会议和面对面会议的东西:

每个人都必须认真对待这些会议。出席会议,与你的队友同步,不要在后台做事情!

不要迟到!

  • 找一个安静的地方,不说话的时候把麦克风静音。
  • 开会前做好准备。尊重他人的时间,不要在所有人都在等待的时候寻找你想要展示的结果。
  • 总是以所需的最少成员数组织会议。你们可以一起开始会议,完成每个人都应该听到的内容,然后分成小组讨论特定的话题。
  • 不要安排超过要求的会议时间!它要么长达 10-15 分钟,“让我们讨论这一件事”,要么更接近于 1 小时,并与头脑风暴大致同步,以项目页面的更新结束。我发现大多数其他类型的会议都是浪费时间。
  • 当你发现讨论不再产生价值时,不要犹豫,尽快结束会议。
  • 讨论
  • 任务可能会有用。或者,正如我所说的,“下一步行动”可能有用。当你看到类似“完成论文的实验部分”这样的原始结果时,甚至开始都可能令人望而生畏。

然而,然后你可以定义下一个行动——“下一个你现在可以做的具体的事情来推进项目”。在这种情况下,可以是“用会议模板创建一个新的 LaTeX 文档”。

如果这不能帮助你开始,那么启动一个 20 分钟的计时器,告诉你自己:“我将只为这个项目工作 20 分钟,从下一个行动开始”。

如果在 20 分钟的训练结束后,你想站起来喝杯咖啡,那就去吧。然而,更多的时候,你会发现自己在心流中,除了项目什么都不想。

总而言之,永远不要忘记什么才是真正重要的:完成项目!

If at the end of the 20-minute session you feel like standing up and getting coffee, go for it. However, more often than not you’ll find yourself in the flow, with nothing on your mind but the project.

All in all, never forget what’s really important: completing the project!

如何管理深度强化学习研究团队第二部分:创造性工作的分形本质

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-manage-a-deep-reinforcement-learning-research-team-part-2-fractal-nature-of-creative-work

在第一部分中,我们讨论了专注于定义明确的项目的重要性。在这篇文章中,我们将更深入地探讨,因为我们将谈论创造性工作的分形性质,或者为什么当你的项目是从子项目构建的时候,很难做有意义的工作,子项目是从子子项目构建的,子子项目是从…你知道该怎么做。

我们将从我的研究工作中的一个例子开始,然后我将解释这一现象,并谈论如何处理它。在你读完这篇文章后,在 LinkedIn 上讨论它会很棒,因为我没有找到很多关于这方面的文章,然而我相信这是管理研究项目的一个非常重要和常见的部分。

所有的工作,没有结果

说明问题

我的示例项目是关于为 RL 代理寻找一种新的探索算法。我希望它是贝叶斯(或者至少受到贝叶斯方法的启发),因为贝叶斯卷土重来,并且最近在人工智能社区中获得了牵引力。

这是一个大项目,所以最好把它分成较小的部分。我从联系我的顾问和查阅文献开始。深度探索引起了我的注意。我看了一下,赶上深度合奏自举,编一些实验代码,实验一点。

然后,我有一个想法,它是最大熵 RL 。我开始更深入地研究 SAC 以真正理解它在做什么,并发现自己处于“简化 RL 讨论的中间。这很有趣,我编写了代码,它运行得很好,而且确实很简单。

同时,我开始尝试在 MuJoCo 中创建新的、困难的探索性连续控制环境。我构建了几个混合最大熵 RL 和深度探索的代理,我认为 SOTA 算法在 MuJoCo 中表现非常好,所以没有必要再开发一个在右边运行稍快的算法,比如说在 HalfCheetah 中。我开始试验人形机器人,并发现分层 RL 有很好的蚂蚁环境,代理必须知道如何推动盒子才能到达目标。

好吧,好吧,所以我跳进层次 RL 并开始回顾文献。我找到这篇论文,它表明分层 RL 是可以的(有时),然而,有更简单的算法来解决蚂蚁环境。这些算法源自深度探索和集合/自举网络的思想。

太好了,经过几个月的工作,我们又回到了起点。

所以这是主要问题。开始很多,结束不多。我陷入了创造性工作的分形性质的陷阱!

创造性工作的分形性质

分形(纬度。fractus–broken,partial,fractional)在口语意义上通常指一个自相似的物体(即一个部分与整体相似的物体)或“无限复杂”(在任何大的放大倍数下显示越来越复杂的细节)~维基百科

我的观察是:你想要实现的每一个想法,你想要学习的每一个主题,你想要完成的每一个(子)项目,每一件事情本身就是一个完整的世界。格雷先生在 Cortex 播客中谈到了这一点(第 96 集“关卡,关卡”)。

当你从事创造性工作时,每深入一步都不会缩小你的研究范围。相反,它在你面前展现了一个与原始主题本身一样大的新主题空间。

越来越深入你手头的问题,你可能会发现自己处于无限的研究项目中。如果幸运的话,你会碰到一些可以发表的东西。

然而,经常发生的是为了得到有价值的东西,你必须推动一个,而且只有一个主题比简单地识别它的分支并进一步深入更难

我该如何处理这个问题?

虽然探索阶段是不可能跳过的,但在某些时候你必须停止探索,集中注意力,变得深思熟虑。项目锁可以帮你处理复杂。

项目锁定

项目锁定是指你有意识地锁定一个已经发现的(子)项目一段时间。请看看下面的信息图。

探索

这几乎就是我在上一节中描述的过程。你阅读、交谈、记笔记、实验、玩耍等等。在这个阶段有很多。你或多或少地以一种系统的方式认识地面。然而,重要的是,一旦你有这种直觉,你发现了一些东西,就进入下一阶段。

是时候整理一下探索阶段形成的创意乱局了。在我的系统中,我将我生成的所有项目放在一个优先级队列中。最上面的项目优先级最高,我锁定了它。

记住,每个项目都必须清楚地陈述你想要实现的结果(见我之前的帖子)。没有成就也是一种结果!当你在做研究时,这是一个非常受欢迎的方法。

这是一个非常重要且经常被跳过的阶段。这个阶段将优秀的研究人员与平庸的研究人员区分开来。

努力完成队列中的第一个项目。推动结果。不允许分心!

当你从事这个项目时,你可能会发现更多的项目。根据你的直觉排列它们,但是,总是在当前最上面的项目下面!还是那句话,推最上面的,只推最上面的。

当你最终得到当前项目的结果时(或者因为你获得的新信息,你有意识地决定不值得进一步推进),核对一下,然后去队列中的下一个项目。

重复

你应该重复上面的过程,这意味着在任何时候你都可以决定回到前一个阶段,例如从推至锁定甚至探索。你为什么要这么做?因为你学习!你有新的信息,你应该适应。

你会问,这个三步走的过程有什么意义?这是一个有用的框架,让你的工作系统化。没有它,你就有无限期陷入“探索”阶段的风险。当你转换阶段时,你可以自由选择,然而,永远记住有三个阶段,并且对成功都是至关重要的。

结束

说到成功,不要忘记你的大目标,例如,你的研究应该以发表论文而告终。为 done 设定一个清晰的定义(例如,论文在本次或本次会议上发表),并引导每次迭代朝着这个目标前进。这个框架可能会很有趣,让你感觉在控制中,这是令人愉快的,但你必须在某个时候完成它,而不是令人愉快的写作和评论者的反馈😉

讨论

今天到此为止。现在,我想知道你的想法。你是否被创造性的分形所困扰?分享你的经历和处理方法——你可以在 LinkedIn 上给我发消息。

如何管理、跟踪和可视化机器学习模型的超参数?

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-manage-track-visualize-hyperparameters

机器学习算法可通过称为超参数的多个量规进行调整。最近的深度学习模型可以通过数十个超参数进行调整,这些超参数与数据扩充参数和训练程序参数一起创建了非常复杂的空间。在强化学习领域,您还应该计算环境参数。

数据科学家要控制好 超参数 空间,才能使 进步

在这里,我们将向您展示最近的 实践技巧&诀窍、示例、工具,以最小的开销高效地管理、跟踪和可视化超参数。你会发现自己掌控了最复杂的深度学习实验!

为什么我应该跟踪我的超参数?也就是为什么这很重要?

几乎每一个深度学习实验指南,像这本深度学习书籍,都建议你如何调整超参数,使模型按预期工作。在实验-分析-学习循环中,数据科学家必须控制正在进行的更改,以便循环的“学习”部分正常工作。

哦,忘了说随机种子也是一个超参数(特别是在 RL 领域:例如检查这个 Reddit )。

超参数管理和跟踪的当前实践是什么?

让我们逐一回顾一下管理超参数的常见做法。我们关注于如何构建、保存和传递超参数给你的 ML 脚本。

Python 词典

很基础,很有用。只需在 Python 字典中收集超参数,如下例所示:

PARAMS = {'epoch_nr': 5,
          'batch_size': 64,
          'dense': 256,
          'optimizer': 'sgd',
          'metrics': ['accuracy', 'binary_accuracy'],
          'activation': 'elu'}

由于这种方法,您将所有超参数保存在一个 Python 对象中,并且您可以轻松地在您的训练脚本中使用它。为了确保你在机器学习项目中跟踪那些参数,建议只在版本控制文件中创建这个字典

你可以点击查看整个例子

优点

  1. 简单明了,因为你已经知道这个工具。
  2. 用嵌套的字典很容易制作一个层次结构。
  3. 几乎没有代码开销。
  4. 易于将多个配置文件合并到一个字典中。
  5. 可以保存在 pickle 文件中以备将来使用。

缺点

  1. 超参数是代码库的一部分,虽然它们应该是独立的——记住要区分逻辑和它的参数化。
  2. 将参数保存到磁盘并不明显。
  3. 您可能没有注意到您覆盖了一些值。然后,很难了解一个特定的设置是如何执行的,因为你可能会覆盖一些神奇的数字。
  4. 保存的 pickle 文件在代码之外是不可读的。

它是一个 Python 库,允许你以键和属性的形式访问字典元素。用属性语法真的很方便。

下面是一个嵌套字典的例子:

config = {'neptune': {'project': 'kamil/analysis',
                      'tags': ['xgb-tune']},
          'booster': {'max_depth': 10,
                      'eta': 0.01,
                      'gamma': 0.001,
                      'silent': 1,
                      'subsample': 1,
                      'lambda': 1,
                      'alpha': 0.05,
                      'objective': 'reg:linear',
                      'verbosity': 0,
                      'eval_metric': 'rmse',
                      },
          'num_round': 20,
          }

您可以像这样访问eta:

有了 attrdict,您可以用更优雅的方式来完成:

cfg = AttrDict(config)rncfg.booster.eta

配置文件

它们是常规的文本文件,有一些预定义的结构和标准的库来解析它们,比如 JSON 编码器和解码器,或者 PyYAML 。常见的标准是 JSON、yaml 或 cfg 文件。

下面是一个 yaml 文件的例子,它为随机森林提供了多个超参数,以及更一般的信息,如项目和实验名称。

与基于字典的风格类似,您只需要对这个文件进行版本控制,以跟踪超参数。

project: ORGANIZATION/home-credit
name: home-credit-default-risk

parameters:

  n_cv_splits: 5
  validation_size: 0.2
  stratified_cv: True
  shuffle: 1

  rf__n_estimators: 2000
  rf__criterion: gini
  rf__max_features: 0.2
  rf__max_depth: 40
  rf__min_samples_split: 50
  rf__min_samples_leaf: 20
  rf__max_leaf_nodes: 60
  rf__class_weight: balanced

  aggregation_method: rank_mean

您可以通过简单地像这样使用yaml.load()读取 yaml 文件并访问它的元素:

由于刚刚介绍了attr direct,我们修改一下这个代码片段,用更优雅的方式访问 n_cv_splits :

import yaml

with open(config_path) as f:
    config = yaml.load(f, Loader=yaml.BaseLoader)  

print(config['parameters']['n_cv_splits'])  

这里是一个用于存储特征选择、模型参数等的大型 yaml 文件的示例

import yaml
from attrdict import AttrDict

with open(config_path) as f:
    config = yaml.load(f, Loader=yaml.BaseLoader)  
    cfg = AttrDict(config)

print(cfg.parameters.n_cv_splits)  

优点

一切都位于一个地方。

  1. 易于重复使用保存的配置文件。
  2. 脚本逻辑及其参数化的良好分离。
  3. 增强了代码的可读性。
  4. 缺点

将超参数放入配置文件需要一些编程知识。

  1. 如果代码库变化很快(新特性、新模型,同时删除旧版本的代码),维护正确的配置文件是额外的开销。
  2. 对于大型代码库,您可能会有几个配置文件,这会使事情变得更加复杂和繁琐。
  3. YAML 文件是在 AWS 和其他云平台中部署时编写配置的标准格式。因此,与 YAML 打交道是值得的,因为播下的种子将在部署中收获好处。

抱怨吗

在进行试验时,您通常会经历多次试验(或实验),以便了解超参数和得分之间的关系,并获得性能最佳的模型(我们将模型性能良好意味着什么的讨论留到另一篇文章中)。

在这种情况下,从命令 直接在 CLI 中指定参数 开始新的实验就派上用场了。 Argparse 是一个 Python 模块,它使得编写用户友好的命令行界面变得容易。

我认为理解 argparse 的一个简单方法是简单地 分析一个例子。下面是一个简单的 Python 程序,它接受三个可选的位置参数并打印它们。

如果你运行这个程序,没有任何参数,那么将使用默认值:

import argparse

parser = argparse.ArgumentParser(description='Process hyper-parameters')

parser.add_argument('--lr',       type=float, default=0.001, help='learning rate')
parser.add_argument('--dropout',  type=float, default=0.0,   help='dropout ratio')
parser.add_argument('--data_dir', type=str,   default='/neptune/is/the/best/data/', help='data directory for training')

args = parser.parse_args()

print(args.lr)
print(args.dropout)
print(args.data_dir)

输出是:

python main.py

如果您指定参数,那么它们将被解析,以便您可以在您的训练脚本中使用它们:

0.001
0.0
/neptune/is/the/best/data/

输出是:

python main.py --lr 0.005 --dropout 0.5

关于跟踪的一个重要注意事项:注意 argparse 不保存或记录在命令行中传递的参数。用户必须自己保存参数值

0.005
0.5
/neptune/is/the/best/data/

优点

方便地开始新的实验。

  1. 动态决定超参数的值。
  2. 易于向 argparse 添加新参数。
  3. 缺点

需要额外的努力(虽然不是很大)来跟踪基于实验的长期项目中超参数的值。Argparse 不在任何地方保存值。

  1. 与配置文件类似,如果您的项目增长迅速,您可能会发现很难维护 CLI 参数。
  2. 如果在代码的几个地方传递参数,如何有效地使用 argparse 就变得不那么明显了。如果从多个位置构建/合并参数,情况也类似。
  3. 水螅

Hydra 是脸书 AI 的一个新项目,它简化了更复杂的机器学习实验的配置。

其背后的关键理念是:

动态地创建一个一个层次化的 配置 组成

需要时通过命令行覆盖它,

  • 通过 CLI 传递新参数(配置中没有)——它们将被自动处理
  • Hydra 使您能够准备和覆盖复杂的配置设置(包括配置组和层次结构),同时跟踪任何被覆盖的值。
  • 与 argparse 类似,理解它的最佳方式(以及使用 hydra 有多简单)是分析一个示例

让我们从关于配置文件的部分考虑简化的配置yaml文件:

下面是极简风格的九头蛇例子:

当您运行它时,您应该会看到:

project: ORGANIZATION/home-credit
name: home-credit-default-risk

parameters:

  n_cv_splits: 5
  validation_size: 0.2
  stratified_cv: True
  shuffle: 1

  rf__n_estimators: 2000
  rf__criterion: gini
  rf__max_depth: 40
  rf__class_weight: balanced

在 hydra 中方便的是,您可以从 CLI 覆盖配置中的任何值,如下所示:

import hydra
from omegaconf import DictConfig

@hydra.main(config_path='hydra-config.yaml')
def train(cfg):
    print(cfg.pretty())  
    print(cfg.parameters.rf__n_estimators)  
if __name__ == "__main__":
    train()

因此,在配置中有了新的值:

name: home-credit-default-risk
parameters:
  n_cv_splits: 5
  rf__class_weight: balanced
  rf__criterion: gini
  rf__max_depth: 40
  rf__n_estimators: 2000
  shuffle: 1
  stratified_cv: true
  validation_size: 0.2
project: ORGANIZATION/home-credit

2000

另一个提供良好灵活性的特性是一个选项,可以直接从命令行传递新的、以前看不到的参数。

python hydra-main.py parameters.n_cv_splits=12   parameters.stratified_cv=False name=entirely-new-name

要启用此功能,只需关闭 hydra 中的严格模式。

name: entirely-new-name
parameters:
  n_cv_splits: 12
  rf__class_weight: balanced
  rf__criterion: gini
  rf__max_depth: 40
  rf__n_estimators: 2000
  shuffle: 1
  stratified_cv: false
  validation_size: 0.2
project: ORGANIZATION/home-credit

2000

在下面的命令中,我将rf__max_features添加到配置中,同时将rf__n_estimators更改为 1500。注意 config 和前面的例子是一样的。在代码中,我们只关闭了严格模式:

输出相应改变:

@hydra.main(config_path='config.yaml', strict=False)

hydra 项目正在积极开发中,所以请确保不时查看他们的教程以了解新特性。

python hydra-main.py parameters.rf__n_estimators=1500   parameters.rf__max_features=0.2

优点

name: home-credit-default-risk
parameters:
  n_cv_splits: 5
  rf__class_weight: balanced
  rf__criterion: gini
  rf__max_depth: 40
  rf__max_features: 0.2
  rf__n_estimators: 1500
  shuffle: 1
  stratified_cv: true
  validation_size: 0.2
project: ORGANIZATION/home-credit

1500

可组合配置。

能够非常容易地覆盖值,并且仍然跟踪它们。

  1. 将组织带入更大实验的配置组。
  2. 缺点
  3. 九头蛇在更大的实验中大放异彩,这些实验以多个超参数及其等级来衡量。对于较小的,其他方法将做得恰到好处。

您需要小心避免重要参数值的意外覆盖。

  1. 为了跨实验跟踪超参数,您需要手动保存配置对象(上面示例中的cfg)。
  2. PyTorchLightning 照明模块超参数
  3. 注意 : 这种方法只有在你选择 PyTorchLightning 作为框架的时候才有效

PyTorch Lightning 有一种隐式的方法来跟踪检查站和 YAML 中的超参数(与我们上面讨论的相同)。这增强了可再现性,并使代码中的跟踪过程干净而高效。不需要在代码库中导入模块或加载任何文件。

所有繁重的工作都由 LightningModule 完成,用户只需直接继承方法。让我们来看一个实际例子:

save_hyperparameters()方法将对象中存在的所有超参数保存到 YAML 文件中。前往文档了解更多关于像模型检查点文件一样保存和加载超参数的信息。

优点:

class LitMNIST(LightningModule):
    def __init__(self, layer_1_dim=128, learning_rate=1e-2):
        super().__init__()

        self.save_hyperparameters()

        self.save_hyperparameters("layer_1_dim", "learning_rate")

        self.hparams.layer_1_dim

没有任何模块或文件加载额外的依赖

快速有效的保存和加载功能

  1. 本质上的隐含性保持了代码库的整洁和可解释性
  2. 缺点:
  3. 这些方法仅限于 PyTorch Lightning 模块

不幸的是,它也受到 YAML 文件的困扰。

  1. 它需要代码和编程知识来处理好事情
  2. 如果配置变化很快,维护配置文件是额外的负担。但是,这可以通过使用版本控制来解决。
    • 这种技术灵活性较差。例如,如果您想在不同的配置文件中保存不同的超参数,那么您必须返回来显式地创建它们。
    • Tensorflow 2 张量板 HParams
  3. 注意 : 这种方法只有在使用 Tensorflow 作为框架选择的情况下才有效

对于超参数调优,最佳实践是将这些超参数放在一个地方,作为做出正确决策的结果。TensorBoard 中的 HParams 仪表板提供了多种工具,可帮助确定最佳实验或最有希望的超参数集。

使用 HParams 类记录超参数将让您在 tensorboard 中可视化它们以及大量其他方便的信息。使用 TF summary writer 以 Tensoroard 兼容格式记录和保存超参数后,您可以在不同的实验中再次导入和重复使用这些参数。让我们看一个在拟合模型时如何记录和利用它的例子。

您可以使用 hp 声明您想要的超参数。HParam 方法,并使用 tf.summary.create_file_writer 保存,它会将它们保存为 tensorboard 可以读取的格式。

您可以在模型中直接使用上面在 HParams 中声明的超参数。前往文档了解更多信息。

import tensorflow as tf
from tensorboard.plugins.hparams import api as hp

HP_NUM_UNITS = hp.HParam('num_units', hp.Discrete([16, 32]))
HP_DROPOUT = hp.HParam('dropout', hp.RealInterval(0.1, 0.2))
HP_OPTIMIZER = hp.HParam('optimizer', hp.Discrete(['adam', 'sgd']))

METRIC_ACCURACY = 'accuracy'

with tf.summary.create_file_writer('logs/hparam_tuning').as_default():
  hp.hparams_config(
    hparams=[HP_NUM_UNITS, HP_DROPOUT, HP_OPTIMIZER],
    metrics=[hp.Metric(METRIC_ACCURACY, display_name='Accuracy')],
  )

优点:

def train_test_model(hparams):
  model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(hparams[HP_NUM_UNITS], activation=tf.nn.relu),
    tf.keras.layers.Dropout(hparams[HP_DROPOUT]),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax),
  ])
  model.compile(
      optimizer=hparams[HP_OPTIMIZER],
      loss='sparse_categorical_crossentropy',
      metrics=['accuracy'],
  )

  model.fit(x_train, y_train, epochs=1) 
  _, accuracy = model.evaluate(x_test, y_test)
  return accuracy

没有任何模块或文件加载额外的依赖

快速简单的可视化过程

  1. 本质上的隐含性保持了代码库的整洁和可解释性
  2. 目录结构将保持整洁有序
  3. 缺点:
  4. 这些方法只限于张量板模块

它需要代码和编程知识来处理好事情

  1. 如果配置变化很快,维护配置文件是额外的负担。但是,这可以通过使用版本控制来解决。
  2. 这种技术也提供了较少的灵活性。例如,如果您想在不同的配置文件中保存不同的超参数,那么您必须返回来显式地创建它们。
  3. 管理超参数的另一个步骤是在更广泛的实验管理环境中使用它们。下面是一个关于【Neptune 如何处理 ML 实验的参数化的例子:
  4. 这样,每个实验都有自己的 params 设置保存到 Neptune,以供进一步分析和跨实验比较。这种方法的主要优点是,您可以将参数与其他实验相关的数据/元数据相关联,如评估指标或结果模型。

前往文档了解如何无缝集成 Neptune,而无需对代码做太多修改。

PARAMS = {'batch_size': 64,
          'n_epochs': 100,
          'shuffle': True,
          'activation': 'elu',
          'dense_units': 128,
          'dropout': 0.2,
          'learning_rate': 0.001,
          'early_stopping': 10,
          'optimizer': 'Adam',
          }

neptune.create_experiment(params=PARAMS)

实验跟踪工具——如 Neptune——在多个不同位置显示参数,以便您可以:

突出显示所有不同的参数时,更详细地比较选定的实验(示例)。

Parameters’ values are displayed for each experiment, allowing you to visually inspect and analyze runs

Parameters compare in Neptune

You can also compare multiple runs

搜索具有当前参数特定值的实验(示例,其中我们仅显示具有正“时间序列 _ 因子”的实验)。

  • 如何可视化超参数?
  • 如果你是一个繁重的实验者,你可能会遇到需要有效地比较数百次运行可视化超参数和分数之间的关系。

平行坐标图

一种方法是准备一个平行坐标图,如下图所示:

每个垂直轴是一个参数,分数是最右边的(垂直)轴。这种可视化提供了对产生最佳分数的参数范围的即时洞察。原则上,它应该是交互式的,允许用户自由地探索数据,并执行他们自己的推理和解释。

一个建造平行坐标罐的伟大工具: HiPlot ,由脸书人工智能研究院 (FAIR)开发。仔细看看如何在 Neptune 中使用平行坐标比较运行。

Parallel coordinates plot build with HiPlot.

顺便说一下,如此大量的运行(如上所述)通常来自于超参数优化作业,简称 hpo。Python 的开源环境在这个问题上有很大的贡献。检查这两个流行的 hpo 库的比较: optuna 和 hyperopt

sci kit-优化

scikit-optimize 的创建者提出了另一种检查和理解 hpo 结果的方法。每个 hpo 作业都会生成诊断图表,显示超参数和分数之间的关系。

这里有一个例子:

奥普图纳

Optuna 是一个自动化超参数搜索的超参数优化框架。它为给定的工作提供了自己的超参数可视化套件。

让我们来研究 optuna hpo 作业的一个示例:

与前面的例子类似,可视化的主要目标是帮助理解超参数如何与正在优化的分数相关。

如果这听起来与你有关,仔细看看文档中的 neptune-optuna 集成。

Optuna diagnostics chart

最后的想法

超参数是大图的中心部分,即实验管理。在这篇文章中,我们展示了超参数跟踪实践的最新状态。有了 Neptune,你可以把它提升一个层次,让团队中的变得容易接近、可比和共享。

Final thoughts

Hyperparameters are the central piece of the larger picture, which is experiment management. In this post, we showed the recent state of the practice in hyperparameters tracking. With Neptune, you can bring it one level up, by making them easily accessible, comparable, and shareable in the team instantaneously.

关于如何在生产中监控模型的全面指南

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-monitor-your-models-in-production-guide

https://web.archive.org/web/20221228213243im_/https://neptune.ai/wp-content/uploads/model-monitorig-gif.mp4

Source

记录暂存

定格

是的,这就是我,因为我们的欺诈检测系统错误地将欺诈交易标记为合法交易,导致公司损失了 50 多万美元,我老板的职业生涯可能就此结束。坐在椅子上的那个人呢?那是我们的 DevOps 工程师。你可能想知道我们是如何来到这里的…

我的故事从一张你可能已经看过 1001 次的图片开始——一个 ML 项目的生命周期。

Model monitoring ML Lifecycle

Source: Author

几个月前,经过几个月完善我们的模型,我们终于投入生产。“恭喜你!”我告诉我自己和我的同事,“我们的努力肯定有回报,不是吗?”。兴奋是无法估量的。

我们的模型是实时服务请求并成批返回结果——好东西!这就足够了,对吗?对吗?

不完全是,我们以一种相对戏剧化的方式意识到了这一点。

我不会用那些陈词滥调的理由来烦你,为什么部署工作软件的典型方式在机器学习应用中不奏效。我还在努力从老板留给我的伤痕中恢复过来,最起码我能做的就是帮助你不要像我一样,在“成功的模型部署”后,最终躺在医院的病床上。

我会告诉你所有关于:

  • 为什么部署不是您的最后一步,
  • 为什么你还需要拥有和监控生产中的模型,
  • 在生产中应该监控什么以及如何监控,
  • 不同的监测和观察平台以及如何选择它们,
  • 记录和报警,
  • 在生产中监控模型的挑战和最佳实践,
  • 还有更多!

在本文结束时,您应该确切地知道在部署您的模型之后要做什么,包括如何在生产中监控您的模型,如何发现问题,如何排除故障,以及如何接近您的模型的“生命”,超越监控。

祝贺您…但它不会停留在部署阶段

部署后,看看您的传统软件应用程序:

很好,对吧?你几乎不用担心任何事情。基于软件开发生命周期,它应该像预期的那样工作,因为你已经严格地测试和部署了它。事实上,当您主要升级以满足新的系统需求或新的业务需求时,您的团队可能会决定定期发布稳定的新版本。

在监控您的应用程序方面,您可能会担心系统指标、错误率、流量、应用程序加载时间、基础设施(服务器数量、负载、CPU/GPU 使用情况)等等。您的应用程序可以扩展到很多用户,它可以按照预期的方式工作,并解决它本来要解决的问题。

那是传统软件。但是现在,进入机器学习的世界:

部署您的模型本身可能就是一件麻烦事。但是现在,谁来管理您部署的内容呢?该软件可能有一个 DevOps 团队来监控和维护生产中的系统,但对于机器学习应用程序,你不能只是将部署的模型交给运营团队——在你的情况下,这必须是一个共同的责任。

Modified by the author and adapted from the source.

从上图可以看出,机器学习模型会随着时间退化。他们是动态的,对现实世界中的真实变化非常敏感。

但是模型有点像汽车。一辆新车从经销商处被开出来的那一刻起,其价值就下降了 10%——也就是它们被“部署”到现实世界的那一刻。你的新型号也一样。

从您将模型部署到生产环境的那一刻起,它的性能就开始下降。一个模型在被部署到生产之前处于最佳状态。这就是为什么部署不应该是您的最后一步。

除此之外,还必须有一种方法,让您能够始终如一地向业务利益相关者报告,您部署的机器学习解决方案是否以及如何解决任何问题。

开发期间的验证结果很少能完全证明您的模型在生产中的性能。这是为什么您必须在部署后监控您的模型的一个关键原因——以确保它们保持预期的性能。

还可能存在这样的情况,您部署了本地化到多个地理区域的模型。你如何确保你的模型为每个对自己现实有高度兴趣的客户提供预期的结果(预测)?如何解释为什么一个模型对一个地理区域做出某些预测,而对另一个区域做出不同的预测?

最终,关键的教训是:在部署之后有许多工作要做,你不应该太容易地交付你的模型。部署并不是模型工作的结束,它实际上是开始!

为什么您需要在生产中监控您的机器学习模型

如果你已经做到了这一步,我可能已经成功地让你相信模型在生产中的表现比在开发中的表现差。作为数据科学家或机器学习工程师,这是一个你需要意识到的挑战。您将在生产中找到这一挑战的解决方案,这是您在部署后采取下一步行动的地方—监控!

但是为什么你需要监控你的模型?

为了回答这个问题,让我们来看看您的模型在生产中会遇到的一些挑战:

生产挑战 关键问题

数据分布变化

|

为什么我的特征值会突然变化?

|
| |

生产中的车型所有权

|

谁拥有生产中的模型?DevOps 团队?工程师?数据科学家?

|
| | |

尽管我们在开发过程中进行了严格的测试和验证,为什么该模型在生产中的效果不佳?

|
| | |

为什么我的模型在生产中表现良好,但随着时间的推移,性能突然下降?

|
| | |

我如何根据业务目标并向相关利益相关者解释和说明我的模型预测?

|
| | |

如何保证我的模型安全?我的模型被攻击了吗?

|
| | |

我如何比较我的模型的新版本和生产版本的结果?

|
| | |

为什么我的培训管道在执行时会失败?为什么再培训工作需要这么长时间?

|
| | |

为什么我的预测服务延迟很高?为什么我的不同型号的延迟差别很大?

|
| |

【极端事件(离群值)】

|

我如何跟踪我的模型在极端和意外情况下的效果和表现?

|
| | |

我如何确保生产数据以与培训数据相同的方式进行处理?

|

这将让您大致了解部署到 prod 后可能遇到的挑战,以及为什么您需要在部署后通过监控生产中的模型来继续良好的工作。

本质上,在生产中监控模型的目标是:

  • 为了在您的模型和为您的模型服务的系统开始产生负面的商业价值之前检测它们,
  • 通过对生产中的模型或支持它们的输入和系统进行分类和故障排除来采取行动,
  • 为了确保他们的预测和结果能够得到解释和报告,
  • 为了确保模型的预测过程对相关的利益相关者是透明的,
  • 最后,提供在生产中维护和改进模型的途径。

让我们说得更具体一些。

根据您的模型在生产中可能遇到的挑战监视什么:功能监视与操作监视

您已经部署了您的模型,现在您需要在整个生命周期中观察和检查您的 ML 应用程序在生产中的进度和质量,保持对它的系统审查,以便它继续服务于其预期的价值——这是在生产机器学习系统的背景下进行的监控。

你的机器学习应用不仅仅是模型,而是在生产中支持你的模型的一切,包括基础设施、输入数据、资源和其他上游和/或下游服务。

如果您想知道要监控什么,通常应该考虑两件事:

  1. 什么会走
  2. 什么可能会出问题?

什么是正确的?

想知道什么是正确的,你应该回想一下你的机器学习项目工作流程的规划阶段,在那里你希望围绕用户和业务目标进行规划。

首先,所有可能正确的事情都是为了保证业务目标和用户(人/服务/系统)需求得到满足。

您如何监控和衡量这一点?对于每个业务用例来说,它都是非常独特的,通常取决于:

  • 你的企业如何定义成功?在规划阶段设定了哪些 KPI?
  • 在部署到生产环境之前,性能预期是什么?
  • 如果我的模型向客户返回一个预测,它对结果有什么期望,应该多快交付?

要回答上述问题,您需要一些度量选择标准。对于一个企业来说,成功可能意味着你的模型在整个系统中只扮演了很小的角色。

为了磨练和细化您的指标选择标准,您可以遵循以下一些最佳实践(这要归功于 Lina Weichbrodt ):

  • 选择一个跨模型的可比指标,
  • 简单易懂,
  • 可以被实时收集,
  • 允许对问题发出可操作的警报。

为了思考成功对一个企业意味着什么,你还必须思考什么是好的用户体验。然后考虑你的模型如何在整个系统的背景下为良好的用户体验做出贡献——你的模型通常不是 UX 问题的主要解决方案

例如,如果我们正在构建一个贷款审批系统,一个好的业务目标可以是:

“快速批准将在规定时间还款的客户贷款”

像这样的目标可能会带来良好的用户体验,但很难监控我们的模型对此有多大贡献。影响客户是否还贷的因素有很多(包括他们对业务的看法、利率等等)。我们无法监控。

因此,一个合适的监控指标可以是:

"模型对客户的请求进行评分并返回预测的速度有多快?"

有这样的约束:

  • 我们的模型应该返回 0.6 到 0.7 之间的预测(可能性)分数,作为应该以非常高的利率来减轻风险的贷款,0.71 和 0.90 作为应该以中等利率来的贷款,以及大于 0.91 的分数作为应该以低利率来的贷款。这是因为我们无法获得关于该客户是否会实际付款的实时反馈(作为评估我们模型的基本事实),所以我们将使用模型的分数作为实时指标进行监控。
  • 对客户端请求的成功 HTTP 200 OK 响应。
  • 大约 100 毫秒的延迟被认为是良好的响应时间。
  • 对于微服务架构中的下游服务,SLA(服务级别协议)超过 95%。

这样,我选择了一个指标:

  • 可以在不同的模型之间进行比较,
  • 既不太宽泛也不太具体;简单易懂。
  • 可以实时收集。
  • 允许对生产中可能出现的问题发出可操作的警报。

任何否定上述观点的东西都应该被认为是“糟糕的”用户体验,可以被描述为任何可能出错的东西。在这种情况下,如果模型为贷款请求返回 0.55 的可能性分数,这应该会警告某人(可能是可以查看贷款请求的顾问)或警告不同的系统加载另一个模型进行评分。

现在是有趣的部分——监控可能出错的事情。

什么会出错?

您可以在两个层面上监控您的机器学习模型在生产中可能出现的问题:

  • 功能级监控–监控模型性能、输入(数据)和输出(预测)。
  • 操作级监控–系统和资源级监控。

功能监控

作为一名数据科学家,您主要负责这一级别的监控。您主要是监控与输入相关的模型性能、预测结果以及在生产中学习时模型中发生的情况。

Functional Monitoring

Source: author

数据

输入级功能监控在生产中至关重要,因为您的模型会对收到的输入做出反应。如果输入不是您的模型所期望的,它很可能会影响性能。监控和测量输入级挑战是排除功能性能问题并在造成严重损害之前解决这些问题的第一步。

下面是您可能希望在输入级别监控的三种情况。

1。数据质量问题

数据质量(完整性)问题主要源于数据管道的变化。为了在数据到达模型之前验证生产数据的完整性,我们必须监控基于数据属性的某些指标。这样,如果输入数据不是我们所期望的或者我们认为模型所期望的,就可以触发一个警报,让数据团队或服务所有者查看。

这里监控的主要目标是在数据被发送到您的模型之前标记任何数据质量问题,无论是来自客户端还是由于不健康的数据管道(这将生成不可靠的预测作为响应)。

数据质量问题的一些可追踪原因是:

预处理生产数据

在某些情况下,您的流数据管道将从多个来源接收数据。一个或多个数据源的变化很容易导致管道中数据预处理步骤的中断——GIGO(垃圾输入垃圾输出)。

更改源数据模式

在其他情况下,您可能会遇到这样的情况:对数据源中的数据进行了有效的更改,预处理工作正常,但它不是模型所训练的那种输入配置。

例如,模式更改可能是某个数据源的数据库管理员重命名了一个特性列,并添加了另一个列来捕获新数据。虽然这可能会通过预处理步骤进行调整,但对于模型预测来说肯定会很麻烦,因此它很可能会作为预测给出部分响应。模式更改意味着需要更新模型,然后才能映射新特性列和旧特性列之间的关系。

数据在源头丢失/损坏

在其他一些情况下,数据管道可能无法从一个源接收数据,因为数据不可用,这可能是由于上游数据源发生了变化,或者数据没有被记录。可能会出现上游数据源损坏或丢失要素的情况。必须监控这些问题,因为它们无疑会影响系统的整体性能。

数据质量问题检测技术

编写测试来检测数据质量问题。一些数据质量检查包括:

  • 测试输入数据是否重复,
  • 测试输入数据的缺失值,
  • 捕捉语法错误,
  • 捕捉数据类型和格式错误,
  • 检查模式在功能名称方面的语义错误,
  • 有效的数据剖析针对数据管道中的复杂依赖关系,
  • 一般完整性检查;数据是否满足下游服务或消费者的要求?

检测到数据质量问题后可能的解决方案

  • 在模式更改后提供警报。
  • 确保数据所有者实施正确的数据验证实践。
  • 确保每个人都意识到自己在将数据传送到管道中的角色,并实现数据所有者之间的有效沟通,以便当数据源发生变化时,模型所有者和其他服务所有者也能意识到。

2。数据/特征漂移

监控您的输入可能是功能监控最重要的方面。它可以提前通知您正在解决的业务案例周围不断变化的环境和背景。模型不够聪明,无法适应不断变化的世界,除非它们不断地被重新训练和更新。

数据漂移是指训练数据和生产数据之间的分布发生有意义的变化。随着时间的推移,输入数据分布的变化会影响模型的性能,尽管这一过程比数据质量问题要慢。

虽然可以在整个数据集的级别上监控这种漂移,但通常建议在要素级别上进行监控。

特性/属性漂移

在要素级别进行监控通常是检测输入数据问题的最佳方式。在分析阶段,当您寻求对模型性能和行为的解释时,正确理解这一点非常有帮助。

您可以通过检测每个要素值的统计属性随时间的变化来监控要素漂移。这些属性包括标准偏差、平均值、频率等。

由于数据质量问题或现实世界中的一般变化,如商业客户偏好的变化,可能会发生特征漂移。下面是一个特征/属性漂移的例子,其中一组历史属性被用作基线,新的属性被比较,以便检测属性分布的变化。

Modified by the author and adapted from this source.

通常,对模型性能影响最大的更改是对模型用来“连接各个点”和进行预测的最重要的功能所做的更改。密切监控输入(数据)漂移可以在模型漂移/模型性能出现问题之前提醒您。当数据分布发生变化、要素漂移或输入发生其他问题时,您可以在它们开始降低模型性能之前收到警告。

数据漂移检测技术

为了检测数据漂移,通过使用距离度量测量分布变化来执行分布测试:

  • 可用于测试历史要素和当前要素之间漂移的基本统计指标有:均值/平均值、标准偏差、最小值和最大值比较以及相关性。
  • 对于连续的特征,可以使用散度和距离检验,如kull back–lei bler 散度Kolmogorov-Smirnov 统计量(广泛使用)、种群稳定性指数(PSI)、、海灵格距离等等。
  • 对于分类特征,卡方检验,特征的基数或频率。
  • 一些平台(如 Fiddler )现在正在使用机器学习和其他无监督方法为离群点检测提供开箱即用的监控解决方案。
  • 如果特征是巨大的,就像很多数据集的情况一样,你可能想要使用维度缩减技术(例如 PCA )来修剪它们,然后执行必要的统计测试。

如果你想了解更多关于这些统计方法的信息,这份由 Arize AI 撰写的白皮书提供了关于这些统计检查的概念性的详细信息。

幸运的是,大多数 ML 监控平台(在下一节中会有更多)都提供了一些现成的指标,因此您不必自己编写脚本。

数据漂移检测后可能的解决方案

  • 最合理的解决方案是触发警报并向服务所有者发送通知。您可能希望使用一个编排工具来启动一个包含生产数据的再培训作业,如果分布变化非常大,您可能希望使用新数据构建另一个模型。
  • 通常,您的新数据不够大,不足以重新训练您的模型或进行重塑。因此,您可以将您的新数据与历史(训练)数据相结合并进行准备,然后在重新训练过程中,为彼此差异较大的特征分配较高的权重。
  • 在其他情况下,您可能很幸运,有足够的新生产数据来完成任务。在这种情况下,您可以继续构建一个挑战者模型,部署它(离线或在线),并使用影子测试A/B 测试方法进行测试,以确定它是否比生产中的冠军(当前)模型更好或一样好。

3。离群值

监控输入数据中的异常值至关重要,但也非常棘手。您正在监控极端和异常事件,这些事件可能是一次性事件或一组一次性事件。这不可避免地会影响模型性能,因为异常值在整个数据集中没有足够的可学习结构,这将导致模型返回不可靠的响应,因为它不会完全“连接”生产数据中的点。

离群点检测

您可能无法设置特定的监视器来检测异常值,但是您可以做的是:

  • 使用我们在上一节中讨论的测试来确定特性的值和分布是否与正常的基准期有很大不同——非常明显的漂移。
  • 对单个事件或少量最近发生的事件执行统计距离测试,以检测非分布问题。
  • 分析您的模型最敏感的功能(您的模型在训练后了解到的最重要的功能)是否发生了巨大变化。
  • 使用任何合适的分布测试来确定这些要素(异常值)与训练集中的要素有多远。
  • 使用无监督学习方法对模型输入和预测进行分类,允许您发现异常示例和预测的群组。一些平台使用 AutoML 来检测您的测试无法捕捉到的异常值。

离群点检测后可能的解决方案

  • 对子数据集执行数据切片方法,以检查特定预测子类的模型性能。当您的模型使用您的监控工具做出预测并将预测记录到一个评估存储库时,您可以自动化这个过程。
  • 如果根据您的度量标准,您的模型一直表现不佳,您可能需要考虑评估模型的当前状态,然后训练一个新的挑战者模型。
  • 记录问题,并跟踪这是季节性异常还是极端的一次性异常,以便您可以制定策略来解决未来的此类问题。
  • 如果模型的性能在重新训练后不能提高,或者新模型不能完全达到它,您可能想要考虑模型的性能基准,并且可能有一个人在循环中,在那个时期协助决策过程。

模型

模型是最重要的监控部分,它是整个生产系统的核心。使用您的模型,您可以监控它在生产、组件、版本和安全威胁方面的性能。

1。监控模型漂移

当特征和/或标签之间的关系——在监督或无监督学习解决方案的情况下——不再成立时,会发生模型漂移,或概念漂移,因为学习的关系/模式已经随着时间的推移而改变。与基准或业务指标/KPI 相比,随着时间的推移,模型始终返回不可靠和不准确的结果。

一个例子是部署情感分类模型。随着时间的推移,人们对任何话题的情绪都会发生变化。如果你用单词和某些话题训练你的模型关于积极或消极的情绪,一些被标记为积极的情绪可能会随着时间的推移演变为消极的情绪,在我们极度固执己见的社交媒体世界中,你不能排除这种情况。

Concept Drfit

Modified and adapted from source

模型漂移的发生是因为现实世界的变化(因此模型被训练来预测的基本事实/目标)——业务问题的答案总是不断变化的。今天适用的东西明天可能不再适用,我们希望在我们的机器学习应用程序中反映这一事实。

模型漂移可以是渐进的,就像商业环境自然变化和发展一样,也可以是突然的,就像极端事件突然中断所有运营一样。

模型漂移可以以不同的方式发生

  • 瞬时模型漂移:当模型性能随时间突然下降时发生。这可能是导致数据质量问题的数据管道中的错误,或者是在新领域中部署的模型,或者是异常事件(如全球危机)。
  • 渐进模式漂移: 最常见的模式漂移是动态、不断变化和演进的商业环境的自然结果。随着时间的推移,用户偏好的改变,采用你的产品的客户的新的人口统计数据,或者新引入的特性扭曲了数据中的潜在模式,都可能导致这种情况的发生。
  • 周期性模型漂移:这是一年中周期性和重复性季节性事件的结果——模式总是已知的,并且可以预测。这些可能是假期和年度折扣。在大多数情况下,用户偏好是季节性的,或者一个型号服务于不同的地区。
  • 临时模型漂移:这很难通过基于规则的方法来检测,并且通常使用无监督的方法来检测。它的发生是由于奇怪的、一次性的事件,如恶意攻击、用户以非预期的方式使用产品、模型临时服务于新客户或系统性能问题。

模型漂移检测

  • 您可以使用与数据漂移相同的统计测试来检测模型/概念漂移。
  • 随着时间的推移,对模型预测性能的监控(使用评估指标)会减少。通过设置预测指标阈值,您可以确认您的模型是否始终返回不可靠的结果,然后从那里分析预测漂移(预测结果随时间的变化)。
  • 监控数据漂移可以提醒您是否应该分析模型的退化或漂移。
  • 当您可以将基础事实/实际标签与模型预测进行比较以分析趋势和数据的新解释时,监控标签漂移(对于监督学习解决方案,实际标签分布的变化)。

检测到模型/概念漂移后的可能解决方案

  • 根据您的业务现实,保持对已部署模型的监控和再培训。如果您的业务目标和环境经常变化,您可能需要考虑让您的系统自动化,以便与更稳定的业务相比,以预定义的时间间隔安排和执行再培训(点击了解更多关于再培训的信息)。
  • 如果重新训练您的模型不能提高性能,您可能要考虑重新建模或从头重新开发模型。
  • 如果你正在从事较大规模的项目,预算充足,成本和性能之间几乎没有权衡(就你的模型赶上动态商业环境的程度而言),你可能想为你的项目考虑在线学习算法

2。模型配置和工件

模型配置文件和工件包含用于构建该模型的所有组件,包括:

  • 训练数据集位置和版本,
  • 测试数据集位置和版本,
  • 使用的超参数,
  • 默认特征值,
  • 依赖项及其版本;您希望监控依赖关系版本中的变更,以便在依赖关系变更导致模型失败时,能够轻松地找到它们以进行根本原因分析,
  • 环境变量,
  • 模型类型(分类与回归),
  • 模型作者,
  • 目标变量名,
  • 从数据中选择特征,
  • 测试场景的代码和数据,
  • 模型及其预处理的代码。

跟踪配置的相关性,尤其是在针对任何异常情况进行再训练期间模型使用的超参数值。

3。车型版本

如果您希望确保部署正确的版本,那么监控生产中的模型版本是至关重要的。

通过将重新训练管道配置为在训练后自动报告模型版本并将元数据记录到元数据存储中,可以监视模型版本。版本历史应该与模型预测一起记录到评估存储中,这样问题将更容易与模型版本联系起来。

阅读如何将您的模型开发置于控制之下——版本、存储、组织和查询模型。

4。一致的对手

每个企业都面临安全威胁。随着机器学习应用越来越成为大多数公司的中央决策系统,您必须关注您的模型在生产中的安全性。大多数机器学习模型容易受到对抗性攻击

这在信贷风险和金融机构的机器学习应用中尤为常见,例如,欺诈者可能试图欺骗负责检测可疑信用卡交易的模型。

其他容易受到恶意攻击的应用程序包括:

  • 采用人工智能检测假新闻和其他不当内容的媒体公司,
  • 处理音频或图像识别的一般应用程序。

协调一致的对手直接来自系统或黑客,他们通过敌对攻击有意利用您的系统。他们用对立的例子误导系统,因此它可以提供不可靠的结果并导致它出错。这种攻击(通常是异常的)代表了您的机器学习应用程序在生产中的特定安全问题,需要进行监控。

您可以通过 来监控您系统的对抗性攻击

  • 使用与标记异常事件相同的步骤,因为对抗性威胁不遵循模式,它们是非典型事件。

检测到一致的对手后可能的解决方案

正在研究能够保护模型免受敌对威胁的方法和算法,但大多数研究仍处于早期阶段。阻止协同对手的解决方案仍然需要在使用预测之前将检测到的异常事件路由给人类管理者。主题专家可以研究这些案例,并使用它们来保护模型免受进一步的威胁。

在关键业务应用中,速度至关重要。专家检测敌对威胁、研究这种威胁、通过重新训练模型来修补漏洞以及重新部署模型的速度可能会对业务产生很大影响。

可信人工智能的对抗性鲁棒性工具箱(ART) 值得一试。

预测(输出)

监控生产中的模型输出不仅仅是模型性能的最佳指标,它还告诉我们是否满足业务 KPI。就模型预测而言,最需要监控的是符合业务指标的模型性能。

模型评估指标

使用度量来评估模型性能是在生产中监控模型的一个重要部分。这里可以使用不同的度量,比如分类、回归、聚类、强化学习等等。

当您有基础事实/标签来比较您的模型时,我们通常使用预定义的模型评分指标(准确性、AUC、精确度等)来评估模型。

地面实况/实际标签

您的基本事实/实际标签是您的模型试图在现实世界中解决的问题的正确解决方案。

一个基本的例子是:

“这个用户会点击这个广告吗?”

如果用户点击广告,那么实际(标签)是肯定的。您的模型预测(如果他们点击了广告或没有点击)和正确的解决方案之间的比较汇总可以让您了解您的模型在生产中的表现。在这种情况下有实时反馈,因为你的系统几乎可以立即判断用户是否点击了广告。比较可能是这样的:

然而,在大多数情况下,将生产中的实际情况与预测进行比较是一项非常困难的任务。尤其是如果你没有专门的专家注释器来为你记录实际的标签,如果它们不可能实时得到的话。例如,贷款审批系统不会实时给你“正确的解决方案”,因为贷款偿还选项可能需要几个月,甚至几年。这个过程涉及到一个复杂的反馈回路,使我们能够根据现实世界的预期来衡量模型的性能。

有时,您可能会遇到这样的情况,您的基础事实受到模型预测的影响。

例如,如果您构建一个贷款批准模型来预测哪个客户可能会偿还贷款,那么您的模型可能会通过适当地批准将会正确偿还的客户的贷款而表现良好(也就是说,符合基本事实)。但是我们怎么确定它不认可的客户不会还钱给你呢?地面事实可能不是这种模型性能的最合适的事实来源。

地面真值可用时的评分模型

衡量模型在生产中的功能性能的最有效方法是监控模型的预测,并将其与现实世界中的真实情况进行比较。

为了实现这一点,模型预测与收集的基本事实一起被记录,以给出关于生产环境中性能的具体想法。下面是一个例子,说明如何建立一个监控系统,从各种来源或单一来源收集地面真相数据:

Modified by the author and adapted from source

在 1 中,一部分生产数据(输入数据)被传送到地面实况服务,该服务通常涉及由您的系统生成的实时地面实况(例如,当模型预测用户点击广告时,记录用户是否点击了广告)、人工标签注释器或其他数据标签供应商,用于更复杂的任务(例如,确认客户是否在规定的时间偿还了贷款,或者在联系客户后确认交易是欺诈性的还是合法的)。

跟踪预测和模型详细信息的事件 id 用该基本事实事件进行标记,并记录到数据存储中。然后,数据被接收到监控平台中,监控平台根据模型的预测和实际标签计算模型性能指标。

正如您可能已经知道的,分类模型的指标包括:

  • 准确(性)
  • 混乱矩阵,
  • ROC-AUC 评分,
  • 精确度和召回分数,
  • f1-得分。

回归模型的指标包括:

  • 均方根误差(RMSE),
  • R 平方和调整的 R 平方度量,
  • 平均绝对误差(MAE),
  • 平均绝对百分比误差(MAPE)。

只有当您有了基本事实时,才可能计算上面的模型度量。

地面实况不可用时的评分模型——预测漂移

当基本事实不可用或受到损害时怎么办?我们使用预测结果分布作为一个性能代理,因为它已经被设置为符合业务 KPI。

希望您的监控平台以这样一种方式设置,即模型预测也被记录到模型评估存储中。模型评估存储保存模型对每个环境中每个模型版本的每条输入数据的响应(模型决策的签名)。这样,您将能够随着时间的推移监控模型预测,并使用统计指标来比较分布,例如海灵格距离(HDDDM)库尔巴克-莱布勒散度人口稳定指数(PSI)

您可能还需要考虑在生产中监控模型的其他情况。查看阿帕娜·迪纳卡兰撰写的关于监控生产中车型性能的实用剧本。

操作级监控

运营和系统级别的监控主要由 IT 运营人员或 DevOps 团队负责。但是,这也是您和运营团队的共同责任。当事情发展到这种程度时,警报通常会转发给运营团队以采取行动,但您也可以选择获得一份副本。

在这个层次上,您主要是监控您的模型在生产中运行的资源,并确保它们是健康的。资源,如管道健康状况、系统性能指标(I/O、磁盘利用率、内存和 CPU 使用率、流量、运营人员通常关心的事情)和成本。

Operational Monitoring

Cc means “carbon copy” in the context of who gets an alert. Source: author*

生产中 ML 模型的系统性能监控

在生产中实施机器学习解决方案从根本上来说是一个基础设施问题。监控模型性能和数据而不监控您的 ML 基础设施的性能就像建造沙堡一样——您的基础设施是成功部署和维护机器学习解决方案的基础。

监控您的系统/应用程序性能可以帮助您回答以下问题:

  • 该应用程序满足正常运行时间要求吗?
  • 它满足请求的速度够快吗?
  • 是否高效利用资源,节约成本?
  • 代码依赖的变化怎么样,it 能处理吗?
  • 它满足可伸缩性要求吗?
  • 它的服务局限性是什么?

系统性能指标

我们在这里监控的内容受到我们预期我们的模型和数据在利用过程中会面临的挑战的影响。虽然这不是您的主要监控问题,但是您确实需要了解某些指标,这些指标可以指示您的模型在整个应用程序堆栈中的执行情况。如果您的模型在返回预测时有很高的延迟,那肯定会影响系统的整体速度。

要监控的系统/应用程序性能指标将为您提供模型性能的概念,包括:

  • CPU/GPU 利用率当模型计算每个 API 调用传入数据的预测时;告诉您您的模型对每个请求消耗了多少。
  • 内存利用率用于模型缓存数据或输入数据缓存在内存中以获得更快的 I/O 性能。
  • 事件/操作导致的个失败请求的数量。
  • API 调用总数
  • 模型服务器或预测服务的响应时间

下面是一个示例 Neptune 仪表板,它跟踪应用程序的一些值得注意的性能指标:

Neptune model monitoring CPU

Neptune dashboard showing application performance metrics | Source

系统可靠性

在这里,我们正在监控基础设施和网络正常运行时间。有多少个集群在运行,哪些机器在运行,以及与基础设施相关的一切。您正在监视在任何给定时间启动并运行的集群数量,以及哪个预测服务(如果您有多个预测服务)收到的请求最多。

作为 ML 工程师和数据科学家,这不是我们主要关心的问题,但是难道你不想知道为你的模型提供动力的整个系统的可靠性吗?知道这些也无妨。

管道

监控数据和模型管道的健康状况。不健康的数据管道会影响数据质量,模型管道泄漏或意外变化很容易产生负值。

数据管道

监控数据管道的健康状况是极其重要的,因为数据质量问题可能是由坏的或不健康的数据管道引起的。这对于您的 IT 运营/开发运维团队来说尤其难以监控,可能需要授权您的数据工程/数据运营团队监控和解决问题。

这也必须是一项共同的责任。与您的 DataOps 团队合作,交流您的模型期望什么,该团队将告诉您他们的数据管道的输出是什么——这可以帮助您收紧您的系统并推动积极的结果。

如果您负责监控您的数据管道,以下是您可能想要跟踪的一些指标和因素:

  • 输入数据–管道中的数据和文件是否具有适当的结构、模式和完整性?是否有适当的数据验证测试和检查,以便团队可以在摄取的数据中出现异常时得到警告?监控进入数据管道的内容,以保持其健康。
  • 中间工作流程步骤——DAG中的每个任务和流程的输入和输出,在文件数量和文件类型方面是否如预期的那样?一个任务在管道中运行需要多长时间?这可能是数据预处理任务,或者验证任务,或者甚至是数据分布监控任务。
  • 输出数据–在特征和特征嵌入方面,输出数据模式是否符合机器学习模型的预期?输出文件的典型文件大小是多少?
  • 数据质量指标–根据流入的数据跟踪统计指标。这可能是数据的基本统计属性,如平均值、标准差、相关性等,或者是距离度量(如 KL 散度、Kolmogorov-Smirnov 统计)。所使用的统计指标将主要取决于预期数据的维度;几个特征或几个特征。
  • 作业的计划运行时间、实际运行时间、运行时间以及作业的状态(作业成功还是失败?).

模型管道

您想要跟踪在重新培训和重新部署之后,可能导致您的模型在生产中中断的关键因素。这包括:

  • 依赖关系–您不希望出现这样的情况:您的模型是用 Tensorflow 2.0 构建的,而您团队中的其他人最近对 Tensorflow 2.4 捆绑的依赖关系进行了更新,导致您的部分再培训脚本失败。验证运行模型的每个依赖项的版本,并将其记录为管道元数据,这样导致失败的依赖项更新可以更容易调试。
  • 触发再培训作业的实际时间、运行再培训作业花费的时间、作业的资源使用情况以及作业的状态(成功再培训和重新部署模型,还是失败?).

成本

你需要留意你和你的组织托管整个机器学习应用的成本,包括数据存储和计算成本、再培训或其他类型的协调工作。这些成本会很快增加,尤其是在没有被跟踪的情况下。另外,你的模型需要计算能力来对每个请求进行预测,所以你还需要跟踪推理成本。

您的应用程序可能托管在云供应商处,如 AWS 或 Google Cloud。这些供应商跟踪您的账单和每项服务的成本,并使您能够设置预算,并在预算已达到上限时发送警报。对于内部部署的系统,监控系统使用和成本可以帮助您分析应用程序的哪个部分成本最高,并查看可以做出(或不做出)哪些妥协。

您可能要考虑监控的另一个指标是应用程序中的服务级别协议(SLA)。预测服务可能与数据管道或查询它的服务有一组 SLA。确保设置阈值,以便在不满足 SLA 时触发警报。

我们已经讨论了许多您可能需要考虑监控的内容,这实在是太多了,不是吗?在下一部分中,您将了解在您当前的 MLOps 成熟度水平下需要监控什么,这将为您提供一个可行的思路,让您知道从哪里开始。

侧栏:生产机器学习系统中的监控与可观察性

如果你有 DevOps 背景,你可能知道监视一个系统和观察同一个系统是两种不同的方法

可观察性是您查看您一直在监控的指标并对其执行根本原因分析的能力,以了解它们为什么是某种方式,以及它们对您的系统的整体性能构成了什么威胁——所有这些都是为了提高系统质量。

监控几乎是在可观察性之前发生的所有事情:

  • 收集绩效指标,
  • 追踪他们,
  • 检测潜在的问题,
  • 提醒正确的用户。

简单来说,你可以监控而不观察,但是不监控就不能观察你的系统的整体性能。监控是收集点,观察是连接它们!

如果你想了解更多关于机器学习生产系统的可观察性和监控,请查看 Christopher 的文章

如何开始在生产中监控您的机器学习模型

您的下一个任务是在部署模型之后开始监控它们。下面是您应该采取的一步一步方法的直观说明,现在您已经知道为什么需要监控以及需要监控什么。

Step-by-Step Monitoring Approach

Source: author

1.需求分析:根据您的 MLOps 成熟度级别监控什么

不同的用户需要跟踪相对大量的东西,这使得在生产中监控模型成为一个复杂的过程。我们需要工具和平台来简化事情。什么是合适的工具和平台,当我看到一个时,我如何知道?

事情是这样的——ML 监控是一个不断发展的领域。我可以向您保证,没有放之四海而皆准的好工具,只有最适合您特定需求的工具。

列出需求并弄清楚你的前期需求可能会非常棘手,所以我认为在你的 MLOps“成熟阶段”与你见面可能会更简单,正如这篇谷歌云博客文章中所强调的。我还在“将它们整合在一起”一节中用一个插图总结了这一点。

您目前处于 MLOps 成熟度阶段的 0 级

处于这个级别意味着您正在手动训练和部署模型。在这个阶段,您可能甚至还没有想到要监控您的模型,可能只是想办法在测试集上验证您的模型,并将其交给您的 it 运营人员或软件开发人员进行部署。

我知道因为我在那里。正如本文开头所提到的,当我把它交给别人的时候,我庆祝了一番,但是正如你所知道的——几个月后——它确实以眼泪和病床结束了。

为了避免这种情况,我建议你优先考虑最低挂的水果。尽管信息量较少,并且不能帮助您监控模型性能,但它仍然可以作为一个合理的性能代理,告诉您您的一般应用程序是否按预期工作。

当您的工作流仍然处于手动部署阶段时,您不希望花费长时间关注于监控您的模型的指标,或者试图根据业务 KPI 来证明它的性能;当您的 MLOps 系统变得成熟时,这样的指标将变得更容易测量和分析,并且您可以收集基础事实标签或在缺乏基础事实的情况下集成其他性能代理。

您目前处于 MLOps 成熟阶段的第 1 级

处于这一级别意味着您已经自动化了机器学习管道,从而能够基于由标准或定义的阈值设置的触发器来持续训练您的机器学习模型。

在这个阶段,我认为你应该更加关注于监控:

  • 用于衡量模型性能的业务指标(参见“什么会变好”一节)——如果它不是很难衡量的话,特别是如果您不能花费它们来获得用于监控模型指标的基本事实的话。
  • 生产数据的属性和模型在生产中的性能,以检测模型的陈旧性和退化;可以通过触发器帮助进行持续培训,这些触发器可以自动执行 ML 生产管道,用新的生产数据重新培训模型。
  • 您的模型的重新训练过程需要记录管道元数据、模型配置和模型元数据,因为您最有可能手动部署一个重新训练的模型,并且您想要确保您可以在将其重新部署到生产环境之前监控该模型的属性。
  • 您还需要监控生产管道的健康状况,因为再培训步骤是自动化的,并且您的数据管道验证和预处理来自一个或多个来源的数据。
  • 你还应该开始监控你的持续培训过程产生了多少费用,这样你就不会在某一天醒来时收到你或你的公司没有计划到的巨额 AWS 账单。

您目前处于 MLOps 成熟阶段的第 2 级

处于这一级别表明您的 MLOps 实施已经完全成熟,几乎整个管道都是一个健壮的自动化 CI/CD 系统。您的培训、验证和部署阶段都是在一个互补的反馈循环中自动完成的。

在这个阶段,你应该监控所有的事情,但是你的团队应该关注更多信息的度量,确保所有相关的涉众在花费更多时间在最少信息的度量上之前,能够获得更多信息的度量。

将他们聚集在一起…

以下是我认为您应该根据您的 MLOps 工作流的成熟度重点监控的可视化说明。

Essential_Signals_to_Monitor

Original concept here. Source: author

虽然这不是一个硬性的规则,可能需要你的团队集思广益才能弄清楚,但我认为你应该问一些问题:

  • 我们希望从 MLOps 监控平台或工具中获得什么?
  • 此时对我们来说最重要的指标是什么?
  • 你想得到什么样的见解?这些见解是否与提高我们整个应用程序的性能直接一致,以确保持续的积极业务价值?
  • 为了得到 80%的结果,我们现在付出 20%的努力能得到什么?在这种情况下,80%是正的商业价值。
  • 我们现有的工具生态系统是什么?我们有专门的 ITOps/DevOps 工程师团队吗?
  • MLOps 监控解决方案与现有软件部署生态系统集成的难易程度如何?

通常,这些很难一次想清楚,但是必须要做,并且不断地重新评估。我想你会从这个问题开始:“我们现在付出 20%的努力能得到 80%的结果吗?”。

一旦你可以和你的团队一起有效地记录上述问题的答案,跟踪必要的指标就足够困难了——你应该从一个简单的解决方案开始。或者至少是一个解决方案,帮助您使用更少的工具来监控最重要的指标。然后,当您了解工具和您的需求时,您可以迭代,如果您需要,添加更丰富的工具,并知道如何使用它们。

调查现有的工具生态系统

根据您的 MLOps 成熟度,您知道要监控什么。如果可能的话,您可能希望在您的组织中调查您的运营/工程团队用来监控部署的应用程序的现有工具。

例如,您可能在一个组织中,您的运营团队已经使用 Prometheus 和 Grafana 来监控系统性能和其他指标。这对您来说可能是个好消息,因为您可能不必太担心寻找平台,您只需设置和定义您的指标,和/或为您的模型和数据编写测试用例。

不管怎样,这种情况很少发生。通常,您可能需要着手寻找一个平台,该平台可以根据您的需求分析来帮助您监控所需的指标。

请务必调查您的公司,了解工程和运营文化(如果您有运营团队,请与他们交谈!)、工具和可能的生态系统集成,然后再开始寻找适合您需求的平台。

选择监控/观察平台

选择一个可观察性平台是非常棘手的,你必须做好它。有很多成本、数据安全问题和其他挑战。

幸运的是,这可以通过以下方式简化:

  • 理解您的监控需求,您可能已经在本文的这一点上做到了。
  • 知道你能得到什么;实地调查你的组织和预算。有些平台可能非常昂贵,但有一些你不需要的功能,也有一些开源的解决方案。
  • 考虑到 ML 应该具备的必备素质和可观测平台。

选择监控/可观察性平台之前需要考虑的事项

目前,长期以来用于监控和观察生产中软件的原则正被用于监控生产中的数据和机器学习模型。

有些平台最适合在生产中监测和观察数据质量(如蒙特卡洛阿诺马洛),而其他平台(如 superwise.ai阿里泽 AI )则是通用(生产)机器学习可观测性平台。

Arize-drift-monitor

Arize AI monitoring platform | Source

如果您想要一个用于您的实验和培训流程的模型监控解决方案,以及一个用于您的 MLOps 工作流的一体化元数据数据存储,您应该查看 Neptune.ai。它可以免费使用并且您可以在这里的实时沙盒中试用。

Get started with Neptune

Customized dashboard in Neptune

您的 ML 监控/观察平台应该:

  • 简单直观地使用,可由个人服务所有者(您!)而不是中央运营团队;把一个模型投入生产已经够难了,不要给自己添堵。
  • 拥有现成的指标,为您注册的模型提供智能默认指标。
  • 开箱即用且灵活的集成:确保平台能够通过 DB(数据库)连接器、API、文件传输将您的生产数据与其系统集成,并且通常能够集成来自任何数据源的数据(无论是批处理还是流数据)。
  • 拥有现成的可视化和仪表板:提供智能预填充的仪表板和图形,可视化您的指标。您还应该能够添加新面板,使用必要的信息创建可视化效果,并根据您的需要创建自定义查询。
  • 灵活访问:一些平台为您提供编程访问和通过管理控制台或用户界面的访问。
  • 可定制:您应该能够定义您的度量标准,编写您的测试案例和检查,创建定制的仪表板和可视化,定制的检查和插件,设置定制的阈值,并且通常设置定制的集成和工作流。
  • 协作:这不是你可能见过的那种单人工作。您应该能够与相关的利益相关者和服务所有者广泛共享数据、仪表板和报告。该平台应该能够根据我们的模型预测,为每个相关的利益相关者提供关于他们如何才能最好地继续提供积极商业价值的见解和警报。
  • 具有模型可解释性特征:一些工具可以通过使用像数据切片这样的方法对特定的部分进行测试来帮助你解释模型决策。
  • 能够测试模型预测,以检测偏见和威胁(例如,对抗性攻击)。
  • 与环境和语言无关:无论您在构建模型时使用了什么技术,或者它在生产环境中运行于什么环境,您都希望平台能够正常工作。
  • 可扩展到其他平台,并轻松与现有组织生态系统集成。
  • 能够自动检测异常值:平台开始使用自动和无监督的方法来检测输入数据中的异常。
  • 拥有云和/或本地部署解决方案:大多数平台提供基于 SaaS 的服务或本地解决方案。更妙的是,有些两者都有!
  • 成为生产级:生产是一个非常辛苦的地方,尤其是模特。您不希望出现这样的情况:您选择的平台跟不上每秒进行数千甚至数百万次预测的监控模型——本质上,要考虑平台的可扩展性。
  • 粒度观点:平台/工具应该能够为您提供数据和模型性能的粒度视图。比如说;使用此工具,您能否深入生产数据中的每个要素,以检测要素级别的问题和偏差?您能监控每秒、每小时、每天、每月甚至每年的指标(或指标的集合)吗?这将确保灵活性,不管您正在监控的用例是实时的还是批处理的。
  • 执行日志审计:审计来自模型、数据、管道和其他系统日志的日志,用于适当的审计和沿袭可追溯性。

如您所见,选择一种工具需要全面的分析。下面是我见过的一些工具,可以勾选上面的所有或大部分选项。如果您想了解更多关于您可以选择的一些工具和部署平台的信息,Ori Cohen 博士已经在这篇文章中解释了其中的大部分,我建议您看一看它们:

在生产中监控机器学习系统时,您可能会遇到的其他挑战

投入层面的监测挑战

在生产中监控输入数据时,您可能会遇到一些挑战,包括:

  1. 您生产中的数据源可能是分散且不可靠的,因此,根据您的数据架构,将它们统一到一个真实的数据源或数据网格中可能会非常困难。
  2. 您没有明确的数据需求,不知道数据结构和模式应该是什么,也不知道上游数据源可接受的服务水平协议(SLA)是什么。
  3. 您的数据源没有定义所有权,这可能会导致团队之间跨职能的沟通不畅,特别是如果有人对数据源进行了更新(比如对数据库的模式更改)而没有通知其他人。
  4. 您的生产数据工作流程的元数据无法被发现,因此,跟踪数据传承变得非常困难。也记录事件;您不知道相关数据的生产者和消费者,这使得跟踪、故障排除和维护变得困难。

有些挑战不仅仅是建筑上的,也可能是文化上的。如果数据是产品,那么:

  • 人们拥有“产品”(在这种情况下,我们的数据!)并被分配特定的角色,
  • 团队成员相互交流他们数据源的状态,
  • 他们通过元数据记录来记录它们,
  • 每个人都能看到数据被有效地访问和利用,这对解决文化问题大有帮助。

如果你很好奇,你可以在这里了解更多关于“数据作为产品”的想法

监控模型质量时的一些挑战

在生产中监控输入数据时,您可能会遇到一些挑战,包括:

  • 地面实况可用性;您很可能会遇到这样的情况,即您没有实时的基础事实收集,并且可能不得不依赖上游系统甚至人工注释器来收集实际的标签。
  • 源于算法偏差或数据集偏差或两者兼有的模型偏差。
  • 黑盒模型预测无法解释,可能导致合规问题。
  • 不跟踪生产中的模型元数据以实现沿袭可追溯性。当你使用 Neptune.ai 这样的元数据存储时,这并不是一个问题——在这里了解更多。

您可以使用的解决方案是执行数据切片来分析模型预测的各个部分并测试偏差。一些工具可以自动为您完成这项工作。数据集特有的一些偏差也可以通过生产数据验证测试案例预防和/或消除。模型特有的偏差可以通过模型元数据和/或度量来检测。

PRO-TIP :你可能也想看看谷歌新的基于网络的数据探索工具 Know Your Data ,据他们称,该工具有助于研究人员、工程师、产品团队和决策者理解数据集,以提高数据质量,并帮助缓解公平性和偏见问题。

在生产中监控机器学习模型的最佳实践

在这一点上应该很清楚,除了将您的模型部署到生产中,还有很多工作要做。

这将帮助您了解您的模型是否按预期执行并解决了问题,或者它是否需要重新培训,是否部署了挑战者模型,或者您是否需要重新定义良好的业务绩效。下面是我推荐你开始的一些最佳实践。

一般监控最佳实践

  • 以人为本。如果您在组织中建立了一种将数据视为产品的文化,人们很可能会倾向于获得产品的所有权,以确保它端到端地服务于其预期目的。你可以从 DevOps 文化变迁中学到很多。
  • 如果可能的话,不要把应用的“监控权”交给一个人。如果你有一个由数据专业人员和运营工程师组成的跨职能团队,让每个人都处理好自己的服务,并进行有效的沟通。这将有助于分散知识和技能,当用例扩展时,没有人会不知所措。
  • 采取精益方法;使用太多的工具会很麻烦。集中你的工具,但是分散团队;每个人都处于任务的顶端。
  • 监控不是在部署后开始,而是在您开始试验时开始。从模型开发阶段就开始建立监控文化(监控模型实验度量、日志等等)。
  • 当你遇到任何关键的决策点时,总是考虑什么对你的团队的生产力是最佳的。
  • 鼓励您的团队正确记录他们的故障排除框架,并为有效的模型维护创建一个从警报到行动再到故障排除的框架。

数据监控的最佳实践

  • 批处理和流数据应该以相同的方式处理,使用相同的管道,这样数据管道的问题可以更加直观地进行故障排除。
  • 请确保您不只是检查整个数据集的漂移,而是逐渐查看要素漂移,因为这可以提供更多见解。
  • 投资一个全球数据目录,它可以帮助记录每个用户(您的数据和 ML 团队)都可以依赖的高质量元数据;它将帮助您应对流式传输和保持可靠数据质量的挑战。这也将使血统跟踪更容易。
  • 在将您的模型投入生产以建立基准性能之前,对您的评估集执行预发布验证

模型监控的最佳实践

  • 随着时间的推移,模型性能将不可避免地下降,但是要小心性能的大幅下降,这通常表明有问题——您可以选择自动检测这一点的工具。
  • 对挑战者模型和冠军模型进行影子部署和测试并记录预测,以便在生产中跟踪新模型和当前模型的性能;在你决定部署新训练的(挑战者)模型之前。
  • 您可以使用一个元数据存储库(比如 Neptune.ai)来存储已经版本化并在生产中重新训练的模型的超参数;这改进了审计、合规性、沿袭可追溯性和故障排除。

监控预测/输出的最佳实践

  • 预测漂移可以作为模型度量的一个很好的性能代理,特别是当地面实况不可收集时,但是它不应该被用作唯一的度量。
  • 跟踪模型中不合理的输出。例如,您的分类模型预测了一组具有高置信度得分的输入的错误类,或者您的回归模型预测了一组给定要素的负得分(当基本度量得分应为 0 时)。

侧栏:以正确的方式设置提醒

警报是监控的重要组成部分。如果您跟踪您的度量标准,但是当出现问题时没有得到通知,为什么还要跟踪它们呢?当出现问题时,您肯定希望得到通知。

不可避免地,不同优先级的不同事情会出错。你怎样把小麦和谷壳分开?一些工具提供了开箱即用的智能警报功能,但通常情况下,它会根据应用程序归结为对特定业务有意义的内容。

以正确的方式设置警报

我从欧内斯特·穆勒和 T2·徐伟贤·卡拉扬诺夫在他们 T4 的 DevOps 课程中得到的最好的建议是:

  1. 在警报投入生产之前对其进行测试

例如,在数据漂移的情况下,编写测试用例来模拟您用来监控开发(验证)数据集和您正在模拟的生产数据之间的分布变化的统计指标。一些平台(如 Domino )会自动为您应用这些统计检查,因此您所要做的就是注册您的开发数据并集成您用于模拟的生产数据。选择特定的统计检查并设置阈值。

Image modified by the author and adapted from this source.

  1. 监控需求分析中得出的主要指标。
  2. 就警报媒体达成一致,这样每个服务负责人都会对他们的媒体感到满意。懈怠?传呼机信息辐射器?其他团队聊天?电子邮件?
  3. 通过包含描述性信息和主要服务所有者的操作,向警报发送上下文。
  4. 确保建立一个反馈回路,让你的监控更好。在数据漂移因超过设定的阈值而触发警报的情况下,如果数据被自动记录,您可能希望使用类似 Apache Airflow 的管道编排工具来启动再培训。或者,团队可能不得不手动对新数据进行再培训,或者根据新数据彻底改造问题。

警报的最佳实践

  • 确保您和您的团队清楚谁收到了什么警报。如果可能,数据质量警报应主要发送给数据运营/数据工程团队,模型质量警报发送给 ML 团队或数据科学家,系统性能警报发送给 IT 运营团队。
  • 仅当您知道存在需要干预的情况时,才设置警报。例如,为数据质量设置一个商定阈值,仅当不满足阈值条件时才触发警报。
  • 了解什么会对业务产生真正的影响,并仅对那些人发出警报,而不仅仅是应用程序出现的任何问题。
  • 让团队描述他们收到的警报(无论是误报、漏报还是真报),记录他们采取的行动以及结果。
  • 本质上,你想避免“警报地狱”;一系列不相关的警报可能会让您在噪音中迷失真正的、影响业务的警报。

最好的工具也将帮助您正确地管理您的警报,所以请留意这个功能!

侧边栏:为什么你应该记录一切!

如果我告诉你,只要知道火源在哪里,你就可以用生产中的机器学习应用程序来节省大量灭火时间,你会怎么样?

回车—日志记录!在大多数情况下,日志监视可以让您在解决生产中整个系统的任何组件的问题时有一个很好的开端。

那么你为什么要记录呢?

很简单——因为你要确保在紧要关头能轻松灭火,识别火源,并采取措施防止未来进一步的火灾爆发。

用机器学习的话来解释——你记录日志是因为你希望能够通过快速识别原因或潜在原因来有效地解决问题,采取必要的措施来解决这些问题,并修补你系统中的漏洞(或至少保持检查)。

还有一件事,你日志审计和合规!能够记录您的数据和模型事件将有助于创建数据和模型谱系,相关的利益相关者可以对其进行跟踪和审计,以符合要求和标准。

那么你应该记录什么呢?

虽然记录系统中每个组件的每个活动很有趣(从数据到模型到应用程序和其他一切),但数量总是会成为一个问题。就卷而言,我指的是将用于托管和处理该过程中生成的日志文件的存储和资源。

对你记录的东西要非常有策略。您可能没有预算来记录系统每个组件的每个活动。您应该只记录真正的问题,而不是所有的问题。从本质上讲,您记录的内容应该对您的应用程序所提供的商业价值有一定的影响。

Meme modified by the author from this source

您应该记录的数据和模型组件的一些对象包括:

  • 数据管道事件,
  • 生产数据(如有可能,包括旁边的元数据),
  • 模型元数据;这包括型号版本和配置细节,
  • 来自模型的预测结果,
  • 影子测试的预测结果(挑战者模型);如果适用于您的系统,
  • 地面实况标签(如果有的话),
  • 一般操作性能(标准监控系统的典型性能)。

最需要注意的是密切关注成交量。记录的文件可以增长到千兆字节,并需要资源来托管和解析,所以您需要确保它包含在您开始时设定的预算中。

此外,还要考虑哪项成本更高—监管机构因无法审核您的系统的合规性要求而收取的费用,或者记录必要对象所需的存储量和资源。

一些有用的测井工具包括 Neptune.aiNew RelicHoneycomb.ioDatadog

日志记录的最佳实践

  • 对于您的管道,您应该记录从计划时间到开始时间、结束时间、作业失败错误、运行次数的运行情况;这一切都是为了让不健康的管道更容易排除故障。
  • 对于您的模型,您应该记录预测以及基础事实(如果可用)、预测的唯一标识符(prediction_id)、预测调用的详细信息、模型元数据(版本、名称、超参数、签名)、模型部署到生产的时间。
  • 对于您的应用程序,您应该记录 champion 模型在生产中服务的请求数量,以及每次服务的平均延迟。
  • 对于您的数据,记录成功运行的每个管道的每个预处理数据的版本,以便它们可以满足审计要求,并且可以跟踪它们的沿袭。
  • 为了存储日志的结构,可以考虑使用带有实际结构的 JSON 格式,这样就可以很容易地解析和搜索它们。
  • 考虑轮换日志文件以便更好地管理;删除旧的和不必要的日志,因为审计或其他原因,您确定不再需要这些日志。
  • 根据欧内斯特·穆勒(Ernest Mueller)的说法,最好的日志是格式化的,具有良好的时间戳和严重性级别,并为用户提供大量的上下文。

哦!它也不止于监视吗?🙁

您将您的模型部署到生产中是有原因的,并且您在那里持续地监控它是有原因的——以继续提供积极的商业价值。

你知道什么是负商业价值吗?当监管者或你的客户要求知道你的系统如何做出决策,而你无法提供时,你会被取消,客户流失,或者更糟,你会被监管者处以巨额罚款(只需问高盛!).

或者当您的推荐系统连续 30 天向所有用户提供相同的推荐时(这里是真实事件)。

为了实现真正完整的监控,您需要:

  • 持续管理生产中的模型,以确保它不会向负业务价值倾斜,
  • 确保模型的决策过程可以被治理、审计和解释。

这里有一个很棒的教程来学习更多关于生产中的模型管理。

通过实时沙盒变得实用

我们已经在本文中介绍了许多实用概念,现在是时候通过检验、使用和/或配置您自己的监控解决方案来充分利用这些概念了。

  1. 使用 SaaS 解决方案尝试 ML 监控: Whylabs.ai 提供了一个漂亮的实时沙箱您可以使用它来检查来自数据漂移、跟踪模型性能、查看数据质量问题警报等事件的监控指标。

  2. 尝试托管您的解决方案:如果您想使用开源解决方案, Prometheus + Grafana 可能是您的最佳选择!这里有一个很好的实用教程,教你如何用 Prometheus 和 Grafana 监控你的集装箱化服务模型(使用 FastAPI )。

  3. 如果你想实际了解一家公司如何实现机器学习监控和可观察性,你可以在这里查看 DoorDash 的伟大文章

结论

没错。监控是我没有做的事情,这就是我如何结束了与 DevOps 家伙试图不卷入所有的疯狂。

Meme modified by the author from this source.

我希望你获得了一些有用的技巧,关于如何在生产中监控你的机器学习模型——不要像我一样结束!我希望您能够理解为什么部署永远不是最后一步,并且您现在已经足够清楚在生产中监控您的模型应该从哪里开始。

在这篇文章的结尾,我想给出前面章节中的挑战的解决方案:

生产挑战 关键问题 解决方法

数据分布变化

|

为什么我的特征值会突然变化?

|

使用统计检查来检测数据漂移

|
| |

生产中的车型所有权

|

谁拥有生产中的模型?DevOps 团队?工程师?数据科学家?

|

生产中的模型所有权是共同的责任

|
| | |

尽管我们在开发过程中进行了严格的测试和验证,为什么该模型在生产中的效果不佳?

|

确保您的生产数据与您的培训数据没有太大的不同,并且您的生产数据和培训数据以相同的方式处理。

|
| | |

为什么我的模型在生产中表现良好,但随着时间的推移,性能突然下降?

|

根据新数据重新训练模型或根据新数据开发另一个模型,如果前者不起作用的话。

|
| | |

我如何根据业务目标并向相关利益相关者解释和说明我的模型预测?

|

查看模型预测的可解释部分。

|
| | |

如何保证我的模型安全?我的模型被攻击了吗?

|

使用无监督学习方法进行离群点检测,包括统计检查,保护您的系统免受安全威胁。

|
| | |

我如何比较我的模型的新版本和生产版本的结果?

|

使用影子测试来测试挑战者(新培训的)模型与冠军模型(当前正在生产的模型。

|
| | |

为什么我的培训管道在执行时会失败?为什么再培训工作需要这么长时间?

|

使用日志来审计错误和警报,以通知服务所有者。

|
| | |

为什么我的预测服务延迟很高?为什么我的不同型号的延迟差别很大?

|

使用日志来审核不符合所需 SLA 的各种服务。

|
| |

【极端事件(离群值)】

|

我如何跟踪我的模型在极端和意外情况下的效果和表现?

|

理解它是采取行动前的一个瞬间或暂时的漂移。

|
| | |

我如何确保生产数据以与培训数据相同的方式进行处理?

|

编写数据完整性测试并执行数据质量检查。

|

快乐监控!

关于生产中 ML 监控的参考资料和其他资源

References and other resources on ML monitoring in production

如何组织深度学习项目——最佳实践范例

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-organize-deep-learning-projects-best-practices

一个成功的深度学习项目,你需要很多迭代,很多时间,很多努力。为了让这个过程不那么痛苦,你应该尽量利用你的资源。

一个好的循序渐进的工作流程将帮助你做到这一点。有了它,你的项目变得高效、可复制、可理解

在本文中,您将看到如何构建深度学习项目的工作——从开始到部署,监控部署的模型,以及中间的一切。

在这个过程中,我们将使用 Neptune 来运行、监控和分析您的实验。Neptune 是提高 ML 项目生产率的一个很酷的工具。

在本文中,您将了解到:

  1. 关于项目的生命周期。
  2. 定义项目目标的重要性。
  3. 根据项目需求收集数据。
  4. 模型训练和结果探索,包括:
    1. 为更好的结果建立基线。
    2. 采用现有的开源最新模型研究论文和代码库中的技术和方法。
    3. 实验跟踪和管理
  5. 避免欠拟合和过拟合的模型优化技术,例如:
    1. 控制超参数
    2. 规范化
    3. 修剪
  6. 在部署之前测试和评估您的项目。
  7. 模型部署
  8. 项目维护

生命周期

因为深度学习项目是如此迭代,我们必须非常小心地以减少任何紧张和复杂性的方式组织项目。

要做到这一点,理解 DL 项目的生命周期是什么样子是有帮助的。这里有一个大概的想法:

定义任务

当你开始一个项目时,你需要清楚地定义任务的目标。迫切需要了解机器学习系统的解决方案最终将如何用于目标问题,这一点非常重要。

甚至当你的任务很模糊的时候,会引发对评价标准优化函数,以及损失函数、数据收集/数据生成过程、等等的不同想法。

这是正确规划项目的关键一步。如果没有适当的规划,当你在后期遇到障碍时,将很难恢复。

这个项目有可能吗?

你可能没有无穷无尽的资源,所以考虑到你的局限性,验证追求你的项目是否有意义是很重要的。

想想你已经拥有的资源或者你可以轻松访问的开源资源:数据集发表的作品代码库计算能力

  • 数据采集
    • 没有可靠的数据来源,无法启动 DL 项目。这通常会占用项目的大部分时间,因为这是一个连续的过程,即使在部署之后,数据也会不断地输入到您的 DL 模型中。
  • 发表作品
    • 对你正在做的事情有个参考总是好的。大多数时候,会有文献可供你学习和获得灵感。利用现有的研究来改进你的方法真的很有帮助。
  • 代码库
    • 代码和算法,你可以重复使用,以节省时间。在 Github栈溢出上寻找代码和算法。
  • 计算能力
    • 这是您可以通过良好的优化节省最多资金的地方。根据您的模型所使用的数据,您可以使用以下任一选项,或者组合使用这两种选项:
      • Google Colab
      • 卡格尔
        • 每周免费使用多达 40 小时的 GPU 和 TPU。为了延长时间周期,或者获得更高的处理速度,你可以将你的项目与谷歌云连接起来,并进行一些配置。
      • AWS
        • 没有免费选项,您可以获得大量的处理能力,并使用它提供的专门用于机器学习训练的设施。
      • 蔚蓝色

合理组织你的项目

按照定义任务的思路,您还应该适当地组织您的项目。这也会帮助你避免将来的问题。

创建你的目录文件结构是开始一个项目最简单的方法之一,你必须为任何 DL 项目做这件事。

一个整洁有序的结构可以改善团队合作,让不同的团队成员更容易专注于各自的任务。当您在开发一个成熟的应用程序时,您需要更加精确地了解项目的需求。

一些需求将涉及保存参数和模型的版本、文档、许可证、Jupyter 笔记本等等。下面是一个如何更有效地构建项目或设置项目代码库的示例:

讨论一般的模型权衡

权衡是重要的决定。你必须用逻辑来解决问题,并可能重新制定项目的目标。

决策智能 是在任何尺度下将信息转化为更好行动的学科。–凯西·科济尔科夫,谷歌首席决策科学家

说到深度学习,应该考虑到速度精度之间的权衡。例如,苹果的 Siri、亚马逊的 Alexa、Grammarly 等使用的深度神经模型。用于从大量数据中进行预测,旨在快速准确。在这些类型的应用中,使用显示此类属性的架构至关重要。这意味着,在设计这种系统时,我们希望调整不同的神经网络参数,以共同最小化两个目标:某些验证数据的预测误差预测速度。

一般来说,这类问题涉及解决多目标优化问题。有两个或更多目标的问题。由于模型的大小会随着输入数据的复杂性而增加,所以您必须足够小心地知道并理解您希望从 DL 模型中得到什么。

从用户的角度彻底理解问题总是一个好的实践,这样你就可以重复和重新审视已定义的目标和目的。模拟出你的深度学习模型,并迭代(如果需要)用户体验,记住目标受众和提供给他们的模型类型。

请记住,一个更快的模型在预测时可能会出错,而一个准确的模型可能会很慢。理解前面的要点可以帮助我们实现一个在速度和准确性之间取得平衡的模型。

在接下来的章节中,我们将看到如何根据我们的需求优化模型。

数据收集

有许多收集数据的方法。如果你在做任何工作之前和你的团队讨论这个问题,它可以为你节省很多时间。

例如,如果您正在考虑从供应商那里购买数据,那么应该回答以下问题:

  • 你需要多少数据?
  • 你能在数据上花多少钱?
  • 有没有更便宜的获取数据的方法,或者开源的替代方法?

一个好的数据来源可以让后续的深度学习任务变得更容易。如果您的资源包含太多有偏见的数据或错误标记的数据,您将不得不解决这些问题。

数据是深度学习过程的燃料,从合法可信的资源中获取数据至关重要。

具有适当管理的数据的此类资源的好例子有:

定义基本事实

定义基本事实(标记)通常是为监督学习而做的。如果数据源不合法,可能会出现问题,导致流程后期出现不合适的 DL 模型,最终导致大量的财务压力。

人工智能不能为你设定目标,那是人类的工作。–凯西·科济尔科夫,谷歌首席决策科学家

地面真相,或标记,意味着为机器设定一个目标,它完全取决于你定义的任务——就像我们之前的例子一样,“建立一个深度学习系统,对一朵花中的真菌图像进行分类”。

你需要决定 DL 系统是对真菌图像敏感还是宽容。这就是我们通常用精确度来交换精确度的地方,反之亦然。

总是建议根据定义的任务和目标受众来设计算法,以便不会过度使用计算资源和财务资源。

另一种标注数据的方法是 主动学习 。它通常用于需要标记的大量数据。

标注可能非常昂贵,因此您需要限制在这项任务上花费的时间。

验证数据的质量

当你定义完基本事实后,下一步就是验证数据的质量。根据项目的不同,您的偏好可能会有所变化。如果您正在构建一个图像分类器,那么应该解决以下问题:

  • 你需要高分辨率的图像吗?
  • 需要什么尺寸的图像?
  • 应该黑白的,还是彩色的?
  • 图像应该有多长时间了?

同样,如果您正在构建一个 NLP 模型,更重要的问题是:

  • 需要多少语料库?
  • 你的项目需要简短的文本吗,比如推文、调查、反馈,还是需要段落,比如短文、故事或者聊天机器人的对话?
  • 需要俚语还是标点符号?
  • 它是面向普通读者还是像小说作家或研究人员这样的领域专家?

当我们分析这些问题时,我们可以从数据中移除不需要的部分或异常。验证数据质量就是在我们将数据输入机器学习模型之前准备好数据。

如果从数据集中移除了噪声,则数据是干净的。除了消除异常,它还涉及裁剪和回答关键问题,就像上面的两个例子。

一旦数据质量得到验证,您就可以继续创建接收管道。

构建数据接收管道

为了达到你想要的结果,你可能需要一次又一次地开始整个过程。自动化的一个好方法是建立一个叫做管道的连续过程。

流水线是执行一系列期望动作的一系列算法。当我们处理数据和管道时,我们倾向于描述与数据 摄取管道相同的过程。

数据摄取管道是一组从各种来源提取数据并使用客观参数对其进行转换的操作。

数据接收管道可以有各种流程:

  • 从各种来源收集数据。它可以是 API、数据中心、云存储,甚至是数据库管理系统。
  • 数据的转换:
    • 使用统计方法填补缺失值
    • 如果是图像,那么调整大小为方阵,归一化等。
  • 数据分析或可视化
  • 创建批次以输入深度学习模型

有了数据接收管道,收集、转换和加载数据的整个过程都变得自动化了。

它的伟大之处在于,您可以将相同的管道转移到其他项目,只需根据适合的项目需求在这里和那里更改一些细节。这使得管道既可伸缩又可再生。

模型训练与探索

现在可以开始探索有用的模型了。这是一个高度迭代的过程。模型探索包括建立一个模型,训练它,评估它在你的测试数据上的表现以估计它的泛化能力。

一旦你用不同配置的几个型号尝试了相同的策略,你就可以选择最终的型号并继续前进。

建立模型性能的基线

你正在处理的每个问题都必须有两条基线:

  • 简单模型基线,
  • 人的水平基线。

基线描述了我们对模型的期望。我们希望模型对各种数据是复杂的、灵活的,还是僵化的?在第二种情况下,我们可能最终在训练上表现良好,但在验证数据时却不太准确。在第一种情况下,该模型也可以在新的和看不见的数据上表现良好。

简单的模型基线可能涉及具有两个隐藏层的深度学习模型。如果模型达到一个较低的阈值(假设 70%的准确率),那么我们肯定可以通过添加层、正则化、池化层等等来增加模型的复杂性,一点一点地达到人类水平的基线。

建立基线的一个好方法是深入研究你的问题。寻找研究文献来近似你的基线,以便更清晰。永远不要被你周围的深度学习世界蒙在鼓里。了解同一个领域的不同工作可以极大地增强你的工作,并引发高效和优化模型的新技术。

从使用初始数据管道的简单模型开始

你可以从一个简单的模型开始,然后逐渐增加复杂度。这通常涉及到使用一个简单的模型,但也可以包括从一个更简单的任务开始。例如,不使用整个数据集,而是使用单个批处理。

试着理解简单模型的局限性。这样,您将看到增加复杂性的必要步骤。开始时,你的目标应该是避免不合身。

将简单模型过度拟合到训练数据

这听起来可能不太好,但知道无约束模型是否可以从数据中学习很重要。如果你的神经网络不能过度拟合单个数据点,那么架构就有严重的问题,但可能很微妙。

过度拟合告诉你,相对于数据的复杂程度,模型是复杂的,这是一件好事。一旦我们知道模型过度拟合,我们就可以开始相应地约束它,或者换句话说,调整它。

为您的问题域找到最先进的(SotA)模型(如果有的话),将其作为第二个基线应用到您的数据集

规范任何深度学习模型的一个好方法是找到关于你正在使用的模型的文献

可能会有针对您当前正在进行的项目的研究论文,所以请查阅文献并尝试不同的方法来改进您的模型。

大多数研究论文描述了他们的最先进的模型,并且它提供了改进模型的重要数学方法。努力找到这一点是值得的。

您可以遵循以下步骤来确保找到正确的研究文献以及代码库:

  1. 参观 paperwithcode.com。它有一个人工智能文献档案,在那里你可以找到几乎所有当前的人工智能研究,以及 Github 上的代码库。你所需要做的就是找到一份符合你需求的合适的论文,并彻底检查这篇论文。(你也可以参观 arxiv.org 的)。
  2. Github 中搜索合适的代码或库。再次,仔细检查代码,并相应地修改您的算法。没有必要多此一举。你所需要做的就是理解资源库中的代码,并找到一种方法将其应用到你自己的代码中。
  3. 不要拘泥于一篇研究论文,从不同的来源获得想法,然后自己想办法解决。
  4. 将更改应用到您的模型,根据您自己的数据对其进行训练,直到获得最佳性能。键是再现结果

海王星允许你随时跟踪所有的实验。每个实验都可以:

  • 使用不同的型号配置
  • 使用不同的培训或评估数据
  • 基于实现的各种技术运行不同的代码
  • 在不同的环境中运行相同的代码(不知道安装的是 PyTorch 还是 Tensorflow 版本)

随着项目中这些变化的进行,很容易忘记在各种配置和环境下进行的实验。Neptune 为每次运行保存所有与实验相关的信息或元数据。这意味着不同配置的型号可以分开存放,不会混淆,并且可以检索或下载到您的本地系统。每个实验都将包含自己的元数据,如参数配置、模型权重、可视化、环境配置文件等。这允许你比较不同的实验,并为项目选择最好的一个。

要深入了解使用 Neptune 的实验跟踪请查看这篇文章: ML 实验跟踪:它是什么,为什么重要,以及如何实施

模型细化

一旦您对成功的模型体系结构和解决问题的方法(包括数据转换)有了大致的了解,您现在应该关注于提高模型性能。

在提高模型性能时要记住几件事:提高模型的准确性,减少过度拟合。

提高效率的一个好方法是用不同的配置训练多个模型,并像前面讨论的那样同时监控它们。这样可以节省时间,也更容易比较和做出决定。

控制模型以避免过度拟合

我们之前提到过过度拟合。当模型在训练数据上表现得非常准确时,它是过度拟合的,但是当根据测试或看不见的数据进行评估时,它表现得很差。

这是因为模型过度拟合了数据。训练精度高于测试精度是这一现象的明显标志。谢天谢地,有一些技术可以解决这个问题。

你可以做以下几件事来减少或避免过度拟合:

  • 正规化
    • 用四个参数我就能让一头大象适应,用五个参数我就能让它扭动鼻子”——约翰·冯·诺依曼,恩利克·费密在《自然》杂志上引用。DL 模型的参数不止几千个,甚至上百万。有了这么多的参数,我们创建了一个复杂的模型,可以适应任何复杂的数据集,但灵活性带来了过度适应的诅咒。正则化试图通过约束来控制模型,对大权重增加惩罚。这确保了模型去除了一定的复杂性,并且可以在看不见的数据中很好地概括。
    • 有两种类型的正规化功能:L1 和 L2。两者的关键区别在于,前者使用均方误差,后者使用平均绝对误差
  • 辍学
    • 辍学是另一种类型的正规化,在深度学习中非常流行。它由 Geoffrey Hinton 于 2012 年提出,并由 Nitish Srivastava 于 2014 年在本文中进一步完善。
    • 想法很简单。在每个训练时期,每个神经元都有可能被暂时关闭或“退出”,但在下一个训练时期它可能是活跃的。
  • 提前停止
    • 如前所述,深度神经网络可能非常复杂,通常我们不知道训练时期应该是什么。如果模型训练的时间太长,那么模型就会过拟合,如果训练的时间不够长,就会过拟合。克服这个问题的一种方法是在指定的时期数之前,尽早停止训练过程。这是通过观察训练和验证损失来实现的。如果在任何给定数量的时期,模型在验证数据集上的性能开始下降(例如,损失开始增加或准确度开始降低),则训练过程停止。

除此之外,我们还可以练习:

  • 修剪模型
    • DL 模型可能不必要的庞大,一些神经元毫无意义,它们只是占用空间。修剪是一种技术,我们试图删除某些权重,而不牺牲太多的功能和准确性。这里的想法是,我们只移除那些具有特定阈值的神经元。
  • 微调超参数
    • DL 模型由大量的层组成,每层都有大量的神经元,最上层是激活,然后是权重初始化逻辑、学习速率等等,为了产生一个好的模型,你必须非常小心地选择这些超参数的组合。
    • 一种选择是尝试不同的超参数组合,看看哪一个在验证集上效果最好。

组织模型并跟踪训练跑步

海王星更容易进行模型探索和实验。它适用于 Python、Jupyter 笔记本以及所有基于云的笔记本,如 Google Colab。

Neptune 最棒的地方就是可以进行多次实验,训练时的所有信息都会在 Neptune 仪表盘中被追踪。这为您提供了一个在训练过程中模型所发生情况的实时交互式可视化。

到目前为止,您已经探索了不同的技术,以及一些关于配置的想法,比如超参数调优、学习速率、时期数等等。

在某些时候,您应该创建相当多的模型,并同时或一次一个地训练它们。有了 Neptune,所有的信息都可以记录到你的个人仪表盘中。

请记住,带有配置的模型可以用不同的版本名称存储,并且每个模型都有自己的关于模型版本的存储信息。

Compare experiments

The image above shows different models (ID) controlled by different owners. | Source

Drill-down-to-experiment-details-whenever-you-want

Each model (ID) has its own saved output stored under the same ID. | Source

Neptune 允许您分别组织每个版本的所有逻辑、数据和代码,因此您可以独立工作,而没有为其他版本更改代码的风险。

您可以在仪表板中比较所有版本,并选择符合您需求的型号。

要深入了解 Neptune 的实验跟踪,请查看本文: ML 实验跟踪:它是什么,为什么重要,以及如何实现它

测试和评估

在项目生命周期的这一点上,您应该开始编写测试。深度学习中的测试确保算法在看不见的数据上表现良好。

需要记住的一点是,深度学习算法是数据驱动的,与传统的软件模型相比,测试这种模型非常困难,因为 DL 旨在为一个之前没有答案的问题提供答案。

在测试时,我们必须确保所有组件(训练、预测和部署)都运行良好:

  • 训练系统处理原始数据,运行实验,管理结果,存储权重
  • 要求的测试:
    • 测试完整的训练管道(从原始数据到训练好的模型),以确保我们的应用程序的数据存储方式没有发生上游更改。这些测试应该每晚/每周运行一次。
  • 预测系统构建网络,加载存储的权重,并进行预测。
  • 要求的测试:
    • 对验证数据(已处理)进行推断,确保模型分数不会因新模型/权重而降低。这应该由每次代码推送触发。
    • 您还应该有一个快速的功能测试,在几个重要的例子上运行,这样您可以快速地(< 5 分钟)确保您在开发过程中没有破坏功能。当您编写新代码时,这些测试被用作健全性检查。
    • 考虑您的模型可能会遇到的场景,并开发测试来确保新模型仍能充分执行。“测试用例”是由人定义的场景,由一组精选的观察结果表示。
      • 例如:对于一辆自动驾驶汽车,你可能会进行一次测试,以确保汽车不会在黄灯时左转。在这种情况下,您可以在汽车处于黄灯状态时运行您的模型,并确保预测不会告诉汽车前进。
  • 服务系统接受“真实世界”的输入,并对生产数据进行推理。该系统必须能够根据需求进行扩展。
    • 要求的监控:
      • 停机和错误警报,
      • 检查数据的分布变化。

模型部署

当您部署 ML 模型时,您需要一直保持新的数据进入。模型需要在现实世界中进行调整,因为添加了新的类别、新的级别等等。

部署您的模型是一个开始,模型通常需要重新训练和检查性能。DL 模型需要用新数据来训练,所以最好有一个版本控制系统来处理:

  • 模型参数,
  • 车型配置,
  • 特色管道,
  • 训练数据集,
  • 验证数据集。

Model checkpoints

Versioning system by Neptune | Source

部署模型最常见的做法之一是将整个系统包装到 Docker 容器中,并公开一个 REST API 进行推理。

向一小部分用户提供新型号(即 5%),同时仍然为其他人提供现有模型。这就是版本控制有用的地方。如果一切正常(部署顺利),那么向其他用户部署一个新模型,同时保存新版本。

Shadow mode :将一个新模型与现有模型一起发布,仍然使用现有模型进行预测,但是存储两个模型的输出。测量新模型预测和当前模型预测之间的差值将向您显示当您切换到新模型时,事情会发生多么剧烈的变化。

这些是您在使用的软件中可以观察到的一些常见做法。在公开版本发布之前,总会有一个测试版提供给开发者。很好的例子是 iOS、macOS、Instagram 和其他流行的系统。

持续的模型维护

一旦您完成了培训、测试和部署,就该进行监控和维护了。

这是最昂贵的过程。您必须理解,模型应该随着时间的推移而发展,以便它总是满足现在的需求——而不是过去,也不是未来。

理解变化会以意想不到的方式影响系统

DL 模型对变化很敏感,即使是一个小的超参数变化也会影响模型的性能。因为您的模型需要发展,所以您需要为模型提供一个新的验证数据集。这样,模型将在看不见的数据上表现良好,并且具有适应性和灵活性。

使用新的验证数据集观察和分析模型的性能。如果性能下降,隔离问题并解决它。

请记住,问题的解决不应该在已部署的模型中进行,而应该在与已部署模型相同的版本中进行。一旦问题得到解决,您就可以部署代码了。

定期重新训练模型,以防止模型不锈钢

当您注意到模型中的退化时,您隔离问题,处理它,然后部署它。一般情况下也是如此。

由于模型是连续工作的,即使您没有注意到性能的任何下降,也不要忘记重新训练模型。有时很难看出输入数据的变化以及神经网络是如何分析的。

为了安全起见,最好的做法是不时地重新训练模型。

如果模型所有权发生转移,就要对新团队进行培训

通常,一旦模型准备好并部署好,工程团队就把它交给监控团队。

在这种情况下,您需要对监控团队进行全面的模型教育。你也可以用海王星来完成这个过程。因为每个人都共享同一个仪表板,所以监控团队可以很容易地了解工程人员提出的所有过程,并在方便的时候监控它们。

Share your work and invite people to your projects

Neptune offers sharing of your projects with your teammates | Source

深度学习项目工作流程到此结束

我希望这篇文章能帮助你明白为什么在你的深度学习项目中实施一个有组织的、一步一步的工作流程是重要的。

这仍然是一个新的领域,因此工作流每个阶段的最佳实践都在不断发展。关键是保持更新,不断尝试新事物来优化你的项目。

这样,你将避免浪费时间、超支和使用比你实际需要的更多的资源来实现良好的绩效。

祝你好运!

如何组织你的 LightGBM ML 模型开发过程——最佳实践范例

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-organize-your-lightgbm-ml-model-development-process-examples-of-best-practices

LightGBM 是一个分布式高效的梯度推进框架,使用基于树的学习。它以快速训练、准确性和有效利用内存而闻名。它使用逐叶树生长算法,与逐深度生长算法相比,这种算法往往收敛得更快。

LightGBM 很棒,用 LightGBM 构建模型很容易。但是,当您使用不断变化的功能和超参数配置训练模型的许多版本时,很容易迷失在所有这些元数据中。

在 Excel 表格或文本文件中管理这些配置会很快变得一团糟。幸运的是,今天有许多工具和库可以帮助你跟踪这一切。

本文将介绍如何使用最流行的实验和模型管理库 Neptune 来处理各种版本的 ML 模型。我还将向您展示如何通过几个步骤将实验管理添加到您当前的工作流程中。

如何跟踪 LightGBM 模型构建元数据: Neptune + LightGBM 集成

用 LightGBM 进行 ML 模型开发的现状

获取数据集

任何模型开发过程都将从获取数据集开始。让我们使用 Scikit-learn 来生成一个回归数据集。之后,我们将它分成训练集和测试集。

from sklearn.model_selection import train_test_split
from sklearn.datasets import make_regression

X, y = make_regression(n_samples=100000, n_features=10, n_informative=8,  random_state=101)
import pandas as pd
X = pd.DataFrame(X,columns=["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10"])
y = pd.DataFrame(y,columns=["Target"])

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=101)

训练 LightGBM 模型

此时,我们可以开始训练 LightGBM 模型的过程。然而,我们需要解决几个问题:

  • 根据train方法的要求,将训练集和验证集定义为lgb.Dataset格式
  • 定义培训参数
import lightgbm as lgb
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
params = {'boosting_type': 'gbdt',
              'objective': 'regression',
              'num_leaves': 40,
              'learning_rate': 0.1,
              'feature_fraction': 0.9
              }
gbm = lgb.train(params,
    lgb_train,
    num_boost_round=200,
    valid_sets=[lgb_train, lgb_eval],
    valid_names=['train','valid']],
   )

培训之后,我们应该保存模型,以便在部署过程中使用。

gbm.save_model('mode.pkl')

我们现在可以运行预测并将它们保存在 CSV 文件中。

import pandas as pd
pd.DataFrame(predictions, columns=["Predictions"]).to_csv("light_predictions.csv")

在构建机器学习模型时,需要对上述所有项目(代码、参数、数据版本、度量和预测)进行管理和版本化。您可以使用 git、电子表格、配置、文件系统等来完成这项工作。但是,今天我将向您展示如何使用 Neptune.ai 对所有内容进行版本控制。

https://web.archive.org/web/20221206214705if_/https://www.youtube.com/embed/w9S5srkfSI4?list=PLKePQLVx9tOd8TEGdG4PAKz0Owqdv1aaw

视频

在 Neptune 组织 ML 开发

安装包并设置 Neptune

首先,我们需要安装 Neptune 客户端包。

pip install neptune-client

使用 Neptune 笔记本,我们可以将笔记本检查点保存到 Neptune。让我们也安装它:

pip install neptune-notebooks

为了完成集成,我们需要启用这个扩展:

jupyter nbextension enable --py neptune-notebooks

:如果你不用笔记本,可以跳过这一部分。

现在我们正在安装软件包,让我们也把 Neptune Contrib 软件包拿出来。这个包将使我们能够在训练 LightGBM 模型时将我们的度量记录到 Neptune。

pip install neptune-contrib[monitoring]

将你的脚本连接到 Neptune

为了让 Neptune 客户端与 Neptune AI 进行通信,我们需要设置一个帐户并获取 API 密钥。登录后,单击个人资料图片即可获得 API 密钥。

第一步是创建一个项目。当您登录到您的帐户时,这可以在“项目”选项卡下完成。

之后我们需要初始化我们和 Neptune AI 之间的通信。

第一步是通过点击 Neptune 图标将我们的笔记本连接到 Neptune。

现在将提示您输入 API 令牌。一旦连接成功,你就可以通过点击上传按钮将你的笔记本上传到 Neptune。

之后,我们使用neptune.init来初始化我们和 neptune.ai 项目之间的通信。

import neptune
neptune.init(project_qualified_name='mwitiderrick/LightGBM, api_token='YOUR_API_KEY')

创建实验并保存超参数

开始登录 Neptune 的第一件事是创建一个实验。这是一个命名空间,您可以在其中记录度量、预测、可视化和任何其他内容(查看您可以在 Neptune 中记录和显示的所有元数据类型的完整列表)。

让我们创建一个实验并记录模型超参数。

neptune.create_experiment('LightGBM',params=params)

运行neptune.create_experiment输出海王星实验的链接。

可以点开看看训练过程直播。

现在,没有记录太多,但是我们可以在 parameters 部分看到超参数。

“参数”选项卡显示用于训练 LightGBM 模型的参数。

创建 Neptune 回调并将其传递给“train”

为了将训练指标记录到 Neptune,我们使用了来自neptune-contrib库的现成回调。这很酷,因为这是我们在训练阶段唯一需要添加的东西。

有了回调设置,海王星照顾其余的。

import lightgbm as lgb
gbm = lgb.train(params,
    lgb_train,
    num_boost_round=200,
    valid_sets=[lgb_train, lgb_eval],
    valid_names=['train','valid'],
    callbacks=[neptune_monitor()],
   )

注意:在笔记本上工作时,一旦完成运行实验,确保您的运行neptune.stop()完成当前工作(在脚本中实验自动停止)。

点击 Neptune 上的项目,将显示与该特定项目相关的所有实验。

单击单个实验将显示该特定实验的图表和日志。

日志部分显示了用于生成上述图表的培训和验证指标。

有趣的是,我们可以在模型训练时监控 RAM 和 CPU 的使用情况。这些信息可以在实验的监控部分找到。

当我们看图表时,海王星允许我们放大和缩小不同的地方。这对于更深入地分析模型的训练是重要的。

此外,我们可以选择几个实验并比较它们的性能。

版本测试指标

Neptune 还允许我们记录我们的测试指标。这是使用neptune.log_metric功能完成的。

neptune.log_metric('Root Mean Squared Error', np.sqrt(mean_squared_error(y_test, predictions)))
neptune.log_metric('Mean Squarred Error', mean_squared_error(y_test, predictions))
neptune.log_metric('Mean Absolute Error', mean_absolute_error(y_test, predictions))

版本数据集

在 Neptune 中对数据集哈希进行版本控制也非常有用。这将使您能够在执行实验时跟踪数据集的不同版本。这可以用 Python 的hashlib模块和 Neptune 的set_property函数来完成。

import hashlib
neptune.set_property('x_train_version', hashlib.md5(X_train.values).hexdigest())
neptune.set_property('y_train_version', hashlib.md5(y_train.values).hexdigest())
neptune.set_property('x_test_version', hashlib.md5(X_test.values).hexdigest())
neptune.set_property('y_test_version', hashlib.md5(y_test.values).hexdigest())

之后,您可以在项目的 details 选项卡下看到版本。

你也可以使用一个数据版本化工具,比如 DVC 来管理数据集的版本。此后,您可以记录。dcv 文件到 Neptune。

为了做到这一点,你首先要添加文件到 dvc。这是在当前工作目录下的终端上完成的。

$ dvc add data.csv

这将创建。dvc 文件,您可以登录到 Neptune。

neptune.log_artifact('data.csv.dvc')

版本型号二进制

还可以使用neptune.log_artifact()将模型的各种版本保存到 Neptune。

修改你认为你还需要的东西

Neptune 还提供了使用您最喜欢的绘图库记录其他东西的能力,例如模型解释器和交互式图表。

记录解释者是使用log_explainer函数完成的。

from neptunecontrib.api import log_explainer, log_global_explanations
import dalex as dx

expl = dx.Explainer(model, X, y, label="LightGBM")
log_global_explanations(expl, numerical_features=["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10"])
log_explainer('explainer.pkl', expl)

这样做之后,这个实验的工件部分将会提供这个经过腌制的解释器和图表。

同样重要的是要注意,即使您使用 LightGBM Scikit-learn 包装器,日志也可以工作。你唯一要做的就是在模型的拟合阶段通过 Neptune 回调。请注意,您可以添加评估集以及评估指标。

model.fit(X_test,y_test,eval_set=[(X_train,y_train),(X_test,y_test)],eval_metric=['mean_squared_error','root_mean_squared_error'],callbacks=[neptune_monitor()])

在仪表板中组织实验

有了 Neptune,您可以灵活地决定想要在仪表板上看到什么。

您可以随意在仪表板中添加或删除列。例如,您可以添加“在笔记本中创建”列,以便立即访问笔记本检查点。

您还可以按列降序或升序筛选仪表板。如果您想删除列,只需单击 x 按钮。

Neptune 还允许您将实验分组到视图中并保存它们。保存的视图可以共享或固定在仪表板上。

与您的团队合作进行 ML 实验

海王星实验可以通过邀请你的队友合作来分享。

可以通过首先公开项目来共享项目。一旦公开,你就可以通过链接与任何人自由分享。

使用团队计划时,您可以与队友分享您的私人项目。该团队计划对研究、非营利组织和 Kagglers 也是免费的。

人们可以分享他们在 Neptune 上做的任何事情,例如,我可以通过发送一个链接来分享我之前做的比较。

以编程方式下载模型工件

Neptune 还允许你下载任何实验的文件。这使您能够从 Python 代码中下载单个文件。例如,您可以使用download_artifact方法下载单个文件。例如,要下载我们之前上传的模型,我们只需要获取实验对象并使用它来下载模型。该模型存储在我们当前工作目录的模型文件夹中。

project = neptune.init('mwitiderrick/LightGBM',api_token='YOUR_TOKEN')
my_exp = project.get_experiments(id='LIG-8')[0]
experiment.download_artifact("light.pkl","model")

当您想要将您的模型转移到生产中时,这很方便。然而,这是另一篇文章的主题。

结论

希望这已经向您展示了使用 Neptune 向您的 LightGBM 训练脚本添加实验跟踪和模型版本化是多么容易。

具体来说,我们讲述了如何:

设置海王星

  • 使用 Neptune 回调来记录我们的 LightGBM 培训课程
  • 分析和比较海王星的实验
  • 海王星上各种项目版本
  • 与团队成员协作
  • 从海王星下载你的神器
  • 希望有了这些信息,LightGBM 模型现在会更清晰,更易于管理。

感谢阅读!

Thanks for reading!

如何有效地组织你的 ML 开发

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-organize-your-ml-development

每个数据科学家和 ML 实践者最终都会遇到的一个主要问题是工作流管理。测试不同的场景和用例,记录信息和细节,共享和比较特定样本集的结果,可视化数据,跟踪洞察力。这些是数据科学工作流管理的关键组件。它们有助于业务,使您能够扩展任何数据科学项目。

数据科学家很清楚,测试一个版本的 ML 算法是不够的。我们的领域非常依赖经验主义,因此我们需要测试和比较具有不同超参数调整和特性选择的同一算法的多个版本。

所有这些都会产生元数据,需要正确存储。为了做到这一点,我使用了一个可以为我管理所有这些东西的平台——Neptune。它附带了一个完整的客户端库,可以无缝集成到您的代码中。它们还可以让您访问基于 web 的用户界面,在这里您的所有数据都被记录下来并可供使用。

为了让您了解 Neptune 所提供的功能,我用一个准备好的在线数据集模拟了一个真实的用例场景。我们将运行不同的分析和 ML 流程,看看海王星在日常工作中能为你提供多少支持。

设置 Neptune 环境

为了使您能够快速开始将 Neptune 集成到项目的所有方面,了解如何安装软件包和库,以及如何将 Jupyter 笔记本连接到 Neptune 帐户可能会很有用。

首先,让我们创建一个 conda 虚拟环境,我们将在其中安装所有需要的 neptune 库:

conda create --name neptune python=3.6

安装 neptune 客户端库:

pip  install neptune-client

安装 Neptune 笔记本,将我们所有的工作保存到 Neptune 的 web 客户端:

pip install -U neptune-notebooks

使用以下扩展启用 jupyter 集成:

jupyter nbextension enable --py neptune-notebooks

获取您的 API 密钥,并将您的笔记本与您的 Neptune 会话连接起来:

成功连接笔记本后,您需要创建一个个人项目,您的所有实验都将保存在该项目中:

要完成设置,请在笔记本中导入 neptune 客户端库,并调用 neptune.init()方法初始化连接:

import neptune
neptune.init(project_qualified_name='aymane.hachcham/CaseStudyOnlineRetail')

你也可以去查一个海王星 AI 前数据科学家 Kamil 做的视频,里面把前面的细节解释的很透彻。

https://web.archive.org/web/20221206091240if_/https://www.youtube.com/embed/37X5iXiVop8?list=PLKePQLVx9tOd8TEGdG4PAKz0Owqdv1aaw

视频

:我把代码放在最有启发性的地方,如果你想查看完整的代码版本和笔记本,请随意访问我的 Github repo—Neptune-Retail

探索数据集

我们将看看在线零售数据集,在 Kaggle 公开发布。该数据集记录了世界各地使用在线销售平台的各种客户。每条记录都通知一个购买特定产品的订单。

数据集显示如下:

为了开始加载数据集,我创建了一个小的 pythondata manager类来下载 CSV 文件,提取主要特征并将它们转换成可用的熊猫数据帧:

class DataETLManager:
    def __init__(self, root_dir: str, csv_file: str):
        if os.path.exists(root_dir):
            if csv_file.endswith('.csv'):
                self.csv_file = os.path.join(root_dir, csv_file)
            else:
                logging.error('The file is not in csv format')
                exit(1)
        else:
            logging.error('The root dir path does not exist')
            exit(1)

        self.retail_df = pd.read_csv(self.csv_file, sep=',', encoding='ISO-8859-1')

    def extract_data(self):
        return self.retail_df

    def fetch_columns(self):
        return self.retail_df.columns.tolist()

    def data_description(self):
        return self.retail_df.describe()

    def fetch_categorical(self, categorical=False):
        if categorical:
            categorical_columns = list(set(self.retail_df.columns) - set(self.retail_df._get_numerical_data().columns))
            categorical_df = self.retail_df[categorical_columns]
            return categorical_df
        else:
            non_categorical = list(set(self.retail_df._get_numerical_data().columns))
            return self.retail_df[non_categorical]

    def transform_data(self):
        data = self.retail_df

        data.drop_duplicates(keep='last', inplace=True)

        data['InvoiceNo'].fillna(value=0, inplace=True)
        data['Description'].fillna(value='No Description', inplace=True)
        data['StockCode'].fillna(value='----', inplace=True)
        data['Quantity'].fillna(value=0, inplace=True)
        data['InvoiceDate'].fillna(value='00/00/0000 00:00', inplace=True)
        data['UnitPrice'].fillna(value=0.00, inplace=True)

        data['CustomerID'].fillna(value=0, inplace=True)
        data['Country'].fillna(value='None', inplace=True)

        data['InvoiceDate'] = pd.to_datetime(data['InvoiceDate'])

        self.data_transfomed = data

我们可以用来开始构建内部核心指标的重要栏目有:

  • 数量
  • 单价
  • CustomerID
  • 国家

*首先使用 DataETLManager 加载数据集:

etl_manager = DataETLManager(root_dir='./Data', csv_file='OnlineRetail.csv')
etl_manager.extract_data()
etl_manager.transform_data()

dataset = etl_manager.data_transfomed

对于零售企业来说,核心价值依赖于平台通过客户订单产生的收入。我们可以将单价和数量结合起来形成月收入,并按发票日期汇总:

dataset['Profit'] = dataset['Quantity'] * dataset['UnitPrice']
revenue = dataset.groupby(['InvoiceDate'])['Profit'].sum().reset_index()

我们还可以通过绘制下图来直观显示收入在几个月内的变化情况:

import chart_studio.plotly as py
import plotly.graph_objects as go
import plotly.offline as pyoff

pyoff.init_notebook_mode()

data = go.Scatter(
    x=revenuePerYear['InvoiceDate'],
    y=revenuePerYear['Profit']
)

layout = go.Layout(
    xaxis={"type": "category"},
    title='Monthly Revenue'
)

fig = go.Figure(data, layout)
pyoff.iplot(fig)

由于我们的主要目标是客户,一个值得关注的指标是我们平台保留的活跃客户数量。我们将专门针对英国客户进行实验,因为他们构成了数据样本的大部分。

为了研究主动客户保持,我们需要检查每个月有多少客户订单:

uk_customers = dataset.query("Country=='United Kingdom'").reset_index(drop=True)
activeCustomers = dataset.groupby(['InvoiceDate'])['CustomerID'].nunique().reset_index()

分布似乎相当单调,在 2011 年 11 月达到峰值。

在我们的案例研究中,我们希望对这些客户进行适当的细分。通过这种方式,我们可以有效地管理投资组合,并剖析每个团队实际提供的不同价值水平。

我们还应该记住,随着业务规模的增长,不可能对每个客户都有一个直觉。在这个阶段,关于追求哪些客户的人类判断将不起作用,企业将不得不使用数据驱动的方法来建立适当的战略。

在下一部分,我们将更深入地挖掘不同的指标和分析,我们可以利用这些指标和分析对我们的客户群进行适当的细分。

提取指标并对数据进行分析

在这一部分,我们将彻底分析数据。我们希望根据财务标准对整个客户群进行细分。在本节结束时,我们应该能够描述和了解我们的客户购买行为。

由于我们已经在 Neptune 中初始化了我们的项目,我们将开始我们的第一个实验,记录我们将在本节中提取的统计数据。您可以将 Neptune 实验想象成一个命名空间,您可以在其中记录度量、预测、可视化以及您可能需要的任何其他内容。

首先初始化这个实验的参数,并调用 create _ experiment()方法。

params = {
    'n_clusters':4,
    'max_iterations': 1000,
    'first_metric': 'Recency',
    'second_metric': 'Frequency',
    'third_metric': 'Monetary Value',
    'users': 'UK'
}

neptune.create_experiment(
    name='KMeans-UK-Users',
    tags=['KMeans-UK'],
    params=params
)

一旦你运行笔记本电池,你可以前往网站。如果您打开我们刚刚创建的实验,在参数下,您会发现值被正确记录,并准备好跟踪进一步的行动。

为了根据盈利能力和增长潜力对我们的客户群进行细分,我们将关注最终会影响我们客户金融行为的三个主要因素。该标准依赖于构成所谓的 RFM 分数的三个因素:

  • 使用频率:监控用户活动最近的一个指标
  • 使用频率:用户多久在平台上购买一次产品
  • 一元价值:从字面上看,它们有多有利可图

首先,我们需要详细阐述数据集的指标。然后,我们将对这些数据点执行聚类,这样我们就可以根据相似性将它们从高价值客户到低价值客户分成不同的类别。从客户细分中获得的见解被用于开发量身定制的营销活动和设计营销策略。

对于这个任务, K-Means 聚类算法仍然是一个非常强大的工具。它的易用性和性能为我们的用例提供了完美的平衡。

关于 K-Means 如何工作的详细解释,我推荐这篇完美完成这项工作的文章: K-Means 聚类——解释

RFM 分数

这个想法是测量自上次购买以来的天数,从而测量平台上记录的不活动天数。我们可以将其计算为所有客户的最大购买日期减去该范围内的总最大日期。
创建我们将在工作的客户数据框架:

customers = pd.DataFrame(dataset['CustomerID'].unique())
customers.columns = ['CustomerID']

合计最大发票日期:

aggregatR = {'InvoiceDate': 'max'}
customers['LastPurchaseDate']=dataset.groupby(['CustomerID'],as_index=False).agg(aggregatR)['InvoiceDate']

生成最近得分:

customers['Recency'] = (customers['LastPurchaseDate'].max() - customers['LastPurchaseDate']).dt.days

客户最近:

因为我们有相应的表,所以将它记录到我们的 Neptune 实验中是一个好主意。

为此,我们可以调用 neptune.log_table()方法,如下所示:

from neptunecontrib.api import log_table
log_table('Recency English Users', recency_UK)

现在,您可以继续应用 K-Means 来对我们的最近分布进行聚类。在此之前,我们需要定义最适合我们需求的集群数量。一种方法是肘法。肘方法简单地告诉最佳惯性的最佳簇数。

K-means_metrics = {}

for k in range(1, 10):
    kmeans = KMeans(n_clusters=k, max_iter=1000).fit(customers['Recency'])
    customers["clusters"] = kmeans.labels_
    k-means_metrics[k] = k means.inertia_

让我们画出海王星的值,这样我们可以彻底检查曲线如何演变的细节:

for val in kmeans_metrics.values():
    neptune.log_metric('Kmeans_Intertia_Values', val)

Neptune 自动记录日志部分的值,并相应地生成一个图表。

根据该图,最佳的最佳聚类数是 4。因此,我们将对三个指标使用 4 个集群。

K-表示最近:

kmeans = KMeans(n_clusters=4)
kmeans.fit(customers[['Recency']])
customers['RecencyCluster'] = kmeans.predict(customers[['Recency']])

让我们记录最近的分布和预测的集群。

for cluster in customers['RecencyCluster']:
    neptune.log_metric('UK Recency Clusters', cluster)

for rec in customers['Recency']:
    neptune.log_metric('Recency in days', rec)

如果您放大最近天数图表,您会注意到数值范围在 50 到 280 天之间。

我们可以通过查看一些常规统计数据来检查有关集群分布的更多信息:

我们可以注意到,聚类 2 中的客户比聚类 1 中的客户更新。

让我们通过分别计算频率和货币价值来推进我们的研究。我们将尝试在这三个指标之间进行更高层次的比较。

汇总客户订单数:

customers = pd.DataFrame(dataset['CustomerID'].unique())
customers.columns = ['CustomerID']

aggregatF = {'InvoiceDate': 'count'}
freq = dataset.groupby('CustomerID', as_index=False).agg(aggregatF)
customers = pd.merge(customers, freq, on='CustomerID')

K-频率得分的均值:

kmeans = KMeans(n_clusters=4)
kmeans.fit(customers[['Frequency']])
customers['FrequencyCluster'] = kmeans.predict(customers[['Frequency']]

当与前面的帧结合时,我们得到下表:

合计每个客户产生的利润总和:

dataset['Profit'] = dataset['UnitPrice'] * dataset['Quantity']
aggregatMV = {'Profit': 'sum'}
mv = dataset.groupby('CustomerID', as_index=False).agg(aggregatMV)
customers = pd.merge(customers, mv, on='CustomerID')

customers.columns = ['CustomerID', 'lastPurchase', 'Recency', 'Frequency', 'MonetaryValue']

然后,我们将所有指标组合在一起,以便有一个总体概述。

K-表示货币价值:

kmeans = KMeans(n_clusters=4)
kmeans.fit(customers[['MonetaryValue']])
customers['MonetaryCluster'] = kmeans.predict(customers[['MonetaryValue']])

为了得到一个综合考虑了我们刚刚收集的所有值的 RFM 分数,我们需要在一个唯一的总分数中总结不同的聚类。然后,我们根据获得的范围值对每个客户部分进行细分。

三个部分:

  • 高值:0-2 分
  • 中间值:3-6 分
  • 高值:6-9 分
customers['RFMScore'] = customers['RecencyCluster'] + customers['FrequencyCluster'] + customers['MonetaryCluster']
customers['UserSegment'] = 'Low'

customers.loc[customers['RFMScore'] <= 2, 'UserSegment'] = 'Low'
customers.loc[customers['RFMScore'] > 2, 'UserSegment'] = 'Mid'
customers.loc[customers['RFMScore'] > 5, 'UserSegment'] = 'High'

最精彩的部分是当我们绘制聚类图并可视化它们是如何分布的,将频率新近度度量与它们产生的货币价值进行比较。

这两个指标都清楚地表明,最近的和频繁的用户更有利可图。因此,我们应该提高高价值用户(红色)的保留率,并根据该标准做出决策。此外,通过提高用户保留率,我们可以立即影响他们在平台上的频率和新近度。这意味着我们还应该在用户参与度上进行操作。

在 Neptune 组织 ML 开发

在这一节中,我们将利用 Neptune 提供的一个优秀特性,即 ML 集成。在我们的例子中,我们将密切关注 XGBoost ,因为海王星有助于所有的技术细节,比如:

  • 每次提升迭代后记录指标
  • 训练后的模型记录
  • 特征重要性
  • 最后一次提升迭代后的树可视化

eXtremeGradientBoosting 是梯度增强的优化和并行化开源实现,由华盛顿大学的博士生陈天琦创建。XGBoost 使用决策树(像 random forest)来解决分类(二元&多类)、排序和回归问题。我们在监督学习算法领域。

本节的想法是预测客户终身价值,这是评估我们客户组合的另一个重要指标。平台对客户进行投资,进行获取成本、促销、折扣等。我们应该跟踪和密切关注当前的盈利客户,并预测他们在未来会如何发展。

在这个实验中,我们将在 9 个月的时间内锁定一组客户。我们将使用 3 个月的数据训练一个 XGBoost 模型,并尝试预测接下来的 6 个月。

分离数据

3 个月用户:

from datetime import datetime, date

uk = dataset.query("Country=='United Kingdom'").reset_index(drop=True)
uk['InvoiceDate'] = pd.to_datetime(uk['InvoiceDate'])

users_3m = uk[(uk['InvoiceDate'].dt.date >= date(2010, 12, 1)) & (uk['InvoiceDate'].dt.date < date(2011, 4, 1))].reset_index(drop=True)

6 个月用户:

users_6m = uk[(uk['InvoiceDate'].dt.date >= date(2011, 4, 1)) & (uk['InvoiceDate'].dt.date < date(2011, 12, 1))].reset_index(drop=True)

现在,在 3 个月的数据框架中,应用我们之前所做的相同汇总。关注频率、近期和货币价值。此外,计算与 K-Means 相同的聚类规则。

为了创建终身价值指标,我们将按 6 个月用户组每月产生的收入进行汇总:

users_6m['Profit'] = users_6m['UnitPrice'] * users_6m['Quantity']
aggr = {'Profit': 'sum'}
customers_6 = users_6m.groupby('CustomerID', as_index=False).agg(aggr) customers_6.columns = ['CustomerID', 'LTV']

然后根据该度量生成 K 均值聚类:

kmeans = KMeans(n_clusters=3)
kmeans.fit(customers_6[['LTV']])
customers_6['LTVCluster'] = kmeans.predict(customers_6[['LTV']])

开始培训过程

将 3 个月的表与 6 个月的表合并,您将拥有相同的数据框,以及我们将在后续步骤中使用的训练集和验证集。

classification = pd.merge(customers_3, customers_6, on='CustomerID', how='left')
classification.fillna(0, inplace=True)

我们的目标是根据核心预测功能为 LTVCluster 提供分类细分,例如:MVCluster、FrequencyCluster、RFMScore 和 Monetary Value。

然而,我们还不知道它们的相关性和预测能力。就此而言,我们需要运行一些属性相关性分析。

属性相关性分析

运行属性相关性分析,我们将考虑两个重要的功能:识别对目标变量影响最大的变量,以及理解最重要的预测因子和目标变量之间的关系。为了运行这种分析,可以使用 信息值证据权重 的方法。

:为了更深入地回顾 WoE 和 IV,我强烈推荐这篇关于流失分析的中型文章: 使用信息价值和证据权重的流失分析 ,作者 Klaudia Nazarko

在我们的例子中,我们将继续查看所有特性之间的相关性,并检查 MVClusterRFM store的信息值。

相关矩阵:

classification.corr()['LTVCluster'].sort_values(ascending=False)
import pandas as pd
import seaborn as sn
import matplotlib.pyplot as plt

corrMatrix = classification.corr()
sn.heatmap(corrMatrix, annot=False)
plt.show()

Neptune 与可视化库(包括熊猫matplotlib 等等)的集成。

我们确实观察到与 LTVCluster 更相关的特征是频率、货币价值和新近性,这是有意义的。

同样,根据 WoE 和 IV 分析,MVCluster 和 RFMScore 似乎比其他的预测能力更强。

最后,为了进行进一步的训练,我们需要将分类变量转换成数字。一种快速的方法是使用 pd.get_dummies():

classification = pd.get_dummies(customers)

UserSegment 列已经消失,但我们有新的数字来表示它。我们已经将它转换为 3 个不同的 0 和 1 列,并使其可用于我们的机器学习模型。

列车 XGBoost

创造实验

首先在我们已经初始化的前一个项目中创建一个新的实验。在本节中,我们将使用 XGBoost 的多个版本来训练我们的数据。每个版本都将设置特定的超参数。

最后,我们将尝试比较不同的实验,以获得更多的见解。你可以随时查看 Neptune docs,找到任何相关的资源和文档,以备不时之需。

params = {
    'max_depth':5,
    'learning_rate':0.1,
    'objective': 'multi:softprob',
    'n_jobs':-1,
    'num_class':3
}

neptune.create_experiment(
    name='XGBoost-V1',
    tags=['XGBoost', 'Version1'],
    params=params
)

根据 hyper-parameters,我们需要一个能够进行多标签分类的 XGBoost 模型(因此我们使用了 multi:softprob 目标函数)。我们专门针对客户 LTV 集群范围内的三个类别。

拆分数据

将数据分成训练集和测试集:

X = classification.drop(['LTV', 'LTVCluster', 'lastPurchase'], axis=1)
Y = classification['LTVCluster'] 
x_train, x_test, y_train, y_test = train_test_split(X,Y, test_size=0.05, random_state=56) 

实例化 XGB DMatrix 数据加载器,以便我们可以方便地将数据传递给模式:

dtrain = xgb.DMatrix(x_train, label=y_train)
dtest = xgb.DMatrix(x_test, label=y_test)

使用 XGBClassifier Neptune 回调并记录所有指标

是时候让数据符合我们的模型了。我们将使用 XGBClassifier,并在实验仪表板中实时记录所有指标。利用 Neptune 与所有不同种类的梯度增强算法的紧密集成,我们能够非常容易地监控性能和进度。

multi_class_XGB = xgb.XGBClassifier(**params3)
multi_class_XGB.fit(x_train, y_train, eval_set=[(x_test, y_test)], callbacks=[neptune_callback()])

neptune.stop()

有一个非常好的视频解释了 Neptune XGBoost 集成是如何工作的:Integrations–XGBoost

https://web.archive.org/web/20221206091240if_/https://www.youtube.com/embed/xc5gsJvf5Wo?list=PLKePQLVx9tOd8TEGdG4PAKz0Owqdv1aaw

视频

如果我们回到 Neptune 并单击我们创建的实验,我们可以可视化损失图表、损失度量和特性重要性图表。

如果我们想看看我们的模型在测试集上的得分,我们可以使用 sklearn.metrics 包打印一个分类报告。

from sklearn.metrics import classification_report,confusion_matrix
predict = multi_class_XGB.predict(x_test)
print(classification_report(y_test, predict))

尽管我们对之前的结果非常满意,但我们仍然可以创建另一个实验,并调整或更改一些超参数以获得更好的结果。

params2 = {
    'max_depth':5,
    'learning_rate':0.1,
    'objective': 'multi:softprob',
    'n_jobs':-1,
    'num_class':3,
    'eta':0.5,
    'gamma': 0.1,
    'lambda':1,
    'alpha':0.35,
}

neptune.create_experiment(
    name='XGBoost-V2',
    tags=['XGBoost', 'Version2'],
    params=params2,
)

让我们来训练:

multi_class_XGB = xgb.XGBClassifier(**params2)
multi_class_XGB.fit(
    x_train,
    y_train,
    eval_set=[(x_test, y_test)],
    callbacks=[neptune_callback()])

neptune.stop()

检查训练集和测试集的准确性:

print('Accuracy on Training Set: ', multi_class_XGB.score(x_train, y_train))
print('Accuracy on Testing Set: ', multi_class_XGB.score(x_test[x_train.columns], y_test))

总的来说,结果相当不错,几乎与之前的实验相同。

比较两个实验

Neptune 允许我们选择多个实验,并在仪表板上进行比较:

我们可以并排观察这两个实验,并比较每个列实验中的参数实际上如何影响训练集、测试集和验证集的损失。

版本化您的模型

Neptune 的一个有趣特性是能够对模型二进制文件进行版本控制,这样我们就可以在进行实验时跟踪不同的版本。

neptune.log_artifact('xgb_classifier.pkl')

但是,在训练过程中调用 neptune_callback()时,最后一次 boosting 迭代会毫不费力地自动记录到 neptune。

结论

本教程的主要目标是帮助您快速开始使用 Neptune。工具非常容易,很难在 UI 中迷失。

我希望这篇教程对你有用,因为我设计它是为了涵盖真实数据科学用例的不同方面。我给你留一些参考资料,看看你是否觉得自己的求知欲还需要淬火:

此外,不要忘了查看 Neptune 文档网站和他们的 Youtube 频道,那里有你开始更有效工作所需的所有工具的深度报道:

别忘了查看我的 Github repo 获取本教程的完整代码: 海王星-零售*

如何组织你的 XGBoost 机器学习(ML)模型开发过程:最佳实践

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-organize-your-xgboost-machine-learning-ml-model-development-process

XGBoost 是一个顶级的渐变增强库,可以在 Python、Java、C++、R 和 Julia 中使用。

该库支持 GPU 培训、分布式计算、并行化和缓存优化。开发人员也喜欢它的执行速度、准确性、效率和可用性。

然而,当你在任何框架中开发机器学习模型时,包括 XGBoost,你可能最终会尝试一堆参数配置和功能版本,以获得满意的性能。使用电子表格和命名约定来管理所有这些配置确实令人头疼。

有一些工具可以帮助开发人员组织他们的机器学习模型开发过程。本文将重点向您展示如何在顶级 ML 实验管理工具之一的 Neptune 中实现这一点。

让我向您展示如何在您当前的模型开发设置之上添加实验管理。

如何跟踪 XGBoost 模型训练:海王星+ XGBoost 集成

使用 XGBoost 进行 ML 模型开发通常是什么样子

准备好数据集

在训练任何模型之前,我们需要一个数据集。对于这个示例,我们将使用 Scikit-learn 生成一个分类数据集。在现实生活中,你可能已经准备好了一些特性,你将会加载它们。

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

X, y = make_classification(n_samples=100000,n_features=10, n_redundant=0, n_informative=8,random_state=1)
import pandas as pd
X = pd.DataFrame(X,columns=["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10"])
y = pd.DataFrame(y,columns=["Target"])

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.33, random_state=42)

训练 XGBoost 模型

接下来,我们将导入 XGBoost,设置我们的参数。由于这是一个二元分类,我们使用logistic目标。之后,我们用这些参数初始化分类器。您也可以使用 YAML 文件传入参数。

params = {"objective":"binary:logistic",'colsample_bytree': 0.3,'learning_rate': 0.1,
                'max_depth': 5, 'alpha': 10}
classification = xgb.XGBClassifier(**params)

下一步是用训练测试来训练模型。

classification.fit(X_train, y_train)

培训之后,我们需要保存模型,以便在部署过程中使用它。

from sklearn.externals import joblib
joblib.dump(classification, 'classifier.pkl')

接下来,我们在测试集上评估模型,并显示分类报告。

from sklearn.metrics import classification_report

print(classification_report(predictions,y_test))

最后,我们将获得的预测转换成数据帧,并保存为 csv 文件以供将来参考,或者进行一些深层错误分析

import pandas as pd
pd.DataFrame(predictions, columns=["Predictions"]).to_csv("predict.csv")

现在,让我向您展示如何对所有这些进行版本控制,并通过 Neptune 轻松管理。

在 Neptune 组织 ML 开发

安装软件包并设置 Neptune

我们将在 Jupyter 笔记本中使用 Neptune,所以我们需要 Neptune 客户端和 Neptune Jupyter 扩展。

在您的终端中运行以下命令来安装 Neptune:

pip install neptune-client

为 Jupyter 笔记本配置 Neptune 是必不可少的,因为它使我们能够将笔记本检查点保存到 Neptune。如果您不使用笔记本电脑,可以跳过这一部分。

接下来,设置笔记本扩展:

pip install neptune-notebooks

安装后,您必须启用扩展,以便与您的 Jupyter 笔记本电脑集成:

jupyter nbextension enable --py neptune-notebooks

如果你在 JupyterLab 上工作,你可以毫无问题地安装扩展。

因为我们正在安装软件包,所以让我们也把 Neptune Contrib 软件包去掉。它包含一个回调函数,让我们在训练 XGBoost 模型时记录度量、模型和特性对 Neptune 的重要性。

pip install neptune-contrib[monitoring]

将您的脚本连接到海王星

此时,您需要一个免费的 Neptune AI 帐户来初始化 Jupyter 笔记本中的 Neptune。为此,您需要一个 Neptune API 密钥。

登录后,您可以通过单击您的个人资料图像来获取密钥。

都准备好了吗?让我们跳到 Jupyter 笔记本上进行初始化。

第一步是通过点击 Neptune 图标将我们的笔记本连接到 Neptune。

现在将提示您输入 API 令牌。一旦连接成功,你可以通过点击上传按钮上传你的笔记本到 Neptune。

之后,我们使用‘neptune . init’来初始化通信,并将当前脚本/笔记本与您在 Neptune 中的项目连接起来。

import neptune

neptune.init(project_qualified_name='mwitiderrick/sandbox', api_token='YOUR_API_KEY')

在这种情况下,我使用的是在你注册时自动创建的“沙盒”项目。但是,您可以在“项目”标签中创建新项目。

创建实验并保存超参数

开始登录 Neptune 的第一件事是创建一个实验。这是一个命名空间,您可以在其中记录度量、预测、可视化和任何其他内容(参见您可以在 Neptune 中记录和显示的元数据类型的完整列表)。

让我们创建一个实验并记录模型超参数。

experiment = neptune.create_experiment(name='xgb', tags=['train'], params=params)

运行neptune.create_experiment输出海王星实验的链接。

可以点开看看训练过程直播。

现在,没有记录太多,但是我们可以在参数部分看到超参数。

“参数”选项卡显示用于训练 XGBoost 模型的参数。

在笔记本上工作时,一旦你完成了运行实验,确保你的运行neptune.stop()完成当前的工作(在脚本中实验自动停止)。

创建 Neptune 回调并将其传递给“fit”

为了将训练指标记录到 Neptune,我们使用了来自 neptune-contrib 库的现成回调。这很酷,因为这是我们在训练阶段唯一需要添加的东西。

有了回调设置,海王星照顾其余的。

from neptunecontrib.monitoring.xgboost import neptune_callback

我们通过调用fit方法并传入我们之前定义的参数来训练模型,包括 Neptune 回调。

classification.fit(X_train, y_train,callbacks=[neptune_callback()],eval_set=[(X_test, y_test)])

一旦训练完成,回到海王星,检查日志。

登录后,您可以单击当前正在进行的项目来查看您的所有实验。

在 monitoring 选项卡上,会实时显示 CPU 和 RAM 的使用情况。

单击单个实验将显示该特定实验的日志。在图表部分,您可以看到培训和验证图表。

使用 Neptune,您还可以放大培训的各个部分,对其进行详细分析。

“日志”部分显示了用于生成这些图形的日志。

注意使用 Neptune 回调后我们自动得到的特性重要性图。

一旦你的项目中有了几个实验,就可以对它们进行比较。你可以通过选择实验并点击比较按钮来完成。

版本数据集

在 Neptune 中对数据集哈希进行版本控制也非常有用。这将使您能够在执行实验时跟踪数据集的不同版本。这可以借助 Python 的hashlib模块和 Neptune 的set_property函数来完成。

import hashlib
neptune.set_property('x_train_version', hashlib.md5(X_train.values).hexdigest())
neptune.set_property('y_train_version', hashlib.md5(y_train.values).hexdigest())
neptune.set_property('x_test_version', hashlib.md5(X_test.values).hexdigest())
neptune.set_property('y_test_version', hashlib.md5(y_test.values).hexdigest())

之后,您可以在项目的 details 选项卡下看到版本。

Neptune versions

版本模型二进制

您也可以使用neptune.log_artifact()将模型的各种版本保存到 Neptune,但是,由于我们使用的是neptune_callback(),所以模型会在最后一次增强迭代后自动登录到 Neptune。

我们还可以记录我们之前保存的模型。

neptune.log_artifact('classifier.pkl')

你认为你还需要的任何版本

Neptune 还提供了记录其他东西的能力,比如模型解释器和交互式图表,比如 ROC 曲线。

记录解释者是使用log_explainer函数完成的。

from neptunecontrib.api import log_explainer, log_global_explanations
import dalex as dx

expl = dx.Explainer(classification, X, y, label="XGBoost")

log_global_explanations(expl, numerical_features=["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10"])

log_explainer('explainer.pkl', expl)

这样做之后,实验的工件部分将会有经过腌制的解释器和图表。

在仪表板中组织实验

海王星允许你选择你想在仪表盘上看到什么。您可以添加或删除列。通过单击管理列,您可以向仪表板添加新列。

如果您想删除某一列,只需单击它旁边的 x 按钮。您也可以使用某列旁边的向上和向下箭头按该列进行筛选。这些按钮指示您是按升序还是降序进行过滤。

该平台还允许您将实验分组到视图中。例如,您可以选择带有特定标签的实验,并将这些实验保存为新视图。一旦你这样做了,你就可以随时访问新的视图。

与您的团队合作进行 ML 实验

你可以通过邀请你的团队合作来分享你的 Neptune 实验。

您还可以通过公开项目来与全世界共享项目。一旦项目公开,你可以自由地与任何人分享链接。

使用团队计划时,您可以与队友分享您的私人项目。该团队计划对研究、非营利组织和 Kagglers 也是免费的。

你在 Neptune app 里做什么都可以分享,比如我发个链接就可以分享我的实验对比。

以编程方式下载模型工件

使用 Neptune,您可以从您的实验中下载文件,甚至直接从您的 python 代码中下载单个项目。例如,您可以使用download_artifact方法下载单个文件。我们可以通过获取实验对象并下载该实验的所有文件来下载模型。在这种情况下,我们下载之前上传的分类器。分类器存储在我们当前工作目录的模型文件夹中。

project = neptune.init('mwitiderrick/sandbox',api_token='YOUR_TOKEN',
)
my_exp = project.get_experiments(id='SAN-21')[0]
experiment.download_artifact("classifier.pkl","model"))

当你想操作你的模型并从你的实验报告中直接获取它们时,这是很有用的。但是将模型投入生产是另外一个故事🙂

结论

希望这已经向您展示了使用 Neptune 向 XGBoost 训练脚本添加实验跟踪和模型版本控制是多么容易。

具体来说,我们讲述了如何:

设置海王星

  • 使用 Neptune 回调来记录我们的 XGBoost 培训课程
  • 分析和比较海王星的实验
  • 海王星上各种项目版本
  • 与团队成员协作
  • 从海王星下载你的神器
  • 希望有了这些信息,XGBoost 模型现在会更清晰,更易于管理。

感谢阅读!

Thanks for reading!

如何运行机器学习项目:最佳实践

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-run-machine-learning-projects-best-practices

ML 和数据科学发展迅速。在过去的几年里,在集成不同的技术和业务工作流方面已经取得了很大的进展。

如果你正在做一个商业 ML 项目,你可能会在打电话前后做很多事情。fit()和。预测()。在本文中,我们将讨论端到端项目的不同方面,通过一些简单的步骤,您可以增加项目成功的机会。

什么时候用 ML?

在创建模型之前,最好问问我们自己:

“这个问题不用 ML 能解决吗?”

意思是,一个基于规则的系统能够很好地解决问题吗?

基于规则的方法具有独特的特征。规则是透明的,易于调试。你总是知道为什么预测会出错。当决策的解释和透明度至关重要时,这些信息就派上了用场。

然而,基于规则的系统很难维护。编写规则最初看起来很简单,但是随着产品的开发,它会变得很混乱。考虑规则的维护是至关重要的,而 ML 系统可以很容易地在新的数据集上重新训练。

例如,如果您正在构建发票解析软件,最初您可能会关注特定的发票模板。在那里很容易编写规则,因为文档结构几乎是一致的。然而,一旦您增加和处理更多的发票,基于 ML 的方法更有意义,因为它容易扩展。你只需要更多的数据和/或更复杂的模型,而不是更多的工程师来编写更多的规则。

启动 ML 项目前的清单

在你写第一行代码之前,你应该对你的进度有一个好的想法。这里有一个清单可能会有所帮助:

  • 你的 ML 项目的目标是什么?为项目定义清晰的目标有助于集中注意力。例如,您可以构建一个 ML 模型来自动化信用卡审批。目的应该尽可能具体和透明。
  • 你有数据吗?这一点我怎么强调都不为过!花更多时间收集高质量数据,而不是实施最先进的模型。实际上,每当您的模型表现不佳时,很可能是由于数据问题。你的公司可能没有任何数据,比如一些早期创业公司,所以你只能依靠第三方 ML 解决方案,直到你获得数据并训练你的模型。即使有了数据,也可能没有注释,注释需要一段时间。
  • 您将如何衡量模型性能?当然,在训练您的模型时,您将跟踪准确性、精确度或任何其他感兴趣的指标。但是,请记住,这些数字并不是最终目标。您的业务度量来自项目目标。例如,网飞推荐引擎是一个 ML 模型,它增加了每个用户观看的时间,或者减少了用户什么也没看 并关闭网站访问次数。有两个级别的指标,模型指标和业务指标。
  • 基础设施真的到位了吗?机器学习是 10%机器学习,90%工程。

如上图所示,实际的 ML 代码只是整个系统的一小部分。在 ML 代码之前,我们需要考虑数据过程。这不仅仅是收集数据并将其存储在一个地方。该系统必须具有高度的容错能力。例如,如果你正在使用云服务收集数据,而服务失败了,应该有一个救援机制来避免数据丢失。

此外,ML 模型需要根据用例频繁更新。让开发人员在每次更新上花费大量时间并不是好的做法。因此,拥有系统和工具来节省时间并在整个过程中更加透明是有益的。一种方法是使用一个好的模型注册中心,它允许我们存储和管理多个经过训练的模型。有像 MLflow 和 ModelDB 这样的开源模型注册中心。对于更复杂和协作的解决方案,请检查 neptune.ai(对个人开发者免费使用)。

从 MLOps 的角度来看,使用 Docker 将您的 ML 推理代码封装起来并使用 Kubernetes 进行部署是一个很好的实践。容器化应用程序使您不必担心如何设置合适的环境,并使您能够在云中的任何地方一致地运行您的应用程序。

  • 部署要求。提前考虑部署策略通常是个好主意。云部署更好,还是边缘部署更好?延迟限制是什么?思考这些问题通常有助于决定您的模型应该有多大或多复杂。

糟糕的部署策略会降低用户体验。例如,如果你正在为一个用户生成餐馆推荐,在他/她打开应用程序的时候就这么做可能会花费很多时间。用户可能会退出应用程序。在这种情况下,当用户不活动时,可以在一夜之间生成推荐,并将它们缓存在他/她的设备上。

  • 需要可解释性吗?任何模型背后的总体目标都是获得最佳指标。通常,这是以可解释性为代价的。越复杂,我们就越不知道模型内部发生了什么。然而,我们关心的是为什么模型在某些情况下做出了特定的预测。例如,在自动贷款申请系统中,申请人想要知道为什么他们的贷款申请被拒绝。在这种情况下,更简单的带有可解释参数的模型可能更好。

训练 ML 模型后的清单

你思考了上面几节的所有问题,训练了一个模型。那现在怎么办?你只是部署它吗?

没那么快。虽然您训练模型所依据的数据是经过仔细筛选的,但是您的模型还是有办法达到一个较高的指标。例如,考虑预测图像是熊猫还是北极熊的图像分类器。你以近乎完美的准确度训练了一个模型。

模型预测(下图)–熊猫

模型预测(下图)——北极熊

模型预测(下图)——北极熊

前两个预测有道理。第三个呢?应该是熊猫。

仔细查看模型后,发现该模型不是熊猫-北极熊分类器,而是雪草分类器。它经常在绿色的丛林中看到熊猫,在雪地里看到北极熊。

同样,NLP 中的数据泄漏也很常见。如果你正在构建一个情感分类器,确保模型是从代表情感的词中学习,而不是从停用词或任何其他不相关的词中学习。像 LIME 和 Shapley 这样的库有助于解释模型预测。

但是你如何评估一个无监督的模型呢?考虑一个句子嵌入模型。该模型的目标是为语义相似的句子生成高分,为不相似的句子生成低分,并在无监督或自我监督的设置中学习所有内容。在这种情况下,有一个定制的测试套件是很好的,就像手工策划的成对的正面(相似的)和负面(不相似的)例子。这些可以作为“单元测试”用于任何模型。设计多层次的测试。简单的检查模型健全性,例如:

(很好的冰淇淋,政治领袖必须团结起来,0

这是很好的冰淇淋,这甜点棒极了!,1

A/B 测试

一旦你的模型准备好了并且正常了,就差不多是时候把它放到野外了。请记住,您的模型是在本地的受限环境中构建和测试的。但是在生产中事情可能会有所不同。因此,首先进行试运行,然后进行全面部署是至关重要的。

简而言之,A/B 测试用于评估随机设置中变量的两个选项。在我们的电影推荐示例中,我们会随机挑选几千个用户,并仅为这些用户部署新的 ML 模型。几天后,我们将新旧模型在推荐接受率、总花费时间等方面进行比较。如果新模型看起来性能更好,我们就为所有用户部署它。

根据测试的目的,一个好的 A/B 测试有许多设计考虑。

在野外测量模型性能

训练时你有标签。但是在真实环境中搅动模型预测又如何呢?很可能你看不到那里的标签。那么,你应该如何衡量一个活生生的模型的表现呢?

在进入 it 之前,我们为什么要在部署之后测量模型的性能呢?我们不是在一个采样良好的测试集上测试过吗?是的,我们确实这样做了。但是,训练数据分布可能与模型在真实环境中看到的分布有很大不同。例如,在 COVID 之前和 COVID 期间生成的推文可能在词汇、情感和主题方面有不同的分布。因此,这个模型肯定会在它没见过的数据上犯更多的错误。这被称为数据漂移

您可以跟踪一些代理指标来显示特性分布是否发生了变化。由于训练的 ML 模型在预测中是确定性的,所以数据分布的变化通过特征分布的变化来反映。此外,预测标签分布的变化也可能是警报。如果定型数据标签看到的是 40-60 分布,而模型预测的标签是 20-80 分布,那么您可能需要检查模型。

在某些情况下,监管不力是有可能的。例如,在聊天机器人中,在一些系统生成的消息之后,系统可以询问对话是否对用户有帮助。过于频繁地要求这种验证会损害用户体验。类似地,在搜索或推荐中,通过点击接受结果可以反馈给系统。这种系统可以在线重新训练。

在您检测到模型质量下降后,下一步是通过对新数据进行重新训练来恢复其性能。但是在重新训练之前有一些考虑:

您应该多久对模型进行一次再培训?取决于你期望的数据移位频率。请记住,再培训是有成本的,尤其是在再培训大型模型的时候。

应该只重新训练深度学习模型的最后几层还是整个模型?您应该使用多少旧数据和多少新数据进行再培训?

这些选择主要取决于您的用例。

偏见和公平

现代深度学习模型是黑箱。我们不知道他们真正学到了什么。一个模型通常赋予一个特征更大的重要性,使其损失最小。当一个模型更加突出某些会引起系统性偏见的词或特征时,问题就出现了。

考虑 word2vec,它可能是为数不多的著名早期语言模型之一。单词向量可以用简单的向量代数来表示语言语义。例如:

国王——男人+女人=王后

同一模型也显示了这种关系。

电脑程序员——男人+女人=家庭主妇

你注意到偏见了吗?

不久前,在谷歌图片搜索中搜索“护士”时,出现了异常多的女性图片。

另一个臭名昭著的例子是亚马逊基于 ML 的招聘系统。亚马逊设计了一种算法,从数百份简历中挑出一份工作的前 5 份简历。人们发现,该制度对女性申请人有偏见,拒绝她们的情况比男性申请人多。

这种系统给公司带来了坏名声和巨大的经济损失。如果一家银行使用 ML 来接受或拒绝贷款申请,该模型可能会对某些种族产生系统性偏见。这显然意味着银行失去了潜在客户和它创造的收入。

偏倚治疗策略

机器学习可以用来消除机器学习模型中的偏差。这类方法分为两类——使用最大似然法去除有偏差的信号,以及使用最大似然法包含减少数据集中偏差的信号。如果在数据集中包括 z 改变了模型预测,则称 ML 模型相对于附加变量 z 有偏差。

有算法被设计来检测 ML 模型中的偏差。像 IBM AI Fairness 360 这样的包提供了这些算法的开源实现。此外,像莱姆和 SHAP 这样的可解释性方法也有助于理解 ML 模型的决策过程。

另一个名为 FairML 的包使用了一个简单的想法,这个想法非常适合黑盒模型。由于模型采用特征的向量或矩阵并预测结果,如果改变特定的特征会彻底且一致地改变模型的结果,则该特征会引入一些偏差。FairML 评估输入特征的相对重要性,以检测输入数据中的偏差。根据该软件包的作者:

" FairML 利用模型压缩和四种输入排序算法来量化模型对其输入的相对预测依赖性

最近,去偏差模型的深度学习方法变得流行起来。在一种这样的方法中,为了从敏感变量 z 中消除分类器的偏差,要求模型预测任务标签 y 以及变量 z 。然而,在反向传播期间,相对于 z 的梯度被求反。因此,不是使用从 z 的梯度来减少损失,该模型现在学习更少地依赖 z

所以,这些问题是有解决办法的,你应该研究一下,以确保你的模型是公平的。

结论

总之,为业务用例开发 ML 解决方案是一个多变量的问题。

我们在本文中讨论的只是冰山一角。你的项目面临的挑战会根据你所解决的问题而有所不同。花点时间想想你的要求,然后着手执行。开始时,提前计划可能看起来很耗时,但将来会为你节省更多的时间。

参考

  1. 毫升偏差
  2. 亚马逊的招聘系统

如何扩展 ML 项目——从经验中吸取的教训

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-scale-ml-projects

在过去的十年中,机器学习负责将数据转化为组织最有价值的资产。利用 ML 应用构建商业解决方案由于计算云基础设施的进步,使用海量数据集比以往任何时候都更容易,在计算云基础设施中,您可以托管和运行 ML 算法。

在企业层面,ML 模型已被应用于支持许多不同的业务方面,从数据源集成/数据域扩充到定制服务或产品推荐、业务运营成本节约等等。

作为数据科学社区的成员,我们都喜欢在白板上对 ML 模型进行头脑风暴,然后在我们的机器上开发模型。只要数据和/或模型是可管理的,这个一般过程就可以工作。然而,大规模这样做可能会变得极具挑战性。

例如,管理和处理大量数据,选择最佳而高效的训练算法,以及最终部署和监控大规模模型,这些都不是可以在白板上解决的小事。

幸运的是,有更好的方法来扩展和加速 ML 工作负载。在这篇文章中,我将分享我和我的团队面临的最大挑战,以及从大规模 ML 项目中吸取的经验教训。具体来说,我们将讨论:

  • 什么是可伸缩性,为什么它很重要?
  • 挑战和经验教训/我在扩展 ML 项目中的最佳实践。

什么是可伸缩性,为什么它很重要?

类似于软件开发,建立一个为你和你的团队工作的 ML 模型是很容易的,但是当你需要这个模型为世界各地的人工作时,它会变得非常复杂。如今,人们期望数据团队构建可扩展的应用程序,为数百万用户、驻留在数百万地点、以合理的速度工作。

这导致了一个被称为 MLOps 的全新领域的兴起,致力于 ML 应用程序的容器化、编排和分发——所有这些都使得 ML 项目的扩展更加容易。

为什么可伸缩性很重要?用大量的数据和复杂的算法训练一个 ML 模型既耗费内存又耗费时间。通常不可能在本地计算机上完成。可伸缩性是指以经济高效的方式操作和计算庞大的数据集,这意味着处理大量数据更容易,同时还有其他好处:

在找到最佳模型之前,ML 模型开发包括大量的试验和错误。快速执行的无缝工作流将允许数据团队尝试更多想法并提高工作效率。

  • 加强模块化和团队协作

大规模模块化使得复制和重用 ML 应用程序变得容易。因此,组织内的数据科学团队可以共享和协作,而不是各自为政地创建数百条管道。

  • 促进 ML 自动化,降低成本:

具有最少人工干预的可扩展的自动化过程不仅使模型更不容易出错,而且还释放了资源来专注于更有影响力的任务。因此,扩展有助于最大限度地利用资源并降低业务成本。

现在,我们已经对 ML 可伸缩性及其给组织带来的好处有了基本的了解,让我们继续讨论我在开发可伸缩 ML 管道时面临的五个挑战,并讨论我在应对这些挑战时学到的经验。

挑战# 1——特性是最难做好的部分

ML 特征是作为系统输入的一组可测量的属性或特征。根据具体的项目,这些特征的来源可能无处不在,从存储在数据仓库中的表格数据表到人类语言和图像像素,最后到来自特征工程的衍生预测器。

为了服务于大规模的 ML 应用程序,我们需要访问和试验数十亿条记录,以创建我们的模型可以消化的有前途的特征的列表。我发现特征生成和存储的工作流程非常具有挑战性,尤其是在大规模完成时。诚然,有人可能会说,这可以通过拥有更强处理能力的机器或转向云服务器来轻松实现。

然而,以上所有只是冰山一角——对我的团队来说,最具挑战性的部分总是在模型在生产中实现的时候。在如此大的范围内,我们如何计算和连续监控特征以确保它们的统计属性保持相对稳定?最重要的是,随着更多的观察不断增加,我们如何存储这些特征以确保我们的模型在这个不断增长的数据集上得到适当的训练?

为了增加另一层挑战,一旦模型#1 投入生产,下一个模型出现,我的团队需要再次进行大规模的特征处理,因为它嵌入在之前的培训工作中。你可以想象这个 ML 基础设施导致了多少重复的工作!

经验教训

考虑到所有这些数据特征挑战,我的团队开始探索使用(大规模)特征商店的可能性,这是由优步的米开朗基罗平台在 2017 年引入的概念。一个特征库被称为一个集中的操作数据管理系统,它允许数据团队存储、共享和重用 ML 项目的策划特征。

Scaling ML projects - Feature store

Feature Store as an important part of ML scalability | Souce

人们普遍认为有两种类型的 ML 特性:离线和在线。离线特性主要用于离线批量操作,一般存储在传统的数据仓库中。相反,在线特性需要(近)实时计算和服务,并存储在键值格式的数据库中,以便快速查找值。大规模的特征存储,例如 Redis,具有支持(离线)批处理和(在线)低延迟服务的能力。

从模型监控的角度来看,要素存储以时间一致的方式维护所有历史数据以及最新值。这使得比较特征值和模型性能就像 API 调用一样简单。

此外,要素存储还有助于最大限度地减少重复工作,因为组织内的内部数据团队可以轻松访问存储在此集中位置的所有可用要素。一些数据科学专家甚至说,未来几年将是功能商店的时代。

挑战 2—数据科学编程语言可能会很慢,选择合适的处理器至关重要

一旦要素/输入预测值可供访问和使用(可能在要素存储中),数据科学团队将启动模型开发流程。

大多数 ML 应用程序是用 Python 或 R 编写的,这是数据科学家中最流行的语言。对于我们的团队以及其他很多人来说,我们经常使用多种语言的组合来构建模型。

尽管我很喜欢用 Python 和 R 编写代码,但我不得不指出,出于速度的考虑,大规模的 ML 模型很少用这些语言进行产品化。与 Python 和 R 相比,更快的生产语言如 C/C++或 Java 更受青睐(与软件开发场景相同)。因此,将 Python 或 R 模型包装成 C/C++或 Java 给我们的团队带来了另一个挑战。

除了编程语言,还需要强大的处理器来执行迭代、繁重的计算操作。这使得硬件成为 ML 可扩展性中最关键的决策之一,尤其是关注矩阵乘法的快速执行。

经验教训

一句话:就大规模的 ML 应用程序而言,Java 可能不是最好的语言,CPU 也可能不是最优的!

Java 被认为是顶级的 ML 生产语言,主要是因为从业者认为它比 Python 或 r 执行得更快。Python 或 R 中的 ML 包经过优化,集成了 C/C++上的包装函数,这使得计算速度比原生 Java 更快。

同样的计算速度,从我的经验来看,由于顺序处理的性质,CPU 对于大规模的 ML 模型来说远非最佳。对于可能受益于并行处理的计算,GPU 是一个很好的选择。

Scaling ML projects - CPU GPU TPU

CPUs are far from optimal for ML models at scale due to their sequential processing nature |Source

另一个进步是 ASICs(专用集成芯片),例如,谷歌的 TPUs(张量处理单元)。为了降低计算复杂度和节省成本,TPU 被专门设计成在不访问存储器的情况下执行矩阵乘法。事实上,一个简单的 TPU 初始化是我的团队坚持使用 Google Tensorflow 框架的部分原因,即使考虑到不同版本 tensor flow 臭名昭著的兼容性问题。

挑战 3–分析数据太大和/或 ML 算法太复杂,单台机器无法处理

我的团队从事的项目之一是开发大规模图像分类算法。对于像这样有大规模数据和模型的项目,在单台计算机上进行 ML 的传统方法不再有效。这导致了分布式 ML 的解决方案,它可以以计算和内存可扩展的方式处理大数据和复杂算法。分布式 ML 背后的想法很直观:如果我们的算法不能在单个节点上完成,我们可以将计算工作量分布在多个节点上。

与分布式 ML 相关的一个概念是并行性或并行处理,它既指数据(处理)并行性,也指算法(构建)并行性。通过划分数据或 ML 模型并将计算工作分配给不同的工作人员,我们可以同时利用多个内核来获得更快的性能。事实上,在我们的图像分类项目中,我们能够通过分布式 ML 算法获得 10 倍的速度提升。

Scaling ML projects - parallelism

Parallelism cans work with big data and complex algorithms in a computation- and memory-scalable way | Source

最流行的开源分布式 ML 框架之一是 Apache Hadoop ,它提供了几种编程语言的 MapReduce API。另一个流行的是 Apache Spark ,它可以用来执行更快的内存计算。

就实现而言,大多数成熟的 ML 框架,如 TensorflowPyTorch ,提供 API 来执行分布式计算,以便您的团队开始使用。

经验教训

一般来说,分布式 ML 工作有效,尤其是数据并行。然而,就算法/模型并行性而言,它可能无法正常工作。

算法并行,在 ML 应用的背景下,主要是关于矩阵操作。对于多个工人同时计算,我们需要将一个巨大的矩阵分成几个更小的部分,将几个分配给每个工人,最后通过工人之间的通信将结果收集回来。最后一步称为同步。在某些情况下,同步可能比分布式计算本身需要更长的时间,因为工作人员通常不会在同一时间完成。

正因为如此,线性可伸缩性(获得与增加的资源百分比相同的性能增加百分比的能力)几乎从未在真正的 ML 项目中发生过(至少从我的经验来看)。

您可能希望花费额外的时间和精力来检查同步后的输出,以确保您的分布式系统的正确配置和 ML 应用程序的收敛。

挑战# 4——ML 部署的框架版本和依赖性问题

问问任何一位已经启动大规模 ML 应用的数据科学家,他们面临的最大挑战是什么。有可能包版本和依赖地狱会是其中之一,我们的团队也不例外。

当我们部署一个 ML 应用程序时,首先,我们必须确保产品化的模型一致地再现它的训练对应物。当 ML 模型涉及大量数据和/或复杂算法时,这一点尤为重要,因为它们可能需要更长的训练时间,并且如果出现任何问题,调试起来也更加困难。

对于我们的团队来说,包版本和依赖性问题是我们的 ML 模型在生产中运行时失败的主要原因。此外,由于对软件包版本的要求,我们过去在每个虚拟机上只托管一个产品化模型。

经验教训

如果你问软件开发人员,就编写大型程序而言,他们的最佳实践是什么,很可能将你的代码分成块是其中之一。

将这个想法应用到 ML 部署中,我建议利用 Docker 容器 ,将所有与模型相关的东西捆绑到一个运行在云中的包中。

Scaling ML projects - Docker

We can scale up ML using Docker | Source

讨论如何使用 Docker 扩展 ML 超出了本博客的范围。尽管如此,值得强调的是,Docker 容器让我的团队可以在同一个容器环境中运行大规模的工作,并在同一台机器上部署多个应用程序实例。

作为一个旁注/提示,所有的 Docker 图片并不都是一样的。谷歌的 Tensorflow Docker images 经过了高度的性能优化,PyTorch 在 Tensorflow 图像中的运行速度要快于它们自己的 PyTorch 图像。当您为下一个大型 ML 应用程序选择数据科学框架时,这可能会很有用。

我们目前正在探索的另一个基础设施是微服务,这是一种使 ML 应用部署变得可访问的架构。我们将为 ML 管道的每个会话创建一个单独的微服务,这些微服务可以通过 RESTful APIs 访问。这将使我们的大型应用程序更有组织性和可管理性。

挑战# 5——大型 ML 应用从来都不是一次性交易,它需要高效的优化方法来通过迭代过程进行微调或再培训

我们已经建立了一个很好的模型并投入生产。现在是我们打开香槟瓶塞庆祝任务完成的时候了,对吗?很不幸,还没有。

这只是万里长征的第一步!随着我们的组织随着时间的推移获取新数据(在模型部署之后),我们的应用程序将需要频繁的微调和再培训。

为了解决这个问题,我的团队提出了一个解决方案,当数据漂移(样本的统计属性发生变化)时,可以实现自动模型再训练。对于大规模的 ML 应用,由于时间和计算的高成本,模型调整或再训练可能是具有挑战性的;更不用说这是定期进行的。

诚然,ML 模型再训练的核心部分在于超参数调整。因此,选择和建立有效的超参数调整算法将是有益的。它将使我们能够使用更少的计算时间和成本实现高质量的模型,这是大规模 ML 应用程序的一个主要目标。

经验教训

在超参数搜索方法方面,有几种选择:随机搜索、网格搜索和 贝叶斯优化 。从我的经验来看,对于大规模的 ML 应用,贝叶斯优化优于网格搜索和随机搜索;数据集/参数网格越大,潜在的效率增益就越高。

The core component of ML model retraining lies in hyper-parameter tuning and it’s crucial for  ML applications at scale | Source

这不应该令人惊讶,因为贝叶斯优化基本上是一种智能搜索策略,其中下一个超参数是以一种知情的方式选择的。它有助于减少最佳超参数组合的搜索时间。

挑战 吸取的教训

特性是最难得到正确的组件

|

特征库为 ML 可扩展性提供特征存储、服务和管理支持

|
|

数据科学编程语言可能会很慢,选择合适的处理器至关重要

|

相对于 CPU

,GPU 和 TPU 是并行处理和复杂矩阵操作的更好选择 |
|

分析数据太大和/或 ML 算法太复杂,单台机器无法处理

|

分布式 ML 通过利用多个工人有效地工作

|
|

框架版本与 ML 部署的依赖问题

|

Docker 容器保持 ML 应用的封装,从而在所有部署环境中保持一致,便于扩展

|
|

大型 ML 应用从来都不是一蹴而就的,它需要高效的优化方法来通过迭代过程进行微调或再培训

| |

作为一个额外的提示,在整个组织中扩展性能良好的 ML 应用程序永远不可能通过筒仓工作来实现。它需要相互联系和协作的努力。数据科学、数据工程、数据架构师、DevOps 和所有其他相关团队之间的参与和沟通对于识别 ML 应用不同阶段的潜在风险至关重要。此外,预先定义角色和职责以避免跨 ML 管道的重复工作同样重要。

扩展 ML 应用程序并不容易!希望我在这篇文章中的经验和教训能让你的大规模 ML 应用之旅变得容易一些。感谢您的阅读!

如何用 TensorFlow 服务和 Docker 服务机器学习模型

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-serve-machine-learning-models-with-tensorflow-serving-and-docker

机器学习(ML)有可能极大地改善业务,但这只有在模型投入生产并且用户可以与之互动的情况下才能实现。

亚马逊微软谷歌苹果脸书这样的全球性公司,都有数百款 ML 机型在生产。从更好的搜索推荐引擎,到数据中心冷却费用降低 40%,这些公司已经开始在他们业务的许多关键方面依赖 ML。将模型投入生产并不是一件容易的事情,虽然该过程与传统软件相似,但它有一些微妙的差异,如模型再训练、数据偏斜或数据漂移,这些都应该考虑在内。

放置 ML 模型的过程不是一个单一的任务,而是许多子任务的组合,每个子任务都有其自身的重要性。这样的子任务之一是模型服务。

“模型服务就是展示一个经过训练的模型,以便端点可以访问它。这里的端点可以是直接用户或其他软件。

在本教程中,我将向您展示如何使用 Tensorflow Serving 来服务 ML 模型,这是一个高效、灵活、高性能的机器学习模型服务系统,专为生产环境而设计。

具体来说,您将学习:

  • 如何使用 docker 安装 Tensorflow 服务
  • 用 Tensorflow 训练并保存一个简单的图像分类器
  • 使用 Tensorflow 服务服务保存的模型

在本教程结束时,您将能够获取任何保存的 Tensorflow 模型,并使其可供其他人使用。

开始之前(先决条件)

为了充分理解本教程,假设您:

以下是一些帮助您开始的链接:

现在简单说一下 Tensorflow 发球(TF 发球)。

Tensorflow 服务简介

“TensorFlow 服务是一个灵活、高性能的机器学习模型服务系统,专为生产环境而设计。TensorFlow 服务使部署新算法和实验变得容易,同时保持相同的服务器架构和 API。TensorFlow 服务提供与 TensorFlow 模型的现成集成,但可以轻松扩展以服务于其他类型的模型。”
来源

简单地说,TF Serving 允许您通过模型服务器轻松地公开一个经过训练的模型。它提供了一个灵活的 API,可以很容易地与现有系统集成。

大多数模型服务教程展示了如何使用 Flask 或 Django 构建的 web 应用程序作为模型服务器。虽然这对于演示来说没问题,但在生产场景中效率非常低。

根据 Oreily 的“构建机器学习管道”一书,你不应该依赖传统 web 应用来服务 ML 模型的一些原因包括:

  1. 缺乏有效的模型版本控制:对经过训练的模型进行正确的版本控制非常重要,而大多数为服务模型而构建的 web 应用程序可能会错过这一部分,或者如果存在的话,管理起来可能会非常复杂。
  2. 缺乏代码分离:数据科学/机器学习代码变得与软件/DevOps 代码交织在一起。这很糟糕,因为数据科学团队与软件/DevOps 团队有很大的不同,因此,当两个团队在相同的代码库上工作时,适当的代码管理会成为一种负担。
  3. 低效的模型推理:用 Flask/Django 构建的 web apps 中的模型推理通常是低效的。

Tensorflow 服务为您解决了这些问题。它处理模型服务、版本管理,让您基于策略服务模型,并允许您从不同的源加载您的模型。它在谷歌和世界各地的许多组织内部使用。

您是否知道,由于 TensorFlow + Neptune 集成,您可以跟踪您的模型训练?在我们的文档中了解更多信息。

张量流服务架构

在下图中,您可以看到 TF 服务架构的概述。这个高级架构显示了构成 TF 服务的重要组件。

tensorflow serving

Overview of the TensorFlow Serving architecture (Source)

在上图中从右到左,让我们从模型源开始:

  • 模型源提供插件和功能来帮助你从多个位置(例如 GCS 或 AWS S3 桶)加载模型或 TF 服务术语服务。一旦模型被加载,下一个组件——模型加载器——就会得到通知。
  • 模型加载器提供了从给定的源加载模型的功能,与模型类型无关,甚至与用例的数据类型无关。简而言之,模型加载器提供了从源代码加载和卸载模型(可服务的)的有效功能。
  • 模型管理器处理模型的整个生命周期。也就是说,它管理何时进行模型更新、使用哪个版本的模型进行推理、推理的规则和策略等等。
  • Servable 处理程序提供了与 TF 服务通信所必需的 API 和接口。TF serving 提供了两种重要的可服务处理程序——RESTgRPC 。在本教程的后面部分,您将了解这两者之间的区别。

有关 TS 架构的更多详细信息,请访问下面的官方指南:

在下一节中,我将绕一点弯路来快速介绍 Docker。这是一个可选部分,我在这里介绍它是因为在安装 TF Serving 时您将使用 Docker。

Docker 简介和安装指南

Docker 是一个计算机程序,它使开发者能够以一种在另一台机器上容易复制的方式轻松打包应用程序或软件。Docker 使用容器,它允许您将应用程序及其库和依赖项打包成一个单独的包,可以在另一个环境中部署。

Docker 类似于虚拟机,只有一些细微的区别,其中之一是 Docker 使用相同的操作系统,而 VMs 使用不同的操作系统实例来将应用程序相互隔离。

Containerized Application

Containerized Application (Source)

虽然我不会深入研究 Docker,但我会带您安装它并提取一个简单的 hello world Docker 映像。

首先,为您的操作系统下载并安装 Docker:

通过各自的安装程序下载并安装 Docker 后,在终端/命令提示符下运行以下命令,以确认 Docker 已成功安装:

 docker run hello-world

它应该输出:

Unable to find image ‘hello-world:latest’ locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the “hello-world” image from the Docker Hub. (amd64)
3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal.

如果您得到上面的输出,那么 Docker 已经成功安装在您的系统上。

安装 Tensorflow 服务

现在您已经正确安装了 Docker,您将使用它来下载 TF Serving。

没有 Docker 也可以安装 Tensorflow Serving,但是推荐使用 Docker,而且肯定是最简单的。

在您的终端中运行以下命令:

docker pull tensorflow/serving

这需要一些时间,完成后,将从 Docker Hub 下载 Tensorflow 服务图像。

如果您在具有 GPU 的实例上运行 Docker,您也可以安装 GPU 版本:

docker pull tensorflow/serving:latest-gpu

恭喜你。Tensorflow 服务已安装。在下一节中,您将使用 TensorFlow Keras 训练并保存一个简单的图像分类器。

构建、训练和保存影像分类模型

为了演示模型服务,您将使用 Tensorflow 为手写数字创建一个简单的图像分类器。如果您没有安装 TensorFlow,请在此处遵循本指南

这不是一个模型优化教程,因此重点是简单性。因此,您不会进行任何大范围的超参数调整,并且构建的模型可能不是最佳的。

MNIST 手写数字分类数据集是一个非常流行的图像分类任务。它包含人类手写的数字,任务是将这些数字分类为 0 到 9 之间的数字。因为数据集非常受欢迎,Tensorflow 预装了它,因此,您可以轻松地加载它。

Handwritten dataset

* MNIST Handwritten dataset (Source)*

下面,我将指导您加载数据集,然后构建一个简单的深度学习分类器。

步骤 1: 创建一个新的项目目录,并在代码编辑器中打开它。我调用我的 tf-server,,并在 VsCode 中打开它。

第二步:在项目文件夹中,创建一个名为 model.py,的新脚本,并粘贴下面的代码:

import matplotlib.pyplot as plt
import time
from numpy import asarray
from numpy import unique
from numpy import argmax
from tensorflow.keras.datasets.mnist import load_data
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import MaxPool2D
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dropout

(x_train, y_train), (x_test, y_test) = load_data()
print(f'Train: X={x_train.shape}, y={y_train.shape}')
print(f'Test: X={x_test.shape}, y={y_test.shape}')

x_train = x_train.reshape((x_train.shape[0], x_train.shape[1], x_train.shape[2], 1))
x_test = x_test.reshape((x_test.shape[0], x_test.shape[1], x_test.shape[2], 1))

x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0

input_shape = x_train.shape[1:]

n_classes = len(unique(y_train))

model = Sequential()
model.add(Conv2D(64, (3,3), activation='relu', input_shape=input_shape))
model.add(MaxPool2D((2, 2)))
model.add(Conv2D(32, (3,3), activation='relu'))
model.add(MaxPool2D((2, 2)))
model.add(Flatten())
model.add(Dense(50, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(n_classes, activation='softmax'))

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit(x_train, y_train, epochs=10, batch_size=128, verbose=1)

loss, acc = model.evaluate(x_test, y_test, verbose=0)
print('Accuracy: %.3f' % acc)

ts = int(time.time())
file_path = f"./img_classifier/{ts}/"
model.save(filepath=file_path, save_format='tf')

上面的代码非常简单,首先,导入将要使用的必要包,并加载预先打包了 Tensorflow 的 MNIST 数据集。然后,您将数据整形为使用单通道(黑白),然后通过除以 1/255.0 进行归一化。

接下来,您创建一个简单的卷积神经网络(CNN ),在输出端有 9 个类,因为您要预测 10 个类(0–9)。然后,通过指定优化器、损失函数和指标来编译模型。

接下来,使用 128 的批量大小来拟合 10 个时期的模型。拟合后,你在测试数据上评估,打印精度,最后保存模型。

保存模型的代码是基于时间戳的。这是一个很好的做法,强烈推荐。

您可以检查文件夹中保存的模型。它应该类似于下图所示:

├── img_classifier
│ ├── 1600788643
│ │ ├── assets
│ │ ├── saved_model.pb
│ │ └── variables

使用 Tensorflow 服务服务保存的模型

一旦保存了模型,并且 Docker 正确安装了 Tensorflow Serving ,您就可以将其作为 API 端点。

值得一提的是,Tensorflow 服务支持两种类型的 API 端点— REST 和 gRPC。

  • REST 是 web 应用使用的一种通信“协议”。它定义了客户端如何与 web 服务通信的通信方式。REST 客户机使用标准的 HTTP 方法(如 GET、POST、DELETE 等)与服务器通信。请求的有效负载大多以 JSON 格式编码
  • gRPC 另一方面是最初在谷歌开发的通信协议。gRPC 使用的标准数据格式称为协议缓冲区。gRPC 提供了低延迟的通信和比 REST 更小的负载,在推理过程中处理非常大的文件时是首选。

在本教程中,您将使用 REST 端点,因为它更容易使用和检查。还应该注意的是,Tensorflow 服务将在您运行它时提供两个端点,因此您不需要担心额外的配置和设置。

按照以下步骤为您的模型提供服务:

首先在你的项目文件夹中,打开一个终端,并在下面添加 Docker 命令:

docker run -p 8501:8501 --name tfserving_classifier
--mount type=bind,source=/Users/tf-server/img_classifier/,target=/models/img_classifier
-e MODEL_NAME=img_classifier -t tensorflow/serving

让我们来理解每一个论点:

  • -p 8501:8501: 这是 REST 端点端口。每个预测请求都将发送到该端口。例如,您可以向 http://localhost:8501 发出一个预测请求。
  • —名称 tfserving_classifier: 这是给予运行 tfserving 的 Docker 容器的名称。它可用于稍后启动和停止容器实例。
  • — mount type=bind,source =/Users/TF-server/img _ classifier/,target =/models/img _ classifier:mount 命令只是将模型从指定路径(/Users/TF-server/img _ classifier/)复制到 Docker 容器( /models/img_classifier )中,这样 TF Serving 就可以访问它了。

如果遇到路径错误:

docker:来自守护程序的错误响应:类型“bind”的挂载配置无效:绑定源路径不存在:/User/TF-server/img _ classifier/。

然后指定模型文件夹的完整路径。记住,不是模型本身,而是模型文件夹。

  • -e MODEL _ NAME = img _ classifier:要运行的模型名称。这是您用来保存模型的名称。
  • -t tensorflow/serving: 要运行的 TF Serving Docker 容器。

运行上面的命令启动 Docker 容器,TF Serving 公开 gRPC (0.0.0.0:8500)和 REST (localhost:8501)端点。

既然端点已经启动并运行,您可以通过 HTTP 请求对它进行推理调用。下面我们来演示一下。

在您的项目文件夹中创建一个名为 predict.py,的新脚本,并添加以下代码行来导入一些包:

import matplotlib.pyplot as plt
import requests
import json
import numpy as np
from tensorflow.keras.datasets.mnist import load_data

requests 包用于构造 HTTP 调用并将其发送到服务器,而 json 包将用于在发送数据(图像)之前对其进行解析。

接下来,您将加载数据并对其进行预处理:

(_, _), (x_test, y_test) = load_data()

x_test = x_test.reshape((x_test.shape[0], x_test.shape[1], x_test.shape[2], 1))

x_test = x_test.astype('float32') / 255.0

注意,我们只关心这里的测试数据。您将加载它,并执行您在模型训练期间添加的相同预处理步骤。

接下来,定义 REST 端点 URL:

url = 'http://localhost:8501/v1/models/img_classifier:predict'

预测 URL 由几个重要部分组成。一般结构可能如下所示:

http://{ HOST }:{ PORT }/v1/models/{ MODEL _ NAME }:{ VERB }

  • 主机:您的模型服务器的域名或 IP 地址
  • 端口:你的 URL 的服务器端口。默认情况下,TF Serving 对 REST 端点使用 8501。
  • MODEL_NAME :你服务的模特的名字。
  • 动词:动词与你的模特签名有关。您可以指定预测分类回归之一。

接下来,添加一个向端点发出请求的函数:

def make_prediction(instances):
   data = json.dumps({"signature_name": "serving_default", "instances": instances.tolist()})
   headers = {"content-type": "application/json"}
   json_response = requests.post(url, data=data, headers=headers)
   predictions = json.loads(json_response.text)['predictions']
   return predictions

在上面的预测代码中,首先定义一个 JSON 数据负载。TF Serving 期望数据为 JSON,格式为:

{ "签名 _ 名称":"<字符串>",
"实例":<值> }

签名名”是可选的,可以忽略。“实例”另一方面是您想要预测的数据/输入/实例。你应该把它作为一个列表来传递。

构造完参数后,您向端点发送一个请求,并加载返回的响应。

为了测试这一点,您将对 4 幅测试图像进行预测,如下所示:

要运行 predict.py 文件,在新的终端窗口中运行python predict.py之前,确保 TF 服务容器仍然是活动的。

predictions = make_prediction(x_test[0:4])

//output
[[1.55789715e-12, 1.01289466e-08, 1.07480628e-06, 1.951177e-08, 1.01430878e-10,
5.59054842e-12, 1.90570039e-17, 0.999998927, 4.16908175e-10, 5.94038907e-09],
[6.92498414e-09, 1.17453965e-07, 0.999999762, 5.34944755e-09, 2.81366846e-10,
1.96253143e-13, 9.2470593e-08, 3.83119664e-12, 5.33368405e-10, 1.53420621e-14],
[3.00994889e-11, 0.999996185, 4.14686845e-08, 3.98606517e-08, 3.23575978e-06,
1.82125728e-08, 2.17237588e-08, 1.60862257e-07, 2.42824342e-07, 4.56675897e-09],
[0.999992132, 5.11100086e-11, 2.94807769e-08, 1.22479553e-11, 1.47668822e-09,
4.50467552e-10, 7.61841738e-06, 2.56232635e-08, 6.94065747e-08, 2.13664606e-07]] 

这将返回一个与您预测的 4 幅图像相对应的 4x 10 数组,以及每个类别的概率值(0–9)。

要获得实际的预测类,可以使用如下所示的“np.argmax”函数:

for pred in predictions:
    print(np.argmax(pred))

 7
2
1
0 

您还可以通过与真实值进行比较来检查预测的正确程度,如下所示:

for i, pred in enumerate(predictions):
    print(f"True Value: {y_test[i]}, Predicted Value: {np.argmax(pred)}")

//output
True Value: 7, Predicted Value: 7
True Value: 2, Predicted Value: 2
True Value: 1, Predicted Value: 1
True Value: 0, Predicted Value: 0

predict.py 的完整代码如下所示:

import matplotlib.pyplot as plt
import requests
import base64
import json
import numpy as np
from tensorflow.keras.datasets.mnist import load_data

(_, _), (x_test, y_test) = load_data()

x_test = x_test.reshape((x_test.shape[0], x_test.shape[1], x_test.shape[2], 1))

x_test = x_test.astype('float32') / 255.0

url = 'http://localhost:8501/v1/models/img_classifier:predict'

def make_prediction(instances):
   data = json.dumps({"signature_name": "serving_default", "instances": instances.tolist()})
   headers = {"content-type": "application/json"}
   json_response = requests.post(url, data=data, headers=headers)
   predictions = json.loads(json_response.text)['predictions']
   return predictions

predictions = make_prediction(x_test[0:4])

for i, pred in enumerate(predictions):
   print(f"True Value: {y_test[i]}, Predicted Value: {np.argmax(pred)}")

就是这样!您已经能够:

  • 保存一个训练好的模型,
  • 启动 TF 服务服务器,
  • 并向其发送预测请求。

TF Serving 为您处理所有的模型和 API 基础设施,以便您可以专注于模型优化。

请注意,一旦新模型出现在 model 文件夹中,TF serving 就会自动加载它。例如,更改模型的一些参数,如历元大小,然后重新训练模型。

一旦训练完成并且您保存了模型,TF Serving 会自动检测这个新模型,卸载旧模型,并加载新版本。

模型的自动热交换非常有效,并且可以很容易地内置到 ML CI/CD 管道中,这样您就可以更专注于模型优化,而不是模型服务基础设施。

使用 Tensorflow 服务的最佳实践

  • 通过 Docker 容器使用 TF 服务是明智的,也更容易,因为这可以很容易地与现有系统集成。如果需要更多的自定义构建或安装,可以从源代码构建 TF Serving。跟随向导到这里
  • 在推理过程中处理大型数据集时,使用 gRPC 作为端点会更有效。另外,请参见在 Kubernetes 上设置 TF 服务。
  • 在 Docker 运行阶段加载模型时,可能会出现路径错误。您可以通过指定完整路径而不是绝对路径来解决这个问题。
  • 建议将 TF 引入 TFX 管道。这样模特在由 TF 上菜前会被自动审查
  • 有时,默认端口 8501 可能不可用或被其他系统进程使用,您可以在运行 Docker 映像时轻松地将其更改为另一个端口。

结论

在本教程中,您学习了如何:

  • 通过 Docker 安装 Tensorflow 服务
  • 训练并保存张量流图像分类器
  • 通过 REST 端点服务保存的模型
  • 通过 TF 服务端点使用模型进行推理

有了这些知识,您就可以为生产环境构建高效的模型管道,不仅可以伸缩,而且可以适当伸缩!

链接到 Github 上的项目代码

如何解决 ML 中的再现性

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-solve-reproducibility-in-ml

有可能你遇到了一篇机器学习论文,并试图复制它,却发现你得到了非常不同的结果。你调整你的代码,但总是出错。此时,您正在怀疑自己作为数据科学家的技能,但是不要担心。我在这里告诉你,这完全没关系,这不是你的错!

这是再现性挑战经典案例,不是机器学习独有的问题。

在科学中,再现性是科学方法的一个主要原则。它表明,从实验或研究中获得的结果或观察结果应该用相同的方法但由不同的研究人员重复,并且这些不同的研究人员获得的结果必须与原始研究人员获得的结果相似。因为一个结果只有在不同的研究团队成功复制几次之后才能成为科学事实。

但是,让我们回到机器学习。ML 中的再现性到底是什么意思?

机器学习中的再现性是什么?

机器学习的可重复性意味着你可以在某些数据集上重复运行你的算法,并在特定项目上获得相同(或相似)的结果

机器学习中的可再现性意味着能够复制在论文、文章或教程中执行的 ML 编排,并获得与原始工作相同或相似的结果。

大多数 ML 编排通常是端到端的,我指的是从数据处理到模型设计、报告、模型分析或评估到成功部署。

能够复制结果是非常重要的,因为这意味着项目是可扩展的,并准备好推动大规模部署的生产。

再现性来之不易。复杂的挑战使得从论文中复制 ML 结果看起来几乎是不可能的,我们马上就要探索这些挑战。

可以说,机器学习中的再现性取决于任何模型的三个核心要素:

代码:为了实现可重复性,你必须在实验过程中跟踪并记录代码和算法的变化。

数据:添加新数据集、数据分布和样本变化都会影响模型的结果。必须记录数据集版本和变更跟踪,以实现可再现性。

环境:对于一个可重现的项目,必须捕获构建它的环境。必须记录框架依赖性、版本、使用的硬件以及环境的所有其他部分,并且易于重现。我们的环境应符合以下标准:

  • 使用最新的库和文档版本,
  • 能够在不破坏设置的情况下返回到先前状态,
  • 在多台机器上使用相同的版本,
  • 设置随机化参数,
  • 使用所有可用的计算能力。

这三个核心元素结合在一起就构成了你的模型。这三者之间的桥梁就是所谓的 ML 管道。

现在我们已经讨论了这些元素,让我们继续讨论机器学习中的再现性挑战。

机器学习中的再现性挑战

1.缺少记录

这可以说是 ML 中可重复实验的最大挑战。当输入和新的决策没有被记录时,通常很难复制所取得的结果。在试验过程中,超参数值、批量大小等参数会发生变化。如果没有这些参数变化的适当记录,理解和复制模型将变得困难。

2.数据的变化

当原始工作的数据被改变时,几乎不可能得到相同的结果。例如,在获得结果后,当新的训练数据被添加到数据集时,不可能获得相同的结果。

数据集上不正确的数据转换(清理等)、数据分布的变化等也会影响再现性的机会。

3.超参数不一致性

当默认的超参数在实验过程中被改变并且没有被正确记录时,它们将产生不同的结果。

4.随机性

ML 充满了随机化,尤其是在发生大量随机化的项目中(随机初始化、随机噪声引入、随机增强、选择隐藏层、丢弃、混洗数据等)。

5.实验

机器学习是实验性的,开发一个模型需要大量的迭代。算法、数据、环境、参数等的变化都是模型构建过程的一部分,虽然这很好,但它会带来丢失重要细节的困难。

6.ML 框架的变化

ML 框架和库在不断升级,用于实现某个特定结果的特定库版本可能不再可用。这些更新可能会导致结果发生变化。例如,Pytorch 1.7+支持来自 NVIDIA 的 apex 库的混合精度,但以前的版本不支持。

此外,从一个框架转换到另一个框架(比如从 Tensorflow 转换到 Pytorch)会产生不同的结果。

7.GPU 浮点差异

再现性的另一个挑战是由于硬件设置、软件设置或编译器而导致的与浮点不同的结果。GPU 架构的变化也使得再现性变得不可能,除非强制执行其中的一些操作。

8.非确定性算法

非确定性算法中,不同运行时同类输入的输出是不同的,这带来了更大的再现性挑战。在深度学习算法中,如随机梯度下降、蒙特卡罗方法等,在实验过程中经常会出现不确定性。深度强化学习也容易受到非确定性的影响,代理从某种程度上不稳定的经验分布中学习,这种学习大多数时候受到非确定性环境和非确定性策略的影响。不确定性的其他来源是 GPU、随机网络初始化和小批量采样。

为了应对这些挑战,我们这些数据科学家必须能够:

  1. 跟踪实验过程中代码、数据和环境的变化。
  2. 记录实验中使用的所有代码参数、数据和环境。
  3. 重用实验中使用的所有代码参数、数据和环境。

现在,让我们来看看解决重现性挑战的解决方案和工具。

1.实验跟踪和记录

模型训练是一个迭代的过程,改变参数的值,检查每个算法的性能,并对其进行微调以获得理想的结果等。在这个过程中,如果没有适当的记录,细节将会丢失,就像他们说的“美在细节中”。

在模型训练和实验期间,你需要能够跟踪发生的每一个变化。让我们来看看一些工具:

  • 通过 DVC ,dvc exp 命令跟踪项目的每一个度量,它有一个度量列表,其中存储了度量值以跟踪进度。因此,您可以使用自动版本控制和检查点日志记录来跟踪您的实验。比较参数、度量、代码和数据的差异。应用、删除、回滚、恢复或共享任何实验。

点击这里查看更多关于 DVC 实验的实用介绍。

了解更多信息

检查如何以自动化的方式版本化你的代码和数据

  • MLflow Tracking 使用 mlflow.autolog()函数自动跟踪和记录每个模型运行和部署的参数、指标和代码版本。这必须在培训之前完成,它可以在本地和远程保存每个实验日志。

  • Pachyderm 自动报告匿名使用指标。它还跟踪模型开发过程中使用的所有代码和数据。

  • WandB 允许您跟踪实验,提供一个仪表板,您可以在其中实时可视化实验,并允许您记录超参数和每次实验运行的输出指标。

  • Comet 帮助数据科学团队跟踪实验代码、指标依赖等。它还有助于在模型的生命周期中比较、解释和优化实验指标和模型。

了解更多信息

你可以在这里获得更多你的 ml 追踪的追踪工具-> 15 个追踪机器学习实验的最佳工具。

2.元数据储存库

机器学习中的元数据是描述数据集、计算环境和模型的信息。ML 再现性取决于此,如果不记录和存储元数据,就无法重新创建实验。一些流行的工具可以帮助你记录和跟踪任何元数据和元数据的变化:

  • DVC 通过创建元文件作为指向存储的数据集和模型的指针来进行数据和模型版本控制。这些图元文件是使用 Git 处理的。
  • Neptune 有一个可定制的 UI,允许你比较和查询你所有的 MLOps 元数据。
  • TensorFlow Extended (TFX) 使用 ML 元数据(MLMD) 库存储元数据,并使用 API 从存储后端记录和检索元数据;它也有现成的 SQLite 和 MySQL 的参考实现。
  • Kubeflow 元数据存储库帮助数据科学家跟踪和管理其工作流程产生的大量元数据。

阅读更多

要了解有关元数据工具的更多信息,请查看此处-> 最佳元数据存储解决方案

3.艺术品商店

机器学习中的工件是描述完全训练的模型的训练过程的输出的数据,或者用 ML 术语来说,模型检查点。工件存储记录了模型中的每个检查点。管理和存储每一个模型检查点在可再现性上是很重要的,因为工件使得模型很容易被 ML 团队成员复制和验证。工具,例如:

  • DVC 可以从项目外部访问数据工件,以及如何从另一个 DVC 项目导入数据工件。这有助于将特定版本的 ML 模型下载到部署服务器,或者将模型导入到另一个项目中。
  • Neptune 存储 ML 工件,例如到数据集或模型的路径(s3 桶、文件系统)、数据集散列/预测预览(表头、图像文件夹的快照)、描述、谁创建/修改、上次修改时间、数据集大小等。
  • Amazon Sagemaker 提供了一个模型工件存储,它存储了模型的 s3 存储桶位置,其中包含了关于模型类型和内容的信息。Amazon Sagemaker 也为 AutoML 实验存储工件。
  • Kubeflow 也将工件数据存储在其工件存储中;它使用工件来理解各种 Kubeflow 组件的管道是如何工作的。Kubeflow Pipeline 可以输出工件数据的简单文本视图和丰富的交互式可视化
  • WandB 允许您使用下面的代码为实验运行创建一个工件存储。
artifact = wandb.Artifact('my-dataset', type='dataset')

  • TFX 元数据也存储您的 ml 管道中生成的模型工件,并通过 SQLite 和 MySQL 存储它们。见下图

4.版本控制

这是一个软件开发工具,有助于管理对代码所做的更改。VCS 通过跟踪源代码中发生的每一个小变化来减少错误和冲突的可能性。

如果您正在处理启用了 VCS 的项目,您将拥有以下内容:

  • 每次修改的版本都会被记录和存储,这样在出错的时候很容易恢复。
  • 对于每个团队成员,都维护了源代码的不同副本。在得到其他团队成员的验证之前,它不会合并到主文件中。
  • 记录了关于谁、为什么以及对项目做了什么更改的信息。

Git 是软件开发中 VCS 最流行的例子。Git 是一个免费的开源分布式版本控制系统,用于跟踪任何一组文件的变化。

5.模型版本控制

模型版本化是组织控件、跟踪模型中的更改以及实现模型策略的整个过程。有助于模型版本化的工具:

  • DVC 通过创建元文件作为指向存储的数据集和模型的指针,同时将它们存储在本地或云中,来进行数据和模型版本控制。这些图元文件是使用 Git 处理的。git commit 等命令

  • Neptune 可以让你在实验的时候存储和跟踪不同的模型版本。它允许您比较不同的模型版本,还允许您对模型进行过滤、分组和排序。

  • MLflow Model Registry 是一个集中的模型存储库,允许您自动保存并跟踪注册模型的版本。您可以在 MLflow 中使用 log_model 方法来实现。一旦您记录了模型,您就可以通过 UI 或 API 在模型注册中心添加、修改、更新、转换或删除模型。

  • WandB 为构建的每个模型提供自动保存和版本控制。每个模型版本的工件都被存储起来,从而创建一个开发历史,并允许我们使用模型的先前版本。您也可以通过索引或其他自定义别名使用任何其他版本。

Weights & Biases - reproducibility

Source: Author

6.数据版本化

在输入或添加更多训练数据的过程中,数据会不时发生变化。数据版本化意味着随时跟踪和记录每一个数据变化。数据集是可以更新的,试图用更新的数据集复制模型是不可能的。有了数据版本控制,您可以跟踪每一个数据

  • DVC 在一个 XML 文件中单独存储有关数据的信息,并存储数据处理和加工,从而实现高效共享。对于大型数据集,DVC 使用一个共享缓存来高效地存储、版本化和访问数据集上的数据。同样对于外部数据,DVC 支持亚马逊 S3,宋承宪,HDFS。
  • Neptune 支持多种记录和显示数据集元数据的方式。您可以使用名称空间和基本的日志记录方法来组织应用程序中的任何 ML 元数据。通常,人们会记录数据集的 md5 哈希、数据集的位置、类列表和功能名称列表。
  • Delta Lake 为您的数据湖带来可靠性,在您的实验运行中统一批量数据处理,并且它在您现有的数据湖之上工作。它与 Apache Spark APIs 兼容。
  • Pachyderm 版本在处理数据时控制数据。它跟踪数据修订并阐明数据沿袭和转换。它处理纯文本、二进制文件和非常大的数据集
  • WandB 允许您将数据集存储在其工件存储中,并使用其工件引用直接指向系统中的数据,如 S3、GCP 或本地托管的数据集。
  • Qri 是一个开源的分布式数据集版本控制系统,可以帮助你清理、版本化、组织和共享数据集。它可以通过命令行、桌面 UI(macOS 和 Windows)和云来使用。它记录对数据集所做的每一次更改,并通过戳记保存它们

7.数据沿袭跟踪

每个模型都是对其进行训练的数据的压缩版本,随着时间的推移,数据会发生变化,如新的训练数据或现有数据的变化会使模型的预测过时,因此必须跟踪这方面的变化。这可以通过数据沿袭来实现。

数据沿袭是理解、记录、可视化数据从其来源到最终消费的变化和转换的过程。它提供了关于数据如何转换、转换了什么以及为什么转换的每个细节。了解数据集的数据血统有助于再现性。

  • MLflow 使用三角洲湖来跟踪模型中使用的大规模数据。
  • Pachyderm 帮助您找到数据源,然后在模型开发过程中对其进行跟踪和版本化。Pachyderm 还允许您快速审计数据版本跟踪和回滚中的差异
  • Apatar 使用可视化来显示数据从起点到终点的流动。这是一个开源的提取、转换和加载(ETL)项目,用于跨多种格式和来源移动数据。它提供了内置的数据集成工具和数据映射工具。
  • Truedat ,一个开源的数据治理工具,提供从模型开始到结束的端到端数据可视化。
  • CloverDX 通过开发人员友好的可视化设计器为您的数据集提供数据沿袭。它有利于自动化数据相关的任务,如数据迁移,而且速度很快。

可以使用基于模式的沿袭、数据标记和解析等技术来跟踪数据。

8.随机化管理

如前所述,机器学习中有很多随机性,例如随机初始化、随机噪声引入、随机增强、选择隐藏层、放弃,为了克服随机性,设置并保存您的环境种子。

您可以按如下方式设置种子值:

import os
os.environ['PYTHONHASHSEED'] = str(seed)
random.seed(seed)

或者使用 numpy 伪随机生成器来设置固定的种子值:

import numpy as np
np.random.seed(seed_value)
from comet_ml import Experiment

或者使用 TensorFlow 伪随机生成器来设置固定的种子值:

import tensorflow as tf
tf.set_random_seed(seed_value)

您还可以配置新的全局“tensorflow”会话:

from keras import backend as K
session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)
sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)

In pytorch:

import torch
torch.manual_seed(0)

设置种子参数以避免随机初始化是很重要的,为你正在使用的框架设置种子参数。使用 GPU 时,种子参数可能会被忽略。但是,设定和记录你的种子仍然很重要。还有,请不要像超参数一样优化你的种子。为了克服拆分数据进行训练、测试和验证时的随机性,请在 test_split_train 代码中包含种子参数。

9.模型注册表

Model registry 是一种跟踪机制,它记录和存储所有的模型元数据、沿袭和版本化日志。它捕获了训练期间使用的数据集、谁训练了模型、模型训练时使用了什么指标以及何时将它部署到生产中。

  • Neptune model registry 允许您将您的模型组织到一个中央模型注册表中,供进行大量实验的研究和生产团队使用。

  • MLflow Model Registry 允许您用唯一的名称、版本、阶段和其他元数据注册您的模型。

  • Comet 允许你通过用户界面或者 comet python SDK 注册你的模型。

Comet - reproducibility

Card view of registered models in Comet | Source

10.依赖性管理

如果不匹配与模型构建时相同的开发环境和软件库/框架,几乎不可能复制模型。正如你所知道的,ML 框架是不断升级的,所以存储和保存软件版本的信息以及在构建模型时使用的环境是很重要的。诸如 Conda、Docker、Kubeflow、Pipenv、Singularity 等工具将帮助您存储环境和软件依赖性。

  • Docker 使得使用一个单一的环境变得很容易,这个环境包含了运行项目所需的所有依赖项、框架、工具和库。在 docker 中,团队可以使用预构建的 Docker 映像轻松构建环境,这些映像可以在 DockerHub 中找到。
  • MLflow Projects 允许你为一个项目选择一个特定的环境并指定其参数。
  • 使用 Kubeflow,您可以将环境的代码、依赖项和配置打包到一个名为 Dockerfile 的容器中
  • Conda : Conda 是一个开源的环境和包管理系统。它允许您快速安装、运行和更新软件包及其依赖项。Conda 可以在本地计算机上轻松创建、保存、加载和切换环境。
  • Pipenv :使用 Pipenv,您可以为您的 ml 项目自动创建和管理虚拟环境。

11.协作和交流

建立模型或进行研究需要团队合作,从数据工程师到研究人员以及参与该过程的每个人。缺乏沟通很容易导致建设过程中出现问题。所以团队必须使用工具来促进他们之间有效的合作和交流。像 DVC、Github、Neptune.ai、Comet.ml、Kubeflow、Pycharderm 和 WandB 这样的工具允许团队有效地远程协作和交流

  • Neptune 帮助您的团队协作构建 ML 模型。
  • Pachyderm 提供跨机器学习工作流程和项目的合作。
  • WandB 允许协作,你可以很容易地邀请人们来编辑和评论一个项目。
  • Comet 让你与其他人分享和合作项目。
  • Colab、Deepnote 等笔记本也提供模型构建方面的协作。

12.避免不确定的算法

对于相同的输入,非确定性算法在不同的运行中显示不同的行为,这对可重复性来说是个坏消息。

import torch
torch.use_deterministic_algorithms(True)

  • TensorFlow 具有 GPU 确定的功能,可以通过英伟达 NGC TensorFlow 容器或 TensorFlow 版本 1.14、1.15 或 2.0 访问,支持 GPU。

对于 NGC tensorflow 容器(版本 19.06–19.09),通过以下方式实现:

import tensorflow as tf
import os
os.environ['TF_DETERMINISTIC_OPS'] = '1'

对于 TensorFlow 版本 1.14、1.15 和 2.0,它是这样实现的:

import tensorflow as tf
from tfdeterminism import patch
patch()

13.综合

大多数 MLOps 工具可能不具备成功的端到端模型编排(从模型设计到模型部署)所需的所有特性。工具的无缝集成对于再现性来说是一件好事。

此外,团队中缺乏对某些工具的专业知识也会导致一个项目使用不同的工具。然后,用于这样一个项目的工具相互之间适当地集成是有意义的。

例如:

  • Docker 与 AWS、Tensorflow、Kubeflow 集成良好。
  • Neptune 使用 neptune-client 与其他 ml 工具和库集成。海王星与牛郎星、Dalex、Fastai、MLflow、Pandas、Pytorch、Tensorflow 等整合良好。
  • MLflow 提供了几种可能对您的应用程序有用的标准风格,如 Python 和 R 函数、H20、Keras、MLeap、PyTorch、Scikit-learn、Spark MLlib、TensorFlow 和 ONNX。
  • Pachyderm 也可以在 5 分钟左右部署在 AWS/GCE/Azure 上。
  • WandB 与 PyTorch、Keras、Hugging Face 等产品集成良好。WandB 支持 AWS、Azure、GCP 和 Kubernetes。

以下是一些可复制工具及其功能的总结:

在笔记本电脑上工作时,您可以查看以下链接,了解有关再现性的更多提示:

结论

再现性是更好的数据科学和 ML 研究的关键,它使你的项目灵活,适合大规模生产。

当你为你的下一个 ML 项目选择工具时,记住没有放之四海而皆准的解决方案(特别是如果你不喜欢 SageMaker 这样的端到端解决方案)。工具的正确选择总是取决于您独特的环境。只要确保您有工具来跟踪您的代码和计算环境,并且存储您的元数据、工件和模型版本。

可重复性,尤其是在研究中,使其他人更容易合作,使您的项目能够长期发展,并有助于正确建立机构知识。但它在商业中同样重要,它可以缩短你的上市时间,提高底线。

小野寺次郎

机器学习工程师和研究员,对人工智能和人类福祉(医疗保健和教育)之间的交叉充满热情。在我的空闲时间,我喜欢尝试新的菜肴和看动漫。


阅读下一篇

在 AILS 实验室建立可扩展的医学 ML 研究工作流程[案例研究]

8 分钟阅读| Ahmed Gad |发布于 2021 年 6 月 22 日

AILS Labs 是一个生物医学信息学研究小组,致力于使人类更加健康。这个任务就是建造模型,也许有一天可以拯救你的心脏病。它归结为应用机器学习来基于临床、成像和遗传学数据预测心血管疾病的发展。

四名全职和五名以上兼职团队成员。生物信息学家、内科医生、计算机科学家,许多人都有望获得博士学位。正经事。

虽然业务可能是一个错误的术语,因为面向用户的应用程序还没有在路线图上,但研究是主要的焦点。研究如此激烈,以至于需要一个定制的基础设施(花了大约一年时间建造)来从不同类型的数据中提取特征:

  • 电子健康记录(EHR),
  • 诊断和治疗信息(时间-事件回归方法),
  • 图像(卷积神经网络),
  • 结构化数据和心电图。

通过融合这些特征,精确的机器学习模型可以解决复杂的问题。在这种情况下,这是心血管一级预防的风险分层。本质上,它是关于预测哪些患者最有可能患心血管疾病

AILS 实验室有一套完整的研究流程。每个目标都有七个阶段:

  1. 定义要解决的任务(例如,建立心血管疾病的风险模型)。
  2. 定义任务目标(例如,定义预期的实验结果)。
  3. 准备数据集。
  4. 使用 Jupyter 笔记本以交互模式处理数据集;快速试验,找出任务和数据集的最佳特性,用 R 或 Python 编码。
  5. 一旦项目规模扩大,使用像 Snakemake 或 Prefect 这样的工作流管理系统将工作转化为可管理的管道,并使其可重复。否则,复制工作流程或比较不同模型的成本会很高。
  6. 使用 Pytorch Lightning 与 Neptune 集成创建机器学习模型,其中应用了一些初始评估。记录实验数据。
  7. 最后,评估模型性能并检查使用不同特征和超参数集的效果。

扩大机器学习研究的 5 个问题

AILS Labs 最初是由一小群开发人员和研究人员组成的。一个人编写代码,另一个人审查代码。没有太多的实验。但是协作变得更具挑战性,随着新团队成员的到来,新问题开始出现:

  1. 数据隐私,
  2. 工作流程标准化,
  3. 特征和模型选择,
  4. 实验管理,
  5. 信息记录。

Continue reading ->


如何构建和管理自然语言处理(NLP)项目

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-structure-and-manage-nlp-projects-templates

如果说我在 ML 行业工作中学到了什么的话,那就是:机器学习项目很乱。

这并不是说人们不想把事情组织起来,只是在项目过程中有很多事情很难组织和管理。

你可以从头开始,但有些事情会阻碍你。

一些典型的原因是:

  • 笔记本中的快速数据探索,
  • 取自 github 上的研究报告的模型代码,
  • 当一切都已设置好时,添加新的数据集,
  • 发现了数据质量问题并且需要重新标记数据,
  • 团队中的某个人“只是快速地尝试了一些东西”,并且在没有告诉任何人的情况下改变了训练参数(通过 argparse 传递),
  • 从高层推动将原型转化为产品“仅此一次”。

多年来,作为一名机器学习工程师,我学到了一堆东西,它们可以帮助你保持在事物的顶端,并检查你的 NLP 项目(就像你真的可以检查 ML 项目一样:)。

在这篇文章中,我将分享我在从事各种数据科学项目时学到的关键指针、指南、技巧和诀窍。许多东西在任何 ML 项目中都是有价值的,但有些是 NLP 特有的。

涵盖的要点:

  • 创建良好的项目目录结构
  • 处理变化的数据:数据版本化
  • 跟踪 ML 实验
  • 正确评估和管理指标和 KPI
  • 模型部署:如何正确使用

让我们跳进来。

目录结构

数据科学工作流由多个元素组成:

  • 数据,
  • 模特,
  • 报告,
  • 培训脚本,
  • 超参数,
  • 诸如此类。

拥有一个跨团队一致的公共框架通常是有益的。很可能你有多个团队成员在同一个项目中工作。

有许多方法可以开始构建您的数据科学项目。您甚至可以根据团队的特定需求创建自定义模板。

然而,最简单快捷的方法之一就是使用千篇一律的模板。它会自动为您生成一个全面的项目目录。

├── LICENSE
├── Makefile           <- Makefile with commands like `make data` or `make train`
├── README.md          <- The top-level README for developers using this project.
├── data
│   ├── external       <- Data from third party sources.
│   ├── interim        <- Intermediate data that has been transformed.
│   ├── processed      <- The final, canonical data sets for modeling.
│   └── raw            <- The original, immutable data dump.
│
├── docs               <- A default Sphinx project; see sphinx-doc.org for details
│
├── models             <- Trained and serialized models, model predictions, or model summaries
│
├── notebooks          <- Jupyter notebooks. Naming convention is a number (for ordering),
│                         the creator's initials, and a short `-` delimited description, e.g.
│                         `1.0-jqp-initial-data-exploration`.
│
├── references         <- Data dictionaries, manuals, and all other explanatory materials.
│
├── reports            <- Generated analysis as HTML, PDF, LaTeX, etc.
│   └── figures        <- Generated graphics and figures to be used in reporting
│
├── requirements.txt   <- The requirements file for reproducing the analysis environment, e.g.
│                         generated with `pip freeze > requirements.txt`
│
├── setup.py           <- Make this project pip installable with `pip install -e`
├── src                <- Source code for use in this project.
│   ├── __init__.py    <- Makes src a Python module
│   │
│   ├── data           <- Scripts to download or generate data
│   │   └── make_dataset.py
│   │
│   ├── features       <- Scripts to turn raw data into features for modeling
│   │   └── build_features.py
│   │
│   ├── models         <- Scripts to train models and then use trained models to make
│   │   │                 predictions
│   │   ├── predict_model.py
│   │   └── train_model.py
│   │
│   └── visualization  <- Scripts to create exploratory and results oriented visualizations
│       └── visualize.py
│
└── tox.ini            <- tox file with settings for running tox; see tox.testrun.org

如您所见,它几乎涵盖了您工作流程中的每一个重要组成部分——数据、文档、模型、报告、可视化。

寻找可视化工具?

数据版本化

机器学习是一个迭代的过程。如果你是一名专业的数据科学家,你会注意到最大的不同是,数据不像在竞争或研究基准数据集中那样定义良好。

研究数据集应该是干净的。在研究中,目标是建立一个更好的架构。研究环境中更好的结果应该归功于新颖的架构,而不是聪明的数据清理技巧。

当涉及到生产中使用的数据时,需要做的不仅仅是简单地预处理数据和删除非 unicode 字符。还有更严重的问题,比如:

  • 错误或不准确的注释–专业数据科学家花费大量时间了解数据生成过程,因为这几乎会影响他做出的任何进一步决策。人们应该知道以下问题的答案:

    • 谁注释了数据?
    • 在使用产品时,是否有一个独立的团队或由用户注释?
    • 您是否需要具备深厚的领域知识才能成功地注释数据?(例如,医疗保健相关数据就是这种情况)
  • 数据的时间线–如果 90 万行数据是很久以前生成的,那么拥有 100 万行数据是没有用的。在消费产品中,用户行为随着趋势或产品修改而不断变化。数据科学家应该问这样的问题:

    • 数据生成的频率如何?
    • 数据生成过程中是否有任何差距(可能生成数据的产品功能被暂时取消了)?
    • 我如何知道我不是在用旧趋势的数据建模(例如在时尚服装推荐中)
  • 数据中的任何偏差–数据中的偏差可以是各种类型。其中很多是由于定义不清的数据收集过程造成的。其中一些是:

    • 抽样偏倚–收集的数据不代表总体数据。如果数据具有“年龄”特征,偏见可能导致年轻人的比例过高。
    • 测量偏差–一部分数据用一种仪器测量,另一部分用不同的仪器测量。这可能发生在重工业,那里的机器经常更换和维修。
    • 标签中的偏差–情感分析任务中的标签可能非常主观。这还取决于标签是由专门的注释团队分配还是由最终用户分配。

考虑 NLP 中的文本分类任务,并假设您的产品在全球范围内工作。你可以收集来自世界各地的用户评论。假设印度的用户评论具有与主要语言是英语的美国或英国的用户相似的单词分布是不实际的。在这里,您可能想要创建一个单独的区域版本历史。

这些与您的数据科学工作流程有什么关系?

通常情况下,您开始使用的数据与您构建最终模型时使用的数据大相径庭。对于您在数据中所做的每一个更改,您都需要对其进行版本化。就像你用 Git 控制你的代码版本一样。为此,您可能需要查看一下数据版本控制( DVC )。

实验跟踪

构建模型有时很有趣,但实际上通常很无聊。考虑建立一个 LSTM(长短期记忆网络)进行分类。有学习率、堆叠层数、隐藏维度、嵌入维度、优化器超参数,以及更多要调整的参数。记录每一件事会让人不知所措。

为了节省时间,一个优秀的数据科学家会试图形成一种直觉,判断超参数的什么值有效,什么值无效。记住你已经形成的度量目标是很重要的。您可能想要跟踪哪些关键值?

  • 超参数
  • 模型大小(针对内存限制)
  • 推理时间
  • 超过基线的增益
  • 优点和缺点(如果模型支持词汇外的单词(如 fasttext)或不支持(如 word2vec)
  • 任何有用的注释(例如–)都使用了具有高初始学习率的调度器。比使用恒定的学习速率更有效。

通常,尝试越来越多的实验来从模型中榨取每一盎司的准确性是很诱人的。但是在商业环境中(与 kaggle 竞赛或研究论文相反),一旦指标达到,实验就应该暂停。

Neptune 的简单 API 可以让你追踪实验的每一个细节,并通过它的用户界面进行有效的分析。我第一次使用海王星,花了几分钟开始跟踪我的实验。

您可以查看您的实验,通过超参数值和指标进行筛选,甚至可以查询-“momentum = 0.9 和 lr<0.01”

海王星记录你的。py 脚本,使你的损失曲线(或一般的任何曲线)交互式可视化,甚至测量你的 CPU/GPU 利用率

另一个好处是,当你在团队中工作时,所有这些变得更加有用。有了 Neptune,分享成果和在想法上合作变得出奇的简单。

最棒的是,它有一个免费的个人计划,允许用户通过无限制的实验(公共或私人)和无限制的笔记本检查点存储高达 100 GB 的数据。

检查模型预测(误差分析)

下一步包括深入的错误分析。例如,在情绪分析任务中(有三种情绪——积极、消极和中立),问以下问题会有所帮助:

  • 创建一个基线:在投入实验之前创建一个基线总是一个好主意。你不希望你的 BERT 模型比 TF-IDF +逻辑分类器的性能稍好。你想让它把你的底线打出水面。始终将您的模型与基线进行比较。我的基线在哪些方面比复杂模型表现得更好?因为基线通常是可解释的,你也可以洞察你的黑盒模型。

  • 度量分析:每个类的精度和召回率是多少?我的错误分类“泄露”到哪里去了?如果负面情绪的大多数错误分类被预测为中性,那么您的模型在区分这两个类别时会遇到困难。对此进行分析的一个简单方法是制作一个混淆矩阵。

  • 低置信度预测分析:模型正确但分类置信度低的例子是怎样的?在这种情况下,预测类别的最小概率可以是 0.33 (⅓):

    • 如果模型预测正确率为 0.35,检查那些例子,看看它们是否真的很难识别。
    • 如果该模型以 0.35 的概率正确预测了一个明显积极的评论,如“我很高兴我做了好工作”,那么事情就有猫腻了。
  • 解释框架:你也可以看看像莱姆SHAP 这样的框架来解释你的模型预测。

  • 看长度 vs 度量分数:如果你在训练数据中的句子在长度上有很大的可变性,那么检查一下误分类率和长度之间是否有相关性。

  • 检查偏差:模型中有偏差吗?例如,如果在推特上训练,模型对种族言论的表现是否不同?在这种情况下,需要对训练数据进行彻底检查。互联网上的信息包含仇恨言论。然而,模型不应该学习这样的模式。现实生活中的一个例子是 Tay,一个由微软开发的推特机器人学习了推特的模式,并在仅仅 24 小时就开始发表种族言论。

如果您的模型在基线上表现不佳,请尝试找出问题所在:

  • 是因为标注数据的质量低还是数量少?
  • 您是否有更多可以注释的已标记数据或未标记数据?有很多开源注释工具可用于文本数据注释——比如 Doccano
  • 如果你没有任何数据,可以使用任何现成的模型或者使用迁移学习吗?

回答这些关键问题需要你非常仔细地分析你的实验。

评估无监督的 NLP 模型

作为一个特例,让我们讨论一下你将如何评估一个无监督的 NLP 模型。让我们考虑一个特定于领域的语言模型。

您已经有了一些度量标准来衡量语言模型的性能。其中之一就是困惑。然而,大多数时候,语言模型的目的是学习领域词汇的高质量表示。你如何衡量表现的质量是好的?

一种方法是将嵌入用于下游任务,如分类或命名实体识别 (NER)。看看如果你使用有限的数据,你能保持和你的从头开始训练的 LSTM 一样的表现水平吗?

模型部署

尽管模型部署是在模型被训练之后进行的,但是有几点您需要从一开始就考虑。例如:

  • 我需要近乎实时的推理吗?在广告定位等应用中,用户一登陆页面,广告就需要显示出来。因此,定位和排序算法需要实时工作。
  • 模型将在哪里托管?–云、内部部署、边缘设备、浏览器?如果您是本地托管,基础架构的大部分构建都由您负责。云在基础架构部署中可以利用多种服务。例如,AWS 提供弹性 Kubernetes 服务( EKS ,无服务器触发功能如λSagemaker 来创建模型端点。还可以在普通的 EC2 服务器实例中添加自动伸缩策略,以便在需要时提供适当的资源。
  • 模型太大?如果模型很大,你可能想研究一下培训后的量化。这降低了模型参数的精度级别,从而节省了一些计算时间并减小了模型大小。
  • 您想在 CPU 或 GPU 服务器上部署模型吗?

一般来说,直接用新模型替换现有模型并不是一个好的做法。您应该执行 A/B 测试来验证模型的健全性。你可能还想看看其他方法,如金丝雀部署或冠军挑战者设置

摘要

我希望你能为下一个 NLP 项目找到新的思路。

总而言之,我们从为什么认真考虑一个好的项目管理工具很重要开始,数据科学项目由什么组成-数据版本控制、实验跟踪、错误分析和管理指标。最后,我们总结了关于成功模型部署的想法。

如果你喜欢这篇文章,那么下一步就是开始用所有相关的工具构建你自己的 NLP 项目结构。查看工具,如:

谢谢,训练愉快!

德鲁维尔·卡拉尼

i3systems India 的数据科学家
一位热爱数学和编程的数据科学家。他以前的经验使他能够处理大规模的自然语言处理问题,如聊天机器人和文档理解。他认为,教育大众了解技术及其影响与开发新技术同样重要。


阅读下一篇

ML 元数据存储:它是什么,为什么重要,以及如何实现它

13 分钟阅读|作者 Jakub Czakon |年 8 月 13 日更新

大多数找到这个页面的人都想改进他们的建模过程。

但是他们在存储和管理 ML 模型元数据方面的问题是不同的。

对一些人来说,问题在于杂乱的实验。

其他人已经将第一批模型部署到生产中,但是他们不知道这些模型是如何创建的,也不知道使用了哪些数据。

有些人已经在生产中有了许多模型,但是编排模型 A/B 测试,切换挑战者和冠军,或者触发、测试和监控再培训管道并不是很好。

如果你认为自己属于这些群体中的一员,或者介于两者之间,我可以告诉你,ML 元数据存储可以帮助你完成所有这些事情,甚至更多。

您可能需要将其连接到其他 MLOps 工具或您的 CI/CD 管道,但它将简化大多数工作流程中的模型管理。

…但是实验跟踪、模型注册、模型存储、模型目录和其他与模型相关的动物也是如此。

那么 ML 元数据存储到底是什么,它与其他模型有什么不同,它如何帮助您更自信地构建和部署模型?

这就是这篇文章的内容。

另外,如果你是那种喜欢摆弄东西来看看它们是什么的人,你可以在 Neptune ML 元数据存储库中查看这个示例项目。

但是首先…

元数据管理和什么是 ML 元数据?

在我们深入 ML 元数据存储之前,我可能应该告诉你我所说的“机器学习元数据”是什么意思。

当你做机器学习时,总会涉及到一个模型。这就是机器学习。

它可能是一个经典的监督模型,如 lightGBM 分类器、强化学习代理、贝叶斯优化算法或其他任何东西。

但它需要一些数据,通过一些数字运行,并输出一个决定。

…将它投入生产需要大量的工作。

Continue reading ->


如何构建、组织、跟踪和管理强化学习(RL)项目

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-structure-organize-track-and-manage-reinforcement-learning-rl-projects

构建和管理机器学习项目可能是一件棘手的事情。

当您投入到一个项目中时,您可能会很快意识到您淹没在 Python 脚本、数据、算法、函数、更新等等的海洋中。在某些时候,你会忘记你的实验,甚至说不出哪个脚本或更新产生了最好的结果。

因此,组织你的项目和跟踪实验 是成功的关键部分。

从这个角度来看,从事一个 ML 项目总体来说可能具有挑战性,但是有些领域比其他领域更复杂。强化学习 ( RL )就是其中比较复杂的一种

本文致力于构建和管理 RL 项目。我会尽量精确,并提供一个全面的分步指南和一些有用的提示。

我们将涵盖:

  • 一般提示—项目目录结构, Cookiecutter ,使用 Neptune 跟踪实验,适当评估
  • 将问题定义为 RL 问题–强化学习、监督学习、优化问题、最大化和最小化
  • 挑选 RL 环境–open ai 健身房
  • 选择 RL 库和算法–RL _ 蔻驰、张量力、稳定基线、RL _ 蔻驰准则
  • 测试代理的性能
  • 准备发布–自述文件、需求、可读代码、可视化

让我们跳进来。

一般提示

首先,你必须回到基础,记住 可以应用于任何 ML 项目提示。这些是:

  1. 项目目录结构
  2. 跟踪实验
  3. 适当的模型评估

项目目录结构

总的来说,保持工作目录结构化并易于浏览的能力是一项了不起的技能。

当谈到数据科学工作流时,我们面临多种因素,例如:

  • 数据
  • 模型
  • 日志
  • 培训和测试脚本
  • 超参数文件
  • 其他的

有各种各样的实践和方法来构建你的工作目录。根据我个人的经验,最好、最快、最简单的方法是使用 Cookiecutter 模板。

Cookiecutter 是一个有着自己理念的强大工具。它提供了易于浏览的完整文档。

尝试使用 Cookiecutter 模板来构建您下一个 RL 项目的工作目录,您会发现这是多么方便。

跟踪实验

从我的角度来看,最重要的一般提示是跟踪实验。您可能想要跟踪许多关键值:

  • 超参数
  • 推理时间
  • 超过基线的增益
  • 任何注释(例如,实验的文本描述)
  • 其他的

即使你的目录结构很差,适当的实验跟踪也是一个必须具备的特性。它将使你免于失去工作节奏和有价值的结果。

对于强化学习,由于有了 Neptune ,实验跟踪并不是一项具有挑战性的任务,它可以与大多数 RL 库一起使用。

还有其他的跟踪工具,但是它们不太适合 RL 项目。在选择你的 RL 库的时候记住这一点,并且总是仔细检查你是否可以使用你最喜欢的跟踪工具来跟踪一个特定的库

尽管如此,海王星是一个稳定和伟大的工具来跟踪你的实验。它有大量有价值的例子和教程,既可以用于你自己的项目,也可以用于团队项目。

你绝对应该在下一个 RL 项目中尝试一下。

恰当的评价

最后但同样重要的是,在评估算法的性能时,您需要既小心又精确。在强化学习领域,评估指标和流程在很大程度上取决于您的问题和您使用的环境

我建议先检查一下比赛和论坛,因为你可能会发现和你相似的问题,以及有价值的想法和建议。永远不要低估社区的力量,并且总是关注是否有新的有趣的东西。

请记住,在 RL 项目中工作时,如果可能的话,您应该总是查看您的代理执行的视频。当然,这不是一个合适的评估或实验跟踪技术,但它是对其他工具和度量标准的一个很好的补充。

我们已经讨论了基础知识,所以让我们继续讨论解决 RL 问题的所有主要步骤:

  1. 将问题定义为 RL 问题
  2. 选择一个 RL 环境
  3. 选择一个 RL 库和算法
  4. 测试代理的性能
  5. 准备发布您的项目

将问题定义为 RL 问题

首先,我们需要决定强化学习是否适合我们的问题。这是非常重要的一步,因为我们不想通过使用不合适的学习模型或不相关的算法来使任务过于复杂。

RL 是关于探索和开发,以及它们之间的权衡。这是 RL 和许多其他类型学习的主要区别,比如监督学习。

RL 代理通过与环境互动来学习,尝试不同的行动,并为这些行动获得不同的奖励值,同时目标是在结束时最大化整体奖励

这是一个与监督学习完全不同的概念,在监督学习中,代理通过将他们的预测与现有标签进行比较来学习,并在之后更新他们的策略。

这就是为什么你需要确定 RL 是否可以用来解决你的问题。

幸运的是,这很容易做到。

想想你的任务是不是一个优化问题。接下来,您必须弄清楚是否有您希望您的 RL 代理学会最大化或最小化的任何指标。

如果你的两个答案都是肯定的,那么强化学习可能是解决这个问题的一个很好的选择,你应该开始考虑一个 RL 环境。

选择一个 RL 环境

如果强化学习很好地解决了你的问题,那么是时候选择或构建运行 RL 算法的基础设施了。

这个基础设施被称为环境。它是用来训练特工的。基本上,环境是一个模拟真实环境的模拟,代理将在真实环境中部署。

有很多不同的 RL 环境:

这也是为什么,如果你不想自己搭建环境,我建议用最流行最常用的——open ai Gym

如果您确实想构建自己的环境,您将面临一系列挑战。你需要考虑:

  1. 环境结构–您想要构建什么类型的环境
  2. 环境接口–将环境连接到 RL 算法的接口
  3. 测试环境–确保您的实现完美运行,您的 RL 代理将正确学习

说实话,这些都不是在上工作的超级明显的事情。这就是为什么我建议使用有价值的文章帖子视频教程来打磨这个话题。希望这足以让你建立自己的 RL 环境。

然而,请记住不要让任务过于复杂,所以只有在必要时才设置自己的环境。使用预装的也没什么不好。

挑选一个 RL 库和算法

在这一点上,你有来选择一个 RL 库和你将用来解决问题的算法

有很多 RL 库,选择正确的库是项目成功的关键。我推荐阅读“你实际想尝试的 Python 中强化学习的最佳工具”。这篇文章将帮助你做出选择。

总体来说,我强烈推荐 Tensorforce,稳定基线,或者 RL _ 蔻驰。它们似乎是最新的,实现了一组很好的算法,并提供了有价值的教程和完整的文档。此外,它们可以在多种环境下工作,因此设置应该不成问题。

至于 RL 算法的选择,我觉得你已经投入到任务中并选择了算法。如果是这样,那太好了,你应该开始训练你的经纪人了。

如果没有,请检查RL _ 蔻驰文档。在我看来,为如何为你的任务选择正确的算法提供了完美的指导。有这个问题应该对你有很大帮助。

测试代理的性能

现在,当你的 RL 代理被训练后,是时候评估它了。正如我之前提到的,这可能是一个棘手的过程,取决于您的问题和您使用的环境。

尽管如此,我还是想在这里提一些一般性的建议。

如果你的目标是最优控制,你应该使用一些奖励的综合措施。例如,每集的总报酬,或每个时间步长的平均报酬。这将有助于您了解代理在任务中的表现。

如果你正在处理一个视频游戏问题,或者一个设计得很容易识别的问题,使用一个基于奖励的衡量标准的最大界限。之后,您可以将您的代理与这个已知值进行比较。有理由期待一个好的代理会接近最大值。

在实践中,许多有趣的问题没有一个已知的奖励总数或平均值的上限。对于这些问题,通常您能做的最好的事情就是在代理之间进行比较。您可以比较:

  • 随机行动的代理人–这通常只是一个基线,表明代理人已经学到了一些东西
  • 自动化代理–代理使用简单的行动选择启发式,这可能是给定问题中自然或明显的东西
  • 一个或多个人在同一项任务上
  • 其他受过 ML 训练的代理包括同一代理的先前实例

如果政策或环境是随机的,你可能想要运行多个测试并平均结果,以尽可能多地评估具有期望值的代理。

在测试期间关闭任何探索也是非常重要的,如果你使用任何不符合政策的技术,比如 DQN,就可以公平地衡量训练有素的代理表现如何。

如果您的代理设计为不断学习和探索,和/或使用政策方法,您可以使用培训期间的结果来评估它。例如,你可以对过去 N 集的总奖励进行滚动平均,或者类似的方法。

此外,这对于监控培训来说是一个不错的指标,甚至对于非政策方法也是如此。尽管对于不符合策略的情况,与单独的测试运行相比,您可能会低估性能。

其他方法和其他指标来评估代理。例如,代理需要学习多少经验或多少计算才能达到某一水平通常是感兴趣的。

如果你想断定代理人对于最优控制任务的训练是好是坏,这种对总报酬的评估可能就是你所需要的。

但是,您也可以查看任何神经网络内部的损失指标——您不会为了将代理分为更好或更差而这样做,但您可以这样做来识别问题。

这些损失度量通常与监督学习等同物相同。例如,在 DQN,或者对于 PPO 的批评部分,您会对任何状态的预测值是否与最终值匹配感兴趣,并使用 MSE 损失。

准备发布

这是最后一步,在这里你可以发挥创造力,展示你的个性。

不过,请记住,如果你计划向全世界发布你的项目,比如在 Github 上,你可能需要遵循一些简单的规则:

  1. 自述文件–请在您的存储库中准备好一份自述文件,它将帮助那些不熟悉您的项目的人建立项目
  2. requirements . txt–一个包含您用来制作这个项目的库和库版本的文件
  3. 易于定制的可读代码——这对你和潜在用户都有好处
  4. 一些有价值的可视化效果–如果是 RL 项目,这可以是你的代理工作的 gif

遵守这些规则是值得的,因为在数据科学社区,它们被认为是基本的礼仪。

就这样,你的项目完成了。恭喜你!

最后的想法

我希望你能为下一个强化学习项目找到新的思路。

总之,我们从构建和管理任何 ML 项目的一些通用技巧开始,并逐步指导如何在强化学习项目中构建您的工作。最后,我们讨论了项目发布的一些想法。

如果你喜欢这篇文章,那么下一步就是开始用所有相关的工具构建你自己的 RL 项目结构。查看工具,如:

感谢阅读,祝训练愉快!

资源

弗拉基米尔·利亚申科

年轻的人工智能爱好者,对医学中的教育技术和计算机视觉充满热情。我想通过帮助其他人学习,探索新的机会,并通过先进的技术跟踪他们的健康状况,让世界变得更美好。


阅读下一篇

ML 元数据存储:它是什么,为什么重要,以及如何实现它

13 分钟阅读|作者 Jakub Czakon |年 8 月 13 日更新

大多数找到这个页面的人都想改进他们的建模过程。

但是他们在存储和管理 ML 模型元数据方面的问题是不同的。

对一些人来说,问题在于杂乱的实验。

其他人已经将第一批模型部署到生产中,但是他们不知道这些模型是如何创建的,也不知道使用了哪些数据。

有些人已经在生产中有了许多模型,但是编排模型 A/B 测试,切换挑战者和冠军,或者触发、测试和监控再培训管道并不是很好。

如果你认为自己属于这些群体中的一员,或者介于两者之间,我可以告诉你,ML 元数据存储可以帮助你完成所有这些事情,甚至更多。

您可能需要将其连接到其他 MLOps 工具或您的 CI/CD 管道,但它将简化大多数工作流程中的模型管理。

…但是实验跟踪、模型注册、模型存储、模型目录和其他与模型相关的动物也是如此。

那么 ML 元数据存储到底是什么,它与其他模型有什么不同,它如何帮助您更自信地构建和部署模型?

这就是这篇文章的内容。

另外,如果你是那种喜欢摆弄东西来看看它们是什么的人,你可以在 Neptune ML 元数据存储库中查看这个示例项目。

但是首先…

元数据管理和什么是 ML 元数据?

在我们深入 ML 元数据存储之前,我可能应该告诉你我所说的“机器学习元数据”是什么意思。

当你做机器学习时,总会涉及到一个模型。这就是机器学习。

它可能是一个经典的监督模型,如 lightGBM 分类器、强化学习代理、贝叶斯优化算法或其他任何东西。

但它需要一些数据,通过一些数字运行,并输出一个决定。

…将它投入生产需要大量的工作。

Continue reading ->


如何测试推荐系统

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-test-recommender-system

推荐系统从根本上解决了人们想要什么的问题。

虽然这是一个广泛的问题,但在像电子商务这样的消费者应用程序的上下文中,答案可能是为消费者提供价格和质量最好的产品。对于一个新闻聚合网站,它可以显示可靠和相关的内容。

在用户不得不浏览成千上万的商品来找到他们想要的东西的情况下,推荐引擎是必不可少的。根据 lighthouselabs.ca 的一篇关于网飞使用数据科学的文章:

该引擎基于用户偏好,使用 1,300 个推荐聚类,一次过滤超过 3,000 个标题。它是如此准确,以至于来自引擎的个性化推荐驱动了 80%的网飞观众活动。

然而,与单一的 ML 模型相比,在设计决策、工程和度量方面,构建和评估推荐系统是非常不同的。在本文中,我们将重点测试一个推荐系统。我们还将讨论:

  • 1 推荐系统的类型
  • 2 最流行模式——协同过滤概述

推荐系统的类型

推荐系统基于三种主要模式工作:

  1. 相似性-基于查询内容:系统根据相似性检索内容。比如你喜欢一个足球视频,它会给你看另一个。或者,如果你搜索一件蓝色 t 恤,它会显示更多的蓝色 t 恤。匹配基于项目内容,如图像、描述、标题等。

  2. 群众的智慧:社交媒体中使用的现代推荐系统就是基于这一点。如果用户 A 喜欢电影 X、Y、Z,用户 B 喜欢电影 X、Z;那么用户 B 可能喜欢电影 y。这些推荐模型不依赖于项目内容,而是考虑用户偏好。这些模型之所以受欢迎,是因为它们超越了主题和内容。他们可以向刚刚喜欢足球视频的热爱体育的用户全面推荐棒球视频。

  3. 基于会话:基于会话的系统捕捉用户在特定会话中的意图,并基于会话级上下文信息推荐项目。例如,如果您正在购买新的工作站,并打算购买显示器、键盘、鼠标、椅子等。您希望网站向您显示与在此会话中设置工作站相关的项目,即使您之前可能喜欢某本书。

第二个和第三个需要大量的用户-项目交互数据。如果没有,可以从第一种推荐系统开始。即使现有用户有大量数据,新用户也可能没有足够的数据。这种情况在推荐系统中被称为冷启动问题。在这种情况下,基于内容的推荐系统可以是一个很好的代理,直到有足够的新用户交互数据。

概述够了,现在让我们简单看看一个流行的推荐系统,看看我们如何测试它。

基于协同过滤的模型综述

协同过滤是最流行的经过实战检验的推荐模型之一。这里的目标是训练项目和用户的向量表示,使得具有表示(嵌入)Vu 的用户 U 更喜欢具有表示(嵌入)的项目I****VI的概率是

**Collaborative filtering is one of the most popular battle-tested recommendation models

Collaborative filtering is one of the most popular battle-tested recommendation models | Source: Author

模特培训是如何进行的?

对于数据集中的 M 个唯一用户和 N 个唯一项目,我们创建一个嵌入表,维度为D。我们有 D*(M+N) 参数要学习。假设我们正在为 YouTube 构建这个系统,并希望预测用户是否会按下视频上的 like 按钮。我们的训练数据会有几十亿对像 (userId,postId) 如果那个 userId 的用户喜欢过那个 postId 的视频。

Train/test split under the case of recommendation

Train/test split under the case of recommendation | Source

我们随机初始化嵌入。然后,在训练期间,我们计算标签为 1 和交叉熵损失的概率。在多个时期分批进行这种操作可以训练用户和项目嵌入。

Model training in recommender systems

Model training in recommender systems | Source: Author

培训-验证分离发生在用户级别。这意味着,每个用户的 X%的喜欢在训练集中,100-X%在验证集中。x 通常为 80-90%。

推荐系统:目标设计

在前面的例子中,我们训练了一个模型来预测用户是否喜欢 YouTube 上的视频。预测的变量非常简单明了。然而,并不是所有的信号都是明确的。例如,考虑关于用户是否将观看视频长度的 95%的预测变量。如果是这样,我们在数据集中包含 (userId,postId)

如果我们有一个近乎完美的模型,预测观看概率> 95%,我们可以说我们在推荐用户喜欢的视频,对吗?

这里有一个问题——考虑一个一分钟的视频(V1)和一个三十分钟的视频(V30)。看完 V1 的 95%需要 57 秒,看完 V30 的 95%需要 1710 秒。V1 也可以是一个点击诱饵视频,而用户可以喜欢 V30,仍然可以观看 1600 秒的视频。那么我们的定义是否保证了正面标签代表了用户偏好?

其次,大多数平台都有多个信号——喜欢、分享、下载、点击等。应该使用哪个目标来训练模型?通常情况下,一个是不够的。假设我们基于不同的目标训练多个模型。我们有来自每个模型的多个 (userId,postId) 分数。然后,基于所有分数的聚合公式创建单个数字分数,用于创建最终排名。

关键是,如果培训目标没有精心设计,即使是近乎完美的模型也不会给出好的建议。

评估推荐系统

离线评估

在本地机器上离线训练一个推荐模型并不能保证它的在线性能。然而,有一些指标来分析预期的模型行为。

ROC-AUC

受试者操作者特征或 ROC 曲线在 Y 轴上测量真阳性率(TPR ),在 X 轴上测量假阳性率(FPR)。对于二元分类器,我们使用一个阈值,高于该阈值的实例被预测为阳性,否则为阴性。对于特定的阈值,

【TPR = %总正阈值以上= TP/(TP + FN)

【FPR = %高于阈值的总否定量= FP/(FP + TN)

在阈值=0 时,所有示例都被分类为阳性。因此,FN=0,因为没有例子被分类为负,并且 TPR=1。出于同样的原因,TN 也为零。因此,FPR 也是 1。这是图上的(1,1)点。

在阈值=1 时,没有示例被预测为阳性。因此 TP 和 FP 都是 0,在图上表示(0,0)。

通过计算[0,1]中不同阈值的 TPR 和 FPR 并绘制它们来绘制曲线。绘制的曲线如下所示:

曲线下的面积最大为 1。如果分类器将标签随机分配给实例,则沿着 x=y 的对角线是 ROC 曲线。

PR-AUC

Precision-Recall AUC 或 PR-AUC 类似于 ROC-AUC,只是在 Y 轴上,我们有 Precision,在 X 轴上,我们有 Recall。正如我们所知,精确度是模型预测的正确率。另一方面,回忆是模型正确分类的全部现存肯定的一部分。

为了更好地理解 PR 曲线,考虑一个二元分类器。如果我们保持低的分类阈值,比如 0.05,大多数例子被预测为阳性。所有现有的阳性将被正确地分类为阳性。尽管如此,我们仍会有许多假阳性,因为真正的阴性也被归类为阳性,这导致了高召回率和低精确度。

另一方面,如果我们保持一个非常高的阈值,该模型做出的大多数正面预测都将是正确的,因为该模型在其所谓的正面预测中非常保守。然而,我们会为了追求始终正确而错过许多实际的肯定,这导致了高精度和低召回率。

注意,在联合优化召回率和精确度之间有一个折衷。像 ROC-AUC 一样,一个完美的分类器应该具有 PR-AUC=1。这条曲线下的面积是 PR-AUC。

然而,在类别分离非常清楚的完美分类器中会存在阈值。所有的正面例子都会在这个阈值以上,所有的负面例子都在这个阈值以下。在这种情况下,AUC 最大,等于 1。

PR-AUC 相对于 ROC-AUC 的显著优势在于,当出现阶层失衡时,它不会产生误导。在不平衡的情况下,ROC-AUC 可以高于 PR-AUC。

排名指标

除了分类,我们还想了解分数的排名顺序。推荐系统的目标不仅仅是挑选出相关的项目,还要根据偏好对它们进行排序。根据福布斯的一篇文章:

谷歌的第一页捕获了 71%的搜索流量点击,据报道近年来高达 92%。第二页的结果远远没有接近第二,在所有网站点击量中不到 6%。

如果你选择了相关的项目,但没有订购它们,这是没有用的。那么我们如何测试我们的模型是否有排名能力呢?

  • 归一化贴现累计收益(NDCG)

想象一下你的模型向用户提出的一系列十个建议。你希望看到获得最大点赞的最佳推荐顺序。以下是用户对这十个视频的回应

1,0,0,1,0,1,1,0,1,0,1,0 …(1)

用户喜欢第一、第四、第六、第七和第九条建议。这里订购的最佳案例是什么?

1,1,1,1,1,0,0,0,0 …… (2)

也就是说,如果我们推荐第一、第四、第六、第七、第九,然后是其他的,我们将会获得最好的排名。请注意,第一、第四、第六、第七和第九之间的任何排列都会产生相同的排名。

要计算 NDCG:

NDCG

Normalised discounted cumulative gains (NDCG) | Source

reli 在我们的例子中表示项目 I-0 或 1 的相关性。p 是项目的总数。对于较低的级别(较低的 I ),总和下的术语比较高的级别具有更大的权重。IDCGp 仅获取相关项目并计算总和,这是通过将所有相关项目排在顶部(表达式 2)并将不相关项目排在底部可以获得的最大 DCG 分数。

注意,对于不相关的项目,分子是 0 (20-1=0)。DCGp 计算分数时,将所有的 p(相关和不相关)按照代表我们的模型在对项目评分后如何对它们进行排序的顺序(表达式 1)来计算。

请注意,NDCG 位于 0 和 1 之间。

如上所述,召回率是模型在全部现有的肯定信息中捕获的肯定信息的比例。对于一组排序的推荐,考虑在位置 k 的特定排序。在位置 1 到 k 中出现的肯定的数量除以肯定的总数量给出我们在 k 的召回

对于许多系统来说,获得所有相关的结果是必不可少的,即使是以一些不相关的结果为代价。在这种情况下,recall@k 给了我们一个关于覆盖率的概念。

与 recall@k 类似,precision@k 计算等级为 k 的模型的精度。这意味着它计算模型正确预测的阳性分数除以总阳性预测。

对于可能不需要全部,而只需要正确结果的情况,precision@k 有助于量化它。

深潜

推荐系统因有偏见而臭名昭著。在我们为 YouTube 建立推荐模型的例子中,我们可能会发现总体 AUC 是好的。然而,当我们在不同层面上分析这些指标时,例如,较长视频与较短视频的 AUC,我们发现较长视频的指标较差,这意味着模型没有很好地学习推荐较长视频。

类似的影响可能发生在任何属性上——地理位置、用户统计数据、主题。知道你的模型哪里做得好,哪里不好是有帮助的。

解决偏见

推荐系统通常比不太受欢迎的长尾内容更多地推送受欢迎的内容。因为受欢迎的内容更有可能被任何随机用户所偏好。这使得该模型能够找到一个“快速修复”的解决方案来最小化损失。然而,用户有许多未开发的兴趣,或者用户可能喜欢许多不太流行的东西。尽管如此,因为它们在训练数据集中出现的频率不高,所以它们的嵌入没有被准确地学习,从而导致偏差。想象一下,Spotify 上仅有的几个流行歌手会获得 Spotify 上数百万歌手中近 90%的播放量。

推荐系统在一个循环中被训练。如果系统向用户推荐有偏见的内容,将对这些有偏见的推荐进行以下训练。随着时间的推移,分布向流行项目倾斜,因为对这些项目的反馈比其他项目观察到的更多——偏差复合。

为什么解决偏见很重要?推荐热门内容有什么问题?如前所述,这使得探索用户的其他兴趣变得困难。从短期来看,流行的内容可能会留住用户,但最终,用户会发现应用程序上没有什么新奇的东西。其次,这使得新创作者很难在应用程序上获得牵引力。新的创作者将没有动力去创造吸引人的、多样化的内容。最终,他们可能会离开这个应用程序。

你如何衡量偏见?

一种简单的方法是查看视图分布。前 1%、5%、10%……的视频获得了多大比例的浏览量,与其他视频相比,这些视频被推荐给用户的频率如何。这种 80-20 效应可以在话题(特定话题主导 app)、创作者(少数热门创作者 vs 小众创作者)等方面看到。机器学习模型学习数据集中的偏差等。因此,如果您的数据集有偏差,那么您的推荐结果很可能会反映出来。

通常,模型会基于某个特征隐含地学习某些偏见。例如,不久前,如果你在谷歌上搜索“CEO”这个词,最上面的结果会是白人男性的照片。类似地,像“护士”这样的词的结果大部分是女性。然而,CEO 这个词是中性的。

根据 washington.edu 的一篇文章:

研究发现,在一些工作中,差异很明显。在谷歌搜索首席执行官的图片中,11%的人是女性,而美国的首席执行官中有 27%是女性。在针对作者的图片搜索结果中,25%的人是女性,相比之下,实际的美国作者中有 56%是女性。

相比之下,图片搜索结果中 64%的电话销售人员是女性,而这一职业男女各半。

测量由属性/特征引起的偏差的一种常用方法是统计奇偶性。简而言之,它测量给定受保护属性 p (例如性别)的模型结果(概率)与没有它的结果的差异。一个无偏的模型应该有:

拥有关于 p 的额外信息不会有什么不同。

如何减轻偏见?

创建更公平的推荐系统是一个活跃的研究领域。解决偏见的一个流行策略是负抽样。在我们的 YouTube 推荐示例中,我们有点击数据。如果我们想要创建一个基于点击预测的推荐模型,我们只有来自受欢迎程度影响的视频的点击数据。为了平衡这一点,我们通过为用户选择随机视频并给他们分配负类来创建样本。这个想法是用户喜欢随机视频的可能性非常低。通过这种方式,我们消除了数据分布的偏差。

除了负面抽样,许多评分机制衡量候选人的多样性。在基于会话的推荐中,可以通过获取用户观看的前 N 个项目并测量要推荐的更多样的主题来引入更多样的推荐。例如,如果有人阅读一些关于政治和电影行业的文章,下面的推荐可以包括一些体育行业的项目。

最大边缘相关度( MMR ) 是信息检索中使用的一种在相关性和多样性之间取得平衡的度量。根据这篇论文——

Maximum Margin Relevance (MMR)

Maximum margin relevance (MMR) | Source

对于给定的 C 和 Q,C 是文档集合,Q 是查询,R 是由 IR 系统检索的文档的排序列表,S 是 R 中已经选择的文档的子集;RS 是 R 中而不是 S 中的文档集;Sim1 是在文档检索和文档(段落)与查询之间的相关性排序中使用的相似性度量;Sim2 可以与 Sim1 相同,也可以是不同的度量。当参数λ=1 时,MMR 递增地计算标准相关性排序列表,并且当λ=0 时,计算 R 中的文档之间的最大多样性排序。

在线评估

A/B 实验

我们训练模型的目标和我们测量的离线指标可能不是我们在现实中寻找的。例如,如果 YouTube 创建了最准确的模型来预测点击,这可能并不意味着用户流失会减少。尽管该模型推荐了用户喜欢的所有视频,但他们可能仍然会离开,第二天不会回来。

其次,精确地按照一个人想要的来训练一个模型是很难的。例如,训练一个模型来推荐视频以减少流失比基于点击推荐视频更复杂。

标准在线指标包括:

  • 用户保持率
  • 参与度(喜欢、书签、关注等。)
  • 点击
  • 购买
  • 收入
  • 花费的时间
  • 建议的多样性。

对任何模型来说,最终的关键时刻是现场 A/B 测试。对照现有模型测试新的变化。例如,假设说学习速度应该是当前速度的 10 倍。我们为平台上的一组随机用户推出了一个新的学习率模型来测试这一点。由于当前模型和新版本运行在相同的用户分布上,在线指标的任何变化都只能归因于学习率的变化。人们可以根据净变化来决定新的变化是好是坏。

测试推荐系统

模型评估与测试

我们看到了如何使用各种度量和分析来评估推荐模型,以便我们的实验和假设成立。然而,当模型交付生产时,事情仍然可能出错。即使是很小的工程错误也会导致意想不到的推荐和糟糕的用户体验。因此,测试每个步骤——推理、重新训练周期、数据集创建和功能范围——对于在线部署至关重要。

在这一节中,我们将看看测试整个推荐系统的一些方法——从模型的行为到管道的健康状况。

推荐系统的行为检查

测量嵌入更新率

由于 RecSys 模型是建立在嵌入基础上的,因此确保正确训练嵌入是至关重要的。每次重新训练,用户和项目的嵌入都会更新。要检查的一个重要指标是不同用户/项目嵌入版本的平均漂移。可以通过测量余弦相似性来检查漂移。

例如,如果用户 A 昨天的嵌入是 e1,并且在重新训练之后是 e2,则漂移被测量为余弦(e1,e2)。理想情况下,该数值不应大于 0.9,但也不应太接近 1。如果太小,则表明嵌入没有收敛。如果它太接近 1,则表明该模型可能没有捕捉到用户的新兴趣。

不同切割的指标

如前所述,单个数字指标看起来可能具有欺骗性。例如,10%的流行项目可以构成 80%的数据集。测量整个数据集的 AUC 可以给出乐观的数字,因为模型必须很好地学习 10%的项目。但是,这意味着模型没有很好地学习项目的长尾。这种疏忽会导致差的多样性和新颖性。在这种情况下,可以分析项目级的度量,并检查所有项目是否都表现得相当好。这同样适用于许多其他属性,如用户、性别、地理位置等。

基于会话的模型的方差测试

基于会话的模型要求模型立即使用新信息来更新建议。一个好的基于会话的推荐模型能够快速准确地适应用户当前的兴趣。

考虑一个基于 RNN 的模型,该模型采用前 N 次交互来为第 N+1 个位置推荐物品。如果模型偏向于流行,势必会推荐 N-2,N-1,N 次交互后的流行单品。然而,一个好的模型会在每次交互后推荐一组不同的项目。在数学上,我们可以看到 RNN 模型中每个时间步长后隐藏状态的变化,就像我们计算嵌入漂移一样(如上所述)。

类似地,如果用户与 10 个跨不同主题(如人工智能、喜剧或足球)的视频进行交互,并对喜剧视频做出积极响应,对其他主题做出消极响应,则下一个推荐应该包括有趣的视频。人们可以在会话历史中测量对某些主题/流派的相似性,并在下一组推荐中测量其表现。

软件检查推荐系统

除了标准的单元和集成测试之外,还有一些 RecSys 特有的行为测试,您应该了解一下”

  • 特征一致性:在模型训练过程中,我们可能会用到除嵌入之外的许多特征,比如用户位置、年龄、视频长度等。在使用这些功能之前,通常会对其应用缩放等变换。然而,由于对特征的错误处理,这增加了推断过程中出错的机会。例如,如果您在训练中缩放了某个要素,但在推理中没有缩放,则模型预测可能会发生变化。
  • 泄漏特征:许多模型,如基于会话的模型,在每次交互中使用接近实时的信息。例如,用户与之交互的项目数量。如果用户与六个项目 A、B、C、D、E 和 F 交互;该特征的值可以是 0、1、2、3、4、5;因为用户在点击 A 之前与 0 个项目交互,在点击 B 之前与 1 个项目交互,以此类推。我们只使用事件发生前可获得的信息。在离线训练期间,我们应该问在从表中选择数据时,它是否会导致训练中的泄漏。
  • 更新嵌入:推荐模型,定期训练。在每个训练周期之后,更新的嵌入应该用于推荐项目。使用旧的嵌入会导致不一致和不准确的推荐。

测试推荐系统的工具

以下是一些测试推荐系统不同阶段的相关工具:

1.数据集创建和特征工程

跟踪特征分布和特征值中的异常是需要跟踪的几个关键数字。通常,推荐模型训练是通过诸如 airflow 或 kedro 之类的工具在 DAGs 中执行的。创建数据集后,可以编写一个测试套件,根据数据中的统计信息测试预期的统计信息。根据可接受的误差范围,可以创建警报。Pytest 是编写这种单元测试的流行工具。

2.培训和部署

大多数推荐模型是使用基于梯度下降的优化以深度学习的方式训练的。自然,学习率和训练步数的重量衰减等超参数开始发挥作用。使用上面讨论的度量和训练-验证损失曲线可以发现训练中的突然性。像 Neptune 这样的工具允许用最小的代码变化来监控模型训练。使用 Neptune 的简单 API 可以记录曲线、指标、超参数和脚本

RecList 这样的开源工具提供了一个易于使用的界面来计算推荐模型评估中最常见的指标。给定数据集和模型,RecList 可以在目标数据集上运行指定的测试。除了度量之外,它还基于不同的切片生成图表和深度聚合。

3.推理

推理需要特性的一致性、可用性、最小延迟以及对更新模型的访问。每一次代码变更,数据科学家都必须确保以上几点。软件工程实践,如代码审查、版本控制(如 Git ),以及自动化测试阶段的 CI/CD 流程(Jenkins,GitHub actions ),确保了安全的软件发布。

结论

在人工智能的许多领域中,如自然语言处理、计算机视觉等,推荐系统的研究相对不足。然而,它们是现代数字应用中最具影响力的应用之一。尽管评估它们并不简单,但是上面的度量标准和想法是一个很好的起点。记住,你应该建立一个推荐系统,而不是一个模型。从长远来看,投资建设坚实的基础设施比制造一个 SOTA 模式更有帮助。**

如何在您的项目中跟踪机器学习模型指标

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-track-machine-learning-model-metrics

跟踪机器学习模型的评估指标至关重要,以便:

  • 了解您的模型做得如何
  • 能够将它与以前的基线和想法进行比较
  • 了解你离项目目标有多远

“如果你不衡量它,你就不能改进它。”

但是你应该跟踪什么呢?

我从来没有发现自己在这样的情况下,我认为我已经为我的机器学习实验记录了太多的指标。

此外,在现实世界的项目中,您所关心的指标可能会由于新的发现或不断变化的规范而改变,因此记录更多的指标实际上可以在将来为您节省一些时间和麻烦。

不管怎样,我的建议是:

“记录比你认为需要的更多的指标。”

好吧,但是你具体是怎么做的呢?

跟踪单一数字的指标

在许多情况下,您可以为机器学习模型的性能分配一个数值。您可以计算保留验证集的准确度、AUC 或平均精度,并将其用作模型评估指标。

在这种情况下,您应该跟踪每次实验运行的所有这些值。

借助 Neptune,您可以轻松做到这一点:

neptune.log_metric('train_auc', train_auc)
neptune.log_metric('valid_auc', train_auc)
neptune.log_metric('valid_f1', train_auc)
neptune.log_metric('valid_accuracy', train_auc)

跟踪训练数据集和验证数据集的度量可以帮助您评估模型在生产中表现不佳的风险。差距越小,风险越低。Jean-Fran ois Puget 的《kaggle days》是一个很好的资源。

也就是说,有时候,一个单一的值不足以告诉你你的模型是否运行良好。

这就是性能图表发挥作用的地方。

跟踪作为性能图表的指标

要了解您的模型是否有所改进,您可能需要查看图表、混淆矩阵或预测分布。

在我看来,这些仍然是指标,因为它们帮助你衡量你的机器学习模型的性能。

对于 Neptune 测井,这些图表是微不足道的:

neptune.log_image('diagnostics', 'confusion_matrix.png')
neptune.log_image('diagnostics', 'roc_auc.png')
neptune.log_image('diagnostics', 'prediction_dist.png')

如果您想要使用二进制分类指标,您可以记录:

  • 所有主要指标,如 f1、f2、brier_loss、准确性等

t

  • 所有主要的性能图表,如混淆矩阵、ROC 曲线、精确召回曲线

import neptunecontrib.monitoring.metrics as npt_metrics//r//n//r//nnpt_metrics.log_binary_classification_metrics(y_test, y_test_pred)

跟踪迭代级别的度量(学习曲线)

大多数机器学习模型迭代收敛。深度学习模型、梯度提升树和许多其他模型都是如此。

您可能希望在每次迭代之后跟踪训练集和验证集的评估度量,以查看您的模型是否监控过度拟合。

监控这些学习曲线很容易实现,但却是重要的习惯。

对于简单的基于迭代的训练,它可能是这样的:

for i in range(iterations):

   train_loss = loss(y_pred, y)
   neptune.log_metric('train_loss', train_loss)

在大多数深度学习框架中使用的回调系统的情况下:

class NeptuneLoggerCallback(Callback):
    ...
    def on_batch_end(self, batch, logs={}):
        for log_name, log_value in logs.items():
            neptune.log_metric(f'batch_{log_name}', log_value)

Neptune 集成了大多数主要的机器学习框架,您可以毫不费力地跟踪这些指标。在此检查可用的集成。

在每个时期后跟踪预测

有时,您可能希望在每个时期或迭代后查看一下模型预测。

这在训练需要大量时间收敛的图像模型时尤其有价值。

例如,在图像分割的情况下,您可能希望在每个时期后绘制预测遮罩、真实遮罩和原始图像。

在 Neptune 中你可以使用.log_image方法来做到这一点:

for epoch in epochs:
     …
     mask_preds = get_preds(model, images)
     overlayed_preds = overlay( images, masks_true, masks_pred)
     neptune.log_image('network_predictions', overlayed_preds)

培训完成后跟踪指标

在某些应用程序中,您无法跟踪培训脚本中所有重要的指标。

此外,在现实生活中的机器学习项目中,项目的范围以及您关心的度量标准可能会随着时间的推移而变化。

在这些情况下,您将需要更新实验指标,或者在您的培训工作已经完成时添加新的性能图表。

幸运的是,用海王星更新实验很容易:

exp = project.get_experiments(id='PROJ-421')[0]

exp.log_metric('test_auc'; 0.62)
exp.log_image('test_performance_charts', 'roc_curve_test.png')

请记住,为一个实验或模型引入新的指标意味着您可能需要重新计算和更新以前的实验。通常情况下,一个模型在一个度量上可能更好,而在另一个度量上可能更差。

最后的想法

在本文中,我们了解到:

你应该记录你的机器学习指标

  • 如何跟踪单值指标并查看哪些模型表现更好
  • 如何跟踪学习曲线以实时监控模型训练
  • 如何跟踪性能图表以了解更多信息
  • 如何在每个时期后记录图像预测,
  • 如果在培训结束后计算评估指标,如何更新实验指标
  • 快乐训练!

Happy training!

如何使用 TensorFlow 对象检测 API 训练自己的对象检测器

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-train-your-own-object-detector-using-tensorflow-object-detection-api

目标检测是一项计算机视觉任务,最近受到机器学习进展的影响。

在过去,创建一个定制的对象检测器看起来是一项耗时且具有挑战性的任务。现在,有了像 TensorFlow 对象检测 API 这样的工具,我们可以快速轻松地创建可靠的模型。

在本文中,我们将重点介绍第二代 TensorFlow 对象检测 API,它:

  • 支持张量流 2,
  • 允许您使用最先进的模型架构进行对象检测,
  • 为您提供了一种配置模型的简单方法。

如果你有兴趣了解 TensorFlow 2 及其 API 中所有可用的特性,你可以在 Google 的官方公告中找到它们。

阅读完本文后,您应该能够创建自己的自定义对象检测器。

我们将使用基于 EfficientDet 的模型作为示例,但是您也将学习如何使用您选择的任何架构来启动并运行模型。敬请期待!你自己的物体探测器就在眼前。

开始之前

让我简单地谈谈开发您自己的对象检测器所必需的先决条件:

  • 你应该在你的电脑上安装 Python。如果你需要安装它,我推荐遵循 Anaconda 的官方指南。
  • 如果你的计算机有一个支持 CUDA 的 GPU(NVIDIA 制造的 GPU),那么需要一些相关的库来支持基于 GPU 的训练。如果您需要启用 GPU 支持,请查看 NVIDIA 网站上的指南。您的目标是为您的操作系统安装 CUDA 工具包和 cuDNN 的最新版本。

安装和设置

让我们首先确保我们已经准备好开始使用 TensorFlow 对象检测 API 所需的一切。我将回顾整个设置过程,并解释每一步的工作原理。

如果您已经使用过 TF API,您仍然可以快速浏览一下这一部分,只是为了确保我们遵循相同的方向。

但是如果您是第一次安装 Tensorflow 对象检测 API,我强烈建议您完成本节中的所有步骤。让我们跳进来吧!

1。创建项目目录

在您选择的路径下,创建一个新文件夹。命名为Tensorflow

2。创建新的虚拟环境

打开一个终端窗口,使用cd命令导航到步骤 1 中创建的Tensorflow文件夹。

  • 使用venv库创建一个新的虚拟环境:

  • 如果您的机器上已经安装了venv(或者您更喜欢使用另一个工具来管理环境,如【Anaconda),那么直接进行新环境的创建。

如果你不知道什么是venv或者没有安装它,你可以在你的终端窗口中输入以下命令:

为了使用venv创建一个新环境,在您的终端窗口中键入以下命令:

pip install venv

一旦执行完毕,venv将创建一个名为tf2_api_env的新虚拟环境。

python -m venv tf2_api_env

激活新创建的虚拟环境:

  • 为了激活我们刚刚创建的虚拟环境,您首先需要确保您当前的工作目录是Tensorflow。您可以通过在您的终端窗口中键入并执行以下命令来检查您当前的工作目录:

为了激活您的虚拟环境,从您的终端窗口运行以下命令:

pwd

如果您在您的终端窗口的命令行开头看到您的环境的名称,那么您就一切就绪了。它应该是这样的:

source tf2_api_env/bin/activate

是时候在我们的环境中安装 TensorFlow 了。确保您的环境已激活,并通过执行以下命令进行安装:

virtual environment activation

Successful virtual environment activation in the Terminal window

注:在我写这篇文章的时候,最新的 TensorFlow 版本是 2.3。您可以使用这个版本,但这不是必需的。我们在本指南中所做的一切都是与 2.3 兼容的,它也可能适用于以后的更新。这取决于你去尝试。如果有任何问题,您可以随时降级到 2.3 并继续前进。

pip install tensorflow==2.*

3。下载并提取 TensorFlow 模型花园

模型花园是 github.com 的官方张量流存储库。在这一步中,我们希望将这个回购克隆到我们的本地机器上。

确保在你的终端窗口中,你位于Tensorflow目录中。

  • 在您的 web 浏览器中,转到 Model Garden Repo 并点击代码按钮,以便选择最适合您的克隆方法(选项有 HTTPS、SSH 或 GitHub CLI)。

  • 选择克隆方法后,将存储库克隆到您的本地Tensorflow目录。如果你在克隆方面需要额外的帮助,请查看官方 GitHub 指南。

cloning metod

Selecting a cloning method for an official Model Garder Tensorflow repo

  • 到现在为止,在Tensorflow目录下应该有如下结构:

4。下载、安装并编译 Protobuf

Tensorflow/
└─ tf2_api_env/
   ├─ bin/
   ├─ include/
   └── …
└─ models/
   ├─ community/
   ├─ official/
   ├─ orbit/
   └── …

默认情况下,TensorFlow 对象检测 API 使用 Protobuf 来配置模型和训练参数,因此我们需要这个库来继续。

前往官方协议发布页面下载与您的操作系统和处理器架构兼容的最新 protobuf 版本的档案。

  • 比如我用的是 Ubuntu 。我的 CPU 是 AMD64 (64 位处理器)。当我写这篇文章时,最新的协议版本是 3.13.0 。鉴于所有这些信息,我将从官方协议发布页面下载protocol-3 . 13 . 0-Linux-x86 _ 64 . zip文件。

Tensorflow项目目录中,创建一个名为protoc的新文件夹。将下载的档案内容解压到Tensorflow/protoc目录。

  • 现在,您的Tensorflow目录结构应该如下所示:

确保在你的终端窗口中,你位于Tensorflow目录中。要编译 proto 文件,请执行以下命令:

Tensorflow/
└─ protoc/
   ├─ bin/
   ├─ include/
   ├─ readme.txt
└─ tf2_api_env/
   ├─ bin/
   ├─ include/
   └── …
└─ models/
   ├─ community/
   ├─ official/
   ├─ orbit/
   └── …

5。安装 COCO API

protoc/bin/protoc models/research/object_detection/protos/*.proto
--python_out=.

COCO API 是一个不直接与对象检测 API 相关的依赖项。您应该单独安装它。手动安装 COCO API 引入了一些新功能(例如,一组流行的检测或/和分割指标可用于模型评估)。安装过程如下:

如果您使用的是 Windows:

确保在你的终端窗口中,你位于Tensorflow目录中。逐一运行以下命令:

  • 如果您使用的是 Linux:
pip install cython
pip install git+https://github.com/philferriere/cocoapi.git

确保在你的终端窗口中,你位于Tensorflow目录中。逐一运行以下命令:

  • 在这一步结束时,您的Tensorflow目录结构应该如下所示:
pip install cython
git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI
make
cp -r pycocotools ./models/research/

6。对象检测 API 安装

Tensorflow/
└─ cocoapi/
   ├─ common/
   ├─ LuaAPI/
   └── …
└─ protoc/
   ├─ bin/
   ├─ include/
   ├─ readme.txt
└─ tf2_api_env/
   ├─ bin/
   ├─ include/
   └── …
└─ models/
   ├─ community/
   ├─ official/
   ├─ orbit/
   └── …

这是我们的安装和设置块的最后一步!我们将安装对象检测 API 本身。你可以通过安装 object_detection 包来实现。方法如下:

确保在你的终端窗口中,你位于Tensorflow目录中。

  • 使用cd命令将当前工作目录从Tensorflow更改为Tensorflow/models/research

  • 在您的终端窗口中逐一运行以下命令:

  • 注意:****第二个命令可能会给你一个错误。一点也不担心。只需再运行一次,直到你看到一个完整的安装。

cp object_detection/packages/tf2/setup.py .
python -m pip install .

终端窗口的Tensorflow/models/research目录下运行以下命令,测试安装是否成功:

  • 一旦测试完成,您将在您的终端窗口中看到一条打印出来的消息。如果所有 20 个测试都运行了,并且它们的状态是“OK”(有些可能会被跳过,这完全没问题),那么您就完成了安装!
python object_detection/builders/model_builder_tf2_test.py

工作量很大,所以恭喜你!干得好!

数据准备

当您完成所有安装步骤时,您需要考虑稍后将输入到自定义对象检测模型中的数据。

基于 TensorFlow 对象检测 API 的模型需要一种特殊的格式用于所有的输入数据,称为 TFRecord 。我们将讨论如何将您的数据转换成 TFRecord 格式(为了更好地理解什么是 TFRecord 格式,我强烈推荐阅读这篇文章),但是首先让我们讨论一些关于您的数据可用性及其注释的假设。具体来说,我们假设:

您已经收集了数据(图像)用于模型训练、验证和测试,

  • 您的图像被注释用于对象检测,这意味着您的数据集中可能出现的所有感兴趣对象的区域被手动定义为边界框,并且为每个框设置了基本事实标签。
  • 如果这些假设对你来说是错误的,你将无法继续进行你的物体检测创作。很简单:没有数据,没有模型。

好消息是有许多公共图像数据集。我强烈建议花些时间搜索你感兴趣的数据集。很有可能你会找到值得你花时间去做的事情。

如果你需要注释,有吨的解决方案可用。挑一个你喜欢的。它们都会给你 JSON 或 XML 格式的注释。两者都适合我们的目的。

这里我不会在图像收集和注释上花太多时间——我希望您能够自己解决这个问题,这样我们就可以进入下一个重要步骤:数据转换。

https://web.archive.org/web/20221206004728im_/https://neptune.ai/wp-content/uploads/2022/11/image-annotation-process.mp4

Image Annotation Process | Source: Article by Rei Morikawa at lionbridge.ai

数据转换

我提到过您的输入数据需要 TFRecord 格式。这一步的目标是将每个数据集(训练、验证和测试)转换成 TFRecord 格式。

为了确保可比性,让我们在您的Tensorflow目录中创建一个名为workspace的子文件夹。我们将使用workspace文件夹来存储所有与模型相关的属性,包括数据。

为了存储所有的数据,让我们在Tensorflow/workspace中创建一个名为data的单独文件夹。我们最终得到的所有转换后的数据集都将被放置在Tensorflow/workspace/data中。

在这一步结束时,您的Tensorflow目录将如下所示:

现在回到数据转换。使用流行的图像注释工具创建的大多数注释文件都有两种格式:JSON 或 XML。

Tensorflow/
└─ cocoapi/
└─ protoc/
└─ tf2_api_env/
└─ models/
└─ workspace/
   └─ data/
      ├─ train.record
      ├─ validation.record
      ├─ test.record

弄清楚你的数据有什么格式的注释。你需要它来选择一个合适的工具来转换到 TFRecord

选项#1: 您的注释是 JSON 格式的。我的建议是:

选项#2: 你的注释采用的格式类似于 COCO、Kitti 或 Pascal 等流行数据集所采用的格式(注意:Pascal 注释采用的是我们已经知道的 XML 格式,并且之前在选项#1 中使用过)。在这种情况下,我建议你:

标签地图创建

标签地图是一种简单的。txt 文件(。确切的说是 pbtxt)。它将标签链接到一些整数值。TensorFlow 对象检测 API 需要此文件来进行训练和检测。

为了理解如何创建这个文件,让我们看一个简单的例子,其中我们只想检测两个类:汽车和自行车。别的都不重要,就这两个物件。让我们看看label_map.pbtxt对于这样一个任务会是什么样子:

现在您知道如何创建自己的标注地图了。选择您选择的文本编辑器(或 IDE)(我使用了 atom ,并创建一个标签映射文件,该文件反映了您将使用未来对象检测器检测的类的数量。给所有的类起一个有意义的名字,这样你就可以很容易的理解和区分它们。

label map file

Example of a label map file for two classes: car and bike

完成后,将新创建的label_map.pbtxt放入Tensorflow/workspace/data目录。你的Tensorflow/workspace/data目录现在应该包含 4 个文件:

train.record

  • validation.record
  • test.record
  • label_map.pbtxt
  • 数据准备到此为止!你向你的物体探测器又迈进了一大步。每一个机器学习项目最本质(可以说)的部分都完成了。您已经有了数据,并准备好输入到您的模型中。

接下来,我们将继续模型架构的选择和配置。继续前进!

型号选择和配置

在教程的这一部分,我们要做两件事:

首先,选择一个要使用的模型架构。幸运的是,有很多选择,而且都很棒。

  • 第二,我们将致力于模型配置,因此它可以处理期望的任务,高效,在您可能经历的资源限制下工作,并且具有足够好的概括能力以用于现实世界。
  • 这是我最喜欢的部分之一,因为这是机器学习开始的地方!我们开始吧!

型号选择

TensorFlow 对象检测 API 最酷的功能之一是有机会与一组先进的模型一起工作,这些模型是在 COCO 数据集上预先训练的!我们可以根据我们的目的微调这些模型,并获得很好的结果。

现在,您需要选择并下载模型:

单击您选择的型号名称开始下载。

  • Tensorflow/workspace/目录中,创建一个名为pre_trained_models的新文件夹,并将下载的模型解压到这个新创建的目录中。

  • 如果你想用不同的架构训练多个模型,然后比较它们的性能来选择一个胜出的模型(听起来是个好主意!),您现在应该下载这些模型并将它们全部解压缩到pre_trained_models目录。

  • 现在,您的项目目录应该如下所示:

Tensorflow/
└─ cocoapi/
└─ protoc/
└─ tf2_api_env/
└─ models/
└─ workspace/
   └─ data/
   └─ pre_trained_models/
      ├─ <folder with the 1st model of your choice>
      ├─ <folder with the 2nd model of your choice>
      ├─ …
      ├─ <folder with the N model of your choice>

车型配置介绍

我们下载并提取了一个预先训练好的模型。现在我们要对它进行配置。我们想这么做可能有多种原因。让我给你举几个例子,这样你就能明白为什么配置是必不可少的:

您的问题域和您的数据集与用于训练原始模型的不同:您需要一个自定义对象检测器(可能是您阅读本文的原因),

  • 您有不同数量的对象类别要检测,
  • 您尝试检测的对象可能与预训练模型应该检测的对象完全不同,
  • 你可能有较少的计算能力来训练一个模型,这也应该被考虑在内。
  • 所以你明白为什么你需要配置你的模型了。原因不胜枚举,但让我们继续前进。我们稍后会用一个真实的例子详细讨论它。

现在,我希望大家记住,模型配置是一个让我们定制模型相关工件(例如超参数、损失函数等)的过程,以便可以对其进行训练(微调)来处理我们感兴趣的对象的检测。就是这样。

TensorFlow 对象检测 API 允许通过预训练模型附带的pipeline.config文件进行模型配置。

项目目录组织

在进入模型配置之前,让我们首先组织我们的项目目录。这是帮助我们保持整个项目结构整洁和易于理解的重要一步。

我们现在想要创建另一个目录,用于存储与不同模型架构及其配置相关的文件。

你可能会问:

“等等,安东,我们已经有了模型架构的pre_trained_models文件夹!我们究竟为什么不用它?”

这是一个公平的观点,但我的个人经验引导我找到了一个不同的、更干净的解决方案。相信我,最后你会喜欢的!你需要做的是:

转到Tensorflow/workspace并创建一个名为models的新目录。

  • Tensorflow/workspace/models中,创建另一个目录,其名称对应于您决定使用的模型架构(您下载到Tensorflow/workspace/pre_trained_models的那些模型)。

  • 例如,我想训练一个基于 EfficientDet 架构的对象检测器。我注意到在 TF 2 检测模型 Zoo 页面有多个 EfficientDets 可用,它们有不同的深度(从 D0 到 D7,更多信息可以在这里找到)。

我想我会首先使用最基本的一个,即 EfficientDet D0 512×512 ,但后来也尝试了 EfficientDet D1 640×640 ,它更深入,可能会获得更好的性能。因此,在我的例子中,我需要创建两个文件夹:efficientdet_d0efficiendet_d1

目录名的选择由你决定。重要的是为您想要使用的每个模型架构创建一个目录,并且在文件夹的名称中包含模型架构信息。就是这样。

到目前为止,您的项目目录结构应该类似于以下内容:

转到Tensorflow/workspace/pre_trained_models并打开包含您想要配置的模型的目录

Tensorflow/
└─ ...
└─ workspace/
   └─ data/
   └─ pre_trained_models/
   └─ models/
      ├─ <folder with the 1st model of your choice>
      ├─ <folder with the 2nd model of your choice>
      ├─ …
      ├─ <folder with the N model of your choice>	
  • 在那里寻找pipeline.config文件。将该文件复制到Tensorflow/workspace/models/<folder with the model of your choice>/v1/内的相应文件夹中(您需要创建v1文件夹。我稍后会解释它的用途)。

  • 复制后,使用文本编辑器或您选择的 IDE 从Tensorflow/workspace/models/<folder with the model of your choice>/v1/打开pipeline.config文件。打开后,您应该会看到类似这样的内容:

  • 现在您已经准备好开始进行模型配置了!下一节将解释如何正确地做到这一点。

opened pipeline

Example of an opened pipeline.config file for EfficientDet D1

除了适当的文件夹和命名结构之外,对组织使用实验跟踪工具也有助于保持整洁。

配置过程:基础

我决定将模型配置过程分为两个部分。

首先,我们来看看基础知识。我们将触及一组需要配置的最小参数,以便开始训练并获得结果……一个基线结果。

使用这种方法,开始工作非常容易,但是会牺牲最终模型的性能。这将是完全可行的,但不会尽如人意。

第二步,我们将重点调整各种可用的模型参数。我将为您提供一个框架,您可以使用它来调整您想要的每个模型参数。

你将有很大的权力来控制模型配置,并且能够使用不同的设置来进行测试,并获得最佳的模型性能。

听起来很刺激?是啊,它是!让我们开始吧。

查看您之前从Tensorflow/workspace/models/<folder with the model of your choice>/v1/打开的pipeline.config文件。无论您决定使用哪种型号,您的基本配置都应符合以下型号参数:

num_classes (int)。您必须提供您的模型将要检测的类的准确数量。默认情况下,它等于 90,因为预训练模型应该用于 COCO 数据集中的 90 个对象。

  • 数量 _ 类别参数。效率检测 D1 的例子

code

batch_size (int,必须能被 2 整除)。这个值应该根据您有多少可用内存来设置。请记住,批量越大,您的机器/GPU 需要的内存就越多。如果你不知道最初该用哪个数字,我建议从batch_size = 8 开始

  • 注意: batch_size参数需要在pipeline.config文件内的两个地方设置:在train_configeval_config(见下图)

train _ config 中的 batch_size 参数效率检测 D1 的例子

code

eval _ config 中的 batch_size 参数。效率检测 D1 的例子

code

对于eval_config你必须用 1。对于train_confid,使用我上面描述的逻辑。

微调检查点。这里是您提供预训练模型检查点的路径的地方。

  • 善意提醒,你需要的关卡位于Tensorflow/workspace/pre_trained_models/<folder with the model of your choice>/checkpoint/ckpt-0

只需将<folder with the model of your choice>替换为预训练模型所在文件夹的名称。

fine_tune_checkpoint_type (str)。该字段应设置为detection,因为我们想要训练一个检测模型。

  • use_bfloat16(布尔)。如果您不打算在 TPU 上训练模型,该字段应设置为false。否则设置为true
  • label_map_path (str)。在这里,您可以提供一个到先前创建的label_map.pbtxt的路径。
  • 另一个善意的提醒:我们把label_map.pbtxt放到了Tensorflow/workspace/data目录下。

注意: label_map_path参数需要在pipeline.config文件中的两个地方设置:在train_input_readereval_input阅读器中(见下图)

train _ input _ reader 内的 label_map_path 参数。效率检测 D1 的例子

code

eval _ input _ reader 内的 label_map_path 参数。效率检测 D1 的例子

code

input_path (str)。在这里,您提供了一个到您之前创建的train.recordvalidation.record的路径。您可能已经猜到,到validation.record的路径应该设置在eval_input_reader内,而到train.record的路径应该设置在train_input_reader内。

  • 我最后善意的提醒:我们还将所有的.record files放在了Tensorflow/workspace/data目录中。

我们刚刚完成基本配置,这是开始训练您的自定义对象检测器所必需的。很难吗?绝对不会。只要多行修改,你就可以开始了。

您可能已经注意到,与我们在基本配置过程中使用的几行相比,pipeline.config文件要长得多。配置空间大吗?绝对是!让我们看看还能做些什么来使我们的模型更健壮。

配置过程:高级

如何调整配置文件中的其他参数?

我应该尝试哪些参数值?

在哪里以及如何阅读关于参数及其含义的更多信息?

这些是我在开始使用 TensorFlow 对象检测 API 时遇到的问题。

如果你也觉得不清楚,不要担心!幸运的是,有一种通用的方法可以用于参数调整,我发现它非常方便易用。

让我用一个真实的例子向你展示它是怎么回事!

假设您在pipeline.config文件中看到一个默认的分类损失函数(对于 D1 效率检测器来说是weighted_sigmoid_focal)。定义为classification_loss参数)是你认为不是最优的,你想寻找其他可用的选项。

pipeline . config 中定义损失函数的行。效率检测 D1 的例子

以下是你寻找其他可用选项的方法:

根据以下请求模式进行搜索:

Place of the search window on the official TensorFlow API GitHub page

  • 至于我们的例子,我们的 parameter_name 就是 classification_loss 。你需要从pipeline.config文件中粘贴一个精确的参数名。在我们的示例中,您的搜索请求如下:
parameter_name path:research/object_detection/protos

浏览搜索结果,寻找最能描述我们请求的参数( classification_loss )的一个。

tensorflow api search request

Example for a search request if we would like to change classification loss

api search results

Example of search results for a given query

parameters code

Piece of code that shows the options for a parameter we interested in

> classification_loss 是一个参数,它可以是在
> 上面的图像上列出的(oneof)6 个预定义选项中的一个。

当您找到您的参数值时,只需将它复制到您的pipeline.config文件中的相应行。例如,我决定使用weighted_sigmoid损失进行分类,而不是默认的weighted_sigmoid_focal。为此,我在我的pipeline.config文件中做了一个更改,现在定义分类损失的行如下所示:

  • 这就是了。您可以使用这种方法来调整您选择的每个参数。现在,您拥有了一种超能力来定制您的模型,使它完全按照您想要的方式运行。是不是很牛逼?绝对是。恭喜你!

classification loss code

Here is how lines for classification_loss look like after a change is made.

模特培训

为了走到这一步,我们做了很多工作。现在我们已经准备好开始训练了。下面是如何做到这一点:

您需要将提供的 python 脚本从Tensorflow/models/research/object_detection/model_main_tf2.py复制到Tensorflow/workspace/model_main_tf2.py进行训练

  • 打开一个新的终端窗口,将Tensorflow/workspace/作为你当前的工作目录。

  • 使用以下命令启动培训作业:

  • 其中:

python model_main_tf2.py
  --pipeline_config_path=<path to your config file>
  --model_dir=<path to a directory with your model>
  --checkpoint_every_n=<int for the number of steps per checkpoint>
  --num_workers=<int for the number of workers to use>
  --alsologtostderr

> <path to your config file> 是当前培训作业要使用的配置文件的路径。应该是来自的配置文件。/models/ <文件夹与您选择的模型>/v1/
>****<path to a directory with your model>是一个目录的路径,您的所有未来模型属性将放置在该目录中。也应该是下面的:。/models/ <包含您选择的模型的文件夹>/v1/
>****<int for the number of steps per checkpoint>是一个整数,它定义了创建模型检查点需要按顺序完成多少个步骤。请记住,当进行单个步骤时,您的模型处理的图像数量等于您为训练定义的 batch_size。
>****<int for the number of workers to use>如果您有一个多核 CPU,该参数定义了可用于训练作业的核心数量。

在您执行上述命令之后,您的培训工作将开始。值得一提的是,如果你要使用 GPU 进行训练,你所有的 GPU 都会参与进来。如果您希望仅涉及选定的 GPU,请在启动培训作业脚本之前执行以下命令:

其中根据订单编号定义要使用的 GPU。比如我有两个 GPU。第一个订单编号为 0,第二个订单编号为 1。如果我想在我的第 0 个 GPU 上训练一个模型,我执行以下命令:

export CUDA_VISIBLE_DEVICES= <GPUs>

如果我想在我的两个 GPU 上训练,我使用以下命令:

export CUDA_VISIBLE_DEVICES=0

如果我决定只使用 CPU 来训练我的模型,我的命令应该是这样的:

export CUDA_VISIBLE_DEVICES=0,1

现在,你该躺下来放松一下了。剩下的工作就交给电脑了!

export CUDA_VISIBLE_DEVICES=-1

最后的想法

这是一次漫长的旅行,不是吗?现在你有知识和实践技能来进口,定制和培训任何物体探测器你想要的。

TensorFlow 对象检测 API 是一个很好的工具,我很高兴您现在已经完全可以使用它了。让我们简要回顾一下我们所做的工作:

我们从需要启动的初始安装和设置开始:我们安装了所有的依赖项,组织了项目目录,启用了 GPU 支持。

  1. 然后我们继续进行数据准备,了解 TFRecords 并将我们的数据转换成这种格式。我们还利用标签映射将类与其名称联系起来。
  2. 然后我们进入模型选择并决定我们想要使用什么模型架构。现在我们知道每个模型都可以通过我们熟悉的配置文件进行定制。
  3. 最后,我们直接进入培训工作,根据我们准备的配置,启动了模型培训
  4. 如果你一直做到最后,那就干得好!我希望你觉得这篇文章有趣并且有用。

在即将到来的第二篇中,我会讲到更酷的东西!特别是,我们将回答以下问题:

如何为您的模型启动评估作业,并检查其随时间推移的性能?

  • 跟踪结果和比较不同模型配置的实验的最便捷方式是什么?
  • 如何进一步提高模型质量及其性能?
  • 如何克服可能出现的问题?
  • 如何导出一个训练好的模型以便用于推理?
  • How to export a trained model in order to use it for inference?**

如何使用 Google Colab 进行深度学习-完整教程

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-use-google-colab-for-deep-learning-complete-tutorial

如果你是一名程序员,你想探索深度学习,需要一个平台来帮助你做到这一点——这篇教程正是为你准备的。

Google Colab 是深度学习爱好者的一个很好的平台,它也可以用来测试基本的机器学习模型,获得经验,并开发一种关于深度学习方面的直觉,如超参数调整,预处理数据,模型复杂性,过拟合等等。

让我们一起探索吧!

介绍

Google 的 Colaboratory(简称 Google Colab)是一个基于 Jupyter 笔记本的运行时环境,它允许你完全在云上运行代码。

这是必要的,因为这意味着你可以训练大规模的 ML 和 DL 模型,即使你没有强大的机器或高速互联网接入。

Google Colab 支持 GPU 和 TPU 实例,这使得它成为深度学习和数据分析爱好者的完美工具,因为本地机器上的计算限制。

因为 Colab 笔记本可以通过浏览器从任何机器远程访问,所以它也非常适合商业用途。

在本教程中,您将学习:

  • 在 Google Colab 中四处逛逛
  • 在 Colab 中安装 python 库
  • 在 Colab 中下载大型数据集
  • 在 Colab 中训练深度学习模型
  • 在 Colab 中使用 TensorBoard

创造你的第一个。colab 中的 ipynb 笔记本

打开你选择的浏览器,进入colab.research.google.com,使用你的谷歌账户登录。单击一个新的笔记本来创建一个新的运行时实例。

在左上角,你可以通过点击将笔记本的名称从“Untitled.ipynb”更改为你选择的名称。

单元执行块是您键入代码的地方。若要执行单元格,请按 shift + enter。

在一个单元格中声明的变量可以作为全局变量在其他单元格中使用。如果明确声明,环境会自动在代码块的最后一行打印变量值。

训练样本张量流模型

在 Colab 中训练一个机器学习模型是非常容易的。它最大的好处是不必建立一个定制的运行时环境,这一切都是为您处理的。

例如,让我们看看训练一个基本的深度学习模型来识别在 MNIST 数据集上训练的手写数字。

数据从标准的 Keras 数据集档案中加载。该模型非常基本,它将图像分类为数字并识别它们。

设置:

import tensorflow as tf

mnist = tf.keras.datasets.mnist

(x_train,y_train), (x_test,y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

该代码片段的输出如下所示:

Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step

接下来,我们使用 Python 定义 Google Colab 模型:

model = tf.keras.models.Sequential([
                               tf.keras.layers.Flatten(input_shape=(28,28)),
                                   tf.keras.layers.Dense(128,activation='relu'),
                                   tf.keras.layers.Dropout(0.2),
                                   tf.keras.layers.Dense(10)
])

loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

model.compile(optimizer='adam',
             loss=loss_fn,
             metrics=['accuracy'])

model.fit(x_train,y_train,epochs=5)

执行上述代码片段的预期输出是:

Epoch 1/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.3006 - accuracy: 0.9125
Epoch 2/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.1461 - accuracy: 0.9570
Epoch 3/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.1098 - accuracy: 0.9673
Epoch 4/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.0887 - accuracy: 0.9729
Epoch 5/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.0763 - accuracy: 0.9754
<tensorflow.python.keras.callbacks.History at 0x7f2abd968fd0>

model.evaluate(x_test,y_test,verbose=2)

预期产出:

313/313 - 0s - loss: 0.0786 - accuracy: 0.9761
[0.07860152423381805, 0.9761000275611877]

probability_model = tf.keras.Sequential([
                                        model,
                                        tf.keras.layers.Softmax()])

在 Google Colab 中安装软件包

您不仅可以使用 Colab 中的 code 单元运行 Python 代码,还可以运行 shell 命令。随便加个前一个命令。感叹号告诉笔记本单元将下面的命令作为 shell 命令运行。

深度学习所需的大多数通用包都是预装的。在某些情况下,您可能需要不太流行的库,或者您可能需要在不同版本的库上运行代码。为此,您需要手动安装软件包。

用于安装包的包管理器是 pip。

import tensorflow

要安装 TensorFlow 的特定版本,请使用以下命令:

!pip3 install tensorflow==1.5.0

运行以上命令后,预期会有以下输出:

tensorflow install output

点击重启运行时间,使用新安装的版本。

tf version

正如你在上面看到的,我们将 Tensorflow 版本从“2.3.0”更改为“1.5.0”。

对于我们上面训练的模型,测试精度大约为 97%。一点也不差,但这是一个简单的问题。

训练模型通常不是那么容易,我们经常不得不从像 Kaggle 这样的第三方来源下载数据集。

因此,让我们看看当我们没有直接链接时,如何下载数据集。

下载数据集

当您在本地机器上训练机器学习模型时,您可能会遇到下载和存储训练模型所需的数据集所带来的存储和带宽成本问题。

深度学习数据集的规模可能非常大,从 20 到 50 Gb 不等。如果你生活在发展中国家,下载它们是最具挑战性的,因为那里不可能有高速互联网。

使用数据集最有效的方式是使用云接口下载它们,而不是从本地机器手动上传数据集。

令人欣慰的是,Colab 为我们提供了多种从通用数据托管平台下载数据集的方法。

从 Kaggle 下载数据集

要从 Kaggle 下载现有数据集,我们可以遵循以下步骤:

进入你的 Kaggle 账户,点击“创建新的 API 令牌”。这将下载一个 kaggle.json 文件到你的机器上。

  1. 转到您的 Google Colab 项目文件,并运行以下命令:
! pip install -q kaggle
from google.colab import files

files.upload()
! mkdir ~/.kaggle

cp kaggle.json ~/.kaggle/

! chmod 600 ~/.kaggle/kaggle.json

! kaggle competitions download -c 'name-of-competition'

从任何通用网站下载数据集

根据您使用的浏览器,有一些扩展可以将数据集下载链接转换为“curl”或“wget”格式。您可以使用它来有效地下载数据集。

对于 Firefox,有一个 cliget 浏览器扩展:CLI Get–为 Firefox (en-US)获取这个扩展

  1. 对于 Chrome,有一个 curlget 扩展: Ad 增加了 curlget 52
  2. 只要你点击浏览器中的任何下载按钮,这些扩展就会生成一个 curl/wget 命令。

然后,您可以复制该命令,并在您的 Colab 笔记本中执行它,以下载数据集。

:默认情况下,Colab 笔记本使用 Python shell。要在 Colab 中运行终端命令,您必须使用" ”命令的开始。

例如,要从 some.url 下载文件并将其保存为 some.file,可以在 Colab 中使用以下命令:

:curl 命令会在 Colab 工作区下载数据集,每次运行时断开连接都会丢失。因此,一个安全的做法是,一旦数据集下载完成,就将数据集移动到您的云驱动器中。

!curl http://some.url --output some.file

从 GCP 或 Google Drive 下载数据集

谷歌云平台是一个云计算和存储平台。您可以使用它来存储大型数据集,并且可以将该数据集直接从云中导入到 Colab 中。

要在 GCP 上传和下载文件,首先你需要验证你的谷歌账户。

它会要求你使用你的谷歌账户访问一个链接,并给你一个认证密钥。将密钥粘贴到提供的空白处,以验证您的帐户。

from google.colab import auth
auth.authenticate_user()

之后安装 gsutil 上传下载文件,然后初始化 gcloud。

google colab auth

这样做将要求您从基本设置的某些选项中进行选择:

!curl https://sdk.cloud.google.com | bash
!gcloud init

一旦您配置了这些选项,您就可以使用以下命令从 Google 云存储中下载/上传文件。

gcloud init

要将文件从云存储下载到 Google Colab,请使用:

要将文件从 Google Colab 上传到云,请使用:

!gsutil cp gs://maskaravivek-data/data_file.csv

在启用 GPU/TPU 的情况下启动运行时

gsutil cp test.csv gs://maskaravivek-data/

深度学习是一个计算量很大的过程,需要同时执行大量计算来训练一个模型。为了缓解这个问题,Google Colab 不仅为我们提供了经典的 CPU 运行时,还提供了 GPU 和 TPU 运行时的选项。

CPU 运行时最适合训练大型模型,因为它提供了高内存。

GPU 运行时对于不规则计算,如小批量和非大型计算,表现出更好的灵活性和可编程性。

TPU 运行时针对大批量和 CNN 进行了高度优化,具有最高的训练吞吐量。

如果你有一个较小的模型要训练,我建议在 GPU/TPU 运行时上训练模型,以充分发挥 Colab 的潜力。

要创建支持 GPU/TPU 的运行时,您可以在文件名下方的工具栏菜单中单击运行时。从那里,点击“更改运行时类型”,然后在硬件加速器下拉菜单下选择 GPU 或 TPU。

请注意,Google Colab 的免费版本并不保证 GPU/TPU 支持的运行时的持续可用性。如果使用时间过长,您的会话可能会被终止!

你可以购买 Colab Pro(如果你在美国或加拿大,目前只能在这些国家购买)。每月 10 美元,不仅提供更快的 GPU,还提供更长的会话。前往此链接

训练更复杂和更大的模型

为了训练复杂的模型,通常需要加载大型数据集。建议使用 mount drive 方法直接从 Google Drive 加载数据。

这将把所有数据从您的驱动器导入运行时实例。首先,您需要安装存储数据集的 Google Drive。

您还可以使用 Colab 中的默认存储,并将数据集从 GCS 或 Kaggle 直接下载到 Colab。

安装驱动器

Google Colab 允许您从 Google Drive 帐户导入数据,以便您可以从 Google Drive 访问训练数据,并使用大型数据集进行训练。

有两种方法可以在 Colab 中挂载驱动器:

使用 GUI

  • 使用代码片段
  • 1。使用 GUI

点击屏幕左侧的文件图标,然后点击“安装驱动器”图标来安装您的谷歌驱动器。

2。使用代码片段

执行以下代码块在 Colab 上安装您的 Google Drive:

单击链接,复制代码,并将其粘贴到提供的框中。按 enter 键安装驱动器。

from google.colab import drive
drive.mount('/content/drive')

接下来,我们将训练一个卷积神经网络(CNN)来识别手写数字。这是在一个基本数据集和一个原始模型上训练的,但现在我们将使用一个更复杂的模型。

Google colab code

用 Keras 训练模型

Keras 是用 Python 写的 API,它运行在 Tensorflow 之上。它用于快速原型实验模型和评估性能。

与 Tensorflow 相比,在 Keras 中部署模型非常容易。这里有一个例子:

一旦这个单元被执行,您将会看到类似如下的输出:

import numpy as np
import cv2
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
import pandas as pd

from google.colab import drive
drive.mount('/content/drive')

cd drive/My Drive/

data = pd.read_csv('train.csv')

train = data.iloc[0:40000,:] 
train_X = train.drop('label',axis=1)
train_Y = train.iloc[:,0]

val = data.iloc[40000:,:]    
val_X = val.drop('label',axis=1)
val_Y = val.iloc[:,0]

train_X = train_X.to_numpy() 
train_Y = train_Y.to_numpy()
val_X = val_X.to_numpy()

val_Y = val_Y.to_numpy()
train_X = train_X/255.    
val_X = val_X/255.

train_X = np.reshape(train_X,(40000,28,28,1)) 
val_X = np.reshape(val_X,(2000,28,28,1))

model = keras.Sequential([
   keras.layers.Conv2D(32,(3,3),activation='relu',input_shape=(28,28,1)),
   keras.layers.MaxPooling2D((2,2)),
   keras.layers.Conv2D(64,(3,3),activation='relu'),
   keras.layers.MaxPooling2D((2,2)),
   keras.layers.Conv2D(64,(3,3),activation='relu'),
   keras.layers.Flatten(),

   keras.layers.Dense(64,activation='relu'),

   keras.layers.Dense(10)
])

model.compile(optimizer='adam',
            loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
            metrics=['accuracy'])

model.fit(train_X,train_Y,epochs=10,validation_data=(val_X, val_Y))

预期产出:

Epoch 1/10
1250/1250 [==============================] - 37s 30ms/step - loss: 0.1817 - accuracy: 0.9433 - val_loss: 0.0627 - val_accuracy: 0.9770
Epoch 2/10
1250/1250 [==============================] - 36s 29ms/step - loss: 0.0537 - accuracy: 0.9838 - val_loss: 0.0471 - val_accuracy: 0.9850
Epoch 3/10
1250/1250 [==============================] - 36s 29ms/step - loss: 0.0384 - accuracy: 0.9883 - val_loss: 0.0390 - val_accuracy: 0.9875
...
1250/1250 [==============================] - 36s 29ms/step - loss: 0.0114 - accuracy: 0.9963 - val_loss: 0.0475 - val_accuracy: 0.9880
Epoch 10/10
1250/1250 [==============================] - 36s 29ms/step - loss: 0.0101 - accuracy: 0.9967 - val_loss: 0.0982 - val_accuracy: 0.9735

test_loss, test_acc = model.evaluate(val_X,val_Y,verbose=2)
Expected output:
63/63 - 1s - loss: 0.0982 - accuracy: 0.9735

predict_model = tf.keras.Sequential([
   model,tf.keras.layers.Softmax()
])

test_image = val_X[140]
test_image = np.reshape(test_image,(1,28,28,1))
result = predict_model.predict(test_image)
print(np.argmax(result))
plt.imshow(val_X[140].reshape(28,28))
plt.show()

使用 FastAI

FastAI 是一个工作在 PyTorch 之上的高级库。它让你用很少几行代码来定义。它用于通过遵循自上而下的方法来学习深度学习的基础知识,即首先我们编码并查看结果,然后研究其背后的理论。

这里可以看到 FastAI 在 Colab 上的一个示例实现

如何使用 Neptune-Keras integrationNeptune-fastai integration跟踪模型训练元数据。

Google Colab 中的 TensorBoard

TensorBoard 是 Tensorflow 提供的用于可视化机器学习相关数据的工具包。

它通常用于绘制度量标准,例如迭代次数的损失和准确性。它还可以用于可视化和总结模型,并显示图像、文本和音频数据。

使用张量板的监测数据

要使用 TensorBoard,需要导入一些必要的库。运行以下代码片段来导入这些库:

在我们开始可视化数据之前,我们需要在 model.fit()中做一些更改:

%load_ext tensorboard
import datetime, os

训练结束后,您可以启动 TensorBoard 工具包来查看模型的表现:

logdir = os.path.join("logs", datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
tensorboard_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)

model.fit(x=x_train,y=y_train,epochs=5,validation_data=(x_test, y_test),callbacks=[tensorboard_callback])

它给出了精度和损失如何随运行的时期数而变化的信息。

%tensorboard --logdir logs

保存和加载模型

训练模型需要花费大量时间,因此能够保存训练好的模型以便反复使用将是明智的。每次都训练它会非常令人沮丧和耗时。Google Colab 允许您保存模型并加载它们。

保存和加载模型重量

训练 DL 模型的基本目的是以正确预测输出的方式调整权重。仅保存模型的权重,并在需要时加载它们是有意义的。

要手动保存重量,请使用:

要在模型中加载权重,请使用:

 model.save_weights('./checkpoints/my_checkpoint')

保存并加载整个模型

model.load_weights('./checkpoints/my_checkpoint'

有时候,最好保存整个模型,这样可以省去定义模型、处理输入维度和其他复杂性的麻烦。您可以保存整个模型并将其导出到其他机器。

要保存整个模型,请使用:

要加载已保存的模型,请使用:

model.save('saved_model/my_model'

结论

new_model = tf.keras.models.load_model('saved_model/my_model')

现在你看到 Google Colab 是一个很好的工具,可以原型化和测试深度学习模型。

凭借其免费的 GPU 和从 Google Drive 导入数据的能力,Colab 脱颖而出,成为在计算和存储有限的低端机器上训练模型的非常有效的平台。

它还管理 Google Drive 中的笔记本,为希望一起从事同一项目的程序员提供一个稳定而有组织的数据管理系统。

感谢阅读!

Thanks for reading!

Jupyter 笔记本如何版本化、调试、比较和共享

原文:https://web.archive.org/web/https://neptune.ai/blog/how-to-version-debug-compare-share-jupyter-notebooks

ML 模型开发有了突飞猛进的改进,Jupyter 笔记本是这种变化的一大因素。由于它的交互式开发、对 markdowns 的支持和 LaTex,一个巨大的插件库,它已经成为任何数据科学家或 ML 从业者的首选工具。

笔记本在这一领域的流行导致了许多在 ML 实验跟踪中的产品,因为它们没有自带的跟踪功能(在撰写本文时),所以人们不得不在其他地方寻找解决方案。在这篇博客中,我们将涉及以下几个方面:

  • 1 为什么给笔记本版本很重要?
  • 2 用不同的方法对笔记本电脑上完成的实验进行版本化、调试和比较。
  • 3Neptune . ai 如何帮助 Jupyter 笔记本的跟踪、调试和对比?

为什么要给笔记本版本化?

构建 ML 模型本质上是实验性的,通常会运行大量实验来寻找算法、参数和数据预处理步骤的组合,从而为手头的任务产生最佳模型。一旦问题变得复杂,这就需要某种形式的组织。

当在笔记本中运行实验时,您会感觉到需要版本控制和跟踪,就像在另一个 IDE 中构建 ML 模型一样。以下是关于为什么您应该采用为您的 ML 实验建立某种形式的版本控制的最佳实践的一些要点:

  1. 协作:在团队中工作需要决策过程中的协作努力,如果没有集中记录的实验细节,如模型元数据、度量等,这将变得很麻烦。

  2. 再现性:如果您在某个地方记录模型配置,可以节省大量的重新训练和测试时间。通过拍摄整个机器学习管道的快照,可以再次重现相同的输出。

  3. 依赖跟踪:通过使用版本控制,您可以跟踪数据集的不同版本(训练、验证和测试),在不同的分支或存储库上测试多个模型,调整模型参数和超参数,并监控每个更改的准确性。

  4. 模型更新:模型开发不是一步到位的,它是循环往复的。在版本控制的帮助下,您可以控制发布哪个版本,同时继续开发下一个版本。

Jupyter 笔记本如何版本化?

有许多方法可以将您在笔记本上运行的实验版本化,从简单的日志文件到提供大量功能的全面实验跟踪工具。让我们来谈谈每个类别中的一些,并了解根据您的要求,什么是正确的选择。

1.在电子表格中跟踪笔记本

Notebook versioning in spreadsheet

Source

在 Excel 或 Google 电子表格中跟踪 ML 实验是一种快速而强力的解决方案。电子表格提供了舒适易用的体验,可以直接粘贴元数据并为多次运行创建多个工作表。但是它有很多警告,让我们看看它哪里有亮点,哪里没有:

赞成的意见

  1. 熟悉的界面易于使用。
  2. 可以在工具中直接为利益相关者创建报告。
  3. 对于团队中的非技术人员来说,做出贡献是一件好事。

骗局

  1. 在电子表格中跟踪实验是一件乏味的事情,您要么需要将模型元数据和指标复制并粘贴到电子表格中,要么使用 pandas 这样的模块来记录信息,然后保存到电子表格中。
  2. 一旦实验数量增加,在单独的表格中记录每次运行将变得难以管理。
  3. 在一个简单的电子表格中跟踪和管理无数的变量和工件并不是解决问题的最佳方式。

2.使用 Git 对笔记本进行版本控制

Notebook-version-git

Source

Git 可以成为您项目的通用工具。它不仅可以跟踪你的笔记本中的变化,还可以作为你整个项目的版本控制工具。借助它的强大功能,您可以将与模型相关的元数据(如训练权重、评估报告(如混淆矩阵)等)推送到一个中央存储库,您的数据科学团队可以使用该存储库做出明智的决策。让我们来看看使用 Git 进行实验跟踪的优缺点:

赞成的意见

  1. 所有代码和笔记本文件的单一版本控制系统。
  2. 技术社区中的一个流行工具。
  3. 它允许访问数百万个其他存储库,这些存储库可以作为一个起点。

骗局

  1. 很难让非程序员和其他利益相关者参与进来。
  2. 不直观的界面可能会给协作工作带来摩擦。
  3. 需要技术专家来执行和维护与实验相关的知识库。

3.使用实验跟踪工具对笔记本进行版本控制

Notebook-versioning-tools

Source

实验跟踪工具是为此用例定制的。它们几乎涵盖了你对元数据管理工具的所有需求,从实验跟踪到模型注册。在过去的几年里,这个领域有很多工具,其中比较突出的有 neptune.ai、Weights and Biases 和 MLflow。让我们来看看这些工具的一些优点/缺点:

赞成的意见

  1. 涵盖了组织实验运行时所需的所有功能。
  2. 所有这些工具都带有专用的交互式 UI,可用于比较、调试或报告生成。
  3. 每个工具都为团队协作提供了过多的功能。

骗局

  1. 与 Git 或电子表格不同,实验跟踪工具通常需要付费。虽然几乎所有的都有一个针对单个用户的免费层,但它有其局限性。但另一方面,为工具付费意味着您不必担心安装、维护或开发功能。

对于实验跟踪的具体问题,可能有许多临时的解决方案。许多遗留工具可以解决跟踪和组织您的 ML 实验的一些领域。但是如果你想要一个成熟的解决方案来满足你的组织的需求,你应该理想地选择一个实验跟踪工具。

在 Neptune 中跟踪、调试和比较 Jupyter 笔记本

neptune.ai 是一个 ML 元数据存储库,它是为运行许多实验的研究和生产团队而构建的。它有一个灵活的元数据结构,允许您以自己喜欢的方式组织培训和生产元数据。

它为您提供了一个中心位置来记录、存储、显示、组织、比较和查询机器学习生命周期中生成的所有元数据。个人和组织使用 Neptune 进行实验跟踪和模型注册,以控制他们的实验和模型开发。

该 web 应用程序专为管理 ML 模型元数据而构建,它允许您:

  • 用高级查询语言过滤实验和模型。
  • 使用灵活的表格视图和仪表板定制您看到的元数据。
  • 监控、可视化和比较实验和模型。

Example custom dashboard Neptune

An example dashboard in the Neptune app with various metadata displayed

海王星-朱庇特扩展

Neptune 使用 Neptune–Jupyter 扩展提供与 Jupyter 笔记本的无缝集成。您可以直接利用实验跟踪的力量,而不必使用许多工具。前往 Neptune-Jupyter 笔记本文档尽可能以最简单的方式开始。

借助 Neptune-Jupyter 集成,您可以:

  • 在模型训练期间手动或自动记录和显示笔记本检查点。
  • 连接笔记本检查点和海王星的模型训练。
  • 用名称和描述组织检查点。
  • 浏览项目中所有笔记本的检查点历史记录。
  • 并排比较笔记本,比较源、降价、输出和执行计数单元格的差异。

Comparing Notebooks in the Neptune app

这里有一个在 Neptune 应用程序中打开的例子,有几个笔记本记录了

为什么要用海王星配 Jupyter 笔记本?

上述特性使得 Neptune 成为 Jupyter 笔记本进行跟踪和版本控制实验的绝佳选择。除了我们在上一节中讨论的技术特性之外,以下是使它成为该角色最佳竞争者的原因:

  1. 无缝集成:借助 Neptune-Jupyter 扩展,您可以将笔记本与 Neptune 仪表盘无缝集成,实现版本控制和共享功能。与其他方法相比,这减少了摩擦。

  2. 丰富的特性:海王星提供的特性让你可以自由地监控/记录/存储/比较任何你想让你的实验成功的东西。

  3. 免费层的可用性:免费层面向单个用户,免费提供重要功能。

  4. 用户和客户支持:得益于快速而有用的支持团队,您可以更快地解决问题,只需专注于构建模型。

你已经到达终点了!

恭喜你!你现在已经完全了解你需要什么样的理想方法来组织你的笔记本实验。在本文中,我们探索了简单的特别方法,如电子表格和 Git,以及更微妙的方法,如实验跟踪工具。以下是一些额外的提示,帮助您轻松选择下一个工具:

  1. 坚持自己需要的!很容易迷失在工具和方法的海洋中,但是绝对坚持你的需求会帮助你做出更好的决定。
  2. 我推荐使用“免费试用?在您锁定任何一个解决方案之前,每个工具都有一个特性。

感谢阅读!敬请关注更多内容!再见!

拥抱脸预训练模型:找到最适合你的任务

原文:https://web.archive.org/web/https://neptune.ai/blog/hugging-face-pre-trained-models-find-the-best

当你在处理一个机器学习问题时,调整现有的解决方案并重新利用它可以帮助你更快地找到解决方案。使用现有模型,不仅可以帮助机器学习工程师或数据科学家,还可以帮助公司节省计算成本,因为它需要更少的培训。有许多公司提供包含预训练模型的开源库,拥抱脸就是其中之一。

抱脸早在 2017 年就首次推出了其聊天平台。为了规范化 NLP 并使所有人都可以访问模型,他们创建了一个 NLP 库,提供各种资源,如数据集、转换器和记号化器等。在发布名为 Transformers 的 NLP 库和各种各样的工具后,拥抱脸立即在大型科技公司中变得非常流行。

拥抱脸专注于自然语言处理(NLP)任务,其想法不仅仅是识别单词,而是理解这些单词的含义和上下文。计算机处理信息的方式与人类不同,这就是为什么我们需要一个管道——处理文本的一系列步骤。

许多公司现在正在将 NLP 技术添加到他们的系统中,以增强交互体验,并且使通信尽可能接近人类体验变得比以往更加重要。这就是拥抱脸的由来。在接下来的部分中,我们将通过一些动手练习详细介绍拥抱脸及其变形金刚。

入门指南

在开始之前,您需要清楚地了解用例及其背后的目的。拥抱脸有多种变形金刚和模型,但它们是针对特定任务的。他们的平台提供了一种简单的方式来搜索模型,你可以通过应用多个过滤器来过滤掉模型列表。

在他们的网站上,在模型的页面,你会看到一个任务、库、数据集、语言等的列表。

假设您正在寻找能够满足您的用例的以下需求的模型:

  • 将文本从一种语言翻译成另一种语言
  • 支持 PyTorch

一旦您选择了这些过滤器,您将获得如下预训练模型列表:

您还需要确保您提供的输入格式与预训练模型的训练格式相同。一旦您从列表中选择了一个模型,您就可以开始为它设置环境。

设置环境

拥抱脸支持超过 20 个库,其中一些非常受 ML 工程师的欢迎,如 TensorFlow,Pytorch 和 FastAI 等。我们将使用 pip 命令安装这些库来使用拥抱脸:

!pip install torch

安装 PyTorch 后,我们可以使用下面的命令安装 transformer 库:

!pip install transformers

有两种方法可以开始使用 Hugging Face NLP 库:使用 pipeline 或任何可用的预训练模型,通过重新调整它的用途来处理您的解决方案。这些模型占用了大量的空间,当您第一次运行上面的代码时,模型将被下载。因此,建议最初使用 Google Colab 或 Kaggle 笔记本进行实验。在本文的后面,我们将了解如何利用管道和预训练模型。

拥抱脸支持的基本任务

在我们了解拥抱脸模型如何用于实现 NLP 解决方案之前,我们需要知道拥抱脸支持哪些基本 NLP 任务以及我们为什么关注它们。拥抱脸部模型提供了许多不同的配置,并为各种用例提供了强大的支持,但这里有一些它广泛用于的基本任务:

1.序列分类

给定一些类别,任务是预测输入序列的类别。这是一个预测建模问题,有着广泛的应用。一些真实世界的用例是——理解评论背后的情绪,检测垃圾邮件,纠正语法错误等。

2.问答

为给定的上下文问题提供答案。这个想法是建立一个可以自动回答人类提出的问题的系统。问题可以是开放式的,也可以是封闭式的,系统的设计应该兼容这两种情况。答案可以通过查询结构化数据库或搜索非结构化文档集合来构建。

3.命名实体识别

命名实体识别是将令牌识别为个人、地点或组织的任务。它正被用于自然语言处理的许多领域,并帮助解决许多现实世界的问题。在这种技术中,我们可以扫描文章,提取基本实体,并将它们归类到定义的类别中。

4.摘要

你记得在学校或大学写总结报告吗?嗯,这个任务是一样的,给定一个文档,在 NLP 的帮助下,它可以转换成一个简洁的文本。这是一个为较长的文本创造一个简短、连贯和流畅版本的过程。有两种方法可以用于文本摘要-提取和抽象。在提取法中,我们提取重要的句子和短语,而在抽象法中,我们需要解释上下文并再现文本,保持核心信息完整。

5.翻译

它的任务是将文本从一种语言翻译成另一种语言。替换原子单词是不够的,因为我们想要创建一个能够像人类翻译员一样翻译文本的系统。我们需要一个考虑语音类型、习语翻译等的语料库。进行复杂的翻译。

6.语言建模

语言建模包括生成文本以理解一系列标记或预测一些可用于完成文本的短语。这些任务可以分为——掩蔽语言建模和随意语言建模。

NLP 的任务不仅仅是处理书面文本,它还涵盖了与语音识别、计算机视觉、生成文本等相关的解决方案。NLP 任务很难用机器学习来处理,已经做了大量的研究来提高这些模型的准确性。

拥抱面部变形金刚以及如何使用它们

NLP 中的 Transformer 是一种新颖的架构,旨在解决序列到序列任务,同时轻松处理长期依赖关系。?

KDnuggets

变形金刚的概念是在 2017 年提出的,并受到了后来推出几个型号的许多研究人员的影响。

Transformer Model Evolution

Transformer Model Evolution | Source

变形金刚是语言模型,已经在大量文本上以自学的方式进行了训练。自我监督或转移学习是一种训练,系统在移动中学习,不需要任何标记数据。

变压器架构

变换器语言模型由编码器-解码器结构组成。这些组件在核心架构中相互连接,但也可以独立使用。

  • 编码器接收输入,并迭代地处理输入,以生成关于输入的哪些部分彼此相关的信息。该模型将被优化以从输入中获得最佳理解。

  • 解码器使用来自编码器的表示生成目标序列,并使用上下文信息生成输出。

The transformer - model architecture

The transformer – model architecture | Source

transformer 模型架构的一个关键特性是关注层。这一层会告诉模型注意具体的细节和用词。它可以被描述为一个键和一组键值对到输出的映射,其中查询、键、值和输出都是向量。要详细了解变压器架构,请查看关于变压器的论文-注意力是你所需要的全部图解变压器博客。

现在你已经对这个架构有了一个基本的了解,让我们看看拥抱脸是如何使这个过程更简单易用的。

变压器和管道介绍

拥抱面部变压器库由不同任务的不同模型组成,可通过高级 API 访问。变压器模型构建起来很复杂,因为它们需要数百亿个参数的微调和高强度的训练。创建拥抱面部变形库是为了通过访问一个 API 来提供使用这些复杂模型的便利性、灵活性和简单性。可以毫不费力地加载、训练和保存模型。

典型的 NLP 解决方案包括从获取数据到微调模型的多个步骤。

使用预定义的管道

A typical NLP solution consists of multiple steps from getting the data to fine-tuning a model.

Source: Author

拥抱面部转换器管道对给定的输入文本数据执行所有预处理和后处理步骤。每个 NLP 解决方案的整个流程都封装在这些管道中,这些管道是 Transformer 库中最基本的对象。这有助于将模型与所需的预处理和后处理步骤联系起来,我们只需提供输入文本。

使用管道时,您不必担心单独实现这些步骤。您可以选择一个与您的用例相关的管道,并用如下几行代码创建一个机器翻译器:

管道是开始熟悉拥抱脸的一个好方法,因为你可以使用预先训练和微调的变压器创建自己的语言模型。拥抱面为上述任务提供了管道,以及一些额外的管道,如这里所提到的。

from transformers import pipeline
translator = pipeline("translation_en_to_de")
text = "Hello world! Hugging Face is the best NLP tool."
translation = translator(text)

print(translation)

Using pre-defined pipelines (Hugging Face)

Source: Author

创建您自己的渠道

默认管道仅支持这些基本任务的一些场景,例如,上述翻译管道仅支持英语到德语的翻译,但是如果您想要翻译成不同的语言呢?对于这些场景,您必须使用经过微调的训练模型来创建管道。

幸运的是,拥抱脸有一个模型中枢,这是一个预先训练和微调的模型集合,用于上面提到的所有任务。这些模型基于各种变压器架构——GPT、T5、BERT 等。如果你过滤翻译,你会看到截至 2021 年 11 月有 1423 个模型。在这一节,我们将看到你如何使用这些模型和翻译文本。让我们创建一个机器学习翻译器:

1.导入并初始化标记器

Transformer 模型不能处理原始文本,需要转换成数字才能理解数据。

2.导入模型

from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-nl")
我们可以下载预先训练好的模型,就像我们在上面的步骤中下载标记器一样。在这里,我们将实例化一个模型,其中包含一个基本的变压器模块,给定输入,它将产生输出,即高维向量。

3.以 seq2seq 方式标记和编码文本

model = AutoModelForSeq2SeqLM.from_pretrained("Helsinki-NLP/opus-mt-en-nl")
为了让模型能够理解数据,我们使用了一个标记器,它可以帮助:

将文本拆分成单词和子单词

  • 将每个令牌映射到一个整数
  • 我们在步骤 1 中初始化了标记器,并将在这里使用它来获取输入文本的标记。tokenizer 的输出是一个包含两个键的字典——输入 id 和注意屏蔽。输入 id 是句子中标记的唯一标识符。注意掩码用于将输入序列分批在一起,并指示令牌是否应该由我们的模型处理。注意掩码值为 0 的令牌表示令牌将被忽略,1 表示令牌很重要,将用于进一步处理。

4.批量翻译和解码元素

text = "Hello my friends! How are you doing today?"
tokenized_text = tokenizer.prepare_seq2seq_batch([text])
print(tokenized_text)

{'input_ids': [[16816, 187, 2493, 68, 650, 48, 41, 1531, 950, 31, 0]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]}

我们将把预处理后的输入输入到模型中,模型生成一个输出向量。

正如我们所看到的,除了仅支持英语-德语、英语-法语和英语-罗马尼亚语翻译的简单管道之外,我们可以在 HuggingFace 中为任何预训练的 Seq2Seq 模型创建语言翻译管道。让我们看看哪些 transformer 模型支持翻译任务。

translation = model.generate(**tokenized_text)
translated_text = tokenizer.batch_decode(translation, skip_special_tokens=True)[0]
print(translated_text)

语言转换器模型

“transformer 是一种深度学习模型,它采用注意力机制,对输入数据的每个部分的重要性进行不同的加权。它主要用于自然语言处理领域。?

变压器越来越成为解决 NLP 问题的首选模型,这也是该领域出现许多发展的原因。许多拥抱脸支持的模型是基于变压器的架构。“翻译有若干?以及“text2text?在拥抱脸和本节中,我们将看看一些流行的语言翻译模型。

Source

在这里,我们将首先了解这些模型,然后获得开发翻译器的实践经验。这些模型中的大多数都支持多任务,并且可以进一步微调,以便为任何其他 NLP 任务提供支持。我们还将评估他们的表现,并找出哪一个是最好的。所以,让我们开始吧!

mBART 模型

mBART 遵循 BART 的概念,是一个序列到序列去噪自动编码器,在多种语言的大规模单语语料库上进行了预训练。实际的 BART 通过随机打乱原始句子的顺序并用单个掩码标记替换文本,将损坏的文档映射到它所源自的原始文档。通过破坏文档和优化解码器输出和主文档之间的损失来训练 BART。可以使用方向模型对损坏的文档进行编码,并使用自回归解码器产生原始文档。

对于输入编码器或转换,它允许您对文档应用任何类型的破坏,如标记屏蔽、删除、填充置换和检测。BART 支持各种下游应用,如序列分类、标记分类、序列生成和机器翻译。

Input encoder & output decoder

Input encoder & output decoder | Source

mBART 模型是在神经机器翻译的多语言去噪预训练中提出的。虽然以前的模型和方法只关注编码器、解码器和转换部分文本,但研究人员首次提出使用 mBART 模型可以对多种语言的全文进行去噪。

Transformations for noising the input

Transformations for noising the input | Source

mBART 是一个多语言编码器-解码器(序列到序列)模型,主要用于翻译任务。由于模型是多语言的,它期望序列采用不同的格式。在源文本和目标文本中都添加了一个特殊的语言 id 标记来标识文本的语言。

该模型针对所有语言训练一次,并提供一组参数,这些参数可以针对有监督的(句子和文档级别)和无监督的机器翻译进行微调,而无需任何任务或语言特定的修改。让我们看看它如何在这些场景中处理机器翻译:

Framework of multilingual denoising pre-training and fine-tuning on downstream

Framework of multilingual denoising pre-training and fine-tuning on downstream | Source

句子级翻译 : mBART 在句子级机器翻译任务上进行评估,目标是最小化源和目标句子表示之间的差异。与其他可用的方法相比,mBART 的预训练设置提供了显著的性能改进。该模型仅使用双文本(词对齐以识别语言之间的翻译关系)进行预训练,然后与反向翻译结合。

  • 文档级翻译:这处理学习不同句子之间的依赖关系,然后翻译一个段落或整个文档。对于预处理文档级数据,在每个块中,应该用句子符号分隔句子,并且整个训练示例应该以语言 id 结束。而翻译模型将在发现语言 id 时停止,因为它不知道句子的数量。

  • 无监督翻译 : mBART 还支持无监督翻译,即没有可用的双文本。当没有双文本时,模型使用反向翻译,并且当没有双文本可用但是在文档集合中的其他语言对中找到目标语言时,它使用语言转移。

  • 由于其独特的框架,它不需要跨多种语言的并行数据,但有针对性的方向。这有助于提高语言的可伸缩性,即使我们没有足够的资源或者这些资源是特定于领域的。

T5 型号

这个模型是在探索迁移学习的局限性的一篇统一的文本到文本迁移论文中介绍的。研究人员通过引入一个统一的框架,可以将所有基于文本的语言问题转换为文本到文本的格式,从而探索迁移学习的有效性。T5 基于编码器-解码器架构,其基本思想是将文本作为输入,并产生新的文本作为输出。

它遵循与最初的变形金刚相同的概念。输入文本的标记序列被映射到嵌入序列,以将其传递给编码器。编码器由模块组成,每个模块包括两个部分:自我关注层,后面是一个小的前馈网络。解码器在结构上类似于编码器,除了它在每个关注编码器输出的自关注层之后包括一个标准关注机制。它还使用一种自回归或因果自我关注的形式,允许模型关注过去的输出。

Diagram of text-to-text framework

Diagram of text-to-text framework | Source

T5 模型在未标记的数据上进行训练,这些数据是使用更干净版本的公共爬行、巨大干净爬行语料库(C4)生成的。在文本到文本转换器和新的预训练数据集的帮助下,T5 模型有助于调查大量的想法。

T5 模型通过在输入序列前添加任务前缀,可以很好地处理各种现成的任务,例如翻译- 将英语翻译成法语和摘要- 摘要。

马里亚纳姆模型

MarianMT 也基于编码器-解码器架构,最初由 rg Tiedemann 使用 Marian 库进行训练。Marian 是一个高效且独立的神经机器翻译框架,由一个基于动态计算图的集成自动微分引擎组成。

Marian 完全是用 C++写的。这个库支持更快的训练和翻译。由于它具有最小的依赖性,所以它提供了对优化基于 MPI 的多节点训练、高效的批量波束搜索、新模型的紧凑实现等的支持。Marian 工具包可用于解决许多 NLP 问题:

自动后期编辑:专注于端到端神经模型来自动编辑机器翻译输出,研究人员发现,两个编码器上的双注意力机制能够从原始机器翻译输出中恢复缺失的单词。

  • 语法错误纠正:玛丽安还被用来制作一套 GEC 场景的模型。想法是使用低资源神经机器翻译进行自动语法错误纠正(GEC)。这些方法被用作 Marian 的扩展,以在源文本中引入噪声、指定加权训练目标、预训练嵌入、使用预训练模型的迁移学习等。

  • 使用 Marian 框架,可以组合不同的编码器和解码器,并创建 Marian MT 来减少实现工作。MarianMT 模型在开放平行语料库(OPUS) 上进行训练,开放平行语料库是从网络上收集的翻译文本。

大约有 1300 种型号支持多种语言对。所有这些模型都遵循相同的命名约定——Helsinki-NLP/opus-mt-{ src }-{ target },其中 src 和 target 是两个字符的语言代码。每个模型在磁盘上大约有 298 MB,这意味着它比其他模型小,可以用于实验、微调和集成测试。Marian 的新型多语言车型需要三字符语言代码。

创建您自己的机器学习翻译器,并对其进行微调

现在,您已经熟悉了一些语言翻译器模型,我们现在将了解如何在相同的数据上使用这些预训练的模型来创建我们自己的机器学习翻译器。我们将开发一个英语到德语文本转换的语言翻译器,并从 transformer 库中训练/微调预训练模型。

在开始之前,我们需要一个数据集,其中包含英语到德语或德语到英语的句子,并可用于教学模型。我们将使用拥抱脸数据集库来寻找我们建模所需的数据。大约有 1,800 个数据集,并且特定于不同的 NLP 任务。在本次动手练习中,我们将使用 wmt16 来培训和调整我们的翻译模型–T5、MarianMT 和 mBART。

1.加载数据集

我们将使用 load_dataset 函数下载数据集并将其缓存在笔记本中。

您可以看到数据已经分为测试、训练和验证。训练集有大量的数据,因此我们的模型训练和微调需要时间。

from datasets import load_dataset, load_metric
raw_datasets = load_dataset("wmt16", "de-en")
raw_datasets

2.预处理数据集

为了预处理 NLP 数据,我们需要使用预定义的标记器对其进行标记。

现在,我们将创建一个预处理函数,并将其应用于所有数据分割。

model_marianMT = "Helsinki-NLP/opus-mt-en-de"

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model_marianMT,use_fast=False)
model_mbart = 'facebook/mbart-large-50-one-to-many-mmt'

from transformers import MBart50TokenizerFast

tokenizer = MBart50TokenizerFast.from_pretrained(model_mbart,src_lang="en_XX",tgt_lang = "de_DE")
model_t5 = "t5-small"
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model_marianMT,use_fast=False)

T5 模型需要一个特殊的前缀放在输入之前,您应该采用下面的代码来定义前缀。对于 mBART 和 MarianMT,前缀将保持空白。

3.创建数据集的子集

prefix = "translate English to German:" 
prefix = "" 
max_input_length = 128
max_target_length = 128
source_lang = "en"
target_lang = "de"
def preprocess_function(examples):
   inputs = [prefix + ex[source_lang] for ex in examples["translation"]]
   targets = [ex[target_lang] for ex in examples["translation"]]
   model_inputs = tokenizer(inputs, max_length=max_input_length, truncation=True)

   with tokenizer.as_target_tokenizer():
       labels = tokenizer(targets, max_length=max_target_length, truncation=True)
   model_inputs["labels"] = labels["input_ids"]
   return model_inputs
tokenized_datasets = raw_datasets.map(preprocess_function, batched=True)

为了避免训练中的延迟,我们将从标记化的数据集创建小的训练和验证子集,并将使用这些子集来训练和微调模型。

4.训练和微调模型

small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(1000))
small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(1000))

我们将为 T5 和 MarianMT 使用 AutoModelForSeq2SeqLM,为 mBART 使用 MBartForConditionalGeneration 来缓存或下载模型:

**为了我们的训练,我们还需要一些东西。首先,定制我们的培训所需的培训属性。

from transformers import AutoModelForSeq2SeqLM, DataCollatorForSeq2Seq, Seq2SeqTrainingArguments, Seq2SeqTrainer

model = AutoModelForSeq2SeqLM.from_pretrained(model_marianMT)

from transformers import MBartForConditionalGeneration
model = MBartForConditionalGeneration.from_pretrained(model_mbart)
from transformers import AutoModelForSeq2SeqLM, DataCollatorForSeq2Seq, Seq2SeqTrainingArguments, Seq2SeqTrainer
model = AutoModelForSeq2SeqLM.from_pretrained(model_t5)

其次,我们将定义一个数据排序器来填充输入并标记它们:

batch_size = 16
model_name = model.split("/")[-1]
args = Seq2SeqTrainingArguments(
   f"{model_name}-finetuned-{source_lang}-to-{target_lang}",
   evaluation_strategy = "epoch",
   learning_rate=2e-5,
   per_device_train_batch_size=batch_size,
   per_device_eval_batch_size=batch_size,
   weight_decay=0.01,
   save_total_limit=3,
   num_train_epochs=1,
   predict_with_generate=True
)

最后一件事是在我们训练模型时计算指标。

data_collator = DataCollatorForSeq2Seq(tokenizer, model=model)

现在,我们可以将所有这些和数据集一起传递给训练器 API。

import numpy as np
from datasets import load_metric
metric = load_metric("sacrebleu")
meteor = load_metric('meteor')

def postprocess_text(preds, labels):
   preds = [pred.strip() for pred in preds]
   labels = [[label.strip()] for label in labels]
   return preds, labels

def compute_metrics(eval_preds):
   preds, labels = eval_preds
   if isinstance(preds, tuple):
       preds = preds[0]
   decoded_preds = tokenizer.batch_decode(preds, skip_special_tokens=True)

   labels = np.where(labels != -100, labels, tokenizer.pad_token_id)
   decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)

   decoded_preds, decoded_labels = postprocess_text(decoded_preds, decoded_labels)
   result = metric.compute(predictions=decoded_preds, references=decoded_labels)
   meteor_result = meteor.compute(predictions=decoded_preds, references=decoded_labels)
   prediction_lens = [np.count_nonzero(pred != tokenizer.pad_token_id) for pred in preds]
   result = {'bleu' : result['score']}
   result["gen_len"] = np.mean(prediction_lens)
   result["meteor"] = meteor_result["meteor"]
   result = {k: round(v, 4) for k, v in result.items()}
   return result

在对模型进行微调之后,模型可以保存在目录中,我们应该能够像预训练模型一样使用它。我们还可以将该模式推广到拥抱脸集线器和共享。

trainer = Seq2SeqTrainer(
   model,
   args,
   train_dataset=small_train_dataset,
   eval_dataset=small_eval_dataset,
   data_collator=data_collator,
   tokenizer=tokenizer,
   compute_metrics=compute_metrics
)
trainer.train()

评估和跟踪模型性能–选择最佳模型

trainer.save_model()

现在,我们的模型已经根据更多的数据进行了训练和微调,我们需要决定为我们的解决方案选择哪个模型。有几件事我们可以看看:

1.预训练 vs 微调 vs 谷歌翻译

在上一节中,我们将微调后的模型保存在本地目录中。现在,我们将测试这些模型,并将翻译后的文本与预先训练的文本和谷歌翻译进行比较。以下是如何从本地目录访问您的微调模型:

马里亚姆特模型

MBart50 型号

import os
for dirname, _, filenames in os.walk('/content/opus-mt-en-de-finetuned-en-to-de'):
   for filename in filenames:
       print(os.path.join(dirname, filename))

from transformers import MarianMTModel, MarianTokenizer
src_text = ['USA Today is an American daily middle-market newspaper that is the flagship publication of its owner, Gannett. Founded by Al Neuharth on September 15, 1982.
']
model_name = 'opus-mt-en-de-finetuned-en-to-de'
tokenizer = MarianTokenizer.from_pretrained(model_name)
model = MarianMTModel.from_pretrained(model_name)
translated = model.generate(**tokenizer(src_text, return_tensors="pt", padding=True))
[tokenizer.decode(t, skip_special_tokens=True) for t in translated]

T5 型号

import os
for dirname, _, filenames in os.walk('/content/mbart-large-50-one-to-many-mmt-finetuned-en-to-de'):
   for filename in filenames:
       print(os.path.join(dirname, filename))

from transformers import MBart50TokenizerFast, MBartForConditionalGeneration
src_text = ["USA Today is an American daily middle-market newspaper that is the flagship publication of its owner, Gannett. Founded by Al Neuharth on September 15, 1982."]
model_name = 'mbart-large-50-one-to-many-mmt-finetuned-en-to-hi'
tokenizer = MBart50TokenizerFast.from_pretrained(model_name,src_lang="en_XX")
model = MBartForConditionalGeneration.from_pretrained(model_name)
model_inputs = tokenizer(src_text, return_tensors="pt")

generated_tokens = model.generate(
   **model_inputs,forced_bos_token_id=tokenizer.lang_code_to_id["de_DE"])
translation = tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)
translation

让我们比较一下 MarianMT、mBART 和 T5 型号的翻译文本:

import os
for dirname, _, filenames in os.walk('/content/t5-small-finetuned-en-to-de'):
   for filename in filenames:
       print(os.path.join(dirname, filename))

from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
src_text = ['USA Today is an American daily middle-market newspaper that is the flagship publication of its owner, Gannett. Founded by Al Neuharth on September 15, 1982.']
model_name = 't5-small-finetuned-en-to-de'
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
translated = model.generate(**tokenizer(src_text, return_tensors="pt", padding=True))
[tokenizer.decode(t, skip_special_tokens=True) for t in translated]

输入文本—《今日美国》是一份美国中型市场日报,是其所有者 Gannett 的旗舰出版物。由 Al Neuharth 于 1982 年 9 月 15 日创立。


【预先训练的 MarianMT 模型翻译】——【今天是美国中档日报,是其所有者的旗舰甘尼特。Al Neuharth 于 9 月 15 日成立
【精调 MarianMT 模型翻译】—今天,美国一家日报是其所有者的旗舰甘尼特的中产阶级。9 月 15 日 Al Neuharth 成立【

【预先训练的姆班波特模型翻译】——【今天是美国一家面向中型市场的日报,是其主人甘尼特的旗舰型出版物。9 月 15 日 Al Neuharth 成立【

【精调姆班波特】 【模型翻译】—美国今天是面向中型市场的美国日报,是其主人甘尼特的旗舰出版物。1982 年 9 月 15 日 Al Neuharth 成立。

预培训 T5 模型翻译----今天是美国中档报纸《T3》的一期

***【谷歌翻译】**—美国今天是美国面向中产阶级的日报,它是所有者的旗舰甘尼特。1982 年 9 月 15 日 Al Neuharth 成立。

使用 MarianMT 微调模型完成的翻译比预训练的 MarianMT 模型好,接近 Google translator。尽管这三本书的翻译都有一些语法错误。


与 MarianMT 和 Google translator 不同,预训练的 mBART 能够识别更多的单词,但在他们的翻译文本中没有太多差异。根据计算时间,mBART 微调需要很多时间,但当测试微调模型时,翻译结果或多或少与预训练相同。

T5 是所有模型中表现最差的,因为它不能翻译整段。预训练和微调的 T5 模型都没有正确翻译文本,甚至与其他模型相差甚远。

2.评估指标–比较模型

为了评估我们的模型,我们需要能够验证转换文本的质量及其准确性的指标。这就是原因,我们将采用以下指标进行评估。

双语评估替补演员

“这是一种算法,用于评估由机器从一种自然语言翻译成另一种自然语言的文本的质量。质量被认为是机器的输出与人类的输出之间的对应关系:“机器翻译越接近专业的人类翻译越好”——这是 BLEU 背后的中心思想。它是第一个声称与人类质量判断高度相关的指标之一,并且仍然是最受欢迎的自动化和廉价的指标之一。?

拥抱脸指标

流星

这是一种用于机器翻译评估的自动度量,其基于机器产生的翻译和人类产生的参考翻译之间的单词匹配的一般化概念。?

拥抱脸指标

在本文中,我们将这些指标定义为上面 compute_metrics()函数的一部分。我们可以在笔记本或任何其他 IDE 中运行代码时看到这些指标的值,但它可能很难阅读,也不太用户友好。为了自动跟踪和查看这些指标,清楚地看到最终的评估结果,我们可以使用 Neptune。它很容易使用,非常方便用户。

要了解我们选择这些指标的更多原因,请参考这篇文章

3.跟踪您的模型数据–参数、培训损失、CPU 使用率、指标等

Neptune 提供了一个很棒的用户界面来减轻跟踪模型、它们的训练、CPU 和 RAM 使用以及性能指标的痛苦。现在您已经知道了我们将在 Neptune 上跟踪和记录什么,让我们看看如何在 Neptune 平台上创建一个设置:

记录指标并在 Neptune UI 中查看它们:

pip install neptune-client
import neptune.new as neptune
%env NEPTUNE_PROJECT= natasha/pytorch-huggingface
%env NEPTUNE_API_TOKEN="<YOUR_API_TOKEN>"

run=neptune.init(project_qualified_name=NEPTUNE_PROJECT, api_token=NEPTUNE_API_TOKEN)

neptune.create_experiment()
  • 为了在 Neptune 中记录度量值,我们需要调用 Neptune . log _ metric("?).这个函数可以在训练模型的时候调用,但是对于本文,我们将在训练完成或者模型被微调之后记录指标。

Neptune 发布了与 HuggingFace Transformers 的集成,所以你现在可以用它来更快地开始跟踪。

我们首先使用 trainer API 的方法 evaluate 获得评估指标。

让我们看看它在海王星平台上是什么样子:

evaluate_results = trainer.evaluate()
neptune.log_metric('epoch',evaluate_results['epoch'])
neptune.log_metric('bleu',evaluate_results['eval_bleu'])
neptune.log_metric('meteor',evaluate_results['eval_meteor'])

在截图中,你可以看到所有预训练模型的 bleu 和 meteor 分数。这些指标表明,即使经过微调,T5 也无法准确预测。mbart 微调的 Bleu 评分(13)和 meteor 评分(. 27)表明很难从其翻译中获得要点。对于 MarianMT 和 mBART 模型,得分非常接近,这表明他们都产生了可理解的良好翻译。

Standard view of the project and experiments in Neptune.ai

Standard view of the project and experiments | Source

我们还可以通过选择任何实验来检查模型的元数据、CPU 和 RAM 的使用情况。

单击“monitoring”时,您将看到 CPU 和 RAM 的使用情况,在“logs”部分,您将看到所有记录的指标。

Model Metadata – logs and monitoring | Source

您还可以直观显示 CPU 和 RAM 的使用情况,如下所示:

让我们在 Neptune 中并排比较所有微调的模型,以便在一个地方有一个统一的视图:

除了比较这两个指标之外,我们还可以做更多的事情,但就本文而言,查看这些指标和翻译结果,我们可以得出结论,MarianMT 和 mBART 预训练模型和微调模型的性能优于 T5。mBART 的表现略好于 MarianMT,因为它能够识别输入文本中的更多单词,并且通过更多的训练可能会表现得更好。

Side-by-side model comparison in Neptune.ai

Side-by-side model comparison | Source

最后的想法

在这篇文章中,我们看到了拥抱脸是如何使 NLP 任务更容易集成到系统中的。虽然拥抱脸做了所有繁重的工作,但我们可以利用他们的 API 来创建 NLP 解决方案。拥抱脸支持许多自然语言处理任务,我们逐一研究了这些任务。我们还看到了拥抱脸如何为这些任务中的每一个任务提供专用管道,以及在无法使用它们的地方,我们可以使用预先训练的模型创建自己的管道。

在本文中,我们主要关注语言翻译任务,并研究了两种流行的模型。我们还看到了如何根据新数据训练和微调这些模型,并提高文本的质量。

在执行 mBart 时,我们还意识到 CPU 和 RAM 的使用高于 MarianMT 和 T5,并且它们的结果也没有太大的不同。有很大的改进空间,我们可以使用稍微大一点的训练数据来训练模型,增加训练的步骤和次数。你可以看看拥抱脸教程来了解更多关于这些模型和如何微调

这些不是支持 NLP 翻译任务的唯一模型。拥抱脸模型中心有许多可用的模型,或者可以使用多语言转换器创建。例如,XLM、伯特和 T5 模型,所有这些模型都被直接或间接地用来改进语言翻译系统,使之接近人工翻译。

拥抱 Face platform 为每个人提供了一个机会,通过他们的开源库开始解决 NLP 问题。他们的网站上也有一些精彩的教程,可以引导你浏览他们的图书馆。

Hugging Face platform is providing everyone an opportunity through their open source repositories to get started with NLP problems. They also have some brilliant tutorials on their website which can guide you through their library.***

超宽带和 BOHB:了解超参数优化算法的最新发展

原文:https://web.archive.org/web/https://neptune.ai/blog/hyperband-and-bohb-understanding-state-of-the-art-hyperparameter-optimization-algorithms

如果你想了解最先进的超参数优化算法(HPO),在这篇文章中我会告诉你它们是什么以及它们是如何工作的。

作为一名 ML 研究人员,我已经阅读并使用了相当多的最新 HPO 算法,在接下来的几节中,我将与您分享我迄今为止的发现。

希望你喜欢!

一点关于 HPO 的方法

HPO 是一种帮助解决机器学习算法的超参数调整挑战的方法。

杰出的 ML 算法具有多个不同的复杂超参数,这些超参数产生巨大的搜索空间。大量的初创企业选择在其管道的核心使用深度学习,深度学习方法中的搜索空间甚至比传统的 ML 算法更大。调谐到一个巨大的搜索空间是一项艰巨的挑战。

要解决 HPO 问题,我们需要使用数据驱动的方法。手动方法无效。

已经提出了许多解决 HPO 问题的方法:

我们将讨论四种主要的、最有效的方法。

贝叶斯优化

要理解 BO,我们应该对网格搜索和随机搜索方法有所了解(在本文的中有很好的解释)。我只是要总结一下这些方法。

假设我们的搜索空间只包含两个超参数,一个是重要的,另一个是不重要的。我们希望对它们进行调整,以提高模型的准确性。如果它们中的每一个都有 3 个不同的值,那么整个搜索空间将有 9 个可能的选择。我们可以尝试其中的每一个来找到两个超参数的最佳值。

但是从上图可以看出,网格搜索无法找到重要的超参数的最佳值。对此的一个解决方案可能是随机遍历搜索空间,就像下图一样。

贝叶斯优化为什么有效?

随机搜索最终收敛到最优答案,但这种方法就是这样的盲目搜索!有没有更智能的搜索方式?是的——贝叶斯优化,由 J . mo kus 提出。你可以在这本贝叶斯优化入门机器学习算法实用贝叶斯优化中找到更多关于 BO 的信息。

本质上,贝叶斯优化是一种概率模型,它想通过基于先前观察的学习来学习一个代价昂贵的目标函数。它有两个强大的功能:代理模型和获取功能。

在上图中,你可以看到基于自动机器学习中超参数优化章节的贝叶斯优化的一个很好的解释。在该图中,我们希望找到虚线所示的真实目标函数。假设我们有一个连续的超参数,在第二次迭代中我们观察到两个黑点,然后我们拟合了一个替代模型(回归模型),即黑线。黑线周围的蓝管是我们的不确定性。

我们还有一个获取函数,这是我们探索搜索空间以找到新的观测最优值的方法。换句话说,获取函数帮助我们改进代理模型并选择下一个值。在上图中,采集函数显示为橙色曲线。获取最大值意味着不确定性最大,而预测值较低。

贝叶斯优化的利弊

贝叶斯优化最重要的优点是它可以很好地运行黑箱函数。BO 也是数据高效的,并且对噪声具有鲁棒性。但是它不能很好地与并行资源 duo 一起工作,因为优化过程是顺序的。

https://web.archive.org/web/20221024193328if_/https://www.youtube.com/embed/3_E4A4G7nME?version=3&rel=1&showsearch=0&showinfo=1&iv_load_policy=1&fs=1&hl=en-US&autohide=2&wmode=transparent

视频

图片来自 Marius Lindauer 在开放数据科学大会上的演讲

*### 贝叶斯优化的实现

是时候看看一些贝叶斯优化实现了。我列出了最受欢迎的几个:

实施名称

代理模型

链接

Surrogate model:

随机森林

Surrogate model:

树 Parzen 估计量

Surrogate model:

高斯过程

Surrogate model:

高斯过程、RF 等。

多重保真优化

在贝叶斯方法中,目标函数的估计是非常昂贵的。有没有更便宜的估计目标函数的方法?多重保真优化方法是答案。我会告诉你:

连续有超带

  1. BOHB

  2. 作为额外的资源,在下面的视频中,Andreas Mueller 非常好地解释了多保真度优化方法。

  3. https://web.archive.org/web/20221024193328if_/https://www.youtube.com/embed/tqtTHRwa8dE?version=3&rel=1&showsearch=0&showinfo=1&iv_load_policy=1&fs=1&hl=en-US&autohide=2&wmode=transparent

    视频

安德里亚斯·穆勒 : 应用机器学习 2019

连续拥有

连续减半试图给最有希望的方法提供最多的预算。它假设所有配置都可以提前停止,并且可以获得验证分数。

假设您有 N 种不同的配置和预算(例如时间)。在每次迭代中,正如你在下图中看到的,连续的一半保留了配置中最好的一半,而丢弃了不好的一半算法。它将继续下去,直到我们只有一个单一的配置。此方法将在达到其预算的最大值时完成。

连续减半最初是在 Kevin Jamieson 和 Ameet Talwalkar 撰写的非随机最佳臂识别和超参数优化中提出的。

连续减半有什么问题?

在连续减半中,我们需要在开始时选择多少配置和需要多少切割之间进行权衡。在下一节中,您将看到 Hyperband 如何解决这个问题。

超波段

这种方法是连续减半算法的扩展,由李丽莎和其他人提出的一种新的基于 Bandit 的超参数优化方法。

我提到过,连续减半方法在选择数字配置和分配预算之间存在权衡。为了解决这个问题,HyperBand 提出使用不同的预算频繁执行连续减半方法,以找到最佳配置。在下图中,你可以看到 HyperBand 比随机搜索有更好的性能。

你可以在 automl.org 的 HpBandSter GitHub 页面中找到 HyperBand 的一个简单实现。如果你想知道如何使用这个 Python 工具,可以查看一下文档

BOHB

BOHB 是一种最先进的超参数优化算法,由 Stefan Falkner、Aaron Klein 和 Frank Hutter 撰写的 BOHB:大规模鲁棒和高效的超参数优化中提出。BOHB 算法背后的想法是基于一个简单的问题——为什么我们要重复运行连续减半?

BOHB 使用贝叶斯优化算法,而不是在连续减半的基础上盲目重复的方法。事实上,BOHB 将 HyperBand 和 BO 结合起来,以一种高效的方式使用这两种算法。丹·瑞恩在他的演讲中完美地解释了 BOHB 方法。将其添加到您的观察列表

https://web.archive.org/web/20221024193328if_/https://www.youtube.com/embed/IqQT8se9ofQ?version=3&rel=1&showsearch=0&showinfo=1&iv_load_policy=1&fs=1&hl=en-US&autohide=2&wmode=transparent

视频

Dan Ryan 在 PyData Miami 2019 上关于高效灵活的超参数优化的精彩演讲

BOHB 是一种多保真度优化方法,这些方法依赖于预算,因此找到相应的预算很重要。另一方面,BOHB 是健壮的、灵活的和可伸缩的。如果你需要更详细的信息,你可能会想要查看安德烈·比登卡普和弗兰克·胡特关于 BOHB 的官方博客文章。

另外, HpBandSter 是 BOHB 和 HyperBand 的一个很好的实现。你可以在这里找到它的文档

在 Neptune 中随机搜索 vs . HyperBand vs . BOHB+结果比较

现在我们已经知道了描述,也熟悉了方法,下面我们就用海王星基于这些方法做一些实验和比较。

如果你想跟着我:

因为我决定在平等的基础上做这个实验,所以我使用了 HpBandSter ,它有一个 BOHB 的实现,HyperBand 和 RandomSearch 作为优化器。一个官方的例子可以在这里找到。基于这个例子,我们在 Pytorch 中有一个小 CNN,它将针对 MNIST 数据集进行调谐。我基于三种不同的优化器运行了这个示例:

BOHB

超波段

  1. 随机搜索。
  2. 对于每个优化器,我使用了以下预算:
  3. RandomSearch.

配置

范围值

[1,2,3,4,8,10]

Range value

Range value:

[1,2,3,4,8,10]

这意味着我们已经运行了不同的组合,至少 26 个实验来检查优化器的能力(BOHB,超波段,随机搜索)。此外,通过这个示例,我们希望根据以下超参数找到 CNN 的最佳配置。

第一个配置层中的过滤器数量

全连接层中隐藏单元的数量

Number of filters in the first conf layer

Number of hidden units in fully connected layer

配置取自惠普主机文档

在海王星中用各种配置运行这些实验后,我得到了一些有见地的结果。

跟随海王星 的所有实验

在这里,您可以看到 n_iteration=3 和 max_budget=3 的优化器之间的良好对比。我发现,如果我增加迭代次数,所有优化器最终都会获得最佳性能,但当预算很大时,BOHB 可以做得更好。

最终,对于 max_budget=5 和 n_iteration=4,每个优化器都会找到一个最佳配置,您可以在下表中查看。

Here you can see a nice contrast between those optimizers for n_iteration=3 and max_budget=3. I find that if I increase the number of iterations, all optimizers finally get best performance, but when the budget is significant, BOHB could do it better.

Neptune hyperband bohb comparison

Comparison between (BOHB, HyperBand, RandomSearch) for n_iteration=3 and max_budget=

超参数

调谐前的范围

调优后:随机搜索

调谐后:超波段

调谐后:BOHB

[1e-6,1e-2]

0.010

Range before tuning:

0.00031

After tuning: Random search:

0.0078

After tuning: Hyperband:

[1,3]

After tuning: BOHB:

2

Range before tuning:

1

After tuning: Random search:

第一个配置层中的过滤器数量

After tuning: Hyperband:

[4, 64]

13

Range before tuning:

9

After tuning: Random search:

[0, 0.9]

After tuning: Hyperband:

0.77

Range before tuning:

0.06

After tuning: Random search:

全连接层中隐藏单元的数量

After tuning: Hyperband:

[8,256]

177

Range before tuning:

248

After tuning: Random search:

177

After tuning: Hyperband:

最后的想法

感谢您加入我的旅程!我们涵盖了:

贝叶斯优化的工作原理。

多重保真优化。

  • BOHB 和超级乐队,以及他们是如何工作的。
  • 哪个优化器(HyperBand 和 BOHB)在实验中效果更好?
  • 希望你喜欢这本书!
  • MJ 巴赫马尼

一位对机器学习领域充满热情的经验丰富的软件工程师。他对开发尽可能高效和自动地解决真正的机器学习问题的软件特别感兴趣。

阅读下一篇

如何跟踪机器学习模型的超参数?


卡米尔·卡什马雷克|发布于 2020 年 7 月 1 日

How to Track Hyperparameters of Machine Learning Models?

机器学习算法可通过称为超参数的多个量规进行调整。最近的深度学习模型可以通过数十个超参数进行调整,这些超参数与数据扩充参数和训练程序参数一起创建了非常复杂的空间。在强化学习领域,您还应该计算环境参数。

数据科学家要控制好 超参数 空间,才能使 进步

在这里,我们将向您展示最近的 实践提示&技巧,工具以最小的开销高效地跟踪超参数。你会发现自己掌控了最复杂的深度学习实验!

为什么我应该跟踪我的超参数?也就是为什么这很重要?

几乎每一个深度学习实验指南,像这本深度学习书籍,都建议你如何调整超参数,使模型按预期工作。在实验-分析-学习循环中,数据科学家必须控制正在进行的更改,以便循环的“学习”部分正常工作。

哦,忘了说随机种子也是一个超参数(特别是在 RL 领域:例如检查这个 Reddit )。

超参数跟踪的当前实践是什么?

让我们逐一回顾一下管理超参数的常见做法。我们关注于如何构建、保存和传递超参数给你的 ML 脚本。

What is current practice in the hyperparameters tracking?

Let’s review one-by-one common practices for managing hyperparameters. We focus on how to build, keep and pass hyperparameters to your ML scripts.

Continue reading ->


Python 中超参数调优:完全指南

原文:https://web.archive.org/web/https://neptune.ai/blog/hyperparameter-tuning-in-python-complete-guide

为机器学习或深度学习模型选择正确的超参数是从模型中提取最后汁液的最佳方式之一。在本文中,我将向您展示目前可用的一些最佳超参数调优方法。

参数和超参数有什么区别?

首先我们来了解一下机器学习中超参数和参数的区别。

  • 模型参数:这些是模型从给定的数据中估计出来的参数。例如深度神经网络的权重。
  • 模型超参数:这些是模型无法从给定数据中估计出来的参数。这些参数用于估计模型参数。比如深度神经网络中的学习速率。
因素 超参数

它们是进行预测所需要的

|

它们是估算模型参数所需要的

|
| |

它们是通过超参数调谐

来估计的 |
|

它们不是手动设置的

| |
|

训练后发现的最终参数将决定模型如何对未发现的数据执行

|

超参数的选择决定了训练的效率。在梯度下降中,学习率决定了优化过程在估计参数时的效率和准确性

|

模型参数 vs 模型超参数|来源:GeeksforGeeks

什么是超参数调整,为什么它很重要?

超参数调整(或超参数优化)是确定最大化模型性能的正确超参数组合的过程。它的工作原理是在一个训练过程中进行多次试验。每次试验都是使用您选择的超参数值(在您指定的范围内设置)完整执行您的训练应用程序。该过程一旦完成,将为您提供最适合模型的一组超参数值,以获得最佳结果。

不用说,这是任何机器学习项目中的重要一步,因为它会导致模型的最优结果。如果您希望看到它的实际应用,这里有一篇研究论文,它通过在数据集上进行实验,讲述了超参数优化的重要性。

如何进行超参数调谐?如何找到最佳超参数?

选择正确的超参数组合需要理解超参数和业务用例。但是,从技术上来说,有两种方法可以设置它们。

手动超参数调谐

手动超参数调整包括手动试验不同的超参数集,即您将执行一组超参数的每次试验。这项技术需要一个强大的实验跟踪器,它可以跟踪从图像、日志到系统指标的各种变量。

有几个实验跟踪器可以勾选所有的框。 neptune.ai 就是其中之一。它提供了一个直观的界面和一个开源包 neptune-client 来方便你登录代码。您可以轻松记录超参数,并查看所有类型的数据结果,如图像、指标等。查看文档,看看如何将不同的元数据记录到 Neptune

替代解决方案包括 W&B、Comet 或 MLflow。点击查看更多实验跟踪工具&管理。

手动超参数优化的优势:

  • 手动调整超参数意味着对过程的更多控制。
  • 如果您正在研究调优以及它如何影响网络权重,那么手动进行调优是有意义的。

手动超参数的缺点优化**** :

  • 手动调谐是一个乏味的过程,因为可能有许多尝试,并且跟踪可能证明是昂贵和耗时的。
  • 当有许多超参数需要考虑时,这不是一个非常实用的方法。

点击了解如何手动优化机器学习模型超参数。

自动超参数调谐

自动超参数调整利用现有的算法来自动化该过程。您需要遵循的步骤是:

  • 首先,指定一组超参数和对这些超参数值的限制(注意:每个算法都要求这组参数是特定的数据结构,例如,在处理算法时,字典是常见的)。
  • 然后算法会帮你完成繁重的工作。它会运行这些试验,并为您获取最佳的超参数集,以获得最佳结果。

在博客中,我们将讨论一些可以用来实现自动调优的算法和工具。我们开始吧。

超参数调谐方法

在这一节中,我将介绍当今流行的所有超参数优化方法。

随机搜索

随机搜索方法中,我们为超参数创建一个可能值的网格。每次迭代尝试这个网格中超参数的随机组合,记录性能,最后返回提供最佳性能的超参数组合。

网格搜索

网格搜索方法中,我们为超参数创建一个可能值的网格。每次迭代以特定的顺序尝试超参数的组合。它在每个可能的超参数组合上拟合模型,并记录模型性能。最后,它返回具有最佳超参数的最佳模型。

贝叶斯优化

为您的模型调整和找到正确的超参数是一个优化问题。我们希望通过改变模型参数来最小化模型的损失函数。贝叶斯优化帮助我们在最少的步骤中找到最小的点。贝叶斯优化还使用一个采集函数,该函数将采样指向可能比当前最佳观测值有所改进的区域。

树结构 Parzen 估计量(TPE)

基于树的 Parzen 优化的思想类似于贝叶斯优化。TPE 模型 P(x|y)和 p(y)不是寻找 p(y|x)的值,其中 y 是要最小化的函数(例如,验证损失), x 是超参数的值。树结构 Parzen 估计器的一个大缺点是它们没有模拟超参数之间的相互作用。也就是说,TPE 在实践中工作得非常好,并且在大多数领域都经过了实战考验。

超参数调整算法

这些是专门为进行超参数调整而开发的算法。

超波段

Hyperband 是随机搜索的一种变体,但是使用了一些探索-利用理论来为每种配置找到最佳的时间分配。你可以查看这篇研究论文以获取更多参考。

基于人口的培训

这种技术是两种最常用的搜索技术的混合:随机搜索和应用于神经网络模型的手动调整。

PBT 从用随机超参数并行训练许多神经网络开始。但是这些网络并不是完全相互独立的。

它使用来自其余群体的信息来改进超参数,并确定要尝试的超参数的值。你可以查看这篇文章了解更多关于 PBT 的信息。

BOHB

BOHB(贝叶斯优化和超带)混合了超带算法和贝叶斯优化。可以查看这篇文章进一步参考。

现在你知道了什么是方法和算法,让我们来谈谈工具,有很多这样的工具。

一些最好的超参数优化库是:

  1. Scikit-learn
  2. sci kit-优化
  3. Optuna
  4. 远视
  5. 雷.调
  6. 塔罗斯
  7. 贝叶斯优化
  8. 度量优化引擎(MOE)
  9. 留兰香
  10. GPyOpt
  11. SigOpt
  12. 法博拉斯

1. Scikit-learn

Scikit-learn 实现了网格搜索和随机搜索,如果您正在使用 sklearn 构建模型,这是一个很好的起点。

对于这两种方法,scikit-learn 在各种参数选择上以 k 倍交叉验证设置训练和评估模型,并返回最佳模型。

具体来说:

  • 随机搜索:randomsearchcv 在一些随机参数组合上运行搜索
  • 网格搜索: gridsearchcv 对网格中的所有参数集进行搜索

用 scikit-learn 调优模型是一个好的开始,但是还有更好的选择,而且它们通常有随机搜索策略。

2.sci kit-优化

Scikit-optimize 使用基于序列模型的优化算法,在更短的时间内找到超参数搜索问题的最优解。

Scikit-optimize 提供了除超参数优化之外的许多功能,例如:

  • 存储和加载优化结果,
  • 收敛图,
  • 比较代理模型

3.奥普图纳

Optuna 使用轨迹细节的历史记录来确定有希望的区域,以搜索优化超参数,从而在最短的时间内找到最佳超参数。

它具有修剪功能,可以在训练的早期阶段自动停止不被看好的轨迹。optuna 提供的一些主要功能有:

  • 轻量级、通用且平台无关的架构
  • Pythonic 搜索空间
  • 高效优化算法
  • 易于并行化
  • 快速可视化

关于如何开始使用 optuna 的教程,可以参考官方文档

4.远视

Hyperopt 是目前最流行的超参数调谐包之一。Hyperopt 允许用户描述一个搜索空间,在该搜索空间中,用户期望得到最佳结果,从而允许 hyperopt 中的算法更有效地搜索。

目前,hyperopt 中实现了三种算法。

要使用远视,您应该首先描述:

  • 最小化的目标函数
  • 要搜索的空间
  • 存储搜索的所有点评估的数据库
  • 要使用的搜索算法

这个教程将带你了解如何构建代码并使用 hyperopt 包来获得最佳的超参数。

您也可以阅读这篇文章,了解更多关于如何使用 Hyperopt 的信息。

5.射线调谐

射线调谐是实验和超参数调谐在任何规模的流行选择。Ray 使用分布式计算的能力来加速超参数优化,并在大规模上实现了几种最先进的优化算法。

“光线调节”提供的一些核心功能包括:

  • 通过利用 Ray 实现开箱即用的分布式异步优化。
  • 易于扩展。
  • 提供了 ASHABOHB基于人口的训练等 SOTA 算法。
  • 支持 Tensorboard 和 MLflow。
  • 支持 Sklearn、XGBoost、TensorFlow、PyTorch 等多种框架。

你可以参考这个教程来学习如何针对你的问题实现光线调谐。

6. Keras Tuner

Keras Tuner 是一个帮助您为 TensorFlow 程序选择最佳超参数集的库。当您为超参数调整构建模型时,除了模型架构之外,您还定义了超参数搜索空间。您为超参数调整设置的模型被称为超模型

您可以通过两种方法定义超级模型:

  • 通过使用模型构建器功能
  • 通过子类化 Keras Tuner API 的超级模型类

对于计算机视觉应用,您还可以使用两个预定义的超级模型类——hyperexceptionHyperResNet

进一步的实现细节可以参考这个官方教程

7.贝叶斯最优化

BayesianOptimization 是一个软件包,旨在最大限度地减少寻找接近最佳组合的参数组合所需的步骤。

这种方法使用了一个代理优化问题(寻找获取函数的最大值),虽然这仍然是一个困难的问题,但在计算意义上它更便宜,并且可以使用常见的工具。因此,贝叶斯优化最适合对要优化的函数进行采样是一项非常昂贵的工作的情况。

点击这里访问 GitHub repo 查看它的运行情况。

8.度量优化引擎

MOE(公制优化引擎)当评估参数耗时或昂贵时,MOE 是优化系统参数的有效方法。

它是解决以下问题的理想选择

  • 优化问题的目标函数是一个黑盒,不一定是凸的或凹的,
  • 衍生品不可用,
  • 我们寻求的是全局最优,而不仅仅是局部最优。

这种处理黑盒目标函数的能力允许我们使用 MOE 来优化几乎任何系统,而不需要任何内部知识或访问。

访问 GitHub repo 了解更多信息。

9.留兰香

Spearmint 是一个软件包,也执行贝叶斯优化。该软件被设计成自动运行实验(因此代号为 spearmint ),以迭代的方式调整多个参数,以便在尽可能少的运行中最小化一些目标。

阅读并实验 GitHub repo 中关于留兰香的内容。

10.GPyOpt

GPyOpt 是使用 GPy 的高斯过程优化。它使用不同的采集函数执行全局优化。

在其他功能中,可以使用 GPyOpt 来优化物理实验(顺序或批量)和调整机器学习算法的参数。它能够通过稀疏高斯过程模型处理大型数据集。

不幸的是,GPyOpt 的维护已经被 repo 的作者关闭了,但是你仍然可以在你的实验中使用这个包。

前往 GitHub repo 这里

11.SigOpt

SigOpt 将自动超参数调整与训练跑步跟踪完全集成,让您了解更广阔的前景和达到最佳模式的途径。

凭借高度可定制的搜索空间和多尺度优化等功能,SigOpt 可以在将模型投入生产之前,使用简单的 API 对其进行复杂的超参数调整。

访问文档此处了解更多关于 SigOpt 超参数调整的信息。

12.法博拉斯

传统的贝叶斯超参数优化器将机器学习算法在给定数据集上的损失建模为要最小化的黑盒函数,而大型数据集上的快速贝叶斯优化(FABOLAS)对数据集大小上的损失和计算成本进行建模,并使用这些模型来执行具有额外自由度的贝叶斯优化。

你可以在这里查看实现 fabolas 的函数,在这里查看研究论文

超参数调整资源和示例

在这一节中,我将分享一些为不同的 ML 和 DL 框架实现的超参数调优示例。

随机森林超参数调整

XGBoost 超参数调整

LightGBM 超参数调谐

CatBoost 超参数调节

Keras 超参数调谐

PyTorch 超参数调谐

最后的想法

恭喜你,你成功了!超参数调优是任何机器学习项目不可或缺的一部分,因此这个主题总是值得深入研究。在这篇博客中,我们讨论了广泛使用和研究的不同超参数调优算法和工具。但即使如此,我们也涵盖了大量的技术和工具,正如一位智者曾经说过的,知识永无止境。

以下是该领域的一些最新研究,你可能会感兴趣:

就这些了,请继续关注更多,再见!

如何通过 3 个简单的步骤在任何 Python 脚本上进行超参数调优

原文:https://web.archive.org/web/https://neptune.ai/blog/hyperparameter-tuning-on-any-python-script

你写了一个 Python 脚本,用来训练和评估你的机器学习模型。现在,您想自动调整超参数以提高其性能吗?

我抓住你了!

在本文中,我将向您展示如何将您的脚本转换成可以用任何超参数优化库进行优化的目标函数。

只需 3 个步骤,你就可以像没有明天一样调整模型参数。

准备好了吗?

我们走吧!

我想你的main.py脚本应该是这样的:

import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import train_test_split

data = pd.read_csv('data/train.csv', nrows=10000)
X = data.drop(['ID_code', 'target'], axis=1)
y = data['target']
(X_train, X_valid, 
y_train, y_valid )= train_test_split(X, y, test_size=0.2, random_state=1234)

train_data = lgb.Dataset(X_train, label=y_train)
valid_data = lgb.Dataset(X_valid, label=y_valid, reference=train_data)

params = {'objective': 'binary',
          'metric': 'auc',
          'learning_rate': 0.4,
          'max_depth': 15,
          'num_leaves': 20,
          'feature_fraction': 0.8,
          'subsample': 0.2}

model = lgb.train(params, train_data,
                  num_boost_round=300,
                  early_stopping_rounds=30,
                  valid_sets=[valid_data],
                  valid_names=['valid'])

score = model.best_score['valid']['auc']
print('validation AUC:', score)

步骤 1:从代码中分离搜索参数

获取您想要调整的参数,并将它们放在脚本顶部的字典中。这样做可以有效地将搜索参数从代码的其余部分中分离出来。

import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import train_test_split

SEARCH_PARAMS = {'learning_rate': 0.4,
                 'max_depth': 15,
                 'num_leaves': 20,
                 'feature_fraction': 0.8,
                 'subsample': 0.2}

data = pd.read_csv('../data/train.csv', nrows=10000)
X = data.drop(['ID_code', 'target'], axis=1)
y = data['target']
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=1234)

train_data = lgb.Dataset(X_train, label=y_train)
valid_data = lgb.Dataset(X_valid, label=y_valid, reference=train_data)

params = {'objective': 'binary',
          'metric': 'auc',
          **SEARCH_PARAMS}

model = lgb.train(params, train_data,
                  num_boost_round=300,
                  early_stopping_rounds=30,
                  valid_sets=[valid_data],
                  valid_names=['valid'])

score = model.best_score['valid']['auc']
print('validation AUC:', score)

步骤 2:将培训和评估打包成一个功能

现在,您可以将整个训练和评估逻辑放在一个train_evaluate函数中。该函数将参数作为输入,并输出验证分数。

import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import train_test_split

SEARCH_PARAMS = {'learning_rate': 0.4,
                 'max_depth': 15,
                 'num_leaves': 20,
                 'feature_fraction': 0.8,
                 'subsample': 0.2}

def train_evaluate(search_params):
    data = pd.read_csv('../data/train.csv', nrows=10000)
    X = data.drop(['ID_code', 'target'], axis=1)
    y = data['target']
    X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=1234)

    train_data = lgb.Dataset(X_train, label=y_train)
    valid_data = lgb.Dataset(X_valid, label=y_valid, reference=train_data)

    params = {'objective': 'binary',
              'metric': 'auc',
              **search_params}

    model = lgb.train(params, train_data,
                      num_boost_round=300,
                      early_stopping_rounds=30,
                      valid_sets=[valid_data],
                      valid_names=['valid'])

    score = model.best_score['valid']['auc']
    return score

if __name__ == '__main__':
    score = train_evaluate(SEARCH_PARAMS)
    print('validation AUC:', score)

步骤 3:运行 hypeparameter 调整脚本

我们快到了。

你现在需要做的就是使用这个train_evaluate函数作为你选择的黑盒优化库的目标。

我将使用 Scikit Optimize ,我已经在的另一篇文章中详细描述了它,但是你可以使用任何超参数优化库。

了解更多信息

💡使用 Scikit-Optimize + Neptune 集成,检查如何在运行时可视化运行,记录每次运行时尝试的参数,等等。

简单地说,我

  • 定义搜索 空间
  • 创建将被最小化的objective函数,
  • 通过skopt.forest_minimize功能运行优化。

在这个例子中,我将从 10 随机选择的参数集开始,尝试 100 种不同的配置。

import skopt

from script_step2 import train_evaluate

SPACE = [
    skopt.space.Real(0.01, 0.5, name='learning_rate', prior='log-uniform'),
    skopt.space.Integer(1, 30, name='max_depth'),
    skopt.space.Integer(2, 100, name='num_leaves'),
    skopt.space.Real(0.1, 1.0, name='feature_fraction', prior='uniform'),
    skopt.space.Real(0.1, 1.0, name='subsample', prior='uniform')]

@skopt.utils.use_named_args(SPACE)
def objective(**params):
    return -1.0 * train_evaluate(params)

results = skopt.forest_minimize(objective, SPACE, n_calls=30, n_random_starts=10)
best_auc = -1.0 * results.fun
best_params = results.x

print('best result: ', best_auc)
print('best parameters: ', best_params)

这就是了。

结果 对象包含关于产生它的最佳分数 和参数的信息。


请注意,由于最近的 API 更新,这篇文章也需要一些改变——我们正在努力!与此同时,请检查海王星文档,那里的一切都是最新的!🥳


注意:

如果您想可视化您的训练并在训练结束后保存诊断图表,您可以添加一个回调和一个函数调用来将每个超参数搜索记录到 Neptune。只需使用 neptune-contrib 库中的这个助手函数。

import neptune
import neptunecontrib.monitoring.skopt as sk_utils
import skopt

from script_step2 import train_evaluate

neptune.init('jakub-czakon/blog-hpo')
neptune.create_experiment('hpo-on-any-script', upload_source_files=['*.py'])

SPACE = [
    skopt.space.Real(0.01, 0.5, name='learning_rate', prior='log-uniform'),
    skopt.space.Integer(1, 30, name='max_depth'),
    skopt.space.Integer(2, 100, name='num_leaves'),
    skopt.space.Real(0.1, 1.0, name='feature_fraction', prior='uniform'),
    skopt.space.Real(0.1, 1.0, name='subsample', prior='uniform')]

@skopt.utils.use_named_args(SPACE)
def objective(**params):
    return -1.0 * train_evaluate(params)

monitor = sk_utils.NeptuneMonitor()
results = skopt.forest_minimize(objective, SPACE, n_calls=100, n_random_starts=10, callback=[monitor])
sk_utils.log_results(results)

neptune.stop()

现在,当您运行参数扫描时,您将看到以下内容:

最后的想法

在本文中,您已经学习了如何通过 3 个步骤优化几乎所有 Python 脚本的超参数。

希望有了这些知识,你会用更少的努力建立更好的机器学习模型。

快乐训练!

雅各布·查孔

大部分是 ML 的人。构建 MLOps 工具,编写技术资料,在 Neptune 进行想法实验。


阅读下一篇

如何跟踪机器学习模型的超参数?

卡米尔·卡什马雷克|发布于 2020 年 7 月 1 日

机器学习算法可通过称为超参数的多个量规进行调整。最近的深度学习模型可以通过数十个超参数进行调整,这些超参数与数据扩充参数和训练程序参数一起创建了非常复杂的空间。在强化学习领域,您还应该计算环境参数。

数据科学家要控制好 超参数 空间,才能使 进步

在这里,我们将向您展示最近的 实践提示&技巧,工具以最小的开销高效地跟踪超参数。你会发现自己掌控了最复杂的深度学习实验!

为什么我应该跟踪我的超参数?也就是为什么这很重要?

几乎每一个深度学习实验指南,像这本深度学习书籍,都建议你如何调整超参数,使模型按预期工作。在实验-分析-学习循环中,数据科学家必须控制正在进行的更改,以便循环的“学习”部分正常工作。

哦,忘了说随机种子也是一个超参数(特别是在 RL 领域:例如检查这个 Reddit )。

超参数跟踪的当前实践是什么?

让我们逐一回顾一下管理超参数的常见做法。我们关注于如何构建、保存和传递超参数给你的 ML 脚本。

Continue reading ->


深度学习的顶级开源工具和库——ICLR 2020 经验

原文:https://web.archive.org/web/https://neptune.ai/blog/iclr-2020-deep-learning-open-source

前沿的深度学习是在哪里产生和讨论的?

排名靠前的地方之一是 ICLR,这是一个领先的深度学习会议,于 2020 年 4 月 27 日至 30 日举行。作为一个完全虚拟的活动,有 5600 多名参与者和近 700 份论文/海报,它可以被称为一个巨大的成功。您可以在这里、这里这里找到关于会议的全面信息。

虚拟社交会议是 ICLR 2020 的吸引力之一。我们决定在最先进的 DL 研究中运行我们自己命名为的开源工具和实践。我们选择这个主题是因为合适的工具是深度学习研究不可避免的一部分。该领域的进步导致了大型框架生态系统(TensorFlow、、PyTorch 、MXNet)以及服务于特定需求的小型定向工具的激增。

我们社交活动的目的是会见开源工具的创造者和用户,并与深度学习社区分享经验和印象。我们总共召集了 100 多人,包括工具的维护人员,我们给了他们很短的时间来展示他们的工作。我们对展示的工具和库的多样性和创造性感到惊讶和兴奋。

在本帖中,创作者再次登台,告诉我们更多关于他们的项目

在这里,出席 ICLR 社交活动的八位创造者分享了更多关于他们工具的点滴。因此,亲爱的读者,由于他们的工作,你对所有可能的奇迹有了第一手的了解。

每一部分都以非常简洁的方式告诉您几件事情:

  1. 工具/库解决什么问题?
  2. 如何运行或创建一个极简的例子?
  3. 深入了解库/工具的外部资源数量。
  4. 创作者简介,以防你想联系到他们。

你可以跳到下面特定部分,或者只是一个一个地浏览,以获得一些灵感:

(按工具名称的字母顺序)


放大图

知识图嵌入模型

描述

知识图是一种表示复杂系统的通用语言。

无论是社交网络、生物信息学数据集,还是零售购买数据,将知识建模为图表可以让组织捕捉到否则会被忽略的模式。

然而,揭示这些数据之间的联系需要专门为图表设计的机器学习模型。

AmpliGraph 是 Apache 2 许可的一套神经机器学习模型,称为知识图嵌入。这种模型用低维向量对图的节点和边进行编码,并组合它们来预测缺失的事实。仅举几个例子,知识图嵌入在知识图完成、知识发现和基于链接的聚类中有应用。

AmpliGraph 降低了知识图嵌入的门槛,使这种模型可以被没有经验的用户使用,从而培养了一个从业者社区,可以利用开源 API 的优势在知识图上进行机器学习。我们将学习如何从真实世界的知识图中生成和可视化嵌入,以及如何在下游的机器学习任务中使用它们。

首先,下面是一个最小的代码片段,用于在基准图数据集上训练模型,并预测缺失的链接:

AmpliGraph 最初由埃森哲都柏林实验室开发,用于各种工业项目。

from ampligraph.datasets import load_fb15k_237
from ampligraph.latent_features import TransE

X = load_fb15k_237()

model = TransE(batches_count=100, epochs=20, k=20, verbose=True)

model.fit(X['train'])

model.calibrate(X['valid'], positive_base_rate=0.5)

X['test'][42]

model.predict_proba(X['test'][42])

AmpliGraph’s machine learning models generate knowledge graph embeddings, vector representations of concepts in a metric space.

It then combines embeddings with model-specific scoring functions to predict unseen and novel links.

GitHub | 文档

自动装载


表格数据预处理平台

描述

Automunge 是一个 Python 库平台,为机器学习准备表格数据。通过应用,简单的特征工程变换被应用于标准化、数字编码和插入填充。转换“适合”训练集的属性,然后在此基础上一致地应用于测试数据。转换可以自动执行,从内部库分配,或由用户自定义。填充选项包括“ML 填充”,其中自动机器学习模型针对每个列进行训练,以预测填充。

换句话说,简单地说:

automunge(.)为机器学习准备表格数据。

postmunge(.)持续高效地准备额外数据。

  • pip 安装现在可以使用自动安装:
  • 安装后,在笔记本中运行以初始化:

使用默认参数运行自动列车组处理的位置:

pip install Automunge

为了测试数据的后续一致处理,使用从相应的automunge(.)调用中填充的postprocess_dict字典,运行:

from Automunge import Automunger
am = Automunger.AutoMunge()

用户可以通过assigncatassigninfill参数在automunge(.)调用中指定转换或填充类型。例如,对于具有列标题“列 1”和“列 2”的训练集,可以将具有 ML 填充的最小-最大缩放(“mnmx”)分配给列 1,将具有模式填充的单热编码(“text”)分配给列 2。任何未明确指定的列都将遵从自动化。

train, trainID, labels,
validation1, validationID1, validationlabels1,
validation2, validationID2, validationlabels2,
test, testID, testlabels,
labelsencoding_dict, finalcolumns_train, finalcolumns_test,
featureimportance, postprocess_dict
= am.automunge(df_train)

网站 | GitHub | 简介

test, testID, testlabels,
labelsencoding_dict, postreports_dict
= am.postmunge(postprocess_dict, df_test)

DynaML

train, trainID, labels,
validation1, validationID1, validationlabels1,
validation2, validationID2, validationlabels2,
test, testID, testlabels,
labelsencoding_dict, finalcolumns_train, finalcolumns_test,
featureimportance, postprocess_dict
= am.automunge(df_train,
            assigncat = {'mnmx':['column1'], 'text':['column2']},
            assigninfill = {'MLinfill':['column1'], 'modeinfill':['column2']})

Scala 中的机器学习


描述

DynaML 是一个基于 Scala 的工具箱,用于机器学习研究和应用。它旨在为用户提供一个端到端的环境,有助于:

开发/原型模型。

处理大型复杂的数据管道。

可视化数据和结果。

  1. 以脚本、笔记本的形式重用代码。
  2. DynaML 充分利用了 Scala 语言和生态系统的优势,提供了一个能够提高性能和灵活性的环境。它基于菊石 scala shell、 Tensorflow-ScalaBreeze 数值计算库等优秀项目构建。
  3. DynaML 的一个关键组件是 REPL/shell,它具有语法高亮和高级自动完成/命令历史。
  4. 在终端会话中复制粘贴代码片段,以运行它们。

该环境加载了 2d 和 3d 可视化支持,可以直接从 shell 会话中绘制结果。

数据管道模块可以方便地以可组合和模块化的方式创建数据处理管道。使用DataPipe构造函数创建函数并包装它们,使用>操作符组成功能块。

一个实验性的 Jupyter 笔记本集成特性也是可用的,资源库中的 笔记本 目录包含了一些使用 DynaML-Scala Jupyter 内核的例子。

用户指南包含广泛的支持和文档,用于学习和充分利用 DynaML 环境。

3D charts are rendered using the jzy3d Java API.

突出 DynaML 优势的一些有趣的应用程序是:

Processing streams of data is intuitive when using pipe composition, the pipeline is divided logically into steps; with each step doing a single task.

GitHub | 用户指南

The linear regression notebook demonstrates the use of the low level Tensorflow API to compute coefficients of a linear regression model.

九头蛇

配置和参数管理器

描述


Hydra 由脸书人工智能公司开发,是一个简化研究应用程序开发的 Python 框架,提供了通过配置文件和命令行组合和覆盖配置的能力。它还提供参数扫描支持,通过插件远程和并行执行,自动工作目录管理和动态标签完成。

使用 Hydra 还可以使您的代码在不同的机器学习环境中具有更好的可移植性。使您能够在个人工作站、公共集群和私有集群之间移动,而无需更改代码。它通过可插拔架构实现这一点。

基本示例:

这个例子使用了数据库配置,但是您可以很容易地用模型、数据集或任何您想要的东西来替换它。

config.yaml

my_app.py :

您可以从命令行覆盖配置中的任何内容:

作文示例:

您可能希望在两种不同的数据库配置之间进行切换:

db:
  driver: mysql
  user: omry
  pass: secret

创建此目录结构:

import hydra
from omegaconf import DictConfig

@hydra.main(config_path="config.yaml")
def my_app(cfg : DictConfig) -> None:
  print(cfg.pretty())

if __name__ == "__main__":
  my_app()

config.yaml:

$ python my_app.py db.user=root db.pass=1234
db:
  driver: mysql
  user: root
  pass: 1234

defaults 是一个特殊的指令,告诉 Hydra 在构造配置对象时使用 db/mysql.yaml。

您现在可以从中选择要使用的数据库配置,并从命令行覆盖值:

查看教程了解更多信息。

此外,一些激动人心的新功能即将推出:

├── db
│ ├── mysql.yaml
│ └── postgresql.yaml
├── config.yaml
└── my_app.py

强类型配置(结构化配置)

defaults:
  - db: mysql

website:
  domain: example.com

通过 Ax 和 Nevergrad 插件优化超参数

$ python my_app.py db=postgresql db.timeout=20
db:
  driver: postgresql
  pass: drowssap
  timeout: 20
  user: postgre_user
website:
	domain: example.com

通过射线发射器插件启动 AWS

通过 joblib 插件进行本地并行执行

描述

Larq 是一个开源 Python 包的生态系统,用于构建、训练和部署二进制神经网络(BNNs)。bnn 是深度学习模型,其中激活和权重不使用 32、16 或 8 位编码,而是仅使用 1 位。这可以大大加快推理时间和降低能耗,使 BNNs 非常适合移动和边缘设备。


开源 Larq 生态系统由三个主要组件组成:

Larq 是一个强大而易用的库,用于构建和训练极度量化的神经网络。它提供了一致而简单的 API,可扩展并与更大的 TensorFlow Keras 生态系统完全兼容。这允许在您当前的代码库中逐步采用,并在开发模型时实现快速迭代。虽然 Larq 主要关注于 BNNs,但它也可以用于训练具有任意精确权重和激活的网络

Larq Zoo 提供了 bnn 的参考实现,可与预训练的权重一起使用。它的目的是鼓励可复制的研究,使研究人员能够在最新的 BNN 文献的基础上进行研究,而不必花费大量的时间复制现有的论文。

Larq 计算引擎是一个用于部署 bnn 的推理库。它构建在 TensorFlow Lite 之上,包括一个基于 MLIR 的转换器,用于将 Larq 模型转换为与 TF Lite 运行时兼容的 FlatBuffer 文件。它目前支持基于 ARM64 的移动平台,如 Android 手机和 Raspberry Pi,并通过使用手动优化的二进制卷积内核和针对 BNN 模型的网络级优化,在设备上的推理速度方面实现了一流的性能。

我们不断创造更好、更快的模型,并将 Larq 生态系统扩展到新的硬件平台和深度学习应用。例如,我们目前正在致力于 8 位量化的端到端集成,因此您可以使用 Larq 来训练和部署混合二进制和 8 位网络。

网站|GitHub larq/larq|GitHub larq/zoo|GitHub larq/compute-engine|教程 | 博客 | 推特

  1. 麦克内尔
  2. 对数线性时间内的近似核展开
  3. 描述

第一个开源的 C++库,通过随机特性提供了内核近似值,还提供了一个成熟的 DL 框架。

McKernel 提供了四种不同的可能用途:


独立照明快速开源 Hadamard。用于:压缩、加密或量子计算。

极快的内核方法。用在:SVM 在 DL 上有用的地方。例如在机器人和医疗保健的 ML 的一些应用中。其他令人兴奋的新兴用途包括联合学习和通信中的信道估计。

DL 方法和内核扩展的集成。培育具有更好的人为/数学先验的新 DL 架构。

DL 研究框架。解决 ML 中的多重开放问题。

控制整个计算的等式如下:

在这里,我们开创了一种通过使用随机特征来解释 DL 和内核方法(arxiv.org/pdf/1702.08159)的形式主义。理论背景依赖于四个巨人:高斯、维纳、傅立叶和卡尔曼。构建模块由拉希米和雷希特(NIPS 2007)和勒等人(2013)建立。

  1. 记住目标用户

  2. McKernel 的主要受众是机器人、医疗保健、信号处理和通信领域的 ML 研究人员和从业者,他们正在寻找高效快速的 C++实现。在这种情况下,大多数 DL 库不能满足这种特定的需求,因为它们主要依赖于 Python 中的高级实现。以及更广泛的 ML 和 DL 社区中试图通过利用内核方法提出更好的 NN 架构的人们。

  3. 下面是一个非常简单的实践示例,可以让库立即运行起来:

  4. 下一步是什么?

端到端的训练,自我监督学习,元学习,与进化策略的集成,NAS 大大减少搜索空间,…

GitHub | 完整呈现

SCCH 培训引擎

自动化 DL 开发例程

描述

什么事?

一个典型的深度学习流水线开发是相当标准的:数据预处理、任务设计/实现、训练、评估。然而,从一个项目到另一个项目的开发需要开发人员在开发过程的每个阶段都参与进来。这导致了相同动作的重复,代码复制粘贴,最终导致了错误。

SCCH 培训引擎的目标是两个最流行的框架 PyTorch 和 TensorFlow 的 DL 开发例程的统一和自动化。单个条目允许最小化开发时间,并防止开发错误。


为谁?

SCCH 培训引擎的灵活架构有两个用户交互级别:

基本。在这个级别,用户需要在配置文件中提供他的数据并定义训练参数。此后,包括数据处理、训练和验证在内的所有过程都将自动完成。因此,将提供一个已定义框架中的训练有素的网络。

高级。由于发动机的模块化概念,用户可以根据自己的需要,通过部署自己的模型、损失和精度功能来修改发动机。这种模块化允许在不干扰核心管道的情况下添加额外的特征。

它能做什么?

目前的特点是:

在 TensorFlow 和 PyTorch 上工作

来自不同格式的数据解析的标准化管道

标准化的培训和验证渠道

支持分类、分割和检测任务

支持交叉验证

开发中的功能:

训练参数的超参数搜索

  • 给定检查点的负重和训练
  • GAN 架构支持
  • 它是如何工作的?
  • 要查看 SCCH 培训引擎的工作情况,您需要执行 2 个步骤:
  • 只需复制存储库并使用pip install requirements.txt安装需求

运行python main.py查看在 LeNet-5 上处理和训练的 MNIST 玩具示例

  • 关于如何创建配置文件以及如何使用高级特性的所有信息都可以在我们的 GitHub 页面上找到。
  • 主要功能稳定发布:2020 年 5 月底
  • GitHub | 网站

记号标记符

语言:Rust with Python API

  1. 描述
  2. huggingface/tokenizers 提供最先进的 tokenizers,重点关注性能和多功能性。这使得培训新的标记器和使用它们变得轻而易举。无论你是 NLP 研究者还是 NLP 实践者,tokenizers 都能帮到你。

主要特点:

极快:标记化不应该成为 NLP 管道中的瓶颈,也不应该对数据集进行预处理。由于 Rust 中的本机实现,标记千兆字节的文本只需几秒钟。

偏移/对准:提供对准跟踪,即使是复杂的标准化处理。这使得像 NER 或问答这样的任务的文本提取变得容易。


预处理:在输入你的语言模型之前,处理任何需要的预处理(截断、填充、添加特殊标记等等)。

简单训练:在新的语料库上训练任何分词器。例如,为 BERT 培训一门新语言的标记器从未如此简单。

多语言:多语言绑定。现在,您可以开始在 Python、Node.js 或 Rust 中使用它。更多即将推出!

示例:

很快:

任何标记化器的单文件序列化和单行加载。

首先:

感谢 Anthony,J. de Curtó i Díaz,Luca,Lukas,Mandar,Natalia,Nicholas 和 Omry 为这篇文章付出的努力!

  • 没有你,它永远不会被创造出来。
  • 在这篇文章中,工具制造商只是强调了现在可能的前沿。考虑的主题范围从配置管理思想、有效的文本标记到知识图嵌入。我们甚至接触了二值化的神经网络。

我们强烈建议给他们一个尝试,因为他们可以让你的研究更容易和(可能)更快——无论是在学术还是工业环境中。

最后,我们愿意听取更多关于深度学习开源生态系统的信息。如果您有一些问题、想法或工具想带到舞台上,请联系 Kamil。你可以在下面找到他的联系方式。

本文由 ICLR 社交活动协办方协调:


PS:

我们还针对 ICLR 2020 期间讨论的主要话题(来源)发布了一系列帖子,即:

深度学习(此处)

强化学习(此处)

生成型(此处)

自然语言处理/理解(此处)

找点时间看看它们吧!

This post was coordinated by the ICLR social event co-hosts:


PS:

We also built a series of posts focused on the main topics (source) discussed during ICLR 2020, that is:

  • Deep learning (here)
  • Reinforcement learning (here)
  • Generative models (here)
  • Natural Language Processing/Understanding (here)

Find some time to take a look at them!

ICLR 2020 大会最佳深度学习论文

原文:https://web.archive.org/web/https://neptune.ai/blog/iclr-2020-deep-learning

上周,我很高兴参加了学习表征国际会议( ICLR ),这是一个致力于深度学习各个方面的研究的活动。最初,会议本应在埃塞俄比亚的亚的斯亚贝巴举行,然而,由于新型冠状病毒疫情,会议虚拟化了。我敢肯定,对于组织者来说,将活动搬到网上是一个挑战,但我认为效果非常令人满意,正如你可以在这里看到的!

超过 1300 名发言人和 5600 名与会者证明,虚拟形式更容易为公众所接受,但同时,会议仍保持互动和参与。从众多有趣的介绍中,我决定选择 16 个,有影响力,发人深省。以下是来自 ICLR 的最佳深度学习论文。

最佳深度学习论文

1。关于神经常微分方程的鲁棒性

深入研究神经常微分方程或简称 NeuralODE 的鲁棒性。将其作为构建更强大网络的基础。

论文

The architecture of an ODENet. The neural ODE block serves as a dimension-preserving nonlinear mapping.


2。为什么梯度裁剪加速训练:适应性的理论证明

梯度裁剪可证明地加速了非光滑非凸函数的梯度下降。

(TL;博士,来自OpenReview.net)

论文 | 代码

*Gradient norm vs local gradient Lipschitz constant on a log-scale along the training trajectory for AWD-LSTM (Merity et al., 2018) on PTB dataset. The colorbar indicates the number of iterations during training. *

第一作者:张京兆

LinkedIn | 网站


3。用于监督表示学习的目标嵌入自动编码器

用于监督预测的新的通用目标嵌入自动编码器框架。作者给出了理论和经验的考虑。

论文

(a) Feature-embedding and (b) Target-embedding autoencoders. Solid lines correspond to the (primary) prediction task; dashed lines to the (auxiliary) reconstruction task. Shared components are involved in both.


4。理解和加强差异化架构搜索

我们通过查看有效性损失的 Hessian 的特征值来研究 DARTS(可区分架构搜索)的失效模式,并基于我们的分析提出稳健性。

(TL;博士,来自OpenReview.net)

论文 | 代码

The poor cells standard DARTS finds on spaces S1-S4. For all spaces, DARTS chooses mostly parameter-less operations (skip connection) or even the harmful Noise operation. Shown are the normal cells on CIFAR-10.


5。比较神经网络修剪中的倒回和微调

在修剪神经网络时,不是在修剪后进行微调,而是将权重或学习率计划倒回它们在训练时的值,并从那里重新训练,以实现更高的精度。

(TL;博士,来自OpenReview.net)

论文 | 代码

The best achievable accuracy across retraining times by one-shot pruning.


6。神经运算单元

神经网络虽然能够逼近复杂的函数,但在精确的算术运算方面相当差。这项任务对深度学习研究人员来说是一个长期的挑战。这里,提出了新颖的神经加法单元(NAU)和神经乘法单元(NMU),能够执行精确的加法/减法(NAU)和向量的乘法子集(MNU)。著名的第一作者是一名独立的研究员🙂

论文 | 代码

Visualization of the NMU, where the weights (W[i,j] ) controls gating between 1 (identity) or x[i], each intermediate result is then multiplied explicitly to form z[j].


7 .。深度神经网络优化轨迹上的平衡点

在深度神经网络训练的早期阶段,存在一个“平衡点”,它决定了整个优化轨迹的性质。

(TL;博士,来自OpenReview.net)

论文

Visualization of the early part of the training trajectories on CIFAR-10 (before reaching 65% training accuracy) of a simple CNN model optimized using SGD with learning rates η = 0.01 (red) and η = 0.001 (blue). Each model on the training trajectory, shown as a point, is represented by its test predictions embedded into a two-dimensional space using UMAP. The background color indicates the spectral norm of the covariance of gradients K (λ¹[K], left) and the training accuracy (right). For lower η, after reaching what we call the break-even point, the trajectory is steered towards a region characterized by larger λ¹[K] (left) for the same training accuracy (right).


8。Hoppity:学习图形转换来检测和修复程序中的错误

一种基于学习的方法,用于检测和修复 Javascript 中的错误。

(TL;博士,来自OpenReview.net)

论文

Example programs that illustrate limitations of existing approaches inculding both rulebased static analyzers and neural-based bug predictors.


9。通过代理选择:深度学习的高效数据选择

我们可以通过使用小得多的代理模型来执行数据选择,从而显著提高深度学习中数据选择的计算效率。

(TL;博士,来自OpenReview.net)

论文 | 代码

SVP applied to active learning (left) and core-set selection (right). In active learning, we followed the same iterative procedure of training and selecting points to label as traditional approaches but replaced the target model with a cheaper-to-compute proxy model. For core-set selection, we learned a feature representation over the data using a proxy model and used it to select points to train a larger, more accurate model. In both cases, we found the proxy and target model have high rank-order correlation, leading to similar selections and downstream results.


10。比特下降:重新审视神经网络的量子化

使用旨在更好的域内重构的结构化量化技术来压缩卷积神经网络。

(TL;博士,来自OpenReview.net)

论文 | 代码

Illustration of our method. We approximate a binary classifier ϕ that labels images as dogs or cats by quantizing its weights. Standard method: quantizing ϕ with the standard objective function (1) promotes a classifier ϕb[standard] that tries to approximate ϕ over the entire input space and can thus perform badly for in-domain inputs. Our method: quantizing ϕ with our objective function (2) promotes a classifier ϕb[activations] that performs well for in-domain inputs. Images lying in the hatched area of the input space are correctly classified by ϕ[activations] but incorrectly by ϕ[standard].


11。用于在初始化时修剪神经网络的信号传播观点

我们在初始化时形式化地描述了有效剪枝的初始化条件,并分析了由此产生的剪枝网络的信号传播特性,这导致了一种增强它们的可训练性和剪枝结果的方法。

(TL;博士,来自OpenReview.net)

论文

(left) layerwise sparsity patterns c ∈ {0, 1} ^(100×100) obtained as a result of pruning for the sparsity level κ¯ = {10, .., 90}%. Here, black(0)/white(1) pixels refer to pruned/retained parameters; (right) connection sensitivities (CS) measured for the parameters in each layer. All networks are initialized with γ = 1.0. Unlike the linear case, the sparsity pattern for the tanh network is nonuniform over different layers. When pruning for a high sparsity level (e.g., κ¯ = 90%), this becomes critical and leads to poor learning capability as there are only a few parameters left in later layers. This is explained by the connection sensitivity plot which shows that for the nonlinear network parameters in later layers have saturating, lower connection sensitivities than those in earlier layers.


12。深度半监督异常检测

我们介绍了深度 SAD,一种用于一般半监督异常检测的深度方法,它特别利用了标记异常。

(TL;博士,来自OpenReview.net)

论文 | 代码

The need for semi-supervised anomaly detection: The training data (shown in (a)) consists of (mostly normal) unlabeled data (gray) as well as a few labeled normal samples (blue) and labeled anomalies (orange). Figures (b)–(f) show the decision boundaries of the various learning paradigms at testing time along with novel anomalies that occur (bottom left in each plot). Our semi-supervised AD approach takes advantage of all training data: unlabeled samples, labeled normal samples, as well as labeled anomalies. This strikes a balance between one-class learning and classification.


13。使用网格单元的空间特征分布的多尺度表示学习

我们提出了一个名为 Space2vec 的表征学习模型来编码地点的绝对位置和空间关系。

(TL;博士,来自OpenReview.net)

论文 | 代码

The challenge of joint modeling distributions with very different characteristics. (a)(b) The POI locations (red dots) in Las Vegas and Space2Vec predicted conditional likelihood of Women’s Clothing (with a clustered distribution) and Education (with an even distribution). The dark area in (b) indicates that the downtown area has more POIs of other types than education. (c) Ripley’s K curves of POI types for which Space2Vec has the largest and smallest improvement over wrap (Mac Aodha et al., 2019). Each curve represents the number of POIs of a certain type inside certain radios centered at every POI of that type; (d) Ripley’s K curves renormalized by POI densities and shown in log-scale. To efficiently achieve multi-scale representation Space2Vec concatenates the grid cell encoding of 64 scales (with wave lengths ranging from 50 meters to 40k meters) as the first layer of a deep model, and trains with POI data in an unsupervised fashion.


14。匹配平均的联合学习

具有逐层匹配的通信高效联邦学习。

(TL;博士,来自OpenReview.net)

论文 | 代码

*Comparison among various federated learning methods with limited number of communications on LeNet trained on MNIST; VGG-9 trained on CIFAR-10 dataset; LSTM trained on Shakespeare dataset over: (a) homogeneous data partition (b) heterogeneous data partition. *


15。变色龙:加速深度神经网络编译的自适应代码优化

深度神经网络优化编译的强化学习和自适应采样。

(TL;博士,来自OpenReview.net)

论文

Overview of our model compilation workflow, and highlighted is the scope of this work.


16。网络去卷积

为了更好地训练卷积网络,我们提出了一种类似于动物视觉系统的网络去卷积方法。

(TL;博士,来自)

*论文 | 代码

Performing convolution on this real world image using a correlative filter, such as a Gaussian kernel, adds correlations to the resulting image, which makes object recognition more difficult. The process of removing this blur is called deconvolution. What if, however, what we saw as the real world image was itself the result of some unknown correlative filter, which has made recognition more difficult? Our proposed network deconvolution operation can decorrelate underlying image features which allows neural networks to perform better.


摘要

ICLR 出版物的深度和广度相当鼓舞人心。在这里,我只是展示了专注于“深度学习”主题的冰山一角。然而,这一分析表明,很少有受欢迎的地区,特别是:

  1. 深度学习(在这篇文章中讨论)
  2. 强化学习(此处)
  3. 生成模型(此处)
  4. 自然语言处理/理解(此处

为了对 ICLR 大学的顶级论文有一个更完整的概述,我们正在建立一系列的帖子,每个帖子都专注于上面提到的一个主题。你可能想要查看以获得更完整的概述。

快乐阅读!

卡米尔·卡什马雷克

人工智能研究倡导者,在 MLOps 领域工作。总是在寻找新的 ML 工具、过程自动化技巧和有趣的 ML 论文。偶尔会有博客作者和会议发言人。


阅读下一篇

如何组织深度学习项目——最佳实践范例

13 分钟阅读|作者 Nilesh Barla |年 5 月 31 日更新

一个成功的深度学习项目,你需要很多迭代,很多时间,很多努力。为了让这个过程不那么痛苦,你应该尽量利用你的资源。

一个好的循序渐进的工作流程将帮助你做到这一点。有了它,你的项目变得高效、可复制、可理解

在本文中,您将看到如何构建深度学习项目的工作——从开始到部署,监控部署的模型,以及中间的一切。

在这个过程中,我们将使用 Neptune 来运行、监控和分析您的实验。Neptune 是提高 ML 项目生产率的一个很酷的工具。

在本文中,您将了解到:

  1. 关于项目的生命周期。
  2. 定义项目目标的重要性。
  3. 根据项目需求收集数据。
  4. 模型训练和结果探索,包括:
    1. 为更好的结果建立基线。
    2. 采用现有的开源最新模型研究论文和代码库中的技术和方法。
    3. 实验跟踪和管理
  5. 避免欠拟合和过拟合的模型优化技术,例如:
    1. 控制超参数
    2. 规范化
    3. 修剪
  6. 在部署之前测试和评估您的项目。
  7. 模型部署
  8. 项目维护

Continue reading ->


ICLR 2020 会议最佳生成模型论文

原文:https://web.archive.org/web/https://neptune.ai/blog/iclr-2020-generative-models

学习代表国际会议于上周在 ICLR 召开,我很高兴参加了这次会议。ICLR 是一个致力于研究表征学习各个方面的事件,俗称深度学习。由于疫情冠状病毒,会议无法按计划在亚的斯亚贝巴举行,而是通过虚拟方式进行。这并没有改变活动的良好氛围,恰恰相反——它引人入胜,互动性强,吸引了比去年更多的观众。如果你对组织者如何看待这次不同寻常的在线会议安排感兴趣,你可以在这里阅读。

作为一名与会者,我从 1300 多名演讲者的演讲中受到启发,并决定创建一系列博客帖子,总结四个主要领域的最佳论文。可以在这里用深度学习论文 赶上第一个帖子,在这里用强化学习论文 赶上第二个帖子。

这让我们看到了该系列的第三篇文章——这里是来自 ICLR 的 7 篇最佳生成模型论文。

最佳生成模型论文

1。私有、分散数据集上有效 ML 的生成模型

生成模型+联合学习+差分隐私为数据科学家提供了一种分析私有、分散数据(例如,在移动设备上)的方法,在这些数据中禁止直接检查。

(TL;博士,来自)

*论文 | 代码

*Percentage of samples generated from the word-LM that are OOV by position in the sentence, with and without bug. *


2。抵御对图像分类的物理可实现攻击

抵御对图像分类的物理可实现攻击。

(TL;博士,来自)

*论文 | 代码

*(a) An example of the eyeglass frame attack. Left: original face input image. Middle: modified input image (adversarial eyeglasses superimposed on the face). Right: an image of the predicted individual with the adversarial input in the middle image. (b) An example of the stop sign attack. Left: original stop sign input image. Middle: adversarial mask. Right: stop sign image with adversarial stickers, classified as a speed limit sign. *


3。跳过连接很重要:论结果网生成的对立范例的可迁移性

我们发现了类 ResNet 神经网络中跳过连接的安全弱点

(TL;博士,来自)

*论文

Left: Illustration of the last 3 skip connections (green lines) and residual modules (black boxes) of a ImageNet-trained ResNet-18. Right: The success rate (in the form of “white-box/blackbox”) of adversarial attacks crafted using gradients flowing through either a skip connection (going upwards) or a residual module (going leftwards) at each junction point (circle). Three example backpropagation paths are highlighted in different colors, with the green path skipping over the last two residual modules having the best attack success rate while the red path through all 3 residual modules having the worst attack success rate. The attacks are crafted by BIM on 5000 ImageNet validation images under maximum L∞ perturbation  = 16 (pixel values are in [0, 255]). The black-box success rate is tested against a VGG19 target model.


4。k 赢家通吃增强对抗性防御

我们提出了一个简单的改变现有的神经网络结构,以更好地抵御基于梯度的对抗性攻击,使用 k 赢家通吃激活函数。

(TL;博士,来自)

*论文 | 代码

1D illustration. Fit a 1D function (green dotted curve) using a k-WTA model provided with a set of points (red). The resulting model is piecewise continuous (blue curve), and the discontinuities can be dense.

第一作者:常晓

网站


5。真实还是不真实,这是个问题

生成对抗网络已被广泛应用于各种话题。在普通设置中,鉴别器输出标量值。这里,提出了新的公式,其中鉴别器输出离散分布而不是标量。

论文 | 代码

*The perception of realness depends on various aspects. (a) Human-perceived flawless. (b) Potentially reduced realness due to: inharmonious facial structure/components, unnatural background, abnormal style combination and texture distortion. *

第一作者:袁波·李湘

网站


6。对抗性训练和可证明的防御:弥合差距

我们提出了一种对抗训练和可证明防御的新组合,它产生了一个在 CIFAR-10 上具有最先进的准确性和经认证的鲁棒性的模型。

(TL;博士,来自)

*论文

An iteration of convex layerwise adversarial training. Latent adversarial example x^’[1] is found in the convex region C1 and propagated through the rest of the layers in a forward pass, shown with the blue line. During backward pass, gradients are propagated through the same layers, shown with the red line. Note that the first convolutional layer does not receive any gradients.


7 .。对抗生成性攻击的最佳策略

在 GANs 社区,防御生成性攻击是一个越来越重要的话题。在这里,作者正式阐述了一个问题,并根据样本复杂性和攻击者可用的时间预算来检查它。问题涉及出于恶意目的伪造/修改数据。

论文 | 代码

Game value (expected authentication accuracy) for the Gaussian case. (a) A comparison between empirical and theoretical game value for different d values (m “ 1, k “ 10). Solid lines describe the theoretical game values whereas the ˚ markers describe the empirical accuracy when learning with the GIM model. (b) Theoretical game value as a function of δ, ρ (see Corollary 4.3) for d “ 100. (c) Empirical accuracy of an optimal authenticator against two attacks: the theoretically optimal attack G ˚ from Theorem 4.2 and a maximum likelihood (ML) attack (See Sec. F.4) for the Gaussian case. It can be seen that the ML attack is inferior in that it results in better accuracy for the authenticator, as predicted by our theoretical results.


总结

ICLR 出版物的深度和广度相当鼓舞人心。这篇文章关注的是“生成模型”这个话题,这只是会议期间讨论的话题之一。正如您在这篇分析中所看到的,ICLR 涵盖了以下主要问题:

  1. 深度学习(此处)
  2. 强化学习(此处)
  3. 生成模型(在本帖中讨论)
  4. 自然语言处理/理解(此处

为了对 ICLR 大学的顶级论文有一个更完整的概述,我们正在建立一系列的帖子,每个帖子都专注于上面提到的一个主题。这是第三篇文章,所以你可能想查看前几篇以获得更完整的概述。

请随意与我们分享其他关于生成模型的有趣论文。我们很乐意扩展我们的列表!*****

ICLR 2020 会议最佳 NLP/NLU 论文

原文:https://web.archive.org/web/https://neptune.ai/blog/iclr-2020-nlp-nlu

学习代表国际会议于上周在 ICLR 召开,我很高兴参加了这次会议。ICLR 是一个致力于研究表征学习各个方面的事件,俗称深度学习。今年的活动有点不同,因为冠状病毒疫情使它虚拟化了。然而,在线形式并没有改变活动的良好氛围。它引人入胜,互动性强,吸引了 5600 名与会者(是去年的两倍)。如果你对组织者如何看待这次不同寻常的在线会议安排感兴趣,你可以在这里阅读。

超过 1300 名演讲者发表了许多有趣的论文,所以我决定创建一系列博客文章,总结他们在四个主要领域的最佳表现。你可以用最好的深度学习论文 在这里赶上第一个帖子,用强化学习论文 在这里赶上第二个帖子用生成模型论文 在这里

这是该系列的最后一篇文章,在这篇文章中,我想分享来自 ICLR 的 10 篇最佳自然语言处理/理解文章。

最佳自然语言处理/理解论文

1。ALBERT:一个用于语言表达自我监督学习的 Lite BERT】

一种新的预训练方法,在胶水、种族和小队基准上建立了新的最先进的结果,同时与 BERT-large 相比具有更少的参数。

(TL;博士,来自)

*论文 | 代码

The L2 distances and cosine similarity (in terms of degree) of the input and output embedding of each layer for BERT-large and ALBERT-large.


2。语言表征学习的互信息最大化视角

单词表示是自然语言处理中的一项常见任务。在这里,作者制定了新的框架,将经典的单词嵌入技术(如 Skip-gram)与基于上下文嵌入的更现代的方法(BERT,XLNet)相结合。

论文

The left plot shows F[1] scores of BERT-NCE and INFOWORD as we increase the percentage of training examples on SQuAD (dev). The right plot shows F[1] scores of INFOWORD on SQuAD (dev) as a function of λ[DIM].


3。莫格里菲耶 LSTM

具有最先进的语言建模结果的 LSTM 扩展。

(TL;博士,来自)

*论文

Mogrifier with 5 rounds of updates. The previous state h⁰ = h[prev] is transformed linearly (dashed arrows), fed through a sigmoid and gates x ^(−1) = x in an elementwise manner producing x¹ . Conversely, the linearly transformed x¹ gates h 0 and produces h² . After a number of repetitions of this mutual gating cycle, the last values of h^∗ and x^∗ sequences are fed to an LSTM cell. The prev subscript of h is omitted to reduce clutter.


4。具有对抗网络的高保真语音合成

我们介绍了 GAN-TTS,一个用于文本到语音转换的生成式对抗网络,其平均意见得分(MOS)为 4.2。

(TL;博士,来自)

*论文 | 代码

* Residual blocks used in the model. Convolutional layers have the same number of input and output channels and no dilation unless stated otherwise. h – hidden layer representation, l – linguistic features, z – noise vector, m – channel multiplier, m = 2 for downsampling blocks (i.e. if their downsample factor is greater than 1) and m = 1 otherwise, M- G’s input channels, M = 2N in blocks 3, 6, 7, and M = N otherwise; size refers to kernel size. *


5。重整器:高效的变压器

具有位置敏感散列和可逆层的高效转换器。

(TL;博士,来自)

*论文 | 代码

An angular locality sensitive hash uses random rotations of spherically projected points to establish buckets by an argmax over signed axes projections. In this highly simplified 2D depiction, two points x and y are unlikely to share the same hash buckets (above) for the three different angular hashes unless their spherical projections are close to one another (below).

主要作者:


6。定义:用于神经序列建模的深度分解输入令牌嵌入

DeFINE 使用具有新的跳过连接的深度、分层、稀疏网络来高效地学习更好的单词嵌入。

(TL;博士,来自)

*论文

With DeFINE, Transformer-XL learns input (embedding) and output (classification) representations in low n-dimensional space rather than high m-dimensional space, thus reducing parameters significantly while having a minimal impact on the performance.


7。深度自适应变压器

动态调整每个输入的计算量的序列模型。

(TL;博士,来自)

*论文

Training regimes for decoder networks able to emit outputs at any layer. Aligned training optimizes all output classifiers C[n] simultaneously assuming all previous hidden states for the current layer are available. Mixed training samples M paths of random exits at which the model is assumed to have exited; missing previous hidden states are copied from below.


8。关于变压器的可识别性

我们研究了基于自我注意的 BERT 模型中上下文嵌入中注意分布和标记的可识别性和可解释性。

(TL;博士,来自)

*论文

(a) Each point represents the Pearson correlation coefficient of effective attention and raw attention as a function of token length. (b) Raw attention vs. (c) effective attention, where each point represents the average (effective) attention of a given head to a token type.


9。镜像生成神经机器翻译

被称为神经机器翻译模型(NMT)的翻译方法依赖于作为语言对构建的大型语料库的可用性。这里,提出了一种使用生成神经机器翻译进行双向翻译的新方法。

论文

*The graphical model of MGNMT. *


10。FreeLB:增强的自然语言理解对抗训练

在这里,作者提出了一种新的算法,称为 FreeLB,它提出了一种新的语言模型的对抗性训练方法。

论文 | 代码


总结

ICLR 出版物的深度和广度相当鼓舞人心。这篇文章主要关注“自然语言处理”这个话题,这是会议期间讨论的主要领域之一。根据本分析,这些区域包括:

  1. 深度学习(此处)
  2. 强化学习(此处)
  3. 生成模型(此处)
  4. 自然语言处理/理解(包含在这篇文章中)

为了对 ICLR 大学的顶级论文有一个更完整的概述,我们建立了一系列的帖子,每个帖子都专注于上面提到的一个主题。这是最后一个,所以你可能想要检查其他的以获得更完整的概述。

我们很乐意扩展我们的列表,所以请随意与我们分享其他有趣的 NLP/NLU 论文。

同时,祝阅读愉快!

卡密耳鸭

人工智能研究倡导者,在 MLOps 领域工作。总是在寻找新的 ML 工具、过程自动化技巧和有趣的 ML 论文。偶尔会有博客作者和会议发言人。


阅读下一篇

自然语言处理的探索性数据分析:Python 工具完全指南

11 分钟阅读|作者 Shahul ES |年 7 月 14 日更新

探索性数据分析是任何机器学习工作流中最重要的部分之一,自然语言处理也不例外。但是你应该选择哪些工具来高效地探索和可视化文本数据呢?

在这篇文章中,我们将讨论和实现几乎所有的主要技术,你可以用它们来理解你的文本数据,并给你一个完成工作的 Python 工具的完整之旅。

开始之前:数据集和依赖项

在本文中,我们将使用来自 Kaggle 的百万新闻标题数据集。如果您想一步一步地进行分析,您可能需要安装以下库:

pip install \
   pandas matplotlib numpy \
   nltk seaborn sklearn gensim pyldavis \
   wordcloud textblob spacy textstat

现在,我们可以看看数据。

news= pd.read_csv('data/abcnews-date-text.csv',nrows=10000)
news.head(3)

jupyter output

数据集只包含两列,发布日期和新闻标题。

为了简单起见,我将探索这个数据集中的前 10000 行。因为标题是按发布日期排序的,所以实际上从 2003 年 2 月 19 日到 2003 年 4 月 7 日两个月。

好了,我想我们已经准备好开始我们的数据探索了!

Continue reading ->


ICLR 2020 会议最佳强化学习论文

原文:https://web.archive.org/web/https://neptune.ai/blog/iclr-2020-reinforcement-learning

上周,我很高兴参加了学习表征国际会议( ICLR ),这是一个致力于表征学习各个方面的研究的活动,通常被称为深度学习。由于冠状病毒疫情,会议变成了虚拟的,由于组织者的巨大努力,这次活动吸引了比去年更多的观众。他们的目标是让会议更具包容性和互动性,在我看来,作为一名与会者,事实的确如此!

受到 1300 多名演讲者的演讲的启发,我决定创建一系列博客帖子,总结四个主要领域的最佳论文。你可以在这里赶上关于最佳深度学习论文的第一篇帖子,今天是来自 ICLR 的 15 篇最佳强化学习论文的时间。

最佳强化学习论文

1。永不放弃:学习定向探索策略

我们提出一个强化学习代理,通过学习一系列定向探索策略来解决困难探索游戏。

(TL;博士,来自)

*论文

(left) Training architecture for the embedding network (right) NGU’s reward generator.

主要作者:


2。节目引导代理

我们提出了一个模块化框架,它可以完成程序指定的任务,并实现对更复杂任务的零镜头泛化。

(TL;博士,来自)

*论文

An illustration of the proposed problem. We are interested in learning to fulfill tasks specified by written programs. A program consists of control flows (e.g. if, while), branching conditions (e.g. is_there[River]), and subtasks (e.g. mine(Wood)).


3。雅达利的基于模型的强化学习

我们使用视频预测模型、基于模型的强化学习算法和每款游戏 2 小时的游戏性来训练 26 款 Atari 游戏的代理。

(TL;博士,来自)

*论文 | 代码

Main loop of SimPLe. 1) the agent starts interacting with the real environment following the latest policy (initialized to random). 2) the collected observations will be used to train (update) the current world model. 3) the agent updates the policy by acting inside the world model. The new policy will be evaluated to measure the performance of the agent as well as collecting more data (back to 1). Note that world model training is self-supervised for the observed states and supervised for the reward.

主要作者:


4。发现和可视化深度强化学习代理的弱点

我们生成经过训练的 RL 算法的临界状态,以可视化潜在的弱点。

(TL;博士,来自)

*论文

*Qualitative Results: Visualization of different target functions (Sec. 2.3). T^+ generates high reward and T^− low reward states; T^± generates states in which one action is highly beneficial and another is bad. *


5。没有记忆的元学习

我们对元学习中的记忆问题进行了识别和形式化,并采用新颖的元正则化方法解决了这一问题,极大地拓展了元学习的适用和有效领域。

(TL;博士,来自)

*论文 | 代码

Left: An example of non-mutually-exclusive pose prediction tasks, which may lead to the memorization problem. The training tasks are non-mutually-exclusive because the test data label (right) can be inferred accurately without using task training data (left) in the training tasks, by memorizing the canonical orientation of the meta-training objects. For a new object and canonical orientation (bottom), the task cannot be solved without using task training data (bottom left) to infer the canonical orientation. Right: Graphical model for meta-learning. Observed variables are shaded. Without either one of the dashed arrows, Yˆ ∗ is conditionally independent of D given θ and X∗, which we refer to as complete memorization (Definition 1).

主要作者


6。一个好的表示对于样本高效强化学习是否足够?

具有函数逼近的基于值和基于策略的强化学习的指数下界。

(TL;博士,来自)

*论文

An example with H = 3. For this example, we have r(s[5]) = 1 and r(s) = 0 for all other states s. The unique state s[5] which satisfies r(s) = 1 is marked as dash in the figure. The induced Q∗ function is marked on the edges.


7 .。真实世界机器人强化学习的要素

系统在现实世界中学习机器人任务,具有强化学习功能,无需仪器。

(TL;博士,来自)

*论文

Illustration of our proposed instrumentation-free system requiring minimal human engineering. Human intervention is only required in the goal collection phase (1). The robot is left to train unattended (2) during the learning phase and can be evaluated from arbitrary initial states at the end of training (3). We show sample goal and intermediate images from the training process of a real hardware system


8。使用学习目标提高元强化学习的泛化能力

我们介绍了一种新的元强化学习算法 MetaGenRL。与以前的工作不同,MetaGenRL 可以推广到与元训练完全不同的新环境。

(TL;博士,来自)

*论文

*A schematic of MetaGenRL. On the left a population of agents (i ∈ 1, . . . , N), where each member consist of a critic Q ^((i)) [θ] and a policy π ^((i)) [φ] that interact with a particular environment e^((i)) and store collected data in a corresponding replay buffer B^((i)) . On the right a meta-learned neural objective function L[α] that is shared across the population. Learning (dotted arrows) proceeds as follows: Each policy is updated by differentiating L[α], while the critic is updated using the usual TD-error (not shown). L[α] is meta-learned by computing second-order gradients that can be obtained by differentiating through the critic. *


9。强化学习和概率推理的意义

将“RL 作为推理”的流行算法忽略了不确定性和探索的作用。我们强调了这些问题的重要性,并为 RL 和推理提出了一个协调一致的框架来优雅地处理它们。

(TL;博士,来自)

*论文

*Regret scaling on Problem 1. Soft Q-learning does not scale gracefully with N. *


10。种子 RL:具有加速中央推理的可扩展且高效的深度 RL

SEED RL,一个可扩展的高效深度强化学习代理,具有加速的中心推理。最先进的结果,降低成本,每秒可以处理数百万帧。

(TL;博士,来自)

*论文 | 代码

*Overview of architectures *


11.网络化系统控制的多智能体强化学习

针对网络化多智能体控制问题,提出了一种新的公式和新的通信协议。

(TL;博士,来自)

*论文 | 代码

Forward propagations of NeurComm enabled MARL, illustrated in a queueing system. (a) Single-step forward propagations inside agent i. Different colored boxes and arrows show different outputs and functions, respectively. Solid and dashed arrows indicate actor and critic propagations, respectively. (b) Multi-step forward propagations for updating
the belief of agent i.

第一作者:褚天舒

网站


12。多智能体学习的通用训练方法

本文研究并扩展了政策空间响应预言(PSRO)。这是一种基于群体的学习方法,使用博弈论原理。作者扩展了该方法,使其适用于多人游戏,同时在多种设置下提供收敛保证。

论文

Overview of PSRO(M, O) algorithm phases.


13。深度研发中的实施事项:PPO 和 TRPO 案例研究

有时,实现细节可能会在您的研究中发挥作用。这里,评估了两种策略搜索算法:邻近策略优化(PPO)和信任区域策略优化(TRPO)。“代码级优化”,从学习动态来看应该是可以忽略的。令人惊讶的是,h 优化对代理的行为有很大的影响。

论文 | 代码

*An ablation study on the first four optimizations described in Section 3 (value clipping, reward scaling, network initialization, and learning rate annealing). For each of the 2⁴ possible configurations of optimizations, we train a Humanoid-v2 (top) and Walker2d-v2 (bottom) agent using PPO with five random seeds and a grid of learning rates, and choose the learning rate which gives the best average reward (averaged over the random seeds). We then consider all rewards from the “best learning rate” runs (a total of 5 × 2⁴ agents), and plot histograms in which agents are partitioned based on whether each optimization is on or off. Our results show that reward normalization, Adam annealing, and network initialization each significantly impact the rewards landscape with respect to hyperparameters, and were necessary for attaining the highest PPO reward within the tested hyperparameter grid. *

主要作者:


14。深入研究政策梯度

这是对深度策略梯度算法行为的深入实证研究。作者分析了基于梯度估计,价值预测和优化景观的 SOTA 方法。

论文

Empirical variance of the estimated gradient (c.f. (1)) as a function of the number of state-action pairs used in estimation in the MuJoCo Humanoid task. We measure the average pairwise cosine similarity between ten repeated gradient measurements taken from the same policy, with the 95% confidence intervals (shaded). For each algorithm, we perform multiple trials with the same hyperparameter configurations but different random seeds, shown as repeated lines in the figure. The vertical line (at x = 2K) indicates the sample regime used for gradient estimation in standard implementations of policy gradient methods. In general, it seems that obtaining tightly concentrated gradient estimates would require significantly more samples than are used in practice, particularly after the first few timesteps. For other tasks – such as Walker2d-v2 and Hopper-v2 – the plots have similar trends, except that gradient variance is slightly lower. Confidence intervals calculated with 500 sample bootstrapping.

主要作者:


15。元 Q 学习

MQL 是一种简单的脱离策略的 meta-RL 算法,它从元训练重放缓冲区回收数据以适应新的任务。

(TL;博士,来自)

*论文

How well does meta-RL work? Average returns on validation tasks compared for two prototypical meta-RL algorithms, MAML (Finn et al., 2017) and PEARL (Rakelly et al., 2019), with those of a vanilla Q-learning algorithm named TD3 (Fujimoto et al., 2018b) that was modied to incorporate a context variable that is a representation of the trajectory from a task (TD3-context). Even without any meta-training and adaptation on a new task, TD3-context is competitive with these sophisticated algorithms.

主要作者:


总结

ICLR 出版物的深度和广度相当鼓舞人心。在这里,我只是展示了“强化学习”主题的冰山一角。然而,正如你在这篇分析中看到的,会议讨论了四个主要领域:

  1. 深度学习(在我们的上一篇文章中讨论过)
  2. 强化学习(在这篇文章中讨论)
  3. 生成模型(此处)
  4. 自然语言处理/理解(此处

为了对 ICLR 大学的顶级论文有一个更完整的概述,我们正在建立一系列的帖子,每个帖子都专注于上面提到的一个主题。你可能想要查看以获得更完整的概述。

请随意与我们分享其他关于强化学习的有趣论文,我们会很乐意将它们添加到列表中。

享受阅读!

卡米尔·卡什马雷克

人工智能研究倡导者,在 MLOps 领域工作。总是在寻找新的 ML 工具、过程自动化技巧和有趣的 ML 论文。偶尔会有博客作者和会议发言人。


阅读下一篇

强化学习的 10 个现实应用

10 分钟阅读|作者 Derrick Mwiti |年 5 月 25 日更新

强化学习(RL) 中,智能体在一个奖励惩罚机制上接受训练。代理人因正确的移动而得到奖励,因错误的移动而受到惩罚。在这样做的时候,代理人试图最小化错误的移动,最大化正确的移动。

在本文中,我们将看看强化学习在现实世界中的一些应用。

自动驾驶汽车中的应用

各种论文都提出了针对自动驾驶的深度强化学习。在自动驾驶汽车中,有各种各样的方面需要考虑,例如各个地方的速度限制,可驾驶区,避免碰撞——仅举几例。

一些可以应用强化学习的自动驾驶任务包括轨迹优化、运动规划、动态路径、控制器优化和基于场景的高速公路学习策略。

比如,可以通过学习自动泊车政策来实现泊车。可以使用 Q 学习来实现变道,而超车可以通过学习超车策略来实现,同时避免碰撞并在其后保持稳定的速度。

AWS DeepRacer 是一款自主赛车,旨在在物理赛道上测试 RL。它使用摄像头来可视化跑道,并使用强化学习模型来控制油门和方向。

Continue reading ->


图像分类:来自 13 个 Kaggle 竞赛的提示和技巧(+大量参考文献)

原文:https://web.archive.org/web/https://neptune.ai/blog/image-classification-tips-and-tricks-from-13-kaggle-competitions

任何领域的成功都可以提炼为一套小规则和基本原则,当它们结合在一起时会产生巨大的效果。

机器学习和图像分类没有什么不同,工程师可以通过参加像 Kaggle 这样的比赛来展示最佳实践。

在本文中,我将为您提供大量的学习资源,重点关注来自 13 个 Kaggle 竞赛的最佳 Kaggle 内核,其中最突出的竞赛是:

我们将经历调整深度学习解决方案的三个主要领域:

…在此过程中会有许多示例项目(和参考资料)供您查阅。

数据

图像预处理+ EDA

每个机器学习/深度学习解决方案都是从原始数据开始的。数据处理流程中有两个基本步骤。

第一步是 探索性数据分析 (EDA)。它帮助我们分析整个数据集并总结其主要特征,如类别分布、大小分布等。可视化方法通常用于显示这种分析的结果。

第二步是 图像预处理 ,目的是获取原始图像,通过抑制不必要的失真、调整大小和/或增强重要特征来改善图像数据(也称为图像特征),使数据更适合模型并提高性能。

您可以深入这些 Kaggle 笔记本,查看一些关于图像预处理EDA 技术的示例:

数据扩充

数据扩充可以通过从现有的训练样本中生成更多的训练数据来扩充我们的数据集。新的样本是通过大量的随机转换生成的,这些随机转换不仅产生看起来可信的图像,还反映了现实生活中的场景——稍后将详细介绍。

这种技术被广泛使用,不仅仅是在数据样本太少而无法训练模型的情况下。在这种情况下,模型开始记忆训练集,但它无法进行归纳(在从未见过的数据上表现很差)。

通常,当一个模型在训练数据上表现很好,但在验证数据上表现很差时,我们把这种情况称为 【过拟合】 。为了解决这个问题,我们通常试图获得新数据,如果新数据不可用,数据增强就可以解决这个问题。

注意:一般的经验法则是总是使用数据扩充技术,因为它有助于将我们的模型暴露给更多的变化并更好地概括。即使我们有一个大数据集,尽管这是以缓慢的训练速度为代价的,因为增强是在运行中完成的(这意味着在训练期间)。

此外,对于每个任务或数据集,我们必须使用反映可能的现实生活场景的增强技术(即,如果我们有一个猫/狗检测器,我们可以使用水平翻转、裁剪、亮度和对比度,因为这些增强技术匹配照片拍摄方式的差异)。

以下是一些 Kaggle 竞赛笔记本,供您在实践中检验流行的数据增强技术:

模型

在这里,我们使用一个非常简单的架构创建了一个基本模型,没有任何正则化或丢弃层,看看我们是否可以打破 50%准确性的基线分数。虽然我们不能总是到达那里,但是如果我们在尝试了多种合理的架构之后不能超过基线,也许输入数据并不包含我们的模型做出预测所需的信息。

用杰瑞米·霍华德睿智的话来说:

“你应该能够在 15 分钟内使用 50%或更少的数据集快速测试你是否进入了一个有前途的方向,如果没有,你必须重新思考一切。”

开发一个足够大的模型,使其适应过度(示例项目

一旦我们的基线模型有足够的能力击败基线得分,我们可以增加基线模型的能力,直到它超过数据集,然后我们移动到应用正则化。我们可以通过以下方式增加模块容量:

添加更多层

  • 使用更好的架构
  • 更好的培训程序
  • 体系结构

根据文献,下面的架构改进提高了模型容量,但几乎没有改变计算复杂性。如果你想深入研究相关的例子,它们仍然很有趣:

大多数情况下,模型容量和准确性是正相关的——随着容量的增加,准确性也会增加,反之亦然。

培训程序

以下是一些训练程序,您可以使用它们来调整您的模型,并通过示例项目来了解它们是如何工作的:

超参数调谐

与参数不同,超参数由您在配置模型时指定(即学习率、时期数、隐藏单元数、批量等)。

除了手动尝试不同的模型配置,您还可以通过使用超参数调整库,如Scikit learn Grid SearchKeras Tuner和其他库来自动执行此过程,这些库将尝试您指定范围内的所有超参数组合,并返回最佳性能模型。

需要优化的超参数越多,这个过程就越慢,所以最好选择模型超参数的最小子集进行优化。

并非所有的模型超参数都同样重要。一些超参数对机器学习算法的行为有巨大的影响,进而影响其性能。您应该仔细挑选对模型性能影响最大的那些,并对它们进行调优以获得最佳性能。

正规化

这种方法通过惩罚 记忆/过拟合欠拟合 来迫使模型学习数据的有意义的和可概括的表示,使得模型在处理它从未见过的数据时更加健壮。

解决上述问题的一个简单方法是获得更多的训练数据,因为基于更多数据训练的模型自然会更好地概括。

这里有一些你可以尝试缓解 过拟合欠拟合 的技巧,并附有示例项目链接供你挖掘:

损失函数

损失函数 也被称为成本函数或目标函数,用于找出模型输出与目标输出之间的差异,并帮助模型最小化它们之间的距离。

以下是一些最受欢迎的损失函数,通过项目示例,您可以找到提高模型容量的技巧:

评估+误差分析

在这里,我们进行烧蚀研究,并分析我们的实验结果。我们确定模型的弱点和优点,并确定未来需要改进的地方。在这个阶段,您可以使用下面的技术,看看它们是如何在链接的示例中实现的:

有许多实验跟踪和管理工具,只需最少的设置即可自动为您保存所有数据,这使得消融研究更容易—Neptune . ai在这里做得很好。

结束语

有很多方法可以调整你的模型,新的想法总是会出现。深度学习是一个快速发展的领域,没有灵丹妙药。我们必须进行大量实验,足够的试错导致突破。这篇文章已经包含了很多链接,但对于最渴求知识的读者来说,我还在下面添加了一个很长的参考部分,供你多阅读和运行一些笔记本。

进一步研究

参考

论文:

博客:

书籍:

Kaggle 竞赛:

Kaggle 笔记本:

Kaggle notebooks:

机器学习中使用的 8 大图像处理 Python 库

原文:https://web.archive.org/web/https://neptune.ai/blog/image-processing-python-libraries-for-machine-learning

IDC 预测,数字数据将暴涨至 175 zettabytes,而这些数据的巨大部分是图像。数据科学家需要在将这些图像输入任何机器学习模型之前对其进行(预)处理。在有趣的部分开始之前,他们必须做重要的(有时是肮脏的)工作。

为了在不影响结果的情况下高效快速地处理大量数据,数据科学家需要使用图像处理工具来完成机器学习和深度学习任务。

在这篇文章中,我将列出 Python 中最有用的图像处理库,它们在机器学习任务中被大量使用。

1.OpenCV

OpenCV 是英特尔在 2000 年开发的开源库。它主要用于计算机视觉任务,如物体检测,人脸检测,人脸识别,图像分割等,但也包含了许多有用的功能,你可能需要在 ML。

灰度级

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

img = cv.imread('goku.jpeg')
gray_image = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

fig, ax = plt.subplots(1, 2, figsize=(16, 8))
fig.tight_layout()

ax[0].imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
ax[0].set_title("Original")

ax[1].imshow(cv.cvtColor(gray_image, cv.COLOR_BGR2RGB))
ax[1].set_title("Grayscale")
plt.show()

彩色图像由 3 个颜色通道组成,而灰色图像仅由 1 个颜色通道组成,该通道携带每个像素的强度信息,将图像显示为黑白。

以下代码分隔每个颜色通道:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('goku.jpeg')
b, g, r = cv.split(img)

fig, ax = plt.subplots(1, 3, figsize=(16, 8))
fig.tight_layout()

ax[0].imshow(cv.cvtColor(r, cv.COLOR_BGR2RGB))
ax[0].set_title("Red")

ax[1].imshow(cv.cvtColor(g, cv.COLOR_BGR2RGB))
ax[1].set_title("Green")

ax[2].imshow(cv.cvtColor(b, cv.COLOR_BGR2RGB))
ax[2].set_title("Blue")

图像翻译

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

image = cv.imread("pics/goku.jpeg")
h, w = image.shape[:2]

half_height, half_width = h//4, w//8
transition_matrix = np.float32([[1, 0, half_width],
                               [0, 1, half_height]])

img_transition = cv.warpAffine(image, transition_matrix, (w, h))

plt.imshow(cv.cvtColor(img_transition, cv.COLOR_BGR2RGB))
plt.title("Translation")
plt.show()

上面的代码将图像从一个坐标转换到另一个坐标。

图像旋转

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

image = cv.imread("pics/goku.jpeg")

h, w = image.shape[:2]
rotation_matrix = cv.getRotationMatrix2D((w/2,h/2), -180, 0.5)

rotated_image = cv.warpAffine(image, rotation_matrix, (w, h))

plt.imshow(cv.cvtColor(rotated_image, cv.COLOR_BGR2RGB))
plt.title("Rotation")
plt.show()

图像绕 X 轴或 Y 轴旋转。

缩放和调整大小

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

image = cv.imread("pics/goku.jpeg")

fig, ax = plt.subplots(1, 3, figsize=(16, 8))

image_scaled = cv.resize(image, None, fx=0.15, fy=0.15)
ax[0].imshow(cv.cvtColor(image_scaled, cv.COLOR_BGR2RGB))
ax[0].set_title("Linear Interpolation Scale")

image_scaled_2 = cv.resize(image, None, fx=2, fy=2, interpolation=cv.INTER_CUBIC)
ax[1].imshow(cv.cvtColor(image_scaled_2, cv.COLOR_BGR2RGB))
ax[1].set_title("Cubic Interpolation Scale")

image_scaled_3 = cv.resize(image, (200, 400), interpolation=cv.INTER_AREA)
ax[2].imshow(cv.cvtColor(image_scaled_3, cv.COLOR_BGR2RGB))
ax[2].set_title("Skewed Interpolation Scale")

图像的缩放是指将图像阵列转换成更低或更高的维度。

这些是可以用 OpenCV 在图像上执行的一些最基本的操作。除此之外,OpenCV 还可以执行诸如图像分割、人脸检测、物体检测、三维重建、特征提取等操作。

如果你想看看这些图片是如何使用 OpenCV 生成的,那么你可以看看这个 GitHub

2. Scikit-Image

scikit-image 是一个基于 python 的图像处理库,其中一些部分是用cy thon(cy thon是一种编程语言,它是 Python 编程语言的超集,旨在具有类似 C 编程语言的性能。)才能取得好的成绩。它包括以下算法:

  • 分段,
  • 几何变换,
  • 色彩空间操作,
  • 分析,
  • 过滤,
  • 形态学,
  • 特征检测等等

你会发现它对几乎任何计算机视觉任务都很有用。

scikit-image使用 NumPy 数组作为图像对象。

活动轮廓

在计算机视觉中,轮廓模型描述了图像中形状的边界。

活动轮廓模型是为基于曲线流、曲率和轮廓的图像分割而定义的,以获得图像中精确的目标区域或片段

下面的代码产生了上面的输出:

import numpy as np
import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage import data
from skimage.filters import gaussian
from skimage.segmentation import active_contour

img = data.astronaut()

s = np.linspace(0, 2*np.pi, 400)
x = 220 + 100*np.cos(s)
y = 100 + 100*np.sin(s)
init = np.array([x, y]).T

cntr = active_contour(gaussian(img, 3),init, alpha=0.015, beta=10, gamma=0.001)
fig, ax = plt.subplots(1, 2, figsize=(7, 7))
ax[0].imshow(img, cmap=plt.cm.gray)
ax[0].set_title("Original Image")

ax[1].imshow(img, cmap=plt.cm.gray)

ax[1].plot(init[:, 0], init[:, 1], '--r', lw=3)
ax[1].plot(cntr[:, 0], cntr[:, 1], '-b', lw=3)
ax[1].set_title("Active Contour Image")

3.我的天啊

Scipy 用于数学和科学计算,但也可以使用子模块 scipy.ndimage 执行多维图像处理。它提供了在 n 维 Numpy 数组上操作的函数,最终图像就是这样。

Scipy 提供了最常用的图像处理操作如:

  • 读取图像
  • 图象分割法
  • 盘旋
  • 人脸检测
  • 特征提取等等。

模糊图像

from scipy import misc,ndimage
from matplotlib import pyplot as plt

face = misc.face()
blurred_face = ndimage.gaussian_filter(face, sigma=3)

fig, ax = plt.subplots(1, 2, figsize=(16, 8))

ax[0].imshow(face)
ax[0].set_title("Original Image")
ax[0].set_xticks([])
ax[0].set_yticks([])
ax[1].imshow(blurred_face)
ax[1].set_title("Blurred Image")
ax[1].set_xticks([])
ax[1].set_yticks([])

输出:

在 这里可以找到所有操作

4.pillow/GDP

PIL (Python 图像库)是一个开源库,用于需要 Python 编程语言的图像处理任务。 PIL 可以在图像上执行任务,例如读取、缩放、以不同的图像格式保存。

PIL 可用于图像存档、图像处理、图像显示。

用 PIL 增强图像

例如,让我们将下面的图像增强 30%的对比度。

from PIL import Image, ImageFilter

im = Image.open('cat_inpainted.png')

im.show()

from PIL import ImageEnhance
enh = ImageEnhance.Contrast(im)
enh.enhance(1.8).show("30% more contrast")

输出:

欲了解更多信息,请点击这里

5.NumPy

图像本质上是像素值的数组,其中每个像素由 1(灰度)或 3 (RGB)值表示。因此,NumPy 可以轻松执行图像裁剪、遮罩或像素值操作等任务。

例如,从下图中提取红/绿/蓝通道:

我们可以使用 numpy,通过用零替换所有的像素值,一次“惩罚”一个通道。

from PIL import Image
import numpy as np

im = np.array(Image.open('goku.png'))

im_R = im.copy()
im_R[:, :, (1, 2)] = 0
im_G = im.copy()
im_G[:, :, (0, 2)] = 0
im_B = im.copy()
im_B[:, :, (0, 1)] = 0

im_RGB = np.concatenate((im_R, im_G, im_B), axis=1)

pil_img = Image.fromarray(im_RGB)
pil_img.save('goku.jpg')

6.马霍塔斯

Mahotas 是另一个为 生物图像信息学 设计的图像处理和计算机视觉库。它在 NumPy 数组中读写图像,用 C++实现,具有流畅的 python 接口。

Mahotas 最受欢迎的功能是

让我们看看如何使用 Mahotas 进行模板匹配,以便找到 wally。

下面的代码片段有助于在人群中找到 Wally。

from pylab import imshow, show
import mahotas
import mahotas.demos
import numpy as np

wally = mahotas.demos.load('Wally')
wfloat = wally.astype(float)

r,g,b = wfloat.transpose((2,0,1))
w = wfloat.mean(2)
pattern = np.ones((24,16), float)

for i in range(2):
    pattern[i::4] = -1
    v = mahotas.convolve(r-w, pattern)
    mask = (v == v.max())
    mask = mahotas.dilate(mask, np.ones((48,24)))
    np.subtract(wally, .8*wally * ~mask[:,:,None], out=wally, casting='unsafe')
imshow(wally)
show()

7.SimpleITK

ITKInsight 分割和配准工具包是一个开源平台,广泛用于图像分割和图像配准(一个叠加两个或更多图像的过程)。

图像分割

ITK 使用了 CMake 构建环境,库是用 Python 包装的 C++实现的。

你可以检查这个 Jupyter 笔记本用于学习和研究。

8.Pgmagick

Pgmagick 是 Python 的一个GraphicsMagick绑定,它提供了对图像执行调整大小、旋转、锐化、渐变图像、绘制文本等操作的工具。

**### 模糊图像

from pgmagick.api import Image

img = Image('leena.jpeg')

img.blur(10, 5)

图像的缩放

from pgmagick.api import Image

img = Image('leena.png')

img.scale((150, 100), 'leena_scaled')

要了解更多信息,你可以查看 Jupyter 笔记本的精选列表这里

最后的想法

我们已经介绍了用于机器学习的前 8 个图像处理库。希望您现在已经知道哪一个最适合您的项目。祝你好运。🙂****

Python 中的图像处理:你应该知道的算法、工具和方法

原文:https://web.archive.org/web/https://neptune.ai/blog/image-processing-python

图像定义了世界,每张图像都有自己的故事,它包含了许多在许多方面都有用的重要信息。这些信息可以借助于被称为图像处理的技术来获得。

它是计算机视觉的核心部分,在许多现实世界的例子中起着至关重要的作用,如机器人、自动驾驶汽车物体检测。图像处理允许我们一次转换和操作数千幅图像,并从中提取有用的见解。它在几乎每个领域都有广泛的应用。

Python 是为此目的广泛使用的编程语言之一。它惊人的库和工具有助于非常有效地完成图像处理任务。

这篇文章将教你关于经典算法、技术和工具来处理图像并得到想要的输出。

让我们开始吧!

什么是图像处理?

顾名思义,图像处理意味着处理图像,这可能包括许多不同的技术,直到我们达到我们的目标。

最终输出可以是图像或该图像的相应特征的形式。这可用于进一步的分析和决策。

但是什么是图像呢?

图像可以表示为 2D 函数 F(x,y ),其中 x 和 y 是空间坐标。在 x,y 的特定值处 F 的振幅被称为图像在该点的强度。如果 x,y 和振幅值是有限的,那么我们称之为数字图像。它是按列和行排列的像素阵列。像素是图像中包含强度和颜色信息的元素。图像也可以用 3D 表示,其中 x、y 和 z 成为空间坐标。像素以矩阵的形式排列。这就是所谓的 RGB 图像

有各种类型的图像:

RGB 图像:它包含三层 2D 图像,这些层是红色、绿色和蓝色通道。

  • 灰度图像:这些图像包含黑白阴影,并且只包含一个通道。

经典图像处理算法

1.形态学图像处理

形态学图像处理试图从二值图像中去除缺陷,因为通过简单的阈值处理产生的二值区域会被噪声扭曲。它还有助于使用打开和关闭操作平滑图像。

形态学操作可以扩展到灰度图像。它由与图像特征结构相关的非线性运算组成。这取决于像素的相关顺序,但取决于它们的数值。该技术使用被称为结构化元素的小模板来分析图像,该模板被放置在图像中不同的可能位置,并与相应的邻域像素进行比较。结构化元素是具有 0 和 1 值的小矩阵。

让我们看看形态学图像处理的两个基本操作,膨胀和腐蚀:

膨胀操作将像素添加到图像中对象的边界

  • 腐蚀操作从对象边界上去除像素。
  • 原始图像中移除或添加的像素数量取决于结构元素的大小。

此时你可能会想“什么是结构化元素?”让我解释一下:

结构化元素是仅由 0 和 1 组成的矩阵,可以具有任意形状和大小。它被定位在图像中所有可能的位置,并与相应的邻域像素进行比较。

正方形结构元素“A”适合我们想要选择的对象,“B”与对象相交,“C”在对象之外。

0-1 模式定义了结构化元素的配置。这取决于我们想要选择的物体的形状。结构化元素的中心标识正在被处理的像素。

2。高斯图像处理

高斯模糊也被称为高斯平滑,是通过高斯函数模糊图像的结果。

用来降低图像噪点,减少细节。这种模糊技术的视觉效果类似于通过半透明屏幕观看图像。它有时用于计算机视觉中不同比例的图像增强,或作为深度学习中的数据增强技术。

基本的高斯函数看起来像:

在实践中,最好是利用高斯模糊的可分离属性,将该过程分为两个过程。在第一步中,一维核用于仅在水平或垂直方向模糊图像。在第二遍中,相同的一维内核用于在剩余方向上模糊。产生的效果与单次通过二维内核进行卷积的效果相同。让我们看一个例子来理解高斯滤波器对图像做了什么。

如果我们有一个正态分布的过滤器,当它应用于图像时,结果看起来像这样:

来源

你可以看到一些边缘细节很少。过滤器给予位于中心的像素比远离中心的像素更多的权重。高斯滤波器是低通滤波器,即削弱高频。通常在边缘检测中使用

3.图像处理中的傅立叶变换

傅立叶变换将图像分解成正弦和余弦分量。

它有多种应用,如图像重建、图像压缩或图像过滤。

因为我们在讨论图像,所以我们将考虑离散傅立叶变换。

让我们考虑一个正弦波,它由三部分组成:

幅度——与对比度相关

  • 空间频率——与亮度相关
  • 相位-与颜色信息相关
  • 频域中的图像如下所示:

2D 离散傅立叶变换的公式是:

在上面的公式中,f(x,y)表示图像。

傅立叶逆变换将变换转换回图像。2D 离散傅里叶逆变换的公式为:

4.图像处理中的边缘检测

边缘检测是一种图像处理技术,用于寻找图像中对象的边界。它的工作原理是检测亮度的不连续性。

这对于从图像中提取有用信息是非常有益的,因为大多数形状信息都包含在边缘中。经典的边缘检测方法通过检测亮度的不连续性来工作。

如果在检测灰度级变化的同时在图像中检测到一些噪声,它可以迅速做出反应。边缘被定义为梯度的局部极大值。

最常见的边缘检测算法是 sobel 边缘检测算法。Sobel 检测算子由 3*3 卷积核组成。一个简单的内核 Gx 和一个 90 度旋转的内核 Gy。通过将两个内核分别应用于图像来进行单独的测量。

而且,

*表示 2D 信号处理卷积运算。

由此产生的梯度可计算如下:

5.小波图像处理

我们看到了傅立叶变换,但它仅限于频率。小波将时间和频率都考虑在内。这种变换适合于非平稳信号。

我们知道边缘是图像的重要部分之一,当应用传统的滤波器时,我们注意到噪声被去除了,但是图像变得模糊。小波变换是以这样一种方式设计的,即我们对低频分量获得良好的频率分辨率。下面是 2D 小波变换的例子:

使用神经网络的图像处理

神经网络是由神经元或节点组成的多层网络。这些神经元是神经网络的核心处理单元。它们被设计得像人脑一样。他们接受数据,训练自己识别数据中的模式,然后预测输出。

基本的神经网络有三层:

输入层

隐蔽层

  1. 输出层
  2. 输入层接收输入,输出层预测输出,隐藏层完成大部分计算。隐藏层数可以根据需要修改。神经网络中至少应该有一个隐藏层。
  3. 神经网络的基本工作如下:

让我们考虑一个图像,每个像素作为输入被馈送到第一层的每个神经元,一层的神经元通过通道连接到下一层的神经元。

这些通道中的每一个都被分配了一个称为权重的数值。

  1. 将输入乘以相应的权重,然后将该加权和作为输入提供给隐藏层。
  2. 隐藏层的输出通过一个激活函数,该函数将决定特定的神经元是否被激活。
  3. 被激活的神经元将数据传输到下一个隐藏层。以这种方式,数据通过网络传播,这被称为前向传播。
  4. 在输出层,具有最高值的神经元预测输出。这些输出是概率值。
  5. 将预测输出与实际输出进行比较,以获得误差。这些信息然后通过网络传回,这个过程称为反向传播。
  6. 基于该信息,权重被调整。这种前向和后向传播的循环在多个输入上进行几次,直到网络在大多数情况下正确预测输出。
  7. 这结束了神经网络的训练过程。在某些情况下,训练神经网络所需的时间可能会很长。
  8. 在下图中, ai 的是输入集合, wi 的是权重, z 是输出, g 是任意激活函数。
  9. 以下是为图像处理准备数据的一些指南。

为了获得更好的结果,需要将更多的数据输入到模型中。

Operations-in-a-single-neuron

Operations in a single neuron | Source

图像数据集应该是高质量的,以获得更清晰的信息,但要处理它们,您可能需要更深层次的神经网络。

  • 在许多情况下,RGB 图像在输入神经网络之前被转换成灰度。
  • 神经网络的类型
  • 卷积神经网络

简而言之,卷积神经网络具有三层:

卷积层 ( CONV ):它们是 CNN 的核心构件,负责执行卷积运算。在该层中执行卷积运算所涉及的元素被称为内核/滤波器(矩阵)。内核根据步距进行水平和垂直移动,直到遍历完整图像。

池层 ( ):该层负责降维。它有助于降低处理数据所需的计算能力。有两种类型的池:最大池和平均池。Max pooling 返回映像上内核覆盖区域的最大值。平均池返回内核覆盖的图像部分中所有值的平均值。

  • 全连接层(FC):全连接层 ( FC )对扁平化输入进行操作,其中每个输入连接到所有神经元。如果存在, FC 层通常出现在 CNN 架构的末尾。

Movement-of-the-kernel

Movement of the kernel | Source

  • CNN 主要用于在图像层的帮助下从图像中提取特征。CNN 广泛用于图像分类,其中每个输入图像通过一系列层来获得 0 和 1 之间的概率值。

Pooling operation

Pooling operation | Source

  • 生成对抗网络

Fully connected layers

Fully connected layers | Source

生成模型使用无监督学习方法(有图像,但没有提供标签)。

GANs 由两种型号的发生器鉴别器组成。 发生器学习制作看起来逼真的假图像以欺骗鉴别器鉴别器学习区分假图像和真图像(它试图不被愚弄)。

发生器不允许看到真实图像,因此在开始阶段可能产生差的结果,而鉴别器被允许看到真实图像,但是它们与发生器产生的伪图像混杂在一起,鉴别器必须将其分类为真实或伪图像。

一些噪声被输入到生成器中,这样它每次都能产生不同的例子,而不是相同类型的图像。基于由鉴别器预测的分数,生成器试图改进它的结果,在某个时间点之后,生成器将能够产生更难区分的图像,在那个时间点,用户对它的结果感到满意。鉴别器也改进了自己,因为它在每一轮从发生器获得越来越多的真实图像。

常见的 GAN 类型有深度卷积 gan(dcgan)、条件 gan(cgan)、StyleGANs、CycleGAN、DiscoGAN、GauGAN 等。

GANs 非常适合图像生成和处理。GANs 的一些应用包括:人脸老化、照片混合、超分辨率、照片修复、服装翻译。

1.OpenCV

它代表开源计算机视觉库。这个库由大约 2000 多种优化算法组成,这些算法对计算机视觉和机器学习非常有用。您可以通过多种方式在图像处理中使用 opencv,下面列出了一些方法:

将图像从一个颜色空间转换到另一个颜色空间,例如 BGR 和 HSV,BGR 和灰色等。

对图像执行阈值处理,如简单阈值处理、自适应阈值处理等。

  • 平滑图像,如对图像应用自定义滤镜和模糊图像。
  • 对图像执行形态学操作。
  • 构建图像金字塔。
  • 用 GrabCut 算法从图像中提取前景。
  • 基于分水岭算法的图像分割。
  • 更多详情请参见此链接
  • 2. Scikit-image

这是一个用于图像预处理的开源库。它利用内置函数的机器学习,只需几个函数就可以对图像执行复杂的操作。

它可以处理 numpy 数组,即使对于 python 新手来说,也是一个相当简单的库。使用 scikit image 可以完成的一些操作有:

要实现阈值操作,请对图像使用 try_all_threshold() 方法。它将使用七种全局阈值算法。这是在过滤器模块中。

为了实现边缘检测,使用滤波器模块中的 sobel() 方法。这种方法需要 2D 灰度图像作为输入,所以我们需要将图像转换成灰度。

  • 要实现高斯平滑,使用过滤器模块中的高斯()方法。
  • 要应用直方图均衡,使用曝光模块,要对原始图像应用正常直方图均衡,使用 equalize_hist() 方法,要应用自适应均衡,使用 equalize_adapthist() 方法。
  • 使用变换模块下的旋转()功能旋转图像。
  • 使用变换模块中的 rescale() 函数来缩放图像。
  • 要应用形态学运算,使用形态学模块下的二元腐蚀()二元膨胀()函数。
  • 3.国内生产总值/pillow
  • PIL 代表 Python 图像库, Pillow 是 Alex Clark 和贡献者的友好的 PIL 分叉。这是一个强大的图书馆。它支持多种图像格式,如 PPM、JPEG、TIFF、GIF、PNG 和 BMP。

它可以帮助你对图像进行旋转、缩放、裁剪、灰度缩放等操作。让我们来看一下这些操作

为了执行操作,该库中有一个名为 Image 的模块。

要加载图像,请使用 open() 方法。

使用 show() 方法显示图像。

  • 要了解文件格式,使用格式属性
  • 要知道图像的大小,使用 size 属性
  • 要了解像素格式,请使用模式属性。
  • 要保存所需处理后的图像文件,请使用 save() 方法。Pillow 将图像文件保存为 png 格式。
  • 要调整图像的大小,请使用 resize() 方法,该方法采用两个参数作为宽度和高度。
  • 要裁剪图像,使用 crop() 方法,该方法将一个参数作为定义裁剪区域的位置和大小的框元组。
  • 要旋转图像,使用 rotate() 方法,该方法将一个参数作为表示旋转度数的整数或浮点数。
  • 要翻转图像,请使用 transform() 方法,该方法采用以下参数之一:image。FLIP_LEFT_RIGHT,图像。FLIP_TOP_BOTTOM,图像。旋转 _ 90°,图像。旋转 _ 180°,图像。旋转 _270。
  • 4.NumPy
  • 使用这个库,您还可以执行简单的图像技术,例如翻转图像、提取特征和分析它们。

图像可以用 numpy 多维数组来表示,因此它们的类型是 NdArrays 。彩色图像是三维的 numpy 数组。通过对多维阵列进行切片,可以分离 RGB 通道。

下面是可以使用 NumPy 对图像执行的一些操作(使用 imread 将图像加载到名为 test_img 的变量中)。

要在垂直方向翻转图像,请使用 np.flipud(test_img)。

要在水平方向翻转图像,请使用 np.fliplr(test_img)。

  • 反转图像,使用 test_img[::-1] (保存为 numpy 数组后的图像命名为< img_name >)。
  • 要给图像添加滤镜,您可以这样做:
  • 例: np.where(test_img > 150,255,0) ,这里说的是在这张图片中如果你找到任何带 150 的东西,那么就用 255 代替,否则 0。
  • 您也可以单独显示 RGB 通道。可以使用以下代码片段来完成:

要获得红色通道,做 test_img[:,:,0] ,要获得绿色通道,做 test_img[:,:,1] ,要获得蓝色通道,做 test_img[:,:,2】。

  • 5.马霍塔斯

这是一个计算机视觉和图像处理库,有 100 多个函数。它的很多算法都是用 C++实现的。Mahotas 本身是一个独立的模块,即它具有最小的依赖性。

目前,它只依赖 C++编译器进行数值计算,不需要 NumPy 模块,编译器会完成所有的工作。

以下是 Mahotas 中一些出色算法的名称:

让我们看看使用 Mahotas 可以完成的一些操作:

使用 imread() 方法读取图像。

使用 mean() 方法计算图像的平均值。

  • 图像的离心率度量从给定的顶点 v 到连通图的任何其它顶点 w 的最短路径长度。要找到图像的偏心率,使用特征模块下的偏心率()方法。
  • 对于图像上的膨胀和腐蚀,使用变形模块下的膨胀()腐蚀()方法。
  • 使用 locmax() 方法找到图像的局部最大值。
  • 摘要
  • 在本文中,我简要解释了可以使用形态滤波、高斯滤波、傅立叶变换和小波变换完成的经典图像处理。

所有这些都可以使用各种图像处理库来完成,如 OpenCV、Mahotas、PIL、scikit-learn。

我还讨论了用于计算机视觉的流行神经网络,如 CNN 和 GANs

深度学习凭借其百老汇术语和图像处理领域的进步正在改变世界。研究人员正在想出更好的技术来微调整个图像处理领域,因此学习不会就此停止。继续前进。

I also discussed popular neural networks like CNN and GANs that are used for computer vision.

Deep learning is changing the world with its broadway terminologies and advances in the field of image processing. Researchers are coming up with better techniques to fine tune the whole image processing field, so the learning does not stop here. Keep advancing.

可以在机器学习项目中使用的图像处理技术

原文:https://web.archive.org/web/https://neptune.ai/blog/image-processing-techniques-you-can-use-in-machine-learning

图像处理是一种对图像执行操作以从中提取信息或增强图像的方法。数字图像处理有着广泛的应用,如图像恢复、医学成像、遥感、图像分割等。每个过程都需要不同的技术。

在这篇文章中,我们将讨论机器学习的六大图像处理技术。

  1. 图像恢复
  2. 线性过滤
  3. 独立成分分析
  4. 像素化
  5. 模板匹配
  6. 图像生成技术

1.图像恢复

图像质量下降的原因有很多,例如,用旧技术相机拍摄的你祖父母的旧图像可能会变得模糊或失去其原始形式。

如果图像受到一些物理压力,或者如果它是数字形式,它可能会因运动模糊或附加噪声而恶化,这种情况就会发生。

那你打算怎么恢复呢?也许这在 50 年前是不可能的,但现在——是可能的。

研究人员想出了一个退化模型 ,可以撤销输入图像上的退化效果。退化模型作为具有线性移位不变量的卷积来工作。

因此,我们用退化滤波器拍摄退化前的图像(称为“真实图像”)和退化后的图像(称为“观察图像”),退化滤波器估计为“真实图像”。

使用 OpenCV 图像修复的图像恢复示例

图像赋予又称“油漆损失赔偿”。这种技术通常用于从图像中移除不想要的对象,以恢复退化图像的受损部分。

在上面的代码中,我们有两种类型的图像

import cv2

img = cv2.imread('damaged_image.png')
mask = cv2.imread('mask.png', 0)
dst = cv2.inpaint(img, mask, 3, cv2.INPAINT_NS)

cv2.imwrite('restored.png', dst)

被损坏的

  1. 戴面具的
  2. 被掩蔽的图像具有与噪声图像中存在的噪声相同的空间维度。

所以如果我们用上面的代码输入下面的图像:

带着面具:

然后我们会得到下面的图像:

OpenCV 的图像修复最大的问题是,我们需要为我们想要修复的特定图像手动输入一个遮罩。那么,我们怎样才能使这个过程自动化呢?

答案是 GAN(一般对抗性网络)。这篇论文提出,通过使用 GAN 网络,可以使用邻域损失函数和梯度损失来进行图像修复,恢复的图像质量更好。

2.线性过滤

线性滤波是一个过程,其中输出像素的值是相邻输入像素的线性组合。这个过程是通过一种叫做卷积的技术来完成的。

卷积是将图像的每个元素添加到其局部邻居的过程,由内核加权。

我们有一个输入图像和一个带有锚点的内核。在上图中,是 H(1,1)。

这个过滤器像一个滑动窗口一样对图像进行卷积。

我们将每个像素乘以相应的核,然后求和。该总和成为输出图像中的新像素。

让我们在 OpenCV 的帮助下看看这是怎么回事

3.独立成分分析

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

image = cv.imread("pics/goku.jpeg")

fig, ax = plt.subplots(1, 3, figsize=(16, 8))
fig.tight_layout()

ax[0].imshow(cv.cvtColor(image, cv.COLOR_BGR2RGB))
ax[0].set_title('Original Image')

kernel_sharpening = np.array([[-1, -1, -1],
                             [-1, 9, -1],
                             [-1, -1, -1]])

kernel_sharpening_2 = np.array([[-1, -1, -1],
                             [-1, 10, -1],
                             [-1, -1, -1]])

sharpened = cv.filter2D(image, -1, kernel_sharpening)
ax[1].imshow(cv.cvtColor(sharpened, cv.COLOR_BGR2RGB))
ax[1].set_title('Sharpened Kernel Image')

sharpened_2 = cv.filter2D(image, -1, kernel_sharpening_2)
ax[2].imshow(cv.cvtColor(sharpened_2, cv.COLOR_BGR2RGB))
ax[2].set_title('Sharpened Kernel Image 2')

plt.show()

独立成分分析或简称 ICA 是一种将多元信号分离成其基本成分的技术。 ICA 有助于从多种成分或信号的混合物中提取所需成分。

让我解释一下。

在 ICA 中,我们“白化”我们的信号。这意味着给定的将被转换,其组件之间的潜在相关性被移除,并且每个组件的方差等于 1。

使用 sklearn 的 ICA

输出:

ICA using sklearn

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from sklearn.decomposition import FastICA, PCA

n_samples = 2000
time = np.linspace(0, 8, n_samples)

s1 = np.sin(2 * time)  
s2 = np.sign(np.sin(3 * time))  
s3 = signal.sawtooth(2 * np.pi * time)  

S = np.c_[s1, s2, s3]
S += 0.2 * np.random.normal(size=S.shape)  

S /= S.std(axis=0)  

A = np.array([[1, 1, 1], [0.5, 2, 1.0], [1.5, 1.0, 2.0]])  
X = np.dot(S, A.T)  

ica = FastICA(n_components=3)
S_ = ica.fit_transform(X)  
A_ = ica.mixing_  

plt.figure()

models = [X, S, S_]
names = ['Observations (mixed signal)',
         'True Sources',
         'ICA recovered signals']
colors = ['red', 'steelblue', 'orange']

for ii, (model, name) in enumerate(zip(models, names), 1):
    plt.subplot(3, 1, ii)
    plt.title(name)
    for sig, color in zip(model.T, colors):
        plt.plot(sig, color=color)

plt.tight_layout()
plt.show()

4.像素化

当图像的尺寸被放大到可以观察到单个像素的程度,或者像素被拉伸到超出其原始尺寸的程度时,就会出现像素化。

使用 OpenCV 进行像素化

输入:

输出:

import cv2

input = cv2.imread('cat.png')

height, width = input.shape[:2]

w, h = (16, 16)

temp = cv2.resize(input, (w, h), interpolation=cv2.INTER_LINEAR)

output = cv2.resize(temp, (width, height), interpolation=cv2.INTER_NEAREST)

cv2.imshow('Input', input)
cv2.imshow('Output', output)

cv2.waitKey(0)

5.模板匹配

模板匹配是一种在较大的图像中搜索并找到模板位置的方法。你可以把它看作是一种非常简单的物体检测方法。

在模板匹配中,我们将模板图像滑动到较大的图像上,就像我们在卷积过程中所做的那样,并找到匹配部分

使用 OpenCV 进行模板匹配

模板:

大图:

输出:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img_rgb = cv.imread('waldo.jpg')
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
template = cv.imread('waldo_temp.jpg',0)
w, h = template.shape[::-1]
res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)

for pt in zip(*loc[::-1]):
    cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

cv.imshow('img_rgb', img_rgb)
cv.waitKey(0)

6.图像生成技术

在生成对抗网络(GANs)的帮助下,我们可以在图像数据上训练深度学习模型,以生成相同类型的图像数据。

gan 是由 Ian Goodfellow 在 2014 年发明的,他在论文生成对抗网络中对此进行了描述。

gan 由两种不同的型号组成

发电机

鉴别器

发生器的工作是产生图像和鉴别器试图在假图像和真实图像之间进行分类。在训练期间,生成器试图通过生成更好的假图像来胜过鉴别器,鉴别器试图改进自身以区分真实图像和假图像。您可以在本文中阅读更多关于 GAN 架构和培训的信息。

最后的想法

  1. 所以在本文中,我简要解释了任何机器学习项目中最常用的图像处理技术:
  2. 线性过滤

图像恢复

模板匹配

图像生成技术

像素化

  • 独立成分分析
  • 但是选择正确的技术需要经验,经验来自实践。
  • 所以继续学习。
  • Image Generation Technique (GAN)
  • Pixelation
  • Independent Component Analysis

But choosing the right technique requires experience and experience comes from practice.

So keep learning.

图像分割:来自 39 场 Kaggle 竞赛的技巧和诀窍

原文:https://web.archive.org/web/https://neptune.ai/blog/image-segmentation-tips-and-tricks-from-kaggle-competitions

在这篇文章中,我们将使用深度学习深入研究图像分割的世界。

让我们开始吧。

什么是图像分割?

顾名思义,这是将图像分割成多个片段的过程。在这个过程中,图像中的每个像素都与一个对象类型相关联。有两种主要类型的图像分割——语义分割和实例分割。

在语义分割中,相同类型的所有对象使用一个类别标签来标记,而在实例分割中,相似的对象得到它们自己的单独标签。

阿努拉格阿纳,郑帅等人。al 2018《条件随机场遇上语义分割的深度神经网络》|来源阅读更多

图像分割:来自 39 场 Kaggle 竞赛的技巧和诀窍
如何为图像分割和物体检测进行数据探索(我必须通过艰苦的方式学习的东西)

图像分割架构

图像分割的基本架构由编码器和解码器组成。

Vijay Badrinarayanan 等人。al 2017“SegNet:深度卷积...

图像分割:架构、损失、数据集和框架

原文:https://web.archive.org/web/https://neptune.ai/blog/image-segmentation

在这篇文章中,我们将使用深度学习深入研究图像分割的世界。

让我们开始吧。

什么是图像分割?

顾名思义,这是将图像分割成多个片段的过程。在这个过程中,图像中的每个像素都与一个对象类型相关联。有两种主要类型的图像分割——语义分割和实例分割。

在语义分割中,相同类型的所有对象使用一个类别标签来标记,而在实例分割中,相似的对象得到它们自己的单独标签。

image segmentation

Anurag Arnab, Shuai Zheng et. al 2018 “Conditional Random Fields Meet Deep Neural Networks for Semantic Segmentation” | Source

图像分割架构

图像分割的基本架构由编码器和解码器组成。

Vijay Badrinarayanan et. al 2017 “SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation” | Source

编码器通过过滤器从图像中提取特征。解码器负责生成最终输出,该输出通常是包含对象轮廓的分割掩模。大多数架构都有这种架构或其变体。

让我们来看看其中的几个。

优信网

U-Net 是一种卷积神经网络,最初开发用于分割生物医学图像。它的结构看起来像字母 U,因此得名 U-Net。它的架构由两部分组成,左边部分是收缩路径,右边部分是扩张路径。收缩路径的目的是捕获上下文,而扩展路径的作用是帮助精确定位。

U-net architecture image segmentation

Olaf Ronneberger et. al 2015 “U-net architecture image segmentation” | Source

收缩路径由两个三乘三的回旋组成。卷积之后是校正的线性单元和用于下采样的 2 乘 2 最大池计算。

U-Net 的完整实现可以在这里找到。

Fast fcn—快速全卷积网络

在这种架构中,联合金字塔上采样(JPU)模块用于取代扩张卷积,因为它们消耗大量内存和时间。它的核心使用全连接网络,同时应用 JPU 进行上采样。JPU 将低分辨率要素地图上采样为高分辨率要素地图。

Huikai Wu et.al 2019 “FastFCN: Rethinking Dilated Convolution in the Backbone for Semantic Segmentation” | Source

如果你想尝试一些代码实现,这就是你要做的

门控 SCNN

这种架构由双流 CNN 架构组成。在这个模型中,一个单独的分支用于处理图像形状信息。形状流用于处理边界信息。

Towaki Takikawa et. al 2019 “Gated-SCNN: Gated Shape CNNs for Semantic Segmentation” | Source

你可以通过检查这里的代码来实现它。

DeepLab

在这种架构中,带有上采样滤波器的卷积用于涉及密集预测的任务。通过 atrous 空间金字塔池实现多尺度的对象分割。最后,使用 DCNNs 来改进目标边界的定位。阿特鲁卷积是通过插入零对滤波器进行上采样或者对输入特征图进行稀疏采样来实现的。

Liang-Chieh Chen et. al 2016 “DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs” | Source

你可以在 PyTorch 或者 TensorFlow 上尝试它的实现。

屏蔽 R-CNN

在这个架构中,使用边界框和语义分割对对象进行分类和定位,将每个像素分类到一组类别中。每个感兴趣的区域得到一个分割掩模。产生类别标签和边界框作为最终输出。该架构是更快的 R-CNN 的扩展。更快的 R-CNN 由提出区域的深度卷积网络和利用区域的检测器组成。

Kaiming He et. al 2017 “Mask R-CNN” | Source

下面是在 COCO 测试集上获得的结果图像。

Mask R-CNN results on the COCO test set

Kaiming He et. al 2017 “Mask R-CNN” | Source

现在,让我们研究几个 Mask R-CNN 用例,为图像中的每个对象自动分割和构建像素级遮罩。

屏蔽 R-CNN 用例

对于今天的介绍性用例演示,我们将重点关注用于图像分割的 Mask R-CNN 框架。具体地,我们将利用在前述 COCO 数据集上预先训练的掩模 R-CNN 模型的权重来构建推理类型的模型。

在模型构建过程中,我们还将设置 Neptune 实验来跟踪和比较不同超参数调整的预测性能。

现在,让我们开始吧!

\ u 003 cimg class = \ u 0022 lazy load block-blog-intext-CTA _ _ arrow-image \ u 0022 src = \ u 0022 https://Neptune . ai/WP-content/themes/Neptune/img/image-ratio-holder . SVG \ u 0022 alt = \ u 0022 \ u 0022 width = \ u 002212 \ u 0022 height = \ u 002222 \ u 022

首先,我们需要安装所需的包并设置我们的环境。在本练习中,将使用由 Matterport 实现的算法。因为到目前为止还没有这个包的发行版,所以我把从 Github repo 克隆来安装它的几个步骤放在一起:

这里需要注意的一点是,最初的 Matterport 代码没有更新为与 Tensorflow 2+兼容。因此,对于包括我在内的所有 Tensorflow 2+用户来说,让它工作变得非常具有挑战性,因为这需要对源代码进行重大修改。如果您不想自定义您的代码,Tensorflow 2+的更新版本也可以从这里获得。因此,请确保根据您的 Tensorflow 版本克隆正确的回购。

第一步:克隆屏蔽 R-CNN GitHub repo

  • 2.2.4 之前的 Tensorflow 1+和 keras:
git clone https://github.com/matterport/Mask_RCNN.git
git clone https://github.com/akTwelve/Mask_RCNN.git updated_mask_rcnn

这将创建一个名为“updated_mask_rcnn”的新文件夹,以区分更新版本和原始版本。

第二步:

  • 检查并安装软件包相关性
  • 导航到包含回购的文件夹
  • 运行:pip install -r requirements.txt

第三步:

  • 运行安装程序来安装软件包
  • 运行:python setup.py clean -all install

需要思考的几点:

  1. 如果您遇到此错误消息:ZipImportError: bad local file header: mask_rcnn-2.1-py3.7.egg.,请升级您的 setuptools。
  2. 对于 windows 用户,如果要求您安装 pycocotools,请确保使用 pip install pycocotools-windows,而不是 pycocotools,因为它可能与 Windows 存在兼容性问题。

\ u 003 cimg class = \ u 0022 lazy load block-blog-intext-CTA _ _ arrow-image \ u 0022 src = \ u 0022 https://Neptune . ai/WP-content/themes/Neptune/img/image-ratio-holder . SVG \ u 0022 alt = \ u 0022 \ u 0022 width = \ u 002212 \ u 022 height = \ u 0022212 \ u 002

接下来,从 Mask_RCNN 项目 Github 中,我们将模型权重下载到当前工作目录: mask_rcnn_coco.h5

\ u 003 cimg class = \ u 0022 lazy load block-blog-intext-CTA _ _ arrow-image \ u 0022 src = \ u 0022 https://Neptune . ai/WP-content/themes/Neptune/img/image-ratio-holder . SVG \ u 0022 alt = \ u 0022 \ u 0022 width = \ u 002212 \ u 022 height = \ u 0022212 \ u 002

当涉及到模型训练过程时,Neptune 提供了一种有效且易于使用的方法来跟踪和记录几乎所有与模型相关的内容,从超参数规范到最佳模型保存,再到绘图记录的结果等等。使用 Neptune 跟踪的实验的酷之处在于,它会自动生成性能图表,供从业者比较不同的运行,从而选择一个最优的运行。

关于配置你的海王星环境和设置你的实验的更详细的解释,请查看这个完整指南和我的另一个关于 Keras 中实现宏 F1 分数的博客。

在这篇博客中,我还将演示如何在图像分割实现过程中利用 Neptune。是的,海王星可以很好地用于跟踪图像处理模型!

导入所有必需的包:

import neptune.new as neptune

import os
import sys
import numpy as np
import skimage.io
import matplotlib
import matplotlib.pyplot as plt

ROOT_DIR = os.path.abspath(PATH_TO_YOUR_WORK_DIRECTORY) 

sys.path.append(ROOT_DIR)  
from mrcnn import utils
import mrcnn.model as modellib
from mrcnn import visualize
from mrcnn.config import Config
from mrcnn.model import MaskRCNN
from mrcnn.visualize import display_instances
from mrcnn.model import log

from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array

sys.path.append(os.path.join(ROOT_DIR, "samples/coco/"))  
import coco

MODEL_DIR = os.path.join(ROOT_DIR, "logs")

COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")

现在,让我们用 Neptune 专门为这个图像分割附加工作创建一个项目:

接下来,在 Python 中,创建一个连接到我们的图像分割项目的 Neptune 实验,以便我们可以记录和监视模型信息并输出到 Neptune:

import neptune
import os

myProject = 'YourUserName/YourProjectName'
project = neptune.init(api_token=os.getenv('NEPTUNE_API_TOKEN'),
                       project=myProject)
project.stop()

npt_exp = neptune.init(
        api_token=os.getenv('NEPTUNE_API_TOKEN'),
        project=myProject,
        name='implement-MaskRCNN-Neptune',
        tags=['image segmentation', 'mask rcnn', 'keras', 'neptune'])

几个音符:

  1. neptune.init()中的 api_token arg 获取从配置步骤中生成的 Neptune API
  2. project.create_experiment()中的标记 arg 是可选的,但是为给定的项目指定标记以便于共享和跟踪是很好的。

在我的演示中有了 ImageSegmentationProject,以及成功设置的初始实验,我们可以进入建模部分了。

\ u 003 cimg class = \ u 0022 lazy load block-blog-intext-CTA _ _ arrow-image \ u 0022 src = \ u 0022 https://Neptune . ai/WP-content/themes/Neptune/img/image-ratio-holder . SVG \ u 0022 alt = \ u 0022 \ u 0022 width = \ u 002212 \ u 022 height = \ u 0022212 \ u 002

为了运行图像分割和推断,我们需要将我们的模型定义为 Mask R-CNN 类的一个实例,并构造一个 config 对象作为输入该类的一个参数。这个配置对象的目的是指定如何利用我们的模型进行训练和预测。

为了预热,让我们只为最简单的实现指定批量大小。

class InferenceConfig(coco.CocoConfig):
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1

config = InferenceConfig()

npt_exp['Model Config Pars'] = str(config.to_dict())

这里,batch size = GPU _ COUNT * IMAGES _ PER _ GPU,其中两个值都设置为 1,因为我们将一次对一个图像进行分割。我们还将配置信息发送到 Neptune,这样我们就可以跟踪我们的实验。

这个视频剪辑显示了我们将在海王星项目中看到的东西,我将它放大以显示细节。

\ u 003 cimg class = \ u 0022 lazy load block-blog-intext-CTA _ _ arrow-image \ u 0022 src = \ u 0022 https://Neptune . ai/WP-content/themes/Neptune/img/image-ratio-holder . SVG \ u 0022 alt = \ u 0022 \ u 0022 width = \ u 002212 \ u 022 height = \ u 0022212 \ u 002

随着所有准备工作的完成,我们继续最令人兴奋的部分——在真实图像上进行推理,看看模型做得如何。

对于任务#1,我们将使用这张图片,它可以从这里免费下载。

下面演示如何定义我们的 Mask R-CNN 模型实例:

model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=config)

model.load_weights(COCO_MODEL_PATH, by_name=True)

image_path = path_to_image_monks
img = load_img(image_path)
img = img_to_array(img)

results = model.detect([img], verbose=1)

思考要点:

  1. 我们将当前模型的类型指定为“推断”,表明我们正在进行图像预测/推断。
  2. 对于要进行预测的掩模 R-CNN 模型,必须将图像转换为 Numpy 数组。
  3. 我们调用 model.detect()函数,而不是像对 Keras 模型预测那样使用 model.predict()。

太棒了。现在我们有了分割结果,但是我们应该如何检查结果并从中获得相应的图像呢?嗯,模型输出是一个包含多个组件的字典,

  • ROI:分割对象的感兴趣区域(ROI)。
  • 遮罩:被分割对象的遮罩。
  • class_ids :被分割对象的类 ID 整数。
  • 分数:每个片段属于一个类别的预测概率。

为了可视化输出,我们可以使用下面的代码。

image_results = results[0]

box, mask, classID, score = image_results['rois'], image_results['masks'], image_results['class_ids'], image_results['scores']

fig_images, cur_ax = plt.subplots(figsize=(15, 15))
display_instances(img, box, mask, classID, class_names, score, ax=cur_ax)

npt_exp['Predicted Image'].upload(neptune.types.File.as_image(fig_images))

这里,class_names 指的是 COCO 数据集中 80 个对象标签/类别的列表。可以从我的 Github 复制粘贴。

运行上面的代码会返回 Neptune 实验中的预测输出图像,

令人印象深刻不是吗!我们的模型成功地分割了僧侣/人类和狗。更令人印象深刻的是,该模型为每个细分分配了非常高的概率/置信度得分(即接近 1)!

\ u 003 cimg class = \ u 0022 lazy load block-blog-intext-CTA _ _ arrow-image \ u 0022 src = \ u 0022 https://Neptune . ai/WP-content/themes/Neptune/img/image-ratio-holder . SVG \ u 0022 alt = \ u 0022 \ u 0022 width = \ u 002212 \ u 022 height = \ u 0022212 \ u 002

现在你可能会认为我们的模型在最后一张图像上做得很好,可能是因为每个对象都在焦点上,这使得分割任务更容易,因为没有太多混杂的背景对象。背景模糊的图像怎么样?该模型能达到同等水平的性能吗?

我们一起实验吧。

下图是一只可爱的泰迪熊,背景是模糊的蛋糕。

为了更好地组织代码,我们可以将前面提到的模型推理步骤编译成函数 runMaskRCNN,它接受两个主要参数。:模型配置和图像路径:

def runMaskRCNN(modelConfig, imagePath, MODEL_DIR=MODEL_DIR, COCO_MODEL_PATH=COCO_MODEL_PATH):
    '''
    Args:
        modelConfig: config object
        imagePath: full path to the image
   '''

    model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=modelConfig)
    model.load_weights(COCO_MODEL_PATH, by_name=True)

    image_path = imagePath
    img = load_img(image_path)
    img = img_to_array(img)

    results = model.detect([img], verbose=1)
    modelOutput = results[0]

    return modelOutput, img

在试验第一个模型时,我们使用与任务#1 相同的配置。这些信息将被发送到海王星进行跟踪和比较。

cur_image_path = path_to_image_teddybear
image_results, img = runMaskRCNN(modelConfig=config, imagePath=cur_image_path)

npt_exp['Model Config Pars'] = str(config.to_dict())
fig_images, cur_ax = plt.subplots(figsize=(15, 15))
display_instances(img, image_results['rois'], image_results['masks'], image_results['class_ids'], class_names, image_results['scores'], ax=cur_ax)

npt_exp['Predicted Image'].upload(neptune.types.File.as_image(fig_images))

根据这个模型的预测,下面的输出图像应该出现在我们的 Neptune 实验日志中。

正如我们所看到的,该模型成功地分割了背景中的泰迪熊和纸杯蛋糕。就纸杯蛋糕封面而言,模型以相当高的概率/置信度将它标记为“瓶子”,这同样适用于下面的纸杯蛋糕托盘,它被标识为“碗”。两者都有道理!

总的来说,我们的模型很好地识别了每个物体。然而,我们也注意到蛋糕的一部分被错误地标注为“泰迪熊”,概率得分为 0.702(即中间的绿色方框)。

我们如何解决这个问题?

\ u 003 cimg class = \ u 0022 lazy load block-blog-intext-CTA _ _ arrow-image \ u 0022 src = \ u 0022 https://Neptune . ai/WP-content/themes/Neptune/img/image-ratio-holder . SVG \ u 0022 alt = \ u 0022 \ u 0022 width = \ u 002212 \ u 022 height = \ u 0022212 \ u 002

我们可以构建一个定制的模型配置来覆盖基本配置类中的超参数。因此,要专门为这个泰迪熊图像定制建模过程:

class CustomConfig(coco.CocoConfig):
    """Configuration for inference on the teddybear image.
    Derives from the base Config class and overrides values specific
    to the teddybear image.
    """

    NAME = "customized"

    NUM_CLASSES = 1 + 80

    GPU_COUNT = 1
    IMAGES_PER_GPU = 1

    STEPS_PER_EPOCH = 500

    DETECTION_MIN_CONFIDENCE = 0.71

    LEARNING_RATE = 0.06
    LEARNING_MOMENTUM = 0.7
    WEIGHT_DECAY = 0.0002

    VALIDATION_STEPS = 30

config = CustomConfig()

npt_exp.send_text('Model Config Pars', str(config.to_dict()))

在使用这个新配置运行模型之后,我们将在 Neptune 项目日志中看到这个具有正确分段的图像,

在我们的自定义配置类中,我们指定了类的数量、每个时期的步数、学习速率、权重衰减等等。有关超参数的完整列表,请参考软件包中的 config.py 文件。

我们鼓励您尝试不同的(超参数)组合,并设置您的 Neptune 项目来跟踪和比较它们的性能。下面的视频剪辑展示了我们刚刚建立的两个模型以及它们在海王星的预测结果。

\ u 003 cimg class = \ u 0022 lazy load block-blog-intext-CTA _ _ arrow-image \ u 0022 src = \ u 0022 https://Neptune . ai/WP-content/themes/Neptune/img/image-ratio-holder . SVG \ u 0022 alt = \ u 0022 \ u 0022 width = \ u 002212 \ u 022 height = \ u 0022212 \ u 002

对于那些想用我们的模型深入杂草的极客观众来说,我们也可以收集并可视化这个 CNN 模型每一层的权重和偏差。下面的代码片段演示了如何对前 5 个卷积层执行此操作。

LAYER_TYPES = ['Conv2D']

layers = model.get_trainable_layers()
layers = list(filter(lambda l: l.__class__.__name__ in LAYER_TYPES, layers))
print(f'Total layers = {len(layers)}')

layers = layers[:5]

fig, ax = plt.subplots(len(layers), 2, figsize=(10, 3*len(layers)+10),
                       gridspec_kw={"hspace":1})

for l, layer in enumerate(layers):
    weights = layer.get_weights()
    for w, weight in enumerate(weights):
        tensor = layer.weights[w]
        ax[l, w].set_title(tensor.name)
        _ = ax[l, w].hist(weight[w].flatten(), 50)

npt_exp['Model_Weights'].upload(neptune.types.File.as_image(fig))

npt_exp.stop()

这是海王星显示的截图,显示了层权重的直方图,

图像分割损失函数

语义分割模型通常在训练期间使用简单的交叉分类熵损失函数。然而,如果你对获得图像的粒度信息感兴趣,那么你必须回到稍微高级一点的损失函数。

让我们来看几个例子。

焦点损失

这种损失是对标准交叉熵准则的改进。这是通过改变它的形状来实现的,使得分配给分类良好的例子的损失是向下加权的。最终,这确保了没有阶级不平衡。在该损失函数中,随着正确类别的置信度增加,交叉熵损失随着缩放因子在零处衰减而缩放。比例因子在训练时自动降低简单示例的权重,并关注困难的示例。

骰子损失

这个损失是通过计算平滑的骰子系数函数得到的。这种损失是最常用的损失是分割问题。

并集上的交集(IoU)-平衡损耗

IoU 平衡的分类损失旨在增加具有高 IoU 的样本的梯度,并降低具有低 IoU 的样本的梯度。这样,提高了机器学习模型的定位精度。

边界损失

边界损失的一个变体应用于具有高度不平衡分割的任务。这种损失的形式是空间轮廓上的距离度量,而不是区域。以这种方式,它解决了由高度不平衡的分割任务的区域损失引起的问题。

加权交叉熵

在交叉熵的一个变体中,所有的正例都被某个系数加权。它用于涉及阶级不平衡的情况。

Lovász-Softmax 损失

该损失基于子模块损失的凸 Lovasz 扩展,对神经网络中的平均交并损失进行直接优化。

值得一提的其他损失有:

  • 其目的是确保网络在训练过程中专注于硬样本。
  • 距离惩罚 ce 损失将网络导向难以分割的边界区域。
  • 敏感性-特异性(SS)损失,计算特异性和敏感性的均方差的加权和。
  • 豪斯多夫距离(HD)损失估计卷积神经网络的豪斯多夫距离。

这些只是图像分割中使用的几个损失函数。要探索更多,请查看这个回购

图像分割数据集

如果你还在这里,你可能会问自己从哪里可以得到一些数据集。

我们来看几个。

1.上下文中的常见对象— Coco 数据集

COCO 是一个大规模的对象检测、分割和字幕数据集。数据集包含 91 个类。它有 25 万人的关键点。其下载大小为 37.57 GiB。它包含 80 个对象类别。它在 Apache 2.0 许可下可用,并且可以从这里下载。

2.PASCAL 可视对象类(PASCAL VOC)

PASCAL 有 20 个不同类别的 9963 个图像。训练/验证集是一个 2GB 的 tar 文件。数据集可以从官网下载。

3.Cityscapes 数据集

该数据集包含城市场景的图像。它可用于评估视觉算法在城市场景中的性能。数据集可以从这里下载。

4.剑桥驾驶标记视频数据库——CamVid

这是一个基于运动的分割和识别数据集。它包含 32 个语义类。这个链接包含进一步的解释和数据集的下载链接。

图像分割框架

现在你已经有了可能的数据集,让我们来介绍几个你可以用来开始的工具/框架。

  • FastAI 库 —给定一幅图像,该库能够创建图像中对象的遮罩。
  • Sefexa 图像分割工具 — Sefexa 是一款免费工具,可用于半自动图像分割、图像分析和创建地面真相
  • deep mask—deep mask由脸书研究是 DeepMaskSharpMask 的火炬实现
  • 多路径 —这一火炬实现的物体检测网络来自于一多路径物体检测网络
  • OpenCV —这是一个开源的计算机视觉库,拥有超过 2500 种优化算法。
  • **——是一个医学图像分割开源库。它允许在几行代码中建立具有最先进的卷积神经网络和深度学习模型的管道。
    ** Fritz:Fritz 为移动设备提供了包括图像分割工具在内的多种计算机视觉工具。*

*## 最后的想法

希望这篇文章给你一些图像分割的背景知识,以及一些工具和框架。我们还希望用例演示能够激发您开始探索深度神经网络这一迷人领域的兴趣

我们涵盖了:

  • 什么是图像分割,
  • 一些图像分割架构,
  • 一些图像分割损失,
  • 图像分割工具和框架,
  • 掩模 R-CNN 算法的用例实现。

要了解更多信息,请查看每个架构和框架的链接。此外,Neptune 项目在这里可用,完整代码可以在这个 Github repo 这里访问。

快乐分段!*

目标检测计算机视觉项目中的不平衡数据

原文:https://web.archive.org/web/https://neptune.ai/blog/imbalanced-data-in-object-detection-computer-vision

数据科学从业者面临的一个典型问题是数据不平衡问题。它困扰着每一个其他的 ML 项目,我们在处理一些分类问题时都面临着它。

数据不平衡可以有几种类型。例如,最经常讨论的问题之一是阶级不平衡。在收集真实世界的数据时,拥有一个类平衡的数据集的可能性真的很低。数据点数量较多的类往往会在模型中产生偏差,如果使用简单的准确度分数,这些有偏差的模型可能会被误解为表现良好。

比方说,如果在一个测试集中,97%被诊断的患者没有癌症,3%有。我们的有偏模型预测没有患者患癌症,准确率为 97%。因此,正确的准确性度量是处理类不平衡问题的重要方面之一。

同样,根据问题的性质和数据集的原始程度,数据集中可能会出现其他类型的不平衡。在本文中,我们将在对象检测问题的背景下研究这些不同的不平衡,以及如何解决它们

对象检测模型中的不平衡

对象检测是在定位图片中感兴趣的对象的同时,将它分类到某个类别中。在深度学习出现之前,第一代对象检测算法主要依赖于手工制作的特征和线性分类器。随着深度学习,虽然对象检测取得了显著的进步,但新的问题也随之产生,即不平衡问题。

图像中有几个输入属性,如图像中的不同对象、前景和背景区域、不同任务的贡献(如网络中的分类和回归)等。如果这些属性的分布不均匀,就会导致不平衡问题。图 1 是对象检测模型数据不平衡的一个例子。

Figure1_foreground_background_imbalance

Figure 1 – Foreground Background Imbalance. | Source: Author

现在让我们详细讨论对象检测中这些不同类型的不平衡。

阶级不平衡

如果数据集中一个对象的实例数多于另一个,就会导致类不平衡。在对象检测中,我们可以将图像中的区域分为前景和背景,如图 2 所示。

Figure2_area_background_foreground

Figure 2 – We can see the area of background is much more than that of the foreground. | Source: Author

从对象检测的角度来看,类别不平衡可以细分为两种类型——前景-背景不平衡和前景-前景不平衡。

  1. 前景-背景不平衡

一般来说,背景的面积比前景的面积大得多,因此大多数边界框被标记为背景。

Figure3_retinanet_anchors_mscoco_background_vs_foreground

Figure 3 – These are the RetinaNet anchors on the MS-COCO dataset for background and foreground. | Source

在图 3 中,您可以看到背景锚和前景锚之间的巨大差异。现在,这很容易导致一个有偏见的模型给出更多的假阴性。

  1. 前景-前景不平衡

在这种情况下,背景锚点不是感兴趣的对象。在图像中,一些对象可能被过度表现,而另一些对象可能被不足表现。因此,当一个类支配另一个类时,这被称为前景-前景不平衡。例如在图 1 中,车辆的数量决定了人的数量。

Figure4_frequency_graph_all_classes

Figure 4 – Frequency graph of 80 object categories in MS-COCO dataset normalized with the total number of images. | Source

在图 4 中,我们可以观察到前景-前景不平衡。

解决阶级不平衡

有几种有效的方法来处理这个问题。让我们从最简单的方法开始。

  1. 硬采样

硬采样是直接丢弃某些边界框,这样它们对训练没有影响,有不同的启发式方法来这样做。

因此,如果 w 是赋予样本的权重,w 将定义其对训练的贡献。对于硬采样,要么 w=0,要么 w=1。

在训练时,从每幅图像的一批样本中,选择一定数量的阴性和阳性样本,其余的被丢弃。

我们不是随机抽样,而是从上到下挑选否定样本的列表(最上面的是最有可能是否定的)。我们选择负面的例子(最上面的),使得负面与正面的比例不超过 3:1。这种方法背后的假设是,具有更多硬样本(其给出更高的损失)的训练算法最终会导致更好的性能。

Figure5_random_vs_hard_negative_mining

Figure 5 – Random Sampling vs Hard Negative Mining, Hard negative mining selects boxes with more negative confidence | Source: Author

负样本被分配到 K 个箱中,然后从每个箱中均匀地选择。这促进了具有给出高损耗值的高 iou 的样本。这也遵循与硬负挖掘相同的假设。

  1. 软采样

与硬采样不同,在硬采样中,正负样本的权重被二进制化(它们要么有贡献,要么没有贡献),在软采样中,我们基于一些方法来调整每个样本的贡献。其中之一就是焦损失。

使用聚焦损失是软采样和处理类别不平衡的最佳方法之一。它赋予硬样品更大的权重。

FL(p[t])=-α(1-p[t])^λlog(p[t])

在上面的损失方程中,p [t] 是样本的估计概率。现在,如果 p [t] ≃1,损失将趋于零(FL≃0),因此只考虑硬例子。

一个很好的焦损 PyTorch 实现可以在这里找到。

  1. 生成方法

取样方法减少和增加样品的重量。然而,生成方法可以生成新的人工样本来平衡训练。生成对抗网络(GANs)的出现推动了这种方法的发展。

论文对抗性快速 RCNN 展示了如何分两个阶段使用。获取来自数据集的图像,然后分两个阶段生成变换后的图像。

  1. ASDN:对抗性空间流失网络造成图像闭塞
  2. ASTN:对抗性空间变换网络将频道从-10 度旋转到 10 度,以创建更难的示例。

Figure6_generative_network_occlusion

Figure 6 – This is the work of ASDN, which shows the occluded areas in the images. | Source

图 6 显示了遮挡区域对分类器的重要性。进行这些改变将允许生成更硬的样本和更健壮的分类器。

Caffe 中的官方实现文件可以在这里找到,很容易理解。

本文主要研究硬正生成。但是生成方法也可以用于前景-背景类别不平衡。

规模失衡

规模不平衡是训练目标检测网络时面临的另一个关键问题。比例失衡的发生是因为某一范围的物体尺寸或某些特定级别(高/低级别)的特征被过度表现或表现不足。

规模失衡可细分为盒子级规模失衡或特征级规模失衡。

  1. 箱级秤不平衡

在某些对象的数据集分布中,大小可能被过度表示。在这种情况下,经过训练的模型会导致不良的感兴趣区域偏向于过度表示的尺寸。

Figure7_normalized_width_height_area_across_datasets

Figure 7 – Normalized width, height and area across different datasets. | Source

图 7 清楚地显示了小尺寸物体的较高频率。

  1. 特征等级比例失调

低级和高级特征的不平衡分布会产生不一致的预测。我们举个例子来理解这一点。快速 RCNN 是一种相当流行的对象检测方法,它使用特征金字塔网络(FPN)进行区域提议。

Figure8_feature_pyramid_netword

Figure 8 – Feature Pyramid Network (FPN). | Source

在图 8 中,我们看到了 FPN 的基本架构。当我们将输入图像传递到自下而上的路径并进行卷积时,初始层由低级特征组成,后续层具有更复杂的高级特征。

请注意,自上而下路径中的每一层都提出了感兴趣的区域。所以所有的层都应该有平衡数量的低级和高级特性。但事实并非如此,正如我们在自上而下的路径中所看到的,我们将在最顶层拥有更多高级功能,在最底层拥有更多低级功能。因此,这可能导致不一致的预测。

解决规模失衡

为了解决规模失衡,你应该更多地处理网络架构的变化,而不是像我们在类失衡中所做的那样处理损失函数的变化。我们讨论了两种类型的规模不平衡,让我们看看如何解决它们。

  1. 箱级秤不平衡

正如您在图 9 中看到的,在所有卷积和池化完成后,早期的对象检测器用于预测最后一层的感兴趣区域。这没有考虑到边界框比例的多样性。

Figure9_RoIprediction

Figure 9 – An example of basic RoI prediction network. | Source

这就是特征金字塔发挥作用的地方。FPN(图 8)包括自下而上的路径、自上而下的路径和横向连接。它给出了从高层到低层的丰富语义。

任何需要区域提案网络的地方都可以使用 FPN。你可以在这里阅读更多关于 FPN 的信息。

在 PyTorch,你可以简单地从 torchvision.ops 获得 FPN;

from torchvision.ops import FeaturePyramidNetwork
net = FeaturePyramidNetwork([10, 20, 30], 5)
print(net)

输出:

FeaturePyramidNetwork(
  (inner_blocks): ModuleList(
    (0): Conv2d(10, 5, kernel_size=(1, 1), stride=(1, 1))
    (1): Conv2d(20, 5, kernel_size=(1, 1), stride=(1, 1))
    (2): Conv2d(30, 5, kernel_size=(1, 1), stride=(1, 1))
  )
  (layer_blocks): ModuleList(
    (0): Conv2d(5, 5, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): Conv2d(5, 5, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (2): Conv2d(5, 5, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  )
)

FPN 也有不同的变体,我们将在下一节讨论。

  1. 特征等级比例失调

我们之前讨论过 FPN 的缺点是如何导致功能级别不平衡的。让我们来看看有助于解决这个问题的网络之一;路径聚合网络(PANet)。

你可以在这里看到 PANet 的建筑。

Figure10_PANet_architecture

Figure 10 – PANet Architecture. | Source

除了 FPN 之外,PANet 还有两个组件,可以生成增强的功能。自底向上的路径增强允许低级别特征被包括在预测中,第二个是 PANet 使用自适应特征池将 ROI 关联到每个级别。

空间不平衡

边界框有某些空间方面,包括并集上的交集(IoU)、形状、大小和位置。很明显,在现实世界的例子中,这些属性会不平衡,这会影响训练。

现在,我们将了解边界框的这些不同属性如何影响训练:

  1. 回归损失不平衡

对象检测网络中的回归损失通常用于收紧图像中对象的边界框。预测边界框和基础真值位置的微小变化都会导致回归损失的剧烈变化。因此,为回归选择一个稳定的损失函数来处理这种不平衡是非常重要的。

Figure11_L1,L2_loss_calc

Figure 11 – L1, L2 loss calculation for bounding boxes. The blue box represents ground truth and the rest are predictions. | Source

在图 11 中,我们可以观察到 L1 和 L2 损耗在相同 IoU 值下的不同表现。

  1. 欠条分配不平衡

当边界框的 IoU 分布(跨数据集)偏斜时,称为 IoU 分布不平衡。

Figure12_IoU_distribution

Figure 12 – This is IoU distribution of anchors on MS-COCO dataset in RetinaNet. | Source

IoU 分布也可以影响两级网络,例如,当在更快的 RCNN 的第二级中处理 IoU 分布不平衡时,它显示出显著的改善。

  1. 物体位置不平衡

我们使用遵循滑动窗口方法的卷积网络。每个窗口都分配有一定比例的锚点,赋予每个窗口同等的重要性。然而,跨图像的对象位置分布是不均匀的,从而导致不平衡。

Figure13_Object_location_distribution

Figure 13 – Above are the object location distribution for different datasets, starting from left; Pascal-Voc, MS-Coco, Open Images and Objects 365. | Source

我们可以在图 13 中看到,我们可以观察到数据集中的对象位置分布并不均匀,而是正态分布(高斯分布)。

解决空间失衡

下面就来逐一说说空间不平衡的三个不平衡的解决方案。

  1. 回归损失不平衡

某些损失函数有助于稳定回归损失。请看下表:

损失函数 说明

用于早期的深层物体探测器。对小错误稳定,但严重惩罚异常值。

|
| |

因微小误差而不稳定。

|
| |

基线回归损失函数。与 L1 的损失相比,对我们的员工来说更加稳健。

|
| |

与平滑 L1 损失相比,增加内点的贡献。

|
| |

基于 KL 散度预测关于输入包围盒的置信度。

|
| |

使用 IoU 的间接计算作为损失函数。

|
| |

固定 IoU 定义中输入框的所有参数,除了在反向传播过程中估计其梯度的参数。

|
| |

根据 IoU 输入的最小外接矩形扩展 IoU 的定义,然后直接使用 IoU 和扩展 IoU,称为 GIoU,作为损失函数。

|
| |

扩展了 IoU 的定义,增加了关于长宽比差和两个方框间中心距离的附加惩罚项。

|

在表中,我们可以看到不同的损失函数。我个人更喜欢平稳的 L1 损失。它很健壮,在大多数情况下都能很好地工作。

  1. 欠条分配不平衡

有些架构可以解决 IoU 分配不平衡的问题。

  1. 级联 RCNN——论文的作者在级联流水线中创建了三个具有不同 IoU 阈值的检测器。并且每个检测器使用来自前一级的盒而不是重新采样它们的事实表明,IoU 分布可以从左偏转变为均匀甚至右偏。
  2. 分级镜头检测器——网络法在回归盒子后运行其分类器,而不是使用级联管道。这使得 IoU 分布更加平衡。您可以在论文中阅读该架构的更多细节。
  3. IoU Uniform RCNN——这种架构通过向回归分支而不是分类分支提供统一边界框的方式增加了变量。

所有这些网络已被证明在处理 IoU 分布方面是有效的,提高了检测的整体性能。

3。物体位置不平衡

一个叫做导向锚定的概念在一定程度上处理了这个问题。这里,来自特征金字塔的每个特征图在到达预测层之前都通过锚定引导模块。导向锚定模块由两部分组成;锚生成部分预测锚形状和位置,特征适应部分将具有锚信息的新特征地图应用于由特征金字塔生成的原始特征地图。

Figure15_guided_anchoring_network

Figure 15 – Guided Anchoring Module. | Source

客观不平衡

正如我们之前讨论的,对于对象检测,有两个问题我们需要优化;分类和回归。现在,同时计算这两个问题的损失会带来一些问题:

  1. 由于梯度范围的差异,其中一个任务可以支配训练。
  2. 在不同任务中计算的损失范围的差异可以不同。例如,为回归而收敛的损失函数可能在 1 左右,而为分类而收敛的损失函数可能在 0.01 左右。
  3. 任务的难度可以不同。例如,对于某个数据集,达到分类收敛可能比回归更容易。

解决客观不平衡

  1. 卡尔

一种称为分类感知回归损失(CARL)的方法假设分类和回归是相关的。

LC= C[I]L1S

这里 L1S 是用作回归损失函数的平滑 L1 损失。ci 是基于由分类层计算的分类概率的分类因子。这样,回归损失提供了具有梯度信号的分类,从而部署了分类和回归之间的相关性。

  1. 引导损失

回归损失仅由前景实例组成,并且仅通过前景类别的数量进行归一化,这一事实可用作分类损失的归一化器。

引导损失通过将损失的总幅度考虑为–,对分类部分进行加权

wregLregLcls

一些有用的提示和技巧

正如我们之前所讨论的,类别不平衡是训练对象检测模型时最令人头疼的问题之一。除了改变损失函数和修改架构之外,我们可以使用一些常识和玩弄数据集来减少类的不平衡。在本节中,我们将尝试通过一些数据预处理来缓解这个问题。

让我们考虑一个带有地理数据的图像(如图 16 所示)。我们想要识别建筑物、树木、汽车等物体。图 16 中的图像是我们的对象检测网络的训练数据集中的图像之一。

Figure16_satellite_picture

Figure 16 – A Satellite picture consisting of buildings, canopy, river, cars, etc. | Source

这是一张高分辨率的卫星照片。现在我们要识别建筑物、汽车、树木等。然而,我们可以清楚地看到这幅画的大部分是由建筑物组成的。你会在几乎所有现实生活的数据集中看到巨大的阶级不平衡。那么我们如何解决这个问题呢?

Figure16_satellite_picture_zoom

Figure 17 – A zoomed-in picture from figure 16. | Source

首先,如果分辨率特别高,我们可以从中提取如图 17 所示的详细图像,然后尝试以下任何方法。

合并类

如果可能的话,合并相似的类。例如,如果我们在数据集中标注了“汽车”、“卡车”和“公共汽车”,将它们合并到“汽车”类别中会增加实例的数量(对于标签“汽车”)并减少类的数量。所有三个标签的平均像素直径几乎相同。

这是一个简单而通用的例子,但是理想情况下,这应该由具有领域知识的人来完成。

分割图像

您可以将高分辨率图像分成一定数量的小块,并使用每个小块作为检测模型的输入,而不是缩小高分辨率图像。这将有助于网络学习更小的物体。

虽然缩小会减少训练时间,但也会使小对象消失。切片数据集肯定会有所帮助。

Figure17_split_image_15

Figure 18 – Splitted high-resolution image, each tile in the grid can be used as an input for the object detection model. | Source

import cv2
from matplotlib.pyplot import plt

a, b = 8, 10

img = cv2.imread('image_path')
M = img.shape[0]//a
N = img.shape[1]//b
tiles = [img[x:x+M,y:y+N] for x in range(0,img.shape[0],M) for y in range(0,img.shape[1],N)]

plt.imshow(tiles[0])

你可以用这段简单的代码来分割你的图片。

欠采样和过采样

欠采样和过采样是处理类不平衡的最基本的方法。但以防万一,如果你有足够的时间和数据,你可以尝试这些东西。

欠采样

欠采样是指从过度表示的类中丢弃数据点。

现在您已经在图 18 中制作了图块。您可以丢弃仅包含建筑物的图块,这将平衡数据集中的其他对象,如天篷、汽车等。

Figure19_undersampling

Figure 19 – Under sampling. | Source: Author

缺点是,这可能会导致一个坏的模型。建筑物的概化程度较低,当您根据模型进行推断时,可能无法识别特定类型的建筑物。

过采样

在过采样中,你为代表性不足的类生成合成数据。在上一节中,我们已经看到了一个使用生成算法(如 GANs)的例子。

我们也可以通过简单地使用 CV 算法来进行过采样。例如,你有一个充满汽车的瓷砖,你扩大它,但旋转,垂直和水平翻转,改变对比度,添加包装,剪切图像等。

我们在 PyTorch 中有可用的转换,或者您可以只使用 OpenCV 来完成这样的任务。

Figure20_oversampling

Figure 20 – Over sampling. | Source: Author

过采样的缺点是,你的模型可能会过拟合你过采样的数据。

未决问题和正在进行的研究

深度学习网络中的不平衡所产生的问题是一个相当新的研究课题,随着网络越来越复杂,新的不平衡问题越来越频繁地被发现。

在回归损失不平衡中,我们看到了许多损失函数解决不同类型的问题,这仍然是一个开放的问题,人们正在努力将不同损失函数的所有优势整合为一个。

像这样需要额外工作的例子有很多。仍然没有一个统一的方法来处理所有不同的不平衡。不同架构的工作正在进行中。

好消息是有大量的资源可以阅读和解决这些不平衡。

进一步阅读

在 Keras 中实现宏观 F1 分数:注意事项

原文:https://web.archive.org/web/https://neptune.ai/blog/implementing-the-macro-f1-score-in-keras

作为 TensorFlow 2.0 生态系统的一部分, Keras 是用于训练和评估神经网络模型的最强大、但易于使用的深度学习框架之一。

当我们构建神经网络模型时,我们遵循与任何其他机器学习模型相同的模型生命周期步骤:

  • 用超参数构造和编译网络,
  • 适合网络,
  • 评估网络,
  • 使用最佳调整的模型进行预测。

具体来说,在网络评估步骤中,选择和定义适当的性能指标至关重要——本质上是判断您的模型性能的函数,包括宏 F1 分数

模型性能评估指标与损失函数

预测模型的建立过程只不过是连续的反馈循环。我们构建一个初始模型,接收来自性能指标的反馈,调整模型以进行改进,并进行迭代,直到获得我们想要的预测结果。

数据科学家,尤其是机器学习/预测建模实践的新手,经常混淆性能指标的概念和损失函数的概念。为什么在训练过程中,我们试图最大化给定的评估指标,如准确性,而算法本身试图最小化完全不同的损失函数,如交叉熵?对我来说,这是一个完全有效的问题!

在我看来,答案有两部分:

  1. 损失函数(如交叉熵)与评估度量(如准确性)相比,通常更容易优化,因为损失函数相对于模型参数是可微分的,而评估度量则不是;
  2. 评估指标主要依赖于我们试图解决的特定业务问题陈述,对于非技术利益相关者来说更容易理解。例如,当向 C 级主管展示我们的分类模型时,解释什么是熵是没有意义的,相反,我们要展示准确度或精确度。

这两点结合起来解释了为什么损失函数和性能度量通常在相反的方向上被优化。损失函数最小化,性能指标最大化。

尽管如此,我仍然认为我们试图优化的损失函数应该与我们最关心的评估指标相对应。你能想出一个损失函数等于性能指标的场景吗?回归模型的某些指标,如 MSE(均方误差),既可以作为损失函数,也可以作为性能指标!

不平衡分类问题的性能度量

对于分类问题,最基本的衡量标准是准确性——正确预测与数据中样本总数的比率。开发预测模型是为了实现高准确性,就好像它是判断分类模型性能的最终权威。

毫无疑问,对于具有平衡类分布的数据集(在二进制分类中大约为 50%),准确性是一个有效的度量。然而,当我们的数据集变得不平衡时,这是大多数现实世界业务问题的情况,准确性无法提供全貌。更糟糕的是,它可能会产生误导。

高精度并不表示少数类的预测能力高,少数类最有可能是感兴趣的类。如果这个概念听起来很陌生,你可以在关于准确性悖论精确回忆曲线的论文中找到很好的解释。

现在,不平衡数据集的理想性能指标是什么?由于正确识别少数类通常是我们的目标,召回/灵敏度、精确度、F 测量分数将是有用的,其中:

Keras metrics

清楚地了解了评估指标、它们与损失函数的区别以及哪些指标可用于不平衡数据集后,让我们简要回顾一下 Keras 中的指标规范。对于 Keras 中可用的指标,最简单的方法是在 model.compile() 方法中指定 "metrics" 参数:

Keras 2.0 以来,传统评估指标——F 分数、精确度和召回率——已经从即用列表中删除。用户必须自己定义这些指标。因此,作为处理神经网络中不平衡数据集的基础,我们将重点关注在 Keras 中实现 F1 分数度量,并讨论您应该做什么,以及不应该做什么。

用海王星跟踪神经网络模型实验

from keras import metrics
model.compile(loss='binary_crossentropy', optimizer='adam',
metrics=[metrics.categorical_accuracy])

在模型训练过程中,许多数据科学家(包括我自己)从 excel 电子表格或包含日志信息的文本文件开始,来跟踪我们的实验。这样我们可以看到什么有效,什么无效。这种方法没有错,尤其是考虑到它对我们繁琐的模型构建是多么的方便。然而,问题是这些笔记的结构并不有序。因此,当我们几年后试图回到它们时,我们不知道它们是什么意思。

幸运的是,海王星来救援。它跟踪并记录了我们模型训练过程中的几乎所有内容,从超参数规范到最佳模型保存,再到结果图等等。使用 Neptune 跟踪的实验的酷之处在于,它会自动生成性能图表,用于比较不同的运行,并选择最佳的运行。这是与您的团队共享模型和结果的一个很好的方式。

关于如何配置你的海王星环境和设置你的实验的更详细的解释,请查看这个完整的指南。它非常简单,所以我没有必要在这里介绍海王星初始化。

我将演示如何在 Keras F1 指标实现过程中利用 Neptune,并向您展示模型训练过程变得多么简单和直观。

你兴奋吗?我们开始吧!

创造海王星实验

首先,我们需要导入所有的包和函数:

现在,让我们在 Neptune 中专门为这个练习创建一个项目:

接下来,我们将创建一个连接到我们的 KerasMetricNeptune 项目的 Neptune 实验,以便我们可以在 Neptune 上记录和监控模型训练信息:

import neptune as neptune.new

import os
import pandas as pd
import numpy as np
from random import sample, seed
from collections import defaultdict

import seaborn as sns
import matplotlib.pyplot as plt

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, GridSearchCV, KFold, StratifiedKFold
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import f1_score, make_scorer, confusion_matrix, accuracy_score, precision_score, recall_score, precision_recall_curve

from tensorflow.keras import backend as K
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Input, Dense, Embedding, Concatenate, Flatten, BatchNormalization, Dropout, Reshape, Activation
from tensorflow.keras.callbacks import Callback, EarlyStopping, ModelCheckpoint

pd.options.display.max_columns = 100
np.set_printoptions(suppress=True)

os.chdir('PATH_TO_YOUR_WORK_DIRECTORY')

这里有两点需要注意:

neptune.init() 中的 api_token arg 取您在配置步骤中生成的 Neptune API

myProject = "YourUserName/YourProjectName"
project = neptune.init(api_token=os.getenv('NEPTUNE_API_TOKEN'),
                       project=myProject)
project.stop()

npt_exp = neptune.init(
        api_token=os.getenv('NEPTUNE_API_TOKEN'),
        project=myProject,
        name='step-by-step-implement-fscores',
        tags=['keras', 'classification', 'macro f-scores','neptune'])

neptune.init() 中的标签 arg 是可选的,但是最好为给定的项目指定标签,以便于共享和跟踪。

  • 随着 Neptune 项目—KerasMetricNeptune在我的演示中——以及成功创建的初始实验,我们可以继续进行建模部分。
  • 第一次尝试:自定义 F1 得分指标

根据 Keras 文档,用户可以在神经网络编译步骤传递自定义指标。听起来很容易,不是吗?我实现了一个度量函数 custom_f1 。它接受真实结果和预测结果作为参数:

数据集:信用卡欺诈检测

为了展示这个自定义指标函数是如何工作的,我将使用信用卡欺诈检测数据集作为例子。这是最受欢迎的不平衡数据集之一(更多细节在这里)。


def custom_f1(y_true, y_pred):
    def recall_m(y_true, y_pred):
        TP = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
        Positives = K.sum(K.round(K.clip(y_true, 0, 1)))

        recall = TP / (Positives+K.epsilon())
        return recall

    def precision_m(y_true, y_pred):
        TP = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
        Pred_Positives = K.sum(K.round(K.clip(y_pred, 0, 1)))

        precision = TP / (Pred_Positives+K.epsilon())
        return precision

    precision, recall = precision_m(y_true, y_pred), recall_m(y_true, y_pred)

    return 2*((precision*recall)/(precision+recall+K.epsilon()))

基本的探索性数据分析表明,0 级(99.83%)和 1 级(0.17%)存在极端的阶级不平衡:

出于演示目的,我将在我的神经网络模型中包括所有输入特征,并将 20%的数据保存为保留测试集:

使用神经网络的模型结构

credit_dat = pd.read_csv('creditcard.csv')

counts = credit_dat.Class.value_counts()
class0, class1 = round(counts[0]/sum(counts)*100, 2), round(counts[1]/sum(counts)*100, 2)
print(f'Class 0 = {class0}% and Class 1 = {class1}%')

sns.set(style="whitegrid")
ax = sns.countplot(x="Class", data=credit_dat)
for p in ax.patches:
    ax.annotate('{:.2f}%'.format(p.get_height()/len(credit_dat)*100), (p.get_x()+0.15, p.get_height()+1000))
ax.set(ylabel='Count',
       title='Credit Card Fraud Class Distribution')

npt_exp['Distribution'].upload(neptune.types.File.as_image(ax.get_figure()))

dat = credit_dat

在对数据进行预处理之后,我们现在可以进入建模部分。在这篇文章中,我将构建一个具有两个隐藏层的神经网络用于二进制分类(使用 sigmoid 作为输出层的激活函数):

def myformat(value, decimal=4):
    return str(round(value, decimal))

def Pre_proc(dat, current_test_size=0.2, current_seed=42):
    x_train, x_test, y_train, y_test = train_test_split(dat.iloc[:, 0:dat.shape[1]-1],
                                                        dat['Class'],
                                                        test_size=current_test_size,
                                                        random_state=current_seed)
    sc = StandardScaler()
    x_train = sc.fit_transform(x_train)
    x_test = sc.transform(x_test)

    y_train, y_test = np.array(y_train), np.array(y_test)
    return x_train, x_test, y_train, y_test

x_train, x_test, y_train, y_test = Pre_proc(dat)

使用自定义 F1 指标建模

接下来,我们使用交叉验证(CV)来训练模型。由于构建准确的模型超出了本文的范围,我设置了一个 5 重 CV,每个 CV 只有 20 个时期,以展示 F1 度量函数是如何工作的:

def runModel(x_tr, y_tr, x_val, y_val, epos=20, my_batch_size=112):

    inp = Input(shape = (x_tr.shape[1],))

    x = Dense(1024, activation='relu')(inp)
    x = Dropout(0.5)(x)
    x = BatchNormalization()(x)
    x = Dense(512, activation='relu')(x)
    x = Dropout(0.5)(x)
    x = BatchNormalization()(x)

    out = Dense(1, activation='sigmoid')(x)
    model = Model(inp, out)

    return model

几个注意事项:

预定义函数 custom_f1 在 model.compile 步骤中指定;

f1_cv, precision_cv, recall_cv = [], [], []

current_folds = 5
current_epochs = 20
current_batch_size = 112

kfold = StratifiedKFold(current_folds, random_state=42, shuffle=True)

for k_fold, (tr_inds, val_inds) in enumerate(kfold.split(X=x_train, y=y_train)):
    print('---- Starting fold %d ----'%(k_fold+1))

    x_tr, y_tr = x_train[tr_inds], y_train[tr_inds]
    x_val, y_val = x_train[val_inds], y_train[val_inds]

    model = runModel(x_tr, y_tr, x_val, y_val, epos=current_epochs)

    model.compile(loss='binary_crossentropy', optimizer= "adam", metrics=[custom_f1, 'accuracy'])

    for val in history.history['custom_f1']:
            npt_exp['Custom F1 metric'].log(val)

    model.fit(x_tr,
              y_tr,
              epochs=current_epochs,
              batch_size=current_batch_size,
              verbose=1)

    y_val_pred = model.predict(x_val)
    y_val_pred_cat = (np.asarray(y_val_pred)).round()

    f1, precision, recall = f1_score(y_val, y_val_pred_cat), precision_score(y_val, y_val_pred_cat), recall_score(y_val, y_val_pred_cat)

    metric_text = f'Fold {k_fold+1} f1 score = '

    npt_exp[metric_text] = myformat(f1)

    f1_cv.append(round(f1, 6))
    precision_cv.append(round(precision, 6))
    recall_cv.append(round(recall, 6))

metric_text_final = 'Mean f1 score through CV = '
npt_exp[metric_text_final] = myformat(np.mean(f1_cv))

我们从我们的训练实验中提取 f1 值,并使用 send_metric() 函数在 Neptune 上跟踪这些 f1 值;

  • 在每次折叠之后,计算性能指标,即 f1、精度和召回率,并因此使用 send_text() 函数发送到 Neptune
  • 当整个交叉验证完成时,通过取每个 CV 的 f1 分数的平均值来计算最终的 f1 分数。同样,这个值被发送到 Neptune 进行跟踪。
  • 在您启动模型后,您将立即看到 Neptune 开始跟踪训练过程,如下所示。因为还没有要记录的指标,所以在此阶段只显示 CPU 和内存信息:
  • 随着模型训练的进行,会记录更多的性能指标值。单击项目 ID 旁边的小眼睛图标,我们将启用交互式跟踪图表,显示每个训练迭代期间的 f1 值:

训练过程结束后,我们可以点击项目 ID 来查看 Neptune 自动存储的所有元数据。正如您在下面的视频中所看到的,该元数据包括每个折叠的 f1 分数,以及 5 个折叠 CV 的 f1 分数的平均值。在元数据之上,图表选项显示由我们的自定义度量函数为每个时期计算的 f1 值,即 5 倍* 20 个时期= 100 个 f1 值:

目前为止一切正常!然而,当我们检查 Neptune 上的详细日志记录时,我们注意到一些意想不到的事情。在训练期间计算的 F1 分数(例如,0.137)与为每个验证集计算的分数(例如,0.824)显著不同。这种趋势在图表中更加明显(在右下方),其中最大 F1 值约为 0.14。

为什么会这样?

使用回调来指定指标

深入研究这个问题,我们意识到 Keras 是通过批量创建自定义度量函数来进行计算的。每个度量在每个批次后应用,然后平均以获得特定时期的全局近似值。这个信息是误导性的,因为我们所监控的应该是每个时期的宏观训练表现。这就是为什么 Keras 2.0 版本中删除了这些指标。综上所述,实施宏观 F1 指标的正确方法是什么?答案是回调功能:

这里,我们定义了一个回调类 NeptuneMetrics 来计算和跟踪每个时期结束时的模型性能指标,也就是宏分数。

然后我们这样编译和拟合我们的模型:

class NeptuneMetrics(Callback):
    def __init__(self, neptune_experiment, validation, current_fold):
        super(NeptuneMetrics, self).__init__()
        self.exp = neptune_experiment
        self.validation = validation
        self.curFold = current_fold

    def on_train_begin(self, logs={}):
        self.val_f1s = []
        self.val_recalls = []
        self.val_precisions = []

    def on_epoch_end(self, epoch, logs={}):
        val_targ = self.validation[1]
        val_predict = (np.asarray(self.model.predict(self.validation[0]))).round()

        val_f1 = round(f1_score(val_targ, val_predict), 4)
        val_recall = round(recall_score(val_targ, val_predict), 4)
        val_precision = round(precision_score(val_targ, val_predict), 4)

        self.val_f1s.append(val_f1)
        self.val_recalls.append(val_recall)
        self.val_precisions.append(val_precision)

        print(f' — val_f1: {val_f1} — val_precision: {val_precision}, — val_recall: {val_recall}')

	    self.exp['Epoch End Loss'].log(logs['loss'])
        self.exp['Epoch End F1-score'].log(val_f1)
        self.exp['Epoch End Precision'].log(val_precision)
        self.exp['Epoch End Recall'].log(val_recall)

        if self.curFold == 4:

            msg = f' End of epoch {epoch} val_f1: {val_f1} — val_precision: {val_precision}, — val_recall: {val_recall}'

            self.exp[f'Epoch End Metrics (each step) for fold {self.curFold}'] = msg

现在,如果我们重新运行 CV 训练,Neptune 将自动创建一个新的模型跟踪–在我们的示例中为 KER1-9–以便于比较(不同实验之间):

与之前一样,在训练发生时检查由新回调方法生成的详细日志记录,我们观察到我们的 NeptuneMetrics 对象为训练过程和验证生成一致的 F1 分数(大约 0.7-0.9),如 Neptune 视频剪辑所示:

model.compile(loss='binary_crossentropy', optimizer= "adam", metrics=[])
model.fit(x_tr,
          y_tr,
          callbacks=[NeptuneMetrics(npt_exp, validation=(x_val, y_val), current_fold=k_fold)],  
          epochs=current_epochs,
          batch_size=current_batch_size,
          verbose=1)

完成模型训练后,让我们检查并确认在最后一个 CV 文件夹的每个(时期)步骤中记录的性能指标符合预期:

太好了!一切看起来都在合理的范围内。

让我们比较一下我们刚刚试验的这两种方法之间的区别,即自定义 F1 指标与 NeptuneMetrics 回调:

我们可以清楚地看到,自定义 F1 指标(左边)实现是不正确的,而 NeptuneMetrics 回调实现是理想的方法!

现在,最后一次检查。使用回调方法预测测试集给我们提供了 F1 分数= 0.8125,这与训练相当接近:

最后的想法

你有它!在您的神经网络模型中计算和监控 F1 分数的正确和不正确方法。如果你感兴趣的话,相似的过程可以应用于召回和精确。我希望这篇博客对你有所帮助。完整的代码可以在这个 Github repo 中找到,整个 Neptune 模型可以在这里找到。

def predict(x_test):
    model_num = len(models)
    for k, m in enumerate(models):
        if k==0:
            y_pred = m.predict(x_test, batch_size=current_batch_size)
        else:
            y_pred += m.predict(x_test, batch_size=current_batch_size)

    y_pred = y_pred / model_num

    return y_pred

y_test_pred_cat = predict(x_test).round()

cm = confusion_matrix(y_test, y_test_pred_cat)
f1_final = round(f1_score(y_test, y_test_pred_cat), 4)

npt_exp['TestSet F1 score'] = myformat(f1_final)

from scikitplot.metrics import plot_confusion_matrix
fig_confmat, ax = plt.subplots(figsize=(12, 10))
plot_confusion_matrix(y_test, y_test_pred_cat.astype(int).flatten(), ax=ax)

npt_exp['Confusion Matrix'].upload(neptune.types.File.as_image(fig_confmat))
npt_exp.stop()

在我让你走之前,这个 NeptuneMetrics 回调计算 F1 分数,但这并不意味着模型是在 F1 分数上训练的。为了基于优化 F1 分数进行“训练”,这有时是处理不平衡分类的首选,我们需要额外的模型/回调配置。请继续关注我的下一篇文章,在那里我将讨论 F1 分数调整和阈值移动。感谢阅读!

There you have it! The correct and incorrect ways to calculate and monitor the F1 score in your neural network models. Similar procedures can be applied for recall and precision if it’s your measure of interest. I hope that you find this blog helpful. The full code is available in this Github repo, and the entire Neptune model can be found here.

Before I let you go, this NeptuneMetrics callback calculates the F1 score, but it doesn’t mean that the model is trained on the F1 score. In order to ‘train’ based on optimizing the F1 score, which sometimes is preferred for handling imbalanced classification, we need additional model/callback configurations. Stay tuned for my next article, where I will be discussing F1 score tuning and threshold-moving. Thanks for reading!

改善机器学习和深度学习模型的最佳实践

原文:https://web.archive.org/web/https://neptune.ai/blog/improving-machine-learning-deep-learning-models

机器学习和深度学习模型在现代组织中,我们身边无处不在。随着新算法、更便宜的计算和更大的数据可用性的快速发展,人工智能用例的数量一直在呈指数增长。每个行业都有适当的机器学习和深度学习应用,从银行到医疗保健到教育到制造、建筑等等。

在不同行业的所有这些 ML 和 DL 项目中,最大的挑战之一是模型改进。因此,在本文中,我们将探索如何改进建立在结构化数据(时间序列、分类数据、表格数据)上的机器学习模型和建立在非结构化数据(文本、图像、音频、视频或多模态)上的深度学习模型。

改进 ML / DL 模型的策略

在这一点上,在商业中实现 ML 和 DL 应用程序仍处于早期阶段,没有单一的结构化过程可以保证成功。然而,有一些最佳实践可以将人工智能项目失败的可能性降至最低[ 1、、 2、、 3

成功的关键之一是模型的准确性和性能。模型性能主要是一个技术因素,对于许多机器学习和深度学习用例来说,如果模型对于给定的业务用例来说不够准确,部署就没有意义。

工厂 例子

什么是业务用例?

| |
|

业务指标有哪些?

| |
|

技术指标有哪些?

| |
|

正在使用哪种数据?

|

结构化–数字、分类、临时或非结构化–图像、文本、音频、视频

|
|

什么是机器学习问题公式化?

|

回归、分类——多类或多标签、聚类

|
|

有哪些相关的 ML 和 DL 型号?

| |
|

需要考虑哪些超参数优化技术?

| |
| | |

表 1。控制机器/深度学习模型改进范围的因素列表

在改进现有的机器学习和深度学习模型的背景下,没有可以一致应用的一刀切的策略。我将回顾一组指导方针和最佳实践,可以对它们进行评估,以系统地识别提高准确性和模型性能的潜在来源。

上面的表 1 显示了在开始调试和改进 ML 和 DL 模型之前应该考虑的一组高级因素。它强调了商业和技术约束下的一系列关键因素,在这些因素中,机器学习或深度学习模型必须得到改进。

例如,预测新零售银行客户信用评级的机器学习模型也应该能够在信用卡申请被拒绝的情况下解释其决定。在这里,如果模型不能为客户理解和提高他们的信用评分提供解释和指导,仅仅为技术指标进行优化是不够的。

为了清晰起见,在本文中,我假设您的机器学习或深度学习模型已经在特定业务用例的内部数据上进行了训练,挑战是在相同的测试集上提高模型性能,以满足所需的验收标准。

我们将探索几种提高模型性能的方法,因此您肯定会找到一两种与您的用例相关的方法。最终,在各种模型上工作的实践和经验会使我们对提高模型准确性的最佳方法有更好的直觉,并使这些技术优先于其他技术。

初步分析

改进机器学习模型的第一步是在业务用例的上下文中仔细检查模型的潜在假设,并评估当前模型的性能。

(1)回顾关于数据集和算法选择的初始假设

在一个理想的场景中,任何机器学习建模或算法工作之前都要仔细分析手头的问题,包括用例的精确定义以及优化[ 1 ]的业务和技术指标。

一旦构建机器学习或深度学习模型的激动人心的阶段开始,就很容易忽视预定义的数据注释指南、数据集创建策略、指标和成功标准。然而,记住更大的图景有利于简化和优先化改进机器学习和深度学习模型的迭代过程。

(2)模型是过拟合还是欠拟合?

通过将模型预测误差绘制为模型复杂性或时期数的函数,这可以在下面的图 1 中可视化。训练和测试误差曲线之间的差异示出了过度拟合,即高方差和低偏差,或者欠拟合,即高偏差和低方差,并且提供了理解机器学习模型的当前状态的有用代理。

如果模型过度拟合,可以通过以下方式进行改进:

  • 使用更多的训练数据,
  • 降低模型的复杂性,
  • 正则化方法包括脊和套索正则化,
  • 辍学,
  • 提前停止

如果模型拟合不足,可以通过使模型更复杂来解决,即添加更多的特征或层,并为更多的时期训练模型。

Overfitting underfitting

Figure 1. Overfitting vs. Underfitting | Source

(3)模型制作存在何种错误?

对于一个典型的分类问题,这可以使用类似混淆矩阵的图来可视化,该图说明了类型 1(假阳性)和类型 2(假阴性)错误的比例。图 2 显示了一个典型的二元分类问题的混淆矩阵。在这个例子中,我们有 15 个真阳性,12 个假阳性,118 个真阴性,47 个假阴性。所以:

  • 精度= 15/(15+12) = 15/27 = 0.56
  • 回忆= 15/(15+47) = 15/62 = 0.24
  • f1-得分= 2 * 0.56 * 0.34 / (0.56 + 0.34) = 0.42

这里,精度和召回率都较低,根据接受标准,有足够的空间来提高这两者。根据业务用例及领域的不同,与精确度相比,关注提高召回率可能更有意义。这适用于医疗保健、金融和教育等领域的几个机器学习问题。

ML models errors

*Figure 2. Illustration of Type 1 and Type 2 errors made by machine learning models. *

图 3 显示了多类分类问题的另一个代表性混淆矩阵,这是行业应用中的一个常见用例。乍一看,可以清楚地看到,该模型混淆了 1-5 类和 0 类,并且在某些情况下,它预测 0 类的频率高于真实类。这表明模型中存在系统误差,很可能与 0 类有关。

有了这种认识,改进该模型的第一步将是检查标记的训练示例的潜在注释错误,或者属于类 0 与类 1-5 的示例之间的相似度。这种错误分析可能会显示相关的证据,比如来自特定注释者的标签被系统地错误标记,从而导致相应类或类别之间的高混淆率。

ML models confusion marix

Figure 3. Normalized confusion matrix for a multi-class classification problem | Source

模型优化

在对模型准确性进行初步分析和评估、可视化关键指标以诊断错误之后,您应该看看是否可以通过使用一组不同的超参数对当前模型进行重新训练来从当前模型中提取额外的性能。

训练的机器学习或深度学习模型的假设是,当前的模型权重和偏差集对应于凸优化过程中的局部最小值。梯度下降应该理想地产生对应于最优模型权重集的全局最小值。

然而,梯度下降是一个随机过程,它作为几个参数的函数而变化,这些参数包括如何初始化权重、学习率时间表、训练时期的数量、用于防止过拟合的任何正则化方法以及特定于训练过程和模型本身的一系列其他超参数。

每个机器学习和深度学习模型都基于独特的算法和内在参数。机器学习的目标是从数据中学习逼近复杂非线性函数的最佳权重集。通常情况下,第一个训练模型是次优的,找到超参数的最佳组合可以获得额外的准确性。

超参数调整包括训练模型的不同版本,每个版本都在不同的超参数组合上进行训练。通常,对于较小的机器学习模型,这是一个快速的过程,有助于以最高的准确性识别模型。对于包括深度神经网络在内的更复杂的模型,对超参数值的不同组合运行同一模型的多次迭代可能是不可行的。在这种情况下,谨慎的做法是根据先验知识或现有文献限制单个超参数值的范围和选择,以找到最佳模型。

最常用的三种超参数调整方法是:

(1)网格搜索

网格搜索是一种常见的超参数优化方法,它通过评估所有可能的组合来找到一组最佳的超参数。当预先知道相关超参数的最佳范围时,这是最有用的,无论是基于经验实验、以前的工作还是出版的文献。

例如,如果您已经确定了 6 个关键超参数和特定范围内每个超参数的 5 个可能值,那么网格搜索将为每个超参数的唯一组合评估 5 * 6 = 30 个不同的模型。这确保我们关于超参数范围的先验知识被捕获到模型评估的有限集合中。

这种方法的缺点是计算量大,并且只从高维超参数网格中定义明确的空间采样。因此,如图 4 所示,更有可能错过与预定义范围之外的最佳超参数值相关的局部最小值。为了减轻网格搜索的这些限制,建议使用随机搜索。

(2)随机搜索

随机搜索本质上涉及对超参数值进行随机采样,并且更善于识别最佳超参数值,人们可能对[4没有强有力的假设。随机采样过程效率更高,通常会基于更少的模型迭代返回一组最佳值。所以随机搜索在很多情况下是超参数优化的首选。

Grid search vs random search

Figure 4. A comparison of Grid search and Random search | Source

(3)贝叶斯搜索

贝叶斯搜索是一种基于贝叶斯定理[ 5 ]的复杂超参数优化方法。它的工作原理是建立一个目标函数的概率模型,称为代理函数,然后在选择候选样本对真实目标函数进行评估之前,使用获取函数对其进行有效搜索。贝叶斯优化通常能够产生比随机搜索更优的解决方案,如图 5 所示,并用于应用机器学习,以调整验证数据集上给定的良好表现模型的超参数。

Random search vs bayesian search

Figure 5. A comparison of Random search and Bayesian search | Source

模型和算法

(1)建立强大的基线模型

为了改善你的机器学习或深度学习模型,建立一个强大的基线模型很重要。一个好的基线模型包含所有的业务和技术需求,测试数据工程和模型部署管道,并作为后续模型开发的基准。

基线模型的选择受到特定应用程序、数据集种类和业务领域的影响。例如,对于来自金融领域的时间序列数据的预测应用程序,XGBoost 模型是一个强基线模型。事实上,对于一些基于回归和分类的应用,梯度推进决策树通常用于生产。因此,从一个已知在生产环境中产生稳定性能的模型开始是有意义的。

对于图像、文本、音频、视频等非结构化数据,深度学习模型通常用于对象分类、图像分割、情感分析、聊天机器人、语音识别、情感识别等应用。鉴于深度学习模型的最新性能的快速发展,使用比旧模型更复杂的模型是谨慎的。例如,对于对象分类,像 VGG-16 或 ResNet-50 这样的深度卷积网络模型应该是基线,而不是单层卷积神经网络。例如,对于来自安全领域的 CCTV 图像数据的人脸识别应用程序,ResNet-50 是一个强有力的基准竞争者。

(2)使用预先训练的模型和云 API

在某些情况下,您可以通过评估预先训练的模型来节省宝贵的时间和精力,而不是自己训练基线模型。有各种各样的来源,如 Github,Kaggle,或来自云公司的 API,如 AWS,Google Cloud,Microsoft Azure,专门的初创公司,如 Scale AI,Hugging Face,Primer.ai 等。

使用预训练模型或 API 的优势在于易于使用、评估速度更快,以及节省时间和资源。然而,一个重要的警告是,这种预训练的模型通常不直接适用于您的用例,不太灵活,并且难以定制。

然而,使用迁移学习,预训练的模型可以应用于您的用例,而不是重新训练复杂的模型,而是在您的特定数据集上微调模型权重。例如,可以利用像 ResNet-50 这样的对象分类模型的内在知识,针对 ImageNet 数据集中的几个图像类别进行训练,以加速定制数据集和用例的模型开发。

API 可用于许多用例,如预测、欺诈、搜索、用于处理文档的光学字符识别、个性化、用于客户服务的聊天和语音机器人,以及其他应用。

(3)尝试自动 ML

虽然预先训练的模型很容易获得,但您也可以研究最先进的 AutoML 技术,以创建定制的机器学习和深度学习模型。对于组织知识和资源有限的公司来说,AutoML 是一个很好的解决方案,可以大规模部署机器学习来满足他们的业务需求。

AutoML 解决方案由 Google Cloud Platform [ 7 ]等云服务以及 H2O.ai 等许多小众公司和初创公司提供。AutoML 的承诺尚未规模化,但它代表了一个令人兴奋的机会,可以为您的用例快速构建和原型化基线机器学习或深度学习模型,并快速跟踪模型开发和部署生命周期。

(4)模型改进

算法和基于模型的改进需要更多的技术专长、直觉和对业务用例的理解。鉴于结合了上述所有技能的数据科学家的供应有限,大多数企业投入大量资源并为创新的机器学习和深度学习研发分配必要的时间和带宽并不常见。

由于大多数业务用例以及组织数据生态系统都是独特的,因此一刀切的策略通常是不可行的,也是不可取的。这就需要原创作品来适应现有的或相关的应用程序,以满足企业的特殊需求。

模型改进可以来自不同的来源:

  • 机器学习或深度学习模型的选择
  • 如上所述的超参数调谐
  • 自定义损失函数,根据业务需求确定指标的优先级
  • 模型的集合,以结合单个模型的相对优势
  • 超越 ReLu 等标准优化器的新型优化器

(5)案例研究:从伯特到罗伯塔

在这一节中,我将描述一个自然语言处理的最新深度学习模型的大规模模型改进的案例研究。[由谷歌 8 ]于 2018 年开发的 BERT ,已经成为一系列自然语言处理应用中事实上的深度学习模型,并全面加速了自然语言处理的研究和用例。它在 GLUE 等基准测试中取得了最先进的性能,这些基准测试在一系列模拟人类语言理解的任务上评估模型。

然而,BERT 在 GLUE 排行榜上的榜首位置很快被脸书·AI 开发的 RoBERTa 取代,这从根本上说是进一步优化 BERT 模型的一次练习,正如其全名——稳健优化的 BERT 预训练方法[ 9 ]所示。

RoBERTA 在简单修改的基础上,在性能方面超过了 BERT,这些修改包括为更多时期训练模型,向模型提供更多数据,以更大的批量在不同数据(更长的序列)上训练模型,以及优化模型和设计选择。这些简单的模型改进技术将 GLUE 基准上的模型分数从 BERT 的 80.5%提高到 RoBERTa 的 88.5%,这是一个非常显著的结果。

数据

在前面的章节中,我讨论了超参数优化和选择模型改进策略。在这一节中,我将描述关注数据对提高机器学习和深度学习模型的性能的重要性。在业务中,通常情况下,提高训练数据的质量和数量会产生更强的模型性能。机器学习和深度学习模型改进的以数据为中心的方法有几种技术。

(1)数据扩充

缺乏黄金标准的标注训练数据是开发和改进大规模监督机器学习和深度学习模型的常见瓶颈。时间、费用和主题专业知识方面的标注成本是创建大规模标记训练数据集的限制因素。通常情况下,机器学习模型会遭受过度拟合,并且可以通过使用更多的训练数据来提高它们的性能。

可以利用数据扩充技术以可扩展的方式扩展训练数据集。数据扩充技术的选择取决于数据的种类。例如,合成时间序列数据可以通过从生成模型或概率分布中采样来创建,该生成模型或概率分布在汇总统计方面类似于观察到的数据。可以通过改变图像特征,如亮度、颜色、色调、方向、裁剪等来增强图像。

可以通过多种方法扩充文本,包括正则表达式模式、模板、同义词和反义词替换、回译、释义生成或使用语言模型生成文本。

音频数据可以通过修改基本声学属性来扩充,如音调、音色、响度、空间位置和其他频谱时间特征。对于特定的应用,预训练模型也可以用于扩展原始训练数据集。

基于弱监督、半监督学习、学生-教师学习和自我监督学习的最新方法也可以用来生成带有噪声标签的训练数据。这些方法基于以下前提:用未标记或有噪声的标记数据增加黄金标准的标记数据,可以显著提高模型性能。现在有可能利用基于规则和基于模型的数据增强技术的组合,这些技术可以使用数据增强平台(如浮潜[ 10 )进行大规模设计。

模型表现不佳的另一个常见场景是在兴趣类别中不平衡的数据的情况下。在这种具有偏斜数据分布的情况下,数据的上采样和下采样以及 SMOTE 等技术有助于校正建模结果。

拥有训练数据集、验证数据集和测试数据集的概念在机器学习研究中很常见。交叉验证有助于打乱这三个数据集的确切组成,以便可以对模型性能做出统计上稳健的推断。

虽然传统方法侧重于具有单个验证数据集的三个数据集,但最好具有两个不同的验证数据集,一个来自与训练数据相同的分布,另一个来自与测试数据相同的分布。这样,您可以更好地诊断偏差-方差权衡,并使用如上所述的一组正确的模型改进策略。

(2)特征工程与选择

典型的机器学习模型是在具有许多特征的数据上训练的。改进机器学习模型的另一种常见技术是设计新的特征,并选择一组最佳特征来更好地改进模型性能。特征工程需要大量领域专业知识来设计新特征,这些新特征捕捉机器学习模型正在学习逼近的复杂非线性函数的各方面。因此,如果基线模型已经捕获了一组不同的特征,这种方法并不总是可行的。

通过编程方法进行特征选择有助于移除一些对模型性能没有太大贡献的相关或冗余特征。用逐渐增加的特征集合迭代地建立和评估模型的方法,或者从用整个特征集合训练的模型中一次迭代地减少一个特征的方法,有助于识别鲁棒特征。

(3)主动学习

对模型误差的分析可以揭示机器学习模型所犯的那种错误。回顾这些错误有助于理解是否有任何特征模式可以通过上述一些技术来解决。

此外,一旦模型已经投入生产,专注于更接近决策边界的模型错误的主动学习方法可以提供性能的显著提升。在主动学习中,模型混淆和预测错误的新示例被发送给提供正确标签的领域专家进行标注。这个由专家审阅和注释的数据集被合并回训练数据集中,以帮助重新训练的模型从其先前的错误中学习。

结论

机器学习和深度学习建模需要大量的主题专业知识,访问高质量的标记数据,以及用于持续模型训练和细化的计算资源。

改进机器学习模型是一门艺术,可以通过系统地解决当前模型的缺陷来完善。在本文中,我回顾了一组方法,这些方法集中于模型、它们的超参数和底层数据,以改进和更新模型,从而达到成功部署所需的性能水平。

参考

安装 MuJoCo 以在 OpenAI 健身房环境中工作

原文:https://web.archive.org/web/https://neptune.ai/blog/installing-mujoco-to-work-with-openai-gym-environments

在本文中,我将向您展示如何在 Mac/Linux 机器上安装 MuJoCo,以便从 OpenAI 的 Gym 运行连续控制环境。这些环境包括像 HalfCheetah、Hopper、Walker、Ant 和 Humanoid 这样的经典环境,以及像用机械臂或机械手灵巧操作物体这样的较难的环境。我还将讨论环境提供的其他代理诊断,这些诊断您以前可能没有考虑过。

你怎么得到 MuJoCo?

你可能会想,安装 MuJoCo 有什么特别的地方需要指南?嗯,获得许可证并正确安装它可能相对容易,但当你匹配 MuJoCo 和 OpenAI Gym 版本,并安装 mujoco-py 包时,大问题就开始了。我第一次尝试花了好几个小时才把它做好!

为了省去你的麻烦,我会一步一步地引导你完成安装过程。然后,我将讨论一些需要关注的有用的诊断,我们将看看来自人形训练的诊断示例。最后,我将链接代码,让您在 MuJoCo 任务上训练代理,并使用 Neptune 观察诊断。首先,我会给你一些关于 MuJoCo 和 OpenAI 健身房环境的背景。

MuJoCo 是一个快速而精确的物理模拟引擎,旨在研究和开发机器人、生物力学、图形和动画。这是一个引擎,这意味着,它不提供现成的模型或环境来工作,而是运行环境(就像 OpenAI 的健身房提供的那些)。

什么是 OpenAI 健身房?

OpenAI Gym(或简称 Gym)是一个环境的集合。其中一些被称为连续控制,运行在 MuJoCo 引擎上。所有环境都有两个重要特征:

  1. 代理观察描述受控机器人运动特性的向量。这意味着状态空间是连续的。
  2. 代理动作也是向量,它们指定了应用在机器人关节上的扭矩。这意味着动作空间也是连续的

健身房 MuJoCo 环境包括经典的连续控制、用机械臂操纵物体和机器人手(影子手)的灵活性。在这些环境中,有多种任务可供培训。下图显示了其中一些。你可以在健身房环境列表中找到所有这些的详细信息。这个帖子对机器人手臂和机器人手环境特别有用。如果你还不知道 Gym API,我鼓励你阅读文档—“环境”和“观察”这两个简短的部分应该足够开始了。

经典连续控制——任务从左到右:Walker2d,And,and Humanoid。
来源:
OpenAI Roboschool

影子手的灵巧性——手操纵积木的任务。
来源:
OpenAI 健身房机器人

安装 MuJoCo 和 OpenAI 健身房

在这一节中,我将向您展示从哪里获得 MuJoCo 许可证,如何安装所有需要的东西,以及如何解决一个常见的 macOS 问题。

许可证

你可以在 MuJoCo 网站 上获得 30 天的免费试用,或者——如果你是学生——获得一年的免费教育许可。许可证密钥将通过电子邮件发送给您,其中包含您的用户名和密码。如果你不是学生,你可以试着鼓励你工作的机构购买许可证。

安装 mujoco-py

以下是逐步说明,下面我添加了一些解释和故障排除提示:

  1. 下载适用于 LinuxmacOS 的 MuJoCo 版本 1.50 二进制文件。
  2. 将下载的mjpro150目录解压到~/.mujoco/mjpro150,并将您的许可证密钥(您电子邮件中的mjkey.txt文件)放在~/.mujoco/mjkey.txt.
  3. 运行pip3 install -U 'mujoco-py<1.50.2,>=1.50.1'
  4. 运行python3 -c 'import mujoco_py'

如果您看到类似于“objc[…]:Class GLFW…在两者中都实现了…”的警告,请忽略它们。如果你在 macOS 上看到“clang:error:unsupported option '-fopenmp '”或任何其他与编译相关的错误,那么转到故障排除小节。如果你想知道为什么 MuJoCo 1.5,那么去版本小节。如果你没有更多的顾虑,那么你可以跳进健身房安装!

解决纷争

如果在 macOS 上,“clang:error:unsupported option '-fopenmp '”错误或任何其他与编译器(例如 gcc,如果您安装了一个)相关的错误在安装或运行python3 -c ‘import mujoco_py’期间发生,请遵循以下步骤:

1.如果还没有安装 brew

2.卸载所有其他编译器,如果你有一些,例如运行brew uninstall gcc。如果您有多个版本,可能需要运行几次。

3.运行brew install llvm boost hdf5

4.将此添加到您的.bashrc / .zshrc

export PATH="/usr/local/opt/llvm/bin:$PATH"
export CC="/usr/local/opt/llvm/bin/clang"
export CXX="/usr/local/opt/llvm/bin/clang++"
export CXX11="/usr/local/opt/llvm/bin/clang++"
export CXX14="/usr/local/opt/llvm/bin/clang++"
export CXX17="/usr/local/opt/llvm/bin/clang++"
export CXX1X="/usr/local/opt/llvm/bin/clang++"
export LDFLAGS="-L/usr/local/opt/llvm/lib"
export CPPFLAGS="-I/usr/local/opt/llvm/include"

5.在编辑完之后,不要忘记对您的.bashrc / .zshrc(例如,重新启动您的 cmd)进行源代码处理,并确保您的 python 环境已被激活。

6.尝试卸载并再次安装 mujoco-py。

更多信息见本 GitHub 问题。你也应该看到 mujoco-py 自述故障排除部分。

版本

在这里,我们遇到了第一个陷阱!最新的 OpenAI 健身房与 MuJoCo 2.0 不兼容,如果你想了解详情,请参见本期 GitHub。这就是你需要下载 MuJoCo 版二进制文件的原因。或者,如果你真的需要使用 MuJoCo 2.0,可以下载 Linux 或者 OSX 的 MuJoCo 2.0 二进制文件,安装最新的 mujoco-py,然后安装最后一个支持 MuJoCo 2.0 的健身房:pip install -U gym[all]==0.15.3

安装 OpenAI 健身房环境(教程)

在这里,重要的是安装带有“mujoco”和“robotics”附加组件的 OpenAI Gym 包,或者简单地安装所有附加组件:

  1. 运行pip3 install gym[mujoco,robotics]pip3 install gym[all]
  2. 通过运行以下命令检查安装:
python3 -c "import gym; env = gym.make('Humanoid-v2'); print('nIt is OKAY!' if env.reset() is not None else 'nSome problem here...')"

如果你看到“没关系!”印在 cmd 的最后,那就没事了!同样,您可以忽略类似“objc[…]: Class GLFW…在两个…中实现”的警告。

穆乔科诊断公司

现在,我将讨论由 OpenAI Gym MuJoCo 环境提供的有用指标。它们依赖于环境版本,所以我将它们分为 v2 和 v3 诊断。您可以在环境步骤方法提供的“info”字典中访问这些指标:observation、reward、done、 info = env.step(action)。详见健身房文档下表提供了允许您访问字典中的指标和指标简短描述的关键字

名字 版本 钥匙 描述

正向奖励机器人前进速度。

对机器人动作向量幅度的负奖励。

|
| | | |

在 X 轴的位置。

X 轴上的速度(前进速度)。

|
| | | |

在 X 轴的位置。

X 轴上的速度(前进速度)。

|
| | | |

在 X 轴的位置。

X 轴上的速度(前进速度)。

|
| | |

奖励 _ 转发

奖励 _ 控制

奖励 _ 联系

奖励 _ 生存

| 对机器人前进速度的正向奖励。 |
| |

x _ 位置

x _ 速度

y _ 位置

y _ 速度

距离 _ 起点

| x _ 位置 | X 轴上的位置。 |
| |

奖励 _linvel

奖励 _ quad ctrl

奖励 _ 影响

奖励 _ 活着

| 奖励 _ 林维尔 | 机器人动作向量幅度的负奖励。 |
|

x _ 位置

x _ 速度

y _ 位置

y _ 速度

距离 _ 起点

| x _ 位置 | x _ 速度 | X 轴的速度。 |

奖励成分可能特别有用,例如,前进速度奖励——这是这些任务的目标。然而,请注意,信息字典中缺少一些度量并不意味着,比如说,生存奖励没有加到霍普或沃克的奖励中——它加了!对于像这样的更多细节,我鼓励你在 GitHub 上查看特定任务的代码,例如 Walker2d-v3

现在,让我们来看看人形任务的示例度量值。

人形诊断学

上图比较了三种不同 DRL 算法的速度: SACSOPSUNRISE 。绘制了完全训练过的特工在事件的不同点的速度。您可以看到 SOP 代理运行最快,这是该任务的目标。在下图中,我们调查了 SAC 代理在不同训练阶段每集结束时的位置。

你可以看到这个特殊的 SAC 代理在负 X 和正 Y 方向上运行,随着训练它会越来越远。因为它在一集结束前的时间保持不变,这意味着它通过训练学会了跑得更快。请注意,代理没有被训练为向任何特定方向运行。它被训练成朝任何方向尽可能快地向前跑。这意味着不同的代理可以学习向不同的方向运行。此外,代理可以在训练的某个时间点改变跑步方向,如下图所示。

Humanoid velocity

Comparison of velocities of three different DRL algorithms: SAC, SOP, and SUNR

结论

MuJoCo logs_AverageXPosition-2

SAC final positions in the X-axis across training on the Humanoid task. Neptune experiment.

MuJoCo logs_AverageYPosition-2

SAC final positions in the Y-axis across training on the Humanoid task. Neptune experiment.

恭喜你,你让 MuJoCo 开始运行了!现在,您会对在这些环境中培训代理感兴趣——查看这个库。它包括一个简单易懂的代码 DRL 算法在现代 TF2 实施。这段代码基于新人友好的 SpinningUp 代码库。而且,包含了登录 Neptune.ai 平台的功能,非常方便存储和分析训练结果!我在我的研究中使用它,你也必须试一试,特别是他们发布了他们的新的、惊人的 API

MuCoJo logs_AverageXPosition-3

SAC final positions in the X-axis across training on the Humanoid task. It changes the run direction in one-third of training. Neptune experiment.

MuJoCo logs_AverageYPosition-3

SAC final positions in the Y-axis across training on the Humanoid task. It changes the run direction late in the training. Neptune experiment.

Conclusions

Congratulations, you’ve got MuJoCo up and running! Now you’ll be interested in training agents in these environments—check out this repository. It includes an easy-to-understand code of DRL algorithms implemented in modern TF2. This code is based on the newcomer-friendly SpinningUp codebase. Moreover, it includes the ability to log into the Neptune.ai platform, which is very convenient to store and analyze the training results! I use it in my research and you have to give it a try too, especially that they shipped their new, amazing API.

安装 tensor flow 2 GPU[分步指南]

原文:https://web.archive.org/web/https://neptune.ai/blog/installing-tensorflow-2-gpu-guide

Tensorflow 是最常用的深度学习框架之一。它可以说是网络上最受欢迎的机器学习平台,拥有广泛的用户,从刚刚起步的人到寻求职业和业务优势的人。

并不是所有用户都知道,如果你的硬件支持的话,可以安装 TensorFlow GPU。我们将讨论什么是 Tensorflow,它在当今世界的使用情况,以及如何在 Windows、Mac 和 Linux 中安装支持 CUDA、cudNN 和 GPU 的最新 TensorFlow 版本。

张量流简介

TensorFlow 是一个用于机器学习的开源软件库,由 Google 创建。它最初于 2015 年 11 月 28 日发布,现在被用于许多领域,包括科学和工程研究。

TensorFlow 背后的想法是让训练使用各种数学模型的深度神经网络变得快速简单。这些网络能够在没有人工干预或监督的情况下从数据中学习,这使它们比传统方法更有效。该库还支持在使用不同操作系统和 GPU 的多台机器上同时进行处理。

TensorFlow 应用

TensorFlow 是谷歌建立的深度学习库,自去年年初推出以来,它已经获得了很多关注。主要功能包括自动微分、卷积神经网络(CNN)和递归神经网络(RNN)。它是用 C++和 Python 编写的,为了获得高性能,它使用了一个运行在谷歌云平台上的名为“云张量流”的服务器。它不需要 GPU,这是它的主要特点之一。

Tensorflow 的最新版本也支持通过 matplotlib 进行数据可视化。这个可视化库非常受欢迎,它经常在数据科学课程中使用,也经常被艺术家和工程师使用 MATLAB 或 Python / R /等进行数据可视化。

安装支持 CUDA、cudNN 和 GPU 的最新 TensorFlow 版本

让我们看看如何在 Windows、macOS 和 Linux 上安装最新的 TensorFlow 版本。

Windows 操作系统

先决条件

步伐

1)从:下载 Microsoft Visual Studio

https://visualstudio.microsoft.com/vs…

2)安装 NVIDIA CUDA 工具包(【https://developer.nvidia.com/cuda-too…】T2),检查软件和硬件版本要求,我们将使用:

| 版本 | Python 版本 | 编译器 | 构建工具 | cuDNN | CUDA |
| tensorflow-2.5.0 | 3.6-3.9 | GCC 7.3.1 版 | 巴塞尔协议 3.7.2 | 八点一 | 11.2 版 |

我们将安装 CUDA 版本 11.2,但请确保您安装了最新或更新的版本(例如–11 . 2 . 2,如果可用的话)。

点击最新版本,会弹出一个屏幕,你可以从几个选项中选择,所以按照下面的图片,为 Windows 选择这些选项。

选择以上选项后,等待下载完成。

使用快速(推荐)选项安装它,在您的机器上安装需要一段时间。

  1. 现在我们来下载 NVIDIA cuDNN,

**从 TensorFlow 网站查看版本代码。

现在,检查 CUDA 和 cuDNN 的版本,并为您的操作系统单击 download。如果你找不到你想要的版本,点击 cuDNN 存档并从那里下载。

下载完成后,解压文件。

现在,复制这三个文件夹(bin,include,lib)。进入 c 盘>程序文件,搜索 NVIDIA GPU 计算工具包。

打开文件夹,选择 CUDA >版本名称,替换(粘贴)那些复制的文件。

现在点击 bin 文件夹并复制路径。应该是这样的: C:程序文件 NVIDIA GPU 计算工具 kitCUDAv11.2bin.

在您的 PC 上,搜索环境变量,如下所示。

点击左下方的环境变量。现在点击表示路径的链接。

一旦你点击路径,你会看到这样的东西。

现在点击新建(左上),并将 bin 路径粘贴到这里。转到 CUDA 文件夹,选择 libnvvm 文件夹,并复制其路径。遵循相同的过程,将该路径粘贴到系统路径中。接下来,只要重启你的电脑。

  1. 安装张量流

打开 conda 提示符。如果没有安装,在这里得到它→https://www.anaconda.com/products/individual

现在复制下面的命令并粘贴到提示符中(检查版本)。

conda create --name tf2.5 python==3.8
conda activate tf2.5 (version)
pip install tensorflow (With GPU Support) //Install TensorFlow GPU command, pip install --upgrade tensorflow-gpu

您将会看到这样的安装屏幕。如果您看到任何错误,请确保您使用的是正确的版本,不要错过任何步骤。

我们已经安装了所有的东西,所以让我们在 Pycharm 中测试一下。

试验

为了测试整个过程,我们将使用 Pycharm。如果没有安装,获取社区版→https://www.jetbrains.com/pycharm/download/#section=windows

首先,要检查 TensorFlow GPU 是否已正确安装在您的计算机上,请运行以下代码:

import tensorflow as tf
tf.test.is_built_with_cuda()
tf.test.is_gpu_available(cuda_only=False, min_cuda_compute_capability=None)

它应该显示为 TRUE 作为输出。如果是假的或者有什么错误,看步骤。

现在让我们运行一些代码。

对于一个简单的演示,我们在手写数字的 MNIST 数据集上训练它。我们将了解如何创建网络以及初始化损失函数、检查准确性等等。

配置 env,创建一个新的 Python 文件,并粘贴以下代码:

import torch
import torchvision
import torch.nn.functional as F
import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch import optim
from torch import nn
from torch.utils.data import DataLoader
from tqdm import tqdm

这里查看其余代码-->https://github . com/aladdinpersson/Machine-Learning-Collection/blob/master/ML/py torch/Basics/py torch _ simple _ CNN . py

运行代码时,寻找 成功打开 cuda(versioncode)。

一旦训练开始,所有的步骤都成功了!

马科斯

MacOS 不支持最新版本的 Nvidia GPU,所以这将是一个纯 CPU 安装。通过一些额外的努力和要求,你可以在 Mac 上获得 GPU 支持。

先决条件

您可以安装网站上的最新版本,但是对于本教程,我们将使用 Python 3.8。此外,请访问 TensorFlow 网站了解版本支持。

2)准备环境:

安装 Miniconda 后,打开命令提示符。

conda install -y jupyter

安装 jupyter 需要一些时间。接下来,安装 Mac tensorflow.yml 文件。还可以创建一个. yml 文件来安装 TensorFlow 和依赖项(下面会提到)。

dependencies:
    - python=3.8
    - pip>=19.0
    - jupyter
    - scikit-learn
    - scipy
    - pandas
    - pandas-datareader
    - matplotlib
    - pillow
    - tqdm
    - requests
    - h5py
    - pyyaml
    - flask
    - boto3
    - pip:
        - tensorflow==2.4
        - bayesian-optimization
        - gym
        - kaggle

从包含 tensorflow.yml 的同一目录中运行以下命令。

conda env create -f tensorflow.yml -n tensorflow

此安装可能需要几分钟时间。

使用以下命令激活环境:

python -m ipykernel install --user --name tensorflow --display-name "Python 3.8 (tensorflow)"

试验

为了测试整个过程,我们将使用 Jupyter 笔记本。使用以下命令启动 Jupyter:

jupyter notebook

复制下面的代码并在 jupyter 笔记本上运行。

import sys

import tensorflow.keras
import pandas as pd
import sklearn as sk
import tensorflow as tf

print(f"Tensor Flow Version: {tf.__version__}")
print(f"Keras Version: {tensorflow.keras.__version__}")
print()
print(f"Python {sys.version}")
print(f"Pandas {pd.__version__}")
print(f"Scikit-Learn {sk.__version__}")
gpu = len(tf.config.list_physical_devices('GPU'))>0
print("GPU is", "available" if gpu else "NOT AVAILABLE")

这可能需要一些时间,但是您会在您安装的版本中看到类似这样的内容。

Linux 操作系统

我们可以在 Linux 上安装 CPU 和 GPU 两个版本。

先决条件

步伐

1)首先从【https://docs.conda.io/en/latest/miniconda.html】下载并安装 Miniconda

要在您的机器上安装 CUDA,您需要:

您可以通过运行以下命令安装 CUDA,

$ sudo apt install nvidia-cuda-toolkit

安装 CUDA 后,运行以验证安装:

nvcc -V

您将看到它的输出如下所示:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Sun_Jul_22_21:07:16_PDT_2019
Cuda compilation tools, release ‘version’

  1. 现在我们来下载 NVIDIA cuDNN,

**从 TensorFlow 网站查看版本代码。

下载后,解压缩文件:

tar -xvzf cudnn-10.1-linux-x64-'version'.tgz

现在,我们将把提取的文件复制到 CUDA 安装路径:

sudo cp cuda/include/cudnn.h /usr/lib/cuda/include/
sudo cp cuda/lib64/libcudnn* /usr/lib/cuda/lib64/

设置 cuDNN 的文件权限:

$ sudo chmod a+r /usr/lib/cuda/include/cudnn.h /usr/lib/cuda/lib64/libcudnn*

4)准备好环境:

导出 CUDA 环境变量。要设置它们,请运行:

$ echo 'export LD_LIBRARY_PATH=/usr/lib/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
$ echo 'export LD_LIBRARY_PATH=/usr/lib/cuda/include:$LD_LIBRARY_PATH' >> ~/.bashrc

也可以用康达和 jupyter 笔记本设置环境。

安装 Miniconda 后,打开命令提示符。

conda install -y jupyter

现在,检查 TensorFlow 站点的版本,并运行以下命令:

conda create --name tensorflow python=3.8

要进入环境:

conda activate tensorflow

让我们为您的新环境创建 Jupyter 支持:

conda install nb_conda

这将需要一些时间来完成工作。

要仅安装 CPU,请使用以下命令:

conda install -c anaconda tensorflow

要安装 GPU 和 CPU,请使用以下命令:

conda install -c anaconda tensorflow-gpu

要添加其他库,更新或在根位置创建 ymp 文件,请使用:

conda env update --file tools.yml

以下是您需要安装的附加库(您可以使用 pip 安装它们)。

dependencies:
    - jupyter
    - scikit-learn
    - scipy
    - pandas
    - pandas-datareader
    - matplotlib
    - pillow
    - tqdm
    - requests
    - h5py
    - pyyaml
    - flask
    - boto3
    - pip
    - pip:
        - bayesian-optimization
        - gym
        - kaggle

试验

有两种方法可以测试你的 GPU。

首先,您可以运行以下命令:

import tensorflow as tf
tf.config.list_physical_devices("GPU")

您将看到类似的输出,[physical device(name = '/physical _ device:GPU:0 ',device_type='GPU')]

第二,也可以用 jupyter 笔记本。使用此命令启动 Jupyter。

jupyter notebook

现在,运行下面的代码:

import sys

import tensorflow.keras
import pandas as pd
import sklearn as sk
import tensorflow as tf

print(f"Tensor Flow Version: {tf.__version__}")
print(f"Keras Version: {tensorflow.keras.__version__}")
print()
print(f"Python {sys.version}")
print(f"Pandas {pd.__version__}")
print(f"Scikit-Learn {sk.__version__}")
gpu = len(tf.config.list_physical_devices('GPU'))>0
print("GPU is", "available" if gpu else "NOT AVAILABLE")

您会看到类似这样的结果:

TensorFlow Version: 'version'
Keras Version: 'version'-tf

Python 3.8.0
Pandas 'version'
Scikit-Learn 'version'
GPU is available

所以,当你看到一个 GPU 可用时,你就成功地在你的机器上安装了 TensorFlow。

结论

TensorFlow 是谷歌创建的一个免费的开源机器学习软件库,它最著名的是它的 GPU 加速计算速度。我们看到了如何在 Windows、Mac 和 Linux 上安装 TensorFlow。希望这个指南能帮助你入门 TensorFlow!

参考资料和推荐读物:****

采访首席人工智能科学家:阿拉什·阿兹汉德

原文:https://web.archive.org/web/https://neptune.ai/blog/interview-with-a-chief-ai-arash-azhand

不久前,我有机会采访了一位伟大的人工智能研究人员和 Lindera 的首席人工智能科学家 Arash Azhand。

我们讨论了:

  • 他在 Lindera 工作背后的人工智能技术
  • 他的职业道路
  • 如何成为一名以研究为中心的科学家
  • 如何成为一名优秀的领导者
  • 为什么从商业角度研究人工智能很重要

以下是我们对话的完整视频:

https://web.archive.org/web/20221206004658if_/https://www.youtube.com/embed/ULklVy3k8JU?feature=oembed

视频

可以看视频看原始内容。

另一方面,这里是我们谈话的摘要。接下来的不是一份一对一的抄本,而是一份经过整理、结构化和重新措辞的抄本。

你在 Lindera 做什么,你和你的团队在做什么?

从人工智能的角度来看,我们在 Lindera 所做的是使用这些非常有趣和新颖的技术,这些技术在医疗技术中被称为人工智能技术。我们的主要重点是将计算机视觉算法用于检测人体骨骼,以便进行行走分析。因此,我们拍摄老年人的视频,从这些 2D 视频图像中提取三维空间的骨架,然后尝试计算行走的参数。比如步长,步数时间,行走速度。这是因为我们知道,从医学的角度来看,这些参数对于评估老年人跌倒的发生率等医学疾病特别重要。

你能告诉我们更多关于它是如何工作的吗?

当然可以。核心技术其实还挺通用的。它不是专门针对任何疾病或一组疾病的。只是取视频,提取关节坐标。想象你有一个人类骨骼,你有这些独立的关节,像膝盖,脚踝,肩膀等。你想知道这些关节的坐标。例如,当你有一段时间的脚的关节,当人们走路时,你可以使用这些坐标来计算其他参数。因此,从那里,它只是普遍的。

你可以用这种技术,这种用于老年人护理的调查,你可以用它来运动,你可以用它来康复。没有限制,相当普遍。

它的核心有这个骨骼追踪器,在此之上,我们可以建立一个工具,它可以获取这些坐标,计算其他一些东西,并向人们提供建议。例如,当我们发现这个人的行走有问题时,我们可以计算一些参数并推荐特定的物理疗法。所以参数的提取和推荐工具都是建立在这个核心技术之上的。

你的团队有多大,你是如何组织的?

Lindera 的整个团队目前大约有 30 人。它包含几个独立的团队。

  • 我们有一个销售团队以及我们的首席执行官和首席财务官,他们正在努力向客户推广我们的产品技术。
  • 我们有一个客户成功团队。客户成功团队的关键成员会去客户那里展示产品,提供帮助和服务,并尝试获得他们的反馈,以便我们改进产品。
  • 然后,我们有一个开发前端和后端系统以及应用程序的 IT 团队。核心是数据科学,这实际上是我的职责范围。
  • 我和我的团队目前有六个人,我们开发这些核心人工智能技术。我们为计算机视觉算法、建议以及步态参数计算开发算法。

我们在数据科学领域的主要关注点是研究和开发。

当我将其与其他行业公司和我在大学的时间进行比较时,我会说 Lindera 的数据科学比其他公司更以研究为中心。这意味着我们通常从一开始就没有技术或技术背后的东西。在此之前,我们必须找出有什么,我们必须阅读出版物,研究前沿研究,并试图提取对我们重要的知识。然后决定这其中的哪一部分对我们有用,以及我们如何在我们的系统中开发它。

你的人生之路是怎样的?你是如何成为数据科学家并最终成为首席研究员的?

我的背景是物理学。我会说我对物理的兴趣始于我对了解自然的好奇心,了解自然现象背后隐藏的原因。就在我开始学习之前,我对宇宙和宇宙学非常感兴趣。我在学校读了很多关于宇宙学的书,想去读天体物理学。可以说,这是我早期的爱情。最终,我开始研究物理。这是非常好的一步,因为我们有一个非常好的天体物理系,还有一个非常好的教授。我们只是从非常哲学的角度进行了研究。这也是我非常感兴趣的地方。

最终,在大学期间,我对生物物理学和复杂生物系统中的自组织产生了更大的兴趣。

我非常好奇,想知道这些非常复杂的生物系统,比如我们,人类,甚至更小的生物,比如昆虫,是如何处理周围的混乱的。

他们如何能够生活在这个混乱的系统中,获得能量,并将其转化为生命。这种自组织原理和生物系统非常有趣。所以,我实际上进入了这个领域,在统计物理领域完成了我的博士学位。我专注于复杂系统,并试图理解这些复杂系统中的模式形成。你会发现复杂的系统无处不在——一些普遍的模式,螺旋波。例如,在人脑、人的心脏以及试图通过波组织昆虫的昆虫群落中,可以发现螺旋形的波。这些波浪大多是螺旋形的。在我博士期间,我研究了化学系统中这些螺旋形波的形成,试图从那里了解它,并专门了解其他系统。

你是怎么从这里转到林达工作的?

我读了博士,然后做了两年博士后。在博士后研究中,我对晶体的形成做了一些非常有趣的研究,晶体不是有机的(所以不是生命系统),但仍然类似于生命系统。它们有曲率,但仍然是无机物。我在这些晶体上做了一些实验和模拟。在这期间,我只是想着我以后要做什么。我会去学术界吗?还是我会步出学术界,走向工业界?我的决定实际上是去这个行业,因为我看到了更多做研究的机会。我对人工智能话题非常感兴趣。

我最感兴趣的系统之一,也许是最感兴趣的,是人脑。

所以我非常好奇,想知道人类大脑中的意识是如何产生的。我们怎么能用这个器官推断出这个世界的知识。另一方面,在过去的几年里,我对人工智能产生了兴趣,这在某种意义上受到了神经科学的影响。我想我在该行业工作的主要动机是了解原始神经科学和人工智能之间的联系。

你找到了其中的联系还是只有灵感?

起初,我找到了灵感,但越来越多的最新研究,也是在人工智能领域,正在试图找到这两种游戏之间的桥梁。所以它始于灵感,但现在越来越多的人看到人工神经网络是受检测模式和数据的专门算法的启发。但是它没有告诉我们这些不同现象之间的因果关系和联系。

因此越来越多的人也试图将这些人工神经网络与其他人工智能研究领域相结合。

另一个人工智能研究领域的例子可能是概率模型。在神经科学中,贝叶斯大脑假说有一个独立的领域,它建立在大脑在某种意义上是一种伟大的贝叶斯机器的原则上,它通过感官从环境中获得输入,并试图在内部模型中模拟这种输入。所以我们只是试着去匹配我们所看到或听到的。

你大学毕业后从事什么工作?

当我大学毕业时,我最初是在另一家公司担任数据科学家。我的日常工作只是在电子体育领域做预测建模和分析建模。电子竞技团队有冠军,我在一家名为 Dojo Madness 的公司担任数据科学家,该公司的产品是开发预测电子竞技游戏结果的模型。过了一段时间,我离开了那里,开始在 Lindera 工作。那是到了 2018 年 11 月。我在 2018 年 4 月离开了大学。我随即开始在道场疯狂和 11 月在林达。

我从 Lindera 开始,因为 Lindera 的数据科学工作更能让人想起我在大学的工作。

更多的是阅读这方面的科学出版物,以有效地提取知识并理解它们。只是为了立即看到我们可以利用现有的科学知识朝哪个方向发展,以及如何为我们所用。

你平常的一天是怎样的?

一部分是肯定的,阅读新的研究。所以我开发了一种系统,在那里我收集研究论文并制定阅读它们的计划。然后,我有效地从中提取知识,并写下我所发现的某种文档。

这是一种团队策略吗?

我们以看板的方式进行整个开发。我们有了古典发展的入场券,在某种意义上,我们也开始做研究部分。我的团队成员也是研究型的,他们试图阅读和测试一些特定论文中的所有内容,并制作文档。我们直接写在这些看板票上。这样,我们可以看到研究的状态,我们中的一些人已经发现了什么,在哪些领域我们不应该再进一步。

这是我们目前的想法,我们正在迭代开发这种方法。我们必须每周对它进行检查,看看它是否能正常工作,以及当它在某些方面正常工作时,我们该如何追求这项技术。

你日常活动的其他重要部分是什么?

当然,另一个主要部分是发展。当我们决定在某个特定领域更进一步时,我们发现这篇论文很好,很有前途,我们应该发展它。我们检查是否有代码,团队中的某个人测试这些代码,试图开发它,研究这些发现,并记录下来。这是工具或算法的第一个证据。我们可以稍后决定是否将它放入我们的生产系统中。这是应用开发领域,我也在其中。所以我主要做研究,但也尝试开发特定的领域和代码。

对于首席数据科学职位来说,很大一部分工作是与企业沟通,并为人们提供基础架构、数据访问或法律信息。这也是你的案子吗?

是的。我在 Lindera 做了一年的普通数据科学家,之后,我有一段时间(2-3 个月)去做首席人工智能。那段时间,我逐渐从这个研发部分的工作中退了出来。我慢慢地把这些领域的任务交给了我的团队成员,并承担了整体的战略发展和沟通。因此,我是数据科学团队、业务和客户之间的一种纽带。

我是数据科学团队、业务和客户之间的纽带。

在您从贡献型数据科学家转变为管理型数据科学家的过程中,有没有什么意想不到的事情?

有趣的是,这对我来说并不意外,因为我来自物理领域,大多数人在一些研究团队中攻读博士学位。你自然会在某个时候在那里做一些管理工作。例如,你必须指导和管理硕士生和其他试图发展研究思路的学生。从这个角度来看,这对我来说并不新鲜。一年前,我在 Lindera 担任数据科学家,从前任主管和高层领导那里得到了很多建议,这也帮助了我。

在我接手这个首席职位之前,我感到了某种焦虑,我想知道事情会如何发展,我是否能够做到这一点。但从我踏入的那一刻起,我和我的大脑内部就有一种开关,我知道我能做到。

我只是有这种感觉,它非常适合我和我的性格来领导这个团队,为他们提供建议,倾听他们的想法,并了解他们的优势是什么。

去理解我如何利用他们的优势,并把它用于数据科学和 Lindera。

你如何帮助人们在某些方面有所提高?你如何鼓励人们做最好的自己?

有两个领域——软技能和硬技能。有趣的是,我的印象是,更需要的技能是软技能。因为硬技能,如研究能力,开发和编程技能,是一种技能。你在大学期间学到的东西,以及之后,你必须做一段时间的手艺。那你就可以做了。对于一个领导职位来说,软技能是主要部分。例如,仔细倾听的能力

你必须倾听团队成员,看看他们如何传达想法,他们如何在日常生活中传达这些想法,以及他们传达这些想法时的感受。让他们感到被欣赏。给他们发展想法的空间,并把想法带给你。你抓住这些想法,然后试着将这些想法整合到你的团队和公司的整体战略中。所以你有公司具体的关键目标。你决定在哪个领域发展。

给你的团队足够的空间来发展想法,并把想法带给你。

此外,你必须注意到这个团队成员是非常以研究为中心的。他或她非常擅长研究,喜欢阅读论文和提取知识。好的领导就在你身后,也把自己的知识推给团队。

在这个极具研究性的数据科学世界中,你认为还有其他对领导角色至关重要的技能吗?

作为一名普通的数据科学家,你每天或每周完成你的任务,完成它,然后记录你的解决方案,一切都很好。但是从领导的角度来看,你还必须具备某种预见能力。客户和企业都有需求。因此,你有一个时间框架向客户交付产品。你必须能够理解你的团队的力量是什么,他们能做什么,如果这个交付时间窗口是可行的。这可能是最困难的事情之一,我不能肯定地说我在上面。所以,时间会证明我做得对不对。

我们在这里称之为决策智能,这是数据科学领域的一个新学科(有人称之为机器学习++或数据科学++),它只是从另一个角度看待所有的东西。

它不是将数据和人工智能放在第一位,而是从“问题是什么,以及必须从业务和客户方面做出哪些决定”这样的问题出发

你认为现在对你在这个领域取得进步至关重要的事情是什么?

我觉得一个主要的东西就是沟通部分。当你在大学时,你主要负责你的工作。你可以做一整年的研究,然后写一写,然后就没有其他责任了。然而,在大多数公司,你每天都必须学会交流更好的解决方案和想法。

当我开始作为一名数据科学家时,作为一名完美主义者,我做了一周的研究来解决一个具体的问题,因为我有这样的印象,我必须这样做。但最终,这并不是什么大问题。我在微观研究和微观改进上浪费了很多时间,而主要的东西却不是这样。我不得不强迫自己分清工作的轻重缓急。

你是怎么做到的?

书籍是有帮助的——我读过一些关于敏捷编程领域的书,一些关于如何区分任务优先级的书。但我认为对我帮助最大的是和其他有这种经历的人交谈。我必须放弃这种认为自己必须完美的焦虑,开始寻求帮助。这听起来很琐碎,但可能是最困难的事情之一。记住我没有义务自己解决所有的问题。

此外,从领导力的角度来看,给你的团队留下这样的印象非常重要:他们可以随时向你或其他团队成员寻求帮助。当团队中有一种竞争的环境时,灾难就来了。所以你必须向你的团队展示他们可以一起工作。

您是否有任何方法或系统来促进团队中的讨论和帮助交流?

至少每月一次,但更多的时候,我会尝试与每个团队成员一对一交谈,询问他们的工作生活如何,一切都好吗,他们有问题吗。我后退一步,让他们说。也许还可以告诉他们,如果他们遇到了阻碍他们前进的具体问题,哪个团队成员擅长于此。以便他们一起工作。

另一件事是知识转移,从数据科学和 Lindera 的角度来看都是如此。

关于如何在职业生涯中取得进步并获得更好的体验,你会给初级或普通数据科学家哪三条建议?

  • 一、整体分析公司,还要数据科学。仔细观察团队结构。有什么样的数据科学带头人?他们给你进步的空间了吗?是否有专业知识多样化的人?他们如何对待你和其他团队成员?
  • 我想给更多以研究为中心的数据科学家的下一个主要建议是,像我这样来自数学或物理领域的科学家,学习硬技能的强化课程,比如特定的编程课程。精通工艺——建筑设计和图书馆很有帮助。这就像说一种语言,可以让你更好地与人交流。当你对手艺非常熟练时,你的大脑将会有创造的自由。例如,我认识到,当我没有那种手艺时,我失去了很多时间和创造力。
  • 下一个主要建议也是看看公司和它的学习环境。他们是否为你提供了学习和成长的空间,或者只是我所说的,更多的是数据工程,只是推动数据。
  • 最后,与第一条相关的另一条建议是分析团队结构。当团队中有数据工程师,也许还有一些开发人员时,这给了数据科学家很大的自由。

你有什么书籍、资源、博客或播客可以推荐吗?

我可以肯定地推荐一件事,可能大多数实际上是从业者的数据科学家已经知道了,那就是媒体博客和走向数据科学博客(它是媒体的一部分)。从去年开始,我决定付费成为中等会员,我真的很喜欢它。我试着阅读关于新奇事物的有趣文章。

还有书籍——对我个人来说,最有价值的是普通书籍,而不是专业书籍。更深入人工智能哲学、神经科学的一般人工智能书籍。

退一步读点别的或者做点别的也不错,比如四处走走,听听音乐,然后再回来,突然问题就自己解决了。

你想给我们的听众留下什么信息吗?

我想我能给那些想知道他们是否应该进入人工智能领域的听众和观众的主要信息是,现在是在这里的最好时间。我的印象是,在未来的一到五年内,主要的改进将会特别出现在某种人工智能领域。我们目前的人工智能与其他科学领域的结合将导致重大的改进。

Arash Azhand 分享的有趣文章和资源

这里有一些关于零起点学习的东西(ZSL):

  1. 关于 ZSL 及其应用的介绍文章:https://towards data science . com/applications-of-Zero-shot-learning-f65bb 232963 fZero-shot learning指的是机器学习的一个特定用例(以及深度学习),在这种情况下,您希望模型基于很少甚至没有标记为的示例对数据进行分类,这意味着动态分类。”
  2. 另一篇关于一项最新研究贡献的文章:https://medium . com/@ Ali tech _ 2017/from-zero-to-hero-shaking-up-the-field of zero-shot-learning-c 43208 f 71332“zero-shot learning 是指机器学习如何在没有任何标记的训练数据帮助分类的情况下识别图像中的对象的过程。”
  3. 马克斯·普朗克研究小组致力于 ZSL,在该领域开展了一些最伟大的工作:https://www . MPI-INF . mpg . de/departments/computer-vision-and-machine-learning/Research/zero-shot-learning/zero-shot-learning-the-good-the-bad-and-the-ught/
  4. …还有他们最好的论文之一:
    https://arxiv.org/pdf/1903.10132.pdf

决策智能领域介绍(数据科学 plus plus):

  1. Cassie Kozyrkov(谷歌首席决策智能科学家)的介绍文章:https://towards data science . com/introduction-to-Decision-Intelligence-5d 147 ddab 767“想知道在大草原上躲避狮子的心理与负责任的人工智能领导和设计数据仓库的挑战有什么共同点吗?欢迎来到决策智能!”
  2. 凯西·科济尔科夫的演讲题目:https://www.youtube.com/watch?v=bCjMhZZYlP4
  3. Cassie Kozyrkov 的博客文章“数据科学到底是什么?”https://hacker noon . com/data-science-EB 1237 D8 CB 37

一种更好地理解神经元网络中深度学习的新理论,基于 Shannon 的经典信息论,称为信息瓶颈“深度学习理论:

  1. Quanta 杂志上关于它的文章:https://www . Quanta Magazine . org/new-theory-cracks-open-the-black-box-of-deep-learning-2017 09 21/“一个被称为“信息瓶颈”的新想法正在帮助解释当今人工智能算法令人困惑的成功——也可能解释人类大脑是如何学习的。”
  2. 我自己关于“信息瓶颈”理论的博客文章,最近作为我们自己的 Lindera AI 博客的第一篇文章写的:“进入黑盒的观点——理解深度学习的信息论方法https://www . Lindera . de/2020/03/05/A-View-into-the-Black-Box-An-Information-Theory-Approach-to-Understand-Learning/

Manuel Brenner 从神经科学角度发表的一系列非常有趣的媒体文章:

  1. 博客文章“我们如何从大脑中学习,以了解大脑如何学习”:https://towards data science . com/How-We-Can-Learn-from-The-Learn-How-The-Brain-Learn-2b 81286 a1 a7b
  2. 博客文章《为什么智能可能比我们想象的简单》:https://towards data science . com/Why-Intelligence-may-be-simple-than-we-think-1d 3d 7 feb 5d 34
  3. 博客文章“自由意志的热力学”:https://medium . com/@ manuel _ Brenner/The-热力学-of-free-will-940cacd02401
  4. 博客文章“贝叶斯大脑假说”:https://towards data science . com/The-Bayesian-Brain-Hypothesis-35b 98847 d331
  5. 博客文章“思想的几何学”:https://towardsdatascience . com/The-Geometry-of-think-700047775956

最后但同样重要的是,卡尔·弗里斯顿教授的作品

也许是当今最著名的神经科学家之一,他发展了自由能原理作为人类智力和思想的驱动力。Manuel Brenner 在上述文章中也介绍了他的一些工作。但这里也有一篇他自己写的关于 Aeon 的文章:“思维-时间的数学——意识不是一个事物而是一个推理过程”https://Aeon . co/essays/意识不是一个事物而是一个推理过程

采访 AI 的负责人:Pawel Godula

原文:https://web.archive.org/web/https://neptune.ai/blog/interview-with-head-of-ai-pawel-godula

几周前,我有机会采访了一个了不起的人,谈到建模和理解客户数据时,他是一个了不起的人。

我们将讨论:

  • 如何建立对变化稳健的模型
  • 如何成为技术组织的领导者
  • 如何关注“正确”的问题
  • 为什么模型组装在现实生活中比在比赛中更重要
  • 还有更多!

查看我们对话的完整视频:

https://web.archive.org/web/20221208034942if_/https://www.youtube.com/embed/Kv-5I5v2UGY?feature=oembed

视频

接下来的不是一份一对一的抄本,而是一份经过整理、结构化和重新措辞的抄本。

可以看视频获取原始内容。

你现在的角色是什么?

我是 deepsense.ai 的客户分析总监,我们在客户行为领域做与预测相关的项目。

例如,我们会做这样的事情:

  • 客户是否会偿还他的信用
  • 我们应该向这位客户推荐什么样的产品
  • 客户的终身价值是什么,以此来判断联系她是否有意义

主要与真实客户数据相关的东西。

我们正在处理的数据通常具有事件的形状,并且是在线收集的。想想那些有活动的电子商务网站的数据,然后从这些活动中你做特征工程,然后你建立一些模型。

你的团队结构是怎样的?

我认为,对于机器学习或人工智能团队来说,通常最有效的规模是每个项目 5 到 10 人。有 5 到 10 个人,你可以很容易地处理一个人工智能项目的大部分重要方面。人多了,就变得不好管理了。通信成本中有很多开销。

由于我们实际上有许多项目在进行,我们需要扩大团队规模。对于以 ML 建模为核心业务的大公司来说也是如此。从我的经验来看,他们的(核心)建模团队在 5 到 10 人左右。所以 5 到 10 个人完成一项任务应该足够了。

5 到 10 个人完成一项任务应该足够了

你目前的项目是什么?

现在我们正在为一个全球广告网络项目工作。就部署和生产需求而言,该项目非常困难,因为我们需要以 100 毫秒的延迟,每秒提供 500 万个点预测。

这是一个非常困难的项目,因为对于每一个客户和他们想通过我们的客户网络做广告的每一种产品,我们都需要做出这些预测。因此,根据产品和客户的数量以及我们的模型需要生成的预测数量,会有多个原始数字,这非常庞大。预测需要每秒发布一次,它是在线的,所以是的,这是一个艰难的决定。

这个项目实际上教会了我很多关于大规模生产的知识。我们做了几个不直观的动作,大大提高了性能。例如:

  • 我们从一个大型 lightGBM 模型发展到 20 个小型 lightGBM 模型。
  • 我们使用大型(500 棵树预测 20 个类别)和小型(50 棵树预测 2 个类别)模型

这些模型的基本区别在于用来训练它的不同数据或者不同的随机种子。

我们面临的问题要求我们稳定结果,平均 20 个模型的预测比从一个大模型中提取一个预测要好得多。

因为当你对 20 个模型的预测进行平均时,你还可以观察这些预测的标准差。所以,如果所有的模特都对某个产品投了赞成票,那就意味着你应该把它展示给顾客。如果喜欢 5 个模特,投赞成票 15 个模特投反对票,那你就有问题了。一件好事是我们可以利用模型集合。

我知道在需要低延迟的大型数据集上进行预测看起来不像是模型集成的典型场景,但这就是为什么我说它不直观。在这样的生产场景中,您通常会期望模型尽可能简单。

我认为,在生产环境中,模型组装比竞赛更重要。通常人们会说你只是用那些怪物套装来赢得比赛,但你永远不会在现实生活中使用它们。我说在现实生活中,这比竞争重要得多,因为一个非常简单的原因,你会得到很多非平稳性。

在现实生活中,模型集成比竞赛重要得多,因为一个非常简单的原因,你会得到很多非平稳性。

非平稳性是现实生活中常见的东西,是你在比赛中不会经历的。在非平稳问题中,拥有一组不同的模型非常有帮助。

事实上,我们每个月在亚马逊上花费几十万美元,但我们决定从一个型号转移到 20 个型号,因为性能改善太大了。

说到比赛,你是一个非常活跃的卡格勒。最近你取得了一些不错的成功,对吗?

是的,我刚刚赢得了我的第一枚个人金牌,这是我梦想成真的时刻。非常感谢。是的,所以,实际上,我是从竞赛中来到数据科学、机器学习和人工智能领域的。

我开始竞争,然后我意识到这是一个非常好的领域,一个可以对我们的生活产生巨大影响的领域。所以我决定彻底改变我的生活,开始编码,做数据科学和机器学习。

你的职业道路是什么?

我最初是一名商业顾问,在波士顿咨询集团工作。这是一家很棒的公司,我已经在那里工作了六年左右。

然后他们慷慨地送我去读 MBA 课程。我选择了新加坡的 INSEAD,这是我一生中遇到的最好的事情之一。这一年,当你回到大学,你有一些时间来思考你真正想做的事情。

我是 MBA 的忠实传播者,有一年的间隔年可以反思。那是在我读 MBA 的时候,我发现了机器学习,写了第一行代码。我的数据科学生涯就是这样开始的。

我是 MBA 的忠实拥护者,有一年的间隔年可以反思。

MBA 毕业后,我回到了波士顿咨询公司,准确地说是波士顿咨询公司。BCG gamma 是 BCG 的姐妹公司,专注于人工智能。所有大的咨询公司都创造了这些。这是一家伟大的公司,由了不起的人领导,由一个了不起的人西尔万·杜兰顿经营。所以他们在华沙开设了一个办事处,他们邀请了我,最终我领导了这个办事处。我认为咨询业,尤其是波士顿咨询公司,是一个很好的去处。

但是过了一段时间,我只是想尝试一些不同的东西,于是我去了 Netsprint。

它是波兰最大的数据生态系统之一,也是一家拥有出色的管理和领导团队的伟大公司。我去那里是为了成为一名首席数据科学家。

我们开发的一些主要用例是基于存储在 cookies 中的互联网用户过去的历史来预测他们的行为。那是在欧洲 GDPR 之前,顺便说一句,那会彻底改变这种情况。

例如,我们开发了一个网站嵌入系统。相似的人访问的网站在嵌入空间中彼此接近,根据这些信息,我们的系统将预测你访问的网站是男性还是女性。对于广告商来说,这实际上是一条非常有价值的信息。

然后 GDPR 发生了,情况完全变了。我搬到了现在的 deepsense.ai。我是客户分析总监。

你典型的一天是怎样的?

每个技术经理必须处理的一个大挑战是他花在编码上的时间和他花在管理人员上的时间。

很容易陷入组织者/推动者的角色,因为你有你的团队为你工作。与此同时,仅仅发邮件、站着说话、开状态会议是非常不令人满意的。

在我的工作中,最驱动我的实际上是解决问题,当我也可以参与编码时,这是最有吸引力的。这是一个很大的挑战,我不仅在自己的案例中看到了这一点,对于许多在组织中成长为优秀程序员、开发人员或科学家并开始领导团队的人来说也是如此。

我很幸运,因为在 deepsense.ai,我们真的有一个很棒的团队,他们几乎不需要牵手,我们可以将会议限制在讨论目标和协调团队成员的会议上。

一旦目标确定,他们就会使用一切必要的手段来实现目标。这是在 deepsense 工作的好处之一。ai:管理非常非常高效。

当谈到百分比分割时,我会说我花 20%到 30%与客户一起制定问题并获得客户反馈,另外 30%与团队合作,另外 40%是我自己的编码和工作。

我会说我花了 20%到 30%的时间和客户一起解决问题并得到客户的反馈,另外 30%和团队一起工作,另外 40%是我自己的编码和工作。

需要有意识的努力才能达到 40%,因为很容易就会降到 5%或 10%。

当这种情况发生时,作为一名程序员你会变得不开心,不开心不会带来任何好处。它需要一些纪律来组织你的会议,你的立场,你和你的客户交谈的方式,但这是可行的。

对于客户分析总监的角色和其他“人工智能主管”类型的角色,什么让你感到惊讶?

我想说的是,这一直让我感到惊讶:由于在同一个项目中工作的不同团队之间缺乏协调,会出现多少问题。

例如,我们正在为一个电子商务网站做需求预测模型。我们的特色是基于网站上顾客对产品的反应。然后网站的设计改了但是我们不知道。我们的特征开始意味着完全不同的东西,我们的预测在很短的时间内变得疯狂,直到我们意识到发生了什么。我总是惊讶于一些小事,甚至是一点点的不协调会导致令人震惊的结果。

我总是惊讶于一些小事,甚至是一点点的不协调会导致令人震惊的结果。为了处理这些问题,我总是试图让整个团队在一个房间里。

为了处理这些问题,我总是试图让整个团队在一个房间里。我知道随着团队的扩大,有时很难维持,但只要我能做到,我就会努力去做,因为这让事情变得容易多了。当然,过多的讨论会带来一些额外的影响,有时我们的工作日会变成一个持续不断的会议,但如果我必须在两者之间做出选择,我会选择后者。

对于一个人工智能负责人来说,哪些是至关重要的领导技能?

我认为最重要的技能实际上是知道在机器学习项目中把重点放在哪里,把时间投入到哪里。弄清楚如果做对了哪里会收获最大的价值,如果做错了哪里会产生最大的问题。

我认为最重要的技能实际上是知道在机器学习项目中把重点放在哪里,把时间投入到哪里。

例如,问题公式化是一个机器学习团队领导或首席数据科学家应该知道如何做的关键事情之一。这需要大量的经验,因为这意味着你应该能够直观地知道,对于一个给定的任务,应该使用什么样的技术。

假设我们有一个项目,我们想用 ML 系统个性化电子商务网站。一种方法可以是使用传统的分类模型,另一种方法可以使用上下文强盗(强化学习方法)。

一开始的技术选择对你以后将要处理的问题有很大的影响。

首席数据科学家应该非常了解或者至少直观地知道应该尝试哪些方法。我认为这无疑是最重要的技能之一。

然后,当然,在任何机器学习项目中,你需要选择你和你的团队应该在哪里争论他们的时间来:

  • 找到最好的算法,
  • 寻找更多的数据,
  • 特征工程。

所以,再次,它来自经验,但几乎总是新的数据,新的高质量的数据比使用不同的算法对你的结果有更大的影响。

我记得几年前,波兰有一家银行开始使用来自波兰最大的电子商务网站的交易数据来给年轻的创业者评分。这种交易数据通常是一种非常有价值的补充,他们在这方面取得了巨大的成功。

为什么?因为通过添加竞争对手没有使用的新数据源,他们能够对其他银行无法定价的风险部分进行定价。他们是唯一愿意向这些人提供贷款的人,而且他们对风险的估计非常精确。

通过添加竞争对手没有使用的新数据源,他们能够对其他银行无法定价的风险部分进行定价。

添加新数据、寻找新数据的来源,甚至与可能为您提供数据的潜在合作伙伴交谈,也属于表现出色的数据科学家的职责范围,尤其是首席数据科学家。

从操作上来说,我更倾向于功能工程。从数据中提取信息比选择算法或者调优超参数更重要。当然,模型选择或超参数调整也很重要,但我很少看到这两个来源的巨大影响。

最后一点,我认为数据科学界低估了很多,但实际将模型应用于现实生活的人欣赏的是非平稳性方面。

非平稳性是指数据生成过程中的一些基本变化。你需要确保你的模型对此有弹性。

非平稳性是指数据生成过程中的一些基本变化。你需要确保你的模型对此有弹性。

我给你举个例子。有一次,我和一个人进行了一次很好的讨论,他是波兰最大的银行之一的消费者贷款建模的负责人。例如,他向我解释了为什么他使用线性回归而不是 lightGBM。

首先让我们理解这个人的处境:

  • 他在做他的训练模型,
  • 他正在将这个模型投入生产,
  • 他的模型决定谁能获得贷款,谁不能
  • 他的模型正在做出数百万美元的决策,只有在 6-12 个月后,当人们开始出现还贷问题时,他才会知道结果。

所以他得到的反馈(来自真实世界)很少,需要现在就做出决定。

在这种情况下,机器学习模型非常需要的是对经济突然变化的响应能力。他告诉我,如果经济发生突然或重大变化,他非常清楚线性回归模型将如何表现,但他对 lightGBM 模型没有同样的感觉。

直到我遇到同样的情况,我才理解他的评论。今天,我们在非静态数据环境中做了大量建模工作,并使用所有这些技巧来稳定结果。使用 20 个模型集合是一种方法,使用线性回归等更简单的模型是另一种方法。

我想说的是,在社会经济领域的背景下,如果数据生成过程中发生变化,您的解决方案将如何表现,这一点非常重要。我觉得这种知识是你在做了几年真实生活的建模并经历了一些失败后得到的。

无论如何,我之前提到的网站设计变化的例子也是一个很好的例子。突然,你的特征意味着完全不同的东西,但模型输出完全错误的预测。

这是机器学习的诅咒之一,我们的模型往往会无声无息地失败。

我经常举的另一个非平稳性的例子是恶性通货膨胀。想象一下在恶性通货膨胀的环境下进行信用风险建模。通常,信用风险模型中最重要的特征之一是受恶性通货膨胀严重影响的个人收入。如果你在两个月前训练你的模型,而你今天使用它,它将是完全错误的。

为了处理非统计性,你可以使用再培训、在线学习、集合方法或其他方法。所有这些都让事情变得更好,但它们也不一定让事情变得更好。

为了处理非统计性,你可以使用再培训、在线学习、集合方法或其他方法。所有这些都让事情变得更好,但它们也不一定让事情变得更好。

它们减轻了非平稳性的影响,但没有消除它。

假设你每天都重新训练你的模型,这是一个很好的实践,然后一些真正大的变化。这只是 180 天中的一天,这是典型的培训样本,它不会产生足够的影响来针对业务环境做出正确的调整。

我想说的是,提高再培训的频率不会有什么坏处,但这并不是一切。

你是如何学习新事物的?

我喜欢两种知识来源。

第一个是 T2 的比赛,在那里我可以学到新的技术。我每天都这么做。我试着找 15- 30 分钟的时间来思考这个问题,思考我将如何解决这个问题,也许只是写一行代码。当然,它不会因为一行代码而停止:)。

第二个是好的行业博客。我特别推荐的一个博客是由杰瑞米·霍华德运营的快速人工智能博客

我也喜欢来自吴恩达的名为“The batch”的时事通讯。

书方面,我有一本极力推荐。

Trevor Hastie、Robert Tibshirani 和 Jerome Friedman 的《统计学习的要素》

这真的是一本非常好的书。

除此之外,我认为最好的体验来自于现实生活中的项目。这实际上是一个我认为数据科学界仍然没有充分利用机会的领域。

我认为最好的体验来自于现实生活中的项目。

例如,互联网上的信息量是巨大的,你可以从中抓取、分析和获得洞察力。有很多公司和创业公司正在这样做,但是仍然有很大的空间。

最近,蓝点公司在 2019 年 12 月 10 日发布了针对武汉病毒的警告,比其他人早得多。

因此,这是你需要将你的模型与你周围的数据联系起来的领域,通过自动化分析,你可以获得真正有趣的见解。

你如何将工作集中在重要的事情上?

提出好问题。

…并且理解这就是为什么实际上有可能来自外部行业,在 29 岁时学习编码,然后成为技术团队的主管。

我承认我的代码可能非常笨拙,但我总是试图专注于我正在回答的问题,那些带来价值的东西。我没有在不相关的问题上花时间。我认为作为数据科学家或机器学习工程师,它可以给你带来巨大的优势。

我试着总是专注于我正在回答的问题,那些带来价值的事情。

不是你的代码在技术上有多优秀,而是你真正知道你带来的价值在哪里。

所以在编码之前,花点时间想想:

  • 应用什么技术,
  • 你应该有什么数据
  • 如何处理数据工程,
  • 如何让你的模型对大多数问题都有弹性?

如果你这样做了,你总是能回答正确的问题,即使你的代码很笨拙,或者在技术上不是很好,你的工作仍然有巨大的价值。

我认为这实际上是来自外部行业的人进入机器学习的一大希望,因为对于习惯于解决商业问题的人来说,这是一种非常自然的技能。

良好的数据科学流程对您有多重要?

我觉得有一个好的数据分析和建模的过程其实很重要。

机器学习和人工智能是一个非常年轻的领域,没有多少既定的最佳实践

机器学习和人工智能是一个非常年轻的领域,在大学或任何书籍中没有多少既定的最佳实践,所以我设计了我的流程,并试图严格遵循它。

当然,我总是偏离这个过程,但至少我是通过遵循某些东西来确保所有重要的元素都被涵盖。

我认为它在现实生活中的项目和比赛中同样重要,但让我给你一个比赛的例子。

我相信,当你想赢得一场 Kaggle 竞赛时,你至少应该接触所有潜在价值的来源:

  • 数据探索
  • 特征工程
  • 型号选择
  • 超参数优化
  • 组装
  • 仔细思考验证

如果您遵循所有步骤,并挖掘,比方说 80%的价值来自所有来源,那么您就有了一个真正强大的解决方案。

我非常喜欢特征工程

我倾向于专注于我喜欢的事情,但我认为这对我们所有人来说都是非常自然的。所以我非常喜欢特征工程,这很好,但是忘记过程的其他部分在过去让我付出了沉重的代价。

我想你还记得 2018 年的住房信贷违约竞赛。我们失去了第一名的位置,因为我们几乎把所有的注意力都放在了功能工程上。我们拥有最好的功能和优秀的模型,但我们完全忘记了作为巨大价值来源的组装。

我们是私人排行榜上的第一名,但我们的模型不够强大,我们在公共排行榜上从第一名跌至第五名。这就是为什么现在,我试图遵循一个非常严格的过程,以确保我利用所有可能的价值来源。

此外,重要的是要提到我最好的想法是在我和妻子在公园散步时产生的,但不要告诉她。好吧,她已经知道当我们在一起的时候,我倾向于考虑机器学习。

当我和妻子在公园散步时,我的好主意就来了

有时候你只需要后退一步,做一些完全不同的事情:去公园,去喝杯啤酒,和你的朋友聊聊天,然后最好的想法就来了。

怎么做才能擅长机器学习?

我的跑步教练告诉我,如果你想保持身材,你需要耐心,你的技术水平来自耐心。我认为在数据科学中也是如此。

你需要花一定的时间编码,经历失败,从中吸取教训。

如果你花足够的时间学习和提高,结果就会到来。

当我与初级数据科学家交谈时,他们问我关于 Kaggle 的问题,我总是告诉他们,忘记结果,专注于一致性和学习。如果你花足够的时间学习和提高,结果就会到来。

你现在在学什么?

我现在的研究集中在两个领域。

第一个是强化学习。我认为这是一项具有巨大发展潜力的技术。我觉得我过去探索的还不够。

强化学习是一项技术,我相信它有着巨大的发展潜力。

另一个实际上是我在 INSEAD 做的关于无意识偏见的研究,以及这些偏见如何影响我们的决定。

这对我来说非常有趣,因为我同时在机器学习和人类学习领域。分析和观察人类和机器在学习过程中的相似之处是非常有趣的,我们在这里得到的一些结论也非常有趣。

分析和观察人类和机器在学习过程中的相似之处是非常有趣的

例如,我认为,现在的大话题是组织中的多样性和包容性。我认为机器在多样性和包容性方面比人类先进得多。这是为什么呢?

如果你还记得在 Kaggle 竞争中,有时在生产环境中,不是一个单一的模型获胜,而是由不同模型组成的团队获胜。因此,对于任何机器学习算法来说,很明显,你的建模堆栈中应该有不同的模型,但对于人类来说却不是这样。

此外,如果你想一想,我们不分析团队如何一起工作的结果,而是看个人。我们给予个人绩效奖金,我们根据个人绩效进行招聘,但实际上拥有一个最好的四人团队与拥有最好的四个人是不同的。

拥有一个最好的四人团队不同于拥有最好的四个人。

这是一个完全不同的问题,因为我们无法测量团队的效果,我们最终只能在一个环境中测量我们能测量的,个人表现。在招聘中,我们考虑这个特殊的人,通常不是在一个更广泛的团队的背景下,而是作为一个个体。

例如,假设你有一个非常大的公司的董事会,你有四个人,年龄在 40 到 50 岁之间,有哈佛学位的白人男性。您想要添加一名新的董事会成员,而您的招聘流程找到了与董事会成员相似的另一个人。作为个人,他可能比其他候选人更好,但如果你考虑团队,可能会有更好的候选人,他们的背景完全不同。

多样性意味着对你的“模型”进行衍生,这对机器学习行业的每个人来说都是非常明显的,但对人类来说很难掌握,因为我们无法测量它。

多样性意味着对你的“模型”进行衍生,这对机器学习行业的每个人来说都是非常明显的,但对人类来说很难掌握,因为我们无法测量它。

遗憾的是,我们现在没有好的解决方案。但我认为这是一个值得问的好问题,是一个值得花时间讨论的好问题。

怎样才能成为 AI 的掌门人?

我觉得最重要的事情是总是做你喜欢的事情,因为如果你在做你喜欢的事情,就很容易成功。

如果你在做自己喜欢的事情,那就很容易成功

我坚信一些热爱编码的资深和非常 t 的技术人员应该只做编码,他们会用他们的编码技能自然地领导团队。

那些喜欢和其他人交谈并能够组织获取不同来源数据的人,他们应该这样做,因为他们会给团队带来很多价值,团队也会随之而来。

也就是说,我认为技术人员的职业发展是一个公司并不真正知道什么是最好的方法的领域。很难调和对优秀编程技能的需求和对管理人员的需求。

我一直劝,做自己喜欢的事,做得非常非常好,你的领导力就来源于此。

无论如何,我总是建议,做你喜欢的事情,做得非常非常好,你的领导力将由此而来。

所有关于管理和与人打交道的培训都是次要的。你作为首席数据科学家或团队领导的身份,自然应该来自于你真正的激情。人们总是追随在他们所做的事情上真诚的人。

当然,你需要一些我们已经讨论过的特殊领域的专业知识,比如:

  • 问题框架
  • 数据采集
  • 处理非平稳性
  • 管理和指导年轻同事

如果你学会了那些你真正热爱的东西,你自然会成为一名领导者。

我需要提到的是,包括我自己在内的开发人员倾向于只关注提高技术编码技能。当然,技能越高越好,但是当你已经精通技术时,提高你在其他领域的技能会对你的职业生涯产生更大的影响。

当你已经精通技术时,提高你在其他领域的技能会对你的职业生涯产生更大的影响。

你有什么最终的想法吗?

我认为人工智能到目前为止,这是人工智能的一个非常广泛的反映,已经对技术(计算机视觉,自然语言处理)产生了巨大的影响,但它对现实生活产生强烈影响的应用却少之又少。

人工智能对技术产生了巨大的影响,但它对现实生活产生强烈影响的应用却少之又少

我强烈鼓励这样的应用,我相信教育和医疗保健是影响最大的两个领域。

我鼓励人们在那里工作,并思考人工智能和机器学习如何改变这种情况,因为我喜欢认为机器学习和人工智能是社会将发生的下一件大事。

也就是说,到目前为止我还没有看到。我已经看到它在技术领域工作得很好,但是为技术而技术并不有趣,它应该改变我们的生活。

采访人工智能的负责人:弗拉基米尔·里巴科夫

原文:https://web.archive.org/web/https://neptune.ai/blog/interview-with-head-of-ai-vladimir-rybakov

不久前,我们采访了 WaveAccess 的数据科学主管 Vladimir Rybakov,他是一位向 ML 团队传达商业信息和向商业人士传达 ML 问题的大师。

我们讨论了:

  • 如何在极端压力下快速解决问题
  • 承担责任如何帮助你在职业生涯中取得进步
  • 为什么寻求帮助可能是需要学习的更重要的技能之一
  • 还有更多!

查看我们对话的完整视频:

https://web.archive.org/web/20221206040656if_/https://www.youtube.com/embed/9vuF01EBmH8?feature=oembed

视频

接下来的不是一份一对一的抄本,而是一份经过整理、结构化和重新措辞的抄本。

可以看视频获取原始内容。

你的团队结构是怎样的?

WaveAccess 是一家相当大的公司。我们现在有 400 多人,为我们的客户定制软件开发解决方案。

如果我们具体谈论我们的数据科学团队,现在大约有 10 人,但如果你算上支持数据科学和机器学习工作的其他人,可能有 30 到 40 人左右。

你在做什么项目?

就我们正在做的项目而言,我实际上无法指定我们关注的任何主题领域,因为我们实际上在文本挖掘、计算机视觉、预测以及数据分析方面做各种各样的事情。基本上什么都有。

我认为我们现在看到的最主要的方向是将机器学习和数据科学应用于 CRM 系统。我们收到了很多关于将机器学习应用于客户数据的询问。如果你想一想,这些可能是公司需要手动处理的巨大数据集,很容易出现人为错误,可以自动化。

我认为我们现在看到的最主要的方向是将机器学习和数据科学应用于 CRM 系统。

另一个大方向是文本挖掘。它实际上与那些 CRM 系统密切相关,我们也有很多计算机视觉项目。

一些最大的问题实际上与视觉有关。最近我们一直在研究这个项目,我们将根据卫星图像分析人们是否在他们应该在的地方种植作物。

正如你所知,俄罗斯是一个相当大的国家,如果你开车去那里,手动检查,这将需要很多时间,你可能不会找到一切。

需要注意的一点是我们实际上不得不从头开始开发这个模型。根据我的经验,很多开源的东西,我会说 60-70%实际上是不太有用的。Github 自述文件上显示的结果是经过精心挑选的,给人留下了良好的印象,但当你尝试使用它时,它们并没有那么好。

你的职业道路是什么?

在过去的两年里,我一直是数据科学的主管,我花了大约 5 年时间才达到这个级别。

不少人只是随意问我:“怎么,怎么会这样?我是如何这么快成为数据科学主管的”。

不过,好吧,我们会说到的。说到我的背景,我是一名数学家。开始学物理但决定转专业,进了实用数学。

我想,在我四年级的时候,我学习了人工智能,并对它产生了浓厚的兴趣。我开始与我的教授密切合作,我们得到了几笔资助,我有幸在数据科学领域攻读了硕士学位。

在那之后,我做了一年的软件开发员,但我并不太喜欢这份工作。我们在非常健壮的旧系统上工作,但是没有太多改变的空间。我根本没有看到自己在那里成长,我决定改变这一点。我想你开始看到一种模式。

所以我决定尝试自由职业者的生活,数据科学自由职业者。因为我是一个人工作,这很难,因为我实际上没有任何人可以给我建议。

那是 6 年前的事了,我记得那时我没有太多的资源可以用来学习。

这是一个有趣的项目,我必须根据脸和耳朵的形状对人的性格进行分类。

无论如何,这是一个有趣的项目,我必须根据脸和耳朵的形状对人的性格进行分类。长话短说我们和客户关系不太好,我决定另谋高就。

我已经 25 岁了,还是一名初级开发人员。我找了一个月左右,但我设法得到了两个报价。我记得一个来自伊莱克斯,另一个来自 WaveAccess。

起初,我打算接受伊莱克斯的邀请,但后来我想我真的不喜欢在有很多官僚主义之类的大公司工作。我想如果我去那里,我将只是另一个小贡献者。WaveAccess 当时只有 100 多人,我认为这是一个更好的选择。

所以我开始做算法专家,我知道这听起来很酷。我会用 Java 开发处理图形数据的算法。

过了一段时间,我决定去找我的首席技术官,告诉他:“好的,我了解数据科学,有什么项目我可以帮你的吗?”

过了一段时间,我决定去找我的首席技术官,告诉他:“好的,我了解数据科学,有什么项目我可以帮你的吗?”他的回答是“没有”。

过了一段时间(顺便说一下,他的名字叫亚历山大)他回来告诉我:“这是你的机会,这个大公司有一个小项目,我们需要创建这个 POC。一周能送过来吗?”

我做到了,我的数据科学生涯就这样开始了。我是 WaveAcces 的第一位数据科学家,在许多项目上努力工作,学到了很多东西。

过了一段时间,当我们接到这个需要预测船只航线的大项目时,我开始为我的团队雇佣第一个人。

既刺激又累。我还记得我做的一个客户演示。这是一场编码马拉松,我在办公室连续呆了 40 个小时,没有睡觉,但我让它开始工作并按时交付。

我还记得我做的一个客户演示。我在办公室呆了 40 个小时,这是一场编码马拉松

我们一直在壮大这个团队,现在已经有 10 个人了,所以你可以猜到现在变得容易多了。

我要说的是,从这里可以得到一个很大的收获:

  • 我不想决定做我不喜欢的事情
  • 当我看到一个机会,我就抓住它,尽我所能

你现在的角色最让你惊讶的是什么?​

我没有意识到在以下方面需要做多少额外的管理工作:

  • 策划,
  • 预算,
  • 管理团队,
  • 展示您的结果

所以我大部分时间都花在了会议上:

  • 我倾听团队在项目中所做的工作,
  • 我试图弄清楚他们需要什么才能成功,需要做什么
  • 我和客户交谈,告诉他们我们做了什么,或者做演示

我还花了很多时间和市场营销和销售团队在一起,因为他们需要我们最近完成的项目,以便在他们的活动中使用这些信息。

我想说,如果你不是一个喜欢被关注的人,那么数据科学主管可能不适合你。

我想说,如果你不是一个喜欢被关注的人,那么数据科学主管可能不适合你。会有很多与客户、团队、面试人员等的谈话。在这种情况下,你必须感到舒服。

成为一名优秀的数据科学领导者的关键技能是什么?

我肯定地认为沟通是其中之一,但在我看来,一个领导者最重要的技能是总是有后备计划的能力。

一个领导者应该具备的重要技能是总是有后备计划的能力。

如果出了问题,你就是那个需要带领人们去哪里的人。告诉人们我们如何修复它。通常你团队中的某个人会有解决方案,但是如果其他人都没有,那就由你来提出建议。

所以我认为一个好的领导者应该是一个伟大的问题解决者。你需要有这种能力去解决连你自己都不完全理解的问题。

在数据科学中,有许多主题领域,你不可能知道所有的领域,有时客户会找上门来,要求你在有机会彻底考虑之前提出一个解决方案。

有时候,在你有机会彻底考虑之前,客户会进来要求你想出一个解决方案。

当这种情况发生时,一个新的请求进来了,而这个主题对我来说是完全陌生的,我只是试图把它归结为一些基本的东西,而放弃所有的细节。

首先,你需要理解问题的核心,并把你理解的概念写下来。

首先,你需要理解问题的核心,并把你理解的概念写下来。之后,你可以根据之前项目的经验提出解决方案。

然后我试着问很多,尽可能从他们的角度理解问题。

然后我试着问很多,尽可能从他们的角度理解问题。

最后,我试图提出一个通用的解决方案,它基于一些简单的构建模块,而不涉及太多的细节。

大多数时候,客户希望感觉你在掌控一切,你知道一切,当然,这并不总是对的,但这就是现实。

这种通用解决方案带来了非常粗略的时间和成本估计,我敢说有 30%的误差。

当客户乐意继续时,我就开始问很多问题。我尽量深入挖掘细节。

当客户乐意继续时,我就开始问很多问题。我试着尽可能深入挖掘细节。

从我的经验来看,在你真正开始工作之前,你是无法理解这个项目的。但是一旦你这么做了,就没有借口了:你必须完全理解这个问题。

我也试着去理解他们的一面,理解他们不理解的地方,并花很多精力去和他们交流。我认为客户和顾问使用同一种语言是绝对重要的。

这实际上是我们现在正在追求的东西。我们正在举办有很多顾问-客户会议的研讨会。我认为,在数据科学市场的买方中,有许多人不了解可以做什么或需要什么来构建东西,而这些咨询会议有助于业务人员从数据科学的角度来看这个过程。

一旦所有人都说同一种语言,交付好的项目就容易多了。

一旦所有人都说同一种语言,交付好的项目就容易多了。

另一项非常重要的技能是承担责任。不承担责任,就不会成长,就这么简单。

我认为,每个人提升自己角色的最佳方式是去找你的老板,问“我需要做什么才能加薪”。问“我怎样才能在我参与的项目中承担更多的责任”,

想想你如何能给公司带来更多的价值。

与其解决一项任务然后完事大吉,不如想想你的解决方案如何能带来更多价值。有没有办法改善需要这个任务的流程。我能改进吗?这类问题。

另一件事是,你需要一个好老板,他会对你承担越来越多的责任和所有权感到满意。我很幸运有一个这样的。

谈到运气,俄罗斯有句谚语:

“只有努力工作的人才会幸运”

所以,是的,我认为没有保证,但你可以把自己放在一个事情会为你发生的位置。

还有一件事我觉得非常重要,那就是了解最新的想法和成果。事物过时的速度如此之快,令人疯狂。我认为跟上所有这些是工作描述的很大一部分。

对你来说最难学的技能是什么?

我认为最难学的技能是与将组织从 2 或 3 个人扩展到更大的单位相关的东西。

我很难将官僚主义、行政管理和结构引入我们的部门,因为这违背了我的本性。在某些时候,我明白这是必要的。

随着您在组织中的成长,您管理的越来越多,发展的越来越少。

另一件事是,随着你在组织中的成长,你管理得更多,发展得更少。

我在这方面很挣扎,因为我想发展,还有很多其他的事情需要我去做。

但是当我明白我不再是一名开发人员,而是一名经理时,事情就变得简单了。

在某些时候,发展自己是不划算的,你必须接受这一点。

在某些时候,发展自己是不划算的,你必须接受这一点。你应该做很多其他更重要的事情。

我想,当我在攻读管理学研究生时,我真正理解了这一点。我想了解商业是如何运作的。我强烈建议任何愿意发展数据科学事业的人。

我认为,在 5 年或 10 年内,那些投入更多时间来理解他们所创造的东西的商业价值的数据科学家将保持相关性,不管 auto ml 和诸如此类的事情会发生什么。

现在这些都不是很好,但他们会变得更好。所以你需要贡献的不仅仅是试衣模特。

我觉得理解商业等式的另一面至关重要。

参加这个课程帮助我更好地沟通,我的项目管理技能也变得更好。现在一切都顺利多了。

即使填写这些计划或构建 GANT 图表很无聊,但从长远来看,这是值得的。

即使填写这些计划或构建 GANT 图表很无聊,但从长远来看,这是值得的。

你如何让自己保持消息灵通?

我在推特上关注一群聪明人!

你可以从他们身上学到很多东西。每当一篇令人兴奋的新论文出现,我都会从他们的推特上知道。

我也经常阅读 Medium。我认为就好的而非纯粹的学术文章而言,它可能是你能在互联网上找到的最好的资源。

我也经常阅读 Medium。我认为就好的而非纯粹的学术文章而言,它可能是你能在互联网上找到的最好的资源。

有一些 YouTube 频道,比如我非常喜欢的两分钟论文。就在最近,有一个关于开放人工智能论文的视频,其中他们谈到了模型手术的概念。所以他们开发了这种方法,你可以在模型训练的时候看到它的内部。

我发现它很迷人。

人应该学什么才能擅长数据科学?

这里已经有很多内容了,但我想这里还有一点我想说的。

我采访了很多新的候选人,我看到很多人在网上参加了一系列课程,他们突然相信自己是数据科学家。

我真的认为人们应该把手弄脏来练习。

我真的认为人们应该把手弄脏来练习。你可以做自己的项目,甚至可以独自去尝试你所学的东西。

说到卡格尔,那是个好地方。我说的不是竞赛和奖励,而是通过讨论和人们展示作品的核心来学习。你可以从这里学到很多东西。

还有一件事我觉得真的很重要。它不是技术性的,但价值不减。

我坚信你应该是个好人。对你的团队和你周围的人都有好处。

我坚信你应该是个好人。对你的团队和你周围的人都有好处。你知道我们部门的结构,它是相当水平的。当然,最终决定权在我,但我不会把自己凌驾于他人之上。

你应该树立榜样,不仅在知识方面,而且在交流方面。你在设定标准,创造工作场所的文化。永远不要忘记这一点。

为什么学习如何寻求帮助很重要?

我们办公室有这个规定。

如果有人遇到问题,在 30 分钟内,他不知道如何解决这个问题。然后他需要去寻求别人的帮助。

如果有人遇到问题,在 30 分钟内,他不知道如何解决这个问题。然后他需要去寻求别人的帮助。

这并不是说他必须在 30 分钟内解决问题,但是如果在网上查找资料并思考后没有解决方案,他应该寻求帮助。超过 30 分钟的任何事情都是浪费时间。

我希望我的团队在寻求他人帮助时感到自在。我总是请人给我解释论文和想法。我不可能从所有最新的论文中知道所有的窍门。但是很可能我的团队中有人理解它。

也就是说,你必须记住这里有一个微妙的平衡。如果你总是寻求帮助,你将不会成长,但是如果你试图自己解决所有的事情,你将会在这上面花费太多的时间。

你有什么最终的想法吗?

你知道,我最近看到了这个迷因,它说“数据科学是痛苦的,如果有人告诉你不同的话,他们是在向你出售东西”

“数据科学是痛苦的,如果有人告诉你不同的说法,他们就是在向你推销东西”

不,但是严肃地说,我认为最重要的一点是,无论你是初级专家还是数据科学主管,都要记得享受工作的乐趣。

不管你是初级专家还是数据科学主管,最重要的一点是要记得享受工作的乐趣。

我强烈反对那些开始做事的人,因为这是一个有利可图的领域。做你喜欢的事,成功就会随之而来。

采访首席数据科学家:Gabriel Preda

原文:https://web.archive.org/web/https://neptune.ai/blog/interview-with-lead-data-scientist-gabriel-preda

在我们播客的最新一集《有效的机器学习》中,我非常高兴地与 Endava 的首席数据科学家兼 Kaggle 特级大师 Gabriel Preda 进行了交谈。

我们讨论了:

  • 他在恩达瓦的工作,
  • NLP,
  • Kaggle 比赛,
  • 以及如何让自己处于一个不断学习的位置。

如果你想看完整的采访,这里有视频版本。

https://web.archive.org/web/20221206165347if_/https://www.youtube.com/embed/bB1tcoQJ72g?feature=oembed

视频

另一方面,如果你喜欢阅读,我也准备了一份摘要。这不是我们谈话的忠实记录,而是采访的结构化和重新措辞版本,包括关键点和观察结果。

事不宜迟,让我们见见加布里埃尔·普雷达!

你现在在做什么?

我在 Endava 工作,这是一家软件服务公司,我们的项目实际上是我们客户的项目。首先,我想说的是,当我谈论我的活动、我正在从事的项目、团队的结构以及我们为满足客户需求而付诸实践的技能工具集和技术时,我不能总是分享所有的细节。

无论如何,当我们向客户提供服务时,我们在多功能团队中工作,这与一般的数据项目没有什么不同,或者更具体地说,与包含数据科学或机器学习组件的数据项目没有什么不同。

举个例子,在我们最近进行的一个项目中(在医疗保健行业),Endava 的主要团队包括:

对于项目的 poco 部分

  • 数据架构师,
  • 数据分析师,
  • 数据工程师,
  • 和数据科学家。

对于生产部分:

  • 我们增加了 DevOps 开发人员和一名数据科学家。
  • 我们将数据分析师和数据工程调整为兼职。

因此,我们开始专注于理解问题,并为客户提供可能的解决方案。然后,当我们就客户希望我们在生产中实施的一个特定解决方案达成一致时,我们的重点就从开发想法转向实施它们。因此团队的结构发生了变化。

当然,团队的规模和结构取决于项目的结构和阶段。

你的客户的项目相似吗,他们有共同的关注点吗,或者他们可能完全不同?

我们在特定领域发展了某些能力或专长,并且我们不断发展这些技能。但是,大多数时候,我们必须找到客户的问题,理解它,并提出解决方案。此解决方案不仅要响应客户的业务需求,还要适应特定的环境。

所以有些情况下,我们有充分的自由,例如,我们可以在云中构建我们的解决方案,并在 Azure 和 AWS 中实现它。另一方面,有时我们有非常严格的限制。

然后,我们必须在很多约束条件下构建一些东西,因此,我们的解决方案必须适应这些条件。一般来说,对于许多客户,我们必须做大量的自然语言处理。这是因为来自我们客户的大量数据都是像文档这样的文本信息形式。这真的取决于业务,当然,我不会在这里具体说明,但我会说,我们做了很多 NLP。有时候是计算机视觉和 NLP 的结合,从文档中提取各种内容。

我们使用现有的自然语言处理技术,但有时我们需要非常有创意。例如,在我们的一个项目中,我们必须开发一些技术来应对非常不标准的英语。它包括许多乏味的手工工作,但有时你也必须做这种清洁工作。在许多项目中,甚至在开始使用模型之前,就要探索数据、清理数据和准备数据。

当然,你所获得的知识,做各种练习,在一些行业网站上发布内容,做个人项目都以某种方式整合在一起。在某个时候,你会将它用于一个新项目。

当然,我不是说复制粘贴它,但它将为你服务于一个新的目的。我觉得这是我们大多数人学习和进步的一种方式。

你是如何成为数据科学家的?

我认为有两三个步骤导致了这一点。大约 20 年前,我在一个从事机器学习的小团队中,当时并不知道有一个词来形容机器学习。有时候我会拿这个开玩笑。我在大学的核工程系做博士后,我们正在研究的问题非常简单。是关于水冷系统中有裂缝的水反应堆。这些裂缝可能会发展并导致事故。为了解决这个问题,我们试图猜测这种效应的几何形状。所以我们试着训练一个神经网络,在那个时候,仅仅几百个案例的训练就花了我们两三天的时间。网络是用 Fortran 语言编写的,我们的模拟代码也是如此。

所以我会说我总是很好奇,那时我正在发表一些东西。但直到最近,我才开始对数据科学中的应用更加好奇。大约 3 或 4 年前,一位同事邀请我参加一个内部专业会议,在一大群观众面前做一个关于数据科学的演示。但我并不真正了解什么是数据科学。此外,我还得做一个关于在数据科学中使用 R 的演示。而我也对 r 了解不多,所以基本上两个月,每天都在学习。我记得那是一个假期。我的家人在黑海的某个地方玩得开心,而我却在晚上学习。但我做到了,我面对了挑战,我做了一个体面的陈述。

在此期间,当我在寻找所有的信息和知识时,我也发现了 Kaggle。

那时,你正在管理软件项目。是这样吗?

是的,我是项目经理。你可以想象一下,作为一个项目经理,你没有很多时间。看起来好像项目经理什么都不做,但这就是秘密。如果你工作做得好,看起来你什么也没做。所以,我想我是一个好的项目经理,因为人们对我的项目非常满意。

我认为这是优秀项目经理的最佳定义——让事情进展顺利。

项目经理经常制造危机来解决它们,这是很常见的。人们倾向于说,这是解决危机的人。但问题是他也是制造危机的人。所以我尽量避免这样。

回到我的 Kaggle 活动——我没有太多时间,所以我白天是项目经理,晚上是 Kaggler。当我在数据科学方面积累了知识,并在 Kaggle 上获得了经验时,我开始做相当多的机器学习。此外,在我的公司,人们开始对数据科学感兴趣。当时我们有一些和数据相关的项目,但并不认为是数据科学。

我们在 Endava 有许多专业社区,我们开始邀请人们就技术主题甚至是项目主题进行演示。我们邀请了公司的人,但有时也会邀请外部人员。这几乎在任何地方都在发生(Endava 在欧洲和南美洲的许多国家都有办事处),人们对此很感兴趣,也想学习。目标是在建立正式的组织之前先聚集一些结构。

反正大部分时间也是在公司外学习。大概两年前,我很活跃,开始做比赛。我在比赛中不太成功。所以我会说,从计算预测建模的角度来看,我不是一个好的数据科学家。人们认为这不太相关。我想说这是非常相关的。这不仅对你的地位非常重要,而且实际上,它显示了你解决问题的知识水平。

我学习数据科学或机器学习新知识的最重要方式是参加比赛,即使我没有获得很高的排名。

在与他人竞争的同时,你在很短的时间内解决一个非常复杂的问题所付出的努力加速了你的学习曲线。

在某个瞬间,我觉得自己达到了某个层次,没有进步。所以我回来学习——我从 Coursera 和技术文章中学到了很多。

所以你在那段时间学习,竞争,但也改变了你在 Endava 的角色,对吗?

我不再做项目经理,我开始做数据科学家,这仍然是我的职位。有时这有点令人沮丧,因为我在那里看到了项目管理问题。但我尽量支持现有的项目经理。

作为一名首席数据科学家,你的日常工作是怎样的?这些天你做了很多管理工作,还是你的任务更有技术含量?

在 Endava,根据你的资历,你可以有一些管理任务。角色也可能因项目而异。比如现在的项目,我不是领导团队,我只是团队的一员。我现在的角色只是开发解决方案。我致力于概念验证,然后和一个团队一起,在当前的应用程序中实现它。所以我不得不重新开发我的开发技能。因为从概念验证到编写生产代码,这是一个漫长的过程。但是,当我的代码是垃圾时,我可以很容易地识别出来。

我想这是件好事。我感觉一旦你从半年前开始看你的代码,它看起来并没有那么糟糕,你认为它相当不错,这意味着你并没有真正进步那么多。

是的,这是一个很好的说法。我想成为实施解决方案的团队的一员,因为你在这方面学到了很多。我想在我的日常工作中快速学习,而不仅仅是在比赛和游戏世界中。我还希望能够涵盖采购的整个生命周期,从早期调查到为生产编写代码。不一定成功,但是不舒服也是好事。因为当我说我完成了,没有任何进展的时候,就是休息的时候。

你认为这一刻会到来吗?

如果你厌倦了战斗,我想。

如果我用几句话来说,如何成为一名优秀的数据科学家,我会说你必须不断学习,并尽可能多地将自己置于可以从各种职业经历中不断学习的角色或环境中。

积极参与社区活动。正如我所说的,把这种经历也带到你的项目中去。当然,反过来也有帮助。你正在编写的代码的组织和健壮性也可以帮助你进行有竞争力的预测建模。因为它促使您编写更健壮和可重用的代码。

当很多人应该在家的时候,让你忙着解决难题是应对当前情况的一个非常好的方法。利用这个机会发展你的技能是很好的。

你还有什么其他的方法或者窍门可以一直坚持学习下去吗?

我试图了解数据科学或机器学习中对我来说新的领域。这并不总是很成功,但有时我只是朝一个方向努力,所以我感到不舒服。我只是去学习别的东西,然后带着更多的精力和决心回来。因为我正在处理我脑袋后面某个地方的第一件事,所以我从不放弃。

你认为在工作中最重要的核心技能是什么,尤其是如果你想发展你的数据科学职业生涯的话?

  • 我获得了计算电磁学的博士学位,我认为所有数学方法论的知识对我帮助很大。合适的背景是有帮助的。
  • 另一件事是,每次我在学东西的时候,我觉得我需要看到它才能理解它。我试着想象事物。
  • 最后,如果你在某个领域有所进步,试着把知识用在某个实际问题上。

说到我使用的工具,我没有具体的工具。我有一个基本的 NLP 工具集(NLTK,SpaCy,GenSim),但有时我不得不切换。我开始用 PyTorch。我曾经和 Keras 和 TensorFlow 合作过。我必须熟悉基于云的工具,比如 SageMaker。

使用能够加速这个过程的工具总是好的。

同时,当你没有这些工具时,你需要为项目做好准备。碰巧的是,虽然我有一个很好的、准备好的解决方案,但由于受到限制(缺少库、内存限制),我无法使用它。我不得不回到早期我用 Fortran 编程的时候,那时我们重用变量,因为我们不能把东西放进内存。有时也有预算限制。此外,当你为企业创造一些东西,并且它应该工作多年,你不应该使用非常复杂的资源。所以,是的,当谈到工具时,有灵活性是好的。

如果你要教育数据科学家(刚刚起步,甚至已经工作但经验不足的人),你会建议他们做什么?

首先也是非常重要的是从基础做起。现在,每个人都想学习最新的解决方案,但他们应该真正理解非常简单的算法是如何工作的。当他们必须向企业解释他们的工作并获得他们的信任时,这尤其有用。解释结果与构建好的解决方案同样重要。能够可视化这些结果也很重要。

当你有问题要解决时,先尝试简单的解决方法。

你总是要尽可能简单地开始。我还建议学习整个机器学习管道,因为它给你更多的机会。

你有什么最后的想法要分享吗?

我把你的问题变成一个笑话。没有期末考试,所以我们会继续…继续学习!

圣诞节到了——这是你在假期学习机器的最佳资源!

原文:https://web.archive.org/web/https://neptune.ai/blog/its-christmas-time-your-best-resources-about-machine-learning-for-holiday-season

有两种人——喜欢圣诞节并沉浸在节日狂热中的人,和宁愿飞到一个荒岛上等待这一次结束的人。

我们有好消息要告诉你!无论你是哪种类型的人,你都会在这篇文章中找到适合自己的东西!

所以圣诞节是一个特定的时间。事实证明,这在机器学习领域也很受欢迎。在这个特殊的时刻,为了帮助你站在…潮流的顶端,我们为你的假期阅读清单整理了一份最佳资源清单。

看看吧,享受吧,学习吧!

圣诞节的最佳资源

我们试着教一个人工智能写圣诞电影情节。欢声笑语随之而来。最终。作者凯伦·郝在《麻省理工科技评论》上

使用神经网络来创建荒谬的情节需要大量的工作,并揭示了生成人类语言的挑战。一定要检查一下,看看热闹的结果!

Reddit 永远不会让你失望!如果你正在寻找关于人工智能的书籍,作为礼物送给你家人、朋友中的数据科学家,或者想为自己买些东西,你可能会在这个 Reddit 帖子中找到一些有趣的东西: 圣诞礼物:关于人工智能的书籍

尽管是从去年开始的,这个机器学习圣诞节 拥有圣诞节前 24 天的每日内容、文章和播客。关于 ML 的一切!

非常适合基督降临节日历的粉丝!

这是一幅关于人工智能和新技术如何改变圣诞节的漫画😉

谷歌的圣诞老人追踪器

自 2004 年以来的每一年,你都可以用谷歌的圣诞老人追踪器追踪圣诞老人在世界各地的行程。它基于人工智能,有一套关于编码基础和世界各地圣诞节传统的游戏和课程计划。

这是和家人,尤其是孩子共度时光、放松和学习新事物的好方法。

一个神经网络在 digg 上写了一首会萦绕你的梦的圣诞颂歌

**机器学习被广泛用于生成歌曲。所以为什么不让它写首圣诞歌唱首呢?

多伦多大学的研究人员训练了一个神经网络来写一首新的圣诞歌曲,结果是…不太好。你自己听听吧!

Synthesia 是一个创新的内容创作工具,允许你创建自己的人工智能视频。还有一个人工智能圣诞老人,让你给朋友、爱人甚至你的老板生成个性化的愿望。

这是我们对你的祝愿!

我想要的圣诞礼物就是人工智能:用汤马索·布诺科尔的《T2》写下下一个圣诞大热门

那么让我们回到创作圣诞歌的话题上来。你曾经梦想过创作自己的圣诞颂歌吗?是的,你可以做到,当然是用人工智能😉

这是一个很好的指导,可以帮助你用机器学习创作一首圣诞歌。这对所有热衷于人工智能生成文本的人来说都是有帮助的,对圣诞歌曲的例子也是一个很好的解释。

与此同时,这是一个有趣的阅读,它展示了如何设计非常复杂的网络来更好地解决文本生成的问题 。

**你喜欢圣诞装饰和所有明亮的灯吗?那你会喜欢这个的!作者在这篇写得很好的文章中描述了他如何着手创建自己的圣诞灯光秀。在神经网络的帮助下闪烁的灯光和歌声。

这是一个很好的实验,你可以在家里做,所以一定要检查出来!

连圣诞老人都需要大数据!

终极人工智能圣诞礼物创意清单蒂姆·古尔克

如果你还在寻找很酷的圣诞礼物,这个列表可能会对你有所帮助。你会为 ML 的狂热实践者找到一些东西,初学者、项目经理、学生、女朋友、男朋友——为每个人!

在 SciBite 上创建标签化训练数据的 12 天机器学习技巧

创建带标签的机器学习训练数据的 12 个顶级技巧。简单却有效。这会帮助你为你的实验创造更好的模型。

一个机器人发明的圣诞菜单由英国广播公司的理查德·格雷制作

圣诞节意味着大量的食物。那么所有的剩菜怎么办?扔掉它们不好。所以为什么不向 AI 求助呢!

世界各地的许多研究团队一直在开发人工智能系统,这些系统能够从现有的食谱中学习,然后提出自己的一些食谱。编辑们询问了两种创新算法背后的研究人员,以了解他们的人工智能对圣诞食物的看法。

结果如何?好吃吗?自己检查!

会发生什么,如果圣诞老人用 ML 给人送礼物,最好不要知道😉

圣诞快乐!

无论你是在这个假期训练你的人工智能模型还是阅读人工智能,不要忘记休息一下,花一些时间与朋友和家人在一起,进行一些人际互动😉

祝你有一个非常机器学习的圣诞节!

Have yourself a very machine learning Christmas!****

机器学习的 19 个最佳 JupyterLab 扩展

原文:https://web.archive.org/web/https://neptune.ai/blog/jupyterlab-extensions-for-machine-learning

Jupyter 的旗舰项目 JupyterLab 是数据科学领域最受欢迎和最有影响力的开源项目之一。Jupyter 生态系统的一大优点是,如果你缺少什么,要么有一个开源扩展,要么你可以自己创建它。

在本文中,我们将讨论 JupyterLab 扩展,这些扩展可以使您的机器学习工作流更好。

什么是 JupyterLab 扩展?

正如 JupyterLab 的人们所说:

“JupyterLab 被设计成一个可扩展的环境”。

JupyterLab extension 只是一个即插即用的插件,它使您需要的更多东西成为可能。

从技术上讲,JupyterLab extension 是一个 JavaScript 包,可以向 JupyterLab 界面添加各种交互式功能。如果你想知道如何创建自己的扩展,请阅读本指南。

如何管理 JupyterLab 扩展

有大量的 JupyterLab 扩展可供您使用。

您如何管理所有这些扩展?

扩展管理器 (命令面板中的小拼图图标)让你直接从 JupyterLab 安装和禁用扩展。我强烈推荐。

如果你的扩展管理器需要添加插件,看看我们的机器学习最佳 JupyterLab 扩展列表。

最佳 JupyterLab 扩展

我们不能谈论 JupyterLab 对机器学习的扩展,而不提到我们建立的帮助人们跟踪实验、数据探索和在笔记本上发生的错误分析的扩展。

Neptune-notebooks 扩展让您:

  • 点击一个按钮发送或下载笔记本电脑检查点从海王星
  • 比较海王星的检查点,分享给团队。

让我展示给你看:

如果看起来有趣,请查看我们的文档。

JupyterLab TensorBoard 是 JupyterLab:)上 TensorBoard 的前端扩展。它使用 jupyter_tensorboard 项目作为 tensorboard 后端。它通过为 jupyter 界面中的 tensorboard 启动、管理和停止提供图形用户界面,帮助 jupyter 笔记本和 tool for tensorflow 的可视化工具)之间的协作。

以下是它的作用:

  • 无需在命令行中键入 tensorboard 和长日志路径。
  • 不需要额外的端口来服务 tensor board——这对远程 jupyter 服务器很有帮助。
  • 多个 tensorboard 实例同时管理。

ML workspace 是一个基于 web 的一体化集成开发环境,专门用于机器学习和数据科学。

它易于部署,让您可以在自己的机器上高效地构建 ML 解决方案。该工作区是面向开发人员的通用解决方案,预装了各种流行的数据科学库(如 Tensorflow、PyTorch、Keras、Sklearn)和开发工具(如 Jupyter、VS Code、Tensorboard),经过完美配置、优化和集成。

系统监视器是一个 JupyterLab 扩展,用于显示系统信息(内存和 cpu 使用情况)。它允许您监控自己的资源使用情况。

该扩展使您能够深入了解当前笔记本服务器及其子服务器(内核、终端等)使用了多少资源,从而优化您的 ML 实验并更好地管理工作。

LSP(语言服务器协议)是一个 JupyterLab 扩展,它使进程间通信能够支持您可能想要使用的多种语言。

LSP 集成有几个详细但有用的特性:

  • 悬停显示带有函数/类签名、模块文档或语言服务器提供的任何其他信息的工具提示
  • 诊断—严重错误、警告等的颜色。
  • 跳转到定义—使用上下文菜单项跳转到定义
  • 引用的突出显示—当光标放在变量、函数等上时,所有的用法都将突出显示。
  • 触发时自动完成某些字符
  • 自动签名建议
  • 无需运行内核的高级静态分析自动完成
  • 在笔记本和文件编辑器中重命名变量、函数等
  • 诊断面板

调试器是一个 JupyterLab 扩展,作为 Jupyter 笔记本、控制台和源文件的可视化调试器。它可以帮助您识别和修复错误,以便您的机器学习模型可以正常工作。

您可以使用 JupyterLab 的 kernelspy 扩展来检查调试器 UI 和内核之间发送的调试消息。

当您使用 VS 代码时,JupyterLab 调试器也很有帮助,因为您可以检查调试消息以了解何时发出调试请求,并在 VS 代码中比较 JupyterLab 调试器和 Python 调试器的行为。

这是 Git 的 JupyterLab 扩展——一个免费的开源分布式版本控制系统。它允许你进行版本控制。您只需从左侧面板的 Git 选项卡中打开 Git 扩展来使用它。

这个扩展为您提供了使用的灵活性,因为它的行为可以通过不同的设置来修改。

该扩展将一些 Jupytext 命令添加到命令选项板中。您可以使用它来为您的笔记本选择所需的 ipynb/text 配对。这是一个小功能,但可以帮助你浏览你的笔记本。

nbgather 是一个 JupyterLab 扩展,它拥有用于清理代码、恢复丢失的代码以及在 Jupyter Lab 中比较代码版本的工具。该扩展为您保存了所有已执行代码的历史记录,以及它生成的笔记本元数据的输出。

下载扩展后,您可以清理和比较代码的版本。

nbgather 正处于开发的初级阶段,所以它仍然可能有一些小故障。无论如何,如果你想拥有整洁一致的笔记本,这是值得一试的。

变量检查器是 JupyterLab 的一个有用的扩展,可以显示当前使用的变量及其值。它的灵感来自 jupyter 笔记本的可变检查器扩展和 jupyterlab 中包含的检查器扩展。

至于现在,它仍在开发中,所以你可能会遇到一些小故障。以下是您可以用它做的事情:

检查 python 控制台和笔记本的变量

  • 在数据网格查看器中检查矩阵,但是,它可能不适用于大型矩阵
  • 以内联和交互方式检查 Jupyter 小部件

这个 JupyterLab 扩展为你提供了一些有助于区分和合并 Jupyter 笔记本的功能。它了解笔记本文档的结构,因此在区分和合并笔记本时可以做出明智的决策。

以下是主要功能的简短总结:

以终端友好的方式比较笔记本电脑

  • 通过自动解决冲突,三方合并笔记本
  • 查看笔记本的丰富渲染差异
  • 为笔记本电脑提供基于网络的三向合并工具
  • 以终端友好的方式查看单个笔记本

Voyager 是一个 JupyterLab MIME 渲染器扩展,用于在 Voyager 2 中查看 CSV 和 JSON 数据。这是一个简单的解决方案,允许您可视化数据。

这个扩展提供了与 Voyager 的最低限度的集成。

LaTeX 是一个 JupyterLab 扩展,允许您实时编辑 LaTeX 文档。

默认情况下,该扩展在服务器上的 xelatex 上运行,但是您可以通过自定义 jupyter_notebook_config.py 文件来自定义该命令。至于书目,它运行在 bibtex 上,但你也可以定制它。

您可以定制的另一个元素是通过触发外部 shell 命令来运行任意代码的能力。

这是一个 JupyterLab 扩展 mimerenderer,用于在 IFrame 选项卡中呈现 HTML 文件。它允许您通过双击来查看呈现的 HTML。文件浏览器中的 html 文件。文件在 JupyterLab 选项卡中打开。

Plotly 是一个 JupyterLab 扩展,用于呈现 Plotly 图表。

要观察扩展源代码的变化并自动重建扩展和应用程序,可以观察 jupyter-renderers 目录并在观察模式下运行 JupyterLab。

我们列表中的另一个位置是用于渲染散景可视化的 Jupyter 扩展。

JupyterLab 的目录扩展可能看起来不太像是一个技术问题,但是它可以在向下滚动和查找信息时为您省去很多麻烦。

当您打开笔记本或 markdown 文档时,它会在左侧区域自动生成目录。条目是可点击的,你可以将文档滚动到有问题的标题。

可折叠标题是一个有用的扩展,它让你可以折叠标题。通过点击标题单元格左侧的插入符号图标或使用快捷方式,可以折叠/取消折叠选定的标题单元格(即以某个数字“#”开头的降价单元格)。

Jupyter Dash 是一个库,可以轻松地从 Jupyter 环境(例如 classic Notebook、JupyterLab、Visual Studio Code notebooks、nteract、PyCharm notebooks 等)中构建 Dash 应用程序。).

它有许多有用的功能:

非阻塞执行

  • 显示模式:外部、内嵌、JupyterLab
  • 热重装:当应用程序的代码发生变化时,自动更新正在运行的 web 应用程序的能力。
  • 错误报告:一个小的用户界面,显示由属性验证失败和回调中引发的异常导致的错误
  • Jupyter 代理检测
  • 生产部署
  • Dash 企业工作区
  • 最后一个是 jupyterlab-sql 扩展,它向 jupyterlab 添加了一个 sql 用户界面。它允许您使用点击式界面浏览您的表,并使用自定义查询读取和修改您的数据库。

结论

JupyterLab 的列表非常广泛,因此有许多工具可供选择。您可以使用一个、两个或全部。只要确保它们不会让你的 Jupyter 空间变得拥挤,不会减慢进程。

愉快地尝试扩展!

The list of JupyterLab is quite extensive so there are many tools to choose from. You can use one, two, or all of them. Just make sure they’re not cluttering your Jupyter space and slow down processes.

Happy experimenting with extensions!

k-均值聚类解释

原文:https://web.archive.org/web/https://neptune.ai/blog/k-means-clustering

聚类是 1932 年由 H.E. Driver 和 A.L.Kroeber 在他们关于“文化关系的量化表达”的论文中引入的。从那时起,这项技术有了一个很大的飞跃,并已被用于发现未知的应用领域,如医疗保健。

聚类是一种无监督学习,其中需要从未标记的数据集中提取参考。通常,它用于捕获数据集中固有的有意义的结构、底层过程和分组。在聚类分析中,任务是以这样一种方式将群体分成几个组,即同一组中的数据点比其他组中的数据点彼此更相似。简而言之,它是基于相似性和不相似性的对象的集合。

通过聚类,数据科学家可以在未标记的数据中发现内在的分组。虽然对于一个好的集群没有特定的标准,它完全取决于用户,他们想如何使用它来满足他们的特定需求。它可用于查找数据中的异常数据点/异常值,或识别未知属性,以在数据集中找到合适的分组。

让我们举一个例子,假设你在沃尔玛担任经理,希望更好地了解你的客户,通过使用新的和改进的营销策略来扩大你的业务。手动细分客户很困难。您有一些包含客户年龄和购买历史的数据,这里的聚类可以帮助根据他们的消费对客户进行分组。一旦客户细分完成,你就可以根据目标受众为每个群体定义不同的营销策略。

What does clustering mean?

What does clustering mean? | Source: Author

有许多聚类算法被分成不同的聚类模型。在为用例选择任何算法之前,熟悉集群模型以及它是否适合用例是很重要的。在选择任何聚类算法时,还有一点需要考虑,那就是数据集的大小。

数据集可以包含数百万条记录,并且不是所有算法都能有效扩展。K-Means 是最流行的算法之一,它也是规模有效的,因为它具有复杂度为 O(n) 的 T2。在本文中,我们将深入讨论 K-Means 以及它的流行原因。

k 均值聚类

K-means 是一种基于质心的聚类算法,其中我们计算每个数据点与质心之间的距离,以将其分配给一个聚类。目标是识别数据集中的 K 个组。

“K-means 聚类是一种矢量量化的方法,最初来自信号处理,旨在将 n 个观测值划分为 K 个簇,其中每个观测值属于具有最近均值的簇,作为该簇的原型。”来源

这是一个将每个数据点分配到组中的迭代过程,慢慢地,数据点会基于相似的特征进行聚类。目标是最小化数据点和聚类质心之间的距离之和,以识别每个数据点应该属于的正确组。

这里,我们将数据空间分成 K 个簇,并为每个簇分配一个平均值。数据点被放置在最接近该聚类平均值的聚类中。有几种距离度量可用于计算距离。

K-means 是如何工作的?

我们举个例子来了解一下 K-means 是如何一步步工作的。该算法可以分为 4-5 个步骤。

  1. 选择集群的数量

第一步是定义 K 个聚类,我们将在这些聚类中对数据进行分组。让我们选择 K=3。

  1. 初始化质心

质心是聚类的中心,但是最初,数据点的精确中心是未知的,因此,我们选择随机数据点,并将它们定义为每个聚类的质心。我们将初始化数据集中的 3 个质心。

K-means clustering - centroid

K-means clustering – centroid | Source: Author

  1. 将数据点分配给最近的聚类

既然已经初始化了质心,下一步就是将数据点 X [n] 分配给它们最近的聚类质心Ck

K-means clustering - assign data points

K-means clustering – assign data points | Source: Author

在这一步中,我们将首先使用欧几里德距离度量来计算数据点 X 和质心 C 之间的距离。

然后为数据点和质心之间的距离最小的数据点选择聚类。

K-means clustering

K-means clustering | Source: Author

  1. 重新初始化质心

接下来,我们将通过计算该聚类的所有数据点的平均值来重新初始化质心。

K-means clustering

K-means clustering | Source: Author

  1. 重复步骤 3 和 4

我们将不断重复第 3 步和第 4 步,直到我们有了最佳的质心,并且数据点到正确聚类的分配不再改变。

K-means clustering

K-means clustering | Source: Author

这个迭代过程是不是听起来很熟悉?嗯,K-means 遵循与期望最大化(EM)相同的方法。EM 是一种迭代方法,用于寻找参数的最大似然,其中机器学习模型依赖于未观察到的特征。这种方法包括两步期望(E)和最大化(M ),并在这两步之间迭代。

对于 K-means,期望(E)步骤是将每个数据点分配给最可能的聚类,最大化(M)步骤是使用最小平方优化技术重新计算质心。

质心初始化方法

定位初始质心具有挑战性,目标是初始化质心,使其尽可能接近实际质心的最佳值。建议使用一些策略来定义初始质心,因为它会直接影响整个运行时间。传统的方法是随机选择质心,但也有其他方法,我们将在本节中介绍。

这是初始化质心的传统方法,其中 K 个随机数据点被选择并定义为质心。正如我们在上面的例子中看到的,在这个方法中,数据集中的每个数据实例都必须被枚举,并且必须保存每个属性的最小/最大值的记录。这是一个耗时的过程;随着数据集复杂性的增加,实现正确质心或正确聚类的步骤数量也将增加。

分片质心初始化算法主要依赖于数据集中特定实例或行的所有属性的合成总和值。其思想是计算复合值,然后用它对数据的实例进行排序。一旦数据集被排序,它就被水平分成 k 个碎片。

**Sorting by composite value and sharding

Sorting by composite value and sharding | Source

最后,将每个碎片的所有属性相加,并计算它们的平均值。shard 属性意味着值集合将被标识为可用于初始化的质心集。

Centroid attribute values

Centroid attribute values | Source

使用分片的质心初始化在线性时间内发生,并且所得的执行时间比随机质心初始化好得多。

K-means++是 K-mean 算法的智能质心初始化方法。目标是通过随机分配第一个质心来展开初始质心,然后根据最大平方距离选择其余的质心。这个想法是将质心彼此推得尽可能远。下面是使用 K-means++初始化质心的简单步骤:

  1. 随机选择第一个质心(C1)
  2. 计算所有数据点和所选质心之间的距离

这表示数据点x[I]到最远质心C[j]的距离**

  1. 将数据点x[I]初始化为新的质心
  2. 重复步骤 3 和 4,直到找到所有定义的 K 个聚类

" 通过 k-means++初始化,保证算法找到与最优 k-means 解相比具有 O(log k)竞争力的解。"来源

在 Python 中实现 K-Means 聚类

既然您已经熟悉了聚类和 K-means 算法,那么是时候使用 Python 实现 K-means,并看看它如何在真实数据上工作了。

我们将致力于商场访客数据集,以创建客户细分,从而确定营销策略。购物中心访客样本数据集可以在 Kaggle 上找到,它总结了大约 2000 名购物中心访客的消费情况。

让我们为下一阶段细分客户清理、探索和准备数据。

加载数据并检查是否有任何缺失值:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

credit_data = pd.read_csv("/content/Mall_Customers.csv")

credit_data.head()

credit_data.isna().sum()

Implementing K-Means clustering in Python.

Mall visitors dataset | Source

Implementing K-Means clustering in Python.

Mall visitors dataset | Source: Author

我们将使用年收入支出分数来寻找数据中的聚类。支出分数从 1 到 100,根据客户行为和支出性质进行分配。

从头开始实现 K 均值

有一些开源库为不同类型的聚类算法提供了函数,但是在通过调用函数来使用这些开源代码之前,理解这些函数是如何工作的非常重要。在本节中,我们将使用随机质心初始化方法从头开始构建 K-means 聚类算法。

我们来看看数据,看看是怎么分布的:

plt.scatter(customer_data['Annual Income (k$)'],customer_data['Spending Score (1-100)'])
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.show()

Implementing K-Means from scratch

Implementing K-Means from scratch | Source: Author

从上面的散点图中,很难判断数据集中是否有任何模式。这就是集群将有所帮助的地方。

首先,我们将随机初始化质心:

K=3
centroids = customer_data.sample(n=K)
plt.scatter(customer_data['Annual Income (k$)'],customer_data['Spending Score (1-100)'])
plt.scatter(centroids['Annual Income (k$)'],centroids['Spending Score (1-100)'],c='black')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.show()

Implementing K-Means from scratch

Implementing K-Means from scratch | Source: Author

接下来,我们将遍历每个质心和数据点,计算它们之间的距离,找到 K 个聚类并将数据点分配给一个重要的聚类。这个过程将继续,直到先前定义的质心和当前质心之间的差为零:

diff = 1
j=0
XD=X
while(diff!=0):

   i=1
   for index1,row_c in centroids.iterrows():
       ED=[]
       for index2,row_d in XD.iterrows():
           d1=(row_c["Annual Income (k$)"]-row_d["Annual Income (k$)"])**2
           d2=(row_c["Spending Score (1-100)"]-row_d["Spending Score (1-100)"])**2
           d=np.sqrt(d1+d2)
           ED.append(d)
       X[i]=ED
       i=i+1

   C=[]
   for index,row in X.iterrows():
       min_dist=row[1]
       pos=1
       for i in range(K):
           if row[i+1] < min_dist:
               min_dist = row[i+1]
               pos=i+1
       C.append(pos)
   X["Cluster"]=C
   centroids_new = X.groupby(["Cluster"]).mean()[["Spending Score (1-100)","Annual Income (k$)"]]
   if j == 0:
       diff=1
       j=j+1
   else:
       diff = (centroids_new['Spending Score (1-100)'] - centroids['Spending Score (1-100)']).sum() + (centroids_new['Annual Income (k$)'] - centroids['Annual Income (k$)']).sum()
       print(diff.sum())
   centroids = X.groupby(["Cluster"]).mean()[["Spending Score (1-100)","Annual Income (k$)"]]
-27.971469513699734
-22.726172762723042
1.7620315282408434
1.2618819139010924
0.0

现在,如果我们要查看数据集,所有数据点都应相应地进行聚类:

color=['grey','blue','orange']
for k in range(K):
   data=X[X["Cluster"]==k+1]
   plt.scatter(data["Annual Income (k$)"],data["Spending Score (1-100)"],c=color[k])
plt.scatter(centroids["Annual Income (k$)"],centroids["Spending Score (1-100)"],c='black')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.show()

Implementing K-Means from scratch

Implementing K-Means from scratch | Source: Author

实现 K-意味着使用 Scikit-Learn

这是相当多的代码,算法可能还需要一些优化,以改善其运行时间。为了避免增强算法并重新编写,我们可以使用开源库函数。Scikit Learn 有一个聚类包,其中包括 K-means 函数,该函数经过优化,在研究人员中非常受欢迎。

首先,我们将导入 K-Means 函数,然后通过将聚类数作为参数传递来调用该函数:

from sklearn.cluster import KMeans
km_sample = KMeans(n_clusters=3)
km_sample.fit(customer_data)

就这样,您的集群数据就准备好了。我们再来看看数据:

labels_sample = km_sample.labels_
customer_data['label'] = labels_sample
sns.scatterplot(customer_data['Annual Income (k$)'],customer_data['Spending Score (1-100)'],hue=customer_data['label'],palette='Set1')

Implementation using Scikit-Learn

Implementation using Scikit-Learn | Source: Author

我们能够使用 Scikit-Learn 只用几行代码创建客户细分。尽管对于这个特定的数据集,您可以看到最终的聚类数据在两个实现中是相同的。但是,通过这种细分,我们对商场顾客了解了什么:

Label 0: 储蓄者,avg 到高收入但花钱明智

标签 1: 无忧无虑,低收入但挥霍无度

标签 2: 支出者,平均高收入和支出者

当我们第一次绘制数据时,这很难理解,但现在我们知道我们有这 3 个类别,商场管理人员可以相应地应用营销策略,例如,他们可能为标签 0:储蓄者群体提供更多的储蓄优惠,并为标签 2:挥金如土者开设更有利可图的商店。

怎么选 K?

一些因素会挑战 K 均值聚类算法的最终输出的功效,其中之一是最终确定聚类的数量(K)。选择较低数量的分类会导致欠拟合,而指定较高数量的分类会导致过拟合。不幸的是,没有确定的方法来找到最佳数量。

聚类的最佳数量取决于相似性度量和用于聚类的参数。因此,要找到数据中的聚类数,我们需要对一系列值运行 k-means 聚类,并比较结果。目前,我们没有任何方法来确定聚类 K 的准确值,但我们可以使用一些技术来估计该值,包括交叉验证、肘方法、信息标准、剪影方法和 G-means 算法。

肘法

距离度量是比较不同 K 值的结果的常用度量之一。当聚类的数量 K 增加时,从质心到数据点的距离将减少,并且将达到 K 与数据点的数量相同的点。这就是我们一直使用到质心的距离平均值的原因。在肘点法中,我们绘制平均距离,并寻找下降率移动的肘点。这个肘点可以用来确定 k。

肘法 是一种用于确定数据集中聚类数量的启发式方法。该方法包括将解释的变化绘制为聚类数的函数,并选取曲线的拐点作为要使用的聚类数。”来源

*肘点在数学优化中用作分界点,以决定在哪个点上收益递减不再值得额外的成本。类似地,在聚类中,当添加另一个聚类不能改善建模结果时,这用于选择多个聚类。这是一个迭代过程,其中 K 均值聚类将在数据集上针对如下 K 值范围进行。

  1. 使用所有 K 值执行 K 均值聚类。对于每个 K 值,我们计算所有数据点到质心的平均距离:
from sklearn.cluster import KMeans
from sklearn import metrics
from scipy.spatial.distance import cdist
import numpy as np
import matplotlib.pyplot as plt

x1 = np.array([3, 1, 1, 2, 1, 6, 6, 6, 5, 6, 7, 8, 9, 8, 9, 9, 8])
x2 = np.array([5, 4, 5, 6, 5, 8, 6, 7, 6, 7, 1, 2, 1, 2, 3, 2, 3])

X = np.array(list(zip(x1, x2))).reshape(len(x1), 2)

distortions = []
K = range(1,10)
for k in K:
   kmeanModel = KMeans(n_clusters=k).fit(X)
   kmeanModel.fit(X)
   distortions.append(sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0])
  1. 标绘这些点,并找出平均距离突然下降的点(肘部):
plt.plot(K, distortions, 'bx-')
plt.xlabel('k')
plt.ylabel('Distortion')
plt.title('The Elbow Method showing the optimal k')
plt.show()

Elbow method

Elbow method | Source” Author

这可能是确定最佳聚类数的最流行的方法。虽然找到肘点可能是一个挑战,因为在实践中可能没有一个尖肘。

剪影法

找到一个拐点在实践中是具有挑战性的,但是有其他技术来确定 K 的最佳值,其中之一是轮廓评分法。

“剪影”是指一种解释和验证数据簇内一致性的方法。这项技术提供了一个简洁的图形表示,显示每个对象的分类情况。来源

轮廓系数用于通过检查一个聚类中的数据点与其他聚类相比有多相似来衡量聚类的质量。剪影分析可用于研究生成的聚类之间的距离。这个离散的度量值范围在-1 和 1 之间:

+1 表示数据点远离相邻的聚类,因此处于最佳位置。

0 表示它位于或非常接近两个相邻聚类之间的判定边界。

-1 表示数据点被分配到错误的簇。

为了找到聚类数 K 的最佳值,我们使用轮廓图来显示一个聚类中的每个点与相邻聚类中的一个点有多接近的度量,从而提供了一种视觉评估聚类数等参数的方法。让我们看看它是如何工作的。

  1. 计算一系列值的 K 均值聚类算法。
  2. 对于每个 K 值,找出数据点的平均轮廓分数:
from sklearn.metrics import silhouette_score

sil_avg = []
range_n_clusters = [2, 3, 4, 5, 6, 7, 8]

for k in range_n_clusters:
 kmeans = KMeans(n_clusters = k).fit(X)
 labels = kmeans.labels_
 sil_avg.append(silhouette_score(X, labels, metric = 'euclidean'))
  1. 绘制每个 K 值的轮廓分数集合
  2. 选择轮廓分数最大时的聚类数:
plt.plot(range_n_clusters,sil_avg,'bx-')
plt.xlabel('Values of K')
plt.ylabel('Silhouette score')
plt.title('Silhouette analysis For Optimal k')
plt.show()

Elbow method

Elbow method | Source” Author

使用上面的轮廓分析,我们可以选择 K 的最佳值为 3,因为平均轮廓得分较高,表明数据点的位置最佳。

聚类评估指标

在聚类中,我们没有任何标记数据,只有一组特征,目标是为这些特征获得高的类内相似性和低的类间相似性。评估任何聚类算法的性能都不像在监督学习中计算错误数或寻找精确度或召回率那样容易。在这里,我们根据数据点之间的相似性或差异性来评估结果。

在上一节中,我们看到了距离度量和轮廓分数如何帮助找到 k 的最佳值。因此,这些评估度量中的许多也可以用于为参数聚类算法找到最佳聚类点。聚类算法只和你的相似性度量一样好。因此,我们需要确保使用适当的相似性度量。一种方法是试验您的测量,并确定哪种算法可以提供更准确的相似性。

“理论上,聚类研究人员已经获得了对聚类评估的直觉,但是在实践中,一方面是大量的数据,另一方面是数据表示和聚类算法的微妙细节,使得直觉判断是不可能的。”博士论文,斯图加特大学

有几个聚类评估指标可以用来帮助研究人员进行聚类,并且这些指标还在不断发展。在这一部分,我们将讨论一些最常见和最流行的指标。

邓恩指数

邓恩指数用于识别密集且分离良好的群体。它是最小类间距离和最大类内距离的比值。邓恩指数可以计算如下:

这里 d(i,j) 是簇 ij 之间的距离,是所有簇间距离的最小值, d(k) 是簇 k 的簇内距离,是所有簇内距离的最大值。创建具有高 Dunn 指数的聚类的算法是更理想的,因为这样,聚类将更紧凑并且彼此不同。

剪影分数

平均轮廓分数也用作聚类中的评估度量。最好的剪影评分是 1,最差的是-1。接近零的值表示数据点位于边界上,即与聚类重叠。

f-测度

F-measure 应用于对的精度和召回率,并用于通过加权召回率来平衡假阴性。

在聚类中,常用的方法是将 F-测度应用于对的精度和召回率,这被称为对计数 F-测度。我们可以使用下面的公式计算 F 值。

这里的选择使得回忆被认为是与精确同等重要的。当我们设置为 1 时,它将是精度和召回率的调和平均值。我们为每个给定的类计算聚类的召回率和精确度,即应该为对象给定一组类。

兰德指数

Rand index 可用于计算集群与基准的相似程度。Rand 指数的值可以使用以下公式计算。

这里 TP 是真阳性的数量,TN 是真阴性的数量,FP 是假阳性的数量,FN 是假阴性的数量。使用这个评估标准,我们可以计算正确的成对分配的数量。

TP 是在预测分区和基本事实分区中聚集在一起的数据点对的数量,FP 是在预测分区中聚集在一起但不在基本事实分区中的数据点对的数量。

要了解更多评估指标,您可以查看 scikit learn 集群性能评估指标页面。

GMM(高斯混合模型)与 K-均值聚类算法

确定总体中聚类概率的概率模型被认为是混合模型。K-means 是一种快速而简单的聚类方法,但有时它不能捕捉固有的异质性。

高斯混合模型 (GMM)可以识别复杂的模式并将它们组合在一起,这是数据集中真实模式的近似表示。

GMM 简介

实际上,无监督数据可能包含高度分散的数据点,并且很难将这些数据点管理到不同的聚类中。高斯混合模型(GMM)初始化一定数量的高斯分布,每个高斯分布代表一个聚类。在 GMM,我们倾向于将相似的数据点分组到一个分布中。

在高斯分布中,我们试图拟合钟形曲线下的数据点,钟形曲线下的所有数据点高度相关,可以形成一个簇。钟形曲线的峰值表示数据点的平均值。GMM 是基于 K 个独立的高斯分布,用于建模 K 个集群。

Clustering using GMM

Clustering using GMM | Soure

比方说,在一个数据集中,有三组不同的数据点遵循高斯分布,这意味着将有三个钟形曲线。GMM 将确定数据点出现在这些分布中的概率。GMM 的概率函数可以定义为:

是 d 维均值向量
是高斯的 dxd 协方差矩阵

d 是特征数量
X 是数据点数量

GMM 模型符合生成模型,该模型给出了数据集的概率分布。为了避免过度拟合或欠拟合,我们必须通过使用交叉验证方法或阿卡克信息标准(AIC)和贝叶斯信息标准(BIC)方法评估模型似然性来找到最佳分布数。

GMM vs K-means 聚类算法及 K-means 为何如此受欢迎

  • GMM 使用概率分布,K-means 使用距离度量来计算数据点之间的差异,以将数据分成不同的聚类。

  • GMM 是一种软聚类算法,在某种意义上,每个数据点都被分配到一个具有一定程度不确定性的聚类中,例如,您可以在上面的图像中看到,一些数据点很有可能属于一个特定的高斯,而一些数据点则位于两个高斯之间。这意味着一个数据点可以属于一个以上的簇,即以 70/30 的比例分布在两个簇中。

  • 在寻找不同大小、形状和密度的聚类时,K-means 可能表现不佳。例如,使用 K-means 对椭圆形分布的数据进行聚类可能会失败,因为它更适合圆形分布。在这种情况下,继续与 GMM 合作是有意义的。

但是,K-means 发现数据点组所需的时间比 GMM 发现高斯分量所需的时间少得多。K-means 之所以受欢迎,是因为它易于应用,收敛速度快。它可以在没有任何关于数据工程过程的假设的情况下使用。由于 K-means 的简单性和效率,它也被用于图像分割,并且它给出了比更复杂的深度神经网络算法更有竞争力的结果。

“K-means 是一个合理的默认选择,至少在您发现集群步骤是您整体性能的瓶颈之前是如此。”–分析 Dimag

应用和使用案例

K-means 可以应用于维数较少的数据集、数值型和连续型数据。它适用于希望将随机分布的数据点组合在一起的情况。下面是一些有趣的使用案例,其中 K-means 很容易使用:

客户细分是将一家公司的客户分成反映每组客户相似性的组的做法。”Optimove

满足客户的需求是关系营销的起点,通过理解所有的客户并不相同,相同的优惠可能并不适用于所有人,可以提高关系营销的起点。根据客户的需求和行为对客户进行细分,可以帮助公司更好地向正确的客户推销产品。例如,电信公司拥有大量用户,利用市场或客户细分,公司可以个性化活动和激励措施等。

互联网和在线服务的不断发展引起了人们对安全性的关注。目前,对这些安全威胁或欺诈活动(例如,从一个不寻常的城市登录 Instagram 账户或隐藏任何类型的金融犯罪)进行会计处理非常普遍。使用 K-means 聚类等技术,人们可以很容易地识别任何异常活动的模式。检测到异常值将意味着欺诈事件已经发生。

众所周知,K-Means 在处理大型数据集时非常有效,这也是它成为文档分类的最佳选择之一的原因。根据主题、内容和标签(如果有)将文档聚类成多个类别。文档将被转换成矢量格式。然后,我们使用术语频率来识别公共术语,并且基于此我们可以识别文档组中的相似性。

使用地理空间特征作为输入,可以通过机器学习来预测室外周围声学环境。然而,收集足够的训练数据是一个昂贵的过程,特别是当试图在大范围、地理空间多样化的区域内提高基于监督学习方法的模型的准确性时。”–地理空间模型

由于这些监督算法的限制,我们需要使用无监督算法,如 K-均值聚类,我们可以通过聚类数据轻松地比较地理多样性。

使用 K-means,我们可以找到图像像素中的模式,这将允许以更快的速度和更有效的方式进行处理。在计算图像的每个像素和质心之间的差异后,将其映射到最近的聚类。在最终输出中,聚类将具有相似的像素组合在一起。

你可以在这里找到更多关于 K-means 应用和用例的信息。

K-means 聚类算法的优势

  • 相对容易理解和实现。
  • 可扩展到大型数据集。
  • 更好的计算成本。
  • 轻松热启动质心的分配和位置

K-means 聚类算法的缺点

  • 手动选择 K 并依赖于初始值
  • 对于不同的 K 值缺乏一致的结果
  • 总是试图找到圆形集群
  • 由于数据集中的异常值,质心会被拖动
  • 维数灾难,K 在维数增加时无效

最后的想法

在本文中,我们讨论了最流行的聚类算法之一。我们首先对 k-means 及其工作原理进行了概述,随后我们按照相同的步骤从头开始并通过 sklearn 实现了它。我们还研究了与 it 及其替代品相关的各种指标和挑战。

我们也看到 K-means 真的很好理解,可以很快交付训练结果。但是,数据的微小变化会影响其性能。聚类被假定为球形且大小均匀,这可能会降低 K-means 聚类的准确性。如果你想了解更多关于 K 均值聚类的知识,我建议你查看这些文章Stanford cs 221–K 均值数据科学手册并访问 scikit 学习网站。***

使用 Optuna 的 Kedro 管道:运行超参数扫描

原文:https://web.archive.org/web/https://neptune.ai/blog/kedro-pipelines-with-optuna-hyperparameter-sweeps

软件工程的工作流管理生态系统已经相当成熟——Git 用于版本控制,Postman 用于 API 测试,还有很多工具让你的生活更轻松。在 ML 中,我们始终如一地对代码和数据进行实验,这与“实验”并不常见的软件开发相反。此外,ML 实验可能很快变得混乱,并且经常无声无息地失败。

因此,需要一些工具来帮助您可靠地迭代实验,并实现最大的可见性和日志记录来跟踪变化。ML 管道中的配置可以在不同的级别上工作:

  • 1 数据集层面:数据选择、数据集大小、消除任何偏见

  • 2 特征级:检查特征范围、异常值、可疑值,选择/转换/创建特征

  • 3 模型级:模型架构、超参数

更重要的是,记录所有关键结果——单个数字指标、图表、损失曲线等。

本文展示了我们如何使用 Kedro 和 Optuna 健壮地满足上述需求。

介绍 Kedro

数据科学代码可能很复杂,而且变化很快。复杂性源于数据处理、EDA、功能工程/功能选择、调整和日志记录等相互关联的组件。代码或数据集的变化在实验之间不断发生。Kedro 帮助模块化数据科学管道,确保以可靠的方式处理代码。

此外,Kedro 还帮助处理各种来源(本地、AWS、GCP)和格式(CSV、HDFS、Spark)的数据。它还提供 Kubeflow、Prefect 和 AWS 批处理平台部署选项。更多关于 Kedro 的信息可以在这里找到。

介绍 Optuna

大多数 ML 模型都有多个超参数,需要进行调整以获得最佳的泛化能力。在数以千计的这些组合中进行强力搜索是很乏味的。

因此,需要灵活地导航超参数搜索空间。Optuna 正是这样做的。Optuna 使用复杂的算法,如 Tree Parzen Estimators (TPE)和协方差矩阵自适应进化策略(CMA-ES),大大减少了获得最佳超参数所需的试验次数。更多关于 Optuna 的信息可以在这里找到。

使用 Kedro 和 Optuna 一起运行超参数扫描

Kedro 和 Optuna 在自动化 ML 工作流方面互为补充。Kedro 处理高级管道、特征转换和预处理,而 Optuna 专注于核心模型优化。

我们现在将通过教程来看看 Kedro 和 Optuna 是如何结合在一起的。

设置项目

要安装 kedro,请遵循此处的说明

建议为该项目使用 conda 环境,并在安装任何依赖项之前激活它:

conda create --name kedro-environment python=3.7 -y
conda activate kedro-environment

现在,让我们通过在 CLI 中运行 kedro new 来创建一个新的 kedro 项目模板。当它询问项目名称时,您可以输入自己选择的名称。现在,我们使用教程作为名称。随后,我们将这个名称用于我们的存储库和 python 包。完成所有工作后,新的项目模板结构应该如下所示:

Using Kedro and Optuna together

Source: Author

目录结构

  • conf 包含用于设置日志记录和管道参数的配置文件
  • 数据包含不同级别数据集(原始、中间、已处理、元数据等)的子目录。正如我们所知,数据集不会在源位置被清理。在这里阅读更多关于每个子目录的意图的信息
  • src 包含我们的应用程序代码

我们将进一步详细探讨其中的每一个。

接下来,我们安装所有的需求。Kedro 的模板已经生成了一个 requirements.txt 文件。我们在文件中添加了一些特定于我们项目的需求。requirements.txt 文件应该如下所示:

black==21.5b1
flake8>=3.7.9, <4.0
ipython~=7.10
ipython~=7.16.3; python_version == '3.6'
ipython>=7.31.1, <8.0; python_version > '3.6'
isort~=5.0
jupyter~=1.0
jupyter_client>=5.1, <7.0
jupyterlab~=3.0
kedro==0.17.7
kedro-telemetry~=0.1.0
nbstripout~=0.4
pytest-cov~=3.0
pytest-mock>=1.7.1, <2.0
pytest~=6.2
wheel>=0.35, <0.37
scikit-learn
numpy
pandas
tqdm
optuna

要安装需求,请遵循以下代码:

(kedro-environment) dhruvilkarani@Dhruvils-MacBook-Air kedro-blog % cd tutorial/src
(kedro-environment) dhruvilkarani@Dhruvils-MacBook-Air src % pip install -r requirements.txt

在此下载酒质数据并保存在教程/data/01_raw 目录下;

(kedro-environment) dhruvilkarani@Dhruvils-MacBook-Air kedro-blog % cd tutorial

编写数据处理管道

Kedro 有两条主要管道——数据处理和数据科学。数据处理管道处理数据操作、清理、连接多个数据集、特征创建,以及模型训练和评估之前的几乎所有事情。要创建数据处理模板,请遵循以下命令:

(kedro-environment) dhruvilkarani@Dhruvils-MacBook-Air tutorial % kedro pipeline create data_processing

现在,kedro 管道非常类似于气流有向无环图(Dag)。Kedro 创建了一个节点图(node=process)。每个节点都有输入和输出。Kedro 允许我们跟踪这些输入和输出,使用它们就像正确命名它们一样好。让我告诉你它是如何工作的。考虑这个管道。

Writing the data processing pipeline

Source: Author

它获取原始数据并进行训练测试分割。这里唯一的节点是列车试裂:

import pandas as pd
from sklearn.model_selection import train_test_split

def create_train_test_data(df, frac, random_seed):
   df_train, df_test = train_test_split(
                           df, test_size=frac,
                           random_state=random_seed,
                           stratify=df["quality"]
                       )
   df_train_mean = df_train.mean()
   df_train = df_train.fillna(df_train_mean)
   df_test = df_test.fillna(df_train_mean)
   return df_train, df_test

现在通常你会添加一个 pd.read_csv 和几个 df.to_csv 来读写文件。如果你想改变测试数据的大小,你可以改变代码中的 frac 参数。这非常乏味。相反,让我们这样做:

src/tutorial/pipelines/data _ processing/nodes . py中添加上面的 train-test 分割代码。您应该在这个文件中编写一个节点必须执行的函数。现在,打开 tutorial/conf/base 下的文件 catalog.yml 。在文件中添加以下内容:

raw:
 type: pandas.CSVDataSet
 filepath: data/01_raw/WineQT.csv

train:
 type: pandas.CSVDataSet
 filepath: data/05_model_input/train.csv

test:
 type: pandas.CSVDataSet
 filepath: data/05_model_input/test.csv

我们告诉 kedro 跟踪三个熊猫 CSV 文件——rawtraintest 。我们之前已经放置了原始数据集。Kedro 会注意到 train 和 test CSV 文件不在它们各自的位置(文件路径参数),它会为您编写这些文件。

接下来,在src/tutorial/pipelines/data _ processing/pipeline . py下添加以下代码:

"""
This is a boilerplate pipeline 'data_processing'
generated using Kedro 0.17.7
"""

from kedro.pipeline import Pipeline, node, pipeline
from tutorial.pipelines.data_processing.nodes import create_train_test_data

def create_pipeline(**kwargs) -> Pipeline:
   return pipeline([
       node(
           func=create_train_test_data,
           inputs=["raw", "params:frac", "params:random_seed"],
           outputs=["train", "test"],
           name="train_test_split"
       ),
   ])

这创建了一个数据处理管道,其中有一个名为 train_test_split 的节点。它将执行函数 create_train_test_data ,输入为 raw (在 conf.yml 中定义),附加参数为 fracrandom_seed 。输出将是 train 和 test(其中 kedro 通过 conf.yml 保持跟踪)。注意 params:frac 中的参数来自conf/base/parameters . yml中的配置文件。在其中添加以下几行:

frac: 0.15
random_seed: 42
features: ['fixed acidity', 'volatile acidity', 'citric acid', 'residual sugar',
      'chlorides', 'free sulfur dioxide', 'total sulfur dioxide', 'density',
      'pH', 'sulphates', 'alcohol']
y_label: 'quality'

所以下一次你想尝试不同的部分和种子时,你只需要改变配置文件而不是代码。

在最后一步中,通过在src/tutorial/pipeline _ registry . py中添加以下内容来注册新的数据处理管道:

from typing import Dict

from kedro.pipeline import Pipeline, pipeline
from tutorial.pipelines import data_processing as dp

def register_pipelines() -> Dict[str, Pipeline]:
   """Register the project's pipelines.

   Returns:
       A mapping from a pipeline name to a ``Pipeline`` object.
   """
   data_processing_pipeline = dp.create_pipeline()
   return {
       "__default__": data_processing_pipeline,
       "dp": data_processing_pipeline,
   }

您现在一切就绪!

只需从 CLI 运行 kedro run 并观察日志。它应该是这样的:

kedro run
2022-03-05 12:29:15,993 - kedro.framework.cli.hooks.manager - INFO - Registered CLI hooks from 1 installed plugin(s): kedro-telemetry-0.1.3
Kedro-Telemetry is installed, but you have opted out of sharing usage analytics so none will be collected.
2022-03-05 12:29:17,446 - kedro.framework.session.store - INFO - `read()` not implemented for `SQLiteStore`. Assuming empty store.
fatal: not a git repository (or any of the parent directories): .git
2022-03-05 12:29:17,469 - kedro.framework.session.session - WARNING - Unable to git describe /Users/dhruvilkarani/Desktop/neptune/kedro-blog/tutorial
2022-03-05 12:29:17,477 - kedro.framework.session.session - INFO - ** Kedro project tutorial
/Users/dhruvilkarani/opt/anaconda3/envs/kedro-environment/lib/python3.7/site-packages/kedro/io/data_catalog.py:194: DeprecationWarning: The transformer API will be deprecated in Kedro 0.18.0.Please use Dataset Hooks to customise the load and save methods.For more information, please visithttps://kedro.readthedocs.io/en/stable/07_extend_kedro/02_hooks.html
  DeprecationWarning,
2022-03-05 12:29:18,200 - kedro.io.data_catalog - INFO - Loading data from `raw` (CSVDataSet)...
2022-03-05 12:29:18,207 - kedro.io.data_catalog - INFO - Loading data from `params:frac` (MemoryDataSet)...
2022-03-05 12:29:18,207 - kedro.io.data_catalog - INFO - Loading data from `params:random_seed` (MemoryDataSet)...
2022-03-05 12:29:18,207 - kedro.pipeline.node - INFO - Running node: train_test_split: create_train_test_data([raw,params:frac,params:random_seed]) -> [train,test]
2022-03-05 12:29:18,216 - kedro.io.data_catalog - INFO - Saving data to `train` (CSVDataSet)...
2022-03-05 12:29:18,226 - kedro.io.data_catalog - INFO - Saving data to `test` (CSVDataSet)...
2022-03-05 12:29:18,229 - kedro.runner.sequential_runner - INFO - Completed 1 out of 1 tasks
2022-03-05 12:29:18,229 - kedro.runner.sequential_runner - INFO - Pipeline execution completed successfully.

如果你注意到了, train.csvtest.csv 文件被创建并存储在tutorial/data/05 _ model _ input中。

编写数据科学管道

现在数据准备好了,我们准备训练一个模型。我们将创建一个数据科学管道,就像我们创建一个数据处理管道一样。教程的其余部分与我们到目前为止所做的非常相似。在本节中,我们选择一个 RandomForestClassifier 并调整它的两个重要的超参数—n _ estimatorsmax_depth 。您可以选择任何具有各自超参数的 sklearn 模型:

(kedro-environment) dhruvilkarani@Dhruvils-MacBook-Air tutorial % kedro pipeline create data_science

接下来,我们将在src/tutorial/pipelines/data _ science/nodes . py中添加以下代码:

"""
This is a boilerplate pipeline 'data_science'
generated using Kedro 0.17.7
"""
from distutils.log import Log
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
from kedro.io import MemoryDataSet
import pandas as pd
import numpy as np
import optuna

def train_model(df_train, y_label, features):
   X_train = df_train[features].values
   y_train = df_train[y_label].values

   def objective(trial):
       n_estimators = trial.suggest_int('n_estimators', 2, 50)
       max_depth = int(trial.suggest_loguniform('max_depth', 1, 20))
       model = RandomForestClassifier(n_estimators=n_estimators, max_depth=max_depth)
       return cross_val_score(model, X_train, y_train,
           n_jobs=-1, cv=5).mean()

   study = optuna.create_study(direction='maximize')
   study.optimize(objective, n_trials=100)
   model = RandomForestClassifier(**study.best_params)
   model.fit(X_train, y_train)

   y_pred = model.predict(X_train)
   return model, {"acc":accuracy_score(y_train, y_pred)}, {"features":features, "model_type": "RandomForest"}

def evaluate_model(model, df_test, y_label, features):
   X_test = df_test[features].values
   y_test = df_test[y_label].values
   y_pred = model.predict(X_test)
   return {"acc": accuracy_score(y_test, y_pred)}

函数 train_modelevaluate_model 将是数据科学管道中的两个节点。 Train_model 训练随机森林分类器,在其中我们使用 optuna 帮助我们找到最佳超参数。这是使用物镜功能完成的。

对于每次试验,我们从目标函数中获得平均 5 倍的交叉验证准确性。我们将试验次数限制在 100 次。最后,使用最佳参数在完整的训练数据集上进行训练。

返回模型、指标字典和元数据字典。在 evaluate_model 函数中,我们使用训练好的模型并返回度量字典。为了在管道中获得所有这些,将以下代码添加到src/tutorial/pipelines/data _ science/pipeline . py:

"""
This is a boilerplate pipeline 'data_science'
generated using Kedro 0.17.7
"""

from kedro.pipeline import Pipeline, node, pipeline
from tutorial.pipelines.data_science.nodes import train_model, evaluate_model

def create_pipeline(**kwargs) -> Pipeline:
   return pipeline([
       node(
           func=train_model,
           inputs=["train", "params:y_label", "params:features"],
           outputs=["model", "train_metrics", "features"],
           name="train_model"
       ),
       node(
           func=evaluate_model,
           inputs=["model", "test", "params:y_label", "params:features"],
           outputs="test_metrics",
           name="evaluate_model"
       )
   ])

并通过将src/tutorial/pipeline _ registry . py修改为以下内容来注册管道:

"""Project pipelines."""
from typing import Dict

from kedro.pipeline import Pipeline, pipeline
from tutorial.pipelines import data_processing as dp
from tutorial.pipelines import data_science as ds

def register_pipelines() -> Dict[str, Pipeline]:
   """Register the project's pipelines.

   Returns:
       A mapping from a pipeline name to a ``Pipeline`` object.
   """
   data_processing_pipeline = dp.create_pipeline()
   data_science_pipeline = ds.create_pipeline()
   return {
       "__default__": data_processing_pipeline+data_science_pipeline,
       "ds": data_science_pipeline,
       "dp": data_processing_pipeline,
   }

就是这样!
如果你运行 kedro viz ,你会看到这样的内容:

Writing the data science pipeline

Source: Author

这个 DAG(有向无环图)代表了我们的整个工作流程。从原始数据集到训练测试分割,再到训练、记录和评估。这就是当我们运行时它是如何被执行的。

在运行管道之前,我们将把它添加到 conf/base/catalog.yml :

train_metrics:
 type: tracking.MetricsDataSet
 filepath: data/09_tracking/train_metrics.json

test_metrics:
 type: tracking.MetricsDataSet
 filepath: data/09_tracking/test_metrics.json

features:
 type: tracking.JSONDataSet
 filepath: data/09_tracking/features.json

model:
 type: pickle.PickleDataSet
 filepath: data/06_models/model.pkl
 backend: pickle

这将告诉 Kedro 跟踪来自 train_modelevaluate_model 函数的度量、元数据和模型。要运行管道,输入 kedro run

您可以在 CLI 中看到类似的内容:

2022-03-06 15:23:47,713 - kedro.io.data_catalog - INFO - Loading data from `params:y_label` (MemoryDataSet)...
2022-03-06 15:23:47,714 - kedro.io.data_catalog - INFO - Loading data from `params:features` (MemoryDataSet)...
2022-03-06 15:23:47,714 - kedro.pipeline.node - INFO - Running node: train_model: train_model([train,params:y_label,params:features]) -> [model,train_metrics,features]
[I 2022-03-06 15:23:47,724] A new study created in memory with name: no-name-587db03d-d58a-49a9-80b9-c5683b044758
[I 2022-03-06 15:23:48,570] Trial 0 finished with value: 0.6478139043087496 and parameters: {'n_estimators': 20, 'max_depth': 15.080923501597061}. Best is trial 0 with value: 0.6478139043087496.
[I 2022-03-06 15:23:48,923] Trial 1 finished with value: 0.5664393338620142 and parameters: {'n_estimators': 46, 'max_depth': 1.9884986491873076}. Best is trial 0 with value: 0.6478139043087496.
[I 2022-03-06 15:23:49,275] Trial 2 finished with value: 0.6550145387258789 and parameters: {'n_estimators': 26, 'max_depth': 18.841791623627735}. Best is trial 2 with value: 0.6550145387258789.
[I 2022-03-06 15:23:49,589] Trial 3 finished with value: 0.6055881575469204 and parameters: {'n_estimators': 31, 'max_depth': 5.408170166043053}. Best is trial 2 with value: 0.6550145387258789.
[I 2022-03-06 15:23:49,669] Trial 4 finished with value: 0.6436901929685435 and parameters: {'n_estimators': 32, 'max_depth': 11.246378990753412}. Best is trial 2 with value: 0.6550145387258789.
[I 2022-03-06 15:23:49,787] Trial 5 finished with value: 0.6529738302934179 and parameters: {'n_estimators': 50, 'max_depth': 15.218464760076643}. Best is trial 2 with value: 0.6550145387258789.
[I 2022-03-06 15:23:49,828] Trial 6 finished with value: 0.628263283108644 and parameters: {'n_estimators': 13, 'max_depth': 13.689325469239577}. Best is trial 2 with value: 0.6550145387258789.
[I 2022-03-06 15:23:49,884] Trial 7 finished with value: 0.6457361882104149 and parameters: {'n_estimators': 23, 'max_depth': 9.102926797194122}. Best is trial 2 with value: 0.6550145387258789.
[I 2022-03-06 15:23:49,972] Trial 8 finished with value: 0.6591488236849061 and parameters: {'n_estimators': 40, 'max_depth': 19.407785624206216}. Best is trial 8 with value: 0.6591488236849061.
[I 2022-03-06 15:23:50,047] Trial 9 finished with value: 0.600385937086968 and parameters: {'n_estimators': 36, 'max_depth': 4.213221746044185}. Best is trial 8 with value: 0.6591488236849061.
[I 2022-03-06 15:23:50,072] Trial 10 finished with value: 0.5519851969336506 and parameters: {'n_estimators': 5, 'max_depth': 1.296628908687125}. Best is trial 8 with value: 0.6591488236849061.
[I 2022-03-06 15:23:50,155] Trial 11 finished with value: 0.6230769230769231 and parameters: {'n_estimators': 41, 'max_depth': 7.236080573101756}. Best is trial 8 with value: 0.6591488236849061.
[I 2022-03-06 15:23:50,222] Trial 12 finished with value: 0.6375469204335183 and parameters: {'n_estimators': 27, 'max_depth': 17.394915525536124}. Best is trial 8 with value: 0.6591488236849061.
[I 2022-03-06 15:23:50,261] Trial 13 finished with value: 0.5726143272535025 and parameters: {'n_estimators': 16, 'max_depth': 3.07366645685214}. Best is trial 8 with value: 0.6591488236849061.
[I 2022-03-06 15:23:50,364] Trial 14 finished with value: 0.6426592651334919 and parameters: {'n_estimators': 37, 'max_depth': 19.982880063130665}. Best is trial 8 with value: 0.6591488236849061.
…

使用这种端到端的管道,我们可以用最少的代码变化迭代实验。尝试做一些改变,并做多次运行

实验跟踪

运行多个实验最重要的部分是分析和比较结果。要在 Kedro 中做到这一点,运行 kedro viz。在左边点击一个烧杯形状的图标。这将带你到你已经完成的所有运行的日志。指标和元数据可用于所有实验:

Experiment tracking

Source: Author

可以选择最多比较三个实验。在我们的例子中,它看起来像这样:

Experiment tracking

Source: Author

我们可以看到,Kedro 的实验跟踪仪表盘信息量并不大。它允许我们一次最多只能比较三个实验。虽然超参数搜索运行了超过 100 个具有多个指标和输入特征的试验,但我们不能使用这样的标准过滤掉试验。从这个意义上来说,这种可视化是非常基本的。我们需要更好的东西来观看我们的实验。

将海王星的全面跟踪与 Kedro 和 Optuna 集成

Neptune 及其与多个开源框架的集成使得通过最小的代码更改来升级您的实验跟踪游戏变得非常简单。

装置

pip install neptune-client
pip install kedro-neptune
conda install -c conda-forge neptune-optuna 

在这里获取您的 API 令牌并运行 kedro neptune init。这将把所有必要的 Neptune 相关文件添加到您的项目中。

对于数据科学管道中的 nodes.py,我们将添加< 10 行,让 Neptune 进行跟踪。更新后的文件如下所示:

"""
This is a boilerplate pipeline 'data_science'
generated using Kedro 0.17.7
"""
from distutils.log import Log
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
from kedro.io import MemoryDataSet
import pandas as pd
import numpy as np
import optuna
import neptune.new as neptune
import neptune.new.integrations.optuna as optuna_utils
import matplotlib.pyplot as plt
from scikitplot.metrics import plot_confusion_matrix

run = neptune.init(
   api_token='<api_token>',
   project='<project_name>'
)
neptune_callback = optuna_utils.NeptuneCallback(run=run, base_namespace="my_hpo")

def train_model(df_train, y_label, features, neptune_run:  neptune.handler.Handler):
   X_train = df_train[features].values
   y_train = df_train[y_label].values

   def objective(trial):
       n_estimators = trial.suggest_int('n_estimators', 2, 50)
       max_depth = int(trial.suggest_loguniform('max_depth', 1, 20))
       model = RandomForestClassifier(n_estimators=n_estimators, max_depth=max_depth)
       return cross_val_score(model, X_train, y_train,
           n_jobs=-1, cv=5).mean()

   study = optuna.create_study(direction='maximize')
   study.optimize(objective, n_trials=10, callbacks=[neptune_callback])
   model = RandomForestClassifier(**study.best_params)
   model.fit(X_train, y_train)

   y_pred = model.predict(X_train)
   acc = accuracy_score(y_train, y_pred)
   neptune_run['nodes/report/train_accuracy'] = acc
   fig, ax = plt.subplots()
   plot_confusion_matrix(y_train, y_pred, ax=ax)
   neptune_run['nodes/report/train_confusion_matrix'].upload(fig)
   return model, {"acc":acc}, {"features":features, "model_type": "RandomForest"}

def evaluate_model(model, df_test, y_label, features, neptune_run):
   X_test = df_test[features].values
   y_test = df_test[y_label].values
   y_pred = model.predict(X_test)
   acc = accuracy_score(y_test, y_pred)
   neptune_run['nodes/report/test_accuracy'] = acc
   fig, ax = plt.subplots()
   plot_confusion_matrix(y_test, y_pred, ax=ax)
   neptune_run['nodes/report/test_confusion_matrix'].upload(fig)
   return {"acc": accuracy_score(y_test, y_pred)}

在这种情况下,我们记录准确度和混淆矩阵图。查看 Neptune 文档,了解关于的更多信息,您还可以记录哪些数据

了解更多信息

💡探索 kedro 与 Neptune 的集成——它让您拥有组织良好的 Kedro 管道的所有好处,并为 ML 元数据管理构建了强大的用户界面。

确保添加了 API 令牌和项目名称。最后,将 train_modelevaluate_model 函数中额外的 neptune_run 参数添加到我们的流水线中:

def create_pipeline(**kwargs) -> Pipeline:
   return pipeline([
       node(
           func=train_model,
           inputs=["train", "params:y_label", "params:features", "neptune_run"],
           outputs=["model", "train_metrics", "features"],
           name="train_model"
       ),
       node(
           func=evaluate_model,
           inputs=["model", "test", "params:y_label", "params:features", "neptune_run"],
           outputs="test_metrics",
           name="evaluate_model"
       )
   ])

就是这样!现在我们坐下来,看着我们的生活变得更容易,当我们做一个凯德罗运行。在你的跑步结束后,进入 Neptune 的项目仪表板,在那里我们会看到两种类型的跑步,一种是 Kedro,另一种是 Optuna,这样的跑步有五组。

Neptune dashboard: Kedro-Optuna

Kedro-Optuna dashboard in Neptune.ai | Source

Kedro-optuna-neptune runs

Kedro-Optuna dashboard in Neptune.ai | Source

您可以记录和比较任意多的运行,从而克服 Kedro 强加的三个实验限制。您还可以添加或删除您希望比较很容易完成的列(指标),在这种情况下,我们已经选择了训练和测试的准确性和执行时间。除了所有的指标和图表,Neptune 还记录了源代码资源利用率,以及一组更丰富的元数据

结论

数据科学家在一个非常混乱的环境中工作,可能会有许多可能被忽视的重大错误来源。因此,我们需要可靠的系统来减少项目的组织开销。Kedro 和 Optuna 将大部分端到端工作流自动化,让数据科学家专注于设计方法和实验的关键任务。此外,当与诸如 Neptune 之类的工具的综合实验管理工具相结合时,在实验中进行比较和协作变得更加容易。

ML-Ops 空间是一个广阔的空间,而且增长速度比以往任何时候都快。在本文中,我们讨论了用于管道和超参数优化的工具。然而, MLOps 包含了更多的领域,比如特性存储、模型版本控制等等。你可以在这里找到关于同一的完整列表。一定要检查一下,保持学习的势头。

参考

德鲁维尔·卡拉尼

i3systems India 的数据科学家
一位热爱数学和编程的数据科学家。他以前的经验使他能够处理大规模的自然语言处理问题,如聊天机器人和文档理解。他认为,教育大众了解技术及其影响与开发新技术同样重要。


阅读下一篇

如何跟踪机器学习模型的超参数?

卡米尔·卡什马雷克|发布于 2020 年 7 月 1 日

机器学习算法可通过称为超参数的多个量规进行调整。最近的深度学习模型可以通过数十个超参数进行调整,这些超参数与数据扩充参数和训练程序参数一起创建了非常复杂的空间。在强化学习领域,您还应该计算环境参数。

数据科学家要控制好 超参数 空间,才能使 进步

在这里,我们将向您展示最近的 实践提示&技巧,工具以最小的开销高效地跟踪超参数。你会发现自己掌控了最复杂的深度学习实验!

为什么我应该跟踪我的超参数?也就是为什么这很重要?

几乎每一个深度学习实验指南,像这本深度学习书籍,都建议你如何调整超参数,使模型按预期工作。在实验-分析-学习循环中,数据科学家必须控制正在进行的更改,以便循环的“学习”部分正常工作。

哦,忘了说随机种子也是一个超参数(特别是在 RL 领域:例如检查这个 Reddit )。

超参数跟踪的当前实践是什么?

让我们逐一回顾一下管理超参数的常见做法。我们关注于如何构建、保存和传递超参数给你的 ML 脚本。

Continue reading ->


Kedro vs ZenML vs Metaflow:应该选择哪个管道编排工具?

原文:https://web.archive.org/web/https://neptune.ai/blog/kedro-vs-zenml-vs-metaflow

在本文中,我将对 Kedro、Metaflow 和 ZenML 进行比较,但在此之前,我认为值得后退几步。为什么还要费心使用 ML 编排工具,比如这三个?启动一个机器学习项目并没有那么难。你安装一些 python 库,初始化模型,训练它,瞧!准备好了。也有很多人告诉你这是数据科学,在本地运行的 Jupyter 笔记本上键入 model.fit 将保证你得到梦想中的工作,并解决宇宙中的所有问题。但这只是事实的一小部分。

先说清楚,用 Jupyter 笔记本做实验和报道没有错。问题是他们无法提供一个可以在大多数行业 ML 项目中使用的软件开发框架。

实现机器学习项目(和创建基于 ML 的产品)和任何其他软件开发一样复杂。例如,在现实世界的 ML 项目中,您必须能够:

  • 以多种格式接收数据
  • 预处理数据、清理数据集等。
  • 做特征工程
  • 训练你的模特
  • 测试它们
  • 部署您的模型
  • 实施 CI/CD
  • 使用 git 跟踪您的代码
  • 跟踪您的模型的指标

还有很多其他的东西,用笔记本是做不到的(如果有人这么说,他们可能是在误导你)。因此,您的代码必须是可维护的、可伸缩的、可跟踪的,并且能够在多人团队中工作。

这就是为什么数据科学家必须学习机器学习编排工具,这篇文章旨在深入探讨一些最常用的 MLOps 编排工具-- Kedro、MetaFlow 和 ZenML。我们将看看他们的:

  • 主要目的
  • 代码结构
  • 主要特征
  • 赞成和反对

我们还将展示:

  • 开始使用其中的每一项是多么容易(以及如何开始)
  • 展示他们真实的能力

为了解决之前提出的问题,已经实现了很多框架。我们选择了 Kedro、Metaflow 和 ZenML,因为它们是一些最常用的编排机器学习管道的工具:

  • 他们有免费使用的许可证:你不需要支付高额费用来构建你的 ML 项目
  • 它们分布广泛:有很多人在使用它们,这样在需要的时候很容易找到人来帮助你
  • 他们在网上有很多学习材料:这样你(以及加入你团队的其他人)可以投入并开始你的第一个项目,或者维持现有的项目
  • 他们与行业中最常用的工具进行了许多集成:您将能够将它们集成到现有的云框架中,甚至扩展它来做更多的事情

因此,这些是让你的机器学习离开你的 Jupyter 笔记本并让它面对真实世界为真实的人解决真实问题的最简单的方法。

选择流程编排工具时,需要考虑许多因素。这将是你的机器学习项目的基础。例如,这种选择会影响:

  • 启动一个项目所需的时间
  • 更改项目的特定部分(如数据源、代码片段等)所需的时间
  • 是时候培训新员工了解正在运行的项目了
  • 项目成本,包括(但不限于)云、处理能力和人力

这就是为什么关注您使用的编排工具如此重要。这就是我们要帮你找到的。

TL;速度三角形定位法(dead reckoning)

如果你没有时间全部读完,你可以跳到这里快速总结

现在,让我们开始吧!

原始文件

定义

首先,让我们看一下每个文档是如何定义其工具的:

Kedro是一个开源的 Python 框架,用于创建可复制、可维护和模块化的数据科学代码。它从软件工程中借用概念,并将它们应用到机器学习代码中;应用的概念包括模块化、关注点分离和版本控制。Kedro 由 LF AI &数据基金会托管。”

在此环节可用。

ZenML是一个可扩展的开源 MLOps 框架,用于创建生产就绪的机器学习管道。它专为数据科学家打造,具有简单、灵活的语法,与云和工具无关,并且具有面向 ML 工作流的接口/抽象。”

在此环节可用。

Metaflow是一个人性化的 Python 库,帮助科学家和工程师构建和管理现实生活中的数据科学项目。Metaflow 最初是在网飞开发的,旨在提高数据科学家的工作效率,这些科学家从事从经典统计到最先进的深度学习的各种项目。”

在此环节可用。

至此,一切看起来都非常相似。但是这些工具之间有什么不同呢?是的,有一些重要的区别需要注意。

谁建的?

这三个都是开源免费使用的框架,但都是由公司开发的:

  • Kedro 是由麦肯锡公司 QuantumBlack 创建的,最近捐赠给了 Linux 基金会
  • 另一方面,ZenML 是由德国慕尼黑的一家小公司开发的
  • Metaflow 是在网飞开发的

它们是否有完整的文件记录?

所有 3 个工具都有文档,提供可用作其实施基础的信息。代码文档对于软件开发尤其重要,因为它是由实际创建软件的人编写的指南,所以没有其他更好的媒介来解释如何使用它。

当维护一个正在运行的项目时,这变得更加重要,因为总是需要检查框架的某个部分的一些特性和代码样本,例如理解语法或首字母缩写词。

Kedro

Kedro 有大量的文档,其中包含教程和示例项目。软件的每个部分都有自己的部分,包含代码片段和示例,从最简单的功能到高级的功能。您可以安装一个模板项目,并使用样本数据集启动您的第一个项目,并在您的终端中用几行代码训练您的第一个模型。

ZenML

ZenML 文档也非常完整。一切都写得很好,有有用的图像帮助我们了解那里正在发生什么。还有一些复制粘贴教程,可以立即投入使用,并查看 ZenML 在实践中的工作。不过,以我的拙见,它缺少代码片段来演示如何应用一些概念。

元流

元流文档是三者中最短的。有一个模板项目,但是文档的覆盖面有点太短。所以,最难理解的是到底发生了什么。Metaflow 是三种语言中唯一可以在 R 中运行的,所以如果这是你首选的编码语言,也许你已经选择了工具。

文件:Kedro = ZenML >元流量

主要特征

现在是时候以更实际的方式来理解这些工具是如何工作的了。我们将看到如何学习它们,以及如何将它们用于现实世界的项目中。

学习如何使用

每一个软件工具都是有用的,就像使用它有多容易一样。让我们来看看每个工具的一些可用材料。

Kedro

Kedro 有一个很大的社区,它也提供了很多关于如何用它创建项目的信息。除了官方文档(附带一个模板项目),YouTube 上还有一个完整的免费 kedro 课程,由 DataEngineerOne 频道主办。它从非常初级的水平(像安装 kedro)到大多数高级功能。在 medium 中还有 4 篇逐步的帖子(我写的)展示了如何使用 kedro、MLflow 和 fastAPI 部署模型(第 1 部分第 2 部分第 3 部分第 4 部分)。

ZenML

YouTube 上有很多 ZenML 项目视频,其中很多都是由他们的官方个人资料保存的,你可以在这里找到。还有一些实现的教程项目,可以从命令界面本身下载然后抓取指南来实现自己的项目,这里的 how-to 是。

基本上,您可以运行“zenml 示例列表”,并通过键入“zenml 示例快速启动”选择一个可用的示例下载到您的当前目录中。

元流

Metaflow 是目前可用材料最少的一个。文档很短,几乎没有代码示例。Youtube 上有一些视频展示了一些实现,就像这个,但似乎没有完整的课程。材料中也有拆分,因为 Metaflow 是这里唯一可以在 R 和 Python 中运行的,所以两者中都有学习材料插图实现。

学习如何使用:Kedro > ZenML > Metaflow

代码结构

Kedro:节点和管道

Kedro 有一个由节点和管道定义的代码结构。每个节点都是一个 Python 函数。管道是节点的编排,指定管道的所有输入、输出和参数。它基本上描述了哪些数据进入每个节点,输出是什么,以及接下来的步骤是什么。

Kedro: nodes and pipelines

Kedro nodes (squares), datasets (round-edge rectangles), and pipelines (the interconnection between them) | Source

不需要指定哪个节点在下一个节点之前。Kedro 自动编排整个管道的执行顺序(如果执行中没有冲突,这样的数据源可以是同一个节点的输入和输出)。这样,如果您的数据结构保持不变,您的源代码可能会发生变化,而无需更改主代码。此外,它还允许您查看管道的每个步骤中发生了什么,因为中间数据正在被存储。

所有代码都位于“src”文件夹中,所有函数都在节点和管道 python 文件中创建。可以(强烈建议)将您的代码拆分到子文件夹中(如预处理、特征工程、模型训练等)以保持其组织性,这样就可以单独运行管道的每一步。整个代码架构,包括代码开发生命周期,可以在这里看到

Kedro 还提供了一个环境接口。Kedro 环境旨在分离管道中使用的代码源,这样您就可以将开发从生产中分离出来,甚至可以在项目中创建其他分区。你可以在这里阅读更多相关信息。它会自动创建本地和基础环境,但是您可以根据需要创建任意多个环境。

当向特定节点(或所有节点)添加附加特性时,kedro 使用了钩子结构。例如,您可以配置特定的行为,如记录数据集加载发生的时间。钩子的结构可以在这里找到。Kedro 也有一个秘密的管理结构,它使用一个证书 yaml 文件,你可以在这里了解更多。

ZenML:步骤和管道

ZenML 是建立在步骤之上的。它为它定义了一个装饰器(@step),然后管道的每一步都写成一个 Python 函数。它包含用于接收数据、数据清理、模型训练甚至度量评估的代码。可以使用管道来组织这些步骤,管道将构建所有的步骤,以允许管道同时运行。对步骤、输入和输出使用 ZenML 内置类的主要优点是所有集成都变得更容易。

另一方面,管道是指定步骤执行顺序的 python 函数,以及它们相应的输入和输出。所有代码都构建在 run.py 文件中,该文件将包含步骤和管道本身。

ZenML 项目基础设施也定义了一个栈,它定义了你的管道将如何运行。它通常包括:

  • 协调器:协调管道执行的框架(比如气流和库伯流)
  • 工件存储:数据的实际存储,主要用于中间管道步骤的数据(因为摄取通常是它自己的一个步骤)
  • 元数据存储库:跟踪关于管道运行本身的数据的存储库

由于其结构,改变堆栈的组件更容易,如数据存储、云基础架构或编排。这里也有对每个可用堆栈组件的解释。例如,您可以使用本地开发栈(在您的机器上运行)和生产栈(在云服务器上运行)。

An example of ZenML pipeline with two stacks, local and cloud

An example of ZenML pipeline with two stacks, local and cloud | Source

在冗余非常重要的项目中,堆栈特别有用。如果您的主系统出现故障(比如依赖于特定的云提供商),您可以切换到不同的基础架构,几乎不需要交互,甚至可以实现自动化。它还可以包括一个工件注册表,它甚至可以管理项目的秘密。

与 Kedro 不同,ZenML 允许您定制整个管道的创建,因此我们强烈建议您遵循一些最佳实践。你可以在这里找到指南

元流:有 UI(也有步骤)的那个

Metaflow 与 Airflow 非常相似,因为它是基于 DAGs(有向无环图)的,所以 Airflow 用户更容易理解它。

就像 ZenML 一样,Metaflow 也使用 steps 来修饰函数,所以可以和有 ZenML 体验的用户相当。然而,它使用了一个在步骤本身中指定流程的结构,这看起来有点混乱。此外,为了创建流,您应该首先创建一个包含其步骤的类(例如,MyFlow)。

大多数功能都是用 decorators 构建的。例如,您可以使用资源装饰器来指定计算资源(比如内存、CPU 和 GPU 的使用)、每个步骤应该使用的 Python 环境、重试次数、负责的用户等等。

使用 Metaflow 的主要优点是它有一个内置的 UI,用于跟踪项目中每次运行的度量。在这里可以找到一个示例 UI

Metaflow 自动跟踪一些指标,比如运行实验的用户、实验所用的时间、实验的步骤以及运行状态。

代码结构:Kedro > ZenML >元流

摄取数据

Kedro:数据目录和参数文件

Kedro 有一个很好的方法将数据源从代码中抽象出来:数据目录文件。这些是 YAML 文件,其中描述了所有源(输入和输出数据),以及关于它们的保存路径、格式和其他参数的信息。这样,它们将作为参数传递给管道,这使得更新更加容易。数据可以以多种格式、多种路径和许多不同的参数存储。

你可以在这里阅读更多相关信息。这个 yaml 示例展示了如何导入位于本地的 CSV 数据集。

cars:
type: pandas.CSVDataSet
filepath: data/01_raw/company/cars.csv
load_args:
sep: ','
save_args:
index: False
date_format: '%Y-%m-%d %H:%M'
decimal: .

将项目的数据集作为参数传递的主要优点是,如果您必须更改数据源(其路径、源或文件),您不需要更新所有代码来匹配它。Catalog 是一个默认的 kedro 类,有几个集成可供使用。在最坏的情况下,数据清理节点需要更新,而管道的中间步骤不会改变。

当我说它可以有任何格式时,我的意思是,它可以是一段 SQL 代码(来自多个源和云)、CSV 表、parquet 表、Spark 数据集、MS Excel 表、JPEG 图像等。它可以位于云(AWS、GCP 和 Azure)、Hadoop 文件系统甚至 HTML 网站中。该目录还用于保存模型和度量文件,使得实现它们和管理所有来源变得更加容易。

Kedro 还使用 YAML 文件作为 params 文件。它可能包含模型或管线需要的所有参数。这样,在需要时可以很容易地跟踪和更改它们。

ZenML

前面说过,ZenML 是基于 steps 的。因此,举例来说,数据摄取就是您可以在一个步骤中以 python 脚本的形式编写的东西。

ZenML 的大部分功能来自于它的集成。它提供了大量工具来集成来自多个来源的数据,以及特性存储、工件存储等等。我们将在下一节进一步讨论 ZenML 集成。

因为 ZenML 是高度可定制的,您可以创建自己的代码结构,包括参数和配置文件,以便使您的项目看起来更有组织性(和更少的硬编码)和更容易维护。

元流

它与 ZenML 摄取非常相似,尽管 Metaflow 只支持 AWS 集成,这在与不同的云供应商合作时可能是一个障碍。因此,基本上,为了集成数据源和其他特性,您可能必须用 Python(或 R)进行一些硬编码。

摄取数据:凯卓> ZenML >元流

集成

Kedro:插件

kedro 的大部分功能来自它的插件。它可以通过本机运行第三方工具来扩展 kedro 的功能,并且它们可以一起工作以充分发挥它们的潜力。虽然 kedro 将它们作为插件添加,但它们实际上是作为集成到 kedro 结构中的独立组件来工作的。其中有很多,比如:

  • Kedro-neptune 一个连接 Kedro 和 Neptune.ai 的插件,允许实验跟踪和元数据管理。

Kedro experiment tracking using kedro-neptune

Kedro experiment tracking using kedro-neptune | Source

  • Kedro-mlflow : 允许实现 MLflo 进行模型跟踪和模型服务
  • Kedro-viz : 一个神奇的工具,可以让你的整个 ML 管道可视化

Kedro pipeline visualization using kedro-viz

Kedro pipeline visualization using kedro-viz | Source

  • Kedro-docker 一个让使用 docker 创建、部署和运行 kedro ML 应用程序变得更加容易的工具;

这些插件的主要优点是它们都可以很容易地用 PyPI 安装,并且它们与 kedro 结构兼容,因此很容易在现有项目中安装和运行它们。您可以查看官方文档,找到一个对解决您的问题最有用的文档。

ZenML

ZenML 支持大量第三方集成。它们包含编排工具、分布式处理工具、云提供商、部署、特性存储、监控等等。ZenML 就像胶水一样把整个管道粘在一起(就像他们自己声称的那样)。在 ZenML Python 文件内部调用这些工具的方式与在 ZenML 外部调用它们的方式非常相似,例如,使用“ZenML . integrations . sklearn”来导入 sk learn。

Original Documentation

Original documentation | Source

在 ZenML 中有一个 Python 集成包,它包含了许多不同工具的所有接口。你可以在这里阅读更多关于已经集成的工具(以及他们目前正在开发的工具)。说到安装集成,离你只有四个字的命令界面,比如‘zenml integration install sk learn’。

元流

众所周知,网飞与 AWS 有着密切的关系。因此,Metaflow 与大多数 AWS 服务很好地集成,使用 S3 存储、AWS Batch 和 Kubernetes 进行计算、AWS Fargate 和 RDS 进行元数据存储、AWS Sagemaker 笔记本和 AWS Step 函数、Eventbridge 和 Argo 工作流进行调度。你可以在这里阅读更多相关信息

集成:Kedro = ZenML >元流

现实世界的应用

我们一直在谈论的所有工具都可以用来将模型部署到生产中,并协调它们的培训和评估。然而,它们的一些特性可能更适合某些用例。

Kedro

由于 Kedro 具有高度组织化的代码结构,并抽象了数据和模型源和路径,因此对于那些应该由大型团队构建并需要长期维护的项目来说,它是一个很好的选择,因此基于插件和挂钩的新功能可以添加到项目中,而无需更改整个管道结构。此外,由于它可以与 PySpark 无缝协作,因此使用大数据或任何云平台进行部署都没有问题。

ZenML

ZenML 的代码结构比 Kedro 更具可定制性,它可能非常适合原型项目。ZenML 的主要优势之一是它可以在不改变代码的情况下处理不同的栈。因此,如果项目需要改变云提供商,例如,由于不可用,它可以在几秒钟内完成,无需太多设置。这提供了健壮性和可伸缩性。

元流

Metaflow 是三个中唯一一个可以使用 r 的。因此,如果有一些模型还没有在 Python 中使用,Metaflow 可以使用 r 将其部署到生产中。此外,Metaflow 的另一个优点是它可以自动跟踪每个运行指标。那么它可能非常适合原型化和测试不同的项目方法。此外,由于它与 AWS 的兼容性,如果您对 AWS 有一些依赖,它应该是您的选择。

优点和局限性

凯德罗

优势
  • Kedro 的结构对于维护复杂项目中的秩序特别有用,而使用其他工具很难做到这一点。
  • 它的插件可以提供广泛的操作,提供 kedro 原生不做的东西;
  • 强社区:社区开发频繁,所以总是有 bug 修复和新插件发布;
  • 节点和管道架构避免了代码重复,因为它允许功能重用,从而清洁编码;
  • 可以使用不同的环境,比如 dev 和 prod 来分离数据和模型源。
限制
  • 因为它结构良好,如果你的项目太简单,kedro 可能是一个大材小用;

ZenML

优势
  • ZenML 非常简单,易于实现。你可以很快地开始你的第一个项目,并随着时间的推移逐渐发展成一个复杂的项目。
  • 它有许多与第三方工具的集成,这允许你实现广泛的项目;
  • 栈结构允许你以多种不同的方式实现你的代码,并使 dev 和 prod 分离成为可能。
限制
  • 因为代码很简单,所以随着项目的增长,保持所有的东西都有组织是很棘手的。在有多个步骤和复杂数据流的项目中,需要遵守纪律。因此,阅读和使用建议的最佳实践非常重要;
  • 它是由一家公司举办的,因此很少有围绕 bug 修复或新功能创建可能性的社区互动。

元流

优势
  • Metaflow 自动跟踪度量和管道运行信息,这在生产中运行时相当有用;
  • 在 R 中可用:即使不是唯一的,也是唯一的一个可以在 R 中运行的框架;
  • 它有一个内置的用户界面来显示所有跟踪的指标;
  • 基于 DAGs:这使得 Metaflow 对于熟悉图形编程的人特别有用,比如气流。
限制
  • 缺少文档和其他在线学习材料;
  • 代码很容易与许多装饰器的使用混淆;
  • 与 ZenML 类似,随着项目的增长,保持一切有序可能会很棘手。
  • 对于初学者来说可能有点难学。

结论

在查看了所有这些方法之后,很明显每个工具之间都有很大的差异。每一种都有自己的优点和局限性,它可以更好或更差地适应每个项目的需求。简而言之:

  • Kedro 有一些有趣的功能,在处理复杂的项目时尤其有用。它抽象了数据源和模型,并且可以与许多其他工具很好地集成。它可以被设置为适合大多数机器学习现代项目,包括所有当前的行业最佳实践。以我的拙见,他们处理和抽象源代码和模型源代码的方式是令人惊奇的。

  • ZenML 也是一个强有力的竞争对手,与 Kedro 相比有一些优势。它更具可定制性,可以在不需要任何代码更改的情况下处理多个堆栈,并且它还可以与许多其他工具很好地集成。但是,它缺少一些功能,主要是在处理数据和模型源时。

  • 元流是目前为止我们将在这里看到的最不结构化的方法。它主要关注编排步骤和跟踪步骤执行度量。因此,您的项目需要的其他特性可能需要通过使用其他 Python 功能手工编码来包含。可能不是不可以,但是肯定有一些弊端。然而,自动指标跟踪和 UI 在生产环境中非常酷。

最后,我希望您现在有更多的信息来选择这些工具中哪一个更适合您的用例,只是请记住,在每个工具的功能之间总是有一个权衡。谢谢你一直看完这篇博客,下次再见!

如何用 Neptune 跟踪 TensorFlow/Keras 模型开发

原文:https://web.archive.org/web/https://neptune.ai/blog/keep-track-of-tensorflow-keras-model-development-with-neptune

模型开发生命周期从数据探索开始,然后我们为模型选择特性,选择基线算法,接下来,我们尝试用不同的算法和参数调整来提高基线性能。

听起来很简单。但是,在所有这些过程中,您可能会创建多个笔记本,或者反复修改一个笔记本。这是一个忘记你的研究的好方法。

幸运的是,这是可以避免的。你只需要记录你所有的模型、数据和特性。这样,无论何时你想重温你以前做过的事情,都很容易做到。

在本文中,我将向您展示如何组织和跟踪 Tensorflow 项目并保持一切整洁。

这一切都归结于 MLOps ,它是一套原则和工具,汇集了产品团队和数据科学团队,以及生产中开发、部署、监控、管理和保护 ML 模型的所有关键操作。

MLOps 基本上就是 DevOps ,但是针对机器学习。 ML 生命周期应该支持模型交付的速度和规模,以便在您的组织中处理数据的速度和数量。你为什么需要这个?因为将 ML 应用从概念阶段发展到生产中的实际部署是非常困难的。

ML 模型生命周期中的挑战

为了跟踪您的实验,有必要跟踪代码、数据、模型版本、超参数和度量。以一种有意义的方式组织它们将有助于你在你的组织内合作。

在现实世界的项目中,数据一直在变化。添加了新的表格,删除了错误标记的点,改变了特征工程技术,改变了验证和测试数据集以反映生产环境。当数据更改时,基于该数据的所有内容也会更改,但代码保持不变,因此跟踪数据版本非常重要。

跟踪您的 ML 实验的方法

适当的实验跟踪使得基于数据版本比较指标和参数、比较实验以及比较测试或验证集的最佳或最差预测变得容易。还可以分析模型训练的硬件消耗。从石灰等工具看预测解释和特征重要性。

下面的解释将帮助你惊人地跟踪你的实验,并获得像上面所附的图表。

指定项目要求

首先,为您的项目设置一个度量标准(性能的阈值)。例如,针对F1-得分优化您的模型。

第一次部署应该包括构建一个简单的模型,重点是构建一个合适的 ML 管道来进行预测。这将帮助您快速交付价值,并避免花费太多时间试图构建完美模型的陷阱。当你在你的组织中开始一个新的 ML 项目时,实验运行可以迅速扩展到几十、几百甚至几千个。如果不跟踪,你的工作流程会变得混乱。

因此,像 Neptune 这样的跟踪工具正在成为 ML 项目中的标准工具。您可以使用它来记录您的数据、模型、超参数、混淆矩阵、图表等等。在你的工作流/代码中包含一个像 Neptune 这样的工具,相对于你不跟踪任何东西时所经历的痛苦,是非常简单的。

为了向您展示如何进行跟踪,我们将使用 Tensorflow 来训练一个文本分类模型。我们将使用 LSTMs 训练模型:

  • 长短期记忆网络是一种特殊的 RNN,能够处理长期依赖。
  • LSTMs 是专门为解决长期依赖问题(长时间记忆信息)而设计的。
  • 所有的 rnn 都有链状的重复神经网络模块。

下图显示了 LSTM 中的重复模块。

不要担心内部发生了什么(如果你渴望了解,请阅读本文以获得关于 LSTMs 的深入见解)。

介绍够了,让我们使用 Neptune 实现和跟踪模型开发。

在我们进行任何建模或分析之前,让我们建立一个组织良好的 ML 代码库。

使用 Neptune 避免模型开发过程中的混乱

为此项目安装依赖项

我们将在 Jupyter 笔记本中使用 Neptune,因此我们需要 Neptune 客户端和 Neptune jupyter 扩展。为 jupyter 笔记本配置 Neptune,它将帮助我们将笔记本检查点保存到 Neptune。按照下面的命令来做这件事。

!pip install neptune-client numpy~=1.19.2 tensorflow nltk
!pip install -U neptune-notebooks
!jupyter nbextension enable --py neptune-notebooks

运行以上命令后,您将在 jupyter 笔记本中看到以下扩展。

现在我们已经安装了必要的依赖项,让我们导入它们。

import tensorflow as tfl
import numpy as np
import csv
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from nltk.corpus import stopwords
from neptune.new.integrations.tensorflow_keras import NeptuneCallback
import neptune.new as neptune
STOPWORDS = set(stopwords.words('english'))

将您的项目连接到 Neptune 客户端。如果您是该平台的新手,请阅读指南开始使用。

run = neptune.init(project='aravindcr/Tensorflow-Text-Classification',
                   api_token=’YOUR TOKEN’) 

这些是我在这个项目中使用的一些参数,我把它们记录在这里。要跟进,使用应用程序中附带的笔记本这里。要了解更多关于记录元数据的信息,请查看这个指南

保存超参数(每次迭代)

run['parameters'] = {'embed_dims': 64,
                    'vocab_size': 5000,
                    'max_len': 200,
                    'padding_type': 'post',
                    'trunc_type': 'post',
                    'oov_tok': '<OOV>',
                    'training_portion': 0.8
                    }

数据集版本

我们使用的数据集是用于分类的 BBC 新闻文章数据。从这里下载数据。您也可以使用下面的命令将您的数据记录到 Neptune。

这将帮助我们在进行实验时跟踪数据集的不同版本。这可以用 Python 中的 Neptune 的 set_property 函数和 hashlib 模块来完成。

run['dataset'].upload('news-docs-bbc.csv')

在下面的部分,我创建了一个名为标签和文本的列表,它将帮助我们存储新闻文章的标签和与之相关的实际文本。我们还使用 nltk 删除了停用词。

labels = []
texts = []

with open('news-docs-bbc.csv', 'r') as file:
    data = csv.reader(file, delimiter=',')
    next(data)
    for row in data:
        labels.append(row[0])
        text = row[1]
        for word in STOPWORDS:
            token = ' ' + word + ' '
            text = text.replace(token, ' ')
            text = text.replace(' ', ' ')
        texts.append(text)
print(len(labels))
print(len(texts))
train_size = int(len(texts) * training_portion)

让我们将数据分成训练集和验证集。如果您查看上述参数,我们将 80%用于培训,20%用于验证我们为此用例构建的模型。

train_text = texts[0: train_size]
train_labels = labels[0: train_size]

validation_text = texts[train_size:]
validaiton_labels = labels[train_size: ]

让我们把句子转换成子单词标记串。这需要五千个最常见的单词。每当我们遇到看不见的特殊值时,我们就使用 oov_token

<00V>将用于在 word_index 中找不到的单词。 fit_on_texts 将根据文本列表更新内部词汇。该方法基于词频创建词汇索引。

tokenizer = Tokenizer(num_words = vocab_size, oov_token=oot_tok)
tokenizer.fit_on_texts(train_text)
word_index = tokenizer.word_index

dict(list(word_index.items())[0:8])

正如我们在上面的输出中看到的, < oov > 是语料库中最常见的标记,其次是其他单词。

现在我们已经创建了一个基于频率的词汇索引,让我们将这些标记转换成序列列表,
text _ to _ sequence将文本转换成一个整数序列。简单来说,它将文本中的单词转换成 word_index 字典中对应的整数值。

train_sequences = tokenizer.texts_to_sequences(train_text)
print(train_sequences[16])

train_padded = pad_sequences(train_sequences, maxlen=max_len, padding=padding_type, truncating=trunc_type)

当在你的下游 NLP 任务上训练神经网络时,需要记住一件事,序列需要具有相同的大小,所以我们使用 max_len 参数填充那些序列。在我们的例子中,我在开始时指定了 200,这就是为什么我们在下面使用 填充 _ 序列 的原因。

序列长度小于或大于 max_len 的文章将被截断为 200。例如,如果序列长度为 186,它将被填充到 200,并带有 14 个零。通常,我们拟合数据一次,但转换序列多次,所以我们没有合并训练集和验证集。

valdn_sequences = tokenizer.texts_to_sequences(validation_text)
valdn_padded = pad_sequences(valdn_sequences,
                             maxlen=max_len,
                             padding=padding_type,
                             truncating=trunc_type)

print(len(valdn_sequences))
print(valdn_padded.shape)

让我们看看我们的标签。标签需要被标记化,所有的训练标签都应该是 NumPy 数组的形式。我们将用下面的代码将它们转换成一个 NumPy 数组。

label_tokenizer = Tokenizer()
label_tokenizer.fit_on_texts(labels)

label_tokenizer = Tokenizer()
label_tokenizer.fit_on_texts(labels)

在开始建模任务之前,让我们看看它们填充前后的样子。我们可以看到有些词变成是因为它们没有出现在顶部提到的 vocab_size 中。

word_index_reverse = dict([(value, key) for (key, value) in word_index.items()])

def decode_article(text):
    return ' '.join([word_index_reverse.get(i, '?') for i in text])
print(decode_article(train_padded[24]))
print('**********')
print(train_text[24])

列车张量流模型

使用 tfl.keras.sequential 我们将层的线性堆栈分组到 tfl.keras.Model 中。f 第一层是嵌入层,它为每个单词存储一个向量。单词序列被转换成向量序列。NLP 中的嵌入主要是为了让意义相近的词有相似的向量表示(词嵌入就是意义相近的词有相似的向量表示的词向量)。

tfl . keras . layers . bidirectional是 RNNs 的双向包装器,它有助于通过 LSTM 层向前和向后传播输入,然后链接输出。这对学习 LSTMs 中的长期依赖关系很有好处。为了进行分类,我们将它组成一个密集的神经网络。

我们在这里使用的激活函数是 relusoftmax 。如果 relu 函数返回负输入,则返回 0,但是对于 x 的任何正值,它都返回值。要了解更多关于 relu 的信息,请查看指南

密集层增加了六个单元。最后一层是‘soft max’激活函数,它将网络输出归一化为预测输出类别的概率分布。

model = tfl.keras.Sequential([
    tfl.keras.layers.Embedding(vocab_size, embed_dims),
    tfl.keras.layers.Bidirectional(tfl.keras.layers.LSTM(embed_dims)),
    tfl.keras.layers.Dense(embed_dims, activation='relu'),
    tfl.keras.layers.Dense(6, activation='softmax')
])
model.summary()

正如您在上面的模型摘要中看到的,我们有一个嵌入层和双向 LSTM。双向的产出是我们在 LSTM 投入的两倍。

我这里用过的损失函数是categorial _ cross _ entropy,通常用于多类分类任务。它主要量化两个概率分布之间的差异。我们使用的优化器是 【亚当】 ,梯度下降的一种变体。

model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

使用 Neptune 组织 ML 模型开发

为了将训练指标记录到 Neptune,我们使用来自 Neptune 库的回调。例如,如下图所示,来自 Tensorflow / Keras 和 NeptuneCallback 的日志元数据。这有助于您记录通常会在这些 ML 库中记录的大多数元数据:

from neptune.new.integrations.tensorflow_keras import NeptuneCallback

neptune_clbk = NeptuneCallback(run=run, base_namespace='metrics')

epochs_count = 10
history = model.fit(train_padded, training_label_seq, epochs=epochs_count, validation_data=(valdn_padded, validation_label_seq), verbose=2, callbacks=[neptune_clbk])

现在,当你运行这个时,你所有的指标和损失都会被记录在 Neptune 中。

作为模型训练的一部分,我们还可以监控 RAM 和 CPU 的使用情况。这些信息可以在实验的监控部分找到。

建立模型性能的基线。从使用初始数据管道的简单模型开始。在您的领域中找到问题的区域模型的状态,然后再现结果。稍后,将数据集应用到下一个基线。

模型版本控制

tfl.keras.models.save_model(model, 'classification.h5', overwrite=True, include_optimizer=True, save_format=None,
        signatures=None, options=None, save_traces=True)

model.save('my_model')

run['my_model/saved_model'].upload('classification.h5')

模型保存在 Neptune 中的 saved_model 目录下。

记录项目中的任何内容

def graphs_plotting(history, string):
    plt.plot(history.history[string])
    plt.plot(history.history['val_'+string])
    plt.xlabel('Epochs')
    plt.ylabel(string)
    plt.legend([string, 'val_'+string])
    plt.show()

graphs_plotting(history, 'accuracy')
graphs_plotting(history, 'loss')
run['train/plots/accuray'].upload('val_accuracy.png')
run['train/plots/loss'].upload('val_loss.png')

PARAMS = {'epoch_num': 10,
          'batch_size': 64,
          'optimizer': 'adam',
          'loss_fun': 'categorical_corss_entropy',
          'metrics': ['accuracy'],
          'activation': 'relu'}

run['parameters'] = PARAMS

记录的参数可以在 Neptune 中找到。

在处理一个行业项目时,您使用的度量标准可能会根据您正在处理的问题和部署模型的领域而发生变化。记录度量可以为您的团队节省大量时间。

在海王星,你所有的实验都组织在一个地方。你可以在你的实验中添加标签,准确记录你所做的尝试,比较指标,在需要的时候重现或重新运行实验。你可以安心地睡觉,因为你知道你所有的想法都安全地藏在一个地方。

你也可以给你的实验添加标签,这将有助于你更好地跟踪你的实验。在模型部署之前,请确保为以下各项准备好版本:模型配置、模型参数训练数据集和验证数据集。部署 ML 模型的一些常见方法是将它们打包到 docker 容器中,并且——为了推理公开——打包到 REST API 中。

您还可以比较已登录到 Neptune 的笔记本的多个版本。

模型细化

上述模型在 6 个时期后开始过度拟合。您可以更改纪元并重新训练您的模型,然后将您的参数记录到 Neptune。

随着模型的复杂性增加,要反复调试它。执行误差分析对于发现模型失败的地方是必要的。跟踪模型性能如何随着训练数据量的增加而扩展。一旦你有了成功地为你的问题建立模型的想法,以后你应该试着从模型中获得最好的性能。将您的错误分解为:

  • 可避免的偏见,
  • 方差,
  • 不可约误差,
  • 测试误差和验证误差的区别。

解决欠拟合问题(高偏差、低方差)

执行特定于模型的优化。如果您的模型拟合不足,那么它已经捕获了数据中的模式和噪声,但它在您的训练和测试数据中表现不佳。对数据进行版本化和更改模型参数非常重要。您可以通过误差分析、增加模型容量、调整超参数和添加新特征来解决欠拟合问题。

解决过度拟合问题

当您的模型过度拟合时,它在训练数据上表现很好,在测试数据上表现很差。这表明你的模型有高方差和低偏差。调查关于此类问题的文献,与你团队中的专家或你认识的可能处理过类似问题的人交谈。

我们可以通过添加更多的训练数据、正则化、误差分析、调整超参数和减小模型大小来解决过度拟合问题。

寻址分布移位

优化您的模型非常重要,因为您构建的模型在某些情况下可能会失败。在生产中使用你的方法会有风险。

我们可以通过执行误差分析来解决分布的偏移,以便确定分布的偏移。扩充您的数据以更好地匹配测试分布,并应用领域适应技术。

调试 ML 项目

这一步主要是为了调查为什么你的模型表现不佳。

可能有一些实现错误、数据集构造问题或坏的超参数。尽快在生产数据上部署基线模型。通常,实时数据会以意想不到的方式发生变化。它可能不会反映您在开发过程中使用的数据(通常称为数据漂移)。

快速部署一个简单的模型,这样你就可以提前知道你需要做什么。这有助于更快的迭代,而不是试图创建完美模型的慢迭代。需要固定随机种子,以确保模型训练是可重复的。

通过对你的实验进行适当的跟踪,上面的一些挑战可以被解决,并且更容易将你的结果传达给团队。

摘要

要高效地构建机器学习项目,从简单开始,逐渐增加复杂性。通常,数据科学家和 ML 工程师面临着难以表达的问题来开发 ML 解决方案。

花大量的时间了解项目的范围,并提前明确定义需求,使您的迭代更好地朝着最终目标前进。

参考

  1. https://colah.github.io/posts/2015-08-Understanding-LSTMs/
  2. https://neptune.ai/
  3. https://towards data science . com/multi-class-text-classification-with-lstm-using-tensor flow-2-0-d 88627 c10a 35
  4. https://neptune.ai/blog/ml-experiment-tracking
  5. https://www.jeremyjordan.me/ml-requirements/
  6. https://docs . Neptune . ai/integrations-and-supported-tools/model-training/tensor flow-keras
  7. https://docs . Neptune . ai/you-should-know/logging-metadata # what-you-can-log

Keras 损失函数:你需要知道的一切

原文:https://web.archive.org/web/https://neptune.ai/blog/keras-loss-functions

你已经在 Keras 中创建了一个深度学习模型,你准备了数据,现在你想知道你应该为你的问题选择哪个损失。

我们一会儿会讲到,但首先什么是损失函数?

在深度学习中,计算损失以获得关于模型权重的梯度,并通过反向传播相应地更新那些权重。在每次迭代之后,计算损耗并更新网络,直到模型更新没有在期望的评估度量中带来任何改进。

因此,当您在机器学习项目的(长时间)期间在验证集上继续使用相同的评估指标(如 f1 得分或 AUC)时,可以改变、调整和修改损失,以获得最佳的评估指标性能。

您可以像考虑模型架构或优化器一样考虑损失函数,在选择它时进行一些思考是很重要的。在这篇文章中,我们将探讨:

  • Keras 中可用的损失函数以及如何使用它们,
  • 如何在 Keras 中定义自己的自定义损失函数
  • 如何添加样品称量以产生观察敏感损失,
  • 如何避免南斯在的损失,
  • 如何通过绘图和回调监控损失函数

让我们开始吧!

Keras 损失函数 101

在 Keras 中,损失函数在编译阶段传递,如下所示。

在这个例子中,我们通过创建 loss 类的一个实例来定义 loss 函数。使用类是有利的,因为您可以传递一些附加参数。

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential()
model.add(layers.Dense(64, kernel_initializer='uniform', input_shape=(10,)))
model.add(layers.Activation('softmax'))

loss_function = keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(loss=loss_function, optimizer='adam')

如果您想使用 Keras 内置的损失函数而不指定任何参数,您可以只使用字符串别名,如下所示:

model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')

你可能想知道,如何决定使用哪个损失函数?

Keras 中有各种损失函数。其他时候,您可能需要实现自己的定制损失函数。

让我们深入所有这些场景。

Keras 中有哪些损失函数?

二元分类

当解决只涉及两个类的问题时,二元分类损失函数开始发挥作用。例如,当预测信用卡交易中的欺诈时,交易要么是欺诈的,要么不是。

二元交叉熵

二元交叉熵将计算预测类和真实类之间的交叉熵损失。默认情况下,使用 sum_over_batch_size 缩减。这意味着损失将返回批次中每个样本损失的平均值。

y_true = [[0., 1.], [0.2, 0.8],[0.3, 0.7],[0.4, 0.6]]
y_pred = [[0.6, 0.4], [0.4, 0.6],[0.6, 0.4],[0.8, 0.2]]
bce = tf.keras.losses.BinaryCrossentropy(reduction='sum_over_batch_size')
bce(y_true, y_pred).numpy()

总和减少意味着损失函数将返回批次中每个样本损失的总和。

bce = tf.keras.losses.BinaryCrossentropy(reduction='sum')
bce(y_true, y_pred).numpy()

将减少值设为 none 将返回每样本损失的完整数组。

bce = tf.keras.losses.BinaryCrossentropy(reduction='none')
bce(y_true, y_pred).numpy()
array([0.9162905 , 0.5919184 , 0.79465103, 1.0549198 ], dtype=float32)

在二元分类中,使用的激活函数是 sigmoid 激活函数。它将输出限制在 0 到 1 之间。

多类分类

涉及多个类别预测的问题使用不同的损失函数。在这一节中,我们将看几个例子:

范畴交叉熵

CategoricalCrossentropy 还计算真实类和预测类之间的交叉熵损失。标签以 one_hot 格式给出。

cce = tf.keras.losses.CategoricalCrossentropy()
cce(y_true, y_pred).numpy()

稀疏分类交叉熵

如果有两个或更多的类,并且标签是整数,那么应该使用 SparseCategoricalCrossentropy。

y_true = [0, 1,2]
y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1],[0.1, 0.8, 0.1]]
scce = tf.keras.losses.SparseCategoricalCrossentropy()
scce(y_true, y_pred).numpy()

毒物流失

您还可以使用泊松类来计算中毒损失。如果数据集来自泊松分布,例如呼叫中心每小时接到的电话数量,这是一个很好的选择。

y_true = [[0.1, 1.,0.8], [0.1, 0.9,0.1],[0.2, 0.7,0.1],[0.3, 0.1,0.6]]
y_pred = [[0.6, 0.2,0.2], [0.2, 0.6,0.2],[0.7, 0.1,0.2],[0.8, 0.1,0.1]]
p = tf.keras.losses.Poisson()
p(y_true, y_pred).numpy()

库尔巴克-莱布勒发散损失

可以使用 KLDivergence 类来计算相对熵。根据 PyTorch 的官方文件:

KL 散度 对于连续分布来说是一种有用的距离度量,在对(离散采样的)连续输出分布空间执行直接回归时通常很有用。

y_true = [[0.1, 1.,0.8], [0.1, 0.9,0.1],[0.2, 0.7,0.1],[0.3, 0.1,0.6]]
y_pred = [[0.6, 0.2,0.2], [0.2, 0.6,0.2],[0.7, 0.1,0.2],[0.8, 0.1,0.1]]
kl = tf.keras.losses.KLDivergence()
kl(y_true, y_pred).numpy()

在多类问题中,使用的激活函数是 softmax 函数。

物体检测

焦点损失

在涉及不平衡数据的分类问题和物体检测问题中,可以使用焦点损失。损失引入了对交叉熵标准的调整。

这是通过改变其形状来实现的,其方式是分配给分类良好的样本的损失是向下加权的。这确保了模型能够平等地从少数和多数类学习。

随着正确类别的置信度增加,通过缩放在零处衰减的因子来缩放交叉熵损失。缩小因子在训练时对无挑战样本的贡献进行加权,并关注有挑战的样本。

import tensorflow_addons as tfa

y_true = [[0.97], [0.91], [0.03]]
y_pred = [[1.0], [1.0], [0.0]]
sfc = tfa.losses.SigmoidFocalCrossEntropy()
sfc(y_true, y_pred).numpy()
array([0.00010971, 0.00329749, 0.00030611], dtype=float32)

并集上的广义交集

也可以使用来自 TensorFlow add on 的【Union 上的广义交集损失。并集上的交集(IoU)是对象检测问题中非常常见的度量。然而,IoU 在涉及非重叠边界框的问题上不是很有效。

引入了 Union 上的广义交集来解决 IoU 面临的这一挑战。它确保通过保持 IoU 的比例不变属性、将比较对象的形状属性编码到区域属性中、以及确保在对象重叠的情况下与 IoU 有很强的相关性来实现概括。

gl = tfa.losses.GIoULoss()
boxes1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]])
boxes2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0]])
loss = gl(boxes1, boxes2)

回归

在回归问题中,你必须计算预测值和真实值之间的差异,但通常有许多方法可以做到这一点。

均方误差

MeanSquaredError 类可用于计算预测值和真实值之间的均方误差。

y_true = [12, 20, 29., 60.]
y_pred = [14., 18., 27., 55.]
mse = tf.keras.losses.MeanSquaredError()
mse(y_true, y_pred).numpy()

当您希望较大的误差比较小的误差受到更多的惩罚时,请使用均方误差。

平均绝对百分比误差

使用以下函数计算平均绝对百分比误差。

它的计算如下所示。

y_true = [12, 20, 29., 60.]
y_pred = [14., 18., 27., 55.]
mape = tf.keras.losses.MeanAbsolutePercentageError()
mape(y_true, y_pred).numpy()

当你想要一个可以直观解释的损失时,考虑使用这个损失。人们很容易理解百分比。这种损失对异常值也是稳健的。

均方对数误差

均方对数误差可以用下面的公式计算:

下面是同样的一个实现:

y_true = [12, 20, 29., 60.]
y_pred = [14., 18., 27., 55.]
msle = tf.keras.losses.MeanSquaredLogarithmicError()
msle(y_true, y_pred).numpy()

均方对数误差对低估的惩罚大于高估。当您不想惩罚大的错误时,这是一个很好的选择,因此,它对异常值是健壮的。

余弦相似损失

如果您对计算真实值和预测值之间的余弦相似性感兴趣,您可以使用 cosine similarity 类。其计算方法如下:

结果是一个介于-1 和 1 之间的数字。0 表示正交性,而接近-1 的值表示有很大的相似性。

y_true = [[12, 20], [29., 60.]]
y_pred = [[14., 18.], [27., 55.]]
cosine_loss = tf.keras.losses.CosineSimilarity(axis=1)
cosine_loss(y_true, y_pred).numpy()

对数损失

LogCosh 类计算预测误差的双曲余弦的对数。

下面是它作为独立函数的实现。

y_true = [[12, 20], [29., 60.]]
y_pred = [[14., 18.], [27., 55.]]
l = tf.keras.losses.LogCosh()
l(y_true, y_pred).numpy()

对数损失的工作原理类似于均方误差,但不会受到偶然的严重错误预测的强烈影响。—张量流文档

胡伯损失

对于对异常值不太敏感的回归问题,使用 Huber 损失

y_true = [12, 20, 29., 60.]
y_pred = [14., 18., 27., 55.]
h = tf.keras.losses.Huber()
h(y_true, y_pred).numpy()

学习嵌入

三重损失

你也可以通过 TensorFlow 插件用半硬负挖掘计算三重态损失。该损失促使具有相同标签的嵌入对之间的正距离小于最小负距离。

import tensorflow_addons as tfa

model.compile(optimizer='adam',
              loss=tfa.losses.TripletSemiHardLoss(),
              metrics=['accuracy'])

在 Keras 中创建自定义损失函数

有时候没有好的损失,或者你需要做一些修改。让我们来学习如何做到这一点。

可通过定义一个将真实值和预测值作为必需参数的函数来创建自定义损失函数。该函数应该返回一个损失数组。然后可以在编译阶段传递该函数。

def custom_loss_function(y_true, y_pred):
   squared_difference = tf.square(y_true - y_pred)
   return tf.reduce_mean(squared_difference, axis=-1)

model.compile(optimizer='adam', loss=custom_loss_function)

让我们看看如何将这个自定义损失函数应用于一组预测值和真实值。

import numpy as np

y_true = [12, 20, 29., 60.]
y_pred = [14., 18., 27., 55.]
cl = custom_loss_function(np.array(y_true),np.array(y_pred))
cl.numpy()

使用 Keras 损失权重

在训练过程中,可以通过观察或样本来衡量损失函数。权重可以是任意的,但是典型的选择是类权重(标签的分布)。每个观测值按其所属类的分数进行加权(反向),因此在计算损失时,少数类观测值的损失更为重要。

做到这一点的方法之一是在训练过程中传递类权重。

使用包含每个类的权重的字典来传递权重。您可以使用 Scikit-learn 计算重量,或者根据您自己的标准计算重量。

weights = { 0:1.01300017,1:0.88994364,2:1.00704935, 3:0.97863318,      4:1.02704553, 5:1.10680686,6:1.01385603,7:0.95770152, 8:1.02546573,
               9:1.00857287}
model.fit(x_train, y_train,verbose=1, epochs=10,class_weight=weights)

第二种方法是在编译阶段传递这些权重。

weights = [1.013, 0.889, 1.007, 0.978, 1.027,1.106,1.013,0.957,1.025, 1.008]

model.compile(optimizer=tf.keras.optimizers.SGD(),
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              loss_weights=weights,
              metrics=['accuracy'])

如何监控 Keras 损失函数[示例]

当模型正在训练时,在训练和验证集上监视损失函数通常是一个好主意。查看这些学习曲线是模型训练过度拟合或其他问题的良好指示。

如何做到这一点有两个主要选择。

使用控制台日志监控 Keras 丢失

记录和查看损失的最快和最简单的方法是简单地将它们打印到控制台上。

import tensorflow as tf

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
   tf.keras.layers.Flatten(input_shape=(28, 28)),
   tf.keras.layers.Dense(512, activation='relu'),
   tf.keras.layers.Dropout(0.2),
   tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='sgd',
             loss='sparse_categorical_crossentropy',
             metrics=['accuracy'])

model.fit(x_train, y_train,verbose=1, epochs=10)

这种方法的问题是,这些日志很容易丢失,很难看到进展,并且当在远程机器上工作时,您可能无法访问它。

使用回调监控 Keras 损失

另一个更干净的选择是使用回调,它将记录每个批处理和 epoch 结束时的丢失。

你需要决定你想在哪里记录什么,但是这真的很简单。

例如,记录 keras 对 Neptune 的损失可能如下所示:

from keras.callbacks import Callback 

class NeptuneCallback(Callback):
    def on_batch_end(self, batch, logs=None):  
        for metric_name, metric_value in logs.items():
            neptune_run[f"{metric_name}"].log(metric_value)

    def on_epoch_end(self, epoch, logs=None): 
        for metric_name, metric_value in logs.items():
            neptune_run[f"{metric_name}"].log(metric_value)

您可以自己创建监控回调,或者使用 keras 库中以及其他与它集成的库中许多可用的 keras 回调之一,如 TensorBoard、 Neptune 等。

一旦您准备好回调,您只需将它传递给model.fit(...):

pip install neptune-client neptune-tensorboard
import neptune.new as neptune
from neptunecontrib.monitoring.keras import NeptuneMonitor

run = neptune.init(
       project='common/tf-keras-integration',
       api_token='ANONYMOUS'
)

neptune_cbk = NeptuneCallback(run=run, base_namespace='metrics')

model.fit(x_train, y_train, 
          validation_split=0.2, 
          epochs=10, 
          callbacks=[neptune_cbk])

并且在 UI 中监控您的实验学习曲线:

为什么会发生卡雷损失南

大多数情况下,您记录的损失只是一些常规值,但有时在使用 Keras 损失函数时,您可能会得到 nan。

当这种情况发生时,您的模型将不会更新其权重,并将停止学习,因此需要避免这种情况。

nan 丢失的原因可能有很多,但通常是这样的:

  • 训练集中的 nans 将导致失败,
  • 训练集中的 NumPy 无穷大也会导致 nans 的丢失,
  • 使用未缩放的训练集,
  • 使用非常大的 l2 正则化子和高于 1 的学习率,
  • 使用了错误的优化函数,
  • 大(爆炸)梯度导致训练期间网络权重的大更新。

所以为了避免 nans 中的损失,确保:

  • 检查您的训练数据是否适当缩放,并且不包含 nans
  • 检查你是否使用了正确的优化器,并且你的学习率不是太大;
  • 检查 l2 正则化是否不太大;
  • 如果你正面临爆炸梯度问题,你可以:重新设计网络或使用梯度剪辑,使你的梯度有一定的“最大允许模型更新”。

最后的想法

希望这篇文章能给你一些 Keras 中损失函数的背景知识。

我们涵盖了:

  • Keras 中内置的损失函数,
  • 实现您自己的自定义损失函数,
  • 如何增加样品称量以产生观察敏感损失,
  • 如何避免损失 nans,
  • 你如何想象你的模型在训练时的损失。

欲了解更多信息,请查看 Keras 知识库和 T2 张量流损失函数文档。

德里克·姆维蒂

Derrick Mwiti 是一名数据科学家,他对分享知识充满热情。他是数据科学社区的热心贡献者,例如 Heartbeat、Towards Data Science、Datacamp、Neptune AI、KDnuggets 等博客。他的内容在网上被浏览了超过一百万次。德里克也是一名作家和在线教师。他还培训各种机构并与之合作,以实施数据科学解决方案并提升其员工的技能。你可能想看看他在 Python 课程中完整的数据科学和机器学习训练营。


阅读下一篇

Keras Metrics:您需要知道的一切

10 分钟阅读|作者 Derrick Mwiti |年 6 月 8 日更新

Keras 指标是用于评估深度学习模型性能的函数。为您的问题选择一个好的度量标准通常是一项困难的任务。

  • 你需要了解【tf.keras 和 tf.keras 中哪些指标已经可用以及如何使用它们,
  • 在许多情况下,您需要定义您自己的定制指标,因为您正在寻找的指标没有随 Keras 一起提供。
  • 有时,您希望通过在每个时期后查看 ROC 曲线或混淆矩阵等图表来监控模型性能。

本文将解释一些术语:

  • keras 度量准确性
  • keras 编译指标
  • keras 自定义指标
  • 回归的 keras 度量
  • keras 混淆矩阵
  • tf.kerac.metrics.meaniou
  • tf.keras.metrics f1 分数
  • tf.keras.metrics.auc

Continue reading ->


Keras Metrics:您需要知道的一切

原文:https://web.archive.org/web/https://neptune.ai/blog/keras-metrics

Keras 指标是用于评估深度学习模型性能的函数。为您的问题选择一个好的度量标准通常是一项困难的任务。

  • 你需要了解【tf.keras 和 tf.keras 中哪些指标已经可用以及如何使用它们,
  • 在许多情况下,您需要定义您自己的定制指标,因为您正在寻找的指标没有随 Keras 一起提供。
  • 有时,您希望通过在每个时期后查看 ROC 曲线或混淆矩阵等图表来监控模型性能。

本文将解释一些术语:

  • keras 度量准确性
  • keras 编译指标
  • keras 自定义指标
  • 回归的 keras 度量
  • keras 混淆矩阵
  • tf.kerac.metrics.meaniou
  • tf.keras.metrics f1 分数
  • tf.keras.metrics.auc

Keras metrics 101

在 Keras 中,度量在编译阶段传递,如下所示。您可以通过逗号分隔来传递多个指标。

from keras import metrics

model.compile(loss='mean_squared_error', optimizer='sgd',
              metrics=[metrics.mae,
                       metrics.categorical_accuracy])

您应该如何选择这些评估指标?

其中一些在 Keras 中可用,另一些在 tf.keras 中可用。

让我们回顾一下所有这些情况。

Keras 中提供了哪些指标?

Keras 提供了丰富的内置指标。根据你的问题,你会使用不同的。

让我们来看看你可能正在解决的一些问题。

二元分类

二元分类度量用于只涉及两个类别的计算。一个很好的例子是建立深度学习模型来预测猫和狗。我们有两个类别要预测,阈值决定了它们之间的分离点。 binary_accuracyaccuracy 就是 Keras 中的两个这样的函数。

binary_accuracy例如,计算二进制分类问题的所有预测的平均准确率。

keras.metrics.binary_accuracy(y_true, y_pred, threshold=0.5)

准确性 指标计算所有预测的准确率。 y_true 代表真实标签,而 y_pred 代表预测标签。

keras.metrics.accuracy(y_true, y_pred)

confusion_matrix 显示一个表格,显示真阳性、真阴性、假阳性和假阴性。

keras.metrics.confusion_matrix(y_test, y_pred)

在上面的混淆矩阵中,模型做出了 3305 + 375 个正确的预测,106 + 714 个错误的预测。

你也可以把它想象成一个 matplotlib 图表,我们稍后会讲到。

什么是 Keras 精度?

这似乎很简单,但实际上并不明显。

术语“准确度”是一个表达式,让训练文件决定应该使用哪个度量标准(二进制准确度分类准确度稀疏分类准确度)。该决定基于某些参数,如输出形状(由该层产生的张量的形状,并且将是下一层的输入)和损失函数。

因此,有时质疑甚至是最简单的事情也是好的,尤其是当您的度量发生了意想不到的事情时。

多类分类

这些度量用于涉及两个以上类别的分类问题。扩展我们的动物分类例子,你可以有三种动物,猫、狗和熊。因为我们要对两种以上的动物进行分类,所以这是一个多类分类问题。

y_true 的形状是条目数乘以 1,即(n,1 ),但是 y_pred 的形状是条目数乘以类数(n,c)

category _ accuracy指标计算所有预测的平均准确率。

keras.metrics.categorical_accuracy(y_true, y_pred)

sparse _ categorial _ accuracycategorial _ accuracy类似,但大多在对稀疏目标进行预测时使用。一个很好的例子是在深度学习问题中处理文本,如 word2vec。在这种情况下,一个人用数千个类工作,目的是预测下一个单词。这个任务会产生一种情况,y_true 是一个几乎全是零的巨大矩阵,这是使用稀疏矩阵的最佳位置。

keras.metrics.sparse_categorical_accuracy(y_true, y_pred)

top _ k _ category _ accuracy计算 top-k 分类准确率。我们从我们的模型中取出前 k 个预测类,并查看正确的类是否被选为前 k 个。如果是,我们说我们的模型是正确的。

keras.metrics.top_k_categorical_accuracy(y_true, y_pred, k=5)

回归

回归问题中使用的度量包括均方误差、平均绝对误差和平均绝对百分比误差。这些指标用于预测房屋销售和价格等数值。查看这个参考资料,获得关于回归度量的完整指南。

from keras import metrics

model.compile(loss='mse', optimizer='adam', 
              metrics=[metrics.mean_squared_error, 
                       metrics.mean_absolute_error, 
                       metrics.mean_absolute_percentage_error])
                       metrics.categorical_accuracy])

如何在 Keras 中创建自定义指标?

正如我们前面提到的,Keras 还允许您定义自己的定制指标。

您定义的函数必须将 y_truey_pred 作为参数,并且必须返回单个张量值。这些对象是具有 float32 数据类型的张量类型。对象的形状是行数乘以 1。例如,如果有 4,500 个条目,形状将是(4500,1)。

可以在深度学习模型的编译阶段传递函数来使用。

model.compile(...metrics=[your_custom_metric])

如何计算 Keras 中的 F1 分数(精度,召回作为加分)?

让我们看看如何在 Keras 中计算 f1 分数、精确度和召回率。我们将为多类场景创建它,但您也可以将其用于二进制分类。

f1 分数是精确度和召回率的加权平均值。因此,为了计算 f1,我们需要首先创建计算精度和召回率的函数。请注意,在多类场景中,您需要查看所有的类,而不仅仅是正类(这是二进制分类的情况)

def recall(y_true, y_pred):
    y_true = K.ones_like(y_true) 
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    all_positives = K.sum(K.round(K.clip(y_true, 0, 1)))

    recall = true_positives / (all_positives + K.epsilon())
    return recall

def precision(y_true, y_pred):
    y_true = K.ones_like(y_true) 
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))

    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision

def f1_score(y_true, y_pred):
    precision = precision_m(y_true, y_pred)
    recall = recall_m(y_true, y_pred)
    return 2*((precision*recall)/(precision+recall+K.epsilon()))

下一步是在我们深度学习模型的编译阶段使用这些函数。我们还添加了默认可用的 Keras 准确性指标。

model.compile(...,metrics=['accuracy', f1_score, precision, recall])

现在让我们根据训练集和测试集来调整模型。

model.fit(x_train, y_train, epochs=5)

现在您可以评估您的模型,并访问您刚刚创建的指标。

(loss, 
accuracy, 
f1_score, precision, recall) = model.evaluate(x_test, y_test, verbose=1)

很好,您现在知道如何在 keras 中创建定制指标了。

也就是说,有时你可以使用已经存在的东西,只是在一个不同的库中,比如 tf.keras🙂

tf.keras 中有哪些指标?

最近 Keras 已经成为 TensorFlow 中的标准 API,有许多有用的指标可供您使用。

让我们来看看其中的一些。与在 Keras 中只使用 keras.metrics 函数调用指标不同,在 tf.keras 中,您必须实例化一个指标类。

例如:

tf.keras.metrics.Accuracy() 

keras 指标和 tf.keras 之间有很多重叠。但是,有一些指标你只能在 tf.keras 中找到。

让我们看看那些。

tf.keras 分类指标

TF . keras . metrics . AUC通过黎曼和计算 ROC 曲线的近似 AUC(曲线下面积)。

model.compile('sgd', loss='mse', metrics=[tf.keras.metrics.AUC()])

您可以使用 precision,回想一下我们以前在 tf.keras 中实现的开箱即用。

model.compile('sgd', loss='mse', 
               metrics=[tf.keras.metrics.Precision(), 
                        tf.keras.metrics.Recall()])

tf.keras 细分指标

TF . keras . metrics . meaniouMean Intersection-Over-Union是用于评估语义图像分割模型的度量。我们首先计算每个类的欠条:

所有班级的平均值。

model.compile(... metrics=[tf.keras.metrics.MeanIoU(num_classes=2)])

tf.keras 回归度量

就像 Keras 一样,tf.keras 也有类似的回归度量。我们不会过多讨论它们,但有一个有趣的指标值得强调,叫做 表示相对误差

表示相对误差 取一次观测的绝对误差,除以常数。这个常数,归一化因子,可以对所有观测值相同,也可以对每个样本不同。

因此,平均相对误差是相对误差的平均值。

tf.keras.metrics.MeanRelativeError(normalizer=[1, 3, 2, 3])

如何在 tf.keras 中创建自定义指标?

tf.keras 中,您可以通过扩展 keras.metrics.Metric 类来创建一个自定义指标。

为此,您必须覆盖 update_state、result 和 reset_state 函数:

  • 【update _ state()对状态变量进行所有更新并计算度量,
  • result() 从状态变量中返回度量值,
  • reset_state() 将每个时期开始时的度量值设置为预定义的常数(通常为 0)
class MulticlassTruePositives(tf.keras.metrics.Metric):
    def __init__(self, name='multiclass_true_positives', **kwargs):
        super(MulticlassTruePositives, self).__init__(name=name, **kwargs)
        self.true_positives = self.add_weight(name='tp', initializer='zeros')

    def update_state(self, y_true, y_pred, sample_weight=None):
        y_pred = tf.reshape(tf.argmax(y_pred, axis=1), shape=(-1, 1))
        values = tf.cast(y_true, 'int32') == tf.cast(y_pred, 'int32')
        values = tf.cast(values, 'float32')
        if sample_weight is not None:
            sample_weight = tf.cast(sample_weight, 'float32')
            values = tf.multiply(values, sample_weight)
        self.true_positives.assign_add(tf.reduce_sum(values))

    def result(self):
        return self.true_positives

    def reset_states(self):

        self.true_positives.assign(0.)

然后我们简单地在编译阶段传递它:

model.compile(...,metrics=[MulticlassTruePositives()])

性能图表:Keras 中的 ROC 曲线和混淆矩阵

有时,性能不能用一个数字来表示,而是用性能图表来表示。这种图表的例子有 ROC 曲线或混淆矩阵。在这些情况下,您可能希望将这些图表记录在某个地方,以便进一步检查。

为了做到这一点,你需要创建一个回调函数,它将在每个时期结束时跟踪你的模型的性能。然后,你可以在一个文件夹中或者在实验跟踪工具中查看改进。让我们开始吧。

首先,我们需要一个回调,在每个时期结束时创建 ROC 曲线和混淆矩阵。

import os

from keras.callbacks import Callback
import matplotlib.pyplot as plt
import numpy as np
from scikitplot.metrics import plot_confusion_matrix, plot_roc

class PerformanceVisualizationCallback(Callback):
    def __init__(self, model, validation_data, image_dir):
        super().__init__()
        self.model = model
        self.validation_data = validation_data

        os.makedirs(image_dir, exist_ok=True)
        self.image_dir = image_dir

    def on_epoch_end(self, epoch, logs={}):
        y_pred = np.asarray(self.model.predict(self.validation_data[0]))
        y_true = self.validation_data[1]             
        y_pred_class = np.argmax(y_pred, axis=1)

        fig, ax = plt.subplots(figsize=(16,12))
        plot_confusion_matrix(y_true, y_pred_class, ax=ax)
        fig.savefig(os.path.join(self.image_dir, f'confusion_matrix_epoch_{epoch}'))

        fig, ax = plt.subplots(figsize=(16,12))
        plot_roc(y_true, y_pred, ax=ax)
        fig.savefig(os.path.join(self.image_dir, f'roc_curve_epoch_{epoch}'))

现在我们简单地将它传递给 model.fit() callbacks 参数。

performance_cbk = PerformanceVisualizationCallback(
                      model=model,
                      validation_data=validation_data,
                      image_dir='performance_vizualizations')

history = model.fit(x=x_train,
                    y=y_train,
                    epochs=5,
                    validation_data=validation_data,
                    callbacks=[performance_cbk])

如果你愿意,你可以有多个回调。

现在,您将能够在模型训练时看到这些可视化效果:

你也可以像 Neptune 一样把一切记录到实验跟踪工具中。这种方法将让您在一个地方拥有所有的模型元数据。为此,您可以使用 Neptune + TensorFlow / Keras 集成:

from neptune.new.integrations.tensorflow_keras import NeptuneCallback
import neptune.new as neptune
from scikitplot.metrics import plot_confusion_matrix
import matplotlib.pyplot as plt

run = neptune.init(
        project='YOUR_WORKSAPCE/YOUR_PROJECT_NAME',
        api_token='YOUR_API_TOKEN')

请注意,您不需要为图像创建文件夹,因为图表将直接发送到您的工具。另一方面,你必须创建一个项目来开始跟踪你的跑步。

一旦你做到了这一点,一切照常。

neptune_cbk = NeptuneCallback(run=run, base_namespace='metrics')

history = model.fit(x=x_train,
                    y=y_train,
                    epochs=5,
                    validation_data=validation_data,
                    callbacks=[neptune_cbk])

fig, ax = plt.subplots(figsize=(16, 12))
plot_confusion_matrix(y_train, y_train_pred, ax=ax)

run['confusion_matrix'].upload(neptune.types.File.as_image(fig))

您可以在应用中探索指标和性能图表。

如何绘制 Keras 历史对象?

每当调用 fit() 时,它都返回一个 历史 对象,该对象可用于可视化训练历史。它包含一个字典,其中包含为训练和验证数据集计算的每个历元的损失和度量值

例如,让我们提取“准确性”指标,并使用 matplotlib 绘制它。

import matplotlib.pyplot as plt

history = model.fit(x_train, y_train, 
                    validation_split=0.25, 
                    epochs=50, batch_size=16, verbose=1)

plt.plot(history.history['accuracy'])
plt.plot(history.history['val_‘accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

Keras 指标示例

好了,你已经走了很长一段路,学到了很多。为了唤起你的记忆,让我们把它们放在一个例子中。

我们将从 mnist 数据集开始,并创建一个简单的 CNN 模型:

import tensorflow as tf

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
validation_data = x_test, y_test

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation='softmax')
])

我们将在 keras 中创建一个自定义指标、多类别 f1 分数:

def recall(y_true, y_pred):
    y_true = K.ones_like(y_true) 
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    all_positives = K.sum(K.round(K.clip(y_true, 0, 1)))

    recall = true_positives / (all_positives + K.epsilon())
    return recall

def precision(y_true, y_pred):
    y_true = K.ones_like(y_true) 
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))

    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision

def f1_score(y_true, y_pred):
    precision = precision_m(y_true, y_pred)
    recall = recall_m(y_true, y_pred)
    return 2*((precision*recall)/(precision+recall+K.epsilon()))

我们将创建一个定制的 tf.keras 度量:multiclasstruepoints确切地说:

class MulticlassTruePositives(tf.keras.metrics.Metric):
    def __init__(self, name='multiclass_true_positives', **kwargs):
        super(MulticlassTruePositives, self).__init__(name=name, **kwargs)
        self.true_positives = self.add_weight(name='tp', initializer='zeros')

    def update_state(self, y_true, y_pred, sample_weight=None):
        y_pred = tf.reshape(tf.argmax(y_pred, axis=1), shape=(-1, 1))
        values = tf.cast(y_true, 'int32') == tf.cast(y_pred, 'int32')
        values = tf.cast(values, 'float32')
        if sample_weight is not None:
            sample_weight = tf.cast(sample_weight, 'float32')
            values = tf.multiply(values, sample_weight)
        self.true_positives.assign_add(tf.reduce_sum(values))

    def result(self):
        return self.true_positives

    def reset_states(self):

        self.true_positives.assign(0.)

我们将用我们的指标编译 keras 模型:

import keras

model.compile(optimizer='sgd',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy',
                       keras.metrics.categorical_accuracy,
                       f1_score, 
                       recall_score, 
                       precision_score,
                       tf.keras.metrics.TopKCategoricalAccuracy(k=5),
                       MulticlassTruePositives()])

我们将实现 keras 回调,它将 ROC 曲线和混淆矩阵绘制到一个文件夹中:

import os

from keras.callbacks import Callback
import matplotlib.pyplot as plt
import numpy as np
from scikitplot.metrics import plot_confusion_matrix, plot_roc

class PerformanceVisualizationCallback(Callback):
    def __init__(self, model, validation_data, image_dir):
        super().__init__()
        self.model = model
        self.validation_data = validation_data

        os.makedirs(image_dir, exist_ok=True)
        self.image_dir = image_dir

    def on_epoch_end(self, epoch, logs={}):
        y_pred = np.asarray(self.model.predict(self.validation_data[0]))
        y_true = self.validation_data[1]             
        y_pred_class = np.argmax(y_pred, axis=1)

        fig, ax = plt.subplots(figsize=(16,12))
        plot_confusion_matrix(y_true, y_pred_class, ax=ax)
        fig.savefig(os.path.join(self.image_dir, f'confusion_matrix_epoch_{epoch}'))

        fig, ax = plt.subplots(figsize=(16,12))
        plot_roc(y_true, y_pred, ax=ax)
        fig.savefig(os.path.join(self.image_dir, f'roc_curve_epoch_{epoch}'))

performance_viz_cbk = PerformanceVisualizationCallback(
                                       model=model,
                                       validation_data=validation_data,
                                       image_dir='perorfmance_charts')

我们将进行培训并监控表现:

history = model.fit(x=x_train,
                    y=y_train,
                    epochs=5,
                    validation_data=validation_data,
                    callbacks=[performance_viz_cbk])

我们将可视化来自 keras 历史对象的指标:

plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

我们将在 TensorBoard 或 Neptune 等工具中监控和探索您的实验。

海王星

run = neptune.init(
        project='YOUR_WORKSAPCE/YOUR_PROJECT_NAME',
        api_token='YOUR_API_TOKEN')

neptune_cbk = NeptuneCallback(run=run, base_namespace='metrics')
history = model.fit(..., callbacks=[neptune_cbk])

如果您感兴趣,请查看此文档和示例实验运行:

👉了解更多关于 Neptune 与 Keras 的整合。

张量板

您只需要添加另一个回调或者修改您之前已经创建的回调:

from  tf.keras.callbacks import TensorBoard

tensorboard_cbk = TensorBoard(log_dir="logs/training-example/")

history = model.fit(..., callbacks=[performance_viz_cbk, 
                                    tensorboard_cbk])

使用 TensorBoard,您需要启动本地服务器并在浏览器中浏览您的跑步记录。

tensorboard --logdir logs/training-example/

最后的想法

希望这篇文章能给你一些 keras 中模型评估技术的背景知识。

我们涵盖了:

  • keras 和 tf.keras 中的内置方法,
  • 实现您自己的定制指标,
  • 如何在模型训练时可视化自定义性能图表。

欲了解更多信息,请查看 Keras 知识库和张量流度量文档。

快乐训练!

德里克·姆维蒂

Derrick Mwiti 是一名数据科学家,他对分享知识充满热情。他是数据科学社区的热心贡献者,例如 Heartbeat、Towards Data Science、Datacamp、Neptune AI、KDnuggets 等博客。他的内容在网上被浏览了超过一百万次。德里克也是一名作家和在线教师。他还培训各种机构并与之合作,以实施数据科学解决方案并提升其员工的技能。你可能想看看他在 Python 课程中完整的数据科学和机器学习训练营。


阅读下一篇

如何在您的项目中跟踪机器学习模型指标

3 分钟阅读| Jakub Czakon |发布于 2020 年 6 月 22 日

跟踪机器学习模型的评估指标至关重要,以便:

  • 了解您的模型做得如何
  • 能够将它与以前的基线和想法进行比较
  • 了解你离项目目标有多远

“如果你不衡量它,你就不能改进它。”

但是你应该跟踪什么呢?

我从来没有发现自己在这样的情况下,我认为我已经为我的机器学习实验记录了太多的指标。

此外,在现实世界的项目中,您所关心的指标可能会由于新的发现或不断变化的规范而改变,因此记录更多的指标实际上可以在将来为您节省一些时间和麻烦。

不管怎样,我的建议是:

“记录比你认为需要的更多的指标。”

好吧,但是你具体是怎么做的呢?

跟踪单一数字的指标

在许多情况下,您可以为机器学习模型的性能分配一个数值。您可以计算保留验证集的准确度、AUC 或平均精度,并将其用作模型评估指标。

在这种情况下,您应该跟踪每次实验运行的所有这些值。

Continue reading ->


Keras Tuner:从现实深度学习模型的超参数调整中获得的经验

原文:https://web.archive.org/web/https://neptune.ai/blog/keras-tuner-tuning-hyperparameters-deep-learning-model

你的机器学习模型的性能取决于你的配置。对于每个机器学习工程师来说,找到模型和训练算法的最佳配置是一个巨大的挑战。

模型配置可以定义为一组影响模型架构的超参数。在深度学习的情况下,这些可以是像层数或激活函数类型这样的事情。另一方面,训练算法配置影响训练过程的速度和质量。您可以将学习率值视为训练配置中参数的一个很好的示例。

为了选择正确的超参数集,我们进行超参数调整。尽管调优可能会耗费时间和 CPU,但最终结果是值得的,可以释放您的模型的最大潜力。

如果你像我一样,是一名使用 TensorFlow/Keras 的深度学习工程师,那么你应该考虑使用 Keras Tuner。这是一款非常棒的工具,有助于以智能、便捷的方式进行超参数调整。

在这篇文章中,我将告诉你我如何喜欢在深度学习项目中实现 Keras Tuner。

为什么真正的项目很重要

我所做的一切都是基于一个真实的项目。这不是一个玩具问题,提到这一点很重要,因为你可能已经看到了其他不是基于真实项目的文章。嗯,不是这个!

为什么参与反映现实生活的项目如此重要?很简单:这些项目的核心要复杂得多。在小的合成问题上可能工作良好的工具,在现实生活的挑战中可能表现不佳。所以,今天我将向你展示你可以从 Keras Tuner 、中期待什么样的真正价值,以及如何在你自己的深度学习项目中实现它。

项目描述和问题陈述

我们将做一个图像分割任务。我们将尝试在纸张扫描图像上分割多个感兴趣的对象。我们的最终目标是使用分段提取特定的文本片段。下面的纸张扫描是我们将要使用的示例:

Keras tuner input image

Example of an input image where we will need to segment text objects of our interest

我们可以利用计算机视觉的最新进展来解决这个问题。例如,由 Ronneberger,Fischer 和 Brox 在 2015 年首次推出的用于分割医学图像的 U-NET 是一种深度学习神经网络,我们可以利用它来实现我们的目的。U-NET 的输出是一组遮罩,其中每个遮罩包含一个感兴趣的特定对象。

Real UNET

Real UNET’s output for an input image introduced previously. Table ordering numbers are segmented in a single mask

Real UNET

Real UNET’s output for an input image introduced previously. Stamp region is segmented in a single mask

基本上,对于一个包含一些物体的输入图像,我们的深度神经网络在训练的时候,要把我们感兴趣的所有物体分割出来,返回一组遮罩;每个遮罩对应于一个特定类别的对象。如果你对 U-NET 及其工作原理感兴趣,我强烈推荐阅读这篇研究论文

模型和指标选择

我们不会从头开始创建一个模型。自 2015 年推出 U-NET 以来,我们已经有了多种实施方案。让我们利用这一点。

我已经导入了模型,我将初始化模型类的一个对象。让我们看一下文档来了解可变参数:

Signature:
unet(
    input_size=(512, 512, 1),
    start_neurons=64,
    net_depth=4,
    output_classes=1,
    dropout=False,
    bn_after_act=False,
    activation='mish',
    pretrained_weights=None,
)
Docstring:
Generates U-Net architecture model (refactored version)

Parameters:
    input_size : tuple (h, w, ch) for the input dimentions
    start_neurons : number of conv units in the first layer
    net_depth : number of convolution cascades including the middle cascade
    dropout : True -> use dropouts
    bn_after_act : True -> BatchNormalizations is placed after activation layers. Before otherwise
    activation : Type of activation layers: 'mish' - Mish-activation (default), 'elu' = ELU, 'lrelu' - LeakyReLU, 'relu' - ReLU
    pretrained_weights - None or path to weights-file
Return:
    U-net model
File:      ~/ml_basis/synthetic_items/models/unet.py
Type:      function

显示一组初始化参数的 U-NET 类的 Docstring】

正如我们从 docstring 中看到的,有八个参数定义了我们未来的模型。只有五个参数影响模型的架构。另外三个参数input_size, output_classespretrained_weights,让我们分别定义输入图像的大小、输出类的数量以及从先前预训练的模型到权重的路径。

我们将关注 5 个参数中的一个,这 5 个参数使模型的架构更加清晰。这就是我们将使用 Keras 调谐器进行超参数调谐的地方。

为了通过超参数调整找到最佳的模型架构,我们需要为模型评估选择一个度量。为了解决这个问题,让我们回忆一下 U-NET 对每个图像像素执行二进制分类,将每个像素链接到一个特定的对象类。与图像尺寸相比,我们的问题域中感兴趣的对象非常小。考虑到这一点,我们应该想出一个度量标准来最好地解释像素分类中的这种不平衡。这也是 F1 得分在车型评估方面表现尤为出色的地方。

Keras 调谐器实现

可用调谐器的高级概述

如何使用 Keras Tuner 充分利用我们的模型?首先要说的是,Keras 有多个调谐器。他们使用不同的算法进行超参数搜索。以下是算法,以及 Keras 中相应的调谐器:

  • kerastuner.tuners.hyperband.Hyperband为基于超波段的算法;
  • kerastuner.tuners.bayesian.BayesianOptimization为基于高斯过程的算法;
  • kerastuner.tuners.randomsearch.RandomSearch为随机搜索调谐器。

为了让你对这些方法有一个初步的直觉,我可以说RandomSearch是效率最低的方法。它不从先前测试的参数组合中学习,而只是从搜索空间中随机抽取参数组合。

BayesianOptimizationRandomSearch相似,都是对超参数组合的子集进行采样。关键的区别在于BayesianOptimization并不是随机地对超参数组合进行采样,而是遵循一种内在的概率方法。这种方法考虑了已经测试过的组合,并使用该信息对下一个测试组合进行采样。

HyperbandRandomSearch在搜索时间和资源分配方面的优化版本。

如果你是一个好奇的人,想了解更多关于随机搜索、贝叶斯优化和 HyperBand 的知识,我绝对推荐这篇文章

定义搜索空间并建立模型

Keras tuner 提供了一种优雅的方式来定义模型和调谐器将使用的参数的搜索空间——您可以通过创建一个模型构建器函数来完成这一切。为了向您展示它是多么简单和方便,下面是我们项目的模型构建器功能:

def model_builder(hp):
    """
    Build model for hyperparameters tuning

    hp: HyperParameters class instance
    """

    start_neurons = hp.Int(name = 'start_neurons', min_value = 16, max_value = 128, step = 16)
    net_depth = hp.Int(name = 'net_depth', min_value = 2, max_value = 6)
    dropout = hp.Boolean(name = 'dropout', default = False)
    bn_after_act = hp.Boolean(name = 'bn_after_act', default = False)
    activation = hp.Choice(name = 'activation', values = ['mish', 'elu', 'lrelu'], ordered = False)

    input_size = (544,544,3)
    target_labels = [str(i) for i in range(21)]

    model = u(input_size = input_size,
              start_neurons = start_neurons,
              net_depth = net_depth,
              output_classes = len(target_labels),
              dropout = dropout,
              bn_after_act = bn_after_act,
              activation = activation)

    model.compile(optimizer = Adam(lr = 1e-3),
                  loss = weighted_cross_entropy,
                  metrics = [f1, precision, recall, iou])

    return model

您可能已经注意到,在模型构建器功能中,我们使用了多种方法来定义超参数的搜索空间—hp.Int, hp.Booleanhp.Choice

这些方法的操作方式没有什么特别之处,只是简单地定义了可以在参数搜索空间中使用的值。真正重要的是,作为工程师,我们如何为每个参数选择方法,并为要采样的值定义最佳范围/选项。

例如,仔细考虑hp.Int中的参数非常重要,给它有意义的最小值和最大值(min_valuemax_value)以及一个合适的step。这里您的目标是不要被选项的数量淹没,这会导致调优过程花费太多的时间和资源。同样重要的是,不要限制搜索空间,否则调优器甚至不会考虑可能的最佳值。根据你的专业技能、知识和问题领域,考虑什么样的价值观可能是最好的测试。

除了hp.Int, hp.Booleanhp.Choice之外,还有一些其他选项可供我们在搜索空间中定义值。你可以通过文档熟悉这些方法。

作为创建模型构建器函数的最后一步,我们在返回模型之前对其进行.compile

调谐器初始化

到目前为止,您应该已经有了一个定义好的模型构建器函数,并且知道您想要使用什么算法来进行超参数调整。如果您已经设置好了函数和算法,那么您就可以启动一个调谐器对象了。

对于我们正在进行的图像分割项目,我决定坚持使用Hyperband算法,因此我的初始化代码如下所示:

tuner = kt.Hyperband(hypermodel = model_builder,
                     objective = kt.Objective("val_f1", direction="max"),
                     max_epochs = 20,
					 project_name='hyperband_tuner')

初始化期间使用四个参数:

  • hypermodel是我们之前定义的模型生成器函数;
  • objective是我们的模型试图改进的指标(最大化或最小化)。您可能会从上面的代码片段中注意到,我显式指定了我选择的度量函数的名称(val_f1,代表验证数据集的 f1 得分)以及它必须前进的方向(max);
  • max_epochs定义用于训练每个模型的总时期数。官方文档建议“将此值设置为比您最大模型的预期收敛时间稍高的值”;
  • project_name是放置和存储所有调整相关结果的文件夹路径。

调整流程启动

启动 hypertuning 过程类似于在 Keras/TensorFlow 中拟合模型,除了我们在 tuner 对象上使用.search方法而不是常规的.fit方法。下面是我如何开始该项目的调优工作:

tuner.search(training_data=train_dg,
             steps_per_epoch=batches_per_epoch,
             validation_data=valid_dg,
             validation_steps=len(glob(img_dir + '/*')) / valid_batch_size,
             epochs=50,
             shuffle=True,
             verbose=1,
             initial_epoch=0,
             callbacks=[ClearTrainingOutput()],
             use_multiprocessing=True,
             workers=6)

.search方法和其中使用的所有参数你应该已经很熟悉了,我唯一想指出的是ClearTrainingOutput()回调,它本质上只是在每个训练周期结束时清除输出。下面是ClearTrainingOutput回调的代码:

class ClearTrainingOutput(tf.keras.callbacks.Callback):
    def on_train_end(*args, **kwargs):
        IPython.display.clear_output(wait = True)

获取优化结果

最激动人心的部分来了。让我们看看调音师表现如何。我们很好奇我们能够实现什么样的结果,以及哪种型号配置带来了这样的性能。

要检查超调作业的摘要,我们只需在一个tuner实例上使用.results_summary()。以下是完整的代码:

tuner.results_summary()

运行时,我们在项目中使用的调谐器的输出如下所示:

Results summary:

Results in hyperband_tuner
Showing 10 best trials
Objective(name='val_f1', direction='max')

Trial summary
Hyperparameters:
start_neurons: 32
net_depth: 5
dropout: False
bn_after_act: True
activation: mish
tuner/epochs: 15
tuner/initial_epoch: 0
tuner/bracket: 0
tuner/round: 0
Score: 0.9533569884300232

Trial summary
Hyperparameters:
start_neurons: 80
net_depth: 5
dropout: False
bn_after_act: True
activation: elu
tuner/epochs: 10
tuner/initial_epoch: 0
tuner/bracket: 1
tuner/round: 0
Score: 0.9258414387702942

Trial summary
Hyperparameters:
start_neurons: 128
net_depth: 3
dropout: True
bn_after_act: False
activation: elu
tuner/epochs: 18
tuner/initial_epoch: 3
tuner/bracket: 1
tuner/round: 1
tuner/trial_id: 5bc455f16fad434a9452c51a71c741b0
Score: 0.9170311570167542
..............
Trial summary
Hyperparameters:
start_neurons: 48
net_depth: 3
dropout: True
bn_after_act: False
activation: mish
tuner/epochs: 3
tuner/initial_epoch: 0
tuner/bracket: 1
tuner/round: 0
Score: 0.5333467721939087

Trial summary
Hyperparameters:
start_neurons: 96
net_depth: 3
dropout: True
bn_after_act: True
activation: mish
tuner/epochs: 3
tuner/initial_epoch: 0
tuner/bracket: 1
tuner/round: 0
Score: 0.5279057025909424

Trial summary
Hyperparameters:
start_neurons: 32
net_depth: 3
dropout: False
bn_after_act: False
activation: elu
tuner/epochs: 3
tuner/initial_epoch: 0
tuner/bracket: 1
tuner/round: 0
Score: 0.5064906477928162

在上面的代码片段中,我将.results_summary()的输出缩短到只有 6 次试验,显示了前 3 名和后 3 名的模型。您可能会注意到,对于我们选择的指标(f1 得分),最差的模型只能达到 50 %,而最佳模型的性能达到了惊人的 95.3 %。

结果和业务影响

表现最好和最差之间的差距超过 45 %。从这样的差异中,我们可以得出这样的结论:

  • Keras Tuner 在寻找模型参数的最佳设置方面做了令人难以置信的工作,显示了度量增长的两倍;
  • 作为工程师,我们定义了适当的搜索空间进行采样;
  • Keras Tuner 不仅适用于玩具问题,更重要的是,适用于现实生活中的项目。

让我也分享一下我们获得的业务影响。使用超参数调优针对特定问题域进行了更好优化的模型使我们的服务获得了更稳定、更准确的长期性能。与我们其他类似但未经优化的服务相比,我们的服务接受率提高了 15 %,分类置信度提高了 25 %。

结果跟踪和分享

是时候做一些小动作了。好消息:如果你使用 Neptune ,它现在支持与 Keras Tuner 的完全集成。

借助 Neptune 集成,您可以:

  • 查看每个试验的记录指标图表,
  • 查看每次试验的参数,
  • 查看搜索过程中的硬件消耗,
  • 训练后记录最佳参数,
  • 对数超参数搜索空间,
  • 记录 Keras Tuner 项目目录中所有试验的信息

相当刺激!让我向您展示我如何在我的项目中集成 Neptune 进行跟踪,以便在云中存储调优结果。

我将跳过基本步骤,如海王星初始化实验创建,因为它在官方文档中有很好的描述。

相反,我将把重点放在将 Neptune 应用到您的项目工作流中所需的代码更改上。唯一的变化是调谐器初始化部分。下面是进行更改后初始化的样子:

import neptunecontrib.monitoring.kerastuner as npt_utils

tuner = kt.Hyperband(hypermodel = model_builder,
                     objective = kt.Objective("val_f1", direction="max"),
                     max_epochs = 20,
                     project_name = 'hyperband_tuner',
					 logger = npt_utils.NeptuneLogger())

我们在调谐器中添加了 logger,因此我们可以在每次试用后记录以下内容:

  • 在“超参数/值”文本日志下运行参数;
  • 损失和编译 Keras 模型时定义的所有指标;
  • 搜索过程中 CPU、GPU 和内存的硬件消耗。

除此之外,我还利用.log_tuner_info()方法将更多信息从 Keras Tuner 对象记录到 Neptune。我是这样做的:

npt_utils.log_tuner_info(tuner)

这将记录我们想要跟踪的几乎所有内容:

  • 最佳分数(“最佳分数”度量);
  • 最佳参数(' best_parameters '属性);
  • 每次运行的得分(“run_score”,度量);
  • 调谐器项目目录(' TUNER_PROJECT_NAME '项目);
  • 参数空间(“超参数/空间”文本日志);
  • 用作目标的指标/损失的名称(“目标/名称”属性);
  • 用作目标的指标/损失的方向(“目标/方向”属性);
  • 调谐器 id(“tuner _ id”属性);
  • 最佳试用 id ('best_trial_id '属性)。

有兴趣了解更多吗?观看此指导视频,其中展示了另一个项目的端到端集成示例。另一个巨大的灵感来源是官方文件

在本文中,我们介绍了一个真实项目中完整的 Keras tuner 实现,展示了它通过选择最佳参数集来提高模型性能的潜力。

我们了解了搜索空间定义的重要性,现在知道如何设置我们自己的调优器并开始调优工作。

最后,我向您展示了如何将 Neptune 集成到您的项目中,并跟踪您的试验结果。

我希望这篇文章是有帮助的,你现在知道如何开始使用 Keras 调谐器,以及它能为你做什么。感谢阅读!

KNN 算法——解释、机会、局限

原文:https://web.archive.org/web/https://neptune.ai/blog/knn-algorithm-explanation-opportunities-limitations

k 近邻(KNN)是一个非常简单,易于理解,通用的机器学习算法。它被用于许多不同的领域,如手写检测、图像识别和视频识别。当标记数据过于昂贵或不可能获得时,KNN 最有用,它可以在各种预测类型的问题中实现高精度。

KNN 是一种简单的算法,基于目标函数的局部最小值,用于学习期望精度和准确度的未知函数。该算法还可以找到未知输入的邻域、其范围或距离以及其他参数。它基于“信息增益”的原则——算法找出最适合预测未知值的信息。

在本文中,我们将探索 KNN 算法背后的关键概念,并分析一个真实世界的 KNN 用例。

懒惰学习范式与 KNN 算法

众所周知,KNN 是一种不需要任何数据训练的最大似然算法。这与依赖训练数据集对未知数据进行预测的急切学习方法有很大不同。有了 KNN,你根本不需要训练阶段。

KNN 依靠可观测数据的相似性和复杂的距离度量来生成准确的预测。这种技术一开始可能看起来有点违反直觉,不值得信任,但实际上非常可靠。它在许多领域都很流行,包括:

  • 计算机视觉 : KNN 执行分类任务。它可以很好地处理图像数据,并且被认为是基于相似性对一堆不同图像进行分类的一个很好的选择。
  • 内容推荐 : KNN 对内容推荐很棒。它被用在许多推荐系统引擎中,即使已经有更新的、更强大的系统可用,它仍然是相关的。

维度的诅咒

维数灾难意味着 KNN 在特征数量少的情况下表现最好。当要素数量增加时,就需要更多的数据。当有更多的数据时,它会产生一个过拟合问题,因为没有人知道哪部分噪声会对模型产生影响。在低维情况下,表现更好(如顾和邵 2014 的研究所示)。

KNN 内部运作

令人惊讶的是,KNN 算法非常容易理解。对于不在数据集中的观察,该算法将简单地查找 K 个实例,这些实例基于与该观察最近的周长被定义为相似的。任何数据点都属于一个特定的组,如果它足够接近它的话。

对于 K 邻居,算法会用它们的输出来计算我们想要预测的观测值的变量 y。

因此:

  • 如果 KNN 用于回归任务,预测将基于 K 个最接近的观测值的 平均值中值
  • 如果 KNN 用于分类目的,最接近的观测值的 模式 将用于预测。

近距离观察 KNN 的建筑

假设我们有:

  • 一个数据集 D
  • 一个定义的距离度量,我们将用它来测量一组观察值之间的距离,
  • 以及整数 K ,表示我们应该考虑建立邻近度的最近邻居的最小数量。

为了预测输出进行新的观察,将遵循以下步骤:**

1. 计算 X 可观测值与所有数据点之间的总距离。
2. 保留构成到可观察点
【x .的较小距离的 K 观察值
3. 用
【y】*输出取自观察值:

1.  应用 ***y*** 扣除的平均值如果是回归问题,
2.  如果是分类问题,使用 ***y*** 扣款模式。* 
  1. 最终预测将是步骤 3 中计算的值。
  2. **该算法的详细版本可以在伪代码中找到:

*### 距离和相似性在 KNN 是如何进行的

在其核心,KNN 使用不同种类的距离度量来评估两个数据点的接近程度(它们的相似性)。KNN 的一个核心假设是:

给定的两个点彼此越接近,它们就越相关和相似。

几个距离度量确定相关性和相似性。即使有大量的距离函数可供选择,我们也应该始终使用最适合我们数据性质的函数。值得注意的指标包括:

:我强烈建议你查阅 这篇文章 关于使用 KNN 进行分类任务时距离度量选择的影响。

大多数 ML 库都提供了现成的度量标准。因此,您不需要从头开始编写代码,但您可能希望这样做只是为了了解它们是如何工作的。

选择 K 值

为了选择适合您的数据的 K 值,我们使用不同的 K 值多次运行 KNN 算法。我们将使用准确性作为评估 K 性能的度量。如果精度值与 K 的变化成比例,那么它就是 K 值的一个很好的候选值。

当选择 K 的最佳值时,我们必须记住每组的特征数和样本量。我们的数据集中的特征和组越多,为了找到适当的 k 值,我们需要做出的选择就越大。

当我们把 K 值减小到 1 时,我们的预测变得不稳定。准确性降低,并且度量“F-Measure”对异常值变得更加敏感。为了获得更好的结果,请增加 K 值,直到 F 测量值高于阈值。

此外,您不应该忘记考虑 K 值对样本类分布的影响。如果您倾向于在一个组中有许多人,那么您应该增加 k。相反,如果您的数据集经常在一个组中有大量的人,您需要减少 k。

以下是针对特定数据集改变 K 值的一些示例:

如您所见,使用的邻居越多,分割就越准确。然而,当我们增加 K 值直到达到 N (数据点的总数)时,我们严重地冒着过度拟合我们的模型的风险,使它不能很好地概括看不见的观察结果。

KNN 算法的实际使用案例

为了说明我们到目前为止所解释的内容,我们将尝试使用 KNN 对一个众所周知的数据集进行分析,该数据集记录了美国威斯康星州临床患者的乳腺癌症状。

首先,让我们从 UCI 机器学习库下载数据集。您会发现数据文件夹中有每个属性的详细解释和我们将尝试预测的目标变量。

设置项目

下载数据集并安装所有必需的软件包:

pip install scikit-learn
pip install matplotlib
pip install pandas

导入数据集并以 csv 格式读取:

import pandas as pd

data = pd.read_csv('breast-cancer-wisconsin.data')
data.info()

KNN dataset description

Description of the dataset | Source: Author

添加数据集列名:

data.columns = ['Id', 'Clump Thickness', 'Unifomrmity of Cell size', 'Unifomrmity of Cell shape', 'Marginal Adhesion',
                'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin', 'Normal Nucleoli', 'Mitoses', 'Class']

使用 Plotly 库可视化数据

数据集明显不平衡,分布不均匀。如果我们绘制两组目标变量,良性组记录的病例比恶性组多得多。这可以解释为,有些事件比其他事件更不可能发生。

这是一个比较良性和恶性记录之间平衡的图:

import matplotlib.pyplot as plt
import chart_studio.plotly as py
import plotly.graph_objects as go
import plotly.offline as pyoff

target_balance = data['Class'].value_counts().reset_index()
target_balance

target_class = go.Bar(
    name = 'Target Balance',
    x = ['2-Benign, '4-Malignant'],
    y = target_balance['Class']
)

fig = go.Figure(target_class)
pyoff.iplot(fig)

KNN Begning-Malignant classes

Beginning and Malignant Group Classes | Credit: Author

另一个有见地的统计数据是两组临床患者的有丝分裂水平。1 级最低,9 级最高。有丝分裂水平是导致肿瘤生长和进化的重要因素。自然地,恶性组将登记更多患有晚期有丝分裂阶段的患者。

beg_class_pat = data.loc[data['Class'] == 2]
mal_class_pat = data.loc[data['Class'] == 4]

Mith_10_beg = beg_class_pat['Mitoses'].value_counts().reset_index()
Mith_10_mal = mal_class_pat['Mitoses'].value_counts().reset_index()
fig = go.Figure(data=[
    go.Bar(name='Levels of Mitoses in Begnin Group', x=['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
           y=Mith_10_beg['Mitoses']),
    go.Bar(name='Levels of Mitoses in Malignant Group', x=['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
           y=Mith_10_mal['Mitoses']),
])
fig.update_layout(barmode='group')
fig.show()

KNN level of mitoses

Level of Mitosis in Both clinical Groups | Credit: Author

初始化你的海王星人工智能实验

我通常喜欢从创建一个虚拟环境开始,在那里我将安装项目所需的包。

conda create --name neptune python=3.6
  • 然后,安装 Neptune 客户端库及其所有依赖项。一个更新的版本已经发布,它包含了很多很酷的新特性和 ML 集成。查看这里:海王星 Doc 首页

Neptune migration guide

New Documentation Website, migrate your old projects to the newest API | Source: Neptune Docs

  • 安装 Neptune 及其依赖项,并启用 jupyter 集成:
pip  install neptune-client
pip install -U neptune-notebooks
jupyter nbextension enable --py neptune-notebooks

你也可以在 Neptune 的官方文档网站上查看安装设置指南: Neptune Doc s

import neptune.new as neptune

run = neptune.init(
api_token='YOUR_TOKEN_API',
project='aymane.hachcham/KNN-Thorough-Tour',
)
  • 从你的实验开始。设置我们将使用的所需参数:
run["Algorithm"] = "KNN"

params = {
    "algorithm": auto,
    "leaf_size": 30,
    "metric": minkowski,
    "metric_params": None,
    "N_jobs": None,
    "N_neighbors": None,
    "P": 2
    "weight": uniform
}
run["parameters"] = params
  • 在开始使用 KNN 模型之前,考虑对数据进行预处理。所有属性都是 int64 类型,没有空值。我们还需要将数据分成训练和测试两部分。
data = data.loc[data['Bare Nuclei'] != '?']
data['Bare Nuclei'] = data['Bare Nuclei'].astype('int64')

features = data.loc[:, data.columns != 'Class']
features = features.loc[:, features.columns != 'Id']
target = data['Class']

x_train, x_test, y_train, y_test = train_test_split(features, target, test_size=0.2, random_state=123) 

训练模型

选择最佳 K 值

我们将遍历一系列三个不同的 K 值,并尝试查看哪个 K 最适合我们的情况和数据。首先,让我们试着理解 K 到底影响算法什么。如果我们看到最后一个例子,假设所有 6 个训练观察值保持不变,利用给定的 K 值,我们可以制作每个类别的边界。对于算法来说,这是 K 的一个很好很有用的性质。但是,你可能知道,K 的值不是静态的。K 的值随着每次连续的迭代而变化。这意味着第二次我们将为每个类设置不同的边界值。

我们将使用 neptune.log_metric()记录 Neptune 中的每一次 K 迭代。

accuracy_K = []
for k in range(1, 10):
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(x_train, y_train)
    preds = knn.predict(x_test)
    accuracy = metrics.accuracy_score(y_test, y_pred=preds)
    accuracy_K.append(accuracy)
    run['KValue_accuray'].log(accuracy)

KNN log value in Neptune

KNN log value in Neptune | Credit: Author

我们观察到达到的最大值是 0.992,并且它出现在 K = 6 时。K = {2,4,5}的其他值是 0.98。由于我们有 3 个以上的候选人共享相同的值,我们可以得出结论,最佳 K 值是 5。

在这个特殊的例子中,我们用闵可夫斯基距离来描述 KNN 模型。但是如果你尝试不同的距离,你可能会得到其他的 K 值。

KNN 分类器如下所示:

KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=None, n_neighbors=5, p=2, weights='uniform')

一旦我们确定最佳值 K 为 5,我们将继续使用数据训练模型,并检查其总体准确性得分。

knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(x_train, y_train)
predictions = knn.predict(x_test)
metrics.accuracy_score(y_test, predictions)

KNN accuracy score

Final accuracy score | Credit: Author

KNN 限制

KNN 是一个很容易理解的算法。它不依赖于任何在内部工作并做出预测的 ML 模型。KNN 是一种分类算法,只需要知道类别的数量(一个或多个)。这意味着它可以很容易地确定是否应该添加一个新的类别,而不需要任何关于可能有多少其他类别的数据。

这种简单的缺点是,它不能预测罕见的事情(如新的疾病),KNN 无法预测,因为它不知道一种罕见的事情在其他健康人群中的流行程度。

虽然 KNN 在测试集上产生了很好的准确性,但分类器在时间和内存方面仍然较慢和昂贵。它需要大的存储器来存储用于预测的整个训练数据集。此外,欧几里德距离对量值非常敏感,因此数据集中具有较高量值的要素的权重总是大于具有较低量值的要素的权重。

最后,我们应该记住,KNN 不适合我们上面提到的大规模数据集。

结论

希望你现在对 KNN 算法的工作原理有了更多的了解。我们探讨了许多关于 KNN 如何存储整个数据集来进行预测的概念。

KNN 是许多不基于学习模型进行预测的懒惰学习算法之一。KNN 通过平均输入观测值和已有数据之间的相似性,即时做出预测。

我将为您留下一些有用的资源,让您进一步了解 KNN:

感谢您的阅读!***

知识蒸馏:原理、算法、应用

原文:https://web.archive.org/web/https://neptune.ai/blog/knowledge-distillation

大规模机器学习和深度学习模型越来越普遍。例如,GPT-3 是在 570 GB 的文本上训练的,包含 1750 亿个参数。然而,尽管训练大型模型有助于提高最先进的性能,但部署这种笨重的模型(尤其是在边缘设备上)并不简单。

此外,大多数数据科学建模工作侧重于训练单个大型模型或不同模型的集合,以便在通常不代表真实世界数据的拒绝验证集上表现良好。

训练和测试目标之间的这种不一致导致了机器学习模型的发展,这些模型在精选的验证数据集上产生良好的准确性,但在对真实世界的测试数据进行推断时,往往无法满足性能、延迟和吞吐量基准。

知识提取 [ 1 ]通过捕获和“提取”复杂的机器学习模型或模型集合中的知识,将其转化为更小的单一模型,更容易部署,而不会显著降低性能,从而帮助克服这些挑战。

在这篇博客中,我将:

  • 详细描述知识提炼,其基础原理,训练方案,和算法
  • 深入研究知识蒸馏在图像、文本和音频深度学习方面的应用

什么是知识升华?

知识提炼指的是将知识从一个大的笨拙的模型或一组模型转移到一个较小的模型的过程,该模型可以在现实世界的约束下实际部署。本质上,它是一种模型压缩的形式,由 Bucilua 及其合作者在 2006 年首次成功演示[ 2 ]。

知识提炼通常在与包括几个层和模型参数的复杂体系结构相关联的神经网络模型上执行。因此,随着深度学习在过去十年中的出现,以及它在包括语音识别、图像识别和自然语言处理在内的不同领域中的成功,知识提炼技术在实际的现实世界应用中变得更加突出[ 3 ]。

部署大型深度神经网络模型的挑战对于具有有限存储器和计算能力的边缘设备尤其相关。为了应对这一挑战,首先提出了一种模型压缩方法[ 2 ],将大模型中的知识转移到训练较小的模型中,而不会有任何明显的性能损失。这种从大模型学习小模型的过程被辛顿和他的同事们形式化为“知识蒸馏”框架[ 1 ]。

如图 1 所示,在知识提炼中,一个小的“学生”模型学习模仿一个大的“老师”模型,并利用老师的知识来获得相似或更高的准确性。在下一节中,我将更深入地研究知识提炼框架及其底层架构和机制。

Knowledge distilation framework

Figure 1. The teacher-student framework for knowledge distillation | Source: Arxiv

更深入地挖掘知识精华

知识提炼系统由三个主要部分组成:知识、提炼算法和师生架构。

知识

在神经网络中,知识通常指学习到的权重和偏差。同时,在一个大的深度神经网络中,知识的来源具有丰富的多样性。典型的知识提炼使用逻辑作为教师知识的来源,而其他人则关注中间层的权重或激活。其他种类的相关知识包括不同类型的激活和神经元之间的关系或者教师模型本身的参数。

不同形式的知识分为三种不同类型:基于响应的知识基于特征的知识基于关系的知识。图 2 展示了教师模型中这三种不同类型的知识。我将在下一节详细讨论这些不同的知识来源。

Types of knowledge

Figure 2. The different kinds of knowledge in a teacher model | Source: Arxiv

1.基于响应的知识

如图 2 所示,基于响应的知识关注于教师模型的最终输出层。假设是学生模型将学习模仿教师模型的预测。如图 3 所示,这可以通过使用称为蒸馏损失的损失函数来实现,该损失函数分别捕捉学生和教师模型的逻辑之间的差异。随着这种损失在训练中被最小化,学生模型将变得更善于做出与老师相同的预测。

在像图像分类这样的计算机视觉任务的背景下,软目标包括基于响应的知识。软目标表示输出类的概率分布,通常使用 softmax 函数进行估计。每个软目标对知识的贡献通过一个称为温度的参数来调节。基于软目标的基于响应的知识提取通常用于监督学习的环境中。

Response-based knowledge distillation

Figure 3. Response-based knowledge distillation | Source: Arxiv

2.基于特征的知识

一个训练有素的教师模型还可以捕获中间层数据的知识,这对于深度神经网络尤其重要。中间层学习辨别特定的特征,并且该知识可以用于训练学生模型。如图 4 所示,目标是训练学生模型学习与教师模型相同的特性激活。蒸馏损失函数通过最小化教师和学生模型的特征激活之间的差异来实现这一点。

Feature-based knowledge distillation

Figure 4. Feature-based knowledge distillation | Source: Arxiv

3.基于关系的知识

除了在神经网络的输出层和中间层中表示的知识之外,捕获特征图之间的关系的知识也可以用于训练学生模型。这种形式的知识,称为基于关系的知识,如图 5 所示。这种关系可以被建模为基于特征表示的特征图、图形、相似矩阵、特征嵌入或概率分布之间的相关性。

Relation-based knowledge distillation

Figure 5. Relation-based knowledge distillation | Source: Arxiv

培养

有三种主要类型的方法用于训练学生和教师模型,即离线、在线和自我升华。蒸馏训练方法的分类取决于教师模型是否与学生模型同时被修改,如图 6 所示。

Types of knowledge distillation

Figure 6. Types of knowledge distillation training schemes | Source: Arxiv

1.离线蒸馏

离线蒸馏是最常见的方法,其中使用预先训练的教师模型来指导学生模型。在该方案中,教师模型首先在训练数据集上进行预训练,然后从教师模型中提取知识来训练学生模型。鉴于深度学习的最新进展,各种各样的预训练神经网络模型公开可用,可以根据用例充当老师。离线蒸馏是深度学习中的一种既定技术,更容易实现。

2.在线蒸馏

在离线蒸馏中,预先训练好的教师模型通常是大容量的深度神经网络。对于一些用例,预训练的模型可能不可用于离线提取。为了解决这个限制,可以使用在线蒸馏,在单个端到端的培训过程中同时更新教师和学生模型。在线蒸馏可以使用并行计算来操作,从而使其成为一种高效的方法。

3.自蒸馏

如图 6 所示,在自提取中,相同的模型被用于教师和学生模型。例如,来自深层神经网络深层的知识可以用来训练浅层。它可以被认为是在线蒸馏的一个特例,并以几种方式进行实例化。来自教师模型的早期时代的知识可以转移到它的后期时代来训练学生模型。

体系结构

师生网络架构的设计对于有效的知识获取和提炼至关重要。通常,在更复杂的教师模型和更简单的学生模型之间存在模型容量差距。这种结构性差距可以通过高效的师生架构优化知识传递来缩小。

由于深度和广度的原因,从深度神经网络传递知识并不简单。最常见的知识转移架构包括学生模型,即:

  • 教师模型的更浅版本,具有更少的层和每层更少的神经元,
  • 教师模型的量化版本,
  • 具有高效基本操作的较小网络,
  • 具有优化的全球网络架构的小型网络,
  • 和老师一个型号。

除了上述方法之外,在给定特定教师模型的情况下,最近的进展如神经架构搜索也可以用于设计最佳学生模型架构。

知识提炼算法

在这一节中,我将重点讨论训练学生模型从教师模型中获取知识的算法。

1.对抗蒸馏

最近在生成对抗网络的上下文中概念化的对抗学习用于训练生成器模型和鉴别器模型,该生成器模型学习生成尽可能接近真实数据分布的合成数据样本,该鉴别器模型学习在真实和合成数据样本之间进行鉴别。这一概念已被应用于知识提炼,以使学生和教师模型能够学习真实数据分布的更好表示。

为了满足学习真实数据分布的目标,对抗学习可以用于训练生成器模型,以获得合成训练数据来使用,或者扩充原始训练数据集。第二种基于对抗学习的提取方法集中于鉴别器模型,以基于逻辑或特征图来区分来自学生和教师模型的样本。这种方法有助于学生很好地模仿老师。第三种基于对抗学习的提炼技术集中于在线提炼,其中学生和教师模型被联合优化。

2.多师蒸馏

在多教师提取中,一个学生模型从几个不同的教师模型中获取知识,如图 7 所示。使用教师模型的集合可以为学生模型提供不同种类的知识,这比从单个教师模型获得的知识更有益。

来自多个教师的知识可以被组合为所有模型的平均响应。教师传授的知识类型通常基于逻辑和特征表示。如 2.1 节所述,多名教师可以传授不同种类的知识。

Multi-teacher distillation

Figure 7. Multi-teacher distillation | Source: Arxiv

3.交叉模式蒸馏

图 8 显示了跨模态蒸馏训练方案。在这里,教师接受一种模态的训练,其知识被提炼到需要不同模态知识的学生身上。当在训练或测试期间特定模态的数据或标签不可用时,出现这种情况,因此需要跨模态传递知识。

跨模态提取最常用于视觉领域。例如,来自在标记的图像数据上训练的教师的知识可以用于提取具有未标记的输入域(如光流或文本或音频)的学生模型。在这种情况下,从来自教师模型的图像中学习的特征被用于学生模型的监督训练。跨模态提取对于诸如视觉问答、图像字幕等应用是有用的。

Cross-modal distillation

Figure 8. Cross-modal distillation | Source: Arxiv

4.其他人

除了上面讨论的提取算法之外,还有其他几种算法已经被应用于知识提取。

  • 基于图形的提炼使用图形而不是从教师到学生的单个实例知识来捕捉内部数据关系。图表有两种用途——作为知识传递的手段,以及控制教师知识的传递。在基于图的提取中,图的每个顶点代表一个自我监督的老师,该老师可以基于基于响应或基于特征的知识,分别像逻辑和特征图。
  • 基于注意力的提炼基于使用注意力地图从特征嵌入中转移知识。
  • 无数据提炼基于因隐私、安全或保密原因而缺乏训练数据集的合成数据。合成数据通常从预先训练的教师模型的特征表示中生成。在其他应用中,GANs 也用于生成合成训练数据。
  • 量子化蒸馏用于将知识从高精度的教师模型(如 32 位浮点)转移到低精度的学生网络(如 8 位)。
  • 终身学习基于持续学习、终身学习和元学习的学习机制,积累以前学到的知识并将其转化为未来的学习。
  • 基于神经架构搜索的提取用于识别合适的学生模型架构,以优化从教师模型的学习。

知识提炼的应用

知识提炼已经成功应用于几个机器学习和深度学习用例,如图像识别、NLP 和语音识别。在这一部分,我将强调知识提炼技术的现有应用和未来潜力。

1.视力

知识提炼在计算机视觉领域的应用非常丰富。最先进的计算机视觉模型越来越多地基于深度神经网络,这些网络可以从部署的模型压缩中受益。知识提炼已成功应用于以下用例:

  • 图像分类,
  • 人脸识别,
  • 图像分割,
  • 动作识别,
  • 物体检测,
  • 车道检测,
  • 行人检测,
  • 面部标志检测,
  • 姿势估计,
  • 视频字幕,
  • 图像检索,
  • 阴影检测,
  • 文本到图像的合成,
  • 视频分类,
  • 视觉问答,以及其他[ 3 ]。

知识提炼还可以用于交叉分辨率人脸识别等利基用例,其中基于高分辨率人脸教师模型和低分辨率人脸学生模型的架构可以提高模型性能和延迟。由于知识提取可以利用不同种类的知识,包括跨模态数据、多领域、多任务和低分辨率数据,因此可以针对特定的视觉识别用例来训练各种各样的提取的学生模型。

2.自然语言处理

考虑到大容量深度神经网络(如语言模型或翻译模型)的流行,针对 NLP 应用的知识提取的应用尤其重要。最先进的语言模型包含数十亿个参数,例如,GPT-3 包含 1750 亿个参数。这比之前最先进的语言模型 BERT 大了几个数量级,它在基础版本中包含 1.1 亿个参数。

因此,知识提炼在 NLP 中非常流行,以获得快速、轻量级的模型,这些模型更容易训练并且计算成本更低。除了语言建模,知识提炼也用于 NLP 用例,如:

  • 神经机器翻译,
  • 文本生成,
  • 问题回答,
  • 文档检索,
  • 文本识别[ 3 ]。

使用知识提炼,可以获得高效和轻量级的 NLP 模型,其可以以较低的存储器和计算需求来部署。师生培训也可以用来解决多语言 NLP 问题,来自多语言模型的知识可以相互转移和共享。

案例研究:蒸馏瓶

DistilBERT 是抱脸研发的更小更快更便宜更轻的 BERT 模型[ 4 ]。在这里,作者预先训练了一个较小的 BERT 模型,该模型可以在各种 NLP 任务上进行微调,具有相当强的准确性。在预训练阶段应用了知识提炼,以获得 BERT 模型的提炼版本,该版本比之前的版本小 40%(6600 万个参数对 1.1 亿个参数),并且快 60%(对于胶水情绪分析任务的推断,410 秒对 668 秒),同时保持相当于原始 BERT 模型准确度的 97%的模型性能。在 DistilBERT 中,学生具有与 BERT 相同的架构,并使用一种新颖的三重损失获得,该损失结合了与语言建模、蒸馏和余弦距离损失相关的损失。

3.演讲

最先进的语音识别模型也是基于深度神经网络的。现代 ASR 模型是端到端训练的,并且基于包括卷积层、序列到序列模型以及最近的变压器的架构。对于实时、设备上的语音识别,获得更小、更快的模型以获得有效的性能变得至关重要。

演讲中有几个知识提炼的用例:

  • 语音识别,
  • 口语识别,
  • 音频分类,
  • 说话人识别,
  • 声学事件检测,
  • 语音合成,
  • 语音增强,
  • 抗噪声 ASR,
  • 多语言 ASR,
  • 重音检测[10]。

案例研究:亚马逊 Alexa 的声学建模

Parthasarathi 和 Strom (2019)利用师生培训为 100 万小时的未标记语音数据生成软目标,其中训练数据集仅由 7000 小时的标记语音组成。教师模型产生了所有输出类的概率分布。给定相同的特征向量,学生模型还在输出类上产生概率分布,并且目标函数优化这两个分布之间的交叉熵损失。在这里,知识提炼有助于简化在大型语音数据语料库上生成目标标签。

结论

现代深度学习应用基于笨重的神经网络,具有大容量、内存占用和缓慢的推理延迟。将这样的模型部署到生产中是一个巨大的挑战。知识提炼是一种优雅的机制,用于训练一个更小、更轻、更快、更便宜的学生模型,该模型是从一个大型、复杂的教师模型中派生出来的。在 Hinton 及其同事(2015 年)提出知识提炼的概念后,为获得生产用例的高效和轻量级模型而采用知识提炼方案的情况大幅增加。知识提炼是一项复杂的技术,基于不同类型的知识、训练方案、架构和算法。知识提炼已经在不同的领域取得了巨大的成功,包括计算机视觉、自然语言处理、语音等等。

参考

[1]在神经网络中提取知识。Hinton G,Vinyals O,Dean J (2015) NIPS 深度学习和表征学习研讨会。https://arxiv.org/abs/1503.02531

[2]模型压缩。布西卢阿 C,卡鲁阿纳 R,尼古列斯库-米齐尔 A (2006 年)https://dl.acm.org/doi/10.1145/1150402.1150464

[3]知识升华:一项调查。尤杰,于 B,梅班克 SJ,陶 D (2021)

[4]蒸馏伯特,伯特的蒸馏版:更小、更快、更便宜、更轻(2019) Sanh V,出道 L,Chammond J,Wolf t .https://arxiv.org/abs/1910.01108v4

[5]用一百万小时的演讲建立声学模型的经验(2019)斯特罗姆·n·帕萨拉蒂·SHKhttps://arxiv.org/abs/1904.01624

库伯流管道中的实验跟踪

原文:https://web.archive.org/web/https://neptune.ai/blog/kubeflow-pipelines-experiment-tracking

实验跟踪一直是机器学习项目中最受欢迎的主题之一。很难想象一个新项目在没有跟踪每个实验的运行历史、参数和度量的情况下被开发。

虽然一些项目可能会使用更“原始”的解决方案,比如将所有实验元数据存储在电子表格中,但这绝对不是一个好的做法。随着团队的成长和越来越多实验的安排,这将变得非常乏味。

许多成熟的、积极开发的工具可以帮助你的团队跟踪机器学习实验。在本文中,我将介绍和描述其中的一些工具,包括 TensorBoardMLFlowNeptune.ai ,特别是在使用 Kubeflow Pipelines 时,这是一个运行在 Kubernetes 上的流行框架。

深入挖掘

点击此处了解更多关于实验跟踪的信息。你会发现:

  • 实验跟踪如何帮助你改进工作流程,
  • 可能的实施方式,
  • 可用工具,
  • 和用例的例子。

什么是库伯流?

为了理解如何跟踪 Kubeflow 管道中的实验,我们需要理解 Kubeflow 是什么。

Kubeflow 是一个先进的、可扩展的平台,用于在 Kubernetes 集群上运行机器学习工作流。它提供的组件涵盖了数据科学项目中经常执行的大多数典型任务,例如:

  • 笔记本:用于探索性数据分析、原型制作等。,
  • 管道:用于定义和运行机器学习(或一般的数据)工作流,
  • Katib :超参数优化和神经架构搜索的内部工具,

它还支持模型服务(使用 KServe、Seldon 和其他框架)、与功能商店的集成,如盛宴等等。你可以在他们的网站上了解 Kubeflow 组件、架构和可能的集成

Kubeflow 的一个主要特点是它运行在 Kubernetes 上,维护起来可能很有挑战性,但由于它能够按需调度和扩展工作负载,并将模型部署为微服务,因此也可以为机器学习项目带来许多好处。

使用 Kubeflow 可能非常复杂(Kubernetes 也是如此),因为有太多可用的功能,甚至更多的功能发生在幕后(集成这些组件、设置网络等)。).在本文中,我们将只关注 KF 的一个子集,即我将在下一节描述的 Kubeflow 管道。

库伯弗洛管道公司

根据 2021 年在 Kubeflow 社区进行的调查,管道是最受欢迎的组件,比笔记本电脑略受欢迎。这是因为这两个模块对于开发阶段的每个机器学习项目都至关重要。

Kubeflow 中的 Pipeline 是单个步骤的图表(如摄取数据、特征工程、培训)。这些组件的流程和它们之间共享的数据形成了一个管道,可以从 Kubeflow UI 或以编程方式执行。一个非常相似的定义被其他管道框架使用,比如 Airflow、Prefect 等。

该组件的一个重要特性是管道中的每一步都在一个独立的容器中执行,该容器运行在 Kubernetes pods 中。这种方法鼓励开发人员编写模块化代码,然后将这些代码组合成一个管道。

由于每个步骤都被定义为一个 Docker 映像,因此在保持管道定义和数据流不变的同时,更新或交换单个步骤也变得更加容易。这是成熟的、可扩展的机器学习管道的一个重要特征。

示例管道可以在 Kubeflow 管道库内的` samples '目录中找到。

Kubeflow pipelines deployment

Figure 2. Standalone deployment of Kubeflow Pipelines | Source: image by the author

如前所述,管道可以手动、编程和循环运行的方式执行。这可能会导致每天执行数十次流水线操作,这自然需要一个合适的实验跟踪解决方案。

在这篇文章中,我将展示如何使用流行的“实验跟踪”工具来记录管道运行的参数、指标和其他元数据。我们将探索不同的选项,从最简单的解决方案到最先进的解决方案。

Pipeline run in kubeflow pipelines

Figure 3. Graph illustrating finished pipeline run in Kubeflow Pipelines | Source: image by the author

库伯流管道中的实验跟踪

令人惊讶的是,Kubeflow 原生支持实验跟踪。虽然这不是最先进的解决方案,但它是现成可用的,这无疑是您应该为您的团队考虑的一个好处。

每次运行可以产生一组指标(例如 F1,Recall ),这些指标将显示在所有管道运行的列表视图中(参见图 4)。)除了标量指标之外,管道还可以输出指标的图形,例如混淆矩阵和 ROC/AUC 曲线。这样的工件也可以与其他度量一起被保存和分析。

这种方法的最大优点是它与 Kubeflow 管道一起提供,并且不需要额外的设置。另一方面,它是一个非常动态的项目,它的文档往往是过时的或混乱的。

本文接下来的部分中描述的其他工具可能会提供更多的特性和灵活性,但是可能需要额外的代码来与您的管道集成,或者可能会增加您的成本。

Runs in kubeflow experiment tracking

Figure 4. List of completed runs with simple metric history displayed | Source: image by the author

Kubeflow 管道中用于实验跟踪的其他工具

虽然使用内置跟踪工具可能是最简单的解决方案,但对于您的用例来说可能不是最方便的。这就是为什么我要介绍一些其他流行的跟踪管道结果的选择。

张量板

如果我没记错的话,过去, TensorBoard 是一个简单的可视化工具,用于记录训练历史(损失和其他指标,如 F1、准确度等)。).现在用户还可以记录图像和各种图表(直方图、分布图),以及模型图

您可能会注意到,这些功能与使用 Kubeflow 可以实现的功能有些相似,但 TensorBoard 可以提供更多功能,例如模型分析或与用于模型理解的假设分析工具集成。此外,Kubeflow Pipelines 的文档显示,与 TensorBoard 的集成非常简单。

不幸的是,TensorBoard 强烈倾向于 TensorFlow/Keras 用户,虽然它仍然可以与其他深度学习框架如 PyTorch 一起使用,但它的一些功能可能不可用或难以集成。例如,假设仪表板要求使用 TFServing 为模型提供服务,而模型分析器使用引擎盖下的 TensorFlow Profiler

物流跟踪

另一个可以用来跟踪机器学习实验的工具是 MLFlow。更具体地说,因为 MLFlow 现在提供了其他组件(如模型注册、项目管理、其他,负责实验监控的组件是 MLFlow Tracking

MLFlow 跟踪的 UI 相当原始和简单,类似于我们在 Kubeflow 管道中看到的。它支持简单的度量记录和可视化,以及存储参数。这个工具的优势来自于与 MLFlow 的其他组件的集成,比如模型注册表

MLFlow 可以在 Databricks 上“作为服务”(采用现收现付定价)但大多数用户使用免费的开源版本。人们必须在本地安装它或者在远程服务器上才能使用它。但是,对于 Kubeflow 管道,最方便的使用方法是将其部署在 Kubernetes 集群上(可以在本地安装,也可以作为托管服务安装)。

这需要一点努力来:

  • 在群集上使用 MLFlow Tracking Server 构建和部署 Docker 映像,
  • 配置和部署 Postgres 数据库,
  • 类似于 Postgres 部署 MinIO (MLFLow 的对象存储)服务。

因此,您需要在 Kubernetes 集群上部署、集成和维护三个独立的微服务,以便能够在内部使用 MLFlow。如果您不允许将任何日志存储在服务器之外,这可能是值得的,但是请记住,在生产中维护这样的服务需要一定的经验和技能。

一些 MLflow 的替代品包括 : Aimguild.ai

Neptune.ai

Neptune.ai 结合了之前工具的良好特性:

此外,Neptune.ai 还为您的所有 ML 实验提供元数据和工件存储。与 MLFlow 相反,开发人员不必在他们的机器上安装任何服务器或数据库。

Neptune 可以很容易地与 Kubeflow 管道集成,只需在管道代码中使用 API 客户端调用。要做到这一点,用户只需要获得一个 Neptune API 密匙,并把它保存在一个安全的地方,比如 Kubernetes secret 。还有一件事是联网——你的集群必须能够使用 API 与 Neptune 通信,以便能够发送实验日志。

每个实验的元数据(参数、指标、图像)存储在 Neptune 中,并使用 API 客户端从用户的管道中发送出去。这是迄今为止最简单的方法,因为它将大部分逻辑转移到了工具上。用户只需安装 Neptune 客户端(作为 Python 库分发),实例化它,并发送日志或任何他们想要存储的数据。

Neptune 的另一个优势是用户可以在不同的项目上协作和工作。您可以创建许多项目并控制对它们的访问(分别为每个用户授予读/写权限)。这对于大型公司来说是非常重要的,因为他们会有多个团队在同一个实验跟踪工具上工作。

虽然将实验跟踪的结果存储在“云中”听起来对一些项目来说是一个很大的优势,但其他人可能会担心这种方法的隐私和安全。如果您想将 Neptune 部署在您的私有云中或本地部署,也有这样一个选项。

一些替代 Neptune.ai 的方法包括 : 重量&偏差彗星

库伯流管道实验跟踪工具的比较

总而言之,现在让我们来看看我已经描述过的工具的比较表。它显示了除实验跟踪之外,与预算、维护工作或组件可用性相关的一些最重要的特性。

Kubeflow

张量板

MLflow

Neptune.ai

托管服务还是内部服务?

Kubeflow:

必须安装在 Kubernetes 集群上

Neptune.ai:

是,针对个人用户,不同的 定价 可供团队选择,视需要而定

TensorBoard:

仅当内部部署时

MLflow:

仅当内部部署时

Neptune.ai:

仅当内部部署时

其他特征(除了实验跟踪)

TensorBoard:

仅在 TensorFlow 生态系统内(如 【剖析】 )

它提供访问控制吗?

Kubeflow:

可以有单独的名称空间

MLflow:

仅在托管版本中(由于数据块)

结论

有许多工具可以提供实验跟踪功能,我只描述了其中的一部分。然而,我希望我指出了这些工具的主要“组”:一些是现成可用的,但是是有限的,另一些必须与数据库一起部署在用户的机器上,还有一组工具是可用的托管服务,只需要很少的努力就可以将它们与您的代码集成在一起。

用户应考虑以下因素:

  • 公司的安全政策:如果你的公司对他们的数据非常严格,你可能会更喜欢可以完全离线托管(在你的环境中)的工具,比如 TensorBoard 或者 MLFlow,
  • 预算:一些工具是开源的,另一些工具的定价取决于项目、实验或用户的数量等因素。这些在做选择的时候也要考虑进去。
  • 维护工具的能力:Neptune 或 Weights&bias 等工具的明显优势是使用它们只需最少的努力,用户基本上没有什么需要维护的(除了他们的管道)。例如,如果您决定选择 MLFlow,您将需要在您的团队中负责设置部署、数据库和其他东西,有时团队可能缺乏有效完成这些工作的技能。
  • 对其他功能的需求:在机器学习项目中,你很少需要一个实验跟踪工具。迟早您可能会发现对模型注册中心、数据版本控制或其他功能的需求。最好是选择一个提供这些特性的提供商,而不是同时使用几十种不同的工具。

马提乌斯

deepsense.ai 高级 MLOps 工程师


阅读下一篇

最佳 MLOps 工具以及如何评估它们

12 分钟阅读| Jakub Czakon |年 8 月 25 日更新

在我们的一篇文章中——机器学习团队实际使用的最好的工具、库、框架和方法——我们从 41 家 ML 初创公司学到的东西——Acerta 的 CTO Jean-Christophe Petkovich 解释了他们的 ML 团队如何接近 MLOps。

据他所说,一个完整的 MLOps 系统有几个要素:

  • 您需要能够构建包含预处理数据和生成结果所需的所有信息的模型工件。
  • 一旦您能够构建模型工件,您必须能够跟踪构建它们的代码,以及它们被训练和测试的数据。
  • 您需要跟踪所有这三样东西,模型、它们的代码和它们的数据,是如何关联的。
  • 一旦您可以跟踪所有这些内容,您还可以将它们标记为准备就绪,进行生产,并通过 CI/CD 流程运行它们。
  • 最后,为了在该过程的最后实际部署它们,您需要某种方法来基于该模型工件旋转服务。

这是对如何在公司中成功实施 MLOps 的高度概括。但是理解高层需要什么只是拼图的一部分。另一个是采用或创建适当的工具来完成工作。

这就是为什么我们编制了一份最佳 MLOps 工具的清单。我们将它们分为六类,以便您可以为您的团队和业务选择合适的工具。让我们开始吧!

Continue reading ->


Kubernetes vs Docker:作为机器学习工程师你应该知道什么

原文:https://web.archive.org/web/https://neptune.ai/blog/kubernetes-vs-docker-for-machine-learning-engineer

今年早些时候(2020 年),我决定从数据科学完全转向机器学习的工程部分。我想体验一种更高效、更可扩展的方式来部署机器学习模型,将我的模型从我的应用程序中分离出来,并正确地对它们进行版本控制。

通常,在训练完模型后,我主要做的是将模型导入 flask 应用程序,然后在调用模型的 API 端点时执行推理。嗯,当我试图打包我的应用程序并部署到谷歌云或任何其他平台时,我会使用 docker,但我认为还有更多。

我开始深入 TensorFlow 服务。TensorFlow extended 和 Kubeflow (Kubernetes 使机器学习项目变得更容易)。沿着这条路线,我发现我需要了解更多(也许只是一点点)部署、编排和扩展机器学习应用程序所需的 Kubernetes。

旅程和好奇心导致了这篇文章。因此,如果你和我一样,准备升级你的游戏并添加一个工具成为独角兽数据科学家,正如 Elle O'Brien 在这篇文章中所描述的,那么这篇文章就是为你准备的。

“…太难了,这位罕见的数据科学家既能开发高质量的软件,又能扮演工程师的角色,被称为独角兽!”艾尔·奥布莱恩

在本文中,我们还将遵循一种基于项目的方法,这将使您有可能将所示的想法和代码直接移植到您的机器学习项目中。

总的来说,我们将看到如何消除在遵循常规方法时出现的一些困难,例如:

  • 无法将模型服务与应用程序分开
  • 回滚更新的困难
  • 轻松推出新更新的困难
  • 当用户流量增加时,应用程序难以扩展
  • 对模型和应用程序进行版本控制的困难。

为了消除上述困难,我们需要实现以下一些目标:

  • 在 web 应用中集成 TensorFlow 服务模型
  • 使用 docker-compose 管理 web 应用程序和 Tensorflow 服务
  • 构建 docker 映像并将其推送到 Docker-hub
  • 介绍 Kubernetes
  • 使用 Kubernetes 提供 Tensorflow web 应用程序。

先决条件

  • Tensorflow 中的训练模型
  • 码头工人,至少是基层
  • tensorflow 发球(如果不是,这里快速介绍一下 TensorFlow 发球

:您可以在这里获得商品的编码。

让我们开始吧。

构建 ML 模型

在本文中,我们将创建一个简单的 ML 模型,用于巩固将要介绍的概念。

该模型是一个 AND 逻辑门模型,由于本文的主要重点既不是如何创建模型,也不是如何训练模型,因此这一部分将较少解释。

让我们创建一个名为model.py的文件,并输入下面的代码:

Import TensorFlow as tf

data=tf.constant([[1,1],[0,0],[2,0],[2,1],[3,0],[0,4],[5,6],[0,10]])
label = tf.constant([1,0,0,1,0,0,1,0])

model = tf.keras.Sequential(
    [
        tf.keras.Input(shape=(2,)),
        tf.keras.layers.Dense(20,activation="relu"),
        tf.keras.layers.Dense(2,activation="softmax")
    ]
)

print(model.summary())

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(),
              metrics=['accuracy'])

model.fit(data,label,batch_size=2, epochs=5)

在创建和训练模型后,需要以一种可以使用 TensorFlow 服务的方式保存模型,因此我们不会只保存模型权重。

Import time

Save_time = int(time.time()) 
Path  = f’./saved_models/{saved_time}’ 
model.save(path, save_format=’tf’)

在上面的代码中,我们注入了使用时间模块进行版本控制的思想。获取保存模型时的时间戳,用于在saved_models/中创建一个内部文件夹,然后将模型保存到该文件夹中。

创建一些 Tensorflow 服务所需的文件。

现在我们的模型已经准备好,可以服务了。

码头工人必备

在本节中,我们将讨论将我们的机器学习项目投入生产所需的最基本的 docker API,并了解如何使用 docker-compose 编排我们的应用程序。

将 web 应用与 Tensorflow 服务图像相结合

本节展示了如何将 tensorflow 服务注入 flask web 应用程序。它展示了如何在 flask 中调用 tensorflow 服务端点 API。

首先,让我们服务于我们的 AND 逻辑门模型,使用 Tensorflow 服务于 docker 映像。第一步是从 docker-hub 提取 tensorflow 服务图像。

注:Neptune . ai 上有一篇文章,详细解释了 Tensorflow 服务的

docker pull tensorflow/serving

现在让我们运行张量流/服务图像:

docker run -p 8501:8501 --mount type=bind,source=path/to/directory/saved_models,target=/saved_models/1602624873 -e MODEL_NAME=1602624873 -e MODEL_BASE_PATH=/saved_models -t tensorflow/serving

上面的命令启动 tensorflow/serving 映像,首先使用以下命令将模型从我们的本地目录挂载到 Docker 容器中的文件路径:

---mount type=bind,source=path/to/directory/saved_models,target=/saved_models/1602624873

因此,为 AND 逻辑门模型创建saved_modelssource路径被绑定到 docker 容器中同名的target路径。

运行映像时,会创建两个端点,如下图所示。其中一个端点是为 GRPC 创建的,但是我们将关注第二个端点,即 REST API 端点。

为了访问 docker 环境外部的 REST API 端点,我们通过在上面的命令中使用-p 8501:8501来公开端口。

让我们测试一下端点,看看它是如何工作的。我们将首先使用 POSTMAN 来测试 REST API。

输入被传递给模型,通过 rest API 提供服务。在 POSTMAN 中,我们使用这种格式“{"instances": [[1,0]]}”指定 JSON 输入,并获得 JSON 格式的响应,这是模型输出。

这表明我们的服务模型工作正常。现在是将 Tensorflow 服务 API 端点与我们的 web 应用程序集成的时候了。

但是在我们开始之前,不要忘记镜像仍在运行,以防我们想要停止镜像运行,下面是执行此操作的代码:

docker ps

上面的命令列出了正在运行的图像。

terminal

复制要停止的图像的容器 id:

docker stop e74fe1336768

该命令停止运行张量流/服务图像。

现在让我们创建 Web 界面和服务器来呈现页面,因为我们的模型现在可以使用 tensorflow 服务。

模型 web 界面将是一个有两个输入和一个提交按钮的表单,如下图所示:

以下是位于index.html的 UI 代码:

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="../static/css/bootstrap-theme.min.css" />
        <link rel="stylesheet" type="text/css" href="../static/css/bootstrap.min.css" />
        <link rel="stylesheet" type="text/css" href="../static/css/responsive.bootstrap.min.css" />
        <link rel="stylesheet" type="text/css" href="../static/css/style.css" />
    </head>
    <body>
        <div class="container">
            {%include 'includes/_messages.html' %}
            <div class="row">
                <h1 class="text-center">AND GATE TEST</h1>
            </div>

                    <form action="{{url_for('home')}}" method="post">
                        <div class="form-row">
                            <div class="col">
                              <input type="text" class="form-control" name="inp1" placeholder="input 1">
                            </div>
                            <div class="col">
                              <input type="text" class="form-control" name="inp2" placeholder="input 2">
                            </div>
                            <div class="col">
                                <button type="submit" class="btn btn-primary ml-4">Submit</button>
                            </div>

                          </div>
                    </form>
        </div>
    </body>
</html>

现在我们已经创建了用户界面,让我们创建 flask 应用程序来呈现用户界面,并处理对 TensorFlow 服务 API 的请求。

创建一个文件名 app.py,并输入下面的代码:

from flask import Flask, render_template, flash, request
import requests
from os import environ

app = Flask(__name__)

上面的代码导入了必要的模块,如 Flask、request 和 os 模块。此外,上面的代码初始化 flask 应用程序。

添加到 app.py 的下一行代码是管理和调用 TensorFlow 服务 API 的代码。

def tfserving_request(req_input, model_name): 
    url = f"http://localhost:8501/v1/models/{model_name}:predict" 
    input_request = {"instances": [req_input]} 
    response = requests.post(url=url, json=input_request) 
    return response

基于注释编号:

  • 1tfserving_request接受两个输入,一个名为re_input的请求输入和模型的名称

  • 2 定义 API 端点基础

  • 3 将输入结构化为 TensorFlow 服务 API 端点接受的格式

  • 4 通过传入请求输入向 API 端点发出请求

下一步是添加将用于在浏览器中呈现 Web 界面的路由:

@app.route("/home",methods=["GET","POST"]) #1
def home():

    if request.method == "POST": 

        inp1 = int(request.form["inp1"]) 
        inp2 = int(request.form["inp2"])

        response = tfserving_request([inp1,inp2], "1602624873") 

        resp = response.json() 
        flash(f"obtained {inp1} and {inp2} have a prediction of {resp['predictions']}", 'success') 

    return render_template("index.html") 

  • 1 我们定义了加载呈现 html has /home '的路由,我们还定义了路由接受的请求方法为 GET '和` POST '

  • 2 检查所做的请求是否是 POST 请求

  • 3 如果 post 请求,我们使用 request.form["inp1"]记住` inp1 '是输入名。

  • 4 调用“tfserving_request”函数,并将模型名称旁边的表单输入传递给该函数。

  • 5 从 TensorFlow 服务返回的响应被转换为 JSON

  • 6 使用包含概率得分的' resp['predictions']获得预测。“flash”功能用于将结果作为消息打印出来

  • 7 从index.html呈现用户界面

最后,让我们添加代码行来启动 flask 服务器:

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=int(environ.get('PORT', 8080)))

当我们运行脚本时,上面的代码使主机成为端口 8080 的服务器。

让我们使用以下代码运行 app.py:

python run app.py

这将像这样启动服务器:

现在服务器启动了,我们可以通过http://0 . 0 . 0 . 0:8080/home&nbsp查看 web app

如果我们访问该链接,我们将看到网络界面:

如果我们在渲染页面的文本框中键入输入内容并单击“提交”按钮,如果 TensorFlow 服务 docker 图像关闭,我们会得到一个错误页面。因此,我们需要启动张量流服务图像。

docker run -p 8501:8501 --mount type=bind,source=path/to/directory/saved_models,target=/saved_models/1602624873 -e MODEL_NAME=1602624873 -e MODEL_BASE_PATH=/saved_models -t tensorflow/serving

一旦我们运行了上面的命令,我们就可以返回到 web 界面并键入我们的输入。我们将在输入字段中输入“1”和“0 ”,然后按提交按钮,我们将得到如下响应,如下图所示:

响应显示在页面顶部,显示服务器收到的输入和预测输出。

既然这样做效果很好,让我们创建一个 docker 映像来管理 flask 应用程序。在包含 flask 应用程序的同一个目录中,我们创建一个 Docker 文件:

FROM python:3.8-slim //1

ENV PYTHONUNBUFFER ED True //2
ADD requirements.txt requirements.txt //3
RUN pip install -r requirements.txt //4
ENV APP_HOME /app //5
WORKDIR $APP_HOME //6

COPY . ./    //7 
CMD ["python","app.py"] //8 

基于注释编号的代码解释:

  1. 获取 3.8 版的轻量级 python 映像-slim
  2. 防止应用程序崩溃而不打印相关消息
  3. 将包含要安装的软件包列表的 requirements.txt 文件添加到同名的虚拟文件中
  4. 安装 requirements.txt 中的所有包
  5. 在 docker 中创建一个目录,并将其分配给环境变量
  6. 根据 5 中创建的目录指定工作目录
  7. 将 flask app 目录中的所有文件复制到工作目录中
  8. 创建映像后运行 flask 应用程序的命令

在我们运行 docker 文件之前,让我们创建requirements.txt,一个简单的方法是通过下面的命令:

Pip freeze > requirements.txt

这将创建 requirements.txt 并在 python 环境中的包安装中添加必要包的基础

但是对于这个项目,唯一需要的包是Flaskrequests包。

创建 requirements.txt 后,让我们为 flask 应用程序创建一个图像:

docker build -t flaskweb .

如果我们运行上面的代码,在成功创建图像的情况下,我们应该会获得下面的输出。

既然映像已成功创建,让我们运行映像:

docker run -p 8080:8080 -e PORT=8080  -t flaskweb

这将启动 flask 服务器,如前所述。

让我们访问前面提到的相同链接,以便查看 web 界面。键入之前的输入,让我们看看输出的是什么:

正在输出一个错误,该错误是由于flaskweb可以与外部主机通信。因此,为了解决这个问题,我们想到了 Docker-compose。

使用 Docker compose 管理服务

Docker-compose 使我们有机会用一个文件和命令创建两个 Docker 服务(TensorFlow serving 和 flaskweb ),并使我们能够管理这两个服务。

注意:要在不同的操作系统上安装 docker-compose,请访问此链接

为了启用 docker-compose,让我们将为我们的模型创建的flask app 目录和saved_models文件夹放在同一个目录中。然后在 flask app 目录下创建一个名为Dockerfile.dev的文件,然后将Dockerfile中的所有内容复制到Dockerfile.dev中。

复制后,Dockerfile.dev'将看起来像这样:

FROM python:3.8-slim

ENV PYTHONUNBUFFERED True
ADD requirements.txt requirements.txt RUN pip install -r requirements.txt ENV APP_HOME /app
WORKDIR $APP_HOME COPY . ./ 
CMD ["python","app.py"] 

确保目录的文件系统如下所示:

/主目录
-/flask _ app
-/saved _ models

创建完成后,让我们创建一个名为docker-compose.yml的 YAML 文件来定义 TensorFlow 服务和 flask web 服务。

version: "3.8"
services:
 server:
 image: tensorflow/serving
 volumes:
 - ./saved_models:/saved_models/1602624873
 ports:
 - '8501:8501'
 environment:
 MODEL_NAME: 1602624873
 MODEL_BASE_PATH: /saved_models/

 web:
 image: flaskweb
 build:
 context: ./flask_app
 dockerfile: Dockerfile.dev
 ports:
 - '8080:8080'

docker-compose.yml中,我们使用version指定 docker-compose 版本,我们还定义了service对象中的服务类型。我们将这两个服务命名为serverweb

server服务对象中,我们指定要从中提取的图像。然后,我们通过将模型从./saved_models复制到 Docker 容器中名为/saved_models/1602624873的目录中来定义volumes。然后,我们为服务指定端口,就像我们在启动普通 docker 映像时所做的那样。同样,所需的环境变量在environment对象中指定。

如您所见,相同的过程类似于我们在前面部分中描述的运行 docker 映像的方式。

同样对于web服务对象,我们指定图像的名称。然后我们创建一个build对象,我们定义如何构建图像。我们通过指向flask_app目录来定义上下文。

我们告诉 docker-compose 使用名为Dockerfile.dev的目录中的dockerfile。我们定义端口。

为了启动服务,我们在包含docker-compose.yml的目录中运行以下命令。

docker-compose up

这将启动两个服务,如下所示:

docker

TensorFlow 服务和 flaskweb 服务正在运行,如果我们访问 URL http:localhost:8080/home,它将加载 web 界面,但是如果我们键入我们的输入并单击 submit,我们仍然会获得相同的错误。

为了解决这个错误,我们没有在 app.py 的tfserving_request函数中使用 TensorFlow 服务 API 端点 define 中的localhost,而是用名为server的 TensorFlow 服务的名称来替换它:


def tfserving_request(req_input, model_name):
    url = f"http://server:8501/v1/models/{model_name}:predict"
    input_request = {"instances": [req_input]}
    response = requests.post(url=url, json=input_request)
    return response

要查看更改,我们需要使用以下命令停止服务运行:

docker-compose stop

一旦两项服务都停止,我们将再次启动它:

docker -compose up

完成后,我们可以进入 web 界面,键入输入内容,然后单击“提交”。应用程序运行良好。

要了解更多关于 docker-compose 的信息,请访问此链接

构建 docker 映像并将其推送到 docker hub

为了将我们的 docker 图像与 Kubernetes 集成(这将在下一节讨论),我们需要将我们的图像推送到 docker hub。

要构建我们的图像并将其推送到 docker-hub,首先,访问 docker-hub ,然后创建一个帐户。创建帐户后。我们需要从系统终端登录 docker hub。

出于安全目的,将您的 docker 密码存储在一个文本文件中,给它取任意名称,我将自己的命名为“my_password.txt ”,然后运行下面的命令:

$ cat ~/my_password.txt | docker login --username steveoni --password-stdin

在上面的命令中,我使用 ~/是因为my_password.txt,因此 docker 登录从。使用标准输入。

如果登录成功,您将看到一条消息,显示登录成功。

让我们为 flask 应用程序创建一个图像,然后推送到 docker hub:

$ docker build -t steveoni/tfweb:1.0

这将创建一个图像,包含标签 1.1,它也是图像的版本。名称“steveoni/tfweb”指定您的“用户名/图像名称”。

映像准备就绪后,我们现在可以推送至 Docker hub:

$ docker push steveoni/tfweb:1.0

这将图像推送到 docker hub,如下所示:

我们已经完成了 flask 应用程序部分,现在让我们做 tensorflow 服务部分。请记住,我们没有为 tensorflow 服务创建 docker 文件,但我们使用了 tensor flow/服务图像。

我们需要建立在 tensor flow/服务形象之上。让我们在/saved_models所在的目录中创建一个 docker 文件。

From tensorflow/serving

ENV APP_HOME /saved_models/1602624873
WORKDIR $APP_HOME
COPY ./saved_models ./ 

上面的 docker 文件中使用的方法与创建以前的 docker 映像时使用的方法相同。

在构建和推送 docker hub 之前,让我们为本地测试构建映像。

$ docker build -t tfs .

让我们测试一下图像是否工作正常:

$docker run -p 8501:8501 -e MODEL_NAME=1602624873 -e MODEL_BASE_PATH=/saved_models -t tfs

这将启动 tensorflow 服务服务器。

现在,我们可以正式创建映像,然后推送:

$ docker build -t steveoni/tfupdate:1.1
$ docker push steveoni/tfupdate:1.1

下图显示了在没有检查 docker-hub 的情况下成功推送的情况:

什么是 Kubernetes 简介

为什么是 Kubernetes?假设您已经将 docker 应用程序部署到云服务,一切都很好,运行正常。但是过了一段时间,您的应用程序现在每秒钟有数千个用户发出请求。

不幸的是,由于每秒发出请求的用户数量,你的应用程序不断崩溃,你无法避免崩溃,用户不断抱怨。

为了解决这个问题,你可以制作应用程序的多个副本,并使其始终可用(如果一个出现故障,另一个可以出现)。另一个要问的问题是,如果所有副本都宕机了,您如何缩减规模?如何设置网络端点?谁来检查每次的状态?您如何以一种相互通信的方式管理副本?

由于上述问题,需要 Kubernetes 来解决上述情况。

“这是一个容器编排平台,由几个组件组成,它不知疲倦地工作,以保持您的服务器处于您想要的状态。”法尔汉·哈辛·乔杜里。

非立方簇

对于本文,我们将在本地机器上运行 kubernetes,而不是云服务。为了让 kubernetes 在我们的系统上运行,我们需要安装两套程序

首先,我们需要安装 Minikube 这允许我们在本地计算机上运行单节点 Kubernetes 集群。然后我们安装 Kubernetes 命令行工具 Kubectl。

要安装这两个程序,请访问下面的链接:

注意:在本文中,我将总结一些与本文中使用的项目相关的想法。要了解 Kubernetes 的概况和实际知识,请访问 Farhan Hasin Chowdhury 的这篇文章。我将用他的一些插图来介绍 kubernetes。

安装完成后,您可以使用下面的命令测试程序:

$ minikube version
$ kubectl version

在我们开始使用 minikube 之前,让我们为它设置一个 hypervisor 驱动程序。在本文中,我们将使用 Docker 作为虚拟机管理程序驱动器。

注意: Hypervisor 作为一个抽象层,将虚拟机与系统硬件分离开来。

以下命令有助于为 minikube 设置虚拟机管理程序:

$ minikube config set driver docker

完成后,我们可以开始 minikube:

$ minikube start

在终端中,运行上面的命令后,我们将看到下面的输入。尽管有时完成整个加载过程可能需要一些时间。

minikube

在我们开始使用我们刚刚开始的 minikube 程序之前,让我们对 Kubernetes 的一些术语和概念有一个总体的了解。

Kubernetes 包含我们所说的节点。节点可以是分配特定任务虚拟机或物理机。一组通过共享网络相互通信的机器称为集群。

因为在这个项目中我们使用了 Minikube。我们只能访问一台虚拟机作为我们的服务器。因此,我们称之为单节点 Kubernetes 集群。

你可以把它想象成,你不需要访问多台可以用作服务器的计算机,你只需要访问一台,也就是你的个人计算机,它可以作为服务器来承载你的应用程序。

下图显示了 minikube 的概况。

通常,库贝内石含有两种成分;

  • 控制平面组件
  • 节点平面组件

控制平面组件负责根据可用资源向节点分配和调度任务。它们还负责保存节点的状态,并验证对节点的请求。请记住,节点是一个虚拟机。

节点平面组件负责维护每个节点服务器上的网络规则。它们还负责维护,并在控制面板和群集中的每个节点之间提供网关。

根据 Kubernetes 文档,每个节点包含我们称之为的 pod

“Pod 是您可以在 Kubernetes 中创建和管理的最小可部署计算单元”。

该图显示了一个集群的概况。上面的集群是一个单节点集群,因为我们使用的是 minikube。

一个 pod 容纳了我们的应用程序容器。即使一个 pod 可以包含多个容器,也建议为其分配一个 Pod。使用更高的对象来管理 Pod 也是明智的。这个更高的对象有能力在任何时候创建和删除 pod,因此它们帮助管理 pod。我们将在本节稍后讨论这些更高级的对象。

一个节点可以包含多个单元,每个单元执行相同的功能。在我们称之为服务的帮助下,我们可以将所有这些 pod 合并到一个节点中作为一个实体。服务使我们能够定义如何访问 pod。

有了这些关于 Kubernetes 的小知识,我们继续手头的项目,并解释一些其他需要的概念。

使用 Kubernetes 提供 ML 驱动的 web 应用程序

本节展示了如何使用 kubernetes 来编排您的应用程序。它展示了创建 pod 和负载平衡器的不同方法。它还引入了“发展”和“集群”的概念

创建 pod 和负载平衡器的显式方法

首先,让我们使用我们在前面几节中创建的 tensorflow 服务图像来测试服务、pod 等概念。

记住我们已经开始了 minikube,现在让我们使用 tensorflow 服务图像创建我们的第一个 pod。

$ kubectl run tf-kube --image=steveoni/tfupdate:1.1 --port=8501 --env=”MODEL_NAME=1602624873”  --env="MODEL_BASE_PATH=/saved_models/"

上面的代码类似于上一节中运行 docker 映像时使用的相同命令。命令中的tf-kube是我们试图创建的 pod 的名称,使用--env定义环境变量。

然后,我们获得一条消息,表明 pod 已经创建。要查看已创建的 pod 列表,我们可以使用如下所示的get pods命令:

$ kubectl get pods

这是创建的窗格列表:

你可以看到我创建的 pod 列表,有些是三天前创建的。我忘记删除它们了。在 pod 列表中,我们可以看到我们刚刚创建的 pod,其状态为正在运行。

要删除任何 pod,我们只需运行以下命令:

$ kubectl delete pod-name

我们的tf-kube pod 正在运行,但我们无法从集群外部访问它。为了访问集群外部的 pod,让我们创建一个名为 LoadBalancer 的服务。该服务有助于将 pod 暴露在集群之外。

$ kubectl expose pod tf-kube --type=LoadBalancer --port=8501

上面的命令创建了名为 tf-kube 的负载平衡器服务:

一旦负载平衡器服务开始读取,我们就可以使用 minikube 启动“tf-kube”负载平衡器服务。

$ minikube service tf-kube

上面的命令启动了如上图所示的服务。它还将“目标端口”映射到图像中显示的“URL”。因此,我们将访问 URL“http://172 . 17 . 0 . 2:30116 ”,而不是访问“http://localhost:8501”来访问 TensorFlow 服务 API 端点。

让我们使用 Postman 测试 TensorFlow 服务 API 端点,如 Tensorflow 服务部分所示。

我们可以看到 API 端点工作正常。现在,我们已经能够创建我们的第一个 pod 和第一个服务。

要删除创建的服务:

$ kubectl delete service tf-kube

我们用来创建第一个 pod 和服务的方法并不是创建 pod 和服务的理想方式。

在下一小节中,我们将展示如何以一种更具可再现性和可管理性的方式创建 pod。

创建 pod 和负载平衡器的声明性方法

让我们采用一种更具声明性的方法,就像我们在 docker-compose 部分所做的那样。这种方法使我们更容易配置我们的 Kubernetes。也让其他人更容易设置。

首先,让我们创建一个名为“tf-kube-pod.yml”的 YAML 文件,并输入以下代码:

apiVersion: v1
kind: Pod
metadata:
 name: tf-kube-pod
 labels:
	component: server
spec:
 containers:
	- name: tf-kube
  	image: steveoni/tfupdate:1.1
  	ports:
    	- containerPort: 8501
  	env:
    	- name: MODEL_NAME
      	value: "1602624873"
    	- name: MODEL_BASE_PATH
      	value: /saved_models/

在 YAML 文件中,我们定义了以下内容

  • 定义了我们想要使用的 Kubernetes API 的版本
  • 指定我们想要创建的对象的kind,即 Pod
  • 我们定义了metadata,通过给component属性赋值server,我们给 pod 一个名称和一个label标签
  • 然后我们定义spec,它包含了我们想要的 pod 的状态。我们定义了要使用的容器映像,即steveoni/tfupdate:1.1,我们还定义了容器端口8501
  • 同样在spec.containers中,我们在env中指定环境变量,包含它们的namevalue

现在让我们使用“tf-kube-pod.yml”文件创建一个 pod:

$ kubectl apply -f tf-kube-pod.yml

这将创建 pod,您可以使用kubectl get pods查看 pod 的创建。

现在,让我们为刚刚创建的 pod 创建负载平衡器服务配置文件。创建一个名为“tf-kube-load-balancer.yml”的文件。

apiVersion: v1
kind: Service
metadata:
 name: tf-kube-load-balancer-service
spec:
 type: LoadBalancer
 ports:
	- port: 8501
  	targetPort: 8501
 selector:
	component: server

和前一个文件一样,这次我们将kind对象指定为service,并且在spec中我们将类型定义为LoadBalancer。在spec.ports中,我们定义了主机 pod 的端口和作为pod tf-kube-pod端口的targetport。在spec.selector中,我们将负载平衡器指向server组件,这是上面创建的tf-kube-pod pod 的标签。

然后,我们使用下面的命令从“tf-kube-load-balancer.yml”创建服务:

$ kubectl apply -f tf-kube-load-balancer.yml

我们还可以检查使用kubectl get services创建的服务列表。要启动服务运行,请执行以下操作:

$ minikube service tf-kube-load-balancer.yml

这将启动服务并打开 web 浏览器。

整个过程按预期进行。但是不要忘记,在本节开始描述 pod 时,我们提到了用更高的对象来管理 Pod 是很好的;它们具有创建和删除 Pod 的能力。我们将在下一节讨论这个问题。

使用多容器应用程序

我们已经能够为我们的 TensorFlow 服务创建一个 Pod,它只是一个容器。别忘了,我们的主要目标是将 TensorFlow 服务融入到 web 应用中。

正如我们在 docker-compose 部分看到的,我们能够创建一个程序来管理 Tensroflow 服务和 flask-web 应用程序服务。我们将在这一部分做同样的事情。

在本节中,我们将使用名为 Deployment 的更高级对象,还将向我们介绍 ClusterIP。

部署:部署是一个控制器,它让我们能够轻松地创建一个 Pod 的多个副本,也让我们能够轻松地推出和回滚更新。

“在 Kubernetes 中,控制器是监控集群状态的控制回路,然后根据需要做出或请求更改。每个控制器都试图将当前的群集状态移至更接近所需的状态。控制回路是调节系统状态的非终止回路。
–Kubernetes文档

ClusterIP: ClusterIP 是另一种类型的服务,就像负载平衡器一样。与 LoadBalancer 服务相反,clusterIP 只公开集群中的一个应用程序。也就是说,它防止应用程序被群集外的人访问。

在 Kubernetes 中部署我们的 Web 应用程序时,我们将使用刚刚定义的两个术语。

tf-kube

App architecture

上图展示了在 Kubernetes 中部署的应用架构。我们将创建 Flask Web 应用程序和 Tensorflow 服务的三个副本。

我们不想在集群之外公开我们的 Tensorflow 服务,正如我们在上一节创建 pod 时所做的那样,因此我们将为 Tensorflow 服务创建一个 ClusterIP。

为 Flask web 应用程序创建了一个负载平衡器,因为我们只想向用户公开应用程序。

为了实现这个架构,让我们为 Flask Web 应用程序创建一个部署配置文件和一个负载平衡器配置文件。在创建时,我们将使用部署到 docker hub 的 flask web 应用程序映像;` steveoni/tfweb:1.0 '

让我们创建一个名为“k8s”的文件夹,你可以给它取任何名字。在这个文件中,我们将创建所有需要的配置文件。

在文件夹中创建一个文件名“tf-web-dev.yml ”,在文件中输入以下文本:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: tfweb-dev
spec:
 replicas: 3
 selector:
 matchLabels:
 component: web
 template:
 metadata:
 labels:
 component: web
 spec:
 containers:
 - name: web
 image: steveoni/tfweb:1.0
 ports:
 - containerPort: 8080

像我们创建的所有其他 yml 文件一样;

  • 我们使用该文件作为“部署”对象来指定要创建的对象的“种类”。
  • 在“规范”中,我们将“副本”的数量指定为 3。
  • 在“spec.selector”中,我们使用“component”属性给对象一个标签“web”。
  • 我们还将图像定义为“steveoni/tfweb:1,0 ”,
  • 并且使用“容器端口”来指定要展示的端口

我们可以决定通过使用“kubectl apply -f tf-web-dev.yml”立即创建部署对象,但我们创建文件夹“k8s”或您称之为该文件夹的任何名称的主要原因是,能够使用一个命令立即创建应用部署所需的整个对象。

因此,让我们为上面定义的部署对象(我们的 flask web 应用程序)创建 LoadBalancer 服务。创建一个文件,并将其命名为“TF web-load-balancer-service . yml”。

apiVersion: v1
kind: Service
metadata:
 name: tfweb-load-balancer-service
spec:
 type: LoadBalancer
 ports:
 - port: 8080
 targetPort: 8080
 selector:
 component: web

负载平衡器与上一节中创建的负载平衡器相同,只是这一次它通过标记名“spec.selector.component:web”指向 flask web 应用程序。

现在 flask web 对象已经准备好了。然后,让我们创建 Tensorflow 服务服务器。创建一个名为“tf-kube-dev.yml”的文件:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: tf-kube-dev
spec:
 replicas: 3
 selector:
 matchLabels:
 component: server
 template:
 metadata:
 labels:
 component: server
 spec:
 containers:
 - name: server
 image: steveoni/tfupdate:1.1
 ports:
 - containerPort: 8501
 env:
 - name: MODEL_NAME
 value: "1602624873"
 - name: MODEL_BASE_PATH
 value: /saved_models/

上面的配置类似于为砂箱网创建的配置;但是标签被设置为“组件:服务器”

让我们为 Tensorflow 服务对象创建一个 CLusterIP 服务。创建一个文件,并将其命名为“tf-cluster-ip-service.yml ”:

apiVersion: v1
kind: Service
metadata:
 name: tf-cluster-ip-service
spec:
 type: ClusterIP
 ports:
 - port: 8501
 targetPort: 8501
 selector:
 component: server

上面的文件与为“LoadBalancer”服务创建的文件相同,只是“spec.type”被赋值为“ClusterIP”。

应用程序架构已经设置好,可以在 Kubernetes 上部署了。以下命令同时初始化 Flask web app 服务(web)和 Tensorflow 服务服务(server)的创建。

$ kubectl apply -f k8s

如果您位于包含“k8s”文件夹的目录中,上述命令将会起作用。但是,如果您的工作目录在“k8s”中,使用下面的命令:

$ kubectl apply -f .

这将基于“k8s”目录中的文件创建所需的服务,如下所示:

从图像中,我们可以看到对象和服务都已创建

让我们检查一下 pod 是否在运行:

$ kubectl get pods

请记住,我们为每个部署对象创建了 3 个副本,因此运行的 pod 总数应该是 6 个,从上图可以看出这是正确的。

要查看部署对象:

$ kubectl get deployments

部署对象已正确创建。

让我们检查为这两个对象创建的服务:

$ kubectl get services

“ClusterIP”的“tf-cluster-ip-service”和“LoadBalancer”的“tfweb-load-balancer-service”已正确创建。

现在我们已经设置好了一切,让我们启动“负载平衡器”服务:

$ minikube service tfweb-load-balancer-service

这将打开位于 URL 的 web 浏览器: http://172.17.0.2:32640/要查看应用程序,让我们转到呈现 web 界面的 route `/home'。

当输入值并提交表单时,服务器响应一个错误:

请记住,我们以前在尝试让 flask web 应用程序 docker 与 TensorFlow 服务 docker 通信时遇到过这种类型的错误。我们通过用“服务器”替换“本地主机”来解决这个问题,服务器是 docker-compose 创建的 TensorFlow 服务的名称。

为了解决这个问题,我们需要将“app.py”中“tfserving_request”中使用的“server”主机替换为托管 TensorFlow 服务的 CLusterIP 服务名称。因此,我们将 app.py 中的“服务器”替换为“tf-cluster-ip-service”

def tfserving_request(req_input, model_name):
ur="http://tf-cluster-ip-service:8501/v1/models/{}:predict".format(model_name)
input_request = {"instances": [req_input]}
response = requests.post(url=url, json=input_request)
return response

完成后,我们重建“tfweb”映像并将其推送到 docker-hub。现在新图像的版本为“1.2”。

$docker build -t steveoni/tfweb:1.2 .
$ docker push steveoni/tfweb:1.2

因此,我们需要将“tfweb-dev.yml”中的“图像”更改为“steveoni/tfweb:1.2”

让我们删除以前创建的部署对象和服务:

$ kubectl delete deployments --all
$ kubectl delete services --all

然后,我们再次创建新的部署对象和服务:

$ kubectl apply -f k8s

然后,我们启动 LoadBalacer 服务:

$ minikube service tfweb-load-balancer-service

网页会自动加载,让我们转到“/home”路线来测试 web 应用程序:

gate test

现在该应用程序工作正常。

如果将这种方法应用于任何其他项目,并且您的 pod 拒绝启动,您可以通过运行以下命令来查看 pod 的全部详细信息:

$ kubectl describe pods

这将给出所创建的整个 pod 的全部细节,但是要获取特定的 pod,请运行“kubectl get pods”。获取 pod 的名称,然后运行:

$ kubectl describe pod pod-name

要查看任何 pod 的日志,我们使用下面的命令:

$ kubectl logs pod-name

结论

在本文中,我们已经能够看到如何从构建机器学习应用程序的传统方法中迁移出来。我相信这篇文章已经向您展示了如何构建高效且可扩展的机器学习应用程序。

此外,您还增加了成为独角兽数据科学家的工具。好吧,还有一些其他的工具和概念需要学习,以便有效地构建和生产 ML 产品,例如:

CI/CD:如何将单元测试添加到您的模型中,并使用一次推送将您的应用程序推送到 github,通过一系列测试,然后推向生产

  • TFX/Kubeflow:定制工具,使您的应用程序的编排和使用 kubernetes 的部署更容易。
  • 参考

Reference

posted @ 2024-11-01 16:32  绝不原创的飞龙  阅读(76)  评论(0)    收藏  举报