TowardsDataScience 2023 博客中文翻译(三百二十四)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

世界地图的多种面貌——地图投影

原文:towardsdatascience.com/the-world-map-with-many-faces-map-projections-f58a210ff2f7

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 米兰·贾诺索夫

·发表于 面向数据科学 ·5 分钟阅读·2023 年 10 月 1 日

在这篇简短的文章中,我回顾了什么是地图投影,并展示了一系列使用 Python 和自然地球数据投影世界地图的例子。

地球大致上是一个球体,确实是一个三维物体(尽管也有一些挑战),而我们的印刷地图和数字屏幕则是二维的。将球体转换为二维地图的中间步骤,无论是制图册还是高级 GIS 应用程序,都称为地图投影。

将地球的椭球面映射到平面上有很多方法;然而,由于这些是近似模型,通常会有一些不足之处需要注意。在某些投影中,相对角度和多边形(例如国家)形状被保留;而在其他投影中,真实的面积或特定的欧几里得距离被保持不变。这些属性也有助于你选择适合你使用情况的最佳投影。

关于投影类型,有多种方式,例如圆柱投影、圆锥投影、方位投影和伪圆柱投影。相互之间转换的实际方法是改变坐标参考系统(CRS),这时 Python 和 PyProj 以及 GeoPandas 库非常有用!

根据 Mathematics.com,投影类型主要有六种类别:

  • 圆柱投影

  • 伪圆柱投影

  • 方位投影

  • 凸透镜投影

  • 杂项

在这里,我不会严格按照这样的分类,而是展示九种我认为有趣的地图投影。根据具体的投影,这些步骤通常会导致形状、面积、距离或方向的失真,因此在实际项目中应谨慎选择。为此,这个 投影系统集合 和下面提供的我的代码应该会有所帮助。那么,不再多说,地图如下:

1. 埃克特 II 投影

特征:埃克特 II 投影是一种等面积伪圆柱投影。它保持面积的准确性,但扭曲形状和距离。

常见用途:主要用于展示直线等面积网格的世界新奇地图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

埃克特 II 投影。图片由作者提供。

2. 等距圆柱投影

特征:等距圆柱投影是一种简单的圆柱投影。它保持纬度和经度为直线,但在远离赤道时会扭曲形状和面积。

常见 用途:通常用于教育或一般参考及主题世界地图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

等距圆柱投影。图片由作者提供。

3. 拉格朗日投影

特征:拉格朗日投影是圆锥形且符合变形的。失真发生在面积、形状和方向上。常见用途:根据 ChatGPT,它的稀有用例主要覆盖海洋学。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

拉格朗日投影。图片由作者提供。

4. 拉里维投影

特征:根据这个 来源,在地图中心不失真,而在大部分情况下会出现面积膨胀的失真

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

拉里维投影。图片由作者提供。

5. 莫尔维德投影

特征:莫尔维德投影是一种等面积伪圆柱投影。它保持面积但扭曲形状和角度。它具有独特的椭圆形状。

常见 用途:当面积准确性至关重要时用于全球地图,尤其是在地理学和地球物理学中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

莫尔维德投影。图片由作者提供。

6. 自然地球投影

特征:自然地球投影是一种为世界地图设计的伪圆柱投影。它在大小和形状失真上保持平衡(但不保持任何一方面),提供了一个视觉上令人愉悦的地图。

常见 用途:由于其平衡的失真特性,它在世界地图和地图集上非常受欢迎。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

自然地球投影。图片由作者提供。

7. 四次阿萨尔投影

特点:Quartic Authalic 投影是一种伪圆柱等面积投影,准确保持面积,但形状、角度和距离会失真。

常见用途:用于需要准确面积表示的特殊制图应用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Quartic Authalic 投影。图片由作者提供。

8. 矩形多锥投影

特点:矩形多锥投影是一种最小化经线失真的圆锥投影。有时称为战争办公室投影。

常见用途:主要用于美国军事目的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

矩形多锥投影。图片由作者提供。

9. 正弦投影

特点:伪圆柱等面积地图投影,将极点表示为点,保持面积,但形状会失真。

常见 用途:主要建议用于绘制接近赤道的区域。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后,作为可视化的数据源,我使用了来自 Natural Earth 的以下两个数据集:

现在,让我们看看代码:

import geopandas as gpd
import matplotlib.pyplot as plt
import pyproj
world = gpd.read_file('ne_10m_admin_0_countries')
ocean = gpd.read_file('ne_10m_ocean')
# visualize all projections at once
projection_dict = { 'Eckert II': '+proj=eck2 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
                    'Equirectangular': '+proj=eqc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +a=6378137 +b=6378137 +units=m +no_defs',
                    'Lagrange' : '+proj=lagrng',
                    'Larrivee' : '+proj=larr',
                    'Mollweide': '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
                    'Natural Earth': '+proj=eqearth +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
                    'Quartic Authalic': '+proj=qua_aut +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
                    'Rectangular Polyconic': '+proj=poly +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
                    'Sinusoidal' : '+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'
                  }

f, ax = plt.subplots(3,3,figsize=(15,15))
indicies = [(i, j) for i in range(3) for j in range(3)]

for idx, (projection_name, proj4_string) in enumerate(projection_dict.items()):

    bx = ax[indicies[idx]] 
    world_projected = world.to_crs(proj4_string)
    ocean_projected = ocean.to_crs(proj4_string)
    ocean_projected.plot(ax=bx, color = 'lightblue')
    world_projected.plot(ax=bx, cmap='Greens', edgecolor='k', linewidth = 0.25, alpha = 0.9)
    bx.set_title(f'{projection_name} Projection')
    bx.axis('off')  

plt.tight_layout()

SQL 查询优化的世界

原文:towardsdatascience.com/the-world-of-sql-query-optimization-e1d5b5fef20d

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由Jake Blucker拍摄,发布在Unsplash上。

数据工程

一窥不同的查询优化器及其工作原理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Kovid Rathee

·发布于Towards Data Science ·6 分钟阅读·2023 年 3 月 27 日

SQL 是一种简单的语言,规则非常少,这使得它如此受欢迎。它还具有大量的关键字和功能,让你以各种方式与数据进行交互。随着这种灵活性,查询编写风格和选择也会有很大的差异。

一旦你向数据库发出查询,它必须解析你的查询以理解其流程,但这并不是数据库工作的结束。数据库引擎还有一个组件用于查看你的查询,并在不改变其功能的情况下,进行重写,以实现更好的性能和响应时间。这个强大的组件,毫不意外,被称为查询优化器

但是优化器如何重写查询呢?它有哪些额外的信息来源来处理查询?这些问题的答案可以将不同类型的查询优化器进行分类。广义上说,以下提到的有四种查询优化技术

  • 基于启发式的优化根据数据库中预定义的规则进行操作,例如,优先使用聚集索引。

  • 基于成本的优化根据查询成本估算来工作,包括估算查询可能使用的资源成本。

  • 混合优化结合了基于启发式的方法和基于成本的方法。大多数关系数据库使用这种技术

  • 自适应优化与上述所有技术不同,它在查询执行过程中改变查询执行计划。这在分布式系统中非常有用。

在 2008 年计算机科学学位的第二年,当我在学习数据库管理系统时,尽管我对数据库有一定的兴趣,但直到后来我才真正意识到查询优化和数据库性能调优技术在我的工作中将会有多么重要。我可以证明,理解特定数据库的查询优化器是编写高效 SQL 查询的最有趣和最有用的技能。这会带来巨大的差别。

让我们更详细地了解一下不同类型的查询优化器。

基于启发式的优化

基于启发式的查询优化,也称为基于规则的查询优化,使用一组经验法则核心原则来确定执行查询的最有效方式,通过重新排列构成查询树的关系代数操作(查询的内部表示)。

我相信你一定听说过在 SQL 工程师中流行的讨论:我连接表的顺序是否重要? 这个问题的简短回答是既重要又不重要。重要,因为顺序确实很重要,但不重要,因为优化器在解析后会修正查询。

让我们以优化查询的最常见示例为例——使用WHERE子句。现在,经验法则是你应该尽早进行选择。这是因为如果你在处理过程中尽早过滤掉不需要的数据,你也会限制需要连接、排序和分组的数据量。

一些关于特定类型的连接、CTE、排序等的规则可以被称为启发式,因此得名启发式优化。优化 SQL 查询不仅仅涉及关系代数和启发式,还要考虑你使用的是哪个数据库以及你使用的是哪种 SQL 方言等因素。

请注意,这种查询优化方法纯粹是理论上的,并未考虑数据库统计信息中的大量实际世界信息,这也是为什么你不会看到数据库仅使用这种优化方法来优化你的 SQL 查询。它们还会考虑基于成本的查询优化,我们将在下一节中讨论这一点。

基于成本的优化

这种方法采取了更实际的优化方法。它考虑了内存、CPU、网络等的约束条件,以及数据库维护的数据统计信息,如行数、平均行大小、表大小等。

虽然基于启发式的优化会根据经验法则重新排序查询树,但基于成本的优化则涉及评估几个查询执行计划,并根据执行查询的估算成本选择其中最优的一个。这个成本包括估算的时间、扫描的行数、使用的索引数量等。

由于基于成本的优化需要评估多个查询执行计划,因此可能需要更多时间来制定正确的执行计划。优化器也可能因为收集和分析数据库统计数据的开销而变得缓慢。然而,它通常比基于启发式的优化更有效。

大多数数据库不仅仅使用基于成本的优化器。它们通常采用混合方法,大部分优化基于成本,其余部分基于启发式方法、用户提示等。Snowflake 的 Jiaqi Yan 在CMU DB 隔离技术讲座的一场会议中谈到了这一点。在下一部分中,我们将通过一些示例,看看混合查询优化是如何工作的。

混合查询优化方法考虑了基于启发式的优化和基于成本的优化,并制定了一个平衡的查询优化计划。我们不会深入探讨混合查询优化的具体细节,因为不同数据库之间的实现差异很大。

自适应查询优化

到目前为止,我们讨论了查询优化技术,这些技术仅在查询执行开始之前查看并改进查询执行计划。自适应查询优化是一种在查询执行过程中尝试改进计划的查询优化类型。这种用例可能对你来说很明显——分布式数据处理系统和处理大量数据以及高并发的查询引擎。

当你处理长时间运行的查询时,自适应查询优化的效果尤其显著,这些查询的处理任务被划分为多个作业分配给集群中的不同计算节点(无论技术是什么——Redshift、Snowflake、Databricks 等)。数据的显著偏斜、不良的分区以及文件格式等问题,可能会使查询变慢。

自适应查询优化在查询执行过程中会关注这些问题以及更多问题。它还会查看查询的预期表现以及实际表现,借助多种指标来进行评估。通过这样的系统,查询引擎可以在查询执行时调整单个查询计划工作流或整个查询计划。

越来越多的数据库,特别是那些具备分布式数据处理能力的数据库,将最终使用某种版本的自适应查询优化,因为它解决了许多耗时的性能优化问题,例如确保数据均匀分布、根据内存和计算资源的可用性确保最佳分区大小等。我强烈推荐查看我在参考资料中分享的 Databricks Data+AI 2020 会议的相关内容。它对自适应查询优化的内部实现提供了一些实际的见解。

结论

这篇文章探讨了在各种数据库、数据仓库和数据处理引擎中使用的不同类型的查询优化器。了解优化器的类型对于数据工程中的查询优化和性能调优至关重要。随着规模的扩大,调优变得越来越困难。通过深入了解优化器,你将能够理解它的工作原理,以及如何调整其输出以满足你的需求和要求。

想想其他类型的空间和时间优化在应用中的想法,例如垃圾回收、缓存等。理解查询优化器为数据工程师带来的好处,与理解上述概念给软件开发者带来的好处类似。

参考文献

  1. 优化技术,数据库设计 424,马里兰大学

  2. 查询优化,数据库 II,CP 465,威尔弗里德·劳里埃大学

  3. 关系查询优化,CS 3200,东北大学

  4. MySQL 8.0 参考手册 — 优化概述

  5. PostgreSQL 内部概述 — 规划器/优化器

  6. Databricks 自适应查询执行 — Data+AI 峰会 2020

如果你觉得这篇文章有用,请订阅并查看我在 🌲 Linktree 上的所有作品。你还可以考虑通过使用我的推荐链接 购买 Medium 会员 来支持我。谢谢!

世界上最小的数据管道框架

原文:towardsdatascience.com/the-worlds-smallest-data-pipeline-framework-408eaf1a4ce4?source=collection_archive---------0-----------------------#2023-11-16

一个简单快速的数据管道基础,具备复杂的功能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Douglas Blank, PhD

·

关注 发表在 Towards Data Science · 7 分钟阅读 · 2023 年 11 月 16 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:Ana Lucia CottoneUnsplash

数据整理可能是数据科学家花费时间最多的工作。数据整理包括清理、转换以及将原始数据处理成有用的信息。像许多活动一样,整理过程通常需要随着时间的推移进行改进。因此,跟踪数据集是如何整理的很重要,这样你的团队可以管理并重复这个过程。虽然数据整理并不总是有趣,但它可能是现代公司中最重要的活动。

有些公司专注于数据管道,这些管道可能很复杂且非常精密。但是为了这次探索,让我们考虑将一个文本文件转化为一组单词或“标记”,并丢弃那些对我们没有用的文本。让我们从简单开始,逐步深入。

首先,让我们定义一系列步骤,以对文本中的单词执行整理函数。我们将使用 Python 的 text.translate() 函数来完成一些工作。考虑这 4 个函数:

import string

def step1(word):
    trans = str.maketrans("", "", string.punctuation)
    return word.replace("\n", " ").translate(trans)

def step2(word):
    return word.lower()

def step3(word):
    trans = str.maketrans("", "", "0123456789")
    return word.replace("\n", " ").translate(trans)

def step4(word):
    return (all([char in string.ascii_letters for char in word]) and 
            len(word) > 0)

step1 是一个函数,用于删除单词中的所有标点符号和换行符。step2 将单词转换为小写。step3 再次使用 text.translate() 来删除数字。而 step4 将用作过滤器,过滤掉包含非 ASCII 字符的单词。你可以想象一些额外的步骤,例如词干提取。

由于这些是简单函数,如果我们对一个单词应用 step1,我们将得到:

>>> step1("Testing---123;")
'Testing123'

确实,它已经从文本中删除了标点符号。我们可以通过将所有三个函数像俄罗斯套娃一样包裹在单词周围来应用它们:

>>> step3(step2(step1("Testing---123;")))
'testing'

在这里我们看到函数 step1step2step3 已被应用,只剩下字母“testing”。注意,我们将定义我们的函数按特定的顺序进行工作。也就是说,step1 应该在 step2 之前完成,等等。

这个基于函数的过程简单易创建,也简单易用。当然,我们可以一次性完成所有的函数。但随着“管道”函数变得越来越长且复杂,将过程分解为离散的步骤会使过程更易于管理。实际上,每一步可能会变得如此复杂,以至于需要不同的团队来处理。

好的,到目前为止,一切顺利。但当然,我们不想手动将函数管道应用到每个单词上。我们想要将它应用到列表中的每个单词。为此,我们创建了一个非常简单的函数 apply()

def apply(step, values):
    return [step(value) for value in values]

现在我们可以在整个单词列表上使用相同的函数:

>>> apply(step3, 
          apply(step2, 
                apply(step1, 
                      ["Testing---123;", "456---", "Hello!"])))
['testing', '', 'hello']

啊,是的,我们需要去除空白单词。step4 正是为此设计的,但使用起来有些复杂。它的样子是这样的:

>>> list(filter(step4, 
            apply(step3, 
                  apply(step2, 
                        apply(step1, 
                              ["Testing---123;", "456---", "Hello!"])))))
['testing', 'hello']

也就是说,因为 step4 是一个过滤函数,返回 True 以保留单词,返回 False 以删除它,所以它的应用方式是:filter(step4, data)

这个简单方法有几个问题:

  1. 步骤是从内向外应用的。也就是说,第一个步骤 step1 是最内层的函数,而 step3 是最外层的。不是很直观。

  2. 这非常冗长,因为我们必须为每个步骤函数重复**apply()**函数。

  3. 过滤器(如step4)不能像其他函数一样使用。

考虑到这些问题,我们能否将主要功能抽象成一个通用的管道?我设想了一个两步法:

# First we create a pipeline function:
p = my_pipeline(step1, step2, step3)

# And then we apply it to a dataset:
p(["Testing---123;", "456---", "Hello!"])

我们如何定义my_pipeline?事实证明,它非常简单:

def my_pipeline(*steps):
    def wrapper(inputs):
        for step in steps:
            inputs = apply(step, inputs)
        return inputs
    return wrapper

也就是说,my_pipeline是一个函数,它接受一系列步骤函数,并返回一个函数,该函数接受一个单词列表,应用系列中的每个步骤,然后返回处理后的单词列表。

让我们试试:

>>> p = my_pipeline(step1, step2, step3)
>>> p(["Testing---123;", "456---", "Hello!"])
['testing', '', 'hello']

它有效——我们得到了之前得到的完全一样的结果!step4过滤器函数怎么样?让我们暂时放下这个问题,试试这个系统在“真实”数据上的表现。好吧,这将是真实的假数据。对于这些实验,我们将创建 10,000 个文档,每个文档包含 10 个段落。我们将使用 Python 包essential_generators中的DocumentGenerator()

from essential_generators import DocumentGenerator
import os

gen = DocumentGenerator()

