TowardsDataScience 博客中文翻译 2021(一百八十五)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

计算机视觉:让我们给蘑菇分类

原文:https://towardsdatascience.com/computer-vision-lets-classify-mushrooms-6b3abe1561eb?source=collection_archive---------18-----------------------

实践教程

张量流进行图像分类

你有没有问过自己,在大自然中行走时,你会遇到哪种真菌?孩子们接触它安全吗?所以我想训练一个模型来识别蘑菇/真菌。这个想法就是用手机拍一张照片,问模特这是什么。很棒,不是吗?
所以,这就是我玩图像分类的心路历程。

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

照片由 KalineriUnsplash 上拍摄

定义问题:图像检测/图像分类

在我们开始之前,让我们澄清一些概念。计算机视觉是人工智能的一个有趣分支,它是一种教会模型在图像中寻找信息,从而理解视觉内容的艺术。当图像分类对人类来说相当简单时(猫、狗、汽车……),机器总是努力保持竞争力。这是我们人类小时候就学会的东西。父母/幼儿的一个常见游戏是重复物体和人的名字。所以对日常课来说很容易。计算机视觉走过了漫长的道路,现在通过深度学习,它已经和人类一样好,甚至在特定领域更好。例如,在医学放射学中,人工智能可以被训练来检测和分类肿瘤,并且通常比人类有更好的结果。

计算机视觉的第一步是图像检测。

图像检测是在给定的图像中找到图像中的特定对象,并返回其坐标/边界框。

图像分类是当你给出一个物体的图像,你的模型返回一个带有概率和置信度的类。因此,我们的模型应该首先检测对象,然后根据它所训练的类的类型对它们进行分类。为此,我们通常使用 CNN-卷积神经网络。什么是 CNN?

图像是像素的矩阵。要仅检测图像中的边缘,您需要乘以一个滤波器矩阵。这将使大多数像素为零/黑色,它将只显示你的边缘。更多详情请查看本页。CNN 是一系列的节点,每个节点都对图像进行过滤。这有助于模型从图像中学习特征,数学上称为向量。网络越深——层数和节点数最多——消耗的内存就越多。

图像识别就是你给模特一个有多个物体的图像。对于图像中的每个对象,该模型给出其边界框(对象检测)和具有置信度的类别预测。

我们这里的问题是多类分类/图像分类。

收集数据

为了训练一个模型,你需要好的标记数据,当我说好的标记数据时,它就像是你项目的第一块石头。如果你错了,那么所有进一步的努力都将是徒劳的。这对任何机器学习项目来说都是至关重要的一步。正如我们所说:“垃圾进来,垃圾出去”。想想看,就像你试图教一个孩子什么是蘑菇。如果你给他看不同的物体,每次都说“那是一个蘑菇”,你可以相当肯定,孩子会认为蘑菇是物体的通称。所以我们需要准确。对于这一步,您可以废弃 web 或找到可用的开放数据。

我尝试了 Kaggle 真菌数据集。这是一个非常好的数据集,有 1394 个可用的类在这里。我玩了一会儿,心想,这是图像识别的经典问题。应该不比人脸识别难。事实上,我不久前了解到,在中国最大的办公楼里,人脸识别被用来检查没有徽章的员工的身份。我印象非常深刻,我以为蘑菇也会如此,我可以从这些模型中转移学习,让我的新模型在 TensorFlow 库中施展魔法。你猜怎么着?

一点效果都没有。一张脸的共同特征对蘑菇来说几乎没有用处。我的第一批模特什么都没学到。我投入了如此多的时间,甚至一些眼泪,最终得知 1394 班的不平衡数据,并不容易。在这个数据集中,对于某些类,我们只有三幅图像。有时,我的模型在训练集上学习,并且做得很好,比如 86%的准确率,而当到达验证集时,我们下降到 20%。为什么?这是由于不平衡的数据集。该模型学习猜测具有最大数量图像的类。如果你给一个孩子看 300 次蘑菇,一次土豆,他肯定会比土豆更容易猜出蘑菇。对于这篇文章,我想重点讨论用 TensorFlow 进行图像分类。所以,我选择只处理 10 个类。我们拥有的类越多,模型就越难以区分它们。所以你必须收集更多的图像来学习更多的特征。对于这第一次尝试,我想保持简单,我希望它将是有效的。

让我们探讨如何使用 TensorFlow 构建一个端到端的图像分类项目。

让我们开始吧!

数据处理

Tensorflow 为我们提供了这个很棒的 API tf.data.dataset,您可以使用一行代码创建一个高效的数据集,其中包含多个经过优化的本地函数面板。我用下面的代码从本地下载的 images 目录中创建了我的数据集。
通常当我在玩一个新项目时,我更喜欢快速制作笔记本,但在这里我不能使用 image_dataset_from_directory 来创建我的 TensorFlow 数据集,所以我切换到 Pycharm。Jupyter 笔记本上还没有。那就 Pycharm 吧!

以下是我们将要学习的 10 个课程:

[’ 11082 _ Xerocomellus _ chrysenteron ‘,’ 12919_Cylindrobasidium_laeve ‘,’ 14064_Fomitopsis_pinicola ‘,’ 14160 _ 灵芝 _pfeifferi ‘,’ 17233 _ 菌丝体 _galericulata ‘,’ 20983_Trametes_versicolor ‘,’ 21143 _ 口蘑 _ 头皮菌’,’ 40392 _ 蜜环菌 _ 藤黄’,’ 40985 _ Byssomerulius _ 真皮层’,’ 6185

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

由我的代码生成的情节的图像

让我们设置数据集性能

迁移学习模式

我从创建自己的 CNN 开始,但它做得不是很好。我没有耐心去改善它,我选择了迁移学习。
迁移学习是指重新使用在更大数据集上训练的模型的能力,这些模型已经学习了多个特征。为此,我们冻结了顶层,并用新的课程进行再培训。许多已知的模型赢得了 imagenet 竞赛。砝码可以重复使用。所以让我们用这些预先训练好的模型来帮助自己。我使用 MobileNetV2 模型是因为它非常轻,它可以在几秒钟内在我的 GPU 上运行。

我增加的提高准确性的独特步骤是数据扩充。
数据扩充是:对于一个输入标签的图像,你对它进行缩放或翻转,将其作为输入添加到模型中。这有助于模型继续识别对象,即使它不总是在相同的位置。

这是结果

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

作者 MobileNetV2 的图片结果

它只对 10 个时期有效,并且只增加了数据。

现在让我们来预测—下面是我的代码。我在 Xerocomellus_chrysenteron 类的 mycodb web 数据集上拍摄了一张图片

这个模型说:

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

很好,不是吗?

结果上方的矩阵是预测的向量。端到端项目现已完成。下一步应该是提高准确性,并扩展到其余的类。这是我训练一个能够识别 1394 种真菌的模型的第一步。令人印象深刻的是,它在不太长的时间内就做得这么好。请继续关注我的更新!
快乐编码!

边缘的计算机视觉

原文:https://towardsdatascience.com/computer-vision-on-edge-b5adb5c6ccde?source=collection_archive---------16-----------------------

AIoT 的目标检测:边缘计算实例

几周前,当我在全球速卖通逛街时,我偶然发现了这个奇妙的装置。据称它将携带 RISC V 架构以及一个 KPU (KPU 是一个通用神经网络处理器)。电路板的对比规格如下:

  • CPU: RISC-V 双核 64 位,带 FPU
  • 图像识别:QVGA@60fps/VGA@30fps
  • 芯片功耗< 300mW

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

MaixDuino (Image from Sipeed

说实话,该单位是旧的,只是最近才注意到。鉴于我对边缘计算的兴趣,我想为一个对象检测示例提供一个完整的端到端指南。这个例子基于 Dimitry 的这篇文章中的知识。然而,我将全面介绍如何收集图像并对它们进行注释。如果你想知道什么是边缘计算,请阅读下面的文章。

https://medium.com/swlh/what-is-edge-computing-d27d15f843e

让我们尝试建立一个图像检测程序,将能够边界出苹果和香蕉。你可以创造性地使用你的探测器。我们将继续讨论所需的工具和库。

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

打开图像数据库(链接)

关于迁移学习的注记

迁移学习是指我们使用预先训练好的模型来进一步专业化。简而言之,您用自己的分类层(或更多层)替换训练模型的最后一个预测层。然后冻结除你之外的层(或者一些预先训练的层)。然后训练网络,以便使用预训练模型的功能来微调图层,从而预测所需的类。

不幸的是,目前我们将要训练的网络没有任何预先训练的模型。因此,我们将大部分时间在地面上训练。但这将是一个有趣的实验!

准备数据

我们需要准备以下格式的数据。首先,我们需要苹果和香蕉的图像。同时,我们需要对它们进行注释,说明每个水果在图像中的位置。这就是物体分类和检测的区别所在。我们需要说出物体的位置。为此,您需要以下工具。

https://github.com/tzutalin/labelImg

或者你可以使用我的工具,用你的背景和物体图像生成带注释的图像(例如:来自卡格尔的 Fruit 360 的图像)。在这里阅读更多;

https://anuradhawick.medium.com/annotator-for-object-detection-950fd799b651

在我的例子中,我使用下面的程序从网络摄像头捕捉。选择简单的方法。下面的程序是用 Nvidia jetson nano 入门容器编译的。

https://github.com/dusty-nv/camera-capture 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

捕捉图像(作者提供的图像)

数据集上的训练

我们想训练我们的模型,以便它们可以在 MaixDuino 设备上运行。为此,我们可以使用下面的存储库。它对模型层进行了所有必要的修改,以适应 K210 处理器的架构。克隆并安装所需的依赖项。以下链接提供了所有说明;

https://github.com/AIWintermuteAI/aXeleRate

我们需要如下组织我们的训练数据:

path-to/data
---anns      # store the training annotations
---imgs      # relevant images for the training
---anns_val  # validation annotations
---imgs_val  # validation images

现在我们需要创建一个 config.json 来设置训练选项。对于我们的例子,它应该如下所示;

{
    "model" : {
        "type":                 "Detector",
        "architecture":         "MobileNet7_5",
        "input_size":           [224,224],
        "anchors":              [0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, 9.77052, 9.16828],
        "labels":               ["Apple", "Banana"],
        "coord_scale" :  1.0,
        "class_scale" :  1.0,
        "object_scale" :  5.0,
        "no_object_scale" :  1.0
    },
    "weights" : {
        "full":     "",
        "backend":              "imagenet"
    },
    "train" : {
        "actual_epoch":         50,
        "train_image_folder":   "data/imgs",
        "train_annot_folder":   "data/anns",
        "train_times":          2,
        "valid_image_folder":   "data/imgs_val",
        "valid_annot_folder":   "data/anns_val",
        "valid_times":          2,
        "valid_metric":         "mAP",
        "batch_size":           4,
        "learning_rate":        1e-4,
        "saved_folder":     "obj_detector",
        "first_trainable_layer": "",
        "augumentation":  true,
        "is_only_detect" :   false
    },
    "converter" : {
        "type":       ["k210"]
    }
}

注意:使用绝对路径来避免不必要的错误。

接下来,我们可以使用以下命令进行训练;

python3 aXelerate/axelerate/traing.py -c config.json

现在训练完成了。我们对在项目文件夹中生成的 kmodel 文件感兴趣。我们可以将它移动到一个 microSD 卡上,并将其连接到 MaixDuino 设备上。

预言;预测;预告

以下是我将在 maixPy IDE 中使用的草图。

import sensor,image,lcd
import KPU as kpulcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((224, 224))
sensor.set_vflip(1)
sensor.run(1)classes = ["Apple", "Banana"]
task = kpu.load("/sd/name_of_the_model_file.kmodel")
a = kpu.set_outputs(task, 0, 7, 7, 35)anchor = (0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, 9.77052, 9.16828)
a = kpu.init_yolo2(task, 0.3, 0.3, 5, anchor) while(True):
    img = sensor.snapshot().rotation_corr(z_rotation=90.0)
    a = img.pix_to_ai()
    code = kpu.run_yolo2(task, img)

    if code:
        for i in code:
            a = img.draw_rectangle(i.rect(),color = (0, 255, 0))
            a = img.draw_string(i.x(),i.y(), classes[i.classid()],
                color=(255,0,0), scale=3)
            a = lcd.display(img)
    else:
        a = lcd.display(img)a = kpu.deinit(task)

确保改变输出参数,以适应kpu.set_outputs(task, 0, 7, 7, 35)中训练好的神经网络。现在你已经准备好运行程序了。这很容易。看看下面的截图。

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

作者提供的图片

注意质量很低。这是因为 maixPy IDE 允许我们将 LCD 显示流式传输到计算机。所以质量比较少。

该图像检测程序可以在 300 毫安的电流下运行。此外,它有类似于 Arduino nano 板的 GPIO 引脚。所以可能性是很多的。然而,用 python 编程也是一大解脱。

我希望这篇文章能让您对数据科学有一个新的认识。快乐阅读!

干杯。

计算机视觉传感器和系统

原文:https://towardsdatascience.com/computer-vision-sensors-systems-bdc079847316?source=collection_archive---------30-----------------------

捕捉和诠释光的旅程。

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

布鲁诺·伊曼纽尔在 Unsplash 上拍摄的照片

从硬件到支持计算机视觉的系统,这篇文章是一个广度优先于深度的综述。为了平衡这种方法,本文将读者引向指导性的参考资料,并提供了现成的源代码。我们从图像形成的机制开始。我们涵盖针孔,镜头,传感器(CCD 和 CMOS),拜耳过滤器,和颜色重建。

然后,我们转向应用计算机视觉来检测图像和图片中的道路车道。第一种方法基于一组常用的计算机视觉算法。我们涵盖了 Canny 边缘检测,高斯模糊,感兴趣的区域,和霍夫变换。第二种方法在空间卷积神经网络上运行推理,以检测图像和视频输入上的道路车道。

成像简史

暗箱图像的美是无法用语言表达的。绘画艺术已经死亡,因为这就是生活本身:或者更高级的东西,如果我们能找到一个词来形容它的话。
——康斯坦丁·惠更斯私人信件,1622 年 4 月 13 日

拍照是将 3D 场景投影到 2D 平面上。暗箱通过针孔实现了这种投影。墙上的一个小针孔可以让光线穿透照相机的暗室。这种简单的机制产生了清晰的投影,让艺术家们可以在场景上勾画出精细的细节。但是这种方法在亮度方面有所欠缺,针孔本身不能收集足够的光。

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

在阿塔纳斯·珂雪的Ars Magna Lucis Et Umbrae(1645)中雕刻一个“便携式”暗箱

针孔摄像机甚至在今天也吸引了广泛的兴趣。他们能够捕捉到令人惊叹的图像,这些图像的特点是在任何地方都具有同等聚焦的视觉效果。缺点还是一样,图像暗淡,需要长时间曝光。

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

伊万·麦格雷戈,邓卢斯城堡的日落,用针孔相机拍摄,曝光时间为 20 分钟。

为了解决昏暗的问题,引入了透镜。通过在光圈前放置一个透镜,可以聚集更多的光。镜头也可以改变投影图像的放大倍数。在过去,放大需要艺术家移动整个相机。如今,在不改变场景和图像平面之间的距离的情况下,可以移动镜头的位置来调整放大效果。变焦是移动镜头来改变放大率的过程。

即使有了镜头,捕捉图像也要持续很长一段时间,依靠艺术家在投影图像上画图。十九世纪三十年代路易·达盖尔发明的胶卷是摄影史上最重要的发明之一。这是第一次有可能在物理层上记录光线,无需依靠艺术家,只需按下按钮就能记住某个时刻。

胶片上涂有卤化银。一旦暴露在光线下,卤化银就转化为金属银。转换的数量取决于胶片上任何特定点的曝光。为了产生图像,胶片随后通过照相显影的化学过程进行处理。

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

玛丽安娜·卡塞塔的黑白底片处理

硅图像探测器的发明甚至比胶片更有影响力。同一块芯片可以用来拍摄无限数量的照片,不再需要化学照相显影。这是数码相机使用的技术,也是今天我们大多数人在手机上使用的技术。

图像传感器

概括地说,拍照就是将 3D 场景投影到 2D 平面上。投影是由镜头辅助的光圈实现的,以收集更多的光并调整放大倍数。2D 平面首先是一个简单的表面,艺术家可以在上面绘画。它后来成为卤化银胶片的表面。最后,它现在是硅片的表面:一个图像传感器。

为了将接收到的光转换成数字图像,大多数图像传感器依赖于硅原子的特性。当具有足够能量的光子撞击硅原子时,它会释放电子。在硅晶格(像素)上,光子通量曝光产生电子通量。电子通量然后被转换成电压。

电荷耦合器件

在这种类型的图像传感器中,光子到电子的转换发生在每个像素中。在每个像素下面有一个电容器储存释放的电子。称为垂直 CCD 移位寄存器的电路连接在每列像素的电容器之间。该电路使得电子能够从一个像素垂直转移到其正下方的像素,直到它们到达最后一行。这最后一行由水平 CCD 移位寄存器连接,该移位寄存器将电子传送到模数转换器。

电荷耦合器件。作者 Gif。

电荷耦合器件中电子的垂直转移是用桶旅法完成的。这意味着每一行在获取前一行的电子之前,先将它的电子传递给下一行。水平转移保持了行的顺序,因为它们向 ADC 水平移动,在 ADC 中它们被转换成与其电子电荷成比例的电压。

互补金属氧化物半导体 CMOS

CMOS 以不同的方式实现图像传感器。它不是将电子从像素转移到 ADC,而是在像素级集成电压转换。

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

互补金属氧化物半导体。图片作者。

使用 CMOS,可以单独寻址每个像素以读取其电压。这提供了更大的灵活性,因为它能够更快地读取感兴趣的特定区域。由于在像素级集成了更多组件,灵活性是以更小的光敏区域为代价的。为了补偿光敏区域的减少,微透镜被放置在每个像素的正上方。这些微透镜将光线聚焦在光敏探测器上。

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

像素结构。图片作者。

捕捉颜色

像素本身能够捕捉光的强度,但不能捕捉光的波长。为了捕捉颜色(波长),最流行的方法是叠加一个拜耳滤光片阵列。在这种方法中,每个像素都覆盖有红色、绿色或蓝色的滤镜。

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

图像传感器像素阵列上滤色器的拜耳排列。每个 2×2 单元包含两个绿色、一个蓝色和一个红色过滤器。图片由科林 M.L 伯内特提供。

几乎所有颜色的人类感觉都可以用三种波长产生。捕捉红色、绿色和蓝色波长足以再现被拍摄场景的真实颜色。但是仅仅覆盖拜耳模式是不够的。它会产生看起来像左边的图像:

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

(左)拜耳模式。(右)插值重建的图片。作者图片。

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

(左)放大的拜耳模式。(右)通过插值放大的重建图片。作者图片。

左侧图像的像素全部是红色、绿色或蓝色。请注意,图像看起来大部分是绿色的。拜耳模式模拟了人类视网膜在白天对绿光最敏感的事实。因此,过滤器是一半绿色,四分之一红色,四分之一蓝色。

为了将左边的图像转换为右边的图像,我们获取每个像素的值,并将其与其相邻像素的值相结合。这个过程叫做插值。假设我们从左边的图片中取一个蓝色像素。插值是将蓝色值与相邻像素的红色和绿色值混合。

为了实验光混合是如何工作的,这里有一个很好的模拟。要了解它与油漆颜色混合的不同,这里有另一个好链接

计算机视觉

图像传感器的应用已经成为我们生活中的基础。它们塑造了我们表达自己和交流的方式,它们开辟了科学和艺术的跨学科领域。也许这些领域中最先进的是计算机视觉。

研究计算机视觉必须从对支持它的硬件的理解开始。我们简要介绍了硬件的历史、进步和主要组件。让我们看一个令人兴奋的实际应用程序,它利用了这一点。

自动驾驶汽车中的车道检测

自 2021 年 5 月以来,特斯拉开始交付不再配备雷达的 Model 3 和 Model Y 车辆。这些车型依靠基于摄像头的自动驾驶系统在相同的安全评级下提供相同的功能( 过渡到特斯拉视觉 ,2021)。

特斯拉 Vision 的主动安全功能包括车道偏离警告/避免。能够探测道路车道对驾驶至关重要。我们将着眼于车道检测,并以两种不同的方式实现它。首先使用计算机视觉算法,其次使用空间卷积神经网络。

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

(左)弗林克瑞的亚利桑那州,(右)维克 _ 醋的锡安国家公园。经所有者许可使用的图像。

第一步是检测图像中最突出的边缘。相邻像素与其亮度水平形成对比的区域被标记为边缘。以下代码将图像转换为灰度,使用高斯滤波器模糊以减少噪声,并应用算法 Canny 边缘检测

精明的边缘检测。

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

Canny 边缘检测后得到的图像。由作者处理的图像。由 Flinchcr 拍摄的原始(左)图像。原(右)图由Vic _ 醋拍摄。经所有者许可使用的图像。

这些图像充满了我们不需要的信息。我们希望专注于前方的道路,因此我们将定义一个感兴趣的多边形区域来裁剪每个图像。对于两幅图像,定义多边形的点会有所不同。为了找到它们,我们可以绘制图像并显示宽度和高度轴。

感兴趣的区域。

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

用于裁剪图像的多边形遮罩。作者图片。

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

由此产生的感兴趣区域。由作者处理的图像。由 Flinchcr 制作的原始(左)图像。原(右)图由Vic _ 醋提供。经所有者许可使用的图像。

观察由此产生的感兴趣区域,人眼可以容易地感知线条。那些线实际上是一系列像素,它们只是计算机的点。我们需要描绘两条最能描述这些点的排列的主线。这是使用霍夫变换算法完成的。

霍夫变换。

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

将蓝线添加到原始图片后的结果。由作者生成的图像。由 Flinchcr 拍摄的原始(左)图像。原(右)图由Vic _ 醋拍摄。经所有者许可使用的图像。

完整的实现包括我的 Colab 笔记本车道检测 OpenCV 的进一步改进和优化。

https://colab.research.google.com/drive/1sX5J1FDec9AUqxELuXfhBq6WLZ-FFssY?usp=sharing

这种方法可能看起来会产生很好的结果,但是这种实现远不是最佳的,因为:

  • 我们必须为每种情况明确定义感兴趣的区域。由于视角的变化,应用相同的多边形遮罩来裁剪 ROI 是不可能的。
  • 计算时间太慢,驾驶需要高处理速度。
  • 转弯涉及曲线车道,这种方法仅适用于直线车道。

让我们来看一个使用[空间 CNN 进行车道检测的替代方案](http://Spatial CNN for Traffic Lane Detection) ( 潘新刚 et all,2018)。在 Colab 笔记本上,我们首先创建一个到 Drive 帐户的链接。然后我们克隆项目存储库。

我们在项目的根目录下上传了三个文件:ERF net _ encoder _ pretrained . PTH . tarERF net _ baseline _ culane _ 2021 02 04 . ptERF net _ baseline _ tu simple _ 2021 04 24 . pt*。*然后我们安装以下依赖项:

我们可以通过以下命令使用图像运行推理:

我们可以通过以下命令使用视频运行推理,在这种情况下,图像路径对应于视频路径:

结果显示检测到的车道带有黑色虚线。Gif 与作者的车道检测。 Flinchcr 原创视频。经所有者许可使用的图像。

完整的实现包括 Git 存储库的克隆、依赖项的安装和推理代码都可以在我的 Colab 笔记本车道检测 SCNN 中找到。

https://colab.research.google.com/drive/1uBv9KQilCvEuAmTvpzQfhSNjN8gJHfY5#scrollTo=h8YWDFqFK6cH

承认

本文第一部分站在一个巨人的肩膀上, Shree K. Nayar 。这是计算机视觉基本原理课程第一课的总结。我计划发布更多的文章来传达我对这门课程的理解。我怀着深深的感激之情,感谢 Nayar 为让这样一个高质量的课程变得免费和容易获得所做的努力。

https://www.youtube.com/channel/UCf0WB91t8Ky6AuYcQV0CcLw/about

第二部分从获取完整的自动驾驶汽车路线以实现基于 OpenCV 的车道检测。这部分还依赖于 Pytorch 自动驾驶项目运行视频推理进行车道检测。

https://github.com/XingangPan/SCNN

计算机视觉——过滤的重要性

原文:https://towardsdatascience.com/computer-vision-the-importance-of-filtering-c0d9640c6e72?source=collection_archive---------33-----------------------

理解计算机视觉中过滤的基础知识

计算机视觉的核心是从图像或视频中提取最有意义的特征。这就是为什么理解“特征提取”过程的基础对于使用或创新最先进的计算机视觉解决方案极其有用。

要深入理解任何一个概念,首先要了解它的基础。在这种情况下,为了理解滤波在图像中的工作原理,我们首先需要回过头来分析它是如何应用于 1D 信号的。

信号过滤

考虑以下信号:

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

作者图片

信号处理中的一个基本概念是信号的叠加,将信号分解成更简单的成分。请记住,这个概念的全部目的是理解信号和系统 如何工作

通过将先前的信号分解成更简单的信号,我们获得以下分量:

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

作者图片

获得这些之后,我们可以分析它们是如何被系统单独影响的。此外,我们正在获取关于**系统如何响应脉冲的信息,也称为卷积。你是如果你看过这篇文章,可能对这个术语很熟悉;然而,知道你在执行卷积时实际在做什么,可能会在将来解决更复杂的问题时对你有所帮助。另一个你可能非常熟悉的术语是滤波器内核,**它只不过是系统的 i **脉冲响应。**这非常重要,因为如果我们知道系统如何响应脉冲,就可以根据任何给定的输入信号计算出其输出。

信号中的卷积运算遵循与图像中的卷积相同的过程:滤波器必须以给定的大小和步幅通过信号的总长度。下图说明了信号 x 与内核 h 的卷积。

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

作者图片

低通滤波与高通滤波

既然您已经了解了滤波的过程及其实际意义,那么能够区分低通和高通滤波也很重要。

  • 低通滤波—它可以被视为一种平滑滤波器,用于衰减高频并保留低频。您可以很容易地将它与其他过滤器区分开来,因为它只有正值(1 个方向)。

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

作者图片

  • 高通滤波 —与低通滤波相反,高通滤波用于衰减低频,保留高频。这个想法是突出信号中变化最大的部分。您可以很容易地将它们识别为高通,因为它们同时具有正值和负值(2 个方向)。

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

作者图片

当应用于信号时,分析这些类型的滤波器是极其重要的,因为这将为你深入理解它们对图像处理的多重影响奠定基础(2D)。

话虽如此,在这一点上,即使你不知道这两种类型的过滤器之间的差异,你已经可以开始理解它们在应用于图像时会产生的不同效果。

滤像

在提出 CNN(卷积神经网络)模型之前,需要手动提取图像的特征,然后将它们输入神经网络或任何其他类型的分类器。这些特征可能很简单,比如黑白像素的数量,也可能有点复杂,比如亮度、强度和能量。这尤其困难,因为除了尝试不同的特征组合和分析模型的性能表现之外,没有办法知道哪些特征对分类器最有意义;然而,这可能是一个非常耗时的过程。从个人经验来看,提取新的有意义的特征并不是一件容易的事情,有时会导致添加可能对模型性能产生负面影响的特征。为了从图像中获得更多独特的特征,通常对其应用过滤器,然后从结果图像中提取特征。 Gabor 滤波器(高通)通常用于检测图像的边缘,如下图所示。

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

作者图片

这就是 CNN 介入并完全改变特征提取过程的地方。如今,如果你有大量的数据,你不需要手动执行任何特征提取,因为模型会自己找到最有意义的特征。

当用老方法执行这个过程时,您必须尝试不同的特征组合来评估模型的性能。现在,CNN 模式也在做同样的事情,但更加严格、自动、规模更大。

话虽如此,任何神经网络模型的主要缺点之一是可解释性。如果一个卷积模型中有 4096 个过滤器,你根本不知道它们是什么意思,也不知道它们在提取哪些特征。你所知道的是,它们提取了非常好的特征,并且它们对于特定的问题是最有意义的。虽然这种方法可以完美地解决大量现实世界的问题,但是如果你想让你的解决方案有机会被政府、健康实体和许多更敏感的领域所接受,你的模型必须**能够解释它的决定。**人们宁愿拥有一个 70%准确并能解释其做出的每一个决定的模型,也不愿拥有一个 99%准确但不能给出任何解释的模型。

此外,本文中提到的两种类型的过滤器可以提取什么样的特征,应该给出更多的例子。

如果您考虑“信号”部分中每种滤镜类型的定义,同样的效果也适用于图像。一方面,低通滤波器具有所有正值,并且通常用于平滑图像或执行模糊。

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

平滑过滤器。作者图片

但是另一方面,高通滤波器通常用于执行边缘检测。如果你记得它的定义,高通滤波器保留高频。在图像中,它们会突出显示像素值差异较大的区域。

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

边缘检测滤波器。作者图片

结论

这篇文章的主要重点是阐明卷积运算的根源,解释它的意义,并提供一个关于什么是滤波器的更好的观点。在实际上没有信号处理基础的情况下学习 CNN 会对设计智能系统产生影响。如今,大多数模型都有大量的超参数,可以通过调整来为我们的问题构建“完美”的系统,因此,理解它们的作用和意义非常重要。

就我个人而言,正如本文之前所述,这些智能系统的一个非常重要的部分是它们的可解释性。而且,为了让我们开始构建能够对他们的行为进行某种解释的模型,我们首先需要理解这些操作的意义。

最后一点,看到这个领域之外的人将这些系统的学习过程视为某种“魔法”是非常令人兴奋的。然而,对于开发人员来说,关键是不要把它当成魔术,并深刻理解它背后的基本原理,以不断创新和构建更好的系统。

张量流计算机视觉

原文:https://towardsdatascience.com/computer-vision-with-tensorflow-9f183636c4cc?source=collection_archive---------38-----------------------

关于我们如何编程机器从图像中学习的全面指南

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

精神岛之旅。作者图片

这将是《人工智能导论》、机器学习和深度学习 Tensorflow story 的延续,在那里我讨论了标准的神经网络。如果这对你来说是全新的,我建议你先从这里开始。

目录:

  1. 构建数字识别器
  2. 发展数字识别器
  3. 这是怎么回事?
  4. 构建猫和狗的分类器

构建数字识别器

MNIST 数据集

计算机视觉是使用神经网络学习图像结构的实践。当我们看一张图片,比如一件衬衫,我们怎么知道这是一件衬衫?我们可以通过识别衬衫的具体特征来识别它,比如衣领、形状或背景(这件衣服穿在哪里?)如图所示。这类似于我们希望机器也能够学习图像的方式——我们希望模型能够理解图像的空间上下文。

和以前一样,我们先从一个例子开始。我们可以从 Tensorflow 加载 MNIST 数据集,这是一个手写数字的大集合。

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

来自 MNIST 数据集的样本,维基百科

作者图片

MNIST 数据库包含 60,000 幅训练图像和 10,000 幅测试图像,黑白图像被归一化以适合 28×28 的边界框。这意味着当您加载数据时,它会在一个列表中产生 60,000 个 28x28x1 项目,但模型中的第一层(卷积层)将需要一个 60,000x28x28x1 的单个 4D 列表,因此这就是我们重塑训练和测试图像的原因。

但是我们为什么要用 255.0 来划分图像呢?这样做是为了将图像的像素值归一化到 0 和 1 之间,这使得网络更容易学习最佳最小值。

现在来构建卷积神经网络。

我们的第一个卷积神经网络

作者图片

标准神经网络只有密集层,因此我们现在发现卷积神经网络有 3 个新层:Conv2D、MaxPooling2D 和 Flatten。这些层代表了这种类型的神经网络如何学习图像的空间特征。

我们将简要介绍各层的功能,但目前该模型能够通过移动过滤器扫描图像的像素,然后将其展平为一维阵列,使其类似于标准神经网络,最后通过密集层发送,就像非卷积网络一样——密集层有 128 个节点,输出层有 10 个节点。

最终输出层包含一个 softmax 激活,它生成十个目标类的概率(0-9 位数值),并预测概率最高的值。

作者图片

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

作者图片

由于这是一个分类任务,特别是多分类,我们将使用的损失函数是稀疏分类交叉熵。如果是二元分类,我们就用二元交叉熵。这与我们使用均方误差的回归任务相反。

当我们在训练集上达到可接受的精度时,我们可以像以前一样使用回调来停止训练。对看不见的数据进行评估的时间。

作者图片

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

作者图片

作者图片

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

作者图片

总的来说,模型表现很好,但是在验证集上稍差一些,所以可能出现了轻微的过度拟合。Dropout 是一种常用的技术,因此模型不会过于依赖给定的节点,这有助于避免过度拟合。简而言之,Dropout 是一种在给定层中随机删除一定比例的节点的方法,以迫使模型不要过于依赖任何给定的节点。

说到图像,还有另一种技术:图像增强。这包括旋转、宽度/高度移动、剪切、缩放、裁剪和翻转。在将数据拟合到您的模型之前,您可以轻松地添加这一步骤,它允许模型更有效地推广到新的示例。这背后的原因也很简单——如果你有一只狗的图像,但它们都是用腿站立的,那么一个模型可能会在狗仰卧的照片上表现得更差。图像增强有助于这一点,因为它提供了更多独特的图像方向供它学习。

让我们试着重建和发展我们最初的模型,看看我们能做些什么!

发展数字识别器

加载和预处理设置

作者图片

代码看起来与我们最初的模型一样,只是我们为训练和验证集添加了一个数据生成器,以在一定程度上增加图像(包括归一化像素值)。这里需要注意的一点是,我们不想增加测试数据,只增加训练数据。为什么会这样?我们希望模型能够推广到新的图片,这些图片通常不会像我们的增强图像那样扭曲;我们的扩充主要是为了让模型考虑到像素空间位置的变化。这也为我们的模型创建了一个更大的训练集来学习。

轻松提升复杂性

作者图片

使用层增加复杂性与使用标准神经网络一样容易,但这里的关键变化包括:

  • 添加一个丢弃层,在输出前从隐藏层中随机丢弃 20%的节点
  • 通过数据生成器收集训练/测试图像,这允许我们在训练模型时添加简单的预处理步骤,如图像增强
  • 将批量大小设置为 64,这是在每个时期更新模型之前要处理的样本数。所以一次可以通过 64 幅图像。

该模型可以通过数据生成器轻松拟合,如下所示:

作者图片

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

作者图片

我降低了准确性阈值以节省计算和时间成本,但看看每个时期的训练/测试损失和准确性——该模型始终能够很好地推广到新数据。

这是怎么回事?

卷积神经网络由在图像的一部分上迭代以提取图像的全局和局部空间特征的滤波器组成。

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

作者图片

这表示在 6x6 图像上卷积 1 个大小为 3x3 的滤波器。我们经常使用 64 个大小为 5×5 的滤波器来卷积 28×28×1 的图像。实际上,每个单元格都乘以其对应的单元格,然后求和以获得新值(31+11+21+00…=-5),然后过滤器移动 1,直到扫描完所有值。对于这些层中的每一层,模型都试图学习图像中类似于信号的有区别的全局和局部特征。通常,随着层数的增加,模型可以学习图像的更多具体特征。一个很好的例子是,扫描面部图像的模型的第一层可以学习面部的整体轮廓边缘,第二层可以学习面部内将眼睛从鼻子和嘴中区分出来的线条,第三层可以学习眼睛的更有区别的特征(形状、颜色、大小等)。),等等。

这里需要注意的一点是,滤波器的值在很大程度上决定了输出图像中检测到的内容。如果滤波器中全是 0,输出图像也将全是 0,不会发生边缘检测。这些过滤器是 CNN 所学习的,因为它能够在每幅图像中提取有意义的、有区别的特征,这使得它能够尽可能地最小化关于目标标签的损失。

过滤器之外

您可能会注意到,在将滤镜通过原始图像后,输出图像会缩小。这种情况可能会逐步升级,因此如果您希望输出图像保持相同的大小,一种常见的技术是在原始图像周围填充一层 0。

此外,您可能不想让过滤器一次一列地通过图像。您可以跨越卷积来跳过原始图像中的两列或更多列。

然后我们也有池层。这些通常是最大或平均池层,它们通过获取图像某一部分的最大值或平均值来运行。

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

作者图片

通常情况下,最大池是这样做的,但这是一种保留可能在图像的一部分中的特征信号的方法。有趣的是,MaxPooling 并没有梯度下降的超参数可以学习。滤波器大小和跨距的固定值相应地应用于每个卷积层。在功能上,它是一种在图像的较小维度的图像区域中保留特征信息(通过高像素值指示的信号)的方式。

更复杂的是,我们经常处理彩色图像,而不是灰度图像。这通常意味着图像驻留在三维(RGB)中,因此我们不只是通过 2D 卷积,而是通过 RGB 像素值矩阵的三维卷积(例如,5x5x3)。

为什么是回旋?

当对图像进行操作时,在密集层上使用卷积层有两个主要好处:

  1. 参数共享:在图像的一部分有用的特征检测器可能在图像的另一部分也有用(例如垂直或水平边缘检测器)
  2. 连接的稀疏性:在每一层中,每个输出值只依赖于少量的输入

因此,我们有过滤器的大小,填充,步幅,池过滤器的大小,层数等。(甚至不包括训练大规模模型的计算和时间成本)-这是一个很大的跟踪量,更不用说编辑来测试什么工作得好,什么工作得不好!这就是一种叫做迁移学习的技术非常有用的地方。

迁移学习是站在巨人肩膀上的概念;您可以下载流行和成功的模型架构,以及它们的学习参数,冻结除输出层之外的所有层,并通过它运行您的数据以获得结果。这已被证明在各种领域产生了真正成功的结果,并且在使用深度神经网络架构时通常是首选。

我们可以将这一知识应用于猫和狗的分类器。

构建猫和狗的分类器

创建数据目录

Tensorflow 有很多方便的功能,可以很好地处理结构化目录。这首先要求我们在构建模型之前将图像加载到一个文件夹路径结构中。从技术上讲,如果您只关心建模部分,可以跳过这一小节,但是学习建模和非有效数据设计模式有点不切实际。

在加载到适当的目录之前,我们将加载谷歌的猫和狗的数据集。

作者图片

作者图片

这段代码将 Google 的猫狗数据集读入适当的目录。我们现在可以构建我们的预处理和数据流生成器。

预处理工作流

作者图片

以前,我们通过训练和测试分割来传输数据,这一次,我们可以简单地将它设置为从每个目录中传输。对于上下文,这仅在训练集中产生 2000 个图像,在测试集中产生 1000 个图像。现在是模型!

我们可以通过 InceptionV3 函数轻松地加载它,并限定我们也需要权重。通过层的循环,我们可以将它们的可训练标志设置为假。

摘樱桃盗梦空间网络

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

初始模型最后一层的快照。作者图片

这个模型相当庞大,如果你想了解更多关于盗梦空间网络的内容,我推荐你去看看这个网站:盗梦空间-v3 网络解释

作者图片

我们可以采用初始网络的输出层,然后像以前一样添加 Flatten()、Dense()和 Dropout 输出层的最后几个标准层。由于这是一个二元分类(猫或狗),我们在输出中只需要一个具有 sigmoid 激活函数的节点,以及用于损失函数的二元交叉熵。

作者图片

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

作者图片

由于数据集很小,我显著降低了历元数和每个历元的步数,但模型仍然表现得非常好。在一个时期内,我们看到大约 96%的准确性。

包裹

今天讨论了很多内容,但我试图在这里提供一个全面的入门指南,介绍计算机视觉的迷人世界。许多概念都建立在这里提到的主题上,包括创造人工智能艺术,使自动驾驶汽车能够“看见”,从 X 射线或 fMRI 扫描中提取模式等等。

我将有后续文章,将在此学到的知识应用于我感兴趣的数据集,但现在感谢您的阅读!请关注更多关于数据科学、机器学习和人工智能的内容。

参考文献

[1]深度学习。人工智能,卷积神经网络

【2】深度学习。AI,tensor flow 中的卷积神经网络

计算和可视化时间和频率相关性的简单方法

原文:https://towardsdatascience.com/computing-cross-correlation-between-geophysical-time-series-488642be7bf0?source=collection_archive---------1-----------------------

互相关是计算两个地震时间序列相互依赖程度的一个公认的可靠工具。一些研究依赖于互相关方法来获得对地震数据的推断。关于互相关方法的细节,我们让读者参考以前的工作(见参考文献)。

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

来自 Pexels 的照片

为了从我们的数据中获得有意义的推断,理解和识别两个时间序列之间的复杂和未知的关系是至关重要的。在本帖中,我们将采用地球物理数据进行理解。对于一般读者,我建议忽略特定领域的示例,继续阅读,因为相关性的概念是数学上的,可以应用于与任何领域相关的数据。

相关性不是因果关系[来源:GIPHY]

在地球物理学(具体来说是地震学)中,一些应用是基于寻找一个时间序列相对于另一个时间序列的时移,例如环境噪声互相关(寻找两个记录站之间的经验格林函数)、震源反演(例如 gCAP)和结构研究(例如全波形反演)、模板匹配等。

在本文中,我们将了解如何计算地震时间序列之间的互相关,以及如何在时域和频域中提取两个地震信号之间关系的时移信息。请注意,除非数据的自由度很高,否则相关值并不显著。详情请参考下面的帖子。

https://www.earthinversion.com/geophysics/estimation-degrees-of-freedom/

此外,人们可以使用蒙特卡罗模拟等数值测试来估计相关性的显著性。参考下面的帖子:

https://www.earthinversion.com/techniques/monte-carlo-simulations-correlations/

计算互相关

现在让我们看看如何计算两个时间序列之间的时域互相关。为了这个任务,我任意选取了两个地震速度时间序列:

任意选择的数据

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from synthetic_tests_lib import crosscorr

time_series = ['BO.ABU', 'BO.NOK']
dirName = "data/"
fs = 748  # take 748 samples only
MR = len(time_series)
Y = np.zeros((MR, fs))
dictVals = {}
for ind, series in enumerate(time_series):
    filename = dirName + series + ".txt"
    df = pd.read_csv(filename, names=[
                     'time', 'U'], skiprows=1, delimiter='\s+')  # reading file as pandas dataframe to work easily

    # this code block is required as the different time series has not even sampling, so dealing with each data point separately comes handy
    # can be replaced by simply `yvalues = df['U]`
    yvalues = []
    for i in range(1, fs+1):
        val = df.loc[df['time'] == i]['U'].values[0]
        yvalues.append(val)

    dictVals[time_series[ind]] = yvalues

timeSeriesDf = pd.DataFrame(dictVals)

上述代码读取包含位于目录(dirName)中的垂直分量的 txt 文件,并为任意获取的fs样本修剪数据。我们可以交互地读取每个txt文件,并将数据列保存到字典中。该字典接下来被转换成“熊猫”数据框架,以利用“熊猫”库中的所有工具。

请注意,有几种不同的方式来读取数据,这种方式的偏好取决于用户和数据格式。

为了绘制时间序列,我使用了matplotlib

# plot time series
# simple `timeSeriesDf.plot()` is a quick way to plot
fig, ax = plt.subplots(2, 1, figsize=(10, 6), sharex=True)
ax[0].plot(timeSeriesDf[time_series[0]], color='b', label=time_series[0])
ax[0].legend()
ax[1].plot(timeSeriesDf[time_series[1]], color='r', label=time_series[1])
ax[1].legend()
plt.savefig('data_viz.jpg', dpi=300, bbox_inches='tight')
plt.close('all')

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

数据可视化(图片由作者提供)

计算时域中的互相关

d1, d2 = timeSeriesDf[time_series[ind1]], timeSeriesDf[time_series[ind2]]
window = 10
# lags = np.arange(-(fs), (fs), 1)  # uncontrained
lags = np.arange(-(200), (200), 1)  # contrained
rs = np.nan_to_num([crosscorr(d1, d2, lag) for lag in lags])

print(
    "xcorr {}-{}".format(time_series[ind1], time_series[ind2]), lags[np.argmax(rs)], np.max(rs))

在上面的代码中,我使用了crosscorr函数来计算一系列滞后值的时间序列对之间的相关性。滞后值被限制在-200 到 200 之间,以避免伪影。

# Time lagged cross correlation
def crosscorr(datax, datay, lag=0):
    """ Lag-N cross correlation. 
    Shifted data filled with NaNs 

    Parameters
    ----------
    lag : int, default 0
    datax, datay : pandas.Series objects of equal length
    Returns
    ----------
    crosscorr : float
    """
    return datax.corr(datay.shift(lag))

这里,正如你所注意到的,crosscorr 使用了 pandas corr 方法;因此,d1 和 d2 需要是“熊猫”系列对象。

我得到了上述时间序列对之间的相关性为0.19,滞后为36

xcorr BO.ABU-BO.NOK 36 0.19727959397327688 

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

任意取真实时间序列的时域互相关(图片由作者提供)

获取时移的互相关频域方法

shift = compute_shift(
    timeSeriesDf[time_series[ind1]], timeSeriesDf[time_series[ind2]])

print(shift)

这给出了-36

其中函数compute_shift简单来说就是:

def cross_correlation_using_fft(x, y):
    f1 = fft(x)
    f2 = fft(np.flipud(y))
    cc = np.real(ifft(f1 * f2))
    return fftshift(cc)

def compute_shift(x, y):
    assert len(x) == len(y)
    c = cross_correlation_using_fft(x, y)
    assert len(c) == len(x)
    zero_index = int(len(x) / 2) - 1
    shift = zero_index - np.argmax(c)
    return shift

这里,shift的移动意味着yx之前的shift时间步开始。

生成时间序列的合成对

虽然所获得的结果看似合理,但由于我们使用了任意一对实时序列,我们不知道我们是否获得了正确的结果。因此,我们将上述方法应用于具有已知时移的时间序列的合成对。

让我们使用scipy.signal函数生成一个双单位脉冲函数。然后,我们应用一个中心频率为 0.2 的 4 阶低通滤波器来平滑边缘(注意,即使没有滤波器,结果也是一样的)。

# Delta Function
length = 100
amp1, amp2 = 1, 1
x = np.arange(0, length)
to = 10
timeshift = 30
t1 = to+timeshift
series1 = signal.unit_impulse(length, idx=to)
series2 = signal.unit_impulse(length, idx=t1)

# low pass filter to smoothen the edges (just to make the signal look pretty)
b, a = signal.butter(4, 0.2)
series1 = signal.lfilter(b, a, series1)
series2 = signal.lfilter(b, a, series2)

fig, ax = plt.subplots(2, 1, figsize=(8, 6), sharex=False)

ax[0].plot(x, series1, c='b', lw=0.5)
ax[0].axvline(x=to, c='b', lw=0.5,
              ls='--', label=f'x={to}')
ax[0].plot(x, series2+0.1, c='r', lw=0.5)
ax[0].axvline(x=to+timeshift, c='r', lw=0.5,
              ls='--', label=f'x={to+timeshift}')
ax[0].set_yticks([0, 0.1])
ax[0].legend()
ax[0].set_yticklabels(['Series 1', 'Series 2'], fontsize=8)

d1, d2 = pd.Series(series2), pd.Series(series1)
lags = np.arange(-(50), (50), 1)

rs = np.nan_to_num([crosscorr(d1, d2, lag) for lag in lags])
maxrs, minrs = np.max(rs), np.min(rs)
if np.abs(maxrs) >= np.abs(minrs):
    corrval = maxrs
else:
    corrval = minrs

ax[1].plot(lags, rs, 'k', label='Xcorr (s1 vs s2), maxcorr: {:.2f}'.format(
    corrval), lw=0.5)
# ax[1].axvline(x=timeshift, c='r', lw=0.5, ls='--')
ax[1].axvline(x=lags[np.argmax(rs)], c='r', lw=0.5,
              ls='--', label='max time correlation')
ax[1].legend(fontsize=6)
plt.subplots_adjust(hspace=0.25, wspace=0.1)
plt.savefig('xcorr_fn_delta.png', bbox_inches='tight', dpi=300)
plt.close('all')

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

低通滤波单位冲激函数的时域互相关(图片由作者提供)

参考

  1. 晁,B.F .,钟,C.H,2019。估计一个数据集与另一个数据集的互相关和最小二乘拟合。地球物种。Sci。6, 1409–1415.https://doi.org/10.1029/2018EA000548
  2. 罗宾逊和特雷特尔(1980 年)。地球物理信号分析。新泽西州恩格尔伍德克利夫斯:普伦蒂斯-霍尔。
  3. 使用快速归一化互相关的模板匹配
  4. 庆开博客:“信号处理:频域互相关”
  5. 如何计算 Python 中变量之间的相关性

下载代码

以上所有代码可从我的 Github repo 下载。

原为 2021 年 2 月 16 日在https://www.earthinversion.com发表。

用 Beam 计算耦合数据流

原文:https://towardsdatascience.com/computing-on-coupled-data-streams-with-beam-3c8872b1faf8?source=collection_archive---------28-----------------------

思想与理论行业笔记

耦合数据流需要一起分析,特别注意事件时间的同时性和控制参与者流的其他流程特定变量……

数据流现在无处不在。IOT 设备、自动柜员机交易、应用程序、传感器等……源源不断地输出数据。当这些数据流到达时,分析它们会带来挑战——尤其是当数据流是耦合的时候。例如,当单个底层进程生成多个数据流时,它们耦合。耦合的数据流只能一起分析,要特别注意这些数据流上的事件在时间上的同时性(以及其他与过程相关的问题,如发出数据流的空间位置)。如果其中一个数据流由于某种原因被延迟,整个处理框架就会停止工作,等待它赶上来,而来自其他数据流的数据就会堆积起来。

等到所有数据都在中才能理解它—不适用。在任何时间所有数据都不会在中。流处理技术在时间内通过窗口将流动的数据分批成块,并将每个块作为一个批次进行分析。由于有不同类型的时间 —事件/日志/流程等,用于批处理流的具体时间量取决于生成数据的流程和分析的目标。要使用的时间窗的具体类型(固定宽度、重叠等)及其宽度也是如此。缓慢发展的现象可以存在于更大的时间窗口中,而高度动态的系统将需要足够薄的时间窗口来忠实地跟踪过程随时间的变化。每个数据窗口可能在该窗口的代表时间产生一些关于过程的度量——比如说它的中点。

这是一个不完美的世界

现实世界中的数据流从来都不是完美的,因此流处理框架必须计划如何处理它们。

  • 迟到、无序到达和未出现。一些旧的测量可能在途中被延迟,并且比新的测量晚到达。有些人可能会完全迷路。时间窗应该打开多长时间是一个没有严格正确答案的问题。它依赖于产生数据并将数据传输到处理框架的机制。
  • 早期和改善结果。在处理该批数据之前,应该不需要等待时间窗口关闭,特别是当我们需要为迟到者打开时间窗口时。计算早期指标,即使它们是近似值,对于检测和警告潜在问题可能是有用的。
  • 需要同时。大多数进程以不同的速率产生不同的数据流。例如,化学反应器可能在不同的位置具有温度和压力传感器,每个传感器生成一个数据流。对反应堆健康状况的任何分析都需要在相同的时间从所有位置测量温度和压力。也就是说,不能使用一次温度测量和几分钟后(或在不同位置)的压力测量来正确评估反应堆的健康状况。

这篇文章的目的是在模拟数据流上说明上述内容。至于流处理框架,我们将使用 Apache Beam ,因为它似乎设计得很好,可以处理真实世界的数据流。此外,Beam 提供了一个可移植的 API 层来构建并行数据处理管道,这些管道可以在各种执行引擎上执行,包括 Google Clouddata flowfor scale。我们将坚持使用在本地运行的 DirectRunner。我们将使用 Apache Kafka 来产生数据流,并在 Beam 管道中使用它们。实现代码可以从 github 获得。

1.数据流

考虑识别一个明确定义的三角形的三个点。让一个理想的质量-弹簧系统附着在每一点上,当实验开始时,在它的最外部位置释放。当这些点以不同的频率围绕其静止状态执行简谐运动时,它们的坐标位置( x,y )产生稳定的数据流。当三角形变形时,对由这三个点标识的三角形的周长和面积等度量的精确估计是令人感兴趣的。这里的理想三角形只是一个替代物,比如说一个支撑关键结点的三角形金属法兰,数据流从每个角落的位置监控器发出。下面的图 1 说明了这一点,并获得了作为时间的显式函数的坐标位置。

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

图一。顶点围绕它们的静止状态沿着指定的轴执行简单的谐波运动。每个顶点处的监视器为其坐标位置(x,y)生成数据流。这些流由 Beam 一起处理,以计算由这三个点确定的三角形 的周长和面积(图片由作者提供)。

给定这些等式,我们可以很容易地计算三角形度量,如周长和面积。下面的图 2 显示了顶点 A 在 90 秒内完成了一整圈,而顶点 B 摆动得更快,只需要 15 秒。随着顶点以不同的方式移动,三角形的面积和周长以某种混乱的方式变化。但它们确实显示出 90 秒的严格周期——因为 Ta 是 Tb 和 Tc 的简单倍数。

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

图二。 Ta=90,Tb=15,Tc=45。(A)顶点的坐标围绕其静止状态执行正弦运动(B)顶点沿着箭头线移动形成变形的三角形面积和周长以混沌的方式变化但具有预期的整体周期性(图片由作者提供)。

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

变形三角形的动画。任意时刻箭头的长度反映了该时刻顶点的移动速度*(图片由作者提供)。*

2.数据流

顶点的( x,y )坐标被发布到 Kafka 主题——数据流的源。实际测量时间是主题中事件的创建时间。但是事件是随机延迟的,所以以完全不同的顺序进入主题,如下面的图 3 所示。当然,每个测量的到达时间都严格地晚于创建时间。

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

图 3。射束处理的时间窗基于事件创建时间。事件到达流的顺序与它们的创建顺序非常不同。因此,多个时间窗口看到在给定处理时间到达它们的事件(图片由作者提供)。

图 3 显示了当事件到达主题/流时,时间窗口被事件填满。给定模拟的随机延迟,第一时间窗继续看到落入其中的事件,直到结束。最后一个时间窗口从一开始就看到一些事件。下面的图 4 显示了其中一个模拟中的活动生产订单与到货订单。

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

图 4。测量事件被模拟为具有随机延迟,因此它们以非常不同的顺序到达流中。例如,顶点 A 的第一个测量事件在超过 10000 个其他测量已经进来之后出现在流中。相同事件时间的 B 和 C 顶点的测量直到 25000 个其他事件进来之后才进来。因此,严格来说,在那之前,第一个三角形的良好定义是不可用的。这是耦合数据流的典型问题。

在理想情况下,从第一个事件落入该窗口的时刻起,每个时间窗口只需要在其宽度的持续时间内保持打开。但是考虑到这里的无序和迟到,时间窗口需要保持打开更长时间,以避免数据丢失。

3.流处理

流处理的目标是计算作为时间函数的三角形的面积和周长。这要求首先在每个时间窗口中识别一个三角形。一个定义明确的三角形要求所有三个顶点的位置同时为。由于三台监视器没有进行同步测量,我们需要估计每个顶点在同一时刻的位置,比如它们所在时间窗口的中点。**

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

图 5。首先通过顶点(每个时间窗口)对事件进行分组,以便估计其在窗口中点时间的位置。通过顶点和窗口,处理是并行的。然后,根据公共时刻对它们进行重新分组,以组装定义三角形和发射度量所需的三个顶点(图片由作者提供)。

图 5 展示了我们通过数据得到我们想要的东西的机制。Beam 提供了方便的 IO 模块来与各种数据源和接收器对话。在这里,我们从 Kafka 主题中读取事件,并最终将指标写入 Elasticsearch 进行分析。上面的每一步(除了“应用窗口”之外,它只是在窗口中按事件时间对数据进行分组)都将一个元素集合作为输入,并将它们转换成另一个元素集合,然后提供给下一步。

3.1 键是 同时并行的键

选择(如果数据中不存在,则构建)正确的键来对数据进行分组对于确保时间上的局部性和同时性非常重要。以顶点为关键字进行分组首先为下一个处理步骤固定顶点,该步骤计算并发出所有顶点在某个公共时刻(如窗口中点)的估计位置。按该时刻分组会在同一时刻产生三个顶点,用于下一步定义三角形并计算该时刻的度量。

此外,并行性从顶点的数量切换到时间窗的数量。对于每个变换步骤,光束平行度内置于元素级别。我们的元素是键值对。例如,如果我们正在监控 10 个三角形法兰的数据,第一个分组可以产生 30 个并发执行。并且,如果我们选择在每个时间窗口内的 5 个瞬间估计顶点位置,第二组产生的潜在并行度是操作窗口数量的 5 倍。

3.2 估算插值

虽然这与波束无关,但我们这里的具体问题要求我们在估计窗口中点时间的顶点位置时要小心。我们可以尝试一个简单的平均值,但这只适用于顶点的位置在时间窗口的持续时间内没有太大变化的情况。更好的方法是如图 6 所示进行插值,从估算时刻的任意一侧选取几个最接近的测量值。

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

图 6。线性插值可以给出比简单平均更好的估计值分段三次曲线可以进一步提高估计值。

此外,快速变化的量显然需要足够薄的时间窗来捕捉其动态,并在时间窗内用分段线性或(可能是三次样条)来近似它。

3.3 触发器

时间窗继续收集折点,直到不再有折点,此时时间窗将关闭。但是没有必要等到那个时候,因为我们可以触发窗格来不时地发出它的内容。当一个窗口触发时,它发布它的内容,以便后续步骤获得一个新的元素集合来处理,并且一些三角形度量被发布出来用于分析。定期触发允许尽早(如果是近似的)立即获得度量。**

窗口可以选择累积它的内容(就像我们在这里做的一样),即使是在周期性地发出它们之后。这意味着随着图 6 中的估计值越来越接近精确值,度量的持续改进是可能的。

3.4 管道代码

这里运行这些模拟的完整代码可以从 github 获得。为 Beam 设置的管道值得一看,以确认它与图 5 和图 6 中描述的内容相一致。

4.结果

对于顶点的两组不同的周期,每次都采用两种不同的估计方法(平均或插值)来获得结果。在第二组中,顶点的移动速度是第一组的三倍,这是为了突出插值策略的影响。因此总共运行四次,每次运行 360 秒,Beam 使用 1 秒的固定时间窗

  1. Ta=90,Tb=15,Tc=45。通过线性插值估计中点顶点
  2. Ta=90,Tb=15,Tc=45。通过以下方式估计中点顶点:简单平均
  3. Ta=30,Tb=5,Tc=15。通过线性插值估计中点顶点
  4. Ta=30,Tb=5,Tc=15。通过以下方式估计中点顶点:简单平均

图 7 显示了基本情况(运行 1)的周长与时间的函数关系。这基本上验证了这里用于处理三个耦合流以计算全局度量的整个方法。

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

图 7。周长与已知解析解的一致性非常好(图片由作者提供)。**

由于比例的原因,在上图中很难看到,但是所有时间窗口中的第一个和最终计算的周长值与精确值非常接近。让我们更仔细地看看这个问题。图 8 显示了所有四种情况下计算面积与精确面积之比随时间的变化情况。理想情况下,我们希望它是 1.0。

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

图 8。在时间窗口中累积事件改进了窗口寿命期间的预测。插值时,度量的最终计算值与精确值(8.1 和 8.3)非常一致,即使在快速变化的度量(8.3)的情况下,第一个计算值也只有大约 5%的误差。使用分段三次样条插值可能会有进一步的帮助。相比之下,当求平均值时,我们看到最终计算值的误差高达 25%,首次计算值的误差高达 40%(8.4)(图片由作者提供)。**

图 9 展示了从给定时间窗口开始的计算指标的演变。有点类似于图 8,但是包括了在时间窗的生命周期内发射的屈光不正的所有(即不仅仅是第一个和最后一个)值。当我们积累顶点时,我们再次希望看到改进。我们在插值的情况下会这样做,而在求平均值时不会这样做。

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

图 9。不同时间窗口发出的指标显示为处理时间的函数。随着处理时间的增加,我们希望该比率接近 1.0。当插值(9.1 & 9.3)时,我们确实看到稳定而快速地收敛到 1.0。(图片作者)。**

5.结论

耦合的数据流需要一起分析,要特别注意事件时间的同时性和控制数据流的其他过程特定变量。借助于一个已知精确解的测试问题,我们已经表明,用波束进行流水线处理可以精确地获得它们。

Apache Beam 提供了应对与处理耦合数据流相关的许多挑战的方法——无论是根据需要切换键以适应处理、允许延迟到达,还是启用早期度量等……加上元素级别的内置并行性和管道在不同运行器上执行的可导出性,使得 Beam 对于大规模流处理非常有吸引力。

原载于 2021 年 9 月 7 日 http://xplordat.com**

您可能不知道的位置编码概念

原文:https://towardsdatascience.com/concepts-about-positional-encoding-you-might-not-know-about-1f247f4e4e23?source=collection_archive---------9-----------------------

关于 Transformer 中的位置编码,您只需要知道

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

Unsplash 上由 corina ardeleanu 拍摄的照片

在 LSTM RNN,单词是按顺序输入的,因此它能理解单词的顺序。随着刑期的增加,在 LSTM 复发将需要大量手术。但是在 transformer 中,我们并行处理所有的单词。这有助于减少培训时间。为了记住单词的顺序,引入了位置编码的概念。这是一种表示单词位置的编码。简而言之,我们将位置编码添加到现有的单词嵌入中,这将为我们提供最终的预处理嵌入,它将用于编码器部分。

注意:- 在开始这篇博文之前,我强烈推荐访问我之前关于变形金刚 概述的 博文。

位置嵌入的不同技术:-

  1. 位置嵌入=单词索引

在这种情况下,如果句子的长度是 30。那么对应于每个单词,索引号可以是它的位置嵌入,如下图所示:-

在这种情况下,如果句子的长度是 30。那么对应于每个单词,索引号可以是它的位置嵌入,如下图所示:-

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

位置嵌入和单词嵌入相加得到最终嵌入**(作者的**图片)

我们可以使用这种编码方式,但问题是随着句子长度的增加,位置嵌入的大值支配了原始单词嵌入,因此扭曲了单词嵌入的值。因此,我们在自然语言处理任务中放弃了这种方法。

2。位置=句子长度的分数。

如果我们将嵌入值转换为长度的一部分,即 1/N,其中 N=字数,它应该可以工作,因为值将被限制在 0 和 1 之间。这里唯一的漏洞是,当我们比较两个不同长度的不同句子时,对于一个特定的索引,位置嵌入值是不同的。一般来说,对于不同长度的句子,位置词嵌入对于特定的索引应该具有相同的值,否则会扭曲对模型的理解。因此,对于我们的自然语言处理任务,我们放弃了这种方法,而采用基于频率的位置编码方法,正如在原始论文“注意力是你所需要的全部”中提到的。

3。基于频率的位置嵌入

该论文的作者提出了一个独特的想法,即使用波频率来捕捉位置信息。

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

正弦函数(图片由作者提供)

对于第一位置嵌入,

位置=0

d=嵌入的大小,应等于现有嵌入的尺寸。

i=每个位置嵌入维度的索引,也表示频率(i=0 是最高频率)

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

位置嵌入(作者图片)

在第一个正弦曲线图中(其中 i=4),我们绘制了具有不同位置值的正弦曲线,其中位置表示单词的位置。由于正弦曲线的高度取决于 x 轴上的位置,我们可以使用高度来绘制单词位置。由于曲线高度以固定长度变化,且不依赖于文本长度,这种方法有助于克服前面讨论的限制。请查看这个令人敬畏的视频了解更多。

值介于-1 和 1 之间。并且随着长度的增加,位置编码值保持不变。但是在从下面看的平滑正弦曲线中(其中 i=4),我们看到 y 轴上的字位置 0字位置 5 的距离非常小。为了克服这一点,我们提高了频率(freq =秒内完成的周期数)。如果我们这样做,那么在上面的第一条正弦曲线(i=0)中,我们看到位置 0位置 5 之间的距离清晰可见。

作者使用了正弦和余弦函数的组合来获得这些嵌入。

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

波频(图片由作者提供)

让我们编码这个

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

用于生成位置嵌入的代码(图片由作者提供)

输出预览为:-

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

以上代码输出(图片由作者提供)

这里我们可以看到第一个和第二个单词的接近度/紧密度很高,因此余弦相似度很高,而第一个和第九个单词之间的距离很远,因此余弦相似度很低。

这就是位置编码,如果你喜欢,可以和你的朋友分享。在那之前,

乳腺癌诊断的概念主成分分析与内在主成分分析

原文:https://towardsdatascience.com/conceptual-vs-inbuilt-principal-component-analysis-for-breast-cancer-diagnosis-7ec3a8455201?source=collection_archive---------34-----------------------

在 PCA 中拟合特征值、特征向量和 python 内置函数的概念,然后使用 ML 模型来测量乳腺癌(Wisconsin)数据集的高级精度参数。使用 2 个聚类和 4 个分类模型进行分析。

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

Unsplash 上由斯特凡·斯特凡·契克拍摄的照片

简介:

我们这些热衷于通过 python 探索世界的数据科学爱好者知道,python 只用几行代码就使主成分分析变得非常容易。但是我们不能忘记选择主成分背后的基本概念。在本文中,在将机器学习模型应用于聚类和分类之前,我已经以两种方式实现了 PCA 一种是计算特征值和特征向量,另一种是使用传统的 scikit-learn 工具。

在深入研究这些方法之前,让我先问你两个非常简单的问题:

为什么要处理一个庞大的数据集,使计算成为一项艰巨的任务?

为什么不减少它,同时保留它所提供的几乎所有有价值的信息呢?

这就是 PCA 用匕首来拯救你的地方,它砍掉了数据,减少了数据的维数,使分析更容易,同时保留了手头数据的统计数据。现在你可能会想,PCA 是如何决定哪些变量要删除,哪些要保留的呢?那就是降维的妙处;它不是删除变量,而是将信息组合成新的主成分,这些主成分是原始变量的线性组合。是的,准确性确实受到了一点影响,但获得的简单性更有价值。

当你在思考的时候,让我为你描绘一个非常简单的场景…

假设你打算很久以后去见你的学校朋友。他们在家里急切地等着你。但是,你的朋友圈挺大的,去他们各自的住处拜访,会占用相当多的时间和精力。你能想到的直接解决办法是什么?这时你决定给他们每个人打电话,约他们在附近的咖啡馆见面。这样,你可以用最少的时间和精力去结识所有的朋友,而不必排除任何人。这不就和上面的解释差不多了吗?

PCA 以这样的方式构造新的变量或主要成分,即大部分信息被塞入第一成分,而最大信息保留在第二成分中,以此类推。它创建了与原始变量相同数量的组件,但是每个组件中包含的信息量随着组件数量的增加而减少。一个简单的图表将帮助您直观地了解主成分如何解释数据中的最大总方差。当我们在数据集上实现它时,这幅图将会变得更加清晰。

我们将要处理的数据集-

我选择了一个维度足够大的数据集来应用 PCA,因为所有真实世界的数据,无论是结构化的还是非结构化的,都是巨大的。Kaggle 的“乳腺癌(威斯康星州)”数据集包含了癌症和非癌症患者的数据。我已经分享了数据的链接-【https://www.kaggle.com/uciml/breast-cancer-wisconsin-data*。*

分析是在 Python (Google colab)上实现的,这里是我在 GitHub 中的代码的链接

https://github . com/debangana 97/Data-science-works/blob/main/Breast _ cancer _ diagnosis _ using _ PCA _ two _ ways . ipynb

从文件中可以明显看出,有 569 行和 30 列,也就是说,30 个不同的变量对应于关于患者的 30 个不同特征的信息。这些特征有助于确定患者是否患有乳腺癌。然而,同时检查所有 30 个变量来预测未来患者的状况是非常乏味的,并且容易出错。对癌症的错误预测是医生最不想做的事!

目标:

这一分析的主要目标可以清楚地表明在以下几点:-

  1. 使用主成分分析来降低数据的维数仅仅意味着主成分分析将把 30 个变量组合成更小的主成分
  2. 根据通过主成分分析获得的新变量(主成分)对数据进行聚类
  3. 检查减少的数据是否可用于分类
  4. 基于分类模型的精确度找到主成分的最佳数量

既然我们已经清楚了这篇文章的主要目的,那就让我们开始吧。

准备数据…

数据预处理或数据清理是数据分析中最重要的先决条件之一。数据的适当准备将导致可靠和可理解的结果。这里有几个步骤,我发现对我的分析是必要的-

  • 删除对研究没有帮助的不必要的列
*#removing the unnecessary columnsexclude = ['Unnamed: 32','id']data = data.drop(exclude, axis = 1)*
  • 检查缺少的值。非常幸运的是,我的数据集中没有丢失值,因此我可以使用整个原始数据,而不必操作任何点
  • 检查数据不平衡

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

图 2:显示每一个班级人数的计数图

  • 将数据分为训练集和测试集,其中 20%的数据被保留用于测试模型的性能,其余的用于训练。训练集的大小为 455 行 30 列
  • 将训练数据分成两个独立的数据帧。因变量/目标变量(y)包括癌症结果,即数据的*‘诊断’*列,特征变量(x)包括患者的所有特征
  • 训练集和测试集中的特征矩阵 x 的标准化是为了更好的计算和无偏的结果。 StandardScalar 包用于数据的集中和规范化
*#standardization or feature scaling of the matrix of features X does both centering and normalizing of the datafrom sklearn.preprocessing import StandardScalersc = StandardScaler()
x_train_std = sc.fit_transform(x_train)
x_test_std = sc.fit_transform(x_test)*
  • 对分类变量“y”进行编码

主成分分析:

方法 1

在进行 PCA 之前,有必要将数据标准化。标准化确保每个原始变量对分析的贡献相等。这种降维方法对原始变量的方差非常敏感,其中值范围较大的变量将比范围较小的变量占优势,因此结果将趋于有偏差。此步骤以这样一种方式转换变量,即整个训练数据的平均值为 0,标准偏差为 1。

*print(np.mean(x_train_std))
print(np.std(x_train_std))**Output:** 4.021203394686281e-17 
        1.0*

在 python 中,我计算了协方差矩阵。矩阵中的正负符号表明特征变量之间是直接相关还是反向相关。

从线性代数的知识中,从这个矩阵中,我们可以构造特征向量,这些特征向量实际上是新轴的方向,其中有最多的信息(最高方差)并且被称为主分量。它们对应的特征值是特征向量的系数,表示每个主分量传递的信息量(方差)。

那么现在应该选择哪些组件呢?

想…

想…

正确!有最大特征值的那些,对吗?

我选择了具有最高特征值的两个分量,并基于这两个分量绘制了显示“恶性”和“良性”之间的区别的二维图。在这里,我也使用不同的组件进行了一些试验,看看哪一对组件能更好地显示这两类患者。

  • 第一次投影在第一和第二主分量的平面上。第二次投影在第二和第三主分量的平面上。

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

图:基于第一和第二主成分绘制了由两类患者分组的数据

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

图:基于第二和第三主成分绘制了由两类患者分组的数据

  • 从图中可以清楚地看到,第一种投影更好地分离了类别。这是一个明显的结果,因为第一分量包含最高比例的信息。

尝试使用第一个和第三个组件绘制图表。你得到了什么?成绩提高了吗?

方法二

接下来,我使用 scikit-learn 直接执行主成分分析,这在第一种方法之后看起来非常容易。Python 完成了上述所有计算,并最终向我们展示了一个图表(scree plot ),按照解释的变化百分比顺序显示了主要成分。该图显示累计约总变化的 73%仅由 前三个分量解释。

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

图:显示 30 个组成部分中每一个解释的变化百分比的 Scree 图

为了与方法 1 的结果进行比较,我绘制了显示基于前两个主成分的两个不同类的数据,这给出了与不直接使用 scikit-learn 的结果相似的可视化。因此,这两种方法表现得一样好,python 已经和人脑不相上下了!

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

图 5:Python scikit-learn 给出了一个与上图类似的图表

下一步是什么?…

现在数据从 30 个变量减少到 3 个变量,定义了一个新的特征向量,它包含作为列的三个分量的特征向量。因此,新特征向量的维数是 455(行)乘 3(列)。

*#transforming the data to the reduced dimension data
#this is the data that we are going to work with during the analysispca_data = pca.fit_transform(x_train_std)print('The reduced data is of the dimension: ', pca_data.shape)**Output:** The reduced data is of the dimension:  (455, 3)*

我要实现的第一个机器学习算法是 K-Means 聚类和层次凝聚聚类模型。粗略地说,聚类是一种无监督的 ML 算法,并且不需要任何训练,因为它基于特征变量创建整个数据的聚类。现在让我们看看这些模型如何在我们的数据集上工作。

K 均值聚类与层次聚类-

在确定聚类之前,我们如何决定要将数据分成多少个聚类?集群应该以这样的方式形成,即它们之间是同质的,同时与其他集群共享异质性。

在 K-Means 聚类中,我们使用肘方法图中聚类平方和内的*,找到最佳聚类数。你为什么要问?看一下图,你会注意到曲线形状像一个肘部,因此得名。但是我们如何决定是使用 2 个、3 个还是 5 个集群呢?***

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

图:弯头方法图

为了消除这种困惑,我使用了一种叫做轮廓分数的度量标准,它测量一个聚类中的每个点与相邻聚类中的点的接近程度。侧影分数+1 表明该点离相邻聚类非常远,从而表明这些聚类是不同的,而分数 0 表明该点与另一个聚类中的点重叠或者离它们不是非常远。因此,显然,对应于最高轮廓分数的聚类数是分析的最佳选择。

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

图:每个聚类数的轮廓分数

从图中可以看出,2 个集群给出了最好的结果。

对于聚类的分层方法,它使用树状图来确定最佳的聚类数目,这显著地表明 2 个聚类将给出有希望的结果。

*#Using dendrogram to find the optimal number of clustersimport scipy.cluster.hierarchy as sch
dendrogram = sch.dendrogram(sch.linkage(pca_data, method = 'ward'))*

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

图:树状图

在下面的代码行中,使用 2、3、4 和 5 个集群对这两种方法进行了彻底的比较。在可视化技术的帮助下,集群以不同的颜色呈现。这些图表确实引人注目,不是吗?

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

图:使用 3 个集群完成的集群* *外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图:使用 5 个集群完成的集群*

随着集群数量的增加,它们开始相互重叠。

我使用了另一个被称为 Davies-Bouldin 指数的验证指标来确定最佳的集群数量。它评估聚类分散和聚类分离之间的比率。

那么,你认为这个指数的理想值是多少?

如果群集定义明确、紧凑且独特,则群集分散肯定小于群集间隔。因此,您认为 DV 指数值越低,表示聚类越好,这是正确的。下表给出了不同 k 值的戴维斯-波尔丁指数及其各自的质心坐标。如前所述,该索引值最小的那个是聚类的最佳选择。

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

图 2:显示不同数量的聚类的 DV 指数的表格,并附有聚类坐标

从上面的讨论和后面的表格中可以明显看出,对于 k = 2,聚类将给出最好的结果。

聚类和分类可以一起应用吗?

机器学习的基础知识将允许我们问自己,虽然聚类是一种无监督的 ML 算法,但分类是一种有监督的算法,那么两者如何应用于同一数据集?数据是否预先标记?我们可以为未标记的数据生成标签吗?

一旦我们计算出聚类的纯度度量,就可以给出这些问题的答案。在得到结果之前,我将告诉你一些关于这个指标和它是如何工作的。

  • 差的聚类将具有接近 0 的纯度值。纯度分数的最高值是 1,其中值 1 意味着每个文档都有自己的聚类。这意味着每个文档都有自己的标签。正如我们所知,分类是一种受监督的机器学习算法,其中类别是预先标记的,因此如果聚类的纯度是 1,这意味着它可以用于分类。
  • 一般来说,当簇的数量大时,高纯度容易实现。然而,如果纯度等于 1,那么形成簇就没有意义。
  • 在我们的例子中,我计算了 K-均值聚类和层次凝聚聚类的这个度量,聚类的数量= 2、3、4 和 5,并且发现在所有情况下纯度值都接近 1。因此,即使集群数量较少,我们也可以应用分类。

K-NN 分类或者 Logistic 回归或者支持向量机,谁分类最好?

因为纯度指标证实了分类模型可以有效地处理数据,所以我决定使用四种不同的模型来比较结果。目标变量(y)显示患者是否被诊断为乳腺癌。它是一个二元变量,其中“M”代表恶性,“B”代表良性。标签编码有助于数据的分类和可视化。对于每个模型,我使用了不同数量的组件,分析了结果,并以表格的形式展示了结果。

*#Encoding the target variablefrom sklearn.preprocessing import LabelEncoder
le = LabelEncoder()y_train = le.fit_transform(y_train)y_test = le.fit_transform(y_test)*

分类结果的可视化是一种享受!使用 2 个主要成分,我已经展示了一些迷人的图表供你欣赏…

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

图 2:训练集和测试集上的 K-最近邻分类器* *外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图:训练集和测试集的逻辑回归* *外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图:训练集和测试集上的线性 SVM* *外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图:训练集和测试集上的径向基函数(核)SVM*

嗯,一口气画了很多图!但是你能指出它们之间的一些区别吗?看起来线性分类器在这个数据集上会工作得更好。

使用不同数量的主成分,我已经应用分类模型回到回答我们的主要问题- 我们实际上需要多少个主成分?

从分类分析中获得的准确度结果(百分比)可列表如下-

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

图 2:显示特定于主成分数量的每个分类模型的总体准确度的表格

如果我们仔细研究这张表,可以得出以下几点结论

  • 对于两个主成分,K-NN 给出最高的精确度,而核 SVM 给出最低的精确度
  • K-NN 对 4 个分量达到最大精度,此后开始下降
  • 使用 4 个主成分,线性 SVM 导致大约 96%的最大准确度
  • 当考虑 4 个主成分时,逻辑回归也能够获得大约 95%的准确度,此后,它保持恒定
  • 使用 4 个主成分,核 SVM 提供了大约 94%的准确度
  • 由核 SVM 结果获得的总体精度低于由线性 SVM 获得的精度,这表明这两类可以通过直线更好地分开

我添加的一些其他可比指标包括-

**混淆矩阵:这是一个 2x2 的列联表,显示模型做出的正确预测数和错误预测数

**每个单独类别的准确度分数:计算模型预测每个类别的准确度

**平均类别特定准确度:上面计算的单个准确度的平均值

**预测正值得分:被模型预测为患有癌症的患者实际患有癌症的概率。

去看看我提供的全部代码,你肯定会理解这些价值。

总结我们可以说…

因为我们的目标是在保留最大信息量的同时降低数据的维数,所以我认为可以肯定地说主成分的最佳数量应该是 4。

你不这么认为吗?

我希望阅读这篇文章有助于您的数据科学知识库,并帮助您获得更深入的见解。因此,请记住,从下次开始,如果你可以用较少的食物提供相同的营养,就不要过量进食你的 python 练习册…谢谢大家!

概念化是认知的基础——人类和机器

原文:https://towardsdatascience.com/conceptualization-as-a-basis-for-cognition-human-and-machine-345d9e687e3c?source=collection_archive---------14-----------------------

机器理解和认知人工智能的缺失环节

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

图片由杰基·尼亚姆土坯股票上提供

虽然大多数当代对人工智能能力的讨论和分类都围绕着一个系统能够做什么,但我相信通向更高智能和机器认知的道路依赖于一个系统能够知道和理解什么 。使用丰富的人工智能知识表示框架和全面的世界模型可以增加人工智能系统将信息转化为深层知识、理解和功能的能力。为了追求更好的人工智能,理解“理解”对人脑的真正意义是必不可少的。这样做可以实现框架,通过将建模和概念化与数据和任务概括相结合,使机器学习能够平行于人类理解。

概念化:人类思维的基础

概念是人类思维中最基本的积木。概念是我们思考的对象的本体论根源。概念代表一个对象类的一组持久的基本属性,这些属性可以随着经验而改变和扩展。现有的概念可以被抽象或通过类比链接到附加的域和对象类。概念的例子包括|狗|、|民主|、|白|和|大叔|。物理或精神对象可以存储为一个概念,并随着时间的推移积累更多的数据和属性(例如|我的幸运狗|和|白雪公主|对|灰白色|)。即使所指对象是不可见的或抽象的,如|love|,它仍然可以作为一个概念存储。我们对世界的理解依赖于概念、概念的属性以及概念之间的关系。我们用概念和由概念组成的事实以及它们之间的关系来构建我们的世界模型。

概念是独特的,因为它们可以包含代理可用的任何类型的信息,并且可以在没有先验知识的情况下形成。想象一下,走进教室,老师说,“今天,我们将学习格查尔。”一个新概念的占位符已经在学生的头脑中形成,除了名称之外没有任何信息。“这是一只小小的热带鸟,”老师继续说道。大量可能的信息现在被添加到这个概念中——它可能非常丰富多彩,可能生活在森林中,并发出有趣的声音。概念具有弹性和持久性,弹性是有界限的,不允许概念变得面目全非。

概念的存在与描述它们的语言相关,但又独立于它们。例如,单词“dog”是概念|dog|的属性(有时称为标记)。即使你用一个不同的词来形容邻居院子里让你睡不着觉的毛茸茸的东西,它仍然是一只|狗。

作为另一个例子,概念|banana|可以从代表香蕉的各种图像的抽象特征开始——绿色的或成熟的、整个的或切片的、单独的或与其他物体相互作用的。概念|香蕉|还可以包括历史和故事(香蕉叶裙、香蕉船)、价值观(营养)、在餐桌上坐几天后的成熟程度,或者它的内涵(香蕉)。在地球上的大多数语言中,香蕉这个概念都是由一个名称来表示的,但它并不是这些名称中的任何一个。

在提出的 6 个知识维度的模型中,一个概念被捕获为一个抽象的概念引用(第 6 个维度),它链接了该概念的所有实例化和引用。它指的是多模式方面,如视觉表现、成熟水果的气味、剥皮时的感觉(对于具有触觉功能的系统)、咬一口时的声音和味道等等。它将有多方面的知识:描述性的,包括分类法和事实;程序性的,包括怎么剥,怎么吃;关于其遗产的故事;与拥有或失去它相关的价值;等等。

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

1.香蕉的概念。

创造概念的过程——概念化——以三种方式之一发生:

教官指导。对人类来说,这包括向老师学习——例如,钢琴教师、生物学教授或足球教练。用机器学习的术语来说,这将是利用标记信息或来自系统设计者的直接输入的监督学习。

**自导自演。**人类通过观察结构良好的概念并将其内化来练习被动概念化。例子包括阅读一本介绍和描述新术语的书,观看两个人打排球,通过观察推断规则和目标。对于机器学习系统来说,这将是获取广泛可用的文本或观看描述和命名概念的视频,以便填充概念数据结构。

**内部。**这些都是通过分析你的现状而形成的概念,或隐或显。例如,攀岩者评估哪些路径是可航行的,哪些是太难的。从这个评估中,形成了|可通过性|的概念(参见图 2 中的例子)。同样,科学家仔细观察,将经验提炼到理论和概念框架中。对于机器学习系统来说,这将是自我发现(识别一个可以有效地模拟人工智能系统所看到的世界的抽象)。

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

2。抽象和类比允许概念在新的领域中重新应用。

关于如何概念化有许多,通常是相互矛盾的定义和理论。对于未来的人工智能系统,可以提供以下概念化的定义:在世界观知识框架内抽象和发展丰富概念结构的能力,以促进广泛的推理并产生新的知识和技能。

概括是认知人工智能的必要但不充分的属性

可以说 t oday 的深度学习忽略了概念,将泛化作为 AI 的终极目标。这种方法可能会导致认知机器学习的能力范围有限。机器学习系统必须学会概念化,以达到创造具有更高智能的机器的目标。

为了证实这一说法,让我们首先检查人工智能中的泛化在人工智能/机器学习的上下文中具体意味着什么(相对于外行人对该术语的使用),然后探索它与概念化有何不同。

**泛化概述:**在机器学习中,泛化是指经过训练的模型对未知数据进行分类或预测的能力。一般化的模型通常适用于所有看不见的数据子集。

古德费勒、本吉奥和库维尔讨论过拟合和欠拟合的概念。他们指出,对于机器学习算法来说,在新的、以前看不到的输入上表现良好是多么具有挑战性,这是泛化问题的核心。增加新的维度或抽象超出了这种概括观点的范围。例如,机器学习模型可以学习正确分类质数和非质数。然而,要得出一个类似于人类数学家对素数的抽象定义是不太可能的。

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

3。一个通用的算法学习一个既适合训练数据又适合验证数据的流形。

概括的两个重要方面是插值外推插值在数学上定义为一种估计,一种在一组离散的已知数据点范围内构造新数据点的方法。外推定义为基于一个变量与另一个变量的关系,对该变量的值进行超出原始观察范围(训练集)的一种估计。在机器学习中,外推是一个在特定数据范围内训练的系统,可以预测不同范围的数据。

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

4。外推和内插是概括的重要方面。

Francois Chollet 将泛化的概念从数据扩展到任务。在他看来,一个系统的智能是通过其获得基于概括难度的任务技能的能力来衡量的:

系统的智能是对其在任务范围内技能获取效率的度量,与先验、经验和概括难度有关。

在他的模型中,Chollet 代表了执行任务能力方面的所有概括水平。

与概括不同,概念不一定与任务直接相关。一个人可以形成一个概念,而不用把它和一个任务联系起来。因此,智力的潜在方面可以用适用于目前未知任务的内在概念来表示。概念不一定只能通过任务中表现出来的行为来理解。

**现在的 AI 还不能说是执行概念化:**首先需要注意的是,概念化并不等同于分类。在机器学习中,分类指的是预测建模问题,其中为输入数据的给定示例预测类别标签。相比之下,概念是一组丰富的、多方面的相关知识,可以不断扩展。

以下标准定义了概念形成的范例,根据该范例,当前的机器学习算法不概念化:

容量和多样性。一个概念首先由它的本质来定义,然后由它的细节来进一步修饰。一个概念并不固有地局限于一组特定的描述符或值,而是可以累积几乎无限的维度——可以把它想象成一块海绵,随着时间和经验吸收相关的知识。例如,报名参加表观遗传学第一堂课的生物学学生可能对该领域一无所知,除了模糊地认识到它听起来类似于“遗传学”。随着时间的推移,随着学生了解朊病毒、核小体定位、糖尿病对巨噬细胞行为的影响、抗生素改变谷氨酸受体活性等,这个曾经非常稀疏的概念将变得更加多面化。这个例子与深度学习形成对比,在深度学习中,令牌或对象具有固定数量的维度。

坚持。一个概念保持不变,即使它的部分或大部分属性可以改变。相比之下,机器学习中令牌或对象的嵌入是由对象的维度(属性)来定义的。假设属性通过附加训练改变,潜在空间嵌入改变,并且潜在地,到其他嵌入向量的距离改变。在不改变固有概念的情况下,概念驱动的知识表示中的属性可能会有实质性变化,因为它反映在知识库中(例如,它在本体中的位置或与其历史的关联)。例如,一名律师可以卖掉他的法拉利,成为一名僧侣,改变他的大部分外在属性,但仍然是同一个人。当映射到基于特征的嵌入空间时,由于人工智能系统观察到的维度特征的变化,概念可能会移动。然而,使它成为一个特定概念的本质很可能不会改变。

**抽象。**这包括提供抽象的信息组织及其含义的能力,这种能力可以应用于完全不同的领域,与它所来自的数据领域无关。在处理|可通过性|的概念时,我们在博客前面介绍过,它可能是在攀岩经历中学到的。尽管如此,这一概念的抽象和属性允许它应用于一个完全不同的领域/空间,例如玩一个风险游戏或考虑联系其中最终能修好你的笔记本电脑的人。这种比深度学习的拟合功能高得多的抽象层次——以及跨不同空间识别类比和概念相似性的能力——是深度学习泛化实践所无法实现的“概念”的主要区分因素。

结论

一个系统吸收数据、抽象数据、扩展概念、增强内部建模能力和推理能力的能力是衡量智能的主要标准。与此同时,对学习任务的衡量表现是一种滞后的措施。一种将底层建模和知识表示(包括概念化)与数据和任务概括相集成的方法,将有可能为总体上更高的机器智能提供更好的途径。

参考文献

歌手 g(2021 a,4 月 6 日)。认知人工智能的崛起——走向数据科学。中等。https://towards data science . com/the-rise-of-cognitive-ai-a 29 D2 b 724 CCC

歌手 g(2021 年 5 月 6 日)。对深度知识的理解和运用——走向数据科学。中等。https://towards data science . com/understanding-of-and-by-deep-knowledge-aac5 ede 75169

维基百科贡献者。(2020 年 12 月 9 日)。概念化(信息科学)。维基百科。https://en . Wikipedia . org/wiki/概念化 _(信息 _ 科学)

墨菲(2004 年)。概念的大书。布拉德福德的书。

什么是机器学习中的泛化? (2021 年 2 月 25 日)。deepai . space .https://deepai . space/什么是机器学习中的泛化/

印第安纳州古德费勒、纽约州本吉奥和库维尔(2016 年)。深度学习。阿姆斯特丹大学出版社。

f . chollet(2019)。论智力的衡量。 ArXiv,abs/1911.01547

维基百科贡献者。(2021 年 8 月 31 日)。插补。维基百科。https://en.wikipedia.org/wiki/Interpolation

维基百科贡献者。(2019 年 8 月 21 日 a)。外推。维基百科。https://en.wikipedia.org/wiki/Extrapolation

布朗利,J. (2020 年 8 月 19 日)。机器学习中的 4 类分类任务。机器学习精通。https://machine learning mastery . com/types-of-class ification-in-machine-learning/

叶,A. (2020 年 6 月 26 日)。真正的人工智能:理解外推 vs 概括。中等。https://towards data science . com/real-artificial-intelligence-understanding-extrapolation-vs-generalization-b 8e 8 DC F5 FD 4b

Sharma,R. (1999 年)。卖掉自己法拉利的和尚。哈珀柯林斯。

Gadi Singer 是英特尔实验室副总裁,认知计算研究总监。

结论作为挖掘法律推理的锚

原文:https://towardsdatascience.com/conclusions-as-anchors-for-mining-legal-reasoning-6f837fb8da3c?source=collection_archive---------28-----------------------

思想和理论

通过检测结论来定位推理

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

图像由弗恩 r .沃克, CC 由 4.0

数据科学中的一个挑战性问题是从法律判决文件中挖掘推理。为了在整个文件中找到这种推理,我们可以利用判决对问题的结论来引导我们找到相关的证据、具体的推理和法律规则。研究表明,机器学习(ML)算法可以自动对陈述法庭事实结论的句子进行分类,精确度足以满足许多用例。因此,训练分类器来自动识别法律结论是重要的第一步。

一般来说,从文档中挖掘任何推理或论证的第一阶段是检测哪些句子起推理链的组成部分的作用(通常称为“论证句子”)以及哪些句子不起作用(“非论证句子”)。然后,一个议论文句子被归类为一个推理单元的“结论”或“前提”(支持结论的句子)。在斯蒂芬·图尔敏的《有影响力的模型》中(斯蒂芬·图尔敏,《论证的用途:更新版);剑桥大学出版社,2003 ),前提可以分为“数据”或“授权”。“数据”是推理所依据的事实,而“保证”是授权从事实到结论进行推理的条件或概括。为了对推理模式进行分类,我们最终需要确定哪些句子是同一推理单元的一部分,推理单元中推理关系的性质,该单元是哪种推理类型,等等。为了在所有这些任务上取得进展,我们可以从识别推理的结论开始,并且我们可以使用该结论来锚定我们的进一步搜索和分析。

同样的一般工作流程也适用于从法律文档中挖掘论点和推理。结论的类型、前提的类型和论证的类型因法律文件的类型而异。例如,在管理裁决中发现的推理类型经常不同于在上诉法院裁决中发现的类型,在初审法院裁决中发现的类型也不同。但是这些例子的共同点是,决策者需要使用语言来表明哪个句子陈述了法律结论。当事人、律师和审查法院需要能够确定是否所有的法律问题都得到了解决。在本文中,我引用了初审法院或机构的事实调查裁决的例子,但同样的分析也适用于其他类型的政府决定。我的例子来自退伍军人上诉委员会(BVA)的决定,该决定宣布了美国退伍军人因服役相关残疾而索赔的结论。

定义和识别特征

一个“法律认定”(也称为“事实认定”,或简称为“认定”)是由事实审判者根据案件中提出的证据对一个事实问题做出的正式裁定。事实的审理者可能是司法程序中的陪审团或法官,也可能是行政程序中的行政机构或官员。因此,“认定句”是主要陈述一个或多个事实认定的句子。因为实体法规则规定了需要裁决的事实问题,案件的裁决就是法庭对这些问题的裁决。换句话说,调查结果表明,在手头的法律案件中,实体法律规则的一个或多个条件是否得到满足。

以下是一个发现句子的示例(显示在由 Apprentice Systems,Inc. 开发的 web 应用程序中,黄色背景色用于编码发现句子):

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

图像由 Vern R. Walker, CC BY 4.0

我们律师如何知道哪些句子陈述了事实的发现?有一些典型的语言特征有助于提示一个发现的句子。例如:

适当的语言提示,用于将一个命题归因于事实的审理者(例如,“委员会发现,”或“法院确信”);或者

表示满足或未满足证明义务的词语或短语(例如,“未满足、“成功证明、“未能证明”);或者

表明法庭的法律任务已经完成的措辞(例如,在审查了所有证据之后的“”);或者

指代案件中涉及的特定人、地点、事物或事件的定名词短语,而不仅仅是用于陈述规则本身的不定类型(例如“老兵”而不是“老兵”)。

虽然法官可能不会使用特定的格式来书写判决,但通常有足够的语言特征使律师能够在判决中识别这样的句子。

此外,由于认定判决必然会宣布对有争议的法律问题的裁决,法官通常使用用于定义法律问题的关键术语来撰写认定判决。例如,考虑这个来自 Shedden 诉 Principi,381 F.3d 1163,1166–67(美联储。Cir。2004) (如学徒系统 web 应用程序所示,带有适当的背景颜色):

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

图片由 Vern R. Walker 拍摄, CC BY 4.0

第一句话(用浅红色突出显示)陈述了一个法律规则,第二句话(用浅橙色突出显示)提供了对法律权威的适当引用。在宣布对这三个编号条件的判决时,法官可以使用:

在陈述条件(1)的调查结果时,短语“目前无行为能力”或类似措辞;

条件(2)调查结果中的短语“运行中发生”或“运行中恶化”;和

条件(3)中的“因果关系”一词。

撰写判决的法官有强烈的动机清楚地表明哪些判决陈述了对哪些法律问题的调查结果。

此外,逻辑帮助我们识别寻找句子的集合。例如,对于要赢得决策的索赔老兵,在所有要求的规则条件上必须有积极的发现(对于老兵)。另一方面,如果老兵失去了决定,那么必须至少有一个负面的发现(针对老兵)。在这种情况下,因为一个否定的裁决就解决了索赔,法官甚至可能不会对其他条件做出明确的裁决。因此,逻辑帮助我们决定寻找多少发现。

机器学习(ML)数据集

但是,是否有足够的语言特征允许 ML 模型正确地识别和标记查找句子?为了回答这个问题, Hofstra Law’s Law,Logic &技术研究实验室(LLT 实验室)人工标注了退伍军人事务委员会 50 个决定中的发现句(标注的数据在 GitHub 上公开)。LLT 实验室将任何包含事实认定的句子归类为认定句。这些决策包含了 5797 个经过预处理的人工标记的句子,其中只有 490 个是找到的句子。一个例子是这个复杂的发现句子(用黄色突出显示):

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

图像由弗恩 r .沃克, CC 由 4.0

如句子前面的图标所示,这句话来自一项决定的第 49 段,第一句。LLT 实验室将此标记为发现句,因为实验室优先考虑不忽略任何发现。但是这个复杂的句子也陈述了一些与该发现相关的证据和推理。如果需要更细粒度的分类,我们可以将复杂的查找句子至少分解到子句级别,然后对子句角色而不是句子角色进行分类。

机器学习结果

机器学习模型可以很好地对这些 BVA 发现句子进行分类。我们在 LLT 实验室的 50 个 BVA 决策数据集上训练了一个逻辑回归模型。模型对发现句进行分类,准确率= 0.81,召回率= 0.78 。我们后来在同一个 BVA 数据集上训练了一个神经网络(NN)模型。神经网络模型查找句子的精度为 0.75,召回率为 0.79。

误差分析

在由 NN 模型预测为发现句子的 173 个句子中,44 个是错误分类(精度= 0.75)。可以理解的是,最常见的混淆是推理句子,这占了几乎一半的错误(21)。推理句子通常包含与发现句子相似的推理措辞,但结论本质上是中介的。被训练的 NN 模型错误分类为发现句子的推理句子(以绿色突出显示)的示例是:

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

图片由 Vern R. Walker, CC BY 4.0

上图是来自法律学徒网络应用程序的一个屏幕截图(这个例子是一个判决的第 39 段的第二句话)。NN 模型的预测分数排列在句子文本的下面。如你所见,该模型预测这是一个发现句(得分= 37.18%),尽管它是一个推理句的预测得分为第二(24.64%)。

这个句子主要陈述推理而不是发现。理由是,延迟发病使现役退伍军人的遭遇和退伍军人当前残疾之间的因果关系的任何决定变得复杂。这句话没有说明调查结果,因为它没有告诉我们法庭对这个问题的最终裁决。然而,在解释这一复杂情况时,法庭使用了相关法律规则中的术语(见上文 Shedden 引文)。因此,预测分类为发现句并不令人惊讶。诸如此类的句子有助于解释 0.75 的低精度。

因为我们律师不想忽略任何实际的判决,回忆也是非常重要的。在神经网络模型的测试集中,有 163 个人工标记的发现句子。虽然其中的 129 个被正确识别(回忆= 0.79),但该模型未能识别其中的 34 个。毫不奇怪,该模型错误地预测了 34 个实际发现句子中的 15 个是推理句子。该模型预测另外 13 个实际发现的句子是证据句。以下句子(摘自一项决定的第 124 段,第二句)是模型将一个结论句(以黄色突出显示)错误归类为证据句的一个例子:

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

图像由弗恩 r .沃克, CC 由 4.0

尽管明确陈述了一个否定的发现(“不支持一个发现”),其余的措辞与陈述的证据非常一致。注意,作为证据句(39.04%)和发现句(36.11%)的预测分数在值上非常接近,这反映了混淆的接近程度。

用例的重要性

分类错误的实际成本取决于用例以及错误的类型。如果用例是提取和呈现法律推理的例子,那么上面提到的精确度和召回率对用户来说可能是可接受的。如果许多错误是由推理句子和发现句子的混淆组成的,这可能是特别真实的。如果用户有兴趣查看论证或推理的不同例子,被分类为推理或发现的句子可能仍然是说明性论证的一部分。

与这样的用例相比,如果目标是生成关于争论成功或不成功频率的统计数据,那么只有 0.75 的精度和 0.79 的召回率可能是不可接受的。确定一个问题的辩论是否成功的唯一方法是确定相关的事实发现,将其映射到适当的法律问题,并确定该发现是积极的还是消极的(其“极性”)。(可以看我们关于自动检测找句子极性的论文。)为了生成准确的统计数据,我们需要高度确信我们已经自动且准确地执行了这三项任务。

摘要

总之,判决是法律判决的重要组成部分。他们陈述法庭对法律问题的结论,并告知当事方其个别辩论的成败。寻找句子在法律规则和判决中适当的法律论据和推理之间架起了桥梁。这样的句子也为从判决中提取相关的证据、推理和法律规则提供了一个定位。换句话说,寻找句子可以引导我们找到证据和推理句子,这些句子作为一个单一的论证或推理单元结合在一起。

Python 中的并发和并行

原文:https://towardsdatascience.com/concurrency-and-parallelism-in-python-bbd7af8c6625?source=collection_archive---------3-----------------------

理解大数据

Python 中可用方法的简明概述

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

照片由 Unsplash 上拍摄

如果你即将开始一个大数据项目,你将要么检索大量信息,要么在你的机器上处理大量数据,或者两者兼而有之。然而,如果代码是顺序的或同步的,你的应用程序可能会开始挣扎。

让我们看看在每种情况下,哪些概念和 Python 库可以提高应用程序的性能。

什么是并发和并行,它们解决什么问题

有两个方面可以提高程序的速度——I/O 和 CPU 消耗。例如,如果您的代码需要通过网络进行大量的文件访问或通信,那么它就是 I/O 受限的。CPU 绑定的代码涉及大量计算。例如,训练统计模型绝对是一项计算密集型工作。

这两种类型的工作在所需资源方面有什么不同?

当 I/O 绑定的代码发送多个请求时,它并没有真正利用机器的 CPU 内核,因为本质上,它是在空闲地等待响应。因此,这样的应用程序不能通过增加更多的计算能力来提高性能。它更多的是关于请求和响应之间的等待时间。

对于 CPU 绑定的代码片段来说,情况正好相反。

缓解任何一种瓶颈的两种机制分别是并发并行

通常,并发被认为是比并行更大的概念。简单来说就是同时做多件事。在实践中,有一个特殊的角度来区分这两种思想,尤其是在 Python 中。并发通常被理解为同时“管理”多个作业。实际上,这些作业并不会同时执行。它们巧妙地交替出现。

然而,并行执行意味着同时执行多个任务,或者并行执行*。并行性允许在一台机器上利用多个内核。*

三个用于并发和并行的 Python 库

在 Python 中,并发由[threading](https://docs.python.org/3/library/threading.html)[asyncio](https://docs.python.org/3/library/asyncio.html)表示,而并行是通过 [multiprocessing](https://docs.python.org/3/library/multiprocessing.html)实现的。

穿线

使用threading,您可以创建多个线程*,您可以在这些线程之间分配一些 I/O 相关的工作负载。例如,如果您有一个简单的函数来下载一些文件download_file(f),您可以使用[ThreadPoolExecutor](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)来启动线程,然后使用map从文件列表中调用每个参数文件:*

*with ThreadPoolExecutor() as executor:
    executor.map(download_file, files)*

这里值得一提的是,Python 中的线程工作方式与 Java 等其他语言不太一样——CPython 的全局解释器锁(GIL)实际上确保了内存使用是线程安全的*,因此一次只能处理一个线程(更多信息请参见[threading](https://docs.python.org/3/library/threading.html)文档)。因此,它实际上是一种如上定义的并发机制。*

阿辛西奥

使用asyncio,您可以为类似的目的创建任务*😗

*tasks = [asyncio.create_task(download_file(f)) for f in files]*

但是任务背后的想法不同于线程。事实上,任务运行在单线程上。然而,如果第一个任务正在等待它的响应而不是阻塞它,每个任务都允许操作系统运行另一个任务。这就是异步 IO* 的本质。(在后面的文章中对异步程序进行了更全面的介绍)。*

大多数情况下,您还会想要创建一个特殊的事件循环对象来管理主函数中的任务。

线程与异步

对于 I/O 绑定的程序来说,asyncio模块可以显著提高性能,因为创建和管理任务的开销比线程少。

线程化方法可以被认为更危险,因为线程之间的切换可以在任何时候发生,甚至在语句执行的中途,这是由于抢先多任务*,而asyncio任务在准备切换时会发出信号——这种机制被称为协作多任务。如果此时出现问题,那么使用线程方法来跟踪它会更加困难。*

然而,使用asyncio模块需要编写大量代码来适应它。

多重处理

以上两种方法对于加速 I/O 相关的程序都很有效。至于 CPU 受限的程序,多重处理将真正有所帮助。

multiprocessing模块为每个进程创建一个 Python 解释器。它实际上利用了您机器上的 CPU 内核数量。一个典型的 CPU 相关代码的例子是压缩文件。因此,如果您有一个函数compress_file(f),启动新进程并在它们之间分配工作负载的语法将类似于线程示例:

*with ProcessPoolExecutor() as executor:
    executor.map(compress_file, files)*

如果多处理这么神奇,为什么不一直用呢?

multiprocessing写代码有几件棘手的事情。首先,您需要能够确定某些数据实际上是否需要被所有进程访问——因为进程之间的内存不是共享的。此外,有时很难确定程序的哪些部分可以清晰地划分为独立的进程。

最后,您应该仔细评估multiprocessing带来的性能提升和成本之间的权衡。如果计算实际上不是那么密集的话,multiprocessing可能不会加速那么多,因为为每个进程增加解释器会带来很大的开销。

你对这些模块的实验结果如何?对他们在不同环境中的行为有什么有趣的观察吗?

如果你对关于 Python 的文章感兴趣,可以随意查看我关于 Python 3.9 中的新特性Python 代码优化的帖子!

Python 中的并发性:如何用线程加速代码

原文:https://towardsdatascience.com/concurrency-in-python-how-to-speed-up-your-code-with-threads-bb89d67c1bc9?source=collection_archive---------28-----------------------

用 Python 实现并发执行的理论+实践指南

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

照片由雷纳·辛普森Unsplash 拍摄

顺序执行并不总是有意义的。例如,如果输出不相互依赖,让程序闲置是没有意义的。这就是并发背后的基本思想——今天你会学到很多关于这个话题的知识。

本文将教您如何通过并发运行任务来加速 Python 代码。请记住,并发执行并不意味着同时。有关同时(并行)执行的更多信息,请查看本文。

这篇文章的结构如下:

  • 线程简介
  • 实现线程—发送 1000 个请求
  • 结果呢
  • 结论

你可以在这里下载这篇文章的源代码。

线程简介

那么,什么是线程化呢?简而言之,这是一个允许并发运行代码的编程概念。并发意味着应用程序运行多个任务,第一个任务不必在第二个任务开始之前完成。

假设您正在向某个 web API 发出一堆请求。发送一个请求,等待响应,一遍又一遍地重复同样的过程是没有意义的。

并发使您能够在第一个请求等待响应时发送第二个请求。下图应该比文字更好地解释了顺序和并发执行背后的思想:

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

图 1 —顺序执行与并发执行(作者提供的图片)

请注意,单个点代表任务的一小部分。如果任务闲置一段时间,并发可以帮助加快运行时间(想想请求-响应类型的通信)。

现在,您已经从理论上了解了线程的基础知识。下一节将向您展示如何用 Python 实现它。

实现线程—发送 1000 个请求

用 Python 实现线程非常简单。但首先,让我们描述一下任务。

我们希望声明一个向端点发出 GET 请求并获取一些 JSON 数据的函数。JSONPlaceholder 网站非常适合这个任务,因为它是一个虚拟 API。我们将重复这个过程 1000 次,并检查我们的程序在多长时间内基本上什么都不做—等待响应。

先不穿线程做测试吧。剧本是这样的:

我认为在上面的脚本中应该没有什么是不熟悉的。我们重复请求 1000 次,并记录开始和结束时间。fetch_single()函数中的打印语句在这里只有一个原因——查看程序在执行时的行为。

以下是运行该脚本后您将看到的输出:

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

图 2 —顺序执行的输出(作者提供的图片)

如您所见,一个任务必须完成,另一个任务才能开始。对我们这种类型的问题来说不是最佳行为。

接下来让我们实现线程化。该脚本看起来或多或少是相同的,但有几处不同:

  • 我们需要额外的进口— concurrent.futures
  • 我们不打印最后一条语句,而是返回它
  • ThreadPoolExecutor()用于并发提交和运行任务

以下是完整的片段:

一旦执行,您将看到类似于下面的输出:

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

图 3 —并发执行的输出(作者提供的图片)

这些都很好,但是速度真的有提高吗?接下来让我们检查一下。

结果呢

到目前为止,您已经了解了顺序执行和并发执行之间的区别,以及如何将代码转换为并发执行函数调用。

现在让我们比较一下运行时性能。下图以秒为单位总结了上述任务的运行时间,即进行 1000 次 API 调用:

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

图 4 —使用和不使用线程的运行时比较(图片由作者提供)

如您所见,执行时间减少了约 13 倍——至少可以说相当不错。

结论

今天,您已经学到了很多——从线程和并发执行背后的基本理论,到如何将非并发代码“转换”为并发代码。

请记住,并发并不是提高 Python 速度的万能答案。在您的应用中实现线程之前,请考虑应用是如何设计的。一个功能的输出是否直接作为另一个功能的输入?如果是这样的话,并发性可能不是您想要的。

另一方面,如果您的应用程序大部分时间处于空闲状态,“并发执行”可能就是您一直在等待的术语。

感谢阅读。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

https://medium.com/@radecicdario/membership

了解更多信息

保持联系

原载于 2021 年 2 月 8 日 https://betterdatascience.com**

Conda:基本概念和技巧

原文:https://towardsdatascience.com/conda-essential-concepts-and-tricks-e478ed53b5b?source=collection_archive---------15-----------------------

对于初学者和有经验的用户

在这篇博文中,我将描述 conda 是什么,以及如何有效地使用它,无论你是第一次看它还是经验丰富的用户。虽然在后一种情况下,你会知道很多事情,但你仍然会发现一些技巧,可以用来改善你的体验。

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

Unsplash 上由 Patrick 拍摄的照片

目录

为什么康达
入门级举例
什么是康达
康达和 pip
康达 vs anaconda vs miniconda
如何安装康达
获取 Miniconda
安装包、 和环境
基地环境
其他环境
使用 Jupyter 和 conda 的最佳方式
移除环境
共享一个环境
通道
conda-forge 通道
Conda 和 pip

为什么是康达

如果符合以下一项或多项条件,Conda 适合您:

  • 你花了太多的时间安装和配置软件,而不是专注于你需要工作的项目
  • 你总是以一个巨大的混乱结束,你必须清理,然后从头开始
  • 您希望能够在机器之间移动您的环境
  • 您需要在同一台机器上为不同的项目安装冲突的需求
  • 您希望有一个可重复、可跟踪的安装过程,可以跨平台和发行版共享,其中也可以包括非 python 包
  • 您刚刚得到一台新机器(可能配有 GPU ),并且希望快速上手
  • 你总是想尝试所有东西的最新版本,但不想处理不兼容的问题,也不想弄清楚哪个版本适合哪个版本
  • 您有多台机器安装了不同的 Linux 发行版,甚至混合了 Linux/macOS/Windows,并且您希望在它们之间使用相同的环境

如果这些都是真的,康达将会对你非常有用。

入门级示例

比方说,你刚刚得到一个新的闪亮的 GPU 机器,你想安装 NVIDIA CUDA 工具包。你是想做这个然后花接下来的 5-10 个小时来完成这个任务,还是宁愿做了这个然后走自己的路?

> conda install -c conda-forge cudatoolkit=10.2

你想安装pytorch并加入深度学习的行列吗?

> conda install pytorch cudatoolkit=10.2 -c pytorch

是否要在同一环境下安装 Tensorflow 和 Pytorch?这不是疯狂,只是:

> conda install -c conda-forge -c pytorch python=3.8 cudatoolkit=10.2 pytorch pytorch tensorflow tensorboard

还有更多。一般来说,大多数事情都是一个conda install之遥。最重要的是,如果您搞砸了,您只需删除环境并重试,不会在您的系统中留下任何痕迹。

我希望这能给你一点提示,为什么 conda 是一个如此神奇的工具。让我们投入其中,了解更多相关信息。

什么是康达

Conda 是跨平台的,开源包管理器。

您可能已经在系统上使用了软件包管理器。在 Linux 中,你可能有一个或多个aptyumsnap。在 macOS 中你有homebrew或其他。Conda 类似,但它是平台无关的。它确实适用于 Linux、Mac 和 Windows,并且在所有 3 个平台上都以相同的方式工作。

康达和皮普

一个常见的错误是将condapip相比较。它们相似,但在某种程度上也有很大不同:pip是一个以 Python 为中心的包管理器(毕竟pip包的存储库被称为 Python 包索引),而conda是语言不可知的。虽然pip包确实包含有时编译的库(例如,numpyscipypandas……),但一般来说,这些只是支持 Python 接口。相反,使用conda你可以安装 C/C++库、编译器、图形库、与 Python 无关的成熟应用程序。你甚至可以使用conda来安装 GPU 软件,比如 NVIDIA CUDA toolkit,或者go语言,或者npmjulia等等。换句话说,conda生态系统远远超越了 Python。因此condayumhomebrewpip更相似,正如我们所说的。事实上,一个典型的conda安装包含 pip作为另一个包,你可以使用 pip 在你的 conda 环境中安装包(但是在你这样做之前要看下面的警告)。

康达 Vs 水蟒 Vs 迷你康达

如上所述,conda是包经理。

Anaconda 是一个conda 包的集合,包含了您在日常工作中将要用到的大部分东西(当然也包括conda 包管理器)。有些人更喜欢它,因为它提供了一个很好的图形用户界面来处理环境和包,而不是命令行工具(CLI)。我个人从不使用 Anaconda,因为我觉得它很臃肿,而且我不介意 CLI。我用 Miniconda 代替。

Miniconda 是一个准系统的包集合:它包含 python、conda包管理器以及一些其他的包(包括pip)。它没有任何图形用户界面,只有 CLI。这是您构建环境的起点,该环境包含您需要的内容,仅此而已。它对于构建 Docker 容器也非常有用(见下文)。我个人只用 Miniconda。

如何安装康达

在这篇博文中,我们将重点放在 Miniconda 和 CLI 上。这是迄今为止最常见的用例,但是如果您想使用 Anaconda 及其 GUI,这里讨论的大部分内容也适用。

获取 Miniconda

转到这里并下载适合您的系统(Linux、Windows 或 Mac)的自安装包。把它保存在某个地方。

或者,运行以下命令:

注意:这里所有的命令行示例都假设使用 Linux 和bash shell。如果你在 Mac 和 bash 上,事情将是相同的。如果您使用的是另一个 shell,那么改动可能很小。例如,在下面的命令中,如果您在 Mac 上,请用 MacOSX 替换 Linux。我不会介绍 Windows,但是在 Windows 中将命令翻译成 shell 应该很容易(或者您可以使用 WSL

# Download Miniconda. You can also use wget or any other command 
# line download tool for this purpose> curl [https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh](https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh) > Miniconda3-installer.sh

现在转到下载文件的地方,通过运行以下命令安装 Miniconda:

# Add run permissions for current user
> chmod u+x Miniconda3-installer.sh
> ./Miniconda3-installer.sh -b -p ~/miniconda3

您可以用任何其他前缀替换-p ~/miniconda3,但是,通常最好保留那个前缀。为了简单起见,这篇博文的其余部分将假设 Miniconda 的路径。

恭喜你,你已经安装了迷你康达!现在让我们将它添加到 PATH 环境变量中,然后激活它:

如果您发现conda很有用,您可能希望将这些行添加到您的.bashrc文件(或者您的 shell 用作 init 脚本的任何文件)中,这样您就不必为每个新的终端都这样做了。

> export PATH=${PATH}:~/miniconda3/bin# While you could use `conda activate` instead,
# this way of activating is more portable
> source ~/miniconda3/bin/activate

注意,我们将 miniconda3 路径放在 PATH env 变量的末尾。这是我使用的一个技巧,以便 Miniconda 的存在是微创的。例如,如果现在我在没有激活 conda 的情况下运行 python,我仍然会进入安装在我的系统中的 python 解释器,而不是 Miniconda 自带的解释器。如果我把 path 放在 PATH env 变量的开头,我会进入 Miniconda python,不管我是否激活 conda。

我们现在已经准备好了,您应该会看到这样的内容:

(base) giacomo@fd4af0669a8:/#

(base)部分告诉你,你处于“基础”环境,conda 已经可以使用了。

等等!不要在基础环境中安装任何东西。首先阅读下一部分

安装软件包和环境

软件包有两种安装方式。一种是显而易见的,即使用命令:

> conda install [name of the package]

在某些情况下,您需要添加一个通道规范(参见关于通道的部分)。

另一种方法是创建环境并在创建过程中指定包。让我们看看那个。

环境是conda中最有用的概念之一。它们是独立的装置:一个环境中的一切都依赖于该环境中的事物。

嗯,不是 100%,而是 99.9%。你仍然依赖于你的系统的一些核心库,比如 Linux 上的*libc*,但是这些都是高级细节(在底部描述)。对于所有意图和目的以及 99.9%的用户来说,我刚才说的近似值是考虑环境的一个好方法。

是的,它们在概念上类似于 python 的虚拟环境,但是它们可以包含比 python 包更多的东西。

如果你对这是如何实现的感兴趣,看看这篇文章的底部。

关于环境的文档包含了所有的细节。在这里,我总结了要点,并提供了一些提示和经验教训。

基础环境

基本环境是在安装 Miniconda 或 Anaconda 时创建的。它包含基本操作所需的conda和包。

一个典型的初学者错误是将软件包安装到基础环境中。不要那样做。这样做会与您将要创建的其他环境产生冲突。

基础环境应该只包含conda,它的依赖项,以及与 conda 相关的东西,比如conda-buildmamba(参见下面的mamba是什么)。相反,对于任何其他软件,您应该总是依赖于其他环境。

其他环境

因为我们不想在基础环境中安装任何东西,所以首先要为日常操作创建您的首选环境。例如,标准的数据科学家环境可能是这样的:

> conda create --name ds -c conda-forge python=3.8 matplotlib numpy scipy pandas jupyter jupyterlab seaborn

康达将打印一份长长的包清单,这些包是让一切正常运转所必需的。您可以查看列表,然后输入y进行确认。如果您想避免该提示,只需在命令行中添加-y

这将创建一个ds环境,同时安装软件包。

提示:如果你已经知道你将需要更多的包,那么用这种方式安装它们,而不是以后依赖于conda install,这样 conda 将会找出满足你的需求的最佳依赖组合

正如你可能已经猜到的,你可以在那里添加任何你需要的软件包,而且很有可能你会在conda-forge 频道找到它。我们一会儿会谈到这意味着什么。

您现在需要激活此环境:

> conda activate ds

由于这是我们的首选环境,您可能希望将上面的行添加到您的.bashrc或您的 shell 运行的任何 init 脚本中,这样每次您打开 shell 时,您都会发现自己处于ds环境中。

从现在开始,如果您运行conda install [package],新的包将被安装在活动环境中。

你不需要在这里停下来。假设您今天想尝试一下最前沿的 python 3.9,但是您不想中断您的日常操作。很简单,只要创造一个不同的环境:

> conda deactivate
> conda create --name py39 python=3.9 numpy scipy matplotlib
> conda activate py39

在创建和激活下一个环境之前,conda deactivate部分会停用当前环境,并使您返回到base环境。这里我们也看到了如何指定包的显式版本,就像在python=3.9中一样。

提示:在激活一个新的环境之前,一定要运行conda deactivate。这避免了奇怪的问题,例如环境变量没有被设置

现在,您在py39环境中安装的任何东西都完全独立于ds环境中的东西。

注意:激活一个环境后,如果您查看$PATH 环境变量(echo ${PATH}),您会看到conda activate将路径添加到环境的bin目录中。这意味着您在那里安装的任何东西都优先于您系统中其他地方安装的东西。

类似地,您可以使用安装环境,比如说一个较旧的 PyTorch 版本,您需要复制一篇旧论文或者从您的 python 环境中单独安装go语言,这里仅举几个例子。

在任何时候,您都可以看到具有以下特征的环境列表:

> conda env list

使用 Jupyter 和 conda 的最佳方式

如果你在日常工作中使用 Jupyter(谁没有呢?)有一个你不能错过的扩展: nb_conda_kernel s .这个简单的扩展允许你从 Jupyter(笔记本或实验室)界面控制哪个环境用于哪个笔记本。你只需要把它安装在你的默认环境中(我们上面称之为ds),然后从你的默认环境中启动 Jupyter

> conda activate ds
> conda install -c conda-forge jupyterlab nb_conda_kernels
> jupyter lab

这是你将得到的:

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

使用 nb_conda_kernels,您无需离开 Jupyter 就可以为每台笔记本电脑选择使用的环境

注意:您不需要在每个环境中安装 Jupyter,但是您必须在每个环境中安装至少一个内核(例如,Python 的 ipykernel)。没有内核的环境不会出现在 Jupyter 的可用环境列表中。

移除环境

如果您想删除一个环境以释放一些磁盘空间,或者因为您想从头开始,您只需执行以下操作:

> conda deactivate
> conda uninstall --name py39 --all

这将完全删除py39环境及其所有包。

共享一个环境

环境可以通过多种方式复制。了解它们之间的差异是很重要的。

首先,你需要激活你的环境。

然后,如果您要导出到相同的平台(比如 Linux 到 Linux),只需:

> conda env export > environment.yml

environment.yml文件类似于piprequirements.txt文件,如果你知道我在说什么的话。它包含您的环境中包含的每一个包,当然包括 C/C++库之类的。它可用于在同一平台上重建环境,如下所示:

> conda env create -f environment.yml

一个典型的用例是在 Linux 上“开发”一个环境,然后以这种方式导出它,以便在 Linux Docker 容器中重新创建。这为您提供了一个精确副本的保证,不仅包括您手动安装的东西,还包括它们所有的依赖项。其中一些是依赖于平台的,这使得在不同的平台上(比如从 Linux 到 macOS)复制这个环境变得困难或者不可能。

相反,如果您希望您的环境可以跨平台复制,请以这种方式导出:

> conda env export --from-history > environment.yml

这个版本的environment.yml文件将只包含你在conda createconda install中明确安装的包。当在一个不同的平台上重新创建环境时(比如从 Linux 到 Mac),conda 将使用目标平台上可用的东西来解决环境文件中列出的包的依赖关系。当然,您可以像以前一样在目标平台上使用这个环境文件:

> conda env create -f environment.yml

第三个选项是核心选项:有一种方法可以将您的整个环境打包到一个二进制文件中,并在目的地解包(这当然只能在相同的平台上工作)。这在某些情况下非常有用,尤其是在使用 conda 和 PySpark 时。这是通过 conda-pack 实现的,详情见此处

频道

Conda 包被远程托管在通道中,例如,通道相当于yumapt的存储库。如果在conda installconda create期间未指定任何-c参数,则使用默认通道。否则,将使用您指定的通道。这意味着 conda 不仅会在默认频道中查找某个包,还会在您指定的频道中查找。例如,像这样的命令:

> conda install -c pytorch torch

将在pytorch通道和默认通道中寻找torch包。然后,可用版本将与此处说明的规则进行比较。

提示:始终打开strict频道策略。它使 conda 更快,并有助于避免冲突。你可以用conda config --set channel_priority strict来做

conda-forge频道

conda-forge 组织在conda-forge渠道中维护着一个庞大的包列表。你可以在他们的网站上找到构建这些包的方法,上面有 GitHub 的链接。您也可以轻松地将自己的软件包贡献给康达锻造。

如果你看看周围的网络,有康达锻造的爱好者和憎恨者。我属于前一类。然而,你需要知道一些重要的事情来使用它。

conda-forge包和默认 conda 通道中包含的包之间存在兼容性问题。因此,在安装东西或创建环境时,你应该总是按照上一节所解释的那样设置channel_priority: strict,并且优先使用conda-forge通道而不是默认通道。有两种方法可以做到这一点。您可以始终使用 conda-forge 指定conda install -c conda-forgeconda create -c conda-forge作为第一个列出的频道,或者在您的家中创建一个包含以下内容的.condarc文件:

channels:
  - conda-forge
  - defaults
channel_priority: strict

一个环境,从创造到毁灭,要么用康达-福吉,要么不用。不要混搭。如果你没有使用 conda-forge 频道就创建了它,那么就不要中途把它添加到组合中。在实践中,我总是用 conda-forge 创建一个环境,除非在非常特殊的情况下,我发现不兼容。

第三种选择是在您的.bashrc中定义一个 bash 函数,如下所示:

condaforge() {

    # $1 is the command, ${@:2} is every other parameter # Print the command before executing it
    echo "==>" conda "$1" -c conda-forge "${@:2}" conda "$1" -c conda-forge "${@:2}"
}

然后用它来创建环境和安装包:

> condaforge create --name test python=3.8

或者

condaforge install numpy

该功能会将-c conda-forge通道添加到您的 conda 安装命令中。

提示:有时很难记住一个给定的环境是否是用 conda-forge 创建的。一个简单的技巧是总是在环境名前面加上cf,比如conda create --name cf_py39 -c conda-forge python=3.9。或者,使用conda list | grep python查看 python 是否是从 conda-forge 通道安装的。在前一种情况下,您会看到类似以下内容:

python       3.8.5     h1103e12_7_cpython    conda-forge

康达和皮普

康达和皮普在历史上很难结合。现在情况好多了,在很多情况下,事情都很顺利。

但是,一般来说,您应该优先考虑这两者之一。例如,通常你会优先考虑 conda,也就是说,你会先尝试用 conda 安装包。如果这不可用,那么使用画中画。

在某些情况下,您可能想做相反的事情,优先考虑 pip。在这种情况下,创建一个只有 python+pip 的环境,然后从那时起使用 pip。

一个折中的办法是使用 conda 来安装基本组件(numpy、scipy、matplotlib、jupyter……)以及对 PyTorch、TensorFlow、Cuda toolkit、OpenCV 等重编译库的依赖,或者安装 GDAL 和 rasterio 等复杂而晦涩的包。用 pip 安装所有 python 专用的包。这不太可能给你带来问题。

注意,如果你用 pip 安装一个依赖于比如 numpy 的包,并且你已经用 conda 安装了 numpy,pip 会识别它,它不会再安装它(除非有版本冲突)。这就是为什么大部分时间事情都是正常的。

最后,请注意,当您如上所述导出环境时,环境文件确实包含所有安装了 pip 的包以及安装了 conda 的包,因此在 conda 环境中使用 pip 不会妨碍它的共享。

康达很慢

对 conda 最常见的抱怨之一是包求解器很慢。不幸的是,这是真的,尽管随着时间的推移,情况会越来越好。一个很酷的替代品刚出来,它叫mamba(见此处)。

Mamba 是 conda 安装程序的直接替代,所以你可以用mamba install代替conda install,用mamba create代替conda create。你会以快得多的方式得到同样的结果。相当酷!

您需要在您的基础环境中安装mamba:

> conda deactivate
# Make sure your prompt says (base)
> conda install mamba

释放一些磁盘空间

过一会儿,你会发现你的 miniconda 目录开始变得很大。主要原因是 conda 保存了你曾经下载过的所有软件包的档案。您可以使用以下工具轻松安全地清理这些垃圾:

conda clean --all

释放一些空间。

康达和多克

在构建 Docker 容器时(即在 Docker 文件中),可以使用 Miniconda 来安装环境。有几个很好的理由说明为什么大腿在某些情况下可能是个好主意:

  1. 您可以使用一个环境文件并完全复制您的开发环境。这是一种快速而简单的方法,可以确保您开发的内容能够找到您在开发过程中使用的相同依赖项
  2. 例如,你可以安装康达-福吉的产品。这允许您安装东西,即使您在容器中使用的发行版(基本映像)没有您需要的包
  3. Docker Hub 上有现成的图片,包含已经预装的 conda:https://hub.docker.com/r/continuumio/miniconda3,所以使用 conda 非常方便,不会增加太多复杂性
  4. 您可以安装和运行软件包,而不必成为root,从安全的角度来看,这有时更好,特别是当这些软件包启动 web 服务时,例如

请注意,在 docker 文件中,您应该在安装命令的末尾运行conda clean --all -y,删除那些会浪费图像空间的无用归档文件。

深入:RPATH 和 conda

你完全不需要知道这些,但是如果你想知道即使在编译库的情况下,conda 是如何实现独立环境的,这里就有。

当你编译一个 C/C++或 FORTRAN 包或一些其他编译的库/可执行文件时,你可以静态地或动态地链接你所依赖的库。大多数现代应用程序都是用动态链接编译的。这意味着在运行时,系统需要查看你的可执行文件或库,了解它所依赖的其他库,并在你的系统中找到它们(动态链接)。

系统有一些预定义的地方来寻找这些库,并维护这些路径的缓存。例如,在 Linux 上,这些地方类似于/lib/usr/lib等等。您可以使用以下命令查看 Linux 系统已知的所有库的列表:

> ldconfig --verbose

macOS 也有类似的系统。现在,如果我们拿一个可执行文件或一个库,我们可以看到它依赖于其他哪些库。例如,它打印了我的系统vim所依赖的库:

> ldd /usr/bin/vim
 linux-vdso.so.1
 libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
 libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 
 libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 
 libpython3.8.so.1.0 => /lib/x86_64-linux-gnu/libpython3.8.so.1.0 
 libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 
 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
 /lib64/ld-linux-x86-64.so.2
 libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 

正如所料,这些都是系统库。如果我在conda vim 上做同样的事情:

> conda install -c conda-forge -y vim
> ldd ${CONDA_PREFIX}/bin/vim
 linux-vdso.so.1
 libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
 libtinfo.so.6 => /root/miniconda3/envs/py39/bin/../lib/libtinfo.so.6 
 libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2
 libpython3.9.so.1.0 => /root/miniconda3/envs/py39/bin/../lib/libpython3.9.so.1.0 
 libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 
 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
 /lib64/ld-linux-x86-64.so.2
 libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 

我们可以看到,现在链接器在 conda 环境中找到了libtinfolibpython,尽管它们在系统/lib中是可用的。为什么?因为 conda 中的vim是使用 RPATH 编译的,也就是说,路径是硬编码在可执行文件中的,它指向 conda 环境。

这意味着我安装在这个特定环境中的vim只链接到同一个环境中的库,所以我可以在不同的环境中或者在我的系统中有不同的vim,有不兼容的版本,一切都很好,没有任何冲突。

但是你也可以注意到我们仍然依赖于一些基本的系统库,比如linux-vdso(一些内核功能的接口)、libc等等。这些不能与 conda 一起运输。这也是为什么 conda 环境不像 Docker 容器那样独立于系统。然而,这些系统库保证是向后兼容的,并且它们在任何 Linux 发行版上都提供相同的接口,所以它们不太可能导致任何问题。

macOS 也是如此,尽管系统库不同。

您甚至可以看到 conda 在您的环境中使用的 RPATH 设置。每次执行conda activate并激活环境时,conda 都会设置一些环境变量:

  1. CONDA_PREFIX:活动 CONDA 环境的根路径
  2. LDFLAGS:这是一个标准的 env 变量,由链接器在编译时读取。如果仔细查看,您会看到 RPATH 设置。例如,在我的笔记本电脑上,我看到:
(ds) giacomov@gr723gad9:~$ echo $LDFLAGS
-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections -Wl,-rpath,/home/user/miniconda3/envs/ds/lib -Wl,-rpath-link,/home/user/miniconda3/envs/ds/lib -L/home/user/miniconda3/envs/ds/lib

-rpath标志指示链接器将该路径硬编码为任何可执行文件中的 RPATH。这意味着当环境处于活动状态时编译可执行文件或库,它将包含 RPATH 设置。这是conda-build运作的基础,但那是以后的事了。

3.CXXFLAGS,CFLAGS:C 编译器的特定标志,包括 conda 环境中头文件的路径

结论

当然还有更多要说的,这篇文章已经够长了。我希望你能从中获得有用的信息,不管你是不是初学者。请随意发表评论和提出问题。

条件概率和三强争霸赛

原文:https://towardsdatascience.com/conditional-probability-and-the-triwizard-tournament-9c2ab6fe0af0?source=collection_archive---------56-----------------------

概率可以帮你避开匈牙利犀鸟!

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

李中清Unsplash 上拍照

概率通常用骰子和硬币来教授。在这篇文章中,我们将做一些不同的事情。我们将用《哈利·波特》中的例子来代替。今天我们将关注发生在《哈利·波特与火焰杯》三强争霸赛中的相关随机事件。

从属事件依赖于之前发生的事件。例如,纸牌游戏中的许多动作可以被认为是相关事件,因为从这副牌中抽取牌的概率取决于已经打出的牌。如果我要在 21 点游戏中算牌,我需要记住所有在洗牌前打出的牌,以便分析我赢一手牌的概率。

把条件概率看作是分析相关事件的一种方式。我们将条件概率表示为ℙ(A|B,这意味着在事件 b 已经发生的情况下,事件 a 发生的概率。

先决条件和符号

  • ω:样本空间;被认为是一个
  • ω:样本结果。
  • A :事件;ω的子集。
  • | A |:集合 A. 中元素的个数
  • a ∈ S :值 a 是集合 S 的“一个成员”或简单的“在”集合S中。

回想一下,上一篇帖子中的三强争霸赛示例,其中我们的样本空间是ω= { SSS,CWG,CF,HH}。为了说明相关事件的影响,让我们将样本空间改为如下:
ω= { SSS,SSS,CWG,CWG,CWG,CF,HH}其中

  1. 瑞典短吻
  2. CWG =普通威尔士绿色
  3. CF =中国火球
  4. HH =匈牙利犀鸟

选择瑞典短吻猪的几率是七分之二。如果芙蓉·德拉库尔选择了瑞典短吻鳄,那么选择瑞典短吻鳄的可能性有多大?自从我们从袋子里拿走了一条龙,机会就变了,因为现在少了一条。

这里的想法是,如果我们在巫师每次选择龙的时候都替换龙,那么概率不会改变,事件被认为是独立的。然而,在这个例子中,龙是而不是被替换,因此事件被认为是相关的。

定义:如果ℙ(A) > 0 那么 b 给定 a 的条件概率

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

让我们再多讨论一下这个符号。

在我们的例子中,假设事件 A 是“首先选择一只瑞典短吻鳄”,概率为 2/7,事件 B 是“其次选择一只瑞典短吻鳄”。

现在是棘手的部分,对于事件 B,我们有四个选择:

  1. 如果我们首先选择瑞典短吻龙,现在的概率是 1/6。
  2. 如果我们选择一个普通的威尔士绿色,现在的概率是 3/6。
  3. 如果我们选择一个中国火球,现在的概率是 1/6。
  4. 如果我们选择匈牙利犀鸟,现在的概率是 1/6。

我们必须规定哪个事件先发生。为了做到这一点,我们使用数学符号“|”来表示“给定”。因此,ℙ(A|B)的意思是“给定事件 b 的事件 a ”,也被称为给定事件 b 的条件概率。让我们使用我们的新符号来做一个例子。先选一条普通威尔士绿龙(事件 A),再选一条普通威尔士绿龙第二(事件 B)的几率有多大?所以我们可以从条件概率公式开始,稍微重新排列一下:

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

我们知道选择普通威尔士绿的概率是 3/7 (ℙ(A),但是在我们从袋子里取出那条龙之后,从袋子里选出的第二条龙不太可能是普通威尔士绿:ℙ(B|A) = 2/6。

所以我们输入数字:

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

这看起来很简单,但有时却很棘手。例如,ℙ(a|b = ℙ(b|a).通常不是这种情况事实上,它们可以是极其不同的!让我们在回答这个问题时想一想:假设我们首先选择了一个中国火球,选择瑞典短吻的概率是多少,ℙ(A|B?

第二,这种可能性是否等同于选择中国火球,而首先选择瑞典短吻海豚(ℙ(B|A)?

好吧,第一个问题的答案是 2/6,因为一旦我们去掉了中国的火球,袋子里就有两个瑞典的短吻海豚了。现在,如果我们先选择瑞典短吻猪,然后选择中国火球,这一事件的概率将是 3/6。看吧!不一样!ℙ(A|B)不等于ℙ(B|A)!

在下一场三强争霸赛中,你将会确切地知道你选择每条龙的概率。希望这个新技能能帮助你通过任务一。

通过微调 GPT-2 的条件文本生成

原文:https://towardsdatascience.com/conditional-text-generation-by-fine-tuning-gpt-2-11c1a9fc639d?source=collection_archive---------3-----------------------

给定一个标题和一系列关键词,GPT-2 能产生令人信服的假新闻吗?

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

照片由 Unsplash 上反推

虽然基于 transformer 的模型近年来在一系列自然语言处理任务上取得了良好的效果,但是文本生成仍然是一个令人好奇的案例。早在 2020 年 9 月,《卫报》发表了一篇令人印象深刻的文章,据称是由 OpenAI 的 GPT-3 从无到有撰写的,在主流媒体上广受好评,但许多人工智能专家仍然持怀疑态度

文本生成的一个问题是缺乏对其方向的控制。使用 GPT-3,你可以给模型一个介绍和说明,但即使这样,也需要一个人类编辑从多个输出中挑选和安排文本,使之具有凝聚力。还有其他方法,例如 Salesforce 的 CTRL 和 UberAI 的 PPLM

在本文中,我们将微调 Huggingface 预训练的 GPT-2,并提出我们自己的解决方案:通过选择数据集,我们可能会更好地控制文本样式和生成的内容。

数据

我们将使用来自新闻聚合数据集的样本。它包含来自著名新闻出版商的 40 多万篇新闻文章的标题和超链接。为了减少训练时间,我从 4 个新闻类别中随机抽取了大约 10k 篇文章:商业、科学、娱乐和健康。文章是预先下载的,以减少运行时间。

关键词提取

我们需要在训练过程中从每篇文章的关键字列表。有一系列可用的方法,从 Rake 到使用 BERT 的等等,但是我们在这里将坚持一个简单的 TFIDF ,因为这不是我们的主要关注点。在我们的关键字选择中,我们还将允许 2 个字母的短语组成一个专有名词短语,例如,“内容创建者”。此过程也是离线执行的,因为只需执行一次。

数据下载和关键词提取的代码可以在我的 GitHub 库中找到。

管道

管道设置包括定义记号化器、模型和数据集,然后使用训练器类进行微调,最后是文本生成。我假设您熟悉这个一般设置— 本文详细介绍了管道,如果您需要提醒的话。我将重点介绍为了实现条件文本生成,我做了哪些不同的工作。

您可以访问我的 Colab 笔记本中的完整代码了解更多详细信息,也欢迎您进行复制和实验。

模型

在这个实验中,我们将使用 12 层解码器的小型版 GPT-2。该模型在 800 万个网页上进行了训练,在语言任务方面已经相当强大。为了在采用我们的数据集时保持其在语言建模中的一般能力,我们将通过设置其参数来冻结底部 6 层。requires_grad 为 False,并且仅训练顶部 6 层。这也将加速训练,因为向后传球的次数减少了。

模型层的名称可以简单地通过打印(模型)找到。

培训设置

在标准的文本生成微调中,由于我们是在给定我们到目前为止看到的文本的情况下预测下一个标记,所以标签只是移位编码的标记化输入(注意,如果我们设置 labels=input_ids,则标签会在模型内自动移位—参见下面的参考文献 1)。

但是在这里,我们希望有更多的控制——除了文章文本,我们还会给模型一个标题和一个微调的关键字列表。我们在定制的数据集类中实现了这一点。

在标准设置中,我们在文本前面加上 bos_token,在后面加上 eos_token:

我们还将在文本前插入标题和关键字列表,用特殊的分隔符号分隔:

为了帮助模型泛化,我们通过使用函数 join_keywords()在训练期间对关键字列表进行采样和洗牌来引入数据扩充。但是在验证期间没有应用任何增加来保持跨时期的一致性。然后,按照标准实践,使用训练器类为少量时期(在我们的例子中是 4 个时期)训练模型。

结果

为了测试我们新的假新闻生成器的威力,我从 BBC 新闻中挑选了一条最近热门的轻松新闻:“当我们的照片成为一种模因时,我们感到非常悲伤”。通过使用相同的标题并(相当主观地)从文章中挑选几个关键词,让我们看看我们的模型能给它带来什么样的变化。要用的关键词是:‘火车’,‘小伙子’,‘喝酒’,‘图片’,‘搞笑’和‘insta gram’。

我们为语料库设置的关键字的大小相当大,但是如果我们想要使用的关键字不在这个集合中,我们总是可以使用集合中的同义词,或者在一些单词相似性度量方面最接近的一个。

有几种方法可以从模型中生成文本。如果我们使用波束搜索和采样,我们得到样本如下:

Unfortunately, all we have right now is an image that has gone viral.

The picture was taken by one of the boys on Instagram and quickly went viral after it appeared to show a group of friends getting drunk at a New York City bar.

As soon as the picture came out online, many people took to Twitter to express their disgust with the picture.

"What's wrong with this f**king train??," one user wrote.

Another said: "I can't believe my eyes didn't even open."

A third added: "Just saw some pictures of men being mugged in NYC... I'm so sick of these dumbasses."

This content is created and maintained by a third party, and imported onto this page to help users provide their email addresses. You may be able to find more information about this and similar content at piano.io

每一句都是语义连贯的,前三句也确实与标题有关,但随后文章发生了意想不到的转折。“这混账火车怎么了?”…我也在想这件事。随着“思想”列车慢慢偏离轨道,我们似乎有了一些控制,但可能还不够。

一些关键词(‘火车’、‘喝酒’、‘图片’和‘insta gram’,或者它们的同义词或内涵)按照指示被用在生成的文本中。但是,‘滑稽’没有用;相反,我们用了“厌恶”这个词,它有效地概括了作品的情绪,这很可能是因为我们选择的标题。

这与原始的 GPT-2 相比如何?使用标题作为第一句话,下面是一个来自原始模型的输出示例以供比较:

We got a lot of grief when our photo became a meme.

"I'm not going to lie, I don't know how many times we've been in that kind of situation," he said. "It's hard for me to put it into words."

He added: "There was no way this could have happened without the help of my family and friends who were there with us on Saturday night. We're all so proud of what they did as well."

这一段开头不错,但最后一句无意的转折泄露了秘密。不出所料,这些关键字根本不重要。

在某种程度上,我们试图做的是与文本摘要相反的事情——我们试图将标题扩展成一篇以关键词为特色的文章,希望标题的效果会渗透到整篇文章中。相比之下,原始的 GPT-2 只是从第一句话开始,标题的记忆效果可能更短暂。

回到我们的模型,我们也可以使用像 top-p (nucleus)采样这样的方法生成文本,这往往会产生更多的变体。这里有一些有趣的,听起来部分真实,部分有趣和令人不安。它们可能没有说服力,但至少很有趣:

It was like we were being mugged and all over again.

“I think it's really sad that this happened to us because people are so used by the pictures on their Instagram feeds... they just want attention," said Dr Emily Loughner-Bullock from Kings College London in England who works as an epidemiologist at King Mungol University School Of Public Health (KMU). ‘When you look back through history there have been many examples where celebrities can make headlines for quite controversial things - such is how social media has affected public health research into mental illness or addiction."

The story spread online after one famous photograph emerged which showed two young men with guns talking about drug use while drinking together before another took off his shirt revealing something he had hidden under her skirt: "Nice impression but I wonder if girls don't understand what 'hooking up' looks exactly?" wrote Shilpa Khetrapal Singh Khalsa Mukherjee following Twitter users sharing similar images showing them laughing happily out loud without any justification whatsoever behind some sort action picture taken during dinner parties held between friends...

There will be no further comment here due today afternoon..
When I was 12 years old my friends and family started seeing pictures from the train accident. It just made them cry so much that they took to Instagram after it happened:

As far as their reactions are concerned this is all very funny but if you take out your cell phone or tablet then these people will be talking about what went down in Boston today - there's no way we could have imagined how bad things would look with photos like those...
“It's hard to remember the day you started your life in this world and it was just too much for one kid. It is really sad that we can no longer celebrate those days with these photos because they were meant only as fun pictures."
Join us for the world’s leading event about accelerating enterprise transformation with AI and Data by signing up today
The internet was flooded in on Saturday morning after one man posted an extremely disturbing photograph to his Twitter account. In it he is seen sitting at home surrounded only wearing headphones – just as we have done before: The picture has gone viral! Here are some highlights from that hilarious moment…
1) It's been nearly six months since I saw this image
It was all very funny. It’s not like I'm going to stop posting photos because people will be more than happy with it and the memes are still growing every day on Twitter

A new poster for an American Idol-themed picture that appeared in The New York Post is showing up at this week's event where fans can get drunk together (and drink too) before their favorite shows!

仔细看看人工智能写作的现状,似乎记者不会很快被技术取代。

毕竟,这是我首先发表这篇文章的原因——否则我怎么能在道德上有理由在互联网上这么容易地制造一个有效的假新闻生成器呢?

参考和鸣谢

  1. 拥抱脸 GPT-2 文件
  2. 拥抱脸变形金刚示例
  3. 如何生成文本:用变形金刚使用不同的解码方法进行语言生成
  4. 杰伊·阿拉玛的插图版 GPT-2
  5. 为万智牌风味文本生成微调 GPT-2
  6. 伊恩·波特的 GPT-2 教程

用 FedJAX 进行联合学习研究

原文:https://towardsdatascience.com/conducting-federated-learning-research-with-fedjax-7be86d349a94?source=collection_archive---------15-----------------------

思想和理论ToF

关于使用 FedJAX 进行联合学习研究的十个或更少的要点

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

(图片由作者提供)ToF 中“o”顶部的️symbol 表示该 t of 的内容本质上更具技术性,因此可能更适合对机器学习以及编码概念更有经验的读者。

十个或更少的 (ToF 的简称,可以读作“tuff”)博客背后的想法是高效地分享围绕特定主题的主要概念、要点、观点等。具体来说,我会尽量简短,只说十件或更少的相关事情。

隶属关系披露:
我在
integrate . ai领导机器学习科学团队,在这里我们专注于让联合学习(FL)更容易实现。我不隶属于 FedJAX,也没有参与过这个开源项目。

**附送代码:https://github . com/integrate ai/openlab/tree/main/fed jax _ tutorial

(0) (一本 FL 入门书,你可以随意跳过,只要需要就可以回头查阅。) **FL 允许建立机器学习模型,而无需首先将数据带到中央位置。**在典型的 FL 设置中,有个客户端* ,它们各自将自己的数据集存放在自己的单独节点中,还有一个中央服务器,它“利用”这些非集中式数据集,以便构建一个全局 ML 模型(即,通常称为服务器模型),然后由所有客户端共享。重要的是,数据集从不聚集在一起形成大规模的训练数据集,而是保存在各自的客户端节点上,并且仅通过在每个客户端节点和中央服务器之间传递模型参数(或它们的更新)来促进训练。FL 框架的基本步骤如下(改编自 Ro,Suresh,Wu (2021) )。*

*Note that that FL training is done in multiple rounds, where in each round the following steps are taken:1\. Server selects a set of clients to participate in the current round;2\. Server communicates the current model parameters of the global, server model to the participating clients;3\. Each client creates a local version of the server model using the snapshot provided in 2\. and updates this by training it on its local data.4\. After performing it's individual client update, each client then communicates back the model parameters updates to the server.5\. The server takes the collection of client model parameter updates and performs an aggregation on them (e.g., via averaging).6\. The server updates the server model via the aggregated model parameter update computed in the previous step.*

(1) FedJAX 是一个进行 FL 研究的库。FedJAX 旨在缩短开展 FL 研究的周期时间(例如,为 FL 进行实验)并使其更加标准化。它通过两种方式做到这一点。首先,由于在进行 FL 模型的算法研究时,执行服务器和客户机之间的通信是完全不必要的,因此 FedJAX 模拟基本上跳过了步骤 2。第四。上面列出的。这是因为使用 FedJAX,多客户端 FL 设置只是在单台机器上虚拟创建的,因此,FedJAX 不应该用于构建和部署实际的 FL 解决方案。其次,FedJAX 为 FL 框架中的核心元素提供了方便的接口,例如:FederatedDataClientDatasetModelsClientSamplerFederatedAlgorithm,它们调用函数来处理客户端模型更新和服务器模型更新。

在 FedJAX 中执行 FL 培训的代码片段。

*(2) **上 FedJAX 一点都不差。*我发现在 FedJAX 上提升到可以在数据集上执行普通水平 FL 的水平相对简单。尽管在写这篇博客的时候还处于早期阶段,文档和官方代码还是很有帮助的。此外,正如学习任何新库的典型情况一样,有一点相关的学习曲线,所以我花了大约 1 周的时间才能够学习足够的库来完成两个示例:I)使用被分成 3400 个客户端的 EMNIST 数据集的示例;以及 ii)一个使用 CIFAR-10 数据集的示例,该数据集被分成 100 个客户端。对于 EMNIST 示例,我使用的数据集和 CNN 模型都是由 FedJAX 库提供的。相比之下,对于 CIFAR-10 示例,我使用 FedJAX 提供的帮助函数创建了一个定制数据集和一个定制 CNN 模型。下面分享了运行时和最终服务器模型的准确性,但是您也可以找到这两个示例的代码,以便自己执行它们这里

打印输出报告两个 FL 示例的性能指标和运行时间:EMNIST 和 CIFAR-10。

(3) 事先熟悉 JAX 并不是入门的必要条件,但对于使用 FedJAX 进行更严肃的研究来说,了解这一点是很重要的。在深入研究 FedJAX 之前,我没有和 JAX 一起工作过,但是我没有发现这是学习 FedJAX 接口和在前面提到的两个例子上运行 vanilla FL 的主要障碍。然而,当更深入地查看源代码时,我肯定开始意识到,我可以从更熟悉 JAX 中受益。所以,我觉得如果有人想使用 FedJAX 在外语方面做更严肃的研究,那么花时间熟悉 JAX,或许还有其他基于 JAX 的深度学习库,比如俳句,肯定是值得的。

接下来要说的三件事涵盖了 FedJAX ( *v=0.0.7* )库中提供的许多核心类中的三个,这些核心类支持标准化的外语模拟。

(4) FederatedData 是包含关于客户端数据集的元信息和用于在模拟外语训练下执行任务的便利方法的数据结构。此外,由于FederatedData可以被认为是提供了client_idClientDataset之间的映射,因此访问表示实际观察的类似数组的数据结构需要更多的工作——这在一定程度上反映了实际的 FL 设置,其中从客户端节点访问数据是具有挑战性的,或者出于隐私考虑,在没有干预的情况下甚至是不可能的。最后,FedJAX 方便地提供了从一个numpy.array创建一个小的定制FederatedData的功能,这是我在第二个例子中用来创建 CIFAR-10 数据集的功能。

从 numpy.array 创建 FederatedData 并访问客户端数据观察的示例代码片段。(改编自 FedJAX 文档中教程的代码)

*(5) Model **是用于指定服务器 ML 模型结构和损失函数的 FedJAX 类。*重要的是要注意到Model类是无状态的,这意味着在每个历元/回合之后的训练期间没有params属性被更新。相反,Model将其信息提供给jax.grad(),后者自动计算相关目标函数的梯度,并将这些信息传递给选定的Optimizer,后者最终返回一组完全符合Model结构的params。通过调用apply_for_eval()(或者apply_for_train(),如果需要一个随机键来为像 dropout 这样的东西注入随机性的话)可以生成对例子的预测。FedJAX 还提供了助手函数,用于从其他基于 JAX 的深度学习库(如 Haiku 或jax.example_libraries.stax)创建Model

对一批示例进行训练后获取一组新参数的代码片段。然后,新的参数可以被传递给另一轮训练或评估函数,该函数将参数和模型都作为输入。

(6) FederatedAlgorithm 是促进 FL 训练的类(即,客户端和服务器更新,或步骤 3。& 5。本博客顶部列出了一个 Model 上一个 FederatedData 。构建一个定制的FederatedAlgorithm将需要定义执行客户端模型更新以及聚合和服务器模型更新的函数,这些函数应该封装在它的apply()方法中。只有另外一个方法属于这个类,即init(),它初始化服务器模型的状态。FedJAX 还旨在通过利用可用的加速器来提高客户端更新的效率,因此,您需要以特定的方式定义客户端更新函数(即,通过三个函数client_initclient_stepclient_final)。

(7) 总的来说,FedJAX 得到了很多承诺。加速和规范外语研究的前提是好的。在撰写本文时,FedJAX 提供的接口既有用又方便,为更深入地研究 FL 打下了良好的基础。在不久的将来,我希望看到更多的数据集和基准有助于这个项目,以提高可重复性和整个领域的水平设置。此外,超越普通 FL 的更多模块和示例将使该项目更加相关,例如考虑不同隐私、跨客户端数据集的非 iid 案例、垂直 FL,甚至可能是非 SGD 类型的客户端/服务器模型的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值