def generate_documents(
    count=10_000, 
    paragraphs=10, 
    output_folder="documents", 
    overwrite=False
):
    os.makedirs(output_folder, exist_ok=True)
    for n in range(count):
        filename = os.path.join(
            output_folder, 
            "doc_%05d.txt" % (n + 1)
        )
        if overwrite or not os.path.exists(filename):
            with open(filename, "w") as fp:
                for p in range(paragraphs):
                    fp.write(gen.paragraph() + "\n\n")

generate_documents()

这将需要大约 30 秒来生成所有数据。要继续我们的简单代码,我们需要引入一个步骤:

def step0(filename):
    return open(filename).read().split(" ")

这一步将接收一个文件名,打开文件,并按空格分割文本。我们还需要对我们的**apply()**函数做一个小调整,以处理单词列表,而不是单词:

def apply(step, outputs):
    return (step(input) if not isinstance(input, list) else 
            [step(i) for i in input] for input in outputs)

我还对apply做了一个小调整:现在它通过使用括号而不是方括号来返回一个生成器表达式而不是列表推导式。这将延迟处理直到需要时(有时称为“延迟评估”)。

现在我们可以构建一个接近完整的管道系统:

p = my_pipeline(step0, step1, step2, step3)
list(p(["documents/doc_00001.txt"]))

请注意,它接受一个文件名列表作为输入。简单明了。但我仍然希望看到一些东西:

  1. 以简单的方式处理过滤器的能力

  2. 以并行运行管道快速处理数据集的能力

  3. 可视化管道的能力

对于这三个附加功能,我会推荐你参考我基于上述想法开发的picopipe项目。你可以通过 pip 安装它:

pip install picopipe

并使用上述相同的步骤函数运行它:

from picopipe import pipeline, pfilter

p = pipeline(step0, step1, step2, step3, pfilter(step4))
list(p(["documents/doc_00001.txt"])[0])

在这里,pfilter代表管道过滤器,你只需将其包裹在step4函数周围。我对这个设计相当满意。但让我们看看它运行得有多快。

首先,让我们获取所有的文档文件名。一种简单的方法是使用glob

import glob

dataset = glob.glob("documents/doc_*.txt")

现在我们可以处理所有文档了:

results = list(p(dataset))

在我的笔记本电脑上处理所有 10,000 个文档大约需要 21 秒。简短而甜美!我们能让它运行得更快吗?

是的!现在管道中还有一个n_jobs参数,指示你可以并行运行的作业数量。这里有一小段代码,将使用 0 到 9 个线程多次处理数据集。你认为使用 9 个线程并行运行会快多少?

import time

x = []
y = []
for i in range(10):
    start = time.time()
    results = list(p(dataset, n_jobs=i))
    total_time = time.time() - start
    x.append(i)
    y.append(total_time)

这将需要几分钟。绘制结果时间与线程数的关系图显示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

显示将处理拆分为多个并行作业的运行时间的绘图。作者提供的图片。

有趣的是:图表并不随着额外线程的增加而继续减少。也就是说,使用 9 个线程并不比使用 1 个线程快 9 倍。为什么呢?不幸的是,您不能违法。而且有一个法则:阿姆达尔定律。它基本上说,您永远不会因为存在无法减少的开销成本而使速度快 N 倍。在这种情况下,我可以使用 4 个线程将时间从约 21 秒减少到 8 秒。还不错!

最后,我想要可视化管道。在项目的这一部分,我选择尝试Mermaid 图表格式。它最近得到了很多支持,包括在 github 的仓库中。这种格式非常简单,易于创建。对于 github 的渲染,只需将文件命名为.mmd 扩展名即可。以下是使用picopipe生成 Mermaid 脚本的方法:

from picopipe import to_mermaid

with open("pipeline.mmd", "w") as fp:
    fp.write(to_mermaid(p))

并且在 github 的渲染中显示如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Github.com 直接支持 Mermaid 文档文件。作者提供的图片。

不幸的是,github 不显示鼠标悬停功能(在 CSS 中定义)。但是,如果您可以设置自己的 CSS,则可以实现不仅可视化管道,还可以在鼠标悬停在步骤框时显示步骤代码:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如 Comet 的自定义面板中所示的 Mermaid 图表。作者提供的图片。

上述的带有鼠标悬停支持的 Mermaid 图表是使用 Comet 的自定义面板系统创建的(所有用户免费)。创建显示 Mermaid 文件的自定义面板非常简单。以下是上述 Mermaid 图表的实时演示:comet.com/dsblank/picopipe/a4c044c1657b464087ec44f67ae22709

这完成了我们对开发“世界上最小数据管道框架”的探索,以及对其并行化和可视化的探索。您可以在此处找到所有的代码:github.com/dsblank/picopipe 我希望您觉得这里呈现的想法和最终模块有用。

对人工智能、机器学习或数据科学感兴趣吗?考虑鼓掌和关注。Doug 是 comet.com 的研究主管。

线性回归的理论深度解析

原文:towardsdatascience.com/theoretical-deep-dive-into-linear-regression-e53c579aef5b

可解释的人工智能

了解线性回归的本质及其如何以自然的方式扩展

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Dr. Robert Kübler

·发布于 Towards Data Science ·10 分钟阅读·2023 年 6 月 23 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Erik van Dijk 提供,来源于 Unsplash

大多数有抱负的数据科学博客作者都会这样做:撰写一篇关于线性回归的介绍性文章——这是一个自然的选择,因为这是我们进入这个领域时学习的第一个模型之一。虽然这些文章对初学者非常有用,但大多数都未能深入挖掘以满足高级数据科学家。

所以,让我带你了解一些鲜为人知但令人耳目一新的线性回归细节,这将使你成为更好的数据科学家(并在面试中获得加分)。

这篇文章内容相当数学化,因此为了跟上内容,具备一些概率和微积分的坚实基础会很有帮助。

数据生成过程

我非常喜欢在建模时考虑数据生成过程。处理过贝叶斯建模的人会明白我的意思,但对于其他人:想象一下你有一个数据集 (X, y),由样本 (x, y) 组成。给定 x,如何得到目标 y

假设我们有 n 个数据点,每个 x k 个组件/特征

对于一个线性模型,参数为 w₁, …, wₖ(系数)b(截距)σ(噪声)**,假设数据生成过程如下:

  1. 计算 µ = wx₁ + wx₂ + … + wₖxₖ + b

  2. 随机生成一个 y ~ N(µ, σ²)。这与其他随机生成的数字独立。或者: 生成 ε ~ N(0, σ²*) 并输出 y = µ + ε

就是这样。这两行简单的文字等同于人们喜欢详细解释的最重要的线性回归假设,即线性、同方差性和误差独立性

从过程的第 1 步开始,你也可以看到我们用典型的线性方程 wx₁ + wx₂ + … + wₖx + b 来建模期望 µ,而不是实际目标。我们知道无论如何不会击中目标,因此我们接受生成 y 的分布的均值。

扩展

广义线性模型。我们不必使用正态分布作为生成过程。如果我们处理的数据集仅包含正目标,那么假设使用泊松****分布 Poi(µ) 可能更有利,这样你就得到了泊松回归

如果我们的数据集只有目标 0 和 1,使用伯努利分布 Ber(p),其中 p = sigmoid(µ),那就是逻辑回归

只有 0, 1, …, n 之间的数字?使用二项分布来获取二项回归

列表还在继续。长话短说:

思考一下哪个分布可能生成你在数据中观察到的标签。

我们到底在最小化什么?

好的,我们现在决定了一个模型。那么我们怎么训练它?我们怎么学习参数?当然,你知道:我们最小化了(均方)误差。但为什么?

关键在于,你只需使用我们之前描述的生成过程进行最大似然估计。我们观察到的标签是 y₁, y₂, …, yₙ*,它们都是通过具有均值 µ₁, µ₂, …, µₙ 的正态分布独立生成的。看到这些 y 的可能性是多少?这是:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

我们现在想找到(隐藏在 µᵢ 中的)参数,以最大化这一项。这等同于最小化均方误差,如你所见。

扩展

不等方差。实际上,σ 不必是恒定的。你可以为数据集中每个观察值设置不同的 σᵢ。然后,你将最小化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

代替,这就是带有样本权重 s 的最小二乘法。建模库通常允许你设置这些权重。在 scikit-learn 中,例如,你可以在 fit 函数中设置 sample_weight 关键字。

这样,你可以通过增加相应的 s 来更强调某些观察值。这等同于减小方差 σ²,即你更确信这个观察值的误差较小。这种方法也称为加权最小二乘法

输入的方差依赖性。 你甚至可以说方差也依赖于输入 x。在这种情况下,你会得到一个有趣的损失函数,这也被称为方差衰减

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

整个推导过程在这里概述:

## 免费获取回归神经网络中的不确定性估计

给定合适的损失函数,标准神经网络也可以输出不确定性

towardsdatascience.com

正则化。 除了仅仅最大化观察到的标签 y₁, y₂, …, yₙ 的似然,你还可以采用贝叶斯观点最大化后验似然

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图像。

在这里,p(y | w) 是上述的似然函数。我们必须决定一个 p(w) 的概率密度,即所谓的先验或先验分布。如果我们说参数独立地服从围绕 0 的正态分布,即 wᵢ ~ N(0, ν²),那么我们最终会得到L2 正则化,即岭回归。对于拉普拉斯分布,我们得到L1 正则化,即 LASSO

为什么呢?让我们以正态分布为例。我们有

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图像。

因此,加上我们上述 p(y | w) 的公式,我们必须最大化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图像。

这意味着我们必须最小化均方误差加上一些正则化超参数乘以 w 的 L2 范数

注意,我们从贝叶斯公式中省略了分母 p(y),因为它不依赖于 w,所以我们可以忽略它进行优化。

你可以使用任何其他的先验分布来创建更有趣的正则化。你甚至可以说你的参数 w 是正态分布的,但与某个相关矩阵 Σ* 相关。*

假设 Σ 是 正定的*,即我们处于非退化情况。否则,没有密度 p(w)。*

如果你进行数学计算,你会发现我们然后必须优化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图像。

对于某个矩阵 Γ。注意:Γ 是可逆的,我们有 Σ⁻¹ = ΓᵀΓ。 这也被称为提霍诺夫正则化

提示: 从以下事实开始

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图像。

并且记住,正定矩阵可以被分解成某个可逆矩阵及其转置的乘积

最小化损失函数

很好,我们定义了我们的模型并知道我们想优化什么。但是我们如何优化它,即学习最优的参数以最小化损失函数?什么时候会有唯一解?让我们来看看。

普通最小二乘法

假设我们不进行正则化,也不使用样本权重。那么,均方误差可以写作

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像由作者提供。

这非常抽象,所以让我们以不同的方式书写

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像由作者提供。

使用 矩阵微积分,你可以对这个函数关于 w 求导(我们假设偏置项 b 已经包含在内)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像由作者提供。

如果你将这个梯度设为零,你会得到

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像由作者提供。

如果 (n × k) 矩阵 X 的秩为 k,那么 (k × k) 矩阵 XX 也是,即它是可逆的。为什么?这可以从 rank(X) = rank(XX) 中推导出来。

在这种情况下,我们得到唯一解

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像由作者提供。

注意: 软件包不像这样优化,而是使用梯度下降或其他迭代技术,因为这样更快。不过,公式很好,并且为我们提供了有关问题的一些高级见解。

但这真的能达到最小值吗?我们可以通过计算 Hessian 矩阵来找出,Hessian 矩阵是 XX。该矩阵是半正定的,因为 wXXw = |Xw|² ≥ 0 对于任何 w。它甚至是严格正定的,因为 XX 是可逆的,即 0 不是特征值,所以我们的最优 w 确实在最小化我们的问题。

完美的多重共线性

这只是友好的情况。但如果 X 的秩小于 k 会发生什么?如果我们数据集中有两个特征,其中一个是另一个的倍数,例如,我们在数据集中使用 height (in m)height (in cm) 作为特征。然后我们有 height (in cm) = 100 * height (in m)

如果我们对分类数据进行独热编码而不丢弃其中一列,也可能发生这种情况。例如,如果我们数据集中有一个特征 color,它可以是红色、绿色或蓝色,那么我们可以进行独热编码,得到三列 color_red, color_green,color_blue。对于这些特征,我们有 color_red + color_green + color_blue = 1,这也会引起完美的多重共线性。

在这些情况下,XX 的秩也小于 k,因此这个矩阵是不可逆的。

故事结束。

还是不行?实际上不是,因为这可能意味着两件事:(XX)w = Xy

  1. 没有解或

  2. 无限多的解。

事实证明,在我们的案例中,我们可以使用 Moore-Penrose 伪逆 获得一个解。这意味着我们处于无穷多解的情况,这些解都给我们相同的(训练)均方误差损失。

如果我们用 A⁺ 表示 A 的 Moore-Penrose 伪逆,我们可以求解线性方程组为

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

要获得其他无穷多解,只需将 XX 的零空间添加到这个特定解中。

使用 Tikhonov 正则化的最小化

记住,我们可以向权重中添加先验分布。然后我们需要最小化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

对于某个可逆矩阵 Γ。按照普通最小二乘法中的相同步骤,即对 w 求导并将结果设置为零,解为

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

精彩的部分:

XᵀX + ΓᵀΓ 始终是可逆的!

让我们找出原因。只需证明 XX + ΓᵀΓ 的零空间仅为 {0}。因此,我们取一个 w 使得 (XX + ΓᵀΓ)w = 0。现在,我们的目标是证明 w = 0。

从 (XX + ΓᵀΓ)w = 0 可得

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

这也意味着 |Γw| = 0 → Γ*w = 0。由于 Γ 是可逆的,w 必须是 0。通过相同的计算,我们可以看到 Hessian 矩阵也是正定的。

很好,因此 Tikhonov 正则化自动帮助使解唯一!由于岭回归是 Tikhonov 回归的特例(对于 Γ = λIₖ,其中 Iₖk 维单位矩阵),因此同样适用。

添加样本权重

最后,让我们还将样本权重添加到 Tikhonov 正则化中。添加样本权重等同于最小化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

对于某些对角矩阵 S 其对角元素 sᵢ 为正,最小化问题和普通最小二乘法一样简单。结果是

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

注意: Hessian 矩阵也是正定的。

你的作业

假设对于 Tikhonov 正则化,我们不强制权重围绕 0,而是围绕某个点 w₀。证明优化问题变为

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

结果是

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

这是 Tikhonov 正则化的最一般形式。有些人更喜欢定义 P := S²,Q := ΓᵀΓ,如 这里所示

结论

在这篇文章中,我带你探讨了线性回归的几个高级方面。通过采用生成视角,我们可以看到广义线性模型与普通线性模型的区别仅在于用于抽样目标y的分布类型。

然后我们看到,最小化均方误差等同于最大化观测值的似然。如果我们对可学习参数施加一个先验正态分布,我们最终会得到 Tikhonov(以及 L2 作为特例)正则化。我们也可以使用不同的先验分布,如拉普拉斯分布,但那样就没有封闭的解公式了。不过,凸优化方法也可以帮助你找到最佳参数。

作为最后一步,我们为每个最小化问题找到了很多直接的解公式。这些公式在大数据集的实际应用中通常不会使用,但我们可以看到这些解总是唯一的。我们在过程中也学会了一些微积分。😉

我希望你今天学到了一些新的、有趣的和有价值的东西。感谢阅读!

如果你有任何问题,请在 LinkedIn上联系我!

如果你想更深入地了解算法的世界,可以试试我的新出版物所有关于算法!我仍在寻找作者!

## 所有关于算法

从直观的解释到深入的分析,算法通过示例、代码和精彩的内容得以呈现…

medium.com

没有所谓的自学程序员。

原文:towardsdatascience.com/theres-no-such-thing-as-a-self-taught-programmer-4062c309aef0

改变职业道路永远不嫌晚,但一定要做到正确。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Gabriel Sena

·发布于 Towards Data Science ·阅读时间 8 分钟·2023 年 8 月 10 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Patrick Fore 提供,来源于 Unsplash

如果你正在寻求改变方向并进入软件行业,希望这篇文章能为你提供一些经历过类似过程的人的见解。

每个人的旅程都不相同,但我将重点讲述我的经历——从没有计算机科学背景到在这个领域拥有丰富经验。我曾有机会担任关键角色,如高级软件工程师/数据工程师、软件架构师、专家等。

在我的青少年时期,我总是喜欢摆弄电脑和机械。不管是旧的 Windows 计算机还是拆解我车子的发动机零件。我对事物的构造充满了好奇。尽管有这些兴趣,我的本科阶段却充满了从建筑学到美术的过渡目标。直到 2000 年代末期,当我正在攻读美术学士学位时,我上的第一门“互动设计”课程让我几乎瞬间意识到,我想进入软件行业。某种东西点击了,我准备从极其主观的艺术和设计领域转向更加具体、更具二元性的领域。

在做出决定后,即使在本科阶段,我也养成了阅读任何我感兴趣的编程语言或概念的习惯——图书馆里有很多选择,我从 WordPress 书籍到 C++等各种书籍中随意挑选。

但等等,这难道不是自学的吗……

并不完全是这样(稍后会详细说明),我把这称为对该领域的探索。这一点非常重要,因为在没有理解的情况下进行如此剧烈的职业变化可能会很冒险,可能会导致你后悔你的决定。我的好奇心帮助我真正决定了这是否是我想要的道路。因此,在迈出那些初步步骤后,我全身心投入到改变中。哦,天哪,我没想到会面临这么多的努力、压力和困惑——但这正是我内心所热爱的。

“做伟大工作的唯一方法是热爱你所做的事”

— 史蒂夫·乔布斯

回首往事,由于渴望获得实际经验,我在大学毕业后急于开始工作。虽然当时我对计算机科学的理解还很初步,但我还是在 2010 年代初找到了第一份软件工作。我感激不已,并期待着面临的挑战。

现在回到那个自学的事上。我发现这个词在计算机科学(以及可能在大多数领域)中完全具有误导性。事实是,即使你没有接受过正式教育,你也依赖于各种资源、学习,最重要的是,来自更有经验的开发者的指导或辅导——在某种程度上,这是一种正式的专业教育👨🏽‍🎓。

自学和研究是这个行业的基础部分;对于那些接受过正式教育的工程师来说,这也是一个持续的追求。

软件行业不断变化,因此对现有和新系统知识库的维护也是如此。

我不会在这篇文章中深入讨论我对程序员软件工程师的看法,因为我可能已经在自学程序员社区引起了一些波澜😶。但我会说,理论知识是重要的。

那里

​ ​ ​​ ​ ​ ​​​ ​ ​​​ ​有

​ ​ ​​​ ​ ​​​ ​ ​​​​ ​ ​​ ​ ​​​ ​​级别

​ ​ ​​​ ​ ​​​ ​ ​​​ ​ ​​​ ​ ​​​ ​ ​​​ ​ ​​​ ​​​ ​ ​​​ ​​​​到这一点

​ ​ ​​​ ​​ ​​​ ​ ​​ ​ ​​​ ​ ​​ ​ ​​​ ​ ​ ​​​ ​ ​​​ ​ ​​​ ​ ​​​ ​​​ ​ ​​​ ​​游戏。

这是我希望在职业生涯早期就知道的 4 个建议。

#1 别慌。

我在 2010 年代初期的第一次“恐慌”之一是处理 Javascript/PHP——API Posts、回调、JQuery,所有那些好东西。我完全是新手,根本不知道自己在做什么。我会说,无法理解的压力和焦虑真是糟糕透了。

我发现许多入门级程序员犯的一个错误是尝试所有的按钮。也就是说,盲目地调整方法或一系列代码输入,试图强行让系统运行。我多次陷入这个陷阱。这是因为一旦你按对了所有按钮,让该死的东西运行起来,就几乎像是一种欣快体验。然而——不要这样做。你不会走得很远,即使你成功了,你也会尝试了很多不同的选项,实际上并不知道它为什么会成功。

相反,退后一步。去散步,调整一下自己。当你回来时,尝试更深入地理解你所挣扎的内容——如果你在处理一个 API,请再次阅读文档;如果你在处理一个编程概念,寻找可以帮助你从不同角度理解的在线资源。咳咳 ChatGPT 🤖(希望我早期能有这个工具)。

关于这个领域的事,你是长期投入的。这是一场永无止境的马拉松。你永远不会到达学习的终点。一切都在于旅程,所以慢慢来,逐步理解每一部分。

#2 失败是可以的。

从小打足球、篮球和网球,我一直是竞争激烈的。失败或在任何情况下输掉的想法我都不喜欢——没有人会喜欢。

职业生涯早期,当我无法理解一个概念、代码崩溃或生产中发现 bug 时,我感到不断的失败。这种感觉有点像是让你的团队失望了。

我认为最困难的事情之一是意识到错误的发生,并理解失败是可以的。失败往往会带来伟大的成果。你应该把握机会面对你的失败,理解发生了什么,以及你可以做得不同。这是你作为程序员成长的地方。

[## 不要害怕失败,要有行动优先的心态]

大多数人面临的最大障碍之一就是对失败的恐惧。他们只是希望一切完美,而……

medium.com](https://medium.com/@elevyhart/dont-be-afraid-to-fail-have-an-action-first-mindset-59a195995ebb?source=post_page-----4062c309aef0--------------------------------)

#3 学习 + 一致性 + 目标 = 成功。

这是任何一个人对所追求的领域或话题的基本要求。但我要说的是,与明确的目标和期望保持一致是关键。刚开始时,确切了解所有需要学习的内容可能是一个艰巨的任务。然而,你应该尽力为自己设定目标,以便评估自己的进展。

没有目标的梦想只是梦想,它们最终会带来失望。

— 丹泽尔·华盛顿

让我在这里分享几个我最喜欢的学习资源:

O’Reilly 在线书籍

Coursera

在我职业生涯的很长一段时间里,导师和在线资源是我学习的途径。你可以在 Coursera 上审计免费的课程,或在这里那里读几本书。对一些人来说,这可能就是他们所需要的一切——这完全没问题。

我为自己设定的一个目标是最终获得该领域的正式教育。我希望在教授和实践者的指导下,对该领域有更深刻和理论性的理解。

在我的职业生涯中期,我终于筹集到了资金,部分得益于我公司提供的学费报销政策,得以完成这一目标。对我而言,在职业生涯的中途获得 NCSU 的正式计算机编程证书是极其宝贵的。目前,我正在 JHU 攻读人工智能硕士学位。这是我的路径,我对至今所经历的经验深感感激。

如果你对正式教育途径感兴趣,我强烈推荐它。同时,我建议你在计划工作和上学时一定要控制好节奏。市场上有多种选择,所以在选择你投入时间和金钱的大学时,也要有所挑选。

如果这不是你当前的路径或合适的选择,正如在职业生涯早期对我来说一样,我建议你围绕那些能够激励你并提供指导或建议的人。保持对自己个人进展的努力和诚实是至关重要的。最重要的是,保持一致并获得正式的专业教育 👨🏽‍🎓。

不要惊慌,也不要急于求成——享受过程

#4 评估你的领导者。

在我的职业生涯中,我学到,打造一款产品需要一个团队。企业主、工程师和其他利益相关者都在协作,共同朝着构建世界级产品的终极目标努力。每个小组在专注于各自的专业领域时,同时也在实现整体解决方案的方向。当然,这是对产品交付方式的简化描述。然而,很明显,沟通、协作和领导者是关键。我有幸在明智的领导下工作过,也曾在不充分的领导下工作过(这里不提名字😅)。这两种类型的领导者都帮助我确定了领导者的品质和性格。

因此,我认为不断评估你所拥有的领导者,并了解他们做出决策的方式至关重要。

你会以不同的方式做吗?如果会,怎么做,为什么?

即使你对成为软件经理或领导层的一部分不感兴趣(因为这并非适合每个人),你仍然应该提出这些问题,以确保你在一个能够帮助你实现目标的合格领导下工作。

最终思考…

如果这是你决定的路径,接受挑战,保持动力和一致性,享受成为程序员的充实旅程。正如生活中的一切,努力工作会有回报。享受你拥有的职业,这个职业不断发展,每天都有新的方面可探索——想象一下,若从事的是一个单调重复的工作,每天做着相同的无聊任务,会是怎样的感受。同时,接受变化,学习不同的编程语言,掌握新概念,并愿意冒一些可能导致失败的计算风险。成长和理解会随着时间、一致性和计划而来。

明白了

这。

当你没有学习动力时,这 5 个技巧将帮助你学习数据科学

原文:towardsdatascience.com/these-5-tips-will-help-you-learn-data-science-when-you-have-no-motivation-to-study-8e25b4d55788?source=collection_archive---------4-----------------------#2023-05-21

使用这 5 个技巧来教自己数据科学,当你没有动力时。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Madison Hunter

·

关注 发表在 Towards Data Science · 8 分钟阅读 · 2023 年 5 月 21 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Priscilla Du Preez 提供,来自 Unsplash

是的,我们都经历过这种情况。

有一天你满怀热情地制定学习计划,打算自学数据科学,但接下来你却开始找借口,理由是今天没有时间学习。我们都知道,除了清洗公寓的墙壁、清理冰箱或遛狗,你还能做多少事情,最终还是会坐在电脑前,试图激发一些学习的兴奋感。

作为一个已经自学数据科学四年的旁听者,我了解自学的消耗,尤其是在动力方面。然而,我也逐渐成为了在每天都能保持学习动机方面的专家。虽然有些人需要课堂的结构才能进行学习,但你也可以发展自己的方法,让自己每天都能保持学习的热情。好吧,也许不是热情,但至少能够坐下来并集中精力进行每天的学习。

这里有五个经过验证的技巧,能够帮助即使是最没有动力的人也能自学数据科学。

使用能帮助你持续进步的学习资源

自从我开始学习数据科学以来,我学到的最重要的一点就是学习资源可以决定你的成败。

例如,我知道要进行数据科学中的许多计算,我需要掌握微积分。凑巧的是,微积分课程是我大学学位要求的一部分。由于我需要为微积分课程付费,我决定利用这个机会自学数据科学所需的微积分。然而,我大学的学习材料糟糕透顶,我花了五个月才学会函数、极限和微分。这段时间真是折磨人。直到我找到了 Youtube 上最棒的数学老师。Leonard 教授的微积分讲座改变了我的人生,我发现通过这些视频自学微积分的速度远快于使用我大学提供的材料。

为了保持自学的动力,你需要使用那些能够帮助你按节奏学习的资源,而不是让你在理解一个概念上反复挣扎数周。没有什么比在一个概念上卡住超过一个月更能快速消耗你的动力了。

如果一个学习资源不能发挥作用,就没有理由继续使用它。幸运的是,互联网充满了数据科学学习资源,你有很多选择。

例如,许多人通过 2021 年变得流行的 Google 数据分析专业证书获得了很好的学习体验。这个自学进度课程旨在通过使用极其设计良好的学习材料来推动学生前进,使你可以在不到 6 个月的时间内完成课程,每周学习 10 小时。Codecademy 是另一个成功帮助人们学习编码的学习资源,它提供了易于跟随和消化的模块,帮助你在学习中不断前进,而不会陷入困境。

总之,如果一个学习资源让你感到意志消沉,无法推进学习,那么你没有理由继续使用它。自学数据科学应该始终是一个前进的过程。是的,前进的速度有时可能很慢,但绝不应该完全停止或倒退——有太多不同的学习资源可以选择。你需要做的就是能够承认某些东西不起作用,并改变策略,找到有效的方法。

以在线学习空间、"与我一起学习"视频和 Discord 聊天的形式寻找学习支持

奇怪的是,即使你们相隔遥远,和某人一起学习这样简单的事情也能如此激励人心。

在线学习空间、"与我一起学习"视频和 Discord 聊天在过去三年中似乎变得非常流行,这些资源每天都有成千上万的观众和成员。

我最喜欢的 YouTube 学习频道之一是由Merve运营的,她也巧合地学习数据科学。该频道拥有 82.2 万订阅者,每周发布的“与我一起学习”视频被数百万观众观看。与某人“一起学习”总是让人感到如此鼓舞,并且帮助你保持动力。

Study TogetherStudyStreamStudyverse 都是虚拟学习室,你可以与来自世界各地的人一起学习。这些学习室可以帮助打破拖延症,并让你集中精力学习几个小时。此外,许多 Instagram 上的学习账户利用直播功能为所有关注者举办学习会议。

另一个保持动力的最佳工具是加入一个 Discord 服务器,特别是那些专注于不同学习领域的服务器 数据科学。这些社区是保持学习动力的绝佳机会,同时也可以在遇到问题时立即得到解答。与志同道合的人交流也是了解数据科学行业、建立人脉和未来成为更全面的数据科学家的好方法。

每天学习时间不超过 6 小时

当你自学数据科学时,可能很难确定每天应该学习多少。这种情况在你没有其他承诺时尤为明显,这可能使你整天都可以用来学习。

这也受到你周围其他人学习情况的进一步影响。社交媒体使得有毒的学习文化更加普遍,许多人会发布他们每天学习多少小时的信息。这会给你带来不必要的压力,促使你也每天学习 12 小时。

尽管每个人能够有效学习的时间不同,但我可以证明你不应每天学习超过 6 到 7 小时。学习是一种强度很大的脑力活动,与你在 8 小时工作制下的脑力使用完全不同。例如,工作 8 小时并不意味着你在这 8 小时内都在高强度使用大脑。其中一些小时会用于耗费精力的任务,但大部分时间会用于低强度的脑力活动,比如参加会议、回复邮件和休息。

相对而言,你的大脑在学习时会持续被高强度地使用。学习需要 100%的专注力来有效进行(特别是当你在探索如微积分和神经网络等话题时),这就是为什么每天 6 到 7 小时的学习应该是你的最大目标。这还考虑到你在学习期间需要以其他方式照顾自己,包括休息、社交、锻炼和营养。

当你的大脑学会了一天最多只需努力工作 6 小时时,你可能会发现,在这 6 小时内更容易集中注意力。你不会再感觉被手机分心,因为你知道你只有 6 小时来完成当天的学习任务。你还会发现,第二天开始学习时感觉更加清爽,因为你的大脑有足够的休息时间。你可能还会发现,你对学习的材料保持的记忆更多,因为你的大脑有更多时间在不受新信息不断轰炸的情况下与学习的材料建立强大的连接。

找到激励你的实际应用

让我们面对现实吧 —— 数据科学中并非所有主题都一视同仁。不幸的是,像机器学习、数据可视化和实际应用这样的好东西,只能在你学会了编码、数学和沟通技能之后才能出现。要通过这些主题,对尚未到来的好东西保持动力可能会很困难。

克服这种低迷的一个我最喜欢的技巧是找到激励我的材料的实际应用。例如,学习极限和微分可能会令人疲倦,但只要你不忘了它们可以用来确定函数的变化率,从而告诉你各种酷炫的事情,比如气候变化加快、商品成本增加或医疗保健获取减少。

当你热衷于如何应用你的数据科学知识(比如在医疗保健、科学、工程、商业、教育等领域),那么找到可以应用正在开发的知识的不同方式变得很容易。例如,一旦掌握了数据分析,你可以为社区内的小企业提供无偿工作,帮助他们增加销售。或者,你可以创建一个预测模型,预测某种自然灾害可能影响多少人,作为一个作品集项目。

无论你的兴趣是什么,总有办法将你所学的应用到能激励你继续前进的方式上。找到激励你的东西,并将数据科学应用到其中。

设置有时间限制的学习目标

我不在乎你有多么拖延,设置有时间限制的学习目标总是奏效的。只要你按时完成,即使把它留到最后一刻也没关系。

自学数据科学时,我看到很多人面临的一个问题是缺乏动力,因为没有结构化的有时间限制的目标。许多人告诉我,他们永远无法自学数据科学,因为他们没有动力坐下来完成工作。然而,这只是因为缺乏结构。

上学的一个重要好处是你处于一个有结构的环境中,并且有截止日期。作业截止日期、考试截止日期以及毕业截止日期。你能想到的几乎都有截止日期。这种时间敏感的结构帮助人们集中注意力,并且不用过多努力就能投入工作。正如我之前提到的,即使你把事情拖到最后一刻,你也会完成任务,因为你知道有一个硬性的截止日期需要遵守。

因此,在自学领域获得这种动力的诀窍是设定你认为是硬性截止日期的时间敏感学习目标。

对于许多人来说,这可能很容易,因为你正在经历职业变动,只希望离开工作几个月。而对其他人来说,这可能更困难,因为可能没有特定的时间压力。

假期、生日、活动,甚至周末都是可以用来激励你完成工作的伟大硬性截止日期。没有什么比在周五完成所有工作、知道你的周末可以做任何事情更令人愉快的了。假期、朋友的生日派对或孩子的学校表演期间无需担心工作也是一样。无论是什么场合、日期还是周末惯例,找到一个可以围绕其安排学习的硬性截止日期,可以帮助即使是最拖延的人也能激励自己学习数据科学。

订阅以将我的故事直接发送到你的收件箱:故事订阅

请成为会员,以通过我的推荐链接获取对 Medium 的无限访问权限(这对你没有额外费用,我将获得一小部分佣金):Medium 会员

通过捐赠来支持我的写作,以资助创作更多类似的故事:捐赠

这 7 个编程习惯让你成为一个低效的数据科学家

原文:towardsdatascience.com/these-7-programming-habits-are-making-you-a-less-productive-data-scientist-6d9767fd8ff3?source=collection_archive---------9-----------------------#2023-02-03

修正这些习惯可以让你成为一个更高效的数据科学家

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Madison Hunter

·

关注 发表在Towards Data Science ·9 分钟阅读·2023 年 2 月 3 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源于Rémi JacquaintUnsplash

我相信在我们共同的数据科学之路上,大家至少都曾经犯过其中一个这些坏习惯。

无论我们是在刚开始学习时做这些注释,还是因为我们已经比较擅长而变得懒惰时做这些注释,我们都曾犯过这些编程错误。

无论出于何种原因,清理你的编程习惯,成为更高效的数据科学家永远不会太晚。幸运的是,你已经完成了最困难的部分,学会了编程。现在,我们只需要完善你的技巧,养成一些良好的习惯,让你在数据科学项目中享受更多乐趣。至少你今天学到的知识会让你避免被软件部门责备。

从软件开发学生的经验来看,这些习惯无疑会妨碍你发挥最佳生产力——让我们现在就改变这一点。

1. 未对代码进行注释

对代码进行注释是代码文档的重要部分,确保以下三点:

  1. 其他人能够理解你的代码。

  2. 其他人能够维护你的代码。

  3. 当你在一段时间后重新访问你的代码时,你能理解它。

至少,你的代码中必须有三种类型的注释——这些是不可协商的:

  1. 第一点是对你个人或团队代码库中任何新提交或共享代码的注释。这个注释可以作为你的 Git 提交消息的一部分,但也应该出现在代码中,通常位于你刚刚提交的代码块上方。我喜欢通过在代码和注释周围创建虚线来进一步分隔这个代码段——只是为了更清晰的查看,仅此而已。这个注释应该描述代码的功能。

  2. 第二点是对代码中每个函数的注释。该注释应直接位于每个函数的上方,并解释其输入、输出以及函数逻辑。

  3. 最终的注释应该位于代码中任何单行代码的上方。单行代码描述了通常分散在几行代码中的逻辑,但却写成了一行。由于这些单行代码有时可能难以理解,因此一个描述其功能及每个部分如何工作的注释是保持组织性的好方法。

从与其他软件开发者的合作中,我看到将好代码与优秀代码区分开来的因素是代码注释的层次和细节。换句话说,简洁、准确、充分地注释你的代码。如果某些内容对你来说很明显,最好还是做个注释,以防对其他人(或将来你自己)不够明显。

2. 未使用 GitHub 进行版本控制

现在已经没有理由让从事技术工作的人不使用 GitHub 了。GitHub 不仅是一个版本控制工具,而且还是一个生产力工具,帮助你轻松处理代码和与他人协作。

GitHub 通常被认为是黄金标准,大多数科技公司都通过它来进行代码的版本控制。即使你是一个在公司里工作的单独数据科学家,如果你将代码分享给一个将其转化为生产代码的软件部门,GitHub 也是一个重要的工具。

在某个时候,我们都曾宣布要真正学会如何使用 GitHub 一劳永逸。GitHub 具有许多有用的功能(包括跟踪代码的变化以及处理代码的旧版本),但说实话,数据科学家通常可以仅仅使用它来进行简单的主分支提交,配合几个分支以运行替代场景。就是这么简单。

好吧,这就是你真正开始使用它的标志——这次是认真的。

## 数据科学家的全面 GitHub 指南

数据科学家的 GitHub 教程,包括 UI 和命令行

[towardsdatascience.com

3. 不测试你的代码

我们都经历过这种情况:因为害怕可能发生的事情而尽可能避免运行和测试代码。1% 的时候我们可能运气好,一切正常运行,但我可以保证,其他 99% 的时候,一切都会出问题。

从软件开发的教育背景中,我们经常接受测试的训练。不定期测试代码被视为一种罪过,我们很快就能做到。不仅帮助我们立即发现错误和缺陷,还意味着我们不需要筛查数百行代码来找出问题所在。

测试你的代码就像编写 单元测试 一样简单,这种测试涉及检查函数、对象或类(单元)是否正常工作。进行单元测试的一种简单方法是根据你提供的输入打印函数的输出。

[## 如何为 Python 函数编写单元测试

本指南将教你如何为 Python 函数编写单元测试。但你为什么应该考虑编写单元测试……

www.freecodecamp.org

4. 没有将复杂问题拆解为简单变量和函数

数据科学问题通常很复杂,涉及许多活动的部分。这些问题可能让人感到气馁,如果不将其拆解成简单的部分,可能会导致你盯着计算机屏幕发呆,直到该回家时却没有写下一行代码。

诀窍是 以终为始地开始解决问题,然后将其拆解成简单的变量和函数——因为实际上,代码就是由变量和函数组成的。

开始之前,你需要问自己这个问题试图解决什么,以及这个解决方案的结果将是什么。这将帮助你开始确定你需要哪些代码片段来达到最终目标。一旦你确定了解决方案的样子,你可以开始规划你需要的各个变量和函数,以实现它。

看,你已经把复杂的问题拆解成了可管理的任务!这感觉不是更好吗?

在将这些任务添加到你的看板上(我在处理复杂问题时保持组织的最爱方式)之后,你可以开始创建将导致完整解决方案的项目小部分。

5. 不重构你的代码

代码重构是指在不改变原有功能的情况下,对代码进行重组。虽然重构通常出现在 软件开发场景中,但数据科学家也可以使用重构来清理他们的代码。

重构 比听起来要简单:查看一些你以前写的旧代码,问问它可以如何更有效地编写。然后,应用良好的编码实践,清理你的代码,直到它看起来比以前更好。

重构最好是在你编写了有效的代码之后进行。例如,当你刚开始处理一个 数据科学问题时,你要确保你的代码能正常工作,不管它是否优雅。然后,一旦你确保它产生了正确的输出,你可以回过头来明确变量名称,正确缩进代码,使用 Python 语法标准创建消除冗余的函数,并且总体上重写任何看起来像一堆意大利面的代码。

我建议在你从专注状态中出来并使代码正常工作之后再进行任何重构。每次写一行代码就停下来重构会让你脱离专注状态,并且使完成代码的时间延长十倍。就像建议在你把想法写到纸上之前不要担心拼写或语法一样,等到你写完所有的代码后再美化它。

6. 不保持代码的组织

在我大学学习软件开发期间,我经常遇到糟糕的组织技能。尽管我的许多同学都是优秀的开发者,但组织能力并不是他们的强项,这使得他们的代码在查看时留下了很多遗憾。

早期学习适当的代码组织技能可以帮助你创建易于导航和处理的代码,从而减少你推动项目的时间。

根据Karl Broman的说法,代码和数据组织可以简单到如下几点:

  • 将项目的所有内容保存在一个目录中。 该目录应包含项目的所有数据、代码和结果,这样将来在继续工作或交给他人时会更方便。

  • 将原始数据与派生数据分开。 保持两个子目录,一个包含原始数据,另一个包含派生数据。包含数据总结的子目录也有助于保持数据的组织。

  • 将数据与代码分开。 将代码放在一个子目录中,将数据放在另一个子目录中(或者像上面描述的那样,三个子目录)。

  • 避免使用绝对路径,改用相对路径: 当与其他人合作时,他们可能没有在完全相同的位置复制你的项目目录,因此使用相对路径很重要,以便他们能够打开和访问你的所有文件。

  • 选择好的文件(以及变量和函数)名称: 原始数据文件名应保持不变,但代码文件名应尽可能具有描述性。变量和函数名称也是如此。

  • 文件名中永远不要使用“final”: 正如 Broman 所说,“没有什么是最终的”。多个版本的文件应附加版本号,但“最终”版本不应如此标记。

  • 编写文档和 README 文件。 文档是解释所有内容及其功能的必要手段。好的文档包括描述文件及其包含的过程。保持 README 更新很重要,同时如果有人有进一步的问题,也要包含你的联系信息。

我在之前的项目中承担的任务之一是组织团队的代码。这不仅是一个学习代码如何工作的好方法,而且是成为熟练开发者的重要技能。建立一个适合你的组织系统(我的系统与上述描述的相似)并在每个项目中付诸实践,无论大小。

7. 不休息

我告诉你一个小秘密:当你不休息时,你写的代码往往很糟糕。

在技术领域,拼命文化依然存在,工作 90 小时的周数并不少见,你可能只会偶尔起身去加点饮料,几天不见太阳也很正常。

虽然你可能觉得老板支配了你,但他们并不支配你的健康(包括身体、心理和情感健康)。

所以我希望你现在就承诺每天至少进行一个小时的活动,每天至少喝两次除了苏打水以外的饮品(开始时可以选择水,咖啡不算),每天至少出去一次,并且尽量吃不是外卖的食物。

相信我,我记不清多少次是在遛狗的时候解决了编码或逻辑问题。新鲜空气似乎对大脑的解决问题部分有奇效。

每天坐在电脑前连续编写代码八小时或更长时间而没有任何休息,会使你感到精疲力竭,生产力也会比之前更低。换句话说,生活短暂,你的工作并不是一切,照顾好自己从长远来看会让你成为更优秀的数据科学家。

订阅以便直接将我的故事发送到你的收件箱:故事订阅

请通过我的推荐链接成为会员,以获得对 Medium 的无限访问(这对你没有额外费用,我会获得少量佣金):Medium 会员

通过捐赠支持我的写作,帮助创造更多这样的故事:捐赠

思考 SQL —— 避免从上到下编写 SQL

原文:towardsdatascience.com/think-in-sql-avoid-writing-sql-in-a-top-to-bottom-approach-476a67f53a59

通过理解逻辑查询处理顺序来编写清晰的 SQL

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Chengzhi Zhao

·发布于 Towards Data Science ·7 分钟阅读·2023 年 2 月 2 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Jeffrey Brandjes 提供,来源于 Unsplash

由于 SQL 的声明式特性,你可能会觉得编写 SQL 有挑战。尤其对于那些熟悉 Python、Java 或 C 等命令式语言的工程师来说,SQL 切换起来是许多人需要的思维转换。思考 SQL 与任何命令式语言都不同,因此学习和开发的方式也不应相同。

当使用 SQL 时,你是按照从上到下的方法编写的吗?你是否从 SQL 中的“SELECT”子句开始开发?在这篇文章中,让我们探讨 SQL 的逻辑查询处理顺序,帮助你理解为何可能需要改变从上到下编写 SQL 的方式。这也有助于你更清晰地思考 SQL,并更有效地开发查询。

SQL 是一种声明式语言

声明式语言的核心概念非常棒:人类传达的是高级结构和逻辑指令,而不需要精确的流程。作为开发者,这意味着我们不需要编写如何实现目标的逐步指南。我们只需编写要实现的目标,这样我们可以更多地关注结果,让底层查询解析器和引擎来决定如何执行指令。

编写 SQL 时,你更关注输入和输出,而执行是幕后的神奇黑匣子。对于详细的执行,用户提供计划和优化的偏好。但执行仍然由查询引擎在运行时处理。

然而,这并不意味着我们可以挥舞魔法棒,一切都会如愿以偿。仍然需要高级指令来提供以下信息。

  • 数据源在哪里(FROM

  • 应用什么条件(WHERE/HAVING

  • 是行级别还是聚合(GROUP BY

  • 如何显示结果(SELECT

  • 如何排序数据(ORDER BY

  • 返回多少行(LIMIT

与获取数据的命令式语言不同,我们不需要编写复杂的逻辑或逐行循环。SQL 查询就像一个蓝图,SQL 引擎是构建者。作为用户,我们只需等待输出,而不必担心它如何获取结果。

SQL 逻辑查询处理顺序

如果你曾使用过其他数据处理框架的命令式语言,甚至对于 Spark 或 Pandas 用户,我们总是需要先有数据集进行处理。获取数据源的地方通常是任何数据处理框架的入口点,SQL 也是如此。

要理解 SQL 逻辑查询处理顺序,让我们用 SQL 查询在语法时间来比较它与逻辑处理顺序。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SQL 语法与逻辑查询处理顺序标记 | 图片由作者提供

  1. FROM: SQL 的入口点是 FROM 子句。它通常在“SELECT”语句之后定义,并作为准备阶段来指导查询引擎从哪些表中提取数据

  2. ON: 在每个表中评估的条件,用于检查要连接的键

  3. JOIN: 一旦知道要连接哪些键,SQL 引擎会检查需要应用哪些类型的连接(内连接、外连接、交叉连接等)

  4. WHERE: 应用行级过滤器

  5. GROUP BY: 指定要聚合的键,并改变原始行级表的视图。在这个阶段之后,所有处理的内容都会是聚合级别而不是原始行级别。如果使用了 cube 或 roll-up 聚合,也会在这个阶段发生。

  6. HAVING: 应用聚合级过滤器。我们还可以编写嵌套查询或 CTE(公共表表达式)在聚合级别进行过滤。不过,紧挨着 GROUP BY 子句使用更为方便,并且可能有利于 SQL 引擎优化。

  7. SELECT: 选择要显示给用户的字段。对于需要复杂逻辑的派生字段,如窗口函数(rank()、row_number() 等)、或 case 语句,或聚合函数,这些操作都会在此时进行。如你所见,SELECT 在 SQL 逻辑查询处理顺序中较晚。如果你先从 SELECT 子句开始,可能很难预见你会如何编写其他 6 个语句,从而可能导致 SELECT 中出现意外结果或错误。让我们在下一节中详细讨论。

  8. ORDER BY: 最终结果的排序顺序。在这个阶段,我们可以解析你在 SELECT 子句中定义的别名。

  9. LIMIT: 返回结果的数量,或者如果你想跳过几行顶部数据,可以结合 ORDER BY 使用。

让我们把 SQL 语句从语法时间重新排列成 SQL 逻辑查询处理顺序,这样会更清晰。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SQL 逻辑查询处理顺序 | 作者图像

微软在 SELECT 语句的逻辑处理顺序 上有很好的文档。

“SELECT” 不应该是编写 SQL 时的第一个单词

“SELECT” 通常是阅读 SQL 语句时的第一个子句。我们的脑袋在阅读或写作时,通常采用自上而下的方法。首先使用 “SELECT” 定义了我们希望显示的结果。将 “SELECT” 作为第一个单词符合这种模式。此外,将 “SELECT” 放在首位是语法正确的,可以编译并运行整个 SQL 脚本。

当你为数据分析编写 SQL 查询时,有多少次你首先写下了以下内容:

SELECT col1, col2, CASE (…), ROW_NUMER(…)

有效!一个编译并正确提取结果的 SQL。

但是,正如你在上面看到的,SELECT 在 SQL 逻辑查询处理顺序中被评估得较晚。 以下是避免首先在 SELECT 中编写所有内容的一些原因:

  • 很难预测你会在 SELECT 之前为语句写些什么。 你有所有的表名吗?你有定义别名吗?你是在处理行级数据还是汇总级数据?我知道有人可以很好地预测所有 SQL 以及所有表和别名。不幸的是,我不擅长预见和记忆。按逻辑查询处理顺序编写 SQL 给了我下一步要写的参考。如果在编码时被打断,它也给我一个提示,使我更容易从中断处恢复。

  • 逻辑查询处理顺序更适合我们的脑袋。 如果你编写 SQL,可能熟悉 ETL 概念(提取、转换、加载)数据。ETL 概念遵循逻辑顺序:你获取数据集,对数据集进行操作,将重构后的数据集放到其他地方。在 SQL 中编写应该遵循相同的逻辑顺序,“SELECT” 更适合作为转换或加载阶段,我们应该先准备数据集,以便为 “SELECT” 提供数据。

  • 它有助于调试和推理错误。 通过遵循逻辑查询处理顺序,一些错误变得明显。例如这个 StackOverflow 问题:“SQL 在 WHERE 子句中未识别列别名”,通过这篇文章,我们可以快速回答:SELECT 别名尚未被评估,因此 SQL 引擎没有你给定的别名的上下文,因此失败了。(一些现代 SQL 供应商进行了一些优化以避免这个问题,但并非所有 SQL 提供商都适用,我们仍应注意这一点)

编写 SQL 的技巧:逻辑查询处理顺序

  • 我们仍然可以先写“SELECT”,但只写这 6 个字母;将其作为占位符,以提醒我们在内容准备好时填入剩余的内容。

  • 从 ETL 角度思考,数据准备对于为其他工作奠定基础至关重要。因此,首先需要关注的是正确编写FROM、ON 和 JOIN 语句。

  • 如果遇到错误,请按照逻辑查询处理顺序进行调试。SELECT * 在生产环境中很糟糕,但我们仍然可以在调试中使用它。我们还可以通过 LIMIT 子句进一步防止拉取过多的数据。

最终思考

如果你从上到下编写 SQL 并且这种方法让你在思考 SQL 时感到困扰,你应该考虑理解 SQL 逻辑查询处理顺序并进行这种练习。

我在准备 Microsoft Exam 70–461 时很早就学到了这种方法,Itzik Ben-Gan 有一本很棒的书 Querying Microsoft SQL Server 2012 (MCSA)。这本书的优点在于它对 SQL 基础的解释远胜于其他书籍中那些花哨的语法。

思考 SQL 是至关重要的。你可以推理事情为何如此发生,并迅速解决错误。此外,它帮助你更好地组织代码,以更有条理的方式解决复杂查询。

我希望这个故事对你有帮助。本文是我工程与数据科学故事的系列之一,目前包括以下内容:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Chengzhi Zhao

数据工程与数据科学故事

查看列表53 个故事外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你也可以订阅我的新文章或成为推荐的 Medium 会员,享受对 Medium 上所有故事的无限访问权限。

如有问题/评论,请随时在本文评论区留言,或通过LinkedinTwitter 直接联系我

考虑微调 LLM?在你开始之前,这里有 3 个考虑因素

原文:towardsdatascience.com/thinking-about-fine-tuning-an-llm-heres-3-considerations-before-you-get-started-c1f483f293

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Sean Smith

·发表于Towards Data Science ·11 分钟阅读·2023 年 6 月 15 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由Brett Jordan拍摄,来自Unsplash

目前 LLM(大型语言模型)和生成 AI 正当红。来自IBM的惊人统计数据显示,近 2/3 的 C-Suite 高管感受到来自投资者的压力,要求加快生成 AI 的采纳。这种压力自然会传递给数据科学和机器学习团队,他们负责应对炒作并创建成功的实施方案。

随着环境的发展,LLM 的生态系统在开源模型和行业模型之间发生了分化,形成了一个迅速填补的护城河。这一新兴场景促使许多团队考虑以下问题:我们如何使 LLM 更具体地适用于我们的用例?

在这篇文章中,我们探讨了在考虑投入时间和工程周期来构建一个细分 LLM 时需要重点关注的一些关键因素。在这段旅程中,了解一些关于潜在限制和最佳实践的最新研究至关重要,这些研究涉及如何构建微调的语言模型。阅读完这篇文章后,你将会有更多的想法来指导你的组织做出正确的决定——是训练还是不训练,以及如何训练。

你可能无法用开源模型模拟 GPT

任何人都知道,OpenAI 正在通过其最新的 GPT 版本引领 LLM 的发展。因此,许多利益相关者可能会要求开发团队部署一个模型,以模仿更强大模型的结果,原因可能包括(速率限制、数据隐私、成本等)。这自然引发了开发者的疑问:我们能否从 GPT 生成输出,并利用这些输出来微调一个模型?

这个问题的答案仍然不确定,因为它似乎取决于几个因素。这个特定任务,称为模仿学习,涉及通过使用来自更先进模型(如 GPT)的目标观察来微调训练一个新的语言模型。虽然这似乎是从下游模型中获得良好性能的一个好方法,但也存在一些潜在的问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图源自参考文献 Gudibande 等人 [1]。

一篇题为“模仿专有 LLM 的虚假承诺” [1] 的最近论文对这种方法可能遇到的陷阱提供了一些见解。作者展示了一些实验,表明增加更多模仿数据可能会导致模型性能的下降。查看上图,我们可以看到在中心图表中,基准任务上的准确性随着令牌数量的增加而下降。那么这是为什么呢?

作者建议出现这种情况的原因是,模仿模型学习的是它们模仿的模型的风格,而不是学习和理解模型的内容。查看上图左侧的窗格,人工评审员更喜欢模仿模型的结果而非 ChatGPT 的结果。经过探索,明显看到评审员喜欢模仿模型的风格,但并未仔细审查内容。注意到模仿模型产生的内容通常缺乏事实准确性,作者总结道:“模仿模型实际上体现了 AI 助手的一些最糟糕的方面:它们的回答听起来很自信,但比 ChatGPT 的回答更不准确。”

重要的是要注意,有些情况下模仿模型可以取得出色的表现。作者指出,模仿模型可以在本地任务或复制教师模型非常特定行为的任务上表现良好。在为研究创建的任务 NQ-Synthetic 中,作者要求语言模型生成与给定背景相关的 10 个问题和答案。值得注意的是,模仿模型的得分接近 GPT。这表明,更具体的模型在尝试模仿教师模型的行为时可能会取得有利的结果。

论文中的一个有趣的推论是,使用教师模型对模型进行微调实际上可以帮助减少模仿模型的毒性评分。这对于希望快速发布开源大语言模型的公司非常有用,而无需进行繁琐的过滤器构建任务。公司可以选择训练一个从精心挑选的教师模型中获得的输出,以获得一个良好的起点,而不是手动尝试构建过滤器。

值得一提的是最近发布的 Orca,这是一款由微软研究院开发的模型,它在训练数据中融入了 GPT 的信号。不同之处在于用于模型训练的数据量。Orca 在 500 万示例上进行了微调,而广覆盖的模仿模型则在大约 15.1 万条观察数据上进行了调整。由于我认为大多数受众不会花费 16000 美元来训练大语言模型作为随意实验,我倾向于发表更接近于模仿建模论文的声明,而非 Orca。话虽如此,我们还需要等待更多研究,以确定模仿学习在更广泛任务中成为可行选项所需的最小示例数。

结论:根据任务的复杂性,尝试用较弱的模型模仿 GPT 或任何复杂模型的输出可能会导致模型性能较差。

上下文学习是你所需的一切吗?

上下文学习(In-Context Learning),或称为少量样本学习(Few Shot Learning),是将任务特定的示例包含在提示中的过程。这种方法对于复杂的语言模型特别适用,因为开源模型尚未具备处理上下文学习所需的灵活性。通常,这种方法可以取得很好的结果,但你是否曾经想过为什么会这样?

Dai 等人[3]的论文探讨了在提示中加载示例与使用相同示例进行微调之间的数学联系。作者展示了提示示例产生的元梯度在推理时的前向传播中得到体现。对于微调,示例实际产生的是真实梯度,用于更新权重。因此,上下文学习似乎达到了与微调类似的结果。为了更深入理解这些发现,我建议阅读该论文,其中详细阐述了数学联系。

尽管上下文学习的方法很棒,但存在一个在精细调整中不明显的限制。如果我们有大量的训练数据,精细调整的模型将通过在训练过程中更新模型的真实梯度来利用所有这些数据。在上下文学习中,我们只能提供有限数量的观察。因此,出现了一个问题:鉴于大量的训练语料库,我们如何利用最相关的示例来实现最佳结果?

解决这个问题的一种方法是使用启发式方法选择示例,幸运的是,LangChain 提供了支持。LangChain 是一个 Python 模块,基本上包含了简化与语言模型工作相关的预构建提示。我们现在关注的 LangChain 工具是 ExampleSelector

def get_similarity(seq_a: str, seq_b: str) -> Union[float, int]:
    """ 
    Make a similarity heuristic,
    here we use Jaccard similarity or IOU

    seq_a: First sequence to compare
    seq_b: Second sequence to compare

    Returns:
    Similarity score (float or int)
    """
    # Tokenize
    set_a = set(seq_a.split(' '))
    set_b = set(seq_b.split(' ')) 

    # Calculate IOU/Jaccard similarity
    return len(set_a.intersection(set_b)) / len(set_a.union(set_b))

def example_selector(examples: List[str], input: str, examples2use: int) -> List[str]:
    """ 
    Pseudo code for an example selector

    examples: List of training corpus
    input: Target sequence to translate
    examples2use: Number of examples to use

    Returns:
    List of selected examples
    """
    scores = [get_similarity(example, input) for example in examples]
    sorted_idx = [i for i, _ in sorted(enumerate(scores), key=lambda x: x[1], reverse=True)]
    return examples[sorted_idx[:examples2use]]

ExampleSelectors 是一种提示操控器,允许我们在推理过程中动态改变使用的示例。有很多启发式方法可以使用。上面我创建了一些 LangChain 的选择器如何工作的伪代码。我使用了输入序列和示例序列之间的 jaccard 相似度。在 LangChain 中还有更多选项,请查看 这里

采用这种方法有两个主要好处。首先,你可以使你的 LLM 数据高效,通过选择最相关的示例来处理给定的输入。这与为所有观察加载少量静态示例相对。第二个好处是节省成本,如果通过托管服务进行调整的话。写作时,使用精细调整的基础 Davinci 模型的费用为每 1,000 个 tokens $0.12。相比之下,使用 instruct Davinci 的费用为 $0.02,这是一种 500% 的价格增长!这些价格也不包括培训的费用。

需要注意的是,这些价格可能会发生变化,因为 OpenAI 目前尚未使用 LoRa 或适配器,这在一篇现已删除的 博客文章 [5] 中有透露。然而,由于需要为每个用户维护自定义权重,精细调整的模型仍然可能更昂贵。这也不包括上下文中示例的费用。你的团队需要评估从成本和准确性的角度来看,ICL 还是精细调整更适合你的任务。

要点:使用动态示例加载的上下文学习可能会在没有来自托管服务的额外成本的情况下实现与精细调整相同的结果。

你的任务是否从最终推理之前的一个或多个中间步骤中受益?

假设你试图回答关于长文档的复杂问题。这项任务从根本上要求语言模型具备良好的语言掌握和理解能力。这引出了一个问题:如果我们帮助语言模型将推理过程分解为子任务,类似于人类如何分析文档并按顺序执行任务呢?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自 Sun 等 [4] 的图示。

这正是微软研究人员设定的目标,他们的解决方案是 PEARL [4]。PEARL 代表规划和执行行动以推理长文档。整体框架分为三个步骤:

  1. 行动挖掘: 语言模型首先被提示阅读文档,并提取可能用于回答领域特定问题的行动。为了提取这些行动,语言模型会提供几个示例行动。以下是一个行动可能的示例。

  2. 计划生成: 在生成一组任务特定行动后,LLM 现在被要求根据问题和上下文生成一个后续的行动列表。LLM 会提供其他任务的计划示例,这有助于构建高质量的计划。有关技术细节的更多信息,请参阅论文。

  3. 计划执行: 现在模型已经有了计划。我们现在将输入提供给模型并执行计划。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自 Sun 等 [4] 的示例行动。

在各个阶段之间使用了一些中间步骤以确保质量。作者包括一个自我校正步骤,确保计划符合所需格式。还有一个自我精炼步骤,确定计划是否可以在以后作为少量示例使用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自 Sun 等 [4] 的表格。

在评估中,PEARL 展示了相较于其他 GPT 模型的显著改进,尤其是在处理长文档时。这个过程的关键收获是,在某些情况下,拥有多个步骤可以显著帮助模型。

另一个中间步骤证明有益的场景是当要包含在上下文中的文档数量超过语言模型支持的范围时。当前,OpenAI 使用的注意力机制的规模为 O(n²),尚无解决方案来克服这一点 [5]。这引起了对将上下文缩减到最小形式的强烈兴趣。

根据你的任务,有处理此问题的方法。例如,如果你的任务完全围绕实体展开,可以提取相关实体及其相关属性。你可以将这种方法视为一种有损压缩,允许你向 LLM 提供更多上下文。这个中间步骤的另一个好处是,你将非结构化数据转换为结构化格式,这使得你能够在没有 LLM 的情况下做出明智的决策。下面的图示来自 Fei 等人[6]展示了这一任务的一个示例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图示摘自 Fei 等人[6]

总结:将任务分解为较小的后续问题可以帮助将较大问题简化为更易管理的部分。你还可以利用这些较小的任务来解决与模型限制相关的瓶颈。

总结思考

这些是关于研究人员在 LLM 性能和效率的新前沿中探索的一些一般想法。这不是微调模型时需要考虑的所有事项的详尽列表,但在考虑这段旅程时是一个很好的起点。

进一步阅读,Hugging Face 关于训练 LLMs 的这篇文章非常有趣,是探索本地问题模仿模型的一个好起点。对LangChain有一个具体的理解也是极其有帮助的。尽管大部分库可以为你的用例重写,但主要好处在于,如果其他人为你编写代码,你可以更容易跟上研究进展!

再次总结要点:

  1. 根据任务的复杂性,试图用较弱的模型模仿 GPT 或任何复杂模型的输出可能会导致模型性能差。

  2. 通过动态示例加载进行上下文学习可能会达到与微调相同的效果,而不会带来额外的管理服务成本。

  3. 将任务分解为较小的后续问题可以帮助将较大问题简化为更易管理的部分。你还可以利用这些较小的任务来解决与模型限制相关的瓶颈。

感谢阅读这篇文章!我的主要兴趣领域是为用户创建个性化互动。请考虑互动文章并关注我在 Medium!如果你想联系我以讨论文章中的技术错误或保持联系,请通过 LinkedIn联系我。

参考文献

[1] Arnav Gudibande, Eric Wallace, Charlie Snell, Xinyang Geng, Hao Liu, Pieter Abbeel, Sergey Levine, & Dawn Song. (2023). 模仿专有 LLMs 的虚假承诺。

[2] Mukherjee, S., Mitra, A., Jawahar, G., Agarwal, S., Palangi, H., & Awadallah, A.(2023)。Orca:从 GPT-4* 复杂解释轨迹中逐步学习。arXiv: 计算与语言*。

[3] Damai Dai, Yutao Sun, Li Dong, Yaru Hao, Shuming Ma, Zhifang Sui, & Furu Wei.(2023)。为什么 GPT 能在上下文中学习?语言模型隐式地作为元优化器执行梯度下降。

[4] Simeng Sun, Yang Liu, Shuohang Wang, Chenguang Zhu, & Mohit Iyyer.(2023)。PEARL:引导大型语言模型规划和执行长文档上的动作。

[5] Habib, R…(2023)。根据 Sam Altman 的说法,OpenAI 的计划。

[6] Hao Fei, Fei Li, Chenliang Li, Shengqiong Wu, Jingye Li 和 Donghong Ji,(2022)。继承前人的智慧:一个用于统一基于方面的情感分析的多层级级联框架

超越数据科学的种种框架

原文:towardsdatascience.com/thinking-outside-data-sciences-many-boxes-d84f0e85a668?source=collection_archive---------5-----------------------#2023-05-11

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 TDS Editors

·

关注 发表于 Towards Data Science ·作为 Newsletter ·3 分钟阅读·2023 年 5 月 11 日

数据科学的两大支柱——基于统计的分析和代码——都带来了各种约束。如果你的查询结构错误,可能会搞乱整个流水线。如果应用公式不正确,你的测试结果可能不再反映现实。

在约束条件下工作并不一定感到僵化或限制,恰恰相反。一个灵活的数据专业人士在仍然在预定的一组参数内工作时,通常需要发挥他们的创造力。这在我们的日常工作流程中成立,在我们学习新技能的方式中成立,也在我们为成功的数据职业做准备的方式中成立。

我们本周突出的文章涵盖了非常广泛的领域,从构建推荐系统到为您的投资组合寻找项目创意。它们的共同点是对许多业内人士可能认为已解决的问题和挑战提供了全新的视角。如果“我们一直这样做”是你经常嗤之以鼻的句子,那么你可能会在本周的精选中找到合适的内容。

  • (重新)考虑仪表盘。在三年前宣布仪表盘的“死亡”后,Taylor Brownlow重新审视了这一普遍存在、偶尔无用、有时不可或缺的数据团队工具,提倡对仪表盘以及数据专业人员如何生成和传达有意义见解的更细致的看法:“改变我们的工作方式比采用新工具要困难得多。”

  • 生成推荐的全新方法。从电子商务网站到 Netflix,推荐系统多年来一直塑造着我们的在线体验。Amine Dadoun的新文章建议通过利用最新的知识图谱技术,来振兴这个广泛领域。

  • 退一步是最具创新性的解决方案。面对复杂的新项目,一些机器学习工程师可能急于尽快应用最先进的算法。正如Olga Chernytska在她的新系列文章开篇所解释的那样,他们真正应该做的是提前规划,以确保他们的解决方案既满足业务需求又符合技术要求。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由Jan Canty拍摄,来自Unsplash

  • 一些最有用的技能无法用代码行数来衡量。职位描述(以及招聘经理)通常倾向于可测量和易于评估的内容:X 年的这项技能,Y 年的那项技能。Abhi Sawhney的首篇 TDS 文章是对这种倾向的有益补救,突出了其他可以帮助你作为数据分析师脱颖而出的领域,从积极主动到同理心。

  • 是时候从“泰坦尼克号”上划走了。在竞争激烈的工作环境中,小细节可能会产生不同的影响——包括你作品集中的项目组合。Matt Chapman认为你应该把那些经过验证的数据集和过度分析留给其他求职者,并提供了几个你可以探索的有前景的方向。

这周我们还有一些阅读推荐,希望你们去看看!

  • 想要了解 ChatGPT 最近更新的隐私功能的动手概览,不要错过Andrea Valenzuela的最新文章。

  • 语言公平是大型语言模型的一个方面,这是从业者讨论不够充分的;幸运的是,Yennie Jun深入探讨了这个棘手的问题。

  • 为了成功地将意图传达给语言模型,Scott LundbergMarco Tulio Ribeiro坚称清晰语法的重要性。

  • 通过跟随Nazlı Alagöz的初学者友好指南,了解合成差分法的优缺点。

  • 我们很高兴启动了Paul Iusztin的新课程,该课程涉及设计、实施和部署机器学习系统,采用 MLOps 最佳实践。

感谢你支持我们的作者!如果你喜欢 TDS 上的文章,可以考虑成为 Medium 会员——它可以解锁我们的整个档案(以及 Medium 上的其他所有帖子)。

直到下一个变量,

TDS 编辑部

为什么以人为本的 AI 设计指南在制造业中使用时可能优雅地失败

原文:towardsdatascience.com/this-is-why-human-centred-ai-design-guidebooks-can-gracefully-fail-when-used-in-manufacturing-95ceae0aad21?source=collection_archive---------10-----------------------#2023-05-09

从一个使用案例中学习

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Yuji Yamamoto

·

关注 发表于 数据科学前沿 ·9 分钟阅读·2023 年 5 月 9 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 UX Indonesia 提供,来源于 Unsplash

我们看到在各个社区对以人为本的 AI(HAI)的关注日益增加。HAI 的基本理念是将人类和人性置于设计 AI 驱动应用程序的中心。HAI 设计寻求实现人类与 AI 的共生——AI 辅助人类任务而不是取代它们,人类通过提供反馈来改进 AI。

像 Google、Microsoft、IBM、Apple 等大科技公司重视 HAI 理念,并开发了自己的 HAI 设计方法,并公开分享作为指南。例如,Google 的 PAIR 研究团队提供的People+AI 指南展示了如何组织和促进一系列研讨会,在这些研讨会上,不同领域的专家共同设计 AI 应用的功能和用户界面。它还提供了一系列在 HAI 设计过程中需要解决的问题和指导,如“应用程序的用户价值是什么?”以及“如何向用户解释预测结果?”。该指南进一步提供了各种实际应用 HAI 设计的示例用例,以激发设计参与者的灵感。Microsoft 分享了一种名为“HAX 工具包”的 HAI 方法。它提供了 PowerPoint 和 Excel 格式的设计指南和工作簿,目的是与 PAIR 的指南类似。

这些 HAI 方法的本质是相似的;它们允许多领域的人参与设计过程,并通过将用户体验、设计思维和负责任的 AI 的理论与实践融入统一的设计框架,促进捕捉和转化人们的需求为应用设计。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ThisisEngineering RAEng拍摄,照片来自Unsplash

好的,现在我来谈谈制造业:)。你可能认为制造业是一个可以轻松自动化的领域,但事实并非如此!即使在许多现代工厂中,许多技术熟练的人员仍在工作,并在开发、运行和改进工厂操作中扮演重要角色。因此,创造人类与机器之间的和谐至关重要。

那么,在制造业中整合 AI 技术时,为什么不使用 HAI 方法呢?这正是我们——一个拥有 AI、制造和用户体验专业知识的研究团队——的想法。我们与一家大型跨国制造商合作,试图开发并实施一种用于制造过程中的异常检测的机器学习模型。该模型检测来自关键制造设备中安装的传感器设备的数据中的异常模式。该模型的原型已经存在。我们使用了《People+AI》指南来帮助公司的 AI 项目。选择这种方法是因为它似乎是最全面且结构良好的方法。我们通过为期一天的研讨会使用了这种 HAI 方法,参与者包括约十名公司成员,涵盖了研发工程师、工艺工程师、数据科学家、技术人员和精益六西格玛专家等不同角色。

那么,使用这种方法的结果如何呢?嗯,我不会说它完全失败,但也不特别成功。总体而言,这种方法未能有效应对设计 AI 驱动的工业过程应用时复杂多面的挑战。研讨会的组织者(我们)和参与者感到他们必须同时处理来自不同角度的太多问题,导致了认知过载,并且体验混乱无序。

但我们从中学到了很多!我们意识到这种方法根本不适合制造业背景,需要对方法进行重大重构,以应对我们遇到的挑战。考虑到 HAI 方法之间的相似性,我们认为如果使用其他 HAI 方法,结果不会有太大不同。

让我们分享一下我们对这种方法在制造业中优雅地失败的反思。几个因素导致了这种失败,但在本文中,我挑选了三个重要的因素。希望这篇文章对那些有兴趣在工业环境中使用 AI 的人无论你的专业是什么,都能带来一些启发。

1. 工作流设计不是该方法的一个组成部分:

目前,科技公司和其他企业的 HAI 方法似乎主要针对帮助设计单一用户使用的应用程序,例如面向消费者的手机应用。在这种使用情况下,人机交互通常通过用户的屏幕、手指、眼睛和耳朵进行。指南似乎在设计这种交互时表现良好,使设计师能够探索不同的用户场景和体验,找到自动化和用户控制之间的平衡,管理对 AI 能力的期望等等。

另一方面,工业设施中的 AI 服务背景可能非常复杂。我们可以设想在制造厂使用异常检测的案例。这个应用程序通过放置在车间地板上的监视器屏幕显示传感器设备的健康状态,并在检测到异常时发出警报。应用程序的第一手用户是操作员。当然,操作员与应用程序之间的交互很重要,但事情并不止于此。当操作员收到警报时应该做什么或想做什么?这个人是否希望通过应用程序的帮助深入分析情况?或者他或她是否应该咨询上级或技术人员进行进一步的分析和决策?是否应该立即联系设备供应商?适当的行动是否取决于异常的严重性?行动是否取决于这些人的技能和知识?需要多少利益相关者参与决策?他们需要什么信息?如何在这些参与者之间共享信息?

如你所见,在制造环境中,初始事件——在此例中是发出警报——通常会触发一系列复杂的动作链,这些动作可能涉及组织内部或外部的多个人员。我们称这系列动作为工作流。我们已经了解到,手指-眼睛-屏幕的交互很难在没有工作流设计的情况下进行设计。因此,同时考虑这些设计或至少在开发过程中较早规划工作流设计是至关重要的,因为它们紧密相连。

HAI 方法是否支持这一点?不,工作流设计部分没有。在案例公司的研讨会上,设计参与者很高兴创建了关于异常状态和其他相关信息在车间地板上应如何显示的不同纸质原型。然而,由于他们对工作流如何展开了解有限,他们很快对哪些原型适合实际使用感到不确定。车间地板上的警报只是工作流的一个触发器。可能还有更多场景触发其他工作流,如假阴性、假阳性、传感器退化、传感器升级等。在没有适当的方法论支持的情况下,想象所有这些场景及其相应的工作流需要参与者付出大量的认知努力。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由Cristina Gottardi拍摄,来自Unsplash

2. 设计指南和问题引发了大量额外的询问:

正如我们在本文介绍部分讨论的那样,PAIR 指南手册与其他 HAI 方法一样,提供了一套在应用设计过程中需要考虑的问题和指南。我可以在这里展示一些更多的例子;“如何建立适当的信任水平,以便用户不会对 AI 结果给予过多或过少的信任?”,“应用程序如何接受用户的反馈以改进应用程序的行为?”

这些问题或指导无疑对我们在设计过程中深入处理关键设计问题大有裨益。同时,解决这些问题需要广泛的假设思考,特别是对于行为具有概率性的 AI 驱动应用程序。在开发过程中,应用程序的具体行为并不总是明确的。对于较简单的交互,如移动电话应用,假设思考可能仍可管理。然而,在公司的研讨会上,假设思考很快发展到了我们无法处理的程度。

在研讨会开始时,除了参与者愿意在操作中使用异常检测模型外,几乎没有决定。我们遵循了指南手册建议的设计过程,设计指南和问题似乎对这个过程有所帮助。然而,研讨会的参与者很快对哪些问题和指南比其他问题和指南更重要以及问题应该回答的深度或细节感到不确定。这些问题也紧密相连。

因此,回答这些问题变成了大量的猜测工作。以一个设计问题为例——如何建立用户对应用程序的信任。许多因素可以影响这一点,但至少它依赖于预测结果如何呈现给用户。展示的设计可能会受到模型性能的影响。性能将受到在开发过程中尚未完全了解的生产阶段数据的影响。正如我们之前讨论的,结果展示还依赖于工作流程。

如你所见,一个设计问题会引发一系列其他相互关联的问题,这些问题很难一一回答。一个答案依赖于另一个答案,而另一个答案又依赖于另一个只能部分回答的答案……难怪参与者很快就感到困惑和不知所措。一位参与者在最后说:“好吧,我们现在知道前方有座巨大的山,但我们仍然不确定如何攀登它。”

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Luis Villasmil 提供,来源于 Unsplash

3. 整合收集信息的责任不明确:

HAI 方法帮助设计参与者生成设计 AI 驱动应用所需的大量信息。这些方法提供了各种工具,如创意卡片、设计问题、指南和工作簿,以协助生成和记录这些信息。

那么谁来整合所有这些信息呢?通过研讨会,显而易见,这个方法主要是从 UX 设计师的角度设计的,而设计师似乎是那个整合信息并将其转化为设计的人。

好吧,我们理解“以人为中心的 AI”这个短语在 HAI 方法中被强调,但它们对 UX 的偏向性较大。这种偏向可能不会在方法用于更简单的交互(如手机应用)时混淆人们。UX 设计师在设计这种应用的功能和界面方面经验丰富。

但是当这个方法用于工业过程,其中工作流设计是交互设计的关键和不可分割部分时情况如何?在这种多面向的使用案例中,UX 设计师是否仍应整合来自研讨会的信息?还是具有广泛和深入工业过程理解的项目负责人更适合这个任务?我们在没有明确理解这一问题的情况下开始了研讨会,这进一步使得研讨会(已经是一团糟!)变得复杂。

最终,从失败中学习并继续前进…

这三个因素已经足以使参与者感到不堪重负,并造成认知超负荷和混乱。我们只是带着对 HAI 方法在工业过程应用中的局限性不够了解的心态进入了研讨会。虽然这些方法为我们提供了坚实的基础,但我们发现需要进行重大修改以适应制造领域。

我们目前正在开发一种基于我们学习的新方法,并在公司进行测试。我们至少知道,工作流设计应该融入到这个方法中,并且该方法应该有效处理在设计过程中出现的一系列相互关联的“假设”问题。希望我们能在未来报告结果!! 😃.

本博文与我的同事 Kristian Sandström 和 Alvaro Aranda Munoz 一起撰写。谢谢!

关于状态保持机器学习、在线学习和智能机器学习模型再训练的思考

原文:towardsdatascience.com/thoughts-on-stateful-ml-online-learning-and-intelligent-ml-model-retraining-4e583728e8a1?source=collection_archive---------14-----------------------#2023-04-05

设计可扩展的在线和离线持续学习系统架构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Kyle Gallatin

·

关注 发表在 Towards Data Science ·6 min read·2023 年 4 月 5 日

自从我读了 Chip Huyen 的实时机器学习:挑战与解决方案后,我一直在思考生产环境中机器学习的未来。短反馈循环、实时特性以及能够在线学习的状态保持机器学习模型部署需要一种与我今天所用的无状态机器学习模型部署截然不同的系统架构。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我在墨西哥科苏梅尔思考有状态的机器学习——图片来自作者

过去几个月,我一直在进行非正式用户研究、白板讨论和临时开发,以探讨真正有状态的机器学习系统可能是什么样的。大部分内容都概述了我的思维过程,并且我继续深入这个领域,发现有趣且独特的架构挑战。

定义

有状态(或连续)学习 涉及到更新模型参数,而不是从头开始再训练,以便于:

  • 缩短训练时间

  • 节省成本

  • 更频繁地更新模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

无状态与有状态的再训练——来自Chip Huyen的许可

在线学习 涉及实时从真实样本中学习,以便于:

  • 提升模型性能和反应性

  • 缓解因漂移/过时导致的性能问题

目前,大多数行业中的学习都是离线进行的。

智能模型再训练 通常指的是使用某些性能指标自动再训练模型,而不是按照固定的时间表进行,以便于:

  • 降低成本而不牺牲性能

目前,大多数行业中的模型都是使用 DAG 按照时间表再训练的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自自动模型再训练指南的智能再训练架构——由 Arize AI 授权

为在线学习设计 MVP

在上一篇文章中,我尝试运用基础工程原理来创建一个极其简单的在线学习架构。我的第一个想法是——将有状态的在线学习架构建模为有状态的网页应用程序。通过将“模型”视作数据库(其中预测为读取,增量训练会话为写入),我认为可以简化设计过程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来自作者

在某种程度上,我确实做到了!通过使用在线学习库River,我构建了一个小型有状态的在线学习应用,这让我能够实时更新模型并提供预测。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Flask 应用程序在多个工作进程之间共享内存中的模型——图片来自作者

这种方法在编码时很酷很有趣——但在规模上存在一些根本性的问题:

  1. 无法横向扩展: 我们可以轻松地在单个应用程序的内存中共享一个模型——但这种方法在像 Kubernetes 这样的编排引擎中无法扩展到多个 pod。

  2. 混合应用职责: 我不知道(也不想成为第一个知道)关于尝试支持一个混合训练和服务的部署的注意事项。

  3. 预先引入复杂性: 在线学习是最积极主动的机器学习类型,但我们甚至还没有验证我们是否需要它。必须有一个更好的起点……

设计一种可扩展的架构

从现有标准开始——分布式模型训练。使用类似参数服务器的东西作为集中存储,同时多个工作者计算部分/分布式梯度……或其他什么……并在之后调整参数是相当常见的做法。

所以——我想尝试在实时模型服务部署的背景下思考这个问题,结果想出了最傻的架构。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一种没有意义的架构——作者提供的图片

分布式模型训练旨在加快训练过程。然而,在这种情况下,没有必要以分布式方式进行训练服务——保持训练去中心化会引入复杂性,并且在在线训练系统中没有实际用途。完全分开训练更有意义。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一种稍微有意义的架构——作者提供的图片

很好!有点。此时我不得不退后一步,因为我做了很多假设,可能有些过于前瞻性:

  1. 我们可能无法在接近实时的情况下获得真实情况。

  2. 持续在线训练可能不会比持续离线训练提供净收益,而且是一种过早的优化。

  3. 离线/在线学习也可能不是二元的——有些场景中我们可能需要/想要两者都具备!

一些合理的智能再训练、持续学习和在线学习架构

让我们从一个更简单的离线场景开始——我想使用某种机器学习可观察性系统,根据性能指标的退化自动再训练模型。在进行持续训练(且模型权重更新不会花费太长时间)的场景下,这在不显著影响业务的情况下是可行的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

智能再训练和持续在线学习——作者提供的图片

真棒——这是我今天画的第一个合理的东西!这个系统可能比无状态训练架构有更低的成本开销,并且对模型/数据的变化反应迅速。通过仅在需要时进行再训练,我们节省了大量的$,总体上也非常简单!

然而,这种架构有一个大问题……它远没有那么有趣!什么样的系统能兼具在线学习的所有反应性、连续学习的成本节约和在线学习的弹性呢?希望,像这样……

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

连续的在线学习 — 作者提供的图像

虽然还有很多细节我还没完全弄清楚,但这种架构有很多好处。它允许混合在线和离线学习(正如特征存储允许访问流式特征和离线计算的特征一样),对数据分布的变化或个别用户偏好(个性化系统(recsys))非常稳健,并且仍然允许我们集成 ML 可观测性(O11y)工具来不断测量数据分布和性能。

然而,尽管这可能是我迄今为止创建的最合理的图表,它仍然留有很多未解的问题:

  • 在在线系统中,我们如何/何时评估模型,以及使用什么数据?如果数据分布发生大幅变化,我们需要创建新的数据驱动方法和最佳实践,设计一个包含旧数据和最新数据的保留评估集。

  • 我们如何调和将训练过程分为批处理/离线和在线的 ML 模型?我们需要尝试新的技术和系统架构,以允许在像这样的系统中涉及大型 ML 模型的复杂计算操作。

  • 我们如何拉取/推送模型权重?按照一定的节奏?在某些事件中或根据某些指标的变化?这些架构决策中的每一个都可能对我们系统的性能产生重大影响——而且没有在线 A/B 测试或其他研究,将很难验证这些选择。

下一步

当然,我的下一步是开始构建这些东西,看看会发生什么。然而,我希望能从业内的任何人那里获得见解、想法和参与,以考虑一些前进的路径!

请通过 twitterLinkedIn 联系我,或报名参加我课程的下一期:Designing Production ML Systems this May

使用 NLP 进行线程总结

原文:towardsdatascience.com/thread-summarization-using-nlp-d5bed9bf0eb4

使用 POS 标记、NER 和情感分析进行抽取式总结

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Arun Jagota

·发表于 Towards Data Science ·13 分钟阅读·2023 年 1 月 7 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Holger 提供,来自 Pixabay

设想一个包含多个参与者的短信(或电子邮件)线程。下面是一个涉及两个人共同规划旅行的示例。每条消息之间由空行分隔。

Here is some lodging near Pismo beach: Cliffs Hotel, SeaCrest, 
Madonna Inn, Shell beach inn

Shell beach & Madonna - a bit pricey.

Check out Inn at the Pier.

Looks good.

What about food?

Coya Peruvian

Any seafood restaurants?

Ada's Fish House. Oyster Loft.

+1 on Oyster loft.

What about bars?

11 22, Boardroom

breweries?

Shell beach brewhouse

Check this lodge out: Wayfarer

Not close enough to where we are going.

反复的对话可能会产生大量的信息,尽管这些信息分散在不同的短信中。当这个线程在智能手机的短信应用上展开时,随着更多消息的持续流入,滚动浏览以保持跟进对话可能会是一个挑战。

如果有一个 NLP 机器人能够阅读线程中的所有消息,并将它们总结成一条新的消息,那岂不是很好?然后这条新消息可以作为新消息发布在同一个线程中。

本文解决了这个问题。

首先让我们观察这个线程中的重复模式,其中一些可能会推广到其他线程。

A 先生建议了一些特定的住宿地点。B 先生给出了一些意见,并建议了另一个地方。其中一人询问关于食物的问题。另一人回应了具体的餐馆。对话接着转到酒吧。提出了一些具体建议。随后是意见。接着是后续问题。然后是回应和意见。

NLP 方法

是否有现有的 NLP 方法适用于这个用例?从总体上看,有的。这被称为抽取式总结

让我们先从基本层面理解它。

The summary is represented as a suitable subset of the content in the text.

这种方法并不一定试图使总结具有可读性,而是旨在捕捉文本中的关键信息。

在深入了解抽取式总结之前,还有一种 NLP 总结方法叫做抽象式总结,值得考虑。

这种方法产生的总结是对原始文本的总结性改述。

提取式摘要似乎更适合我们的用例,因为我们的主要目标是创建一个线程文本的简化版本,并保留所有关键内容。不是改写。

此外,请注意,抽象摘要是一个更具挑战性的问题,因为它似乎涉及更深入的自然语言理解和生成。

在我们的设置中进行提取式摘要

让我们考虑以下基本方法,如[1]所述。

  1. 将文本标记化为句子。

  2. 将每个句子标记化为词语。

  3. 删除停用词。像isaanthetoforof这样的词,

  4. 以某种方式根据词频对每个句子的剩余文本进行评分。

在我们的线程设置中,我们将用“消息”替换“句子”。也就是说,将文本标记化为句子意味着将其标记化为消息。

这种方法在我们的线程中可能效果如何?

词语标记化确实有帮助。它有助于识别和删除停用词。

也就是说,稍后我们将看到一种不同的提取方法,完全避免删除停用词。

我们的线程已标记化

首先,我们将把线程标记化为消息序列,然后将每条消息标记化为词语序列。在 python 术语中,这只是一个列表的列表。

最重要的是,在这种表示中,我们没有保留发送特定消息的人的身份。

去除停用词的效果是否足够?

以下是去除停用词后的文本版本。在这样做时,我们必须决定什么是停用词,什么不是。我们遵循了常见的做法,这通常偏向保守。

要删除的停用词在/…/中标记。

Here /is/ some lodging near Pismo beach: Cliffs Hotel, SeaCrest, 
Madonna Inn, Shell beach inn. Shell beach & Madonna - /a/ bit pricey.
Check out Inn /at the/ Pier. Looks good. What about food? Coya Peruvian. 
Any seafood restaurants? Ada's Fish House. Oyster Loft. +1 on Oyster loft.
What about bars? 11 22, Boardroom breweries? Shell beach brewhouse 
Check this lodge out: Wayfarer Not close enough /to/ where we /are/ going.

斜体和粗体中的词是我们删除的停用词。显然,这帮助不大。此外,请注意,旅馆名称Inn at the Pier中的at the也被删除了。

朝着更好的解决方案

正如我们刚刚看到的,单独去除停用词是无效的。首先,它没有删除足够的词。其次,它有时会删除出现在实体名称中的停用词。

让我们更一般地考虑一下。如果有某种方法来确定哪些词应该删除,哪些词应该保留,那就太好了。有人可能会说,这不就是在重新描述问题吗?

是的。不过,以这种方式来看,打开了新的思维方式。

在我们的情况下,接下来我们介绍的自然语言处理方法——词性标注,将比单独去除停用词带来显著改善。事实上,它将消除对去除停用词的需求。

词性分析

一种广泛使用的自然语言处理方法是为文本中的每个词标记其词性类别。例如nounsverbsadjectives等。

那么我们为什么认为这会对我们的线程摘要需求有所帮助呢?这是因为我们认为一个词的词性将作为是否应该在摘要中保留该词的良好预测因素。我们期望删除动词、冠词和代词。我们期望保留名词。

让我们在示例中测试这个想法。

我们在parts-of-speech.info/上应用了词性标注服务于我们的线程文本。(所有消息被串联,消息边界以段落分隔符表示。)

下面是我们得到的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

颜色到词性标签的映射如下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

各种词的词性标签确实对总结很有用。我们希望保留所有名词,也许还包括形容词,因为四个中有两个携带明确的情感(价格,好)。

也就是说,虽然相对于仅仅去除停用词已有所改进,但仅仅基于词性标签的简单过滤可能还不够。原因如下。

首先,即使我们仅保留名词,仍然有太多的词语。

其次,就像我们在去除停用词时发生的情况一样,我们最终删除了旅馆名称Inn at the Pier中的at the。这不好。我们遮蔽了一个可能值得进一步研究的旅馆名称。

第三,形容词词性标签虽然提供了一些情感信号,但与情感的相关性并不足够强。

另一种方法

我们首先观察到,线程中的几乎所有显著信息都属于三种 NLP 类别之一:命名实体情感显著短语

如我们将很快看到的,能够区分这些将有助于改善我们的线程摘要器。

我们将从命名实体开始,因为这是该线程中的主要类别。

命名实体

在 NLP 中,任何短小的文本,通常是一到三个词,(i)是一个“事物”并且(ii)可以命名的,都称为命名实体。例子包括人名、国家名、餐厅名、酒店名等等。有关 NLP 中命名实体识别的详细帖子,请参见[2]。

拥有能够识别城市名称、餐厅名称和酒店名称的命名实体识别器,我们将能够更好地进行摘要。只要我们能够组装出足够丰富的城市名称、餐厅名称和酒店名称集合,就可以通过训练现成的命名实体识别器实现这一点。

下面是识别了上述命名实体并删除了其余文本后的摘要文本样式。我们还删除了段落分隔符,并在需要的地方添加了句号。(段落分隔符对摘要文本没有价值。)

Pismo beach: Cliffs Hotel, SeaCrest, Madonna Inn, Shell beach inn. Shell 
beach & Madonna - . Inn at the Pier. Coya Peruvian. Ada's Fish House. 
Oyster Loft. Oyster loft. Shell beach brewhouse. Wayfarer.

由于我们的文本摘要器进行命名实体识别,如果需要的话,我们可以利用这一点,通过标注命名实体来呈现摘要。像这样:

CITY: Pismo beach: 
HOTELS: Cliffs Hotel, SeaCrest, Madonna Inn, Shell beach inn. 
HOTELS: Shell beach & Madonna — . Inn at the Pier. 
RESTAURANTS: Coya Peruvian. Ada’s Fish House. Oyster Loft. Oyster loft. 
Shell beach brewhouse. 
HOTEL: Wayfarer.

还不错。不过,我不确定添加实体名称是否增加了价值,或者在这个线程中是否造成了杂乱。这确实告诉我们这是一种可能性。在较长的线程中,这可能效果更好。

不过,仍然有改进的空间。我们将改进分为以下几种类型,顺序不分先后。

  1. 牡蛎阁被提到两次。幸运的是,去重很容易(在这个具体的情况下),因为它已经被识别为一个命名实体。

  2. 情感没有被提取出来。例如看起来不错有点贵、+1 和离我们要去的地方不够近

  3. 显著短语,即标签,也没有被提取出来。具体而言,海鲜餐厅、酒吧、啤酒厂、旅馆(住宿)

关于 1)没有更多要说的。

情感

关于 2),这属于 NLP 情感分析的范畴。更具体地说,是基于方面的情感分析,即检测哪些情感适用于文本的哪些部分。与情感分类不同,情感分类是确定文本中的整体情感是积极、消极还是中性的任务。

详细的情感分析帖子请参见[3]。它详细介绍了基于方面的情感分析和情感分类,并提供了说明性例子。

话虽如此,在我们具体的讨论中,让我们尝试更好地理解我们真正需要什么,能够做出哪些假设,并考虑我们可能将它们推进多远。简而言之,让我们(i) 检查我们的具体用例,并(ii) 逐步推进。

首先,让我们将焦点缩小到我们想要提取的情感的消息和紧接在其后的消息。我们选择后者,因为消息中的情感可能在前一条消息中。我们已经在/…/中标注了携带情感的区域。

Here is some lodging near Pismo beach: Cliffs Hotel, SeaCrest, 
Madonna Inn, Shell beach inn. Shell beach & Madonna - /a bit pricey/.
Check out Inn at the Pier. /Looks good/.
…
Ada's Fish House. Oyster Loft.
/+1/ on Oyster loft.
…
Check this lodge out: Wayfarer. /Not close enough to where we are going/.

首先,让我们假设我们检测到了携带情感的术语。即使是基于词典的方法在这里也是一个很好的起点,尽管它的扩展性仍然是一个未解的问题。

我们的第一个想法是保持检测到的术语在总结中的位置不变。让我们看看最终结果是什么样的。与之前一样,携带情感的术语用/…/标记。

Pismo beach: Cliffs Hotel, SeaCrest, Madonna Inn, Shell beach inn. Shell 
beach & Madonna — /a bit pricey/. Inn at the Pier. /Looks good/. Coya 
Peruvian. Ada’s Fish House. Oyster Loft. /+1/ on Oyster loft. Shell beach 
brewhouse. Wayfarer. /Not close enough/

好的。

第一点,一个小点是,由于我们知道哪些文本块是携带情感的术语,我们可以将它们与实体视觉区分开来。这在/…/中有所说明。

第二点是我们可以更明确地将携带情感的术语与紧接其前的实体关联起来。当然,这样做有一定的风险。让我们看看结果会是什么样的。

Pismo beach: Cliffs Hotel, SeaCrest, Madonna Inn, Shell beach inn. 
Shell beach & Madonna — a bit pricey. Inn at the Pier (Looks good). 
Coya Peruvian. Ada’s Fish House. Oyster Loft (+1) on Oyster loft. 
Shell beach brewhouse. Wayfarer (Not close enough)

在这种情况下很好。

显著短语

现在让我们关注我们希望被检测并添加到总结中的显著短语。在我们的讨论中,这些是海鲜餐厅、酒吧、啤酒厂、旅馆(住宿)。再次,我们假设这些短语已被检测到,并查看包含它们的结果。这次我们用/…/标记检测到的显著短语。

lodging Pismo beach: Cliffs Hotel, SeaCrest, Madonna Inn, Shell beach inn. 
Shell beach & Madonna — a bit pricey. Inn at the Pier (Looks good). 
Coya Peruvian. /seafood restaurants/. Ada’s Fish House. Oyster Loft (+1) 
on Oyster loft. /bars/. /breweries/. Shell beach brewhouse. Wayfarer 
(Not close enough)

嗯。注入的显著短语没有像注入的情感那样增加太多价值。

差别在哪里?让我们分析一下。首先,添加情感丰富了总结,因为情感不能从周围的文本中预测。

在我们的线程中,检测到的突出的短语并没有提供太多信息。例如,读者可以看到接近住宿的实体是酒店,因此添加该词并不会丰富总结。同样的观点也适用于海鲜餐馆酒吧酿酒厂

用数据科学的语言,我们可以说,将情感添加到总结中获得的信息比添加突出的短语获得的信息要高。

第二点是,在文本消息的线程设置中,情感通常会集中在刚刚提到的实体上,无论是在同一消息中还是在之前的消息中。相比之下,突出的短语更为开放。在我们的线程中,突出的短语出现在问题中,这些问题的答案稍后会出现,可能会分散在不同的位置。

第三点是从读者的角度来看这些总结。这些读者通常是线程中的一些参与者。他们对线程中特定实体的其他人的情感将对他们很重要。

话虽如此,问题并非非黑即白,因为可以认为添加突出的短语确实增加了一些信息。考虑海鲜餐馆。我们现在知道对话中的某人对海鲜餐馆感兴趣。如果其他人对此建议有情感反馈,那么这一短语所传递的信息只会增加。

话虽如此,我们仍然可以说,相对而言,命名实体和情感比突出的短语更值得保留在总结中。我们可以这样做:最初保留突出的短语,但如果总结变得过长,则将其删除。

回顾

现在让我们回顾并反思 POS 标记与命名实体识别、情感分析和突出的短语提取的组合。

单独去除停用词非常粗略。根据词性决定去除哪些词和保留哪些词则更细致。用命名实体识别、情感分析和突出的短语提取的组合替代 POS 分析则更为精细。

因此,随着我们从最简单的方法进展到最复杂的方法,总结的质量会提高。当然,工作量也会增加。对于第三种方法,我们需要使用或训练合适的命名实体识别器。此外,还需要使用情感分析器,并可能进一步改进它。识别突出的短语是另一个问题。我们在本文中没有深入探讨这一点,因为在某个阶段,保留这些短语在总结中的理由减弱了。

出版后的更新

在我们示例中的线程中,一个之前遗漏的反复出现的主题是讨论各个相关人员的工作时间。

在我们的线程示例中,让我们将下面的内容作为前几个消息添加进去。

What days work for you all? For me, April 1011, 1718, or May 2122 work.

None of these work for me. How about April 23?

...

Yup, Apr 23 works.

上述的“…”是一个指示,表示在两个包夹消息之间还有其他消息。

现在让我们致力于将上述消息中的关键信息整合到我们的总结中。

首先,我们希望扩展我们的命名实体识别器以识别日期。下面是相同的消息,我们希望识别为日期的部分已用粗体标出。

大家都能工作哪些天?对我来说,4 月 10–11 日17–18 日5 月 21–22 日都可以。这些日期对我来说都不行。4 月 2–3 日怎么样?是的,4 月 2–3 日可以。

识别日期实体在上述消息中并不难。字典基础、序列基础和模式基础机制的混合将是一个有效的开始,并可以随着时间的推移进行优化。

例如,模式<month> <num>-<num>将捕捉到上述一些日期。<month>来自字典,包括模糊条目如Apr,<num>可以通过正则表达式匹配一位或两位数字。

这将无法检测到17–184 月 10–11 日、17–18 日或 5 月 21–22 日中是一个日期。

将日期作为命名实体检测也提出了以下想法。我们可以将那些检测到日期实体的消息归入总结的一个单独部分,我们可以恰当地称之为日期

下面是一个增强了这些信息的总结版本。

Pismo beach: Cliffs Hotel, SeaCrest, Madonna Inn, Shell beach inn. Shell 
beach & Madonna - a bit pricey. Inn at the Pier (Looks good). Coya 
Peruvian. Ada's Fish House. Oyster Loft (+1) on Oyster loft. Shell beach 
brewhouse. Wayfarer (Not close enough)

Dates: For me, April 1011, 1718, or May 2122 work. None of these work 
for me. How about April 23? Yup, Apr 23 works.

如果我们能够推断出4 月 2 日3 日适用于每个人,那就更好了。我们在这里不会追求这一点。

总结

在这篇文章中,我们讨论了构建一个总结文本消息的问题,该消息概述了特定对话线程中各个消息的内容。

我们取了一个现实的例子,并讨论了一些可能在这里有用的 NLP 方法。

我们观察到,去除停用词并基于词频评分是不够的。

从这里,我们进展到了使用文本中各种词汇的词性信息。这效果更好,但仍不够理想。

从这里我们进展到了使用命名实体识别和情感分析。在我们的线程中,这效果相当好,因为该线程充满了命名实体。我们能够识别这些命名实体并将其纳入总结中,并附上相关的情感。

最后,虽然我们看到命名实体及其附带的情感对于检测和添加到总结中是至关重要的,至少在我们的线程中,将此扩展到检测额外的显著短语并将其添加到总结中的价值较小。我们也解释了原因。

参考文献

  1. 使用 NLTK 在 Python 中进行提取式文本摘要

  2. NLP 中的命名实体识别。实际用例、模型、方法……

  3. NLP 中的文本情感分析。问题、用例和方法

用两行代码将你的 Python 程序多线程

原文:towardsdatascience.com/thread-your-python-program-with-two-lines-of-code-3b474407dbb8

通过同时做多件事来加速你的程序

Mike Huls 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Mike Huls

·发表于Towards Data Science ·阅读时间 8 分钟·2023 年 1 月 10 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

更好地组织我们的线程(图片来自Karen PenrozUnsplash

当你的程序有很多涉及等待的任务时,你可以通过同时执行这些任务来加速程序,而不是一个一个地处理。比如在做早餐时,你不会等咖啡机完成后再煮鸡蛋。相反,你会启动咖啡机,同时给自己倒一杯橙汁,并加热平底锅以煎炒鸡蛋。

这篇文章向你展示如何做到这一点。最后你将能够安全地在两行代码中应用线程,并在程序中实现巨大的加速。让我们开始编程吧!

但首先……

本文将详细介绍如何通过对整列表参数应用相同的函数来应用线程。然后我们将查看如何以线程方式应用不同的函数。

[## Cython 入门:两步实现 30 倍速度提升

轻松的 Python 代码编译,打造飞快的应用程序

前往数据科学的文章链接

线程能解决我的问题吗?理解并发

确实在许多情况下,通过“同时做多件事”可以加速你的程序,但盲目地在各处应用线程并不是一个明智的解决方案。在 Python 中有两种多任务处理的方法:多进程和线程:

  • 线程并发方式运行代码:我们有一个活跃的 CPU,它在多个线程之间快速切换

  • 多进程并行的方式运行代码:我们有多个活动的 CPU 每个都运行自己的代码(请查看下面的文章)

## Applying Python multiprocessing in 2 lines of code

何时以及如何使用多个核心以更快地执行多次任务

## Applying Python multiprocessing in 2 lines of code

在线程处理时,你有一个执行所有任务的角色,通过在任务之间切换来同时完成它们。在早餐示例的上下文中:有一个角色(你)在咖啡机、锅和橙汁杯之间切换。

在多进程中,你激活多个任务,每个任务都被分配一个任务。在早餐的类比中,这就像把自己克隆两次,并给每个克隆分配一个单独的任务。虽然它比一个一个地运行任务要快得多,但多进程有更多的开销;克隆自己是一项很大的工作,只是为了让克隆在等待锅加热!

简而言之:多进程在需要计算大量数据时是最佳解决方案,线程则更适合需要等待的情况。

在这篇文章中,我们将专注于线程处理;如果你对多进程感兴趣,请查看下面的文章:

## Multi-tasking in Python: Speed up your program 10x by executing things simultaneously

逐步指南,以应用线程和进程来加速你的代码

## Multi-tasking in Python: Speed up your program 10x by executing things simultaneously

设置

对于这篇文章,我们假设一个旅行程序接收到一个需要验证的大型电子邮件地址列表。假设我们设置了一个 API,可以发送一个电子邮件地址,并根据电子邮件地址的有效性返回真/假。

最重要的是,我们需要发送请求并等待 API 响应。这是一个典型的可以多线程处理的任务:我们不需要额外的核心来加速计算;我们只需要一些额外的线程来同时发送多个电子邮件地址。

对于这篇文章,我们将使用这个电子邮件地址列表:

email_addresses = [
  'mikehuls42@gmail.com',
  'mike@mikehuls.com',
  'johndoe@some_email.com',
  'obviously_wrong@address',
  'otheraddress.com',
  'thisis@@wrong.too',
  'thisone_is@valid.com'
]

这将是我们的函数,它模拟将电子邮件地址发送到验证 API:

def send_email_address_to_validation_api(email_address:str):
  # We'll simulate the request to the validation API by just sleeping between 1 and 2 seconds
  sleep_time = random.random() + 1
  time.sleep(sleep_time)
  # Randomly return a true / false depending on the sleep_time
  return sleep_time > 1.5

## Docker for absolute beginners: the difference between an image and a container

了解 Docker 镜像和容器的区别 + 实用代码示例

towardsdatascience.com](/docker-for-absolute-beginners-the-difference-between-an-image-and-a-container-7e07d4c0c01d?source=post_page-----3b474407dbb8--------------------------------)

A. 非线程

首先,我们来看一下在不使用线程的情况下如何使用这个函数。

遍历电子邮件地址

我们将遍历我们的 7 个电子邮件地址列表,将每个值发送到 API;简单明了:

for email_address in email_addresses:
  is_valid = send_email_address_to_validation_api(email_address=email_address)
  # do other stuff with the email address and validity

这很容易理解,但它快吗?(剧透:不快)。由于我们依次验证每个 7 个电子邮件地址,每个地址需要 1 到 2 秒,因此总共需要 7 到 14 秒。我测得的时间是11.772 秒

## 用 OpenCV 摧毁《鸭子猎人》 — 初学者的图像分析

编写代码以打破每一个《鸭子猎人》的高分

towardsdatascience.com

使用映射函数

为了更好地理解下一部分,我们将使用 Python 的map函数重写上面的代码:

results: [bool] = map(send_email_address_to_validation_api, email_addresses)

上面的代码完全一样;它将函数映射到地址列表,这意味着它对email_addresses列表中的每个值执行该函数。

让我们将时间添加到基准测试中:

NON THREADED           11.772 secs

## 为什么 Python 如此慢以及如何加快速度

检查一下 Python 的瓶颈在哪里

towardsdatascience.com

B. 使用线程

在这一部分,我们检查 3 种不同的将线程应用到我们函数的方法。所有这些方法都使用线程池,可以通过以下方式导入:

from multiprocessing.pool import ThreadPool

将线程池视为等待任务的线程集合。线程池具有一个map函数,我们可以像在上面的非线程示例中一样使用它。一旦线程完成任务,它会返回到线程池中,等待另一个任务。

线程池允许我们通过提供对线程池中线程数量的限制,轻松且安全地使用线程

## Python 到 SQL — 安全、简单且快速的 UPSERT

使用 Python 进行闪电般快速的插入和/或更新

towardsdatascience.com

1. 线程池映射

我们将首先切换到线程池提供的map函数。

with ThreadPool(processes=10) as t_pool:
  results = t_pool.map(send_email_address_to_validation_api, email_addresses)

我们定义了一个最大进程数为 10 的线程池。由于这个原因,map 函数会同时启动所有对函数的调用。一旦所有工作线程完成,我们就可以评估结果,在这种情况下是1.901 秒

NON THREADED           11.772 secs
THREADED MAP            1.901 secs

## 创建并发布自己的 Python 包

关于如何使用 pip 安装你自制包的简短而简单的指南

towardsdatascience.com

2. 线程池 imap

在之前的示例中,我们不得不等待所有函数调用完成。如果我们使用 imap 而不是 map,情况就不同了。imap 函数返回一个迭代器,我们可以在结果可用时立即访问:

strt_time_t_imap = time.perf_counter()
with ThreadPool(processes=10) as t_pool:
  for res in t_pool.imap(send_email_address_to_validation_api, email_addresses):
    print(time.perf_counter() - strt_time_t_imap, 'seconds')

上述代码几乎完全相同。唯一的区别是添加了一些计时代码。此外,我们显然在第 3 行的 t_pool 上使用了 imap 函数。

如果我们查看打印结果,我们会看到:

1.4051628 seconds
1.4051628 seconds
1.7985222 seconds
1.7985749 seconds
1.7985749 seconds
1.7985957 seconds
1.7986305 seconds

imap 函数返回一个迭代器,我们可以在结果完成后立即访问。不过,这些结果是按顺序返回的。这意味着例如第二个电子邮件地址必须等待第一个;如果第二个电子邮件地址在 1.3 秒内完成,第一个电子邮件地址在 1.4 秒内完成;两者都在 1.4 秒后返回(正如你在上面的打印输出中看到的)。

尽管验证完整的电子邮件地址列表所需的时间与之前的示例大致相同,但我们可以更快地获取结果!第一个结果在1.4 秒后即可访问!

NON THREADED           11.772 secs
THREADED MAP            1.901 secs
THREADED IMAP           1.901 secs(first result accessible after 1.4  secs)

[## 针对绝对初学者的虚拟环境——什么是它以及如何创建一个(+ 示例)

深入了解 Python 虚拟环境、pip 和避免复杂的依赖关系

mikehuls.medium.com](https://mikehuls.medium.com/virtual-environments-for-absolute-beginners-what-is-it-and-how-to-create-one-examples-a48da8982d4b?source=post_page-----3b474407dbb8--------------------------------)

3. 线程池 imap_unordered

另一个改进:我们将返回无序的迭代器,而不是按顺序返回:

strt_time_t_imap = time.perf_counter()
with ThreadPool(processes=10) as t_pool:
  for res in t_pool.imap_unordered(send_email_address_to_validation_api, email_addresses):
    print(time.perf_counter() - strt_time_t_imap, res)

使用上述代码,我们可以在结果可用时立即访问。你也可以在打印输出中看到这一点:

1.0979514 seconds
1.2382307 seconds
1.3781070 seconds
1.4730333 seconds
1.7439070 seconds
1.7909826 seconds
1.9953354 seconds

最后的电子邮件地址可能在1.09 秒内完成并最先返回。这非常方便。

NON THREADED           11.772 secs
THREADED MAP            1.901 secs
THREADED IMAP           1.901 secs(first result accessible after 1.4  secs)
THREADED IMAP_UNORDERED 1.901 secs(first result accessible after 1.09 secs)

## 创建一个快速自动文档生成、可维护且易于使用的 Python API,只需 5 行代码

非经验丰富的开发者只需一个完整、有效、快速且安全的 API,这非常适合他们。

[towardsdatascience.com

4. 不同的函数

在前面的例子中,我们探讨了如何以线程方式应用相同的函数,但如果我们有多个函数呢?在下面的示例中,我们模拟加载一个网页。我们有不同的函数用于加载横幅、广告、帖子以及当然,还有吸引点击的内容:

def load_ad():
    time.sleep(1)
    return "ad loaded"
def load_clickbait():
    time.sleep(1.5)
    return "clickbait loaded"def load_banner():
    time.sleep(2)
    return "banner loaded"def load_posts():
    time.sleep(3)
    return "posts loaded"

如果我们顺序运行这些函数,我们的程序将需要大约 7.5 秒。我们可以通过稍微调整来使用线程池及其 mapimapimap_unordered 函数。请参见下面的 imap_unordered 示例:

with ThreadPool(processes=4) as t_pool:  # limit to 4 processes as we only need to execute 
  results = t_pool.imap_unordered(lambda x: x(), [load_ad, load_posts, load_banner, load_clickbait])

如你所见,我们将函数列表映射到一个 lambda 函数。函数列表由 lambda 函数执行(x 是每个函数的占位符,x() 将执行它)。以这种方式执行,渲染网页仅需 3.013 秒

## Git 入门:通过视频游戏了解 Git

对如何使用 git 的经典 RPG 类比获得直观的理解

[towardsdatascience.com

结论

使用线程池进行多线程处理是安全且易于应用的。总结:multiprocessing 库的 Pool 对象提供了三个函数。map 是 Python 内置 map 的并发版本。imap 函数返回一个有序迭代器,访问结果是阻塞的。imap_unordered 函数返回一个无序迭代器,使得可以在每个结果完成后立即访问,而无需等待另一个函数先完成。

我希望这篇文章的解释清晰明了,但如果不是,请告诉我我可以做什么进一步澄清。同时,查看我 其他文章,涉及各种编程相关主题:

编程愉快!

— Mike

附言:喜欢我做的事吗? 关注我!

[## 使用我的推荐链接加入 Medium — Mike Huls

阅读 Mike Huls 的每一个故事(以及 Medium 上其他成千上万位作家的故事)。你的会员费用直接支持 Mike…

mikehuls.medium.com

在生产中部署生成模型的三大挑战

原文:towardsdatascience.com/three-challenges-in-deploying-generative-models-in-production-8e4c0fcf63c3?source=collection_archive---------5-----------------------#2023-08-07

如何将大型语言模型和扩散模型部署到你的产品中,而不让用户感到恐惧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Aliaksei Mikhailiuk

·

关注 发表于 数据科学前沿 · 9 分钟阅读 · 2023 年 8 月 7 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者在 SDXL 1.0 中生成。

OpenAIGoogleMicrosoftMidjourneyStabilityAICharacterAI等公司——每个人都在竞相提供最佳的文本到文本、文本到图像、图像到图像和图像到文本模型解决方案。

原因很简单——这一领域提供了广阔的机会;毕竟,它不仅仅是娱乐,还有以前无法解锁的实用功能。从更好的搜索引擎到更令人印象深刻的个性化广告活动和友好的聊天机器人,如Snap 的 MyAI

尽管这一领域非常动态,许多模型检查点每天都在发布,但每个从事生成式 AI 的公司都在寻找解决方案来应对挑战。

在这里,我将讨论在生产中部署生成模型的主要挑战以及如何解决这些挑战。尽管有许多不同类型的生成模型,在这篇文章中,我将重点讨论最近在扩散模型和基于 GPT 的模型中的进展。然而,许多讨论的话题也适用于其他模型。

什么是生成式 AI?

生成式 AI 广泛描述了一组可以生成新内容的模型。广泛知名的生成对抗网络通过学习真实数据的分布,并从添加的噪声中生成变异来实现这一点。

近期生成式 AI 的繁荣源于模型在大规模上达到了人类水平的质量。解锁这一转变的原因很简单——我们现在只有足够的计算能力(因此是NVIDIA 股价飙升)来训练和维护足够容量的模型,以实现高质量的结果。当前的进步由两种基础架构驱动——变换器和扩散模型。

也许最近一年最重要的突破是 OpenAI 的 ChatGPT——一个基于文本的生成模型,最新的 ChatGPT-3.5 版本有 1750 亿个参数,具有足够的知识库来维持各种话题的对话。虽然 ChatGPT 是一个单模态模型,因为它只能支持文本,但多模态模型可以处理多种输入和输出,例如文本和图像。

图像到文本和文本到图像的多模态架构在一个由文本和图像概念共享的潜在空间中操作。通过在需要两个概念的任务(例如,图像标注)上训练来获得潜在空间,通过惩罚同一概念在两个不同模态中的潜在空间距离。一旦获得了这个潜在空间,它可以用于其他任务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像到文本模型的示例。图片由作者提供。

今年发布的著名生成模型有DALL·E/Stable-Diffusion(文本到图像/图像到图像)和BLIP(图像到文本实现)。DALL·E 模型以提示或图像作为输入,提示生成图像作为响应,而基于 BLIP 的模型可以回答关于图像内容的问题。

挑战与解决方案

不幸的是,机器学习没有免费的午餐,大规模生成模型在生产部署时遇到了一些挑战——大小和延迟、偏差和公平性以及生成结果的质量。

模型大小和延迟

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型大小趋势。数据来自P. Villalobos。图片由作者提供

先进的 GenAI 模型非常庞大。例如,文本到文本的Meta 的 LLaMA模型范围在 7 亿到 65 亿参数之间,而 ChatGPT-3.5 有 1750 亿参数。这些数字是合理的——在简化的世界里,经验法则是模型越大,训练所用的数据越多,质量也越好。

尽管文本到图像模型较小,但仍显著大于其生成对抗网络的前身——Stable Diffusion 1.5 检查点略低于 10 亿参数(占用超过三 GB 的空间),而 DALL·E 2.0 有 35 亿参数。很少有 GPU 能够拥有足够的内存来维持这些模型,通常你需要一整套设备来维护一个大型模型,这可能很快变得非常昂贵,更不用说将这些模型部署到移动设备上。

生成模型需要时间来产生输出。对于某些模型,延迟是由于其大小——在多个 GPU 上传播信号通过数十亿个参数即使需要时间,而对于其他模型,则是由于生成高质量结果的迭代性质。扩散模型在默认配置下需要 50 步来生成图像,减少步数会降低输出图像的质量。

解决方案: 将模型缩小通常有助于提高其速度 — 提炼、压缩和量化 模型也会减少延迟。高通为此铺平了道路,通过将稳定扩散模型压缩到可以在移动设备上部署的程度。最近,稳定扩散(tiny 和 small)的小型、提炼和更快速版本已被发布

特定模型的优化也有助于加快推理速度 — 对于扩散模型;可以生成低分辨率的输出,然后进行放大,或使用更少的步骤和不同的调度器,因为有些模型在较少的步骤下效果最好,而其他模型在更多迭代下会生成更高质量的结果。例如,Snap 最近展示了八个步骤就足以 使用稳定扩散 1.5 创建高质量的结果,并在训练时采用了各种优化。

例如,使用 NVIDIAs tensorrttorch.compile 编译模型,可以在最小的工程努力下大幅减少延迟。

## 边缘 — 在移动设备上部署深度学习应用

在受限设备上打破效率和准确性权衡的技术

towardsdatascience.com

偏见、公平性和安全性

你是否尝试过破解 ChatGPT?许多人成功揭露了偏见和公平性问题,值得称赞的是 OpenAI 做得很好 解决这些问题。如果没有大规模的修复,聊天机器人可能会通过传播有害和不安全的思想和行为而造成现实世界的问题。

破坏模型的示例见政治;例如,ChatGPT拒绝创作关于特朗普的诗歌,但会创作关于拜登的诗歌,特别是性别平等和职业——暗示某些职业适合男性,某些适合女性以及种族

与文本到文本模型类似,文本到图像和图像到文本模型也存在偏见和公平性问题。Stable Diffusion 2.1模型在生成医生和护士的图像时,通常生成的是白人男性作为医生和白人女性作为护士。有趣的是,偏见会根据提示中指定的国家而有所不同——例如,日本医生或巴西护士。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

询问 Stable Diffusion 模型生成一位医生和一位护士的图像。图片由作者使用SD 2.1 接口生成。

玩弄BLIP 图像到文本模型,将一张超重人士和男女医生的图片输入时,我得到了一些带有评判和偏见的图像描述——“一个胖男人”,“一个男性医生”,“一位穿着实验室大褂、带着听诊器的女性”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者使用 Stable Diffusion 2.1 生成,描述由 BLIP 模型生成,依次为[1]一个胖男人吃冰淇淋;[2]一位穿着白大褂和领带的男性医生;[3]一位穿着白色实验室大褂、脖子上挂着听诊器的女性。图片由作者使用SD 2.1 接口生成,并通过BLIP处理。

如何测试这个问题: 这是一个相当难以诊断的问题——在许多情况下,你需要知道要查找什么。拥有一个包含各种提示的独立基准数据集,其中可能会出现问题的情况、模板响应和我们将检测的每个答案的警告标志,以及来自不同背景和多个场景的人类数据集,存储关于图像中人物的所有可能属性,将会有所帮助。这些数据集需要包含数十万条记录,以获得可靠的统计数据。

**解决方案:**几乎所有的偏见、公平性和安全性问题都源于训练数据。我喜欢这样的类比:AI 模型是人性的镜像,加剧了我们所有的偏见。在干净、公正的数据上训练会大大改善结果。然而,即使有了这些,模型仍然会出错。

结果后处理和过滤是另一个可能的解决方案;例如,Stable Diffusion 在包含裸露图像的数据上进行训练,配有 NSFW 内容检测器以捕捉潜在问题。类似的过滤器可以应用于文本到文本模型的输出。

输出质量、相关性和正确性

生成模型在解释用户请求时可以非常有创意,虽然最近的大规模模型达到了人类水平的质量,但对于每种使用情况,它们不会开箱即用,需要额外的调整和提示工程。

在早期阶段,图像到文本和文本到文本模型的质量评估相对简单——毕竟,相较于无意义的内容,改进是显而易见的。高质量生成模型开始展现出更难以察觉的行为;例如,文本到文本模型可能变得含糊其辞,自信地输出错误和过时的信息。

扩散模型在其他方面表现出输出缺陷。典型的图像基础模型问题包括几何破损、变异的解剖结构、提示与图像结果不匹配、图像传输中的肤色和性别不匹配。自动化美学和现实性评估滞后,典型的度量指标,如 FID,无法捕捉这些变化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从左到右:[1] 两个人拥抱;[2] 一个竖起大拇指的男人;[3] 一只狗在公园里跑步。一张由作者生成的来自Stable Diffusion 1.5的图像

如何测试问题: 测试生成模型的质量具有挑战性;毕竟,这些模型没有真实的标准——它们被设计用于提供新颖的输出。因此,到目前为止,没有一种度量标准能可靠地捕捉质量方面。最可靠的度量标准是人工评估。

与偏见和公平性评估一样,最好的方法是拥有一个大规模的提示和图像数据集来测试质量。随着文本到文本模型变得更加个性化并调整到每个用户,除了对话的连贯性、正确性和相关性,我们还希望评估它们记住关于对话的信息的能力。

解决方案: 许多质量问题可以归因于训练数据和模型的大小;它们可能还稍微有点小,不足以实现另一个质量飞跃(考虑 GPT-3.5 与 GPT-4)——当前的潜在空间是一个抽象概念,并不是为了存储精确信息而设计的。许多问题可以通过更好的提示工程解决——无论是文本到文本和文本到图像的提示增强,还是文本到图像模型的负面提示。

文本到图像和图像到图像的模型可以使用附加工具来提升质量——图像增强,无论是通过传统的深度学习方法还是基于扩散的细化器。像ControlNet这样的附加模块,与扩散架构正交,可以帮助对生成结果进行额外控制。针对特定应用进行微调的 Dreambooth 技术也有助于提升结果。调整额外参数,如调度器、CFG 和扩散步骤数,可能会大幅度影响质量。

总结

生成模型开启了新的应用范围,包括有趣的AI 镜头和商业用途,如更好的搜索引擎、共同助手和广告。同时,企业急于推出产品和消费者对新功能的兴奋,有时会使技术中的明显缺陷被忽视。

尽管有一种普遍的推动力,旨在通过发布大规模开源数据集、训练代码和评估结果来提高模型基准测试的透明度,但对大规模 AI 模型的严格监管也在不断推进。在理想的世界中,两者不会走向极端,而是相互促进,使 AI 更加安全和有趣。

喜欢这位作者?保持联系!

我是否遗漏了什么?请随时在LinkedInTwitter上留言、评论或直接给我发消息!

## 深度图像质量评估

深入探讨全参考图像质量评估。从主观图像质量实验到深度目标评估…

towardsdatascience.com ## 感知损失用于深度图像修复

从均方误差到 GAN——什么才是好的感知损失函数?

[towardsdatascience.com

本博客中的观点仅代表我个人,与 Snap 无关,也不代表 Snap 的立场。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值