Python-数据扩充-二-

77 阅读1小时+

Python 数据扩充(二)

原文:annas-archive.org/md5/2766659fe3db9ab25bc76eb90bd568a6

译者:飞龙

协议:CC BY-NC-SA 4.0

第四章:图像增强用于分割

图像分割,像图像分类一样,是计算机视觉领域的基石。图像分割涉及将属于同一对象的图像部分进行分组,也称为像素级分类。与图像分类不同,图像分类是识别和预测照片的主题或标签,而图像分割则决定一个像素是否属于某个对象列表——例如,一张城市照片包含街道、路标、汽车、卡车、自行车、建筑物、树木和行人。图像分割的任务是判断这个图像像素是否属于汽车、树木或其他物体。

深度学习DL),一种人工神经网络ANN)算法,在图像分割中取得了巨大的突破。例如,深度学习中的图像分割使得自动驾驶车辆和高级驾驶辅助系统ADAS)能够检测可导航的表面或行人。许多医学应用利用分割技术绘制肿瘤边界或测量组织体积。

图像增强方法无论是用于分割还是分类都是相同的,不同的是分割还需要附加的掩膜图像或真实图像。因此,我们在第三章中学到的关于增强图像用于分类的内容,也适用于增强图像分割。

本章旨在提供持续的几何和光度变换,用于图像分割。具体来说,你将学习以下主题:

  • 几何和光度变换

  • 现实世界中的分割数据集

  • 通过 Python 代码强化你的学习

有趣的事实

图像分割或语义分割在许多自动驾驶汽车的 AI 控制系统中都有应用。它用于识别街道上的物体和行人。世界各地的比赛胜负,主要取决于图像分割增强技术,例如Kaggle竞赛中的Udacity 和 Lyft 感知挑战的获胜者,采用了随机调整大小裁剪、水平翻转以及亮度、对比度和饱和度的随机颜色扰动。

让我们从分割的几何和光度变换开始。

几何和光度变换

如在第三章中讨论的那样,几何变换会改变图像的几何形状,例如通过翻转、裁剪、填充、旋转或调整大小。对于图像分割,当水平翻转图像时,必须对掩膜进行相同的处理。Pluto 将向你展示如何翻转原始图像及其对应的掩膜图像;下面是一个预览:

图 4.1 – 图像分割水平翻转

图 4.1 – 图像分割水平翻转

第三章 中讨论的许多安全值大多保持不变。例如,如果图像的主题是人或城市景观,分类增强不能垂直翻转,因为预测人的年龄或城市的名称依赖于图像不被颠倒。然而,分割的目的是将人或车进行分组或勾画轮廓。因此,垂直翻转是可以接受的。

对于许多真实世界的应用,安全范围需要进一步研究。例如,对于自动驾驶汽车,如果你遇到车祸并且你的车辆翻倒了呢?AI 是否仍然需要正确地分类周围环境?

光度变换,如亮度、饱和度、对比度、色相偏移和 FancyPCA,在应用于分割时更具挑战性,因为原始图像会被扭曲,但掩码图像不会。一个大问题是,仅增强原始图像而不增强掩码图像,会否提高预测的准确性?

Albumentations 库定义了 37 种变换,认为它们在扭曲原图和掩码图像时是安全的。

从技术上讲,你可以使用光度变换来进行分割,并用 Python 代码实现,但最好查阅已发布的学术论文以确认。我们在 第三章 中讨论的黄金增强规则也适用于此——你选择一种能提高预测准确性的过滤器,这种方法在已发布的学术论文中有描述。

使用 Python 代码进行学习是理解图像分割的另一种途径。然而,在我们进行之前,让我们请 Pluto 从 Kaggle 下载一些真实世界的分割数据集。

真实世界的分割数据集

Kaggle 网站是一个为数据科学家和机器学习爱好者提供的在线社区平台。它包含了成千上万的真实世界数据集,如在第一章第二章第三章中所提到的。

在寻找图像分割数据集时,Pluto 找到了大约 500 个可用的真实世界分割数据集。这些数据集的主题从自动驾驶汽车和医学到微型化石不等。Pluto 从热门市场领域中挑选了两个分割数据集。

另一个考虑因素是图像类型必须易于在 Albumentations 库中处理。Pluto 使用PILNumPy库来读取并将照片转换成三维数组。原始图像的shape是(宽度、高度和深度),其中深度通常等于三。掩码图像的shape是(宽度、高度),值为 0、1、2 等,直到标签的数量。

有趣的事实

PIL 库可以读取 .jpg.gif.tiff.png 等格式的图像文件,还有大约 50 种其他图像格式。然而,有时真实世界的分割数据集会带有 PIL 无法读取的图像格式。在这种情况下,Pluto 借助 Python 的ImageIO库,该库可以读取超过 100 种图像格式。

选中的两个分割数据集如下:

  • Cambridge-Driving Labeled Video (CamVid) 数据库是第一个真实世界的分割数据集。Kaggle 网站上的背景如下:

Cambridge-Driving Labeled Video Database (CamVid) 提供了将每个像素与 32 个语义类别之一关联的地面真值标签。该数据集常用于(实时)语义分割研究。

它于 2020 年由剑桥大学发布,许可证为CC BY-NC-SA 4.0creativecommons.org/licenses/by-nc-sa/4.0/

  • 第二个真实世界数据集叫做 空中图像语义分割。来自 Kaggle 网站的描述如下:

数据集由通过 MBRSC 卫星获取的迪拜空中图像组成,并通过像素级语义分割标注为 6 个类别。数据集的总容量为 72 张图像,分为 6 个较大的瓦片。

它于 2020 年由叙利亚 Roia 基金会发布,许可证为CC0: 公共领域creativecommons.org/publicdomain/zero/1.0/

选择两个分割数据集后,接下来的四个步骤你应该已经熟悉。如果需要澄清,请复习第二章第三章。步骤如下:

  1. 获取 Python Notebook 和 Pluto。

  2. 下载真实世界的数据。

  3. 将数据加载到 pandas 中。

  4. 查看数据图像。

有趣的挑战

Kaggle 网站或其他来源查找并下载两个额外的图像分割数据集。Kaggle 的竞赛和数据包含数百个图像分割数据集。因此,找到对你或你的工作有意义的图像分割数据集应该不成问题。提示:使用 Pluto 的 fetch_kaggle_dataset() or fetch_kaggle_comp_data() 函数。

让我们从 Pluto 开始。

Python Notebook 和 Pluto

从加载 data_augmentation_with_python_chapter_4.ipynb 文件到 Google Colab 或你选择的 Jupyter Notebook 或 JupyterLab 环境开始。从这一点起,代码片段将来自 Python Notebook,其中包含完整的函数。

接下来,你必须克隆仓库并使用%run命令启动 Pluto:

# clone the github
!git clone 'https://github.com/PacktPublishing/Data-Augmentation-with-Python'
# instantiate Pluto
%run 'Data-Augmentation-with-Python/pluto/pluto_chapter_3.py'

输出将如下所示,或类似:

---------------------------- : ---------------------------
            Hello from class : <class '__main__.PacktDataAug'> Class: PacktDataAug
                   Code name : Pluto
                   Author is : Duc Haba
---------------------------- : ---------------------------
                fastai 2.6.3 :  actual 2.7.9
---------------------------- : ---------------------------
        albumentations 1.2.1 : actual 1.2.1
---------------------------- : ---------------------------

仔细检查 Pluto 是否已正确加载:

# display Python and libraries version number
pluto.say_sys_info()

输出将如下所示,或根据你的系统类似:

---------------------------- : ---------------------------
                 System time : 2022/10/21 15:46
                    Platform : linux
     Pluto Version (Chapter) : 3.0
       Python version (3.7+) : 3.7.13 (default, Apr 24 2022, 01:04:09) [GCC 7.5.0]
            PyTorch (1.11.0) : actual: 1.12.1+cu113
              Pandas (1.3.5) : actual: 1.3.5
                 PIL (9.0.0) : actual: 7.1.2
          Matplotlib (3.2.2) : actual: 3.2.2
                   CPU count : 2
                  CPU speed : NOT available
---------------------------- : ---------------------------

Pluto 已验证 Python Notebook 正常工作。下一步是从 Kaggle 下载真实世界的图像数据集。

真实世界数据

以下下载功能来自第二章。Pluto 已在此处重用:

# Fetch Camvid photo
url = 'https://www.kaggle.com/datasets/carlolepelaars/camvid'
pluto.fetch_kaggle_dataset(url)
# Fetch Aerial image
url = 'https://www.kaggle.com/datasets/humansintheloop/semantic-segmentation-of-aerial-imagery'
pluto.fetch_kaggle_dataset(url)

在查看下载的照片之前,Pluto 需要将数据加载到 pandas DataFrame 中。

Pandas

这里需要进行一些清理任务,比如将目录或文件名中的空格字符替换为下划线,并将原始图像与掩码图像分开。清理后,Pluto 重用make_dir_dataframe()函数将原始图像数据读取到 pandas 数据框中。CamVid 数据的命令如下:

# import data to Pandas
f = 'kaggle/camvid/CamVid/train'
pluto.df_camvid = pluto.make_dir_dataframe(f)

前三条记录的输出如下:

图 4.2 – CamVid pandas 数据框,前 3 行

图 4.2 – CamVid pandas 数据框,前 3 行

掩码图像位于不同的文件夹中,且掩码图像的文件名在原文件名后加上了_L

Pluto 使用 pandas 的主要原因是,为匹配的掩码和原始文件名添加新列是个简单的任务。只有两行关键代码。第一行是在帮助函数中生成正确的掩码图像路径,第二行是创建新列以应用帮助函数。相关代码如下:

# define helper function
@add_method(PacktDataAug)
def _make_df_mask_name(self,fname):
  p = pathlib.Path(fname)
  return (str(p.parent.parent) +
    '/' + str(p.parent.name) + '_labels/' +
    str(p.stem) + '_L' + str(p.suffix))
# method definition
@add_method(PacktDataAug)
def make_df_mask_name(self,df):
  df['mask_name'] = df.fname.apply(self._make_df_mask_name)
  return

完成 CamVid 数据框的命令如下:

# create mask file name
pluto.make_df_mask_name(pluto.df_camvid)

输出结果如下:

图 4.3 – 完整的 CamVid 数据框,前 3 行

图 4.3 – 完整的 CamVid 数据框,前 3 行

一旦 Pluto 将所有信息整理到数据框中,下一步就是展示原始图像与掩码图像。

查看数据图像

Pluto 可以重用第二章中的draw_batch()函数,以分批显示原始图像和掩码图像,但结果无法加强原始图像与掩码图像的结合。因此,Pluto 将修改draw_batch()方法,创建一个新的draw_batch_segmentation()方法,并设计一个名为_draw_batch_segmentation()的帮助函数。

结果展示了原始图像,接着是掩码图像,并重复此过程。显示 CamVid 分割照片的命令如下:

# use new batch display method for segmentation
pluto.draw_batch_segmentation(pluto.df_camvid,
  is_shuffle=True)

输出结果如下:

图 4.4 – CamVid 的原始图像与掩码图像批次

图 4.4 – CamVid 的原始图像与掩码图像批次

分割批次看起来是正确的,因此 Pluto 对航拍分割数据重复相同的过程。

使用以下命令下载数据:

# fetch real-world data
url = 'https://www.kaggle.com/datasets/humansintheloop/semantic-segmentation-of-aerial-imagery'
pluto.fetch_kaggle_dataset(url)

清理目录和文件名,然后使用以下命令将它们导入到 pandas 中:

# import to Pandas
f = 'kaggle/semantic-segmentation-of-aerial-imagery'
pluto.df_aerial = pluto.make_dir_dataframe(f)

前五条记录的输出如下:

图 4.5 – 航拍 pandas 数据框,前 3 行

图 4.5 – 航拍 pandas 数据框,前 3 行

使用新的帮助函数添加掩码的文件名,如下所示:

# create mask filename
pluto.make_df_mask_name_aerial(pluto.df_aerial)

前三条记录的输出如下:

图 4.6 – 完整的航拍数据框,前 3 行

图 4.6 – 完整的航拍数据框,前 3 行

使用以下命令显示分割图像批次:

# draw batch image
pluto.draw_batch_segmentation(pluto.df_aerial,
  is_shuffle=True)

输出结果如下:

图 4.7 – 航拍 pandas 数据框,前五行

图 4.7 – 航拍 pandas 数据框,前五行

有趣的挑战

这是一个思维实验:给定一个图像数据集,你如何为这些照片创建掩膜?提示:你可以使用高级图像软件自动描绘物体或轮廓,然后进行标注。其他选择是使用 Mechanical Turk 或众包。你应该考虑成本与时间的平衡。

Pluto 已经成功下载并展示了 CamVid 和航拍分割照片。现在,让我们用 Python 进行一些图像增强。

强化你的学习

分类图像变换的相同概念适用于分割图像变换。在这里,Pluto 重复使用或稍微修改了第三章中的包装函数。特别地,Pluto 为分割处理黑客化了以下方法:

  • 水平翻转

  • 垂直翻转

  • 旋转

  • 随机调整大小和裁剪

  • 转置

  • 光照

  • FancyPCA

有趣的事实

你无法完成或理解本章节,除非你已经阅读了第三章。这是因为 Pluto 重复使用或稍微修改了现有的图像增强包装函数。

Pluto 选择这些滤镜是因为 Albumentations 库将它们标记为安全的分割方法。所以,让我们从水平翻转开始。

水平翻转

Pluto 在第三章中使用 PIL 库演示了水平翻转,因为代码易于理解。因此,他将draw_image_flip_pil()函数黑客化为draw_image_flip_pil_segmen()函数。转换代码是相同的——即,PIL.ImageOps.mirror(img)。变化之处在于将图像并排显示。

在 Python Notebook 中,翻转 CamVid 数据集图像的命令如下:

# use wrapper function to flip image
pluto.draw_image_flip_pil_segmen(pluto.df_camvid.fname[0])

输出结果如下:

图 4.8 – 使用 PIL 库翻转图像

图 4.8 – 使用 PIL 库翻转图像

Pluto 使用相同的函数处理掩膜图像,并将mask_image列传入 pandas 数据框。这就是这么简单。Pluto 必须使用相同的滤镜来转换原始图像和掩膜图像。

翻转掩膜图像的命令如下:

# use wrapper function to flip image mask
pluto.draw_image_flip_pil_segmen(pluto.df_camvid.mask_name[0]

输出结果如下:

图 4.9 – 使用 PIL 库翻转掩膜

图 4.9 – 使用 PIL 库翻转掩膜

有趣的事实

Pluto 在本书中仅展示相关的代码片段,但完整的面向对象方法可以在 Python Notebook 中找到。本章的代码与第三章中的代码非常相似。Pluto 使用第一章提供的原则布局设计了软件架构。因此,代码看起来简洁,但在后台包含了较高的复杂性。

从底层来看,彩色图像是一个三维数组或Rank 3 张量。图像的形状为(宽度、高度和深度),其中深度通常为 3,而掩码图像的形状为(宽度、高度),其中值为 0、1、2 等,一直到标签数量。因此,镜像Rank 3 张量的操作与镜像Rank 1 张量的操作相同。

对于 Albumentations 库,分割的包装函数与在第三章中提供的非常简单。draw_image_flip_segmen() 方法的代码如下:

# method definition
@add_method(PacktDataAug)
def draw_image_flip_segmen(self,df):
  aug_album = albumentations.HorizontalFlip(p=1.0)
  self._draw_image_album_segmentation(df,aug_album,
    'Horizontal Flip')
  return

它与我们在第三章中提供的 draw_image_flip() 函数相同。不同之处在于,使用了不同的辅助函数。它没有使用 _draw_image_album() 辅助函数,而是使用了 _draw_image_album_segmentation() 方法。

对 CamVid 分割数据在 Python Notebook 中执行水平翻转的命令如下:

# use wrapper function to flip both image and image mask
pluto.draw_image_flip_segmen(pluto.df_camvid)

输出如下:

图 4.10 – CamVid 数据集的水平翻转

图 4.10 – CamVid 数据集的水平翻转

对航拍分割数据执行水平翻转的命令如下:

# use the same flip segmentation wrapper function on arial
pluto.draw_image_flip_segmen(pluto.df_aerial)

输出如下:

图 4.11 – 航拍数据集的水平翻转

图 4.11 – 航拍数据集的水平翻转

如同在第三章中所述,本章中的包装函数每次都会随机选择一批新的图像。

有趣的挑战

这里有一个思维实验:你如何利用图像分割来支持环保组织,例如野生动物保护组织?提示:考虑海关人员如何使用 iPhone 或**闭路电视(CCTV)**监控系统,在开放市场中发现有人出售濒危物种的部分,如象牙或萨嘎角。

Pluto 使用垂直翻转滤镜完成了翻转操作。

垂直翻转

垂直翻转的包装函数几乎与水平翻转方法相同。Pluto 本可以写一个通用函数来替代每个包装方法的独立实现。但目标是解释每个转换,而不是将其重构为更紧凑或更高效的代码。包装函数的关键代码行如下:

# use albumentations library function
aug_album = albumentations.Flip(p=1.0)

在 Python Notebook 中对 CamVid 分割数据执行垂直翻转的命令如下:

# use flip wrapper function for camvid data
pluto.draw_image_flip_both_segmen(pluto.df_camvid)

输出如下:

图 4.12 – CamVid 数据集的垂直翻转

图 4.12 – CamVid 数据集的垂直翻转

对航拍分割数据执行垂直翻转的命令如下:

# use flip wrapper function for aerial image
pluto.draw_image_flip_both_segmen(pluto.df_aerial)

输出如下:

图 4.13 – 航拍数据集的垂直翻转

图 4.13 – 航拍数据集的垂直翻转

翻转操作到此为止。现在,让我们来看一下旋转。

旋转

旋转的安全参数可以顺时针或逆时针旋转 45 度。Albumentations 方法如下:

# use albumentation library function for rotating
aug_album = albumentations.Rotate(limit=45, p=1.0)

用于在 Python Notebook 中旋转 CamVid 分割数据的命令如下:

# use rotate wrapper function for camvid image
pluto.draw_image_rotate_segmen(pluto.df_camvid)

输出如下:

图 4.14 – 旋转 CamVid 数据集

图 4.14 – 旋转 CamVid 数据集

用于旋转航拍分割数据的命令如下:

# use rotate wrapper function for aerial image
pluto.draw_image_rotate_segmen(pluto.df_aerial)

输出如下:

图 4.15 – 旋转航拍数据集

图 4.15 – 旋转航拍数据集

下一个滤镜是调整大小和裁剪。

调整大小和裁剪

分类模型旨在识别对象,而分割模型则按像素对对象进行分组。因此,裁剪和调整大小是在相对较高的安全参数下可以接受的变换。包装函数的关键代码行如下:

# use albumentations function for resizing and cropping
aug_album = albumentations.RandomSizedCrop(
  min_max_height=(500, 600),
  height=500,
  width=500,
  p=1.0)

用于随机调整大小和裁剪 CamVid 分割数据的 Python Notebook 命令如下:

# use resize and crop wrapper functiion for camvid photo
pluto.draw_image_resize_segmen(pluto.df_camvid)

输出如下:

图 4.16 – 调整大小和裁剪 CamVid 数据集

图 4.16 – 调整大小和裁剪 CamVid 数据集

用于随机调整大小和裁剪航拍分割数据的命令如下:

# use resize and crop wrapper functiion for aerialphoto
pluto.draw_image_resize_segmen(pluto.df_aerial)

输出如下:

图 4.17 – 调整大小和裁剪航拍数据集

图 4.17 – 调整大小和裁剪航拍数据集

接下来,我们将介绍转置滤镜。

转置

Pluto 没有在第三章中使用转置滤镜进行分类,但对于分割是可以接受的。转置是指交换 x 轴y 轴。包装函数的关键代码行如下:

# use albumentations library for transpose
aug_album = albumentations.Transpose(p=1.0)

用于转置 CamVid 分割数据的命令如下:

# use transpose wrapper function for camvid data
pluto.draw_image_transpose_segmen(pluto.df_camvid)

输出如下:

图 4.18 – 转置 CamVid 数据集

图 4.18 – 转置 CamVid 数据集

用于转置航拍分割数据的命令如下:

# use transpose wrapper function for aerial data
pluto.draw_image_transpose_segmen(pluto.df_aerial)

输出如下:

图 4.19 – 转置航拍数据集

图 4.19 – 转置航拍数据集

有趣的挑战

在 Python Notebook 中实现光学畸变。提示:使用与 Albumentations 库函数 albumentations.OpticalDistortion() 方法类似的 Pluto 包装函数。

转置是 Pluto 用于几何变换的最后一个示例。光照,也称为亮度,属于光度变换类。

光照

光照或亮度在 Albumentations 库中是可以接受的分割变换,但它属于光度变换类。原始图像会变更为随机亮度级别,直到安全水平,但掩码图像不会改变。对于两个数据集,安全参数的亮度为 0.5。包装函数中的关键代码行如下:

# use albumentations library for brightness
aug_album = albumentations.ColorJitter(
  brightness=brightness,
  contrast=0.0,
  saturation=0.0,
  hue=0.0,
  always_apply=True,
  p=1.0)

用于对 CamVid 分割数据应用光照的命令如下:

# use the brightmess wrapper function for camvid image
pluto.draw_image_brightness_segmen(pluto.df_camvid)

输出如下:

图 4.20 – 在 CamVid 数据集上使用闪电

图 4.20 – 在 CamVid 数据集上使用闪电

使用闪电处理空中分割数据的命令如下:

# use the brightmess wrapper function for aerial image
pluto.draw_image_brightness_segmen(pluto.df_aerial)

输出如下:

图 4.21 – 在空中数据集上使用闪电

图 4.21 – 在空中数据集上使用闪电

类似于光照滤镜,FancyPCA 属于光度变换类。

FancyPCA

FancyPCA 是 Pluto 演示的最后一个光度变换示例。对于这两个数据集,安全的参数是 alpha 值为 0.3。再次强调,FancyPCA 不会改变掩码图像。包装函数中的关键代码行如下:

# use albumentations library for fancyPCA
aug_album = albumentations.FancyPCA(
  alpha=alpha,
  always_apply=True,
  p=1.0)

使用 FancyPCA 处理 CamVid 分割数据的命令如下:

# use the fancyPCA wrapper function for camvid image
pluto.draw_image_fancyPCA_segmen(pluto.df_camvid)

输出如下:

图 4.22 – 在 CamVid 数据集上使用 FancyPCA

图 4.22 – 在 CamVid 数据集上使用 FancyPCA

使用 FancyPCA 处理空中分割数据的命令如下:

# use the fancyPCA wrapper function for aerial image
pluto.draw_image_fancyPCA_segmen(pluto.df_aerial)

输出如下:

图 4.23 – 在空中数据集上使用 FancyPCA

图 4.23 – 在空中数据集上使用 FancyPCA

有趣的挑战

这里有一个思维实验,或者也许是一个实践题:你能做什么看起来在图像增强中是可接受的,但在实际部署中有很高概率产生 假阳性假阴性 预测?抱歉,没有提示。

Pluto 发现,分割增强与分类增强并没有太大区别。包装函数几乎相同,只有辅助方法以不同的方式显示图像。Pluto 已经展示了翻转、调整大小、裁剪、旋转、转置、光照和 FancyPCA 变换的分割处理。与 第三章 类似,接下来,Pluto 将把各个滤镜组合成一个超级函数。

组合

在 Python 中编码超级组合方法之前,Pluto 需要使用 pandas 汇总本章中的滤镜。分割操作适用更多的变换,因此如果你在 Python 笔记本中试验其他滤镜,可以通过你的新滤镜扩展 pandas 表格。

Pluto 使用以下命令显示汇总表格:

# use Pandas to display the combination filters
pluto.print_safe_parameters_segmen()

输出如下:

图 4.24 – 汇总分割滤镜

图 4.24 – 汇总分割滤镜

使用汇总表格,Pluto 编写了包装函数。关键的代码行如下:

# use albumentations library
aug_album = albumentations.Compose([
  albumentations.ColorJitter(brightness=0.5,
    contrast=0.0,
    saturation=0.0,
    hue=0.0,p=0.5),
  albumentations.HorizontalFlip(p=0.5),
  albumentations.Flip(p=0.5),
  albumentations.Rotate(limit=45, p=0.5),
  albumentations.RandomSizedCrop(
    min_max_height=(500, 600),
    height=500,
    width=500,
    p=0.5),
  albumentations.Transpose(p=0.5),
  albumentations.FancyPCA(alpha=0.2, p=0.5)])

Pluto 显示了 CamVid 数据集的组合分割变换,如下所示:

# use combination wrapper function for camvid photo
pluto.draw_uber_segmen(pluto.df_camvid)

输出如下:

图 4.25 – 组合 CamVid 数据集的滤镜

图 4.25 – 组合 CamVid 数据集的滤镜

空中数据集在 Python 笔记本中的命令如下:

# use combination wrapper function for aerial photo
pluto.draw_uber_segmen(pluto.df_aerial)

输出如下:

图 4.26 – 组合空中数据集的滤镜

图 4.26 – 为航拍数据集组合过滤器

有趣的挑战

Pluto 挑战你重构 Pluto 类,使其更快、更紧凑。你被鼓励创建并上传你的库到 GitHub 和 PyPI.org。此外,你不必将类命名为 PacktDataAug,但如果你引用或提到本书,Pluto 和他的人类伙伴将非常高兴。代码的目标是易于理解、可重用的模式以及在 –Python Notebook 中教学。因此,将代码重构为 Python 库将相对轻松且有趣。

到这里,你已经学会了如何组合分割转换。接下来,我们将总结本章所涵盖的内容。

摘要

图像分割由原始图像和附带的掩膜图像组成。目标是确定某个像素是否属于某个对象列表。例如,一张城市照片包含街道、街道标志、汽车、卡车、自行车、建筑物、树木和行人。图像分割的任务是判断这个像素是属于汽车、树木还是其他物体。

图像分割和图像分类共享相同的转换。换句话说,大多数几何转换,如翻转、旋转、调整大小、裁剪和转置,适用于图像分割中的原始图像和掩膜图像。光度转换,如亮度、对比度和 FancyPCA,技术上可以通过 Python 实现,但这些过滤器不会改变掩膜图像。另一方面,像噪声注入和随机擦除这样的过滤器不适用于分割,因为它们会在原始图像中添加或替换像素。

在本章中,有许多 有趣的事实有趣的挑战。Pluto 希望你能利用这些内容,拓展你的经验,超越本章的范围。

切换话题,下一章将讨论文本增强。Pluto 不能使用任何图像增强功能,但他可以重用用于从 Kaggle 网站下载数据集的包装函数。

第三部分:文本增强

本部分包含以下章节:

  • 第五章文本增强

  • 第六章机器学习中的文本增强

第五章:文本增强

文本增强是一种在自然语言处理NLP)中使用的技术,通过修改或从现有文本数据创建新文本来生成额外数据。文本增强涉及的技术包括字符交换、噪声注入、同义词替换、单词删除、单词插入和单词交换。图像和文本增强的目标相同,它们都旨在增加训练数据集的大小并提高 AI 预测的准确性。

文本增强相对较难评估,因为它不像图像增强那样直观。图像增强技术的意图很明确,比如翻转照片,但字符交换技术可能会让读者感到困惑。因此,读者可能会将其益处视为主观的。

文本增强的效果取决于生成数据的质量以及正在执行的具体 NLP 任务。确定给定数据集所需的适当安全级别的文本增强可能会非常具有挑战性,这通常需要实验和测试才能获得预期的结果。

客户反馈或社交媒体上的聊天内容是文本增强的合理素材,因为这些内容通常杂乱无章,并且大多数包含语法错误。相反,法律文件或书面医疗通讯,如医生处方或报告,则不适合进行文本增强,因为这些内容要求精确表达。换句话说,错误注入、同义词替换甚至 AI 生成的文本可能会改变法律或医学的含义,超出安全水平。

文本增强中的偏差同样很难察觉。例如,通过故意拼写错误单词来使用键盘增强方法添加噪声,可能会引入对现实世界推文的偏见,而这些推文通常包含拼写错误的单词。没有普遍适用的规则可循,答案只有在深入研究数据并审查 AI 预测目标后才能显现出来。

有趣的事实

随着生成型 AI 的普及,你可以使用OpenAI 的 GPT-3Google BardFacebook 的 Roberta系统生成原创文章用于文本增强。例如,你可以让生成型 AI 创建关于公司产品的正面或负面评论,然后使用 AI 编写的文章来训练情感分析预测 AI。

第五章中,你将学习文本增强,并如何在 Python 笔记本中编写相关方法。特别是,我们将涵盖以下主题:

  • 字符增强

  • 单词增强

  • 句子和流程增强

  • 文本增强库

  • 真实世界文本数据集

  • 通过 Python 笔记本强化学习

让我们从最简单的主题开始,字符增强。

字符增强

字符增强会替换或注入字符到文本中。换句话说,它会制造打字错误。因此,这种方法似乎是违反直觉的。然而,就像图像增强中的噪声注入一样,学术论文展示了字符增强在提高 AI 预测准确性方面的好处,例如Zhuosheng Zhang, Yafang Huang, Pengfei Zhu 和 Hai Zhao于 2018 年在《CCF 国际自然语言处理会议》上发表的《有效的字符增强词嵌入用于机器阅读理解》。

三种标准的字符增强方法如下所示:

  • 光学字符识别(OCR)增强功能通过将图像转换为文本来替代 OCR 中常见的错误,例如将字母o转换为数字0,或将大写字母I转换为数字1

  • 键盘增强方法将字符替换为其相邻的其他字符。例如,字符b的常见打字错误是按下v键或n键。

  • 随机字符功能会在文本中随机交换、插入或删除字符。

有趣的事实

计算机编码文本在 1963 年至 1970 年期间有很大不同;例如,计算机会将字母A编码为整数 64 或十六进制 41。这一做法起源于 1964 年的美国国家标准学会ANSI),并在 1970 年左右被国际标准化组织ISO)采纳。1980 年,统一码Unicode)取代了 ISO 标准,适用于所有国际语言。然而,如果你遇到来自 1964 年左右的计算机文本,它可能采用扩展二进制编码十进制交换码EBCDIC),它将字母A编码为 193 或十六进制 C1。作为程序员,你可能需要回答这样一个问题:你的网站或移动应用是否支持 Unicode?

在字符增强之后,接下来的类别是单词增强。

单词增强

单词增强与字符增强具有相同的偏差和安全级别警告。超过一半的这些增强方法会向文本中注入错误,但其他功能则使用同义词或预训练的 AI 模型生成新文本。标准的单词增强功能如下所示:

  • 拼写错误增强功能使用预定义的字典模拟拼写错误。它基于Claude Coulombe在 2018 年发布的学术论文《通过利用 NLP 云 API 简化文本数据增强》。

  • 分割增强功能会将单词随机分成两个词元。

  • 随机词增强方法通过四个参数对文本应用随机行为:替换交换删除裁剪。它基于两篇学术论文:Yonatan Belinkov 和 Yonatan Bisk于 2018 年发表的《Synthetic and Natural Noise Both Break Neural Machine Translation》以及Gozde Gul SahinMark Steedman的《Data Augmentation via Dependency Tree Morphing for Low-Resource Languages》。

  • 同义词增强功能用来自预定义数据库的同义词替换单词。第一个选项是使用WordNet。WordNet 是普林斯顿大学提供的一个广泛的英语词汇数据库。该数据库将名词、动词、形容词和副词分组为认知同义词集。第二个选项是使用同义词数据库PPDB)。PPDB 是一个自动提取的数据库,包含 16 种语言的数百万个同义词。PPDB 旨在通过增强系统对语言变异性和未见过单词的鲁棒性来改善语言处理。整个 PPDB 资源可在美国创意共享署名****3.0许可证下免费获取。

  • 反义词增强功能用反义词替换单词。它基于Tong NiuMohit Bansal于 2018 年发表的学术论文《Adversarial Over-Sensitivity and Over-Stability Strategies for Dialogue Models》。

  • 保留字增强方法在你定义的单词列表中交换目标单词。它与同义词相似,只是这些术语是手动创建的。

有趣的挑战

这里有一个思想实验:你能想出一种新的字符或单词增强技术吗?一个提示是考虑一下阅读障碍者是如何阅读的。

接下来,我们将看看句子增强。

句子增强

句子增强使用生成式 AI 来创建新文本。AI 模型的例子有 BERT、Roberta、GPT-2 等。

三种句子增强方法如下所示:

  • 上下文词嵌入使用 GPT-2、Distilled-GPT-2 和 XLNet。

  • 抽象总结使用 Facebook Roberta 和 T5-Large。

  • Top-n 相似词使用 LAMBADA。

在 Pluto 解释 Python 笔记本中的代码之前,我们先来回顾一下文本增强库。

文本增强库

比起文本增强库,Python 中开源的图像增强库更多。有些库对特定类别的适应性比其他库更强,但通常来说,选择一到两个库并精通它们是一个不错的选择。

知名的库有Nlpaug自然语言工具包NLTK)、生成相似Gensim)、TextBlobTextAugmentAugLy

  • Nlpaug是一个用于深度学习文本增强的库。其目标是通过生成文本数据来提高深度学习模型的表现。GitHub 链接是github.com/makcedward/nlpaug

  • NLTK 是一个用于构建 Python 程序以处理人类语言数据的平台。它提供了对超过 50 种语料库和词汇资源的接口,例如 WordNet。NLTK 包含用于分类、分词、词干提取、标注、解析和语义推理的文本处理库。GitHub 链接是 github.com/nltk/nltk

  • Gensim 是一个流行的开源 NLP 库,用于无监督主题建模。它利用学术模型和现代统计机器学习来执行词向量、语料库、主题识别、文档比较和分析纯文本文档。GitHub 链接是 github.com/RaRe-Technologies/gensim

  • TextBlob 是一个用于处理文本数据的库。它提供了一个简单的 API,方便处理典型的 NLP 任务,如词性标注、名词短语提取、情感分析、分类和翻译。GitHub 链接是 github.com/sloria/TextBlob

  • TextAugment 是一个用于增强 NLP 应用中文本的库。它使用并结合了 NLTK、Gensim 和 TextBlob 库。GitHub 链接是 github.com/dsfsi/textaugment

  • AugLy 是 Facebook 提供的一个数据增强库,支持音频、图像、文本和视频模块,并提供超过 100 种增强方法。每种模态的增强被分类到不同的子库中。GitHub 链接是 github.com/facebookresearch/AugLy

)

与图像增强包装函数类似,Pluto 将编写包装函数,通过库实现底层功能。你可以为一个项目选择多个库,但 Pluto 将使用 Nlpaug 库来支持这些包装函数。

让我们从 Kaggle 网站下载真实世界的文本数据集。

真实世界的文本数据集

Kaggle 网站是一个面向数据科学家和机器学习爱好者的在线社区平台。Kaggle 网站有成千上万的真实世界数据集;Pluto 在其中找到了约 2,900 个 NLP 数据集,并选择了两个 NLP 数据集用于本章内容。

第二章 中,Pluto 以 NetflixAmazon 数据集为例,帮助理解偏差问题。Pluto 保留了 Netflix 的 NLP 数据集,因为电影评论是经过筛选的。虽然存在一些语法错误,但整体上输入文本质量较高。

第二个 NLP 数据集是 Twitter 情感分析 (TSA)。29,530 条真实世界的推文包含许多语法错误和拼写错误。挑战在于将推文分类为两类: (1) 正常,或 (2) 种族歧视和性别歧视。

数据集由 Mayur Dalvi 于 2021 年发布,许可证为 CC0: 公共领域creativecommons.org/publicdomain/zero/1.0/

选择两个 NLP 数据集后,您可以使用相同的四个步骤,通过 Python Notebook 开始实际学习的过程。如果需要澄清,可以参考第二章第三章。步骤如下:

  1. 获取 Python Notebook 和 Pluto。

  2. 下载真实世界数据。

  3. 导入到 pandas。

  4. 查看数据。

让我们从 Pluto 开始。

Python Notebook 和 Pluto

从将 data_augmentation_with_python_chapter_5.ipynb 文件加载到 Google Colab 或您选择的 Jupyter notebook 或 JupyterLab 环境开始。从此开始,代码片段来自 Python Notebook,其中包含完整代码。

下一步是克隆代码库。Pluto 将重用来自第二章的代码,因为它包含下载 Kaggle 数据的方法,而不包含图像增强功能。!git%run 语句用于启动 Pluto。命令如下:

# clone GitHub repo
!git clone 'https://github.com/PacktPublishing/Data-Augmentation-with-Python'
# instantiate Pluto
%run 'Data-Augmentation-with-Python/pluto/pluto_chapter_2.py'

输出如下:

---------------------------- : ---------------------------
            Hello from class : <class '__main__.PacktDataAug'> Class: PacktDataAug
                   Code name : Pluto
                   Author is : Duc Haba
---------------------------- : ---------------------------

我们需要进行最后一次检查,以确保 Pluto 已经成功加载。以下命令让 Pluto 报告他的状态:

pluto.say_sys_info()

输出应该如下所示,或根据您的系统可能有所不同:

---------------------------- : ---------------------------
                 System time : 2022/10/30 06:52
                    Platform : linux
     Pluto Version (Chapter) : 2.0
             Python (3.7.10) : actual: 3.7.15 (default, Oct 12 2022, 19:14:55) [GCC 7.5.0]
            PyTorch (1.11.0) : actual: 1.12.1+cu113
              Pandas (1.3.5) : actual: 1.3.5
                 PIL (9.0.0) : actual: 7.1.2
          Matplotlib (3.2.2) : actual: 3.2.2
                   CPU count : 2
                  *CPU speed : NOT available
---------------------------- : ---------------------------

在这里,Pluto 报告说他来自第二章,也就是版本 2.0。这正是我们所需要的,因为我们不需要来自第三章第四章的任何图像增强功能。下一步是下载真实世界的 NetflixTwitter NLP 数据集。

真实世界的 NLP 数据集

目前尚未为本章编写新代码。Pluto 重用 fetch_kaggle_dataset() 方法下载 Netflix 数据集,具体如下:

# fetch data
url = 'https://www.kaggle.com/datasets/infamouscoder/dataset-netflix-shows'
pluto.fetch_kaggle_dataset(url)

dataset-netflix-shows.zip 文件大小为 1.34 MB,功能会自动解压到 kaggle 目录中。

获取 Twitter 数据集的方法如下:

# fetch data
url = 'https://www.kaggle.com/datasets/mayurdalvi/twitter-sentiments-analysis-nlp'
pluto.fetch_kaggle_dataset(url)

twitter-sentiments-analysis-nlp.zip 文件大小为 1.23 MB,功能会自动解压到 kaggle 目录中。

有趣的挑战

挑战是从 Kaggle 网站搜索并下载两个额外的真实世界 NLP 数据集。提示:使用 pluto.fetch_kaggle_dataset() 方法。Pluto 是一只虚拟的数字西伯利亚哈士奇犬。因此,他会一直开心地获取数据,直到你的磁盘空间用尽。

下一步是将数据加载到 pandas 中。

Pandas

fetch_df() 方法。请注意,df 是 pandas DataFrame 类的典型缩写。

对于 Netflix 数据,Pluto 使用以下两个命令将数据导入 pandas 并打印出数据批次:

# import into Panda
f = 'kaggle/dataset-netflix-shows/netflix_titles.csv'
pluto.df_netflix_data = pluto.fetch_df(f)
# display data batch
pluto.print_batch_text(pluto.df_netflix_data,
  cols=['title', 'description'])

输出如下:

图 5.1 – Netflix 电影描述

图 5.1 – Netflix 电影描述

有趣的事实

fetch_df() 方法随机选择若干记录显示在数据批次中。记录的数量或批次大小是 bsize 参数,默认是 10 条记录。

Netflix 电影评论数据经过整理,因此是干净的。Pluto 不需要清洗这些数据。然而,Twitter 数据就另当别论了。

清洗、导入并批量显示 Twitter 数据到 pandas 的命令如下:

# clean space-char
f = 'kaggle/twitter-sentiments-analysis-nlp'
!find {f} -name "* *" -type f | rename 's/ /_/g'
# import into Pandas
f = 'kaggle/twitter-sentiments-analysis-nlp/Twitter_Sentiments.csv'
pluto.df_twitter_data = pluto.fetch_df(f)
# display data batch
pluto.print_batch_text(pluto.df_twitter_data,cols=['label', 'tweet'])

输出如下:

图 5.2 – Twitter 推文

图 5.2 – Twitter 推文

由于来自 Twitter 的现实世界推文是由公众编写的,它们包含拼写错误、脏话以及各种胡闹。

目标是预测普通推文与种族主义或性别歧视推文。Pluto 重点学习文本论证,因此他希望推文中包含可打印字符,没有 HTML 标签,也没有脏话。

Pluto 编写了两个简单的辅助方法来清洗文本并去除脏话。_clean_text() 函数使用了 regex 库,代码如下:

return (re.sub('[^A-Za-z0-9 .,!?#@]+', '', str(x)))

_clean_bad_word() 辅助函数使用了 filter-profanity 库,代码如下:

return (profanity.censor_profanity(x, ''))

clean_text() 方法利用 pandas 强大的 apply 函数结合这两个辅助函数。利用 pandas 内建的函数,Pluto 用两行代码编写了 clean_text() 函数,而不是用十几行标准的 if-elsefor 循环构造。代码如下:

# clean text
df['clean_tweet'] = df.tweet.apply(self._clean_text)
# remove profanity words
df['clean_tweet'] = df['clean_tweet'].apply(
    self._clean_bad_word)

清洁推文和显示数据批次的命令如下:

# clean tweets
pluto.clean_text(pluto.df_twitter_data)
# display data batch
pluto.print_batch_text(pluto.df_twitter_data,
    cols=['label', 'clean_tweet'])

输出如下:

图 5.3 – 清洁后的 Twitter 推文

图 5.3 – 清洁后的 Twitter 推文

趣味事实

谁能想到狗和熊猫能合作得这么好?下一部 功夫熊猫 电影讲述的是 PoPluto 联手抵御世纪风暴的故事,这场风暴是由全球变暖引起的,它正摧毁着城市墙。

让我们使用 pandas 和其他一些库来可视化 NLP 数据集。

可视化 NLP 数据

第二章 使用 draw_word_count() 方法显示每条记录的平均单词数,以及最短和最长的电影评论。图表的右侧显示了电影评论单词计数的直方图。pandas 库生成了漂亮的单词计数图表。Pluto 重用了这个函数来显示 Netflix NLP 数据,具体如下:

# draw word count
pluto.draw_word_count(pluto.df_netflix_data)

输出如下:

图 5.4 – Netflix 单词计数

图 5.4 – Netflix 单词计数

Netflix 电影描述的平均字数为 23.88 字,最少 10 字,最多 48 字。Pluto 对 Twitter NLP 数据做了同样的处理,具体如下:

# draw word count
pluto.draw_word_count(pluto.df_twitter_data)

输出如下:

图 5.5 – Twitter 单词计数

图 5.5 – Twitter 单词计数

Twitter 推文的平均字数为 12.78 字,最少 1 字,最多 33 字。

Pluto 编写了 draw_text_null_data() 方法来检查是否存在缺失数据,也就是使用 Missingno 库生成图表,关键代码行如下:

missingno.matrix(df,color=color,ax=pic)

Pluto 为 Netflix 数据绘制了 null 数据图表,如下所示:

# draw missing data/null value
pluto.draw_text_null_data(pluto.df_netflix_data)

输出结果如下:

图 5.6 – Netflix 缺失数据

图 5.6 – Netflix 缺失数据

Netflix 数据中的 directorcastcountry 分类存在缺失数据,但 description 分类,也就是电影评论,没有缺失数据。

Pluto 对 Twitter 数据做了相同的操作,如下所示:

# draw missing data/null value
pluto.draw_text_null_data(pluto.df_twitter_data)

输出结果如下:

图 5.7 – Twitter 缺失数据

图 5.7 – Twitter 缺失数据

Twitter 数据中没有缺失数据。

有趣的事实

许多价值数百万美元的 AI 系统失败的主要原因是缺乏对输入数据的控制。例如,2020 年的 Amazon Recruiting 系统失败了,因为数据集中缺乏多样性,最严重的失败是 2016 年的 Microsoft Chatbot Tay。它被 Twitter 用户输入的性别歧视和种族主义推文所破坏。

下一个图表是字词云信息图。这是一种极好的 NLP 文本可视化方法。最常用的词语以大字号显示,而最少使用的词语则以较小字号显示。WordCloud 库生成了信息图表,关键代码片段如下:

# generate word cloud
img = wordcloud.WordCloud(width = 1600,
        height = 800,
        background_color ='white',
        stopwords = xignore_words,
        min_font_size = 10).generate(words_str)
# covert Pandas to word string input
orig = df_1column.str.cat()
word_clean = re.sub('[^A-Za-z0-9 ]+', '', orig)

Pluto 使用 _draw_text_wordcloud() 辅助函数和 draw_text_wordcloud() 方法,展示了真实世界的 Netflix 数据的字词云信息图,如下所示:

# draw word cloud
pluto.draw_text_wordcloud(pluto.df_netflix_data.description,
    xignore_words=wordcloud.STOPWORDS,
    title='Word Cloud: Netflix Movie Review')

输出结果如下:

图 5.8 – Netflix 字词云,包含大约 246,819 个单词

图 5.8 – Netflix 字词云,包含大约 246,819 个单词

Pluto 对真实世界的 Twitter 数据也做了相同的操作,如下所示:

# draw word cloud
pluto.draw_text_wordcloud(pluto.df_twitter_data.clean_tweet,
    xignore_words=wordcloud.STOPWORDS,
    title='Clean Tweets Word Cloud')

输出结果如下:

图 5.9 – Twitter 字词云,包含大约 464,992 个单词

图 5.9 – Twitter 字词云,包含大约 464,992 个单词

有趣的事实

这里有一个关于字词云图的有趣小知识。字词云,又称标签云、Wordle 或加权列表,最早由 Douglas Coupland 在 1995 年的书籍 Microserfs 中以印刷形式使用。但直到 2004 年,字词云才在 Flickr 网站上以数字格式存在。今天,字词云信息图在互联网上和学术论文中广泛应用。

到目前为止,Pluto 已经讨论了字符、单词和句子增强理论,选择了 Nlpaug 文本增强库,并下载了真实世界的 NetflixTwitter NLP 数据集。现在是时候通过 Python 代码执行文本增强来强化他的学习了。

通过 Python Notebook 强化学习

Pluto 使用 Python Notebook 加深我们对文本增强的理解。他使用批处理函数以批次的形式显示文本。它的工作方式类似于图像的批处理函数。换句话说,它会随机选择新的记录,并使用增强方法进行转换。

有趣的事实

Pluto 推荐重复运行批处理函数,以深入了解文本增强方法。在 TwitterAmazon 数据集中有成千上万的文本记录。每次运行批处理函数时,它会显示来自数据集的不同记录。

与图像增强实现类似,包装函数在幕后使用 Nlpaug 库。这个包装函数让你可以专注于文本转换的概念,而不被库的实现所分心。你也可以使用其他文本增强库,包装函数的输入和输出将保持不变。

Pluto 可以编写一个复杂的函数,包含所有文本转换技术,这可能更高效,但这并不是本书的目标。阅读完本书后,你可以自信地选择重写或修改 Python Notebook 以适应你的风格。

在本章中,Pluto 使用 查尔斯·狄更斯 的《双城记》中的开篇句子作为控制文本。Pluto 通过将短语之间的逗号替换为句号来改写文本,因为这样更有利于文本增强过程。控制文本如下:

“这是最好的时代,也是最坏的时代。是智慧的时代,也是愚蠢的时代。是信仰的纪元,也是怀疑的纪元。”

Python Notebook 涵盖以下主题:

  • 字符增强

  • 单词增强

让我们从三种字符增强技术开始。

字符增强

字符增强是指向文本中注入错误。这个过程是违反直觉的,因为它故意向数据中添加错误。换句话说,它使得文本对于人类来说更难理解。相反,计算机使用深度学习算法来预测结果,尤其是 卷积神经网络CNN)和 递归神经网络RNN)算法。例如,推文的情感分类不会受到拼写错误的影响。

特别是,Pluto 将解释以下三种方法:

  • OCR 增强

  • 键盘增强

  • 随机增强

让我们从 OCR 开始。

OCR 增强

OCR 过程将图像转换为文本,在转换过程中常出现错误,如将 0o 混淆。

Pluto 编写了 _print_aug_batch() 辅助函数,随机选择 NLP 数据中的样本记录,应用文本增强方法,并使用 pandas 打印。输入或方法定义如下:

# method definition
def _print_aug_batch(self, df,
    aug_func,
    col_dest="description",
    bsize=3,
    aug_name='Augmented'):

这里,df 是 pandas DataFrame,aug_function 是包装函数中的增强方法,col_dest 是选择的目标列,bsize 是批次中的样本数,默认为三,title 是图表的可选标题。

OCR 包装函数是基础的。两行代码分别是 aug_func 和辅助函数。整个代码如下:

# method definiton
@add_method(PacktDataAug)
def print_aug_ocr(self, df,
    col_dest="description",
    bsize=3,
    aug_name='Augmented'):
    aug_func = nlpaug.augmenter.char.OcrAug()
    self._print_aug_batch(df,
        aug_func,
        col_dest=col_dest,
        bsize=bsize,
        aug_name=aug_name)
    return

Pluto 使用 print_aug_ocr() 方法处理 Netflix 数据,如下所示:

# use OCR method
pluto.print_aug_ocr(pluto.df_netflix_data,
    col_dest='description',
    aug_name='OCR Augment')

输出如下:

图 5.10 – Netflix OCR 增强

图 5.10 – Netflix OCR 增强

图 5.10 中,第一行是 狄更斯 的控制文本,左侧是增强后的文本,右侧是原始文本。接下来的三行是从 Netflix NLP 数据中随机抽取的。Pluto 推荐先阅读左侧的增强文本。停下来并试着解读其含义,然后再阅读原始文本。

趣味事实

Pluto 推荐反复运行 print_aug_ocr() 方法以查看其他电影描述。你可以增加 bsize 来查看一次超过两条记录。

Pluto 同样对 Twitter 的 NLP 数据进行处理,如下所示:

# print the batch
pluto.print_aug_ocr(pluto.df_twitter_data,
    col_dest='clean_tweet',
    aug_name='OCR Augment')

输出如下:

图 5.11 – Twitter OCR 增强

图 5.11 – Twitter OCR 增强

接下来,Pluto 从 OCR 方法转向键盘技术。

键盘增强

键盘增强方法通过用键盘上相近的键替换字符。例如,字符 b 的典型打字错误是按了键 v 或键 n。增强变量定义如下:

# define augmentation function variable definition
aug_func = nlpaug.augmenter.char.KeyboardAug()

Pluto 使用 print_aug_keyboard() 包装函数处理 Netflix 的 NLP 数据,如下所示:

# use keyboard augmentation technique
pluto.print_aug_keyboard(pluto.df_netflix_data,
    col_dest='description',
    aug_name='Keyboard Augment')

输出如下:

图 5.12 – Netflix 键盘增强

图 5.12 – Netflix 键盘增强

Pluto 同样对 Twitter 的 NLP 数据进行处理,如下所示:

# use keyboard augmentation technique
pluto.print_aug_keyboard(pluto.df_twitter_data,
    col_dest='clean_tweet',
    aug_name='Keyboard Augment')

输出如下:

图 5.13 – Twitter 键盘增强

图 5.13 – Twitter 键盘增强

三种文本增强方法中的最后一种是随机技术。

随机增强

随机字符功能会随机交换、插入或删除文本中的字符。随机过程的四种模式是 插入删除替换交换。增强变量定义如下:

# define augmentation function variable definition
aug_func = nlpaug.augmenter.char.RandomCharAug(action=action)

Pluto 在 Netflix 的 NLP 数据中使用 print_aug_random() 包装函数,并将 action 设置为 insert,如下所示:

# use random insert augmentation technique
pluto.print_aug_char_random(pluto.df_netflix_data,
    action='insert',
    col_dest='description',
    aug_name='Random Insert Augment')

输出如下:

图 5.14 – Netflix 随机插入增强

图 5.14 – Netflix 随机插入增强

Pluto 同样对 Twitter 的 NLP 数据进行处理,如下所示:

# use random insert augmentation technique
pluto.print_aug_char_random(pluto.df_twitter_data,
    action='insert',
    col_dest='clean_tweet',
    aug_name='Random Insert Augment')

输出如下:

图 5.15 – Twitter 随机插入增强

图 5.15 – Twitter 随机插入增强

Pluto 在 Netflix NLP 数据上使用 print_aug_random() 包装函数,action 设置为 delete,具体如下:

# use random delete augmentation technique
pluto.print_aug_char_random(pluto.df_netflix_data,
    action='delete',
    col_dest='description',
    aug_name='Random Delete Augment')

输出结果如下:

图 5.16 – Netflix 随机删除增强

图 5.16 – Netflix 随机删除增强

Pluto 对 Twitter 的 NLP 数据也进行了相同处理,具体如下:

# use random delete augmentation technique
pluto.print_aug_char_random(pluto.df_twitter_data,
    action='delete', col_dest='clean_tweet',
    aug_name='Random Delete Augment')

输出结果如下:

图 5.17 – Twitter 随机删除增强

图 5.17 – Twitter 随机删除增强

Pluto 在 Netflix NLP 数据上使用 print_aug_random() 包装函数,action 设置为 substitute,具体如下:

# use random substitute augmentation technique
pluto.print_aug_char_random(pluto.df_netflix_data,
    action='substitute',
    col_dest='description',
    aug_name='Random Substitute Augment')

输出结果如下:

图 5.18 – Netflix 随机替换增强

图 5.18 – Netflix 随机替换增强

Pluto 对 Twitter NLP 数据也进行了相同处理,具体如下:

# use random substitude augmentation technique
pluto.print_aug_char_random(pluto.df_twitter_data,
    action='substitute',
    col_dest='clean_tweet',
    aug_name='Random Substitute Augment')

输出结果如下:

图 5.19 – Twitter 随机替换增强

图 5.19 – Twitter 随机替换增强

Pluto 在 Netflix NLP 数据上使用 print_aug_random() 包装函数,action 设置为 swap,具体如下:

# use random swap augmentation technique
pluto.print_aug_char_random(pluto.df_netflix_data,
    action='swap',
    col_dest='description',
    aug_name='Random Swap Augment')

输出结果如下:

图 5.20 – Netflix 随机交换增强

图 5.20 – Netflix 随机交换增强

Pluto 对 Twitter NLP 数据也进行了相同处理,具体如下:

# use random swap augmentation technique
pluto.print_aug_char_random(pluto.df_twitter_data,
    action='swap',
    col_dest='clean_tweet',
    aug_name='Random Swap Augment')

输出结果如下:

图 5.21 – Twitter 随机交换增强

图 5.21 – Twitter 随机交换增强

有趣的挑战

这里有一个思维实验:如果输入文本包含拼写错误和语法错误,比如推文,那么纠正拼写和语法是否可以作为有效的增强方法?

Pluto 已涵盖 OCR键盘 和四种模式的 随机 字符增强技术。下一步是增强单词。

单词增强

到目前为止,Pluto 可能会觉得文本增强毫不费力,实际上这是真的。我们在 第一章 中打下了坚实的基础,使用面向对象的类并学习如何在学习新增强技术时扩展对象。在 第二章 中,Pluto 添加了用于下载任何 Kaggle 真实世界数据集的函数,第三章第四章 给我们提供了包装函数模式。因此,到了这一点,Pluto 复用了这些方法和模式,使 Python 代码简洁易懂。

单词增强过程类似于字符增强。Pluto 使用相同的 _print_aug_batch() 辅助方法。特别是,Pluto 将涵盖 拼写错误分割随机同义词反义词保留 单词增强技术。

让我们从拼写错误增强技术开始。

拼写错误增强

拼写错误增强函数使用预定义字典模拟拼写错误。增强变量定义如下:

# define augmentation function variable definition
aug_func = nlpaug.augmenter.word.SpellingAug()

Pluto 在 Netflix NLP 数据上使用 print_aug_word_misspell() 包装函数,具体如下:

# use word missplell augmentation
pluto.print_aug_word_misspell(pluto.df_netflix_data,
    col_dest='description',
    aug_name='Word Spelling Augment')

输出结果如下:

图 5.22 – Netflix 拼写错误单词增强

图 5.22 – Netflix 拼写错误单词增强

Pluto 对Twitter NLP 数据执行相同操作,如下所示:

# use word missplell augmentation
pluto.print_aug_word_misspell(pluto.df_twitter_data,
    col_dest='clean_tweet',
    aug_name='Word Spelling Augment')

输出结果如下:

图 5.23 – Twitter 拼写错误单词增强

图 5.23 – Twitter 拼写错误单词增强

拼写错误类似的是分割单词增强技术。

分割增强

分割增强函数随机将单词拆分为两个标记。增强变量定义如下:

# define augmentation function variable definition
aug_func = nlpaug.augmenter.word.SplitAug()

Pluto 在Netflix NLP 数据上使用 print_aug_word_split() 包装函数,如下所示:

# use word split augmentation
pluto.print_aug_word_split(pluto.df_netflix_data,
    col_dest='description',
    aug_name='Word Split Augment')

输出结果如下:

图 5.24 – Netflix 分割单词增强

图 5.24 – Netflix 分割单词增强

Pluto 对Twitter NLP 数据执行相同操作,如下所示:

# use word split augmentation
pluto.print_aug_word_split(pluto.df_twitter_data,
    col_dest='clean_tweet',
    aug_name='Word Split Augment')

输出结果如下:

图 5.25 – Twitter 分割单词增强

图 5.25 – Twitter 分割单词增强

在分割单词方法之后,Pluto 展示了随机单词增强方法。

随机增强

随机单词增强方法对文本应用随机行为,具有四个参数:交换裁剪替换删除。增强变量定义如下:

# define augmentation function variable definition
aug_func = nlpaug.augmenter.word.RandomWordAug(action=action)

Pluto 在Netflix NLP 数据上使用 print_aug_word_random() 包装函数进行交换模式,如下所示:

# use word random swap augmentation
pluto.print_aug_word_random(pluto.df_netflix_data,
    action='swap',
    col_dest='description',
    aug_name='Word Random Swap Augment')

输出结果如下:

图 5.26 – Netflix 随机交换单词增强

图 5.26 – Netflix 随机交换单词增强

Pluto 对Twitter NLP 数据执行相同操作,如下所示:

# use word random swap augmentation
pluto.print_aug_word_random(pluto.df_twitter_data,
    action='swap',
    col_dest='clean_tweet',
    aug_name='Word Random Swap Augment')

输出结果如下:

图 5.27 – Twitter 随机交换单词增强

图 5.27 – Twitter 随机交换单词增强

Pluto 在Netflix NLP 数据上使用 print_aug_word_random() 包装函数进行裁剪模式,如下所示:

# use word random crop augmentation
pluto.print_aug_word_random(pluto.df_netflix_data,
    action='crop',
    col_dest='description',
    aug_name='Word Random Crop Augment')

输出结果如下:

图 5.28 – Netflix 随机裁剪单词增强

图 5.28 – Netflix 随机裁剪单词增强

Pluto 对Twitter NLP 数据执行相同操作,如下所示:

# use word random swap augmentation
pluto.print_aug_word_random(pluto.df_twitter_data,
    action='crop',
    col_dest='clean_tweet',
    aug_name='Word Random Crop Augment')

输出结果如下:

图 5.29 – Twitter 随机裁剪单词增强

图 5.29 – Twitter 随机裁剪单词增强

所以,Pluto 描述了交换裁剪单词增强方法,但没有涉及替换删除方法。这是因为它们类似于字符增强函数,并且已经在 Python Notebook 中。接下来的内容是同义词增强。

同义词增强

同义词增强函数将单词替换为预定义数据库中的同义词。WordNetPPBD 是两个可选的数据库。增强变量定义该过程如下:

# define augmentation function variable definition
aug_func = nlpaug.augmenter.word.SynonymAug(
    aug_src='wordnet')

Pluto 在Netflix NLP 数据上使用 print_aug_word_synonym() 包装函数,如下所示:

# use word synonym augmentation
pluto.print_aug_word_synonym(pluto.df_netflix_data,
    col_dest='description',
    aug_name='Synonym WordNet Augment')

输出结果如下:

图 5.30 – Netflix 同义词单词增强

图 5.30 – Netflix 同义词单词增强

有趣且好笑的是,It 的同义词对于控制文本来说是 信息技术。写下《双城记》的狄更斯先生,1859 年时肯定无法预见到 IT 是信息技术的流行缩写。Pluto 在 Twitter NLP 数据上做了相同的处理,如下所示:

# use word synonym augmentation
pluto.print_aug_word_synonym(pluto.df_twitter_data,
    col_dest='clean_tweet',
    aug_name='Synonym WordNet Augment')

输出如下:

图 5.31 – Twitter 同义词增强

图 5.31 – Twitter 同义词增强

当有同义词时,你也会找到反义词。

反义词增强

反义词增强功能会随机用反义词替换词汇。增强变量定义了这个过程,如下所示:

# define augmentation function variable definition
aug_func = nlpaug.augmenter.word.AntonymAug()

Pluto 使用 print_aug_word_antonym() 包装函数处理 Netflix NLP 数据,如下所示:

# use word antonym augmentation
pluto.print_aug_word_antonym(pluto.df_netflix_data,
    col_dest='description',
    aug_name='Antonym Augment')

输出如下:

图 5.32 – Netflix 反义词增强

图 5.32 – Netflix 反义词增强

Pluto 在 Twitter NLP 数据上做了相同的处理,如下所示:

# use word antonym augmentation
pluto.print_aug_word_antonym(pluto.df_twitter_data,
    col_dest='clean_tweet',
    aug_name='Antonym Augment')

输出如下:

图 5.33 – Twitter 反义词增强

图 5.33 – Twitter 反义词增强

在同义词和反义词增强(自动化处理)之后,保留字增强需要手动词汇表。

保留字增强

保留字增强方法通过定义一个词汇表来交换目标词汇。它与同义词增强相同,只不过这些词是手动创建的。Pluto 使用 NetflixTwitter 的词云图,图 5.85.9,来选择 NLP 数据集中排名前三的重复词汇。增强变量定义了这个过程,如下所示:

# define augmentation function
aug_func = nlpaug.augmenter.word.ReservedAug(
    reserved_tokens=reserved_tokens)
# define control sentence reserved words
pluto.reserved_control = [['wisdom', 'sagacity',
    'intelligence', 'prudence'],
    ['foolishness', 'folly', 'idiocy', 'stupidity']]
# define Netflix reserved words
pluto.reserved_netflix = [['family','household', 'brood',
    'unit', 'families'],
    ['life','existance', 'entity', 'creation'],
    ['love', 'warmth', 'endearment','tenderness']]
pluto.reserved_netflix = pluto.reserved_control +
    pluto.reserved_netflix
# define Twitter reserved words
pluto.reserved_twitter = [['user', 'users', 'customer',
    'client','people','member','shopper'],
    ['happy', 'cheerful', 'joyful', 'carefree'],
    ['time','clock','hour']]
pluto.reserved_twitter = pluto.reserved_control +
    pluto.reserved_twitter

Pluto 使用 print_aug_word_reserved() 包装函数处理 Netflix NLP 数据,如下所示:

# use word reserved augmentation
pluto.print_aug_word_reserved(pluto.df_netflix_data,
    col_dest='description',
    reserved_tokens=pluto.reserved_netflix)

输出如下:

图 5.34 – Netflix 保留字增强

图 5.34 – Netflix 保留字增强

请注意,wisdomfoolishness 被替换为 Intelligenceidiocylife 被替换为 existancefamily 被替换为 brood。Pluto 在 Twitter NLP 数据上做了相同的处理,如下所示:

# use word reserved augmentation
pluto.print_aug_word_reserved(pluto.df_twitter_data,
    col_dest='clean_tweet',
    reserved_tokens=pluto.reserved_twitter)

输出如下:

图 5.35 – Twitter 保留字增强

图 5.35 – Twitter 保留字增强

请注意,wisdomfoolishness 被替换为 sagacityidiocyuser 被替换为 peoplecustomer

保留字 增强是本章的最后一种词汇增强方法。Pluto 涵盖了 拼写错误拆分随机同义词反义词保留字增强,但这些只是你可以使用的一些词汇增强技术。

有趣的挑战

挑战是使用 Augly 库或 NLTK、Gensim 或 Textblob 库编写一个新的包装函数。这相对简单。第一步是复制一个包装函数,比如 print_aug_keyboard() 函数。第二步也是最后一步是将 aug_func = nlpaug.augmenter.char.KeyboardAug() 替换为 aug_func = augly.text.functional.simulate_typos()。Augly 函数中有更多参数。一个提示是使用 augly.text.functional.simulate_typos? 命令来显示该函数的文档。

Nlpaug 库和其他文本增强库,如 NLTKGensimTextblobAugly,提供了更多的文本增强方法。此外,最新发布的学术论文也是发现新文本增强技术的绝佳来源。

让我们总结一下本章内容。

总结

初看之下,文本增强似乎违反直觉且有问题,因为这些技术会向文本中注入错误。然而,基于 CNN 或 RNN 的深度学习仍然能够识别模式,不管是拼写错误还是同义词替换。此外,许多已发布的学术论文都描述了文本增强在提高预测或预报准确性方面的好处。

第五章中,你学习了三种字符增强技术,分别是OCR键盘随机。此外,还有六种单词增强技术,分别是拼写错误分割随机同义词反义词保留词。在 Nlgaug、NLTK、Gensim、TextBlob 和 Augly 库中还有更多文本增强方法。

使用 Python Notebook 实现文本增强方法看似简单。因为 Pluto 在第一章中构建了一个面向对象的类,并学习了如何使用装饰器扩展对象,从而在发现新的增强技术时能够加以利用。在第二章中,Pluto 添加了用于下载任何Kaggle真实世界数据集的功能,第三章第四章为我们提供了包装函数模式。因此,在本章中,Pluto 复用了这些方法和模式,使得 Python Notebook 代码简洁易懂。

在整个章节中,包含了有趣的事实有趣的挑战。Pluto 希望你能够利用这些内容,拓展你的经验,超越本章的范围。

下一章将深入探讨使用机器学习方法的文本增强。具有讽刺意味的是,文本增强的目标是使机器学习和深度学习能够准确预测和预报,而我们将使用相同的 AI 系统来提高文本增强的效率。这是一个循环逻辑或周期性过程。

Pluto 正在下一章等你,使用机器学习进行文本增强

第六章:使用机器学习的文本增强

使用机器学习ML)的文本增强是一种比我们在上一章中介绍的标准文本增强方法更为先进的技术。具有讽刺意味的是,文本增强旨在提高机器学习模型的准确性,但我们使用了一个预训练的机器学习模型来创建额外的训练 NLP 数据。这是一个循环过程。本书不涉及机器学习编程,但理解使用库与使用机器学习进行文本增强之间的区别是非常有益的。

增强库,无论是用于图像、文本还是音频,都会遵循传统的编程方法论,包含结构化数据、循环和条件语句。例如,如在第五章中所示,实施_print_aug_reserved()方法的伪代码可能如下所示:

# define synonym words, pseudo-code
reserved = [['happy', 'joyful', 'cheerful'],
  ['sad', 'sorrowful', 'regretful']]
# substitute the word with its synonym, pseudo-code
for i, word in (input_text)
  for set_word in (reserved)
    for i, syn in set_word
      if (syn == word)
        input_text[i] = set_word[i+1]

正常路径的代码未覆盖错误检查,但重点是该库的功能遵循标准的顺序编码方法。

另一方面,机器学习基于 13 种已知的机器学习算法之一,包括_print_aug_reserved()伪代码算法。

以下是用于图像分类的深度学习(DL)架构表示。它展示了过程化方法与神经网络算法之间的区别。此图是通过LatexOverleaf云系统创建的,输出结果如下:

图 6.1 – 深度学习模型的表示

图 6.1 – 深度学习模型的表示

Overleaf 项目及其代码来自 Duc Haba 先生的公开代码库,网址为www.overleaf.com/project/6369a1eaba583e7cd423171b。你可以克隆并修改代码以展示其他 AI 模型。

本章将介绍使用机器学习的文本增强,特别是以下主题:

  • 机器学习模型

  • 词汇增强

  • 句子增强

  • 真实世界的 NLP 数据集

  • 通过 Python 笔记本强化你的学习

让我们简要描述在 Python 包装函数代码中使用的机器学习模型。

机器学习模型

本章中,文本增强包装函数使用机器学习生成新的文本,用于训练机器学习模型。理解这些模型是如何构建的并不在本书范围内,但对这些机器学习模型及其算法的简要描述是必要的。Python 包装函数将在后台使用以下机器学习模型:

  • Tomáš Mikolov 于 2013 年发布了一个名为Word2Vec的神经网络 NLP 算法。该模型可以根据输入文本提议同义词。

  • 全局词向量表示GloVe)算法由 Jeffrey Pennington、Richard Socher 和 Christopher D. Manning 于 2014 年创建。它是一种无监督学习的自然语言处理(NLP)算法,用于将词语表示为向量格式。其结果是一个线性算法,能够将最接近的相邻词汇聚集在一起。

  • Wiki-news-300d-1M 是一个预训练的机器学习模型,使用了fastText开源库。它是基于维基百科 2017 年文章中的 100 万个单词、UMBC WebBase 语料库(包含超过 30 亿个单词)和 Statmt.org 新闻数据集(包含超过 160 亿个词元)进行训练的。T. Mikolov、E. Grave、P. Bojanowski、C. Puhrsch 和 A. Joulin 在他们的论文《预训练分布式词表示的进展》中介绍了Wiki-news-300d-1M。该模型的许可协议为 Creative Commons Attribution-Share-Alike License 3.0。

  • GoogleNews-vectors-negative300 是一个预训练的Word2Vec模型,使用了包含约 1000 亿个单词和 300 个维度的 Google 新闻数据集。

  • Google 于 2017 年推出了transformer神经网络算法。近期自然语言处理和计算机视觉领域的前沿突破均来源于该变换器模型。

  • BERT 模型由 Jacob Devlin、Ming-Wei Chang、Kenton Lee 和 Kristina Toutanova 于 2018 年提出,专门用于语言推理和预测。

  • RoBERTa 是一种优化过的自监督自然语言处理模型算法,建立在 BERT 的基础上。它在许多自然语言处理推理任务中表现优异。Meta AI 于 2019 年发布了 RoBERTa。

  • Facebook 的wmt19-en-dewmt19-de-en是来自HuggingFace的预训练自然语言处理模型,用于从英语翻译到德语(Deutsch)并相互转换。该模型于 2021 年公开发布。

  • Facebook 的wmt19-en-ruwmt19-ru-en是来自HuggingFace的预训练自然语言处理模型,用于从英语翻译到俄语(Русский)并相互转换。该模型于 2021 年公开发布。

  • XLNet 是一个基于 transformer-XL 的预训练模型,由 Zhilin Yang、Zihang Dai、Yiming Yang、Jaime Carbonell、Russ R. Salakhutdinov 和 Quoc V. Le 于 2021 年在HuggingFace上公开发布。该模型在学术论文《XLNet: 用于语言理解的广义自回归预训练》中进行了介绍。

  • 生成式预训练变换器 2GPT-2)算法是一个开源 AI 模型,由 OpenAI 于 2019 年发布。该模型在生成反馈问题与答案以及文章文本摘要方面表现出色,且与人类写作水平相当。

  • T5T5X 模型使用文本到文本的变换器算法。它们是基于庞大的语料库进行训练的。Colin Raffel、Noam Shazeer、Adam Roberts、Katherine Lee、Sharan Narang、Michael Matena、Yanqi Zhou、Wei Li 和 Peter J. Liu 在 2020 年的论文《探索统一文本到文本变换器的迁移学习极限》中介绍了 T5。

有趣的事实

生成式人工智能,当使用变换器模型时,例如 OpenAI 的 GPT-3、GPT-4 或 Google Bard,能够写出与人类作家一样好的内容,甚至更好。

现在我们了解了一些机器学习模型,接下来我们来看看哪些增强功能使用了哪些机器学习模型。

词汇增强

在这一章中,词语增强技术类似于第五章中的方法,该方法使用了Nlpaug库。不同之处在于,包装函数使用强大的机器学习模型来实现显著的效果,而非 Python 库。有时,输出或重写的文本与人类写作非常相似。

具体来说,你将学习四种新技术,每种技术有两种变体。让我们从 Word2Vec 开始:

  • Word2Vec方法使用神经网络 NLP Word2Vec 算法和 GoogleNews-vectors-negative300 预训练模型。Google 使用包含约 1000 亿个单词和 300 维度的大型语料库进行了训练。替换和插入是两种模式变体。

  • BERT方法使用 Google 的 Transformer 算法和 BERT 预训练模型。替换和插入是两种模式变体。

  • RoBERTa方法是 BERT 模型的一种变体。替换和插入是两种模式变体。

  • 在本章中,我们将介绍的最后一种词语增强技术是使用 Facebook(Meta)的预训练翻译模型进行反向翻译。它将输入的英文文本翻译成另一种语言,然后再翻译回英文。我们将研究的两种变体涉及将英文翻译成德语(Deutsch),然后再翻译回英文,使用的是facebook/wmt19-en-defacebook/wmt19-de-en模型;将英文翻译成俄语(Русский),然后再翻译回英文,使用的是facebook/wmt19-en-rufacebook/wmt19-ru-en模型。

通过查看词语包装函数的输出,这将更容易理解,但在此之前,我们先来描述句子增强。

句子增强

在句子级别进行增强是一个强大的概念,5 年前这是无法实现的。你必须在机器学习研究公司工作,或者是亿万富翁,才能访问这些著名的预训练模型。某些 Transformer 和大型语言模型LLMs)在 2019 和 2020 年作为开源发布,但它们通常用于研究。当时,方便通过 GPU 访问在线 AI 服务器并不普及。LLM 和预训练模型最近才开始向公众开放,可以将它们集成到你的项目中,如 HuggingFace 网站。重要的是,对于独立研究人员或学生来说,LLM 和预训练模型直到 2021 年中才开始变得可访问。

使用机器学习的句子和词语增强方法不能像使用Nlpaug库的方法那样动态进行。换句话说,你必须将增强后的文本写入并保存到本地或云端磁盘空间。其主要原因是每个训练周期的增强步骤所需时间过长。优点是,你可以将原始文本的大小增加 20 到 100 倍。

具体来说,我们将介绍以下技术:

  • 使用T5 NLP 算法进行文本摘要。

  • 顺序有时是两种句子流方法。这些流方法结合了 GloVeBERT NLP 算法。

对于句子增强技术,通过使用真实世界的 NLP 数据集作为输入文本并查看包装函数的输出,更容易理解这些技术。因此,接下来的部分将介绍如何用 Python 代码编写包装函数来深入了解句子增强,但首先,让我们下载真实世界的 NLP 数据集。

真实世界的 NLP 数据集

本章将使用与第五章相同的 Netflix 和 Twitter 真实世界 NLP 数据集。此外,两个数据集已经经过审核、清洗,并存储在本书 GitHub 仓库中的 pluto_data 目录中。启动过程与前几章相似,步骤如下:

  1. 克隆 Python Notebook 和 Pluto。

  2. 验证 Pluto。

  3. 定位 NLP 数据。

  4. 将数据加载到 pandas。

  5. 查看数据。

让我们从 Python Notebook 和 Pluto 开始。

Python Notebook 和 Pluto

首先将 data_augmentation_with_python_chapter_6.ipynb 文件加载到 Google Colab 或您选择的 Jupyter Notebook 或 JupyterLab 环境中。从这一点开始,我们将仅显示代码片段。完整的 Python 代码可以在 Python Notebook 中找到。

下一步是克隆仓库。我们将重用第五章的代码。使用 !git%run 语句来实例化 Pluto:

# clone Packt GitHub repo.
!git clone 'https://github.com/PacktPublishing/Data-Augmentation-with-Python'
# Instantiate Pluto
%run 'Data-Augmentation-with-Python/pluto/pluto_chapter_5.py'

输出如下:

---------------------------- : ----------------------------
                        Hello from class : <class '__main__.PacktDataAug'> Class: PacktDataAug
                                     Code name : Pluto
                                     Author is : Duc Haba
---------------------------- : ----------------------------

接下来的设置步骤是检查 Pluto 是否正确加载。

验证

以下命令要求 Pluto 显示他的状态:

# Am I alive?
pluto.say_sys_info()

输出将如下所示,具体取决于您的系统:

---------------------------- : ----------------------------
                 System time : 2022/11/09 05:31
                    Platform : linux
     Pluto Version (Chapter) : 5.0
             Python (3.7.10) : actual: 3.7.15 (default, Oct 12 2022, 19:14:55) [GCC 7.5.0]
            PyTorch (1.11.0) : actual: 1.12.1+cu113
              Pandas (1.3.5) : actual: 1.3.5
                 PIL (9.0.0) : actual: 7.1.2
          Matplotlib (3.2.2) : actual: 3.2.2
                   CPU count : 12
                  CPU speed : NOT available
---------------------------- : ----------------------------

Pluto 显示他来自第五章(版本 5.0),这是正确的。此外,清洗后的 NLP Twitter 和 Netflix 数据集已存储在 ~/``Data-Augmentation-with-Python/pluto_data 目录中。

真实世界的 NLP 数据

Pluto 正在使用来自第五章的干净版本数据,这些数据没有脏话。它们是来自 Kaggle 网站的 Netflix 和 Twitter NLP 数据集。清洗后的数据集已经保存在本书的 GitHub 仓库中。因此,Pluto 不需要再次下载它们。不过,您仍然可以通过 fetch_kaggle_dataset() 函数下载它们或其他真实世界数据集。Pluto 使用以下命令来定位已清洗的 NLP 数据集:

# check to see the files are there
f = 'Data-Augmentation-with-Python/pluto_data'
!ls -la {f}

输出如下:

drwxr-xr-x 2 root root    4096 Nov 13 06:07 .
drwxr-xr-x 6 root root    4096 Nov 13 06:07 ..
-rw-r--r-- 1 root root 3423079 Nov 13 06:07 netflix_data.csv
-rw-r--r-- 1 root root 6072376 Nov 13 06:07 twitter_data.csv

有趣的事实

Pluto 变懒了,他没有使用 Python 库和用 Python 编码,而是通过下达 Linux Bash 命令行代码作弊。感叹号字符 (!) 允许 Python Notebook 后门进入内核,例如在 Linux 上使用 !ls -la 或在 Windows 上使用 !dir。您可以使用任何操作系统的命令行代码。但这不是可移植的代码,因为 Windows、iOS、Linux、Android 等操作系统(支持 Safari、Chrome、Edge 和 Firefox 等网页浏览器)上的命令是不同的。

下一步是将数据加载到 Pluto 的伙伴 pandas 中。

Pandas

Pluto 重用了 第二章 中的 fetch_df() 方法,将数据加载到 pandas 中。以下命令将真实世界的 Netflix 数据导入 pandas:

# import to Pandas
f = 'Data-Augmentation-with-Python/pluto_data/netflix_data.csv'
pluto.df_netflix_data = pluto.fetch_df(f,sep='~')

同样,加载真实世界 Twitter 数据的命令如下:

# import to Pandas
f = 'Data-Augmentation-with-Python/pluto_data/twitter_data.csv'
pluto.df_twitter_data = pluto.fetch_df(f,sep='~')

有趣的挑战

Pluto 挑战你从 Kaggle 网站找到并下载两个额外的 NLP 数据。提示:使用 Pluto 的 fetch_kaggle_dataset() 函数。使用 fetch_df() 函数将其导入 pandas。

现在,Pluto 已经定位并将数据导入 pandas,加载数据序列的最后一步是查看和验证数据。

查看文本

draw_word_count()draw_null_data() 方法帮助我们理解 NLP 数据,Pluto 建议重新查看 第五章,以查看那些 Netflix 和 Twitter 图表。一种更有趣、更丰富多彩的方法是使用 draw_word_cloud() 函数。

Pluto 使用以下命令绘制 Netflix 词云信息图:

# draw infographic plot
pluto.draw_text_wordcloud(pluto.df_netflix_data.description,
  xignore_words=wordcloud.STOPWORDS,
  title='Word Cloud: Netflix Movie Review')

输出如下:

图 6.2 – Netflix 词云

图 6.2 – Netflix 词云

同样,Pluto 使用以下命令显示 Twitter 词云:

# draw infographic plot
pluto.draw_text_wordcloud(pluto.df_twitter_data.clean_tweet,
  xignore_words=wordcloud.STOPWORDS,
  title='Word Cloud: Twitter Tweets')

输出如下:

图 6.3 – Twitter 词云

图 6.3 – Twitter 词云

除了真实世界的 NLP 数据,Pluto 还使用了查尔斯·狄更斯的《双城记》前几行作为控制文本。在本章中,Pluto 将扩展控制文本,加入狄更斯先生的《双城记》第一页、梅尔维尔的《白鲸》和卡罗尔的《爱丽丝梦游仙境》。这些书籍是公共领域作品,定义见古腾堡计划。

变量分别为 pluto.orig_textpluto.orig_dickens_pagepluto.orig_melville_pagepluto.orig_carroll_page

有趣的事实

机器学习擅长改变典型的人类写作文本,但修改经典作品几乎是犯罪行为。Pluto 只希望阐明增强概念,绝不亵渎经典。这一切都是为了科学。

你已经加载了 Python Notebook,实例化了 Pluto,访问了清理过的 NLP 真实世界数据,并通过词云信息图进行了验证。现在,是时候编写并调试 Python 代码,以更深入地了解机器学习中的单词和句子增强。

通过 Python Notebook 加强你的学习

尽管 NLP ML 非常复杂,包装代码的实现却出奇地简单。这是因为 Pluto 采用了结构化的面向对象方法。首先,我们在第一章中为 Pluto 创建了一个基础类,并使用装饰器在学习新的增强概念时添加了新方法。在第二章中,Pluto 学会了从 Kaggle 网站下载成千上万的真实世界数据集。第三章第四章介绍了包装函数的处理过程,使用了强大的开源库。最后,第五章提出了使用Nlpaug库时的文本增强概念和方法。

因此,基于我们之前的知识,本章中的包装函数使用强大的 NLP ML 预训练模型来执行增强。

本章将特别介绍包装函数和使用以下技术对 Netflix 和 Twitter 真实世界数据集进行增强的结果:

  • Word2Vec 词语增强

  • BERTTransformer 词语增强

  • RoBERTa 增强

  • 回译

  • T5 增强

  • SequentialSometime 增强

让我们从 Word2Vec 开始。

Word2Vec 词语增强

print_aug_ai_word2vec()包装函数的关键参数如下:

# code snippet for print_aug_ai_word2vec()
model_type = 'word2vec',
model_path = 'GoogleNews-vectors-negative300.bin'
action = 'insert'    # or 'substitute'
nlpaug.augmenter.word.WordEmbsAug(model_type,
  model_path,
  action)

完整的函数可以在 Python Notebook 中找到。Pluto 使用真实世界的 NLP Netflix 数据来测试该函数,具体如下:

# augment using word2vec
pluto.print_aug_ai_word2vec(pluto.df_netflix_data,
  col_dest='description',
  action='insert',
  aug_name='Word2Vec-GoogleNews Word Embedding Augment')

趣味事实

当你运行一个包装函数时,新的数据会被随机选择并处理。因此,最好反复运行包装函数,查看来自 Netflix 数据集的不同电影评论或来自 Twitter 数据集的不同推文。

输出如下:

图 6.4 – 使用插入模式的 Word2Vec 在 Netflix 数据上的应用

图 6.4 – 使用插入模式的 Word2Vec 在 Netflix 数据上的应用

图 6.3中,第一行是控制输入。它摘自《双城记》这本书。你会发现,通过将控制文本与数据集中的文本进行对比,增强效果更容易察觉。此外,控制文本对于比较不同增强技术之间的差异也是必需的。

Pluto 发现,在第 1 行中注入的名称,如Punta(一个可信的西班牙作家名字)和Poydras,作为实际名称和可行的添加物,符合这个名人电影评论的背景。虽然这些名字在电影中并不真实出现,但它们在电影情感预测的文本增强中是可以接受的。

第 2 行中,blendingdangerousoriginal 1960s这几个词为电影描述增添了色彩,同时又不改变间谍电影描述的意图。

第 3 行,在漫画《绿箭侠》电影描述中,加入像Kent of Cabus(来自英国 Cabus 村的 Kent)、Rangjung(不丹的一个村庄,作为可能的英雄名字)和Elizabeth(作为反派角色)的名字是 100%合理的情节设定,适合我们的超级英雄。

总的来说,Pluto 对Word2Vec机器学习模型感到惊讶。单词和名字的插入情境非常合适,仿佛是人类作家创作的。然而,狄更斯的控制文本读起来非常有趣,这并不是机器学习的错。系统并不知道这本书是 19 世纪写的,只根据文本的前几行做出了推断。电影评论是完整的思路,而控制文本只是片段之一。

Pluto 对真实世界的 Twitter 数据执行类似的命令,具体如下:

# augment using word2vec
pluto.print_aug_ai_word2vec(pluto.df_twitter_data,
  col_dest='clean_tweet',
  action='insert',
  aug_name='Word2Vec-GoogleNews Word Embedding Augment')

输出如下:

图 6.5 – Word2Vec 在 Twitter 数据上的插入模式

图 6.5 – Word2Vec 在 Twitter 数据上的插入模式

由于推文就像是没有经过深思熟虑或编辑的随机想法,在图 6.4中,Word2Vec的插入就像一个无聊的高中生一边做作业一边玩电脑游戏。Pluto 无法判断修改后的文本是否合理。这会增加还是减少 AI 在情感分析中的预测准确性?

对于狄更斯的控制文本,Pluto 感到震惊。它非常糟糕,但他承诺当使用变换器和生成 AI 时,后续模型会更好。

现在我们看过了insert模式,让我们看看Word2Vec模型在substitute模式下的表现。

Substitute

Substitute模式会替换单词,并且在句子中添加单词。Pluto 将Word2Vec模型以substitute模式应用于 Netflix 数据,具体如下:

# augmenting using word2vec
pluto.print_aug_ai_word2vec(pluto.df_netflix_data,
  col_dest='description',
  action='substitute',
  aug_name='Word2Vec-GoogleNews Word Embedding Augment')

输出如下:

图 6.6 – Word2Vec 在 Netflix 数据上的替换模式

图 6.6 – Word2Vec 在 Netflix 数据上的替换模式

图 6.5中,第 0 行是控制文本,而第 1 行中,zany adventure适合儿童冒险电影,但liquid viagra显然不合适。

第 2 行,将police替换为troopersjob替换为plum assignmentwrest替换为must takefigure替换为hand,以及将offenders替换为criminals,这些在警匪电影中是合适的。因此,Word2Vec模型做了适当的增强处理。

第 3 行,将cinematic distillation替换为Scorcese decaffeination是一个有趣的选择,值得人类作家考虑。将electrifying改为sparkling很聪明,因为电力可以产生火花。将shadowy替换为clandestine是个不错的选择,但将seven改为five则显得不必要。

再次说明,Word2Vec模型在控制文本的处理上本可以做得更好。

Pluto 对 Twitter 数据做了同样的处理,命令如下:

# augmenting using word2vec
pluto.print_aug_ai_word2vec(pluto.df_twitter_data,
  col_dest='clean_tweet',
  action='substitute',
  aug_name='Word2Vec-GoogleNews Word Embedding Augment')

输出如下:

图 6.7 – Word2Vec 在 Twitter 数据上使用替换模式

图 6.7 – Word2Vec 在 Twitter 数据上使用替换模式

图 6.6中,推文杂乱无章,许多内容是不完整的想法。Word2Vec模型尽力而为,而 Pluto 认为没有人类能做得更好。

接下来我们要探讨的技术是 BERT,它使用变压器模型和生成性 AI。

BERT

BERT 是一个由 Google 开发的变压器模型,经过大量语料库的训练。结果是接近完美的人类质量输出。从 2022 年 8 月中旬开始,BERT 和许多其他变压器模型通过 HuggingFace 向公众开放,易于获取。

print_aug_ai_bert() 函数的关键代码行如下:

# code snippet for print_aug_id_bert()
model_path='bert-base-uncased'
aug_func = nlpaug.augmenter.word.ContextualWordEmbsAug(
  action=action,
  model_path=model_path)

完整的函数可以在 Python Notebook 中找到。Pluto 使用 insert 模式将 NLP Netflix 数据输入,命令如下:

# Augmenting using BERT
pluto.print_aug_ai_bert(pluto.df_netflix_data,
  col_dest='description',
  action='insert',
  aug_name='BERT Embedding Insert Augment')

结果如下:

图 6.8 – BERT 在 Netflix 数据上使用插入模式

图 6.8 – BERT 在 Netflix 数据上使用插入模式

图 6.7中,Pluto 立刻识别出与 Word2Vec 模型的改进。在控制文本第 0 行中,插入的单词是可以接受的。虽然缺乏散文的优雅,但如果必须在文本中加入单词,这样的文本看起来像人类写的。

第 1 行,添加的短语恰到好处,如 afterward(之后)、financial dubious(财务可疑)、knee surgery(膝盖手术)、和 to play a national film stage(演奏国家级电影舞台)。

第 2 行,增强的短语质量达到了人类作家的水平,如 whilst in hiding(在隐藏中)、deeply suspect(深度可疑)、unknown maid(未知的女仆)、perhaps his only(或许是他唯一的)、outside Russian world(俄罗斯外部世界)、以及 maybe hiding quite something(也许隐藏着某种东西)。

第 3 行,Pluto 对结果印象深刻,例如 arriving in February(二月到达)、little Indian lad(小印度男孩)、despite sparse funding(尽管资金稀缺)、funding mathematics and physics(资助数学和物理)、和 first functioning airplane(第一架有功能的飞机)。

有趣的事实

你是否像 Pluto 一样对 BERT 模型的输出感到惊讶?它就像是一个真人,而不是一个人工神经网络(ANN)。

请重新运行包装函数,查看 BERT 对其他电影评论的增强效果。你读得越多,就越能欣赏使用 变压器 模型的先进突破。它是生成性 AI 的基础。

接下来,Pluto 使用插入模式将 Twitter 数据输入 BERT 模型,命令如下:

# augmenting using BERT
pluto.print_aug_ai_bert(pluto.df_twitter_data,
  col_dest='clean_tweet',
  action='insert',
  aug_name='BERT Embedding Insert Augment')

结果如下:

图 6.9 – BERT 在 Twitter 数据上使用插入模式

图 6.9 – BERT 在 Twitter 数据上使用插入模式

有趣的事实

图 6.8中,BERT 模型给出了另一版本的狄更斯控制文本。每次 Pluto 运行包装函数时都会得到一个新的版本。可能性是无穷无尽的。Pluto 必定运行了超过 50 次包装函数。每次结果都不同。

Pluto 发现有比推文更适合研究的 NLP 数据,但它们代表了真实世界,因此值得继续使用。当 Pluto 反复运行包装函数时,他更喜欢 BERT 增强版的推文而不是原始推文,因为插入文本使其更易阅读。

当切换到替换模式时,BERT 的输出优于普通人类写作。

替换

接下来,Pluto 使用以下命令将 Netflix 数据以替换模式输入到 BERT 中:

# augmenting using BERT
pluto.print_aug_ai_bert(pluto.df_netflix_data,
  col_dest='description',
  action='substitute',
  aug_name='BERT Embedding Substitute Augment')

结果如下:

图 6.10 – BERT 在 Netflix 数据上使用替换模式

图 6.10 – BERT 在 Netflix 数据上使用替换模式

图 6.9中,对于控制文本,第 #0 行,BERT 将它是愚蠢的时代替换为死亡是爱的时代

有趣的事实

停止。Pluto 的思维被震撼了。甚至 Pluto 的人类伙伴也无言以对。Pluto 期待像 BERT 这样的变压器模型能做到很好,但哲学思考或诗歌是另一个层次的。现在,你对 BERT 印象深刻了吗?

剩余的电影评论增强内容,如第 #1 行第 #2 行第 #3 行,完美无瑕。增强后的词语与电影的类型和背景契合。就像 BERT 理解了电影的意义,但这并不真实。BERT 模型并不像烤面包机那样具备意识。然而,BERT 确实能很好地模仿人类写作。

一个有趣的注释是,在第 #1 行中,在描述一对情侣关系的电影描述中,BERT 使用了词汇gay,这在上一章关于数据偏见中有讨论过。因为gay是一个形容轻松和无忧无虑的词汇,但在现代语境下,gay通常与一个人的同性恋倾向,尤其是男性的同性恋倾向相关联。

再次提醒,Pluto 鼓励你在 Python Notebook 上反复运行包装函数。你将会超越技术成就的欣赏,觉得 BERT 甚至有了个性。

Pluto 使用以下命令对 Twitter 数据进行了相同的处理:

# augmenting using BERT
pluto.print_aug_ai_bert(pluto.df_twitter_data,
  col_dest='clean_tweet',
  action='substitute',
  aug_name='BERT Embedding Substitute Augment')

结果如下:

图 6.11 – BERT 在 Twitter 数据上使用替换模式

图 6.11 – BERT 在 Twitter 数据上使用替换模式

当 Pluto 在 Python Notebook 上反复运行包装函数时,在图 6.10中,他发现增强后的推文比原始文本更易于阅读。

对于控制文本,第 #0 行,Pluto 发现将增强后的文本它是青春的时代替换原文它是信仰的时代,是非常合适的。这与狄更斯先生书中的背景和风格非常契合。

有趣的挑战

这个挑战是一个思维实验。BERT 是基于人工神经网络(ANN)算法构建的。它不包含语法规则,比如名词和动词用来构造句子。没有语法规则,它是如何写出如此流利的英语的呢?提示:考虑模式。BERT 在庞大的语料库上进行了训练。单词和句子的数量大到五年前根本无法想象。很少有人知道神经网络算法是如何学习的。这不是复杂的数学问题。它是梯度下降和矩阵乘法推动数十亿个节点(或神经元),但这些节点的集合又是如何写出让人信服的英语的呢?

冥王星可以花几天时间讨论 BERT,但让我们继续深入了解RoBERTaRoberta)。这听起来像是 BERT 的女性版。

RoBERTa

RoBERTa 是 BERT 的自监督优化算法。虽然 BERT 是由谷歌创建的,但 RoBERTa 是 Meta AI(或 Facebook)开发的。

冥王星用以下命令将 Netflix 数据输入 RoBERTa 的插入模式:

# augmenting using Roberta
pluto.print_aug_ai_bert(pluto.df_netflix_data,
  col_dest='description',
  model_path='roberta-base',
  action='insert',
  aug_name='Roberta Embedding Insert Augment')

结果如下:

图 6.12 – RoBERTa 在 Netflix 数据上使用插入模式

图 6.12 – RoBERTa 在 Netflix 数据上使用插入模式

图 6.11中的输出与BERT的输出相似,令人印象深刻。单词并不是随机插入句中的。它们表达了可能的解释,并给人一种RoBERTa理解单词意义的印象。这样的技术成就 1 年前是无法实现的,而RoBERTa几个月前才发布。

冥王星反复运行包装函数,并且从未厌倦阅读结果。他用以下命令对 Twitter 数据做了相同的操作:

# augmenting using Roberta
pluto.print_aug_ai_bert(pluto.df_twitter_data,
  col_dest='clean_tweet',
  model_path='roberta-base',
  action='insert',
  aug_name='Roberta Embedding Insert Augment')

结果如下:

图 6.13 – RoBERTa 在 Twitter 数据上使用插入模式

图 6.13 – RoBERTa 在 Twitter 数据上使用插入模式

冥王星无法将铅变成金子,而 RoBERTa 也无法将如图 6.12所示的包含拼写错误和不完整想法的推文转化为连贯的句子。尽管如此,RoBERTa 仍然是增强现实世界推文的最佳选择之一。

接下来,冥王星将尝试使用替换模式的RoBERTa

替换

在替换模式下,RoBERTa 将根据上下文和写作风格,以惊人的准确度替换单词或短语。

冥王星将 Netflix 数据以替换模式输入 RoBERTa 模型,使用以下命令:

# augmenting using Roberta
pluto.print_aug_ai_bert(pluto.df_netflix_data,
  col_dest='description',
  model_path='roberta-base',
  action='substitute',
  aug_name='Roberta Embedding Substitute Augment')

输出如下:

图 6.14 – RoBERTa 在 Netflix 数据上使用替换模式

图 6.14 – RoBERTa 在 Netflix 数据上使用替换模式

无论冥王星执行多少次包装函数,他仍然对 RoBERTa 在图 6.13中提供的输出感到惊讶。例如,在第 1 行,她将短语Alex discovers he has little in common with the local改为Alex discovers Flix had special romantic chemistry with the local。RoBERTa 真是富有想象力。这就是人类写作时的方式吗?

冥王星使用以下命令对 Twitter 数据执行相同操作:

pluto.print_aug_ai_bert(pluto.df_twitter_data,
  col_dest='clean_tweet',
  model_path='roberta-base',
  action='substitute',
  aug_name='Roberta Embedding Substitute Augment')

结果如下:

图 6.15 – RoBERTa 在 Twitter 数据上的替代模式使用

图 6.15 – RoBERTa 在 Twitter 数据上的替代模式使用

图 6.14所示,文本增强不必是枯燥或临床的。使用 BERT 和 RoBERTa 等变换器模型,增强过程既有趣又充满奇迹。例如,在控制文本中,第 0 行,RoBERTa 写道,它对傲慢宣讲了诅咒,取代了这是一个信仰的时代

有趣的事实

冥王星的人类伴侣需要经过长时间的思考,才能得出结论:增强文本确实与图 6.14中的原始文本——控制文本——意义相同。很容易被误导,认为 RoBERTa 有良知。我们将智能与意识相联系,意味着如果你有智能,你必须是自我意识的,反之亦然,但我们知道这并不成立。例如,一名职业政治家非常自我意识。他一直在谈论自己,但他聪明吗?

继续使用最新的强大 ML 模型,冥王星将通过使用反向翻译技术走上不同的文本增强道路。

反向翻译

反向翻译是文本增强中的一个新概念,因为在两年前是不可行的。机器学习的自然语言处理(ML NLP)技术早已存在,Google 翻译也一直在推进。但只有少数数据科学家能够使用变换器和进行语言翻译所需的强大服务器,访问大型语言模型。

文本增强的技术是将文本翻译成另一种语言,然后再翻译回原语言。通过这种方式,结果将是原始文本的增强版本。没有任何语言翻译是完美的,因此扩展版本会与原始文本略有不同。例如,原文是英文的。使用强大的 NLP 模型,我们将其翻译成德语,然后再翻译回英语。翻译后的英语文本将与原始的英语文本有所不同。

Word2VecBERTRoBERTa相比,反向翻译方法可能更具鲁棒性。这是因为翻译回原文时,第二次或第三次得到的结果是相同的。换句话说,其他方法的输出会产生成千上万种变化,而反向翻译则只有两三种增强版本。

冥王星在HuggingFace网站上找到了两个来自 Facebook(或 Meta AI)的 NLP 预训练翻译模型,它们支持英语到德语(Deutsch)和英语到俄语(Русский)。还有更多的模型,但这两个足以展示该技术。让我们从德语开始。

德语 (Deutsch)

print_aug_ai_back_translation()方法遵循与其他包装函数相同的结构。它看起来 deceptively 简单,只有五行代码,但实际上包含了复杂的理论和编码技巧。这让 Pluto 想起了艾萨克·牛顿爵士的名言:“如果我看得更远,那是因为站在了 巨人的肩膀上。

关键代码行如下:

# code snippet for back translation
from_model_name='facebook/wmt19-en-de'
to_model_name='facebook/wmt19-de-en'
aug_func = nlpaug.augmenter.word.BackTranslationAug(
  from_model_name=from_model_name,
  to_model_name=to_model_name)

完整的函数可以在 Python Notebook 中找到。Pluto 使用以下命令将 Netflix 数据输入:

# augmenting using back translation
pluto.print_aug_ai_back_translation(pluto.df_netflix_data,
  col_dest='description',
  from_model_name='facebook/wmt19-en-de',
  to_model_name='facebook/wmt19-de-en',
  aug_name='FaceBook Back Translation: English <-> German Augment')

结果如下:

图 6.16 – 回译,Netflix 数据中的德语

图 6.16 – 回译,Netflix 数据中的德语

趣事

图 6.15中的输出令人失望,因为它与原文相似,但这一技术成就令人震惊。首先,你需要一位专家将英语翻译成德语。这对人类来说是一个具有挑战性的任务。其次,你必须将其无误地翻译回英语。选择类似词语的差异体现在表达上。也许只有全球 5% 的人能完成这个任务。让机器全天候、每周 7 天、维持同样的准确性水平来完成这项任务是神奇的。没有人类能够达到这个水平。

图 6.15中的输出提供了几乎完美的英德回译。Pluto 用以下命令对 Twitter 数据做了相同的操作:

# augmenting using back translation
pluto.print_aug_ai_back_translation(pluto.df_twitter_data,
  col_dest='clean_tweet',
  from_model_name='facebook/wmt19-en-de',
  to_model_name='facebook/wmt19-de-en',
  aug_name='FaceBook Back Translation: English <-> German Augment')

输出如下:

图 6.17 – 回译,Twitter 数据中的德语

图 6.17 – 回译,Twitter 数据中的德语

图 6.16中,将无意义的推文翻译成德语并回译对人类来说更困难,因为我们的思维更容易疲劳并且会放弃。只有机器才能全天候完成这项工作。控制文本的德语回译是可以接受的。

将文本翻译成俄语并回译会产生类似的结果。我们来看看。

俄语(Русский)

Pluto 选择重复相同的英俄回译技术,因为他好奇选择非罗曼语族语言是否会对增强结果产生不同的影响。

使用相同的print_aug_ai_back_translation()函数,Pluto 将俄语翻译的 Facebook 模型定义如下:

# code snippet for back translation to Russian
from_model_name='facebook/wmt19-en-ru'
to_model_name='facebook/wmt19-ru-en'

完整的函数代码可以在 Python Notebook 中找到。Pluto 将 Netflix 数据传递给包装函数如下:

# augmenting using back translation
pluto.print_aug_ai_back_translation(pluto.df_netflix_data,
  col_dest='description',
  from_model_name='facebook/wmt19-en-ru',
  to_model_name='facebook/wmt19-ru-en',
  aug_name='FaceBook Back Translation: English <-> Russian Augment')

结果如下:

图 6.18 – 回译,Netflix 数据中的俄语

图 6.18 – 回译,Netflix 数据中的俄语

值得注意的是,在图 6.17中,NLP T5 模型将一种罗曼语族语言(英语)翻译成一种东斯拉夫语言(俄语)并回译,几乎达到了完美的准确性。语法规则、句子结构、字母表、历史、文化和语言都不同,但机器能够在没有意识的情况下完成这项任务。

推文不适合测试,但并非所有项目都是合乎逻辑的。Pluto 曾参与过一些构思不周的现实世界 NLP 项目。向包装函数提供推特数据的命令如下:

# augmenting using back translation
pluto.print_aug_ai_back_translation(pluto.df_twitter_data,
  col_dest='clean_tweet',
  from_model_name='facebook/wmt19-en-ru',
  to_model_name='facebook/wmt19-ru-en',
  aug_name='FaceBook Back Translation: English <-> Russian Augment')

结果如下:

图 6.19 – 反向翻译,推特数据上的俄语

图 6.19 – 反向翻译,推特数据上的俄语

如果俄罗斯人不能理解推文,那么还有谁能呢?阅读图 6.18中的控制文本,Pluto 可以判断翻译是否正确。由于某些推文较短,翻译成俄语后再翻回英语非常完美。

有趣的挑战

这个挑战是一个思想实验。你能否使用相同的技术来增强德语?或者你能否将几个反向翻译组合在一起——例如,从英语翻译到德语,再到俄语,最后回到英语?

反向翻译RoBERTaBERTWord2Vec NLP 机器学习模型是文本增强的最先进技术。下一个层次是使用摘要和顺序及有时技术的句子增强。

句子增强

句子级别使用了多种词汇增强方法的结合。但在此之前,Pluto 将使用T5 NLP 模型生成文本摘要。摘要技巧是最近才实现的一项新概念。它可以将一页、一篇文章甚至一本书生成一个摘要,用于 NLP 文本增强模型中。

摘要技巧

对于文本增强,摘要技巧可能会带来几个不同的版本进行训练。然而,假设 Pluto 将摘要技巧结合起来,例如,向技巧提供摘要文本,而不是原始文本,在这种情况下,它将生成许多新的原始文本用于训练。

有趣的事实

Pluto 首创了摘要到流的概念,用于文本增强。他在网上和学术出版物中做了初步搜索,但他需要帮助找到摘要到流技巧的参考文献。如果没有找到相关资料,那么 Pluto 就是第一个实现该策略的人。

Pluto 不会使用 Netflix 电影描述或 Twitter 推文作为摘要方法。这是因为它们太短,无法展示 T5 NLP 模型的强大功能。相反,Pluto 将使用以下现实世界 NLP 数据部分提到的书籍的第一页:

  • 双城记 由狄更斯所著

  • 白鲸 由梅尔维尔所著

  • 爱丽丝梦游仙境 由卡罗尔所著

再次强调,这些书籍是公有领域的,如古腾堡计划所定义。

此外,Pluto 将使用本章的第一页,因为你已经读过这本书,但你可能没有读过那三本经典书籍。

print_aug_ai_t5()包装函数的关键代码行如下:

aug_func = nlpaug.augmenter.sentence.AbstSummAug(
  model_path='t5-base')

普鲁托正在和你玩猜谜游戏。首先,他将列出四条命令行来生成四个摘要,但他会将输出结果打乱顺序。因此,你必须猜出哪个摘要属于哪本书。你将再次对T5 NLP 模型的输出质量感到惊讶,它可与人类作家相媲美。

深刻的意义在于,你或普鲁托可以通过几行 Python 代码自动生成书籍、论文、文档、文章和帖子摘要。几年前,这项任务被认为是不可能完成的。

有趣的挑战

这里有一个思维实验。你能在不懂德语的情况下成为德国法律的专家吗?一年前这是不可能的,因为当时没有机器学习的突破,但今天,你可以使用 Python Notebook 中的代码作为基础,翻译所有德国语法书籍。

获取我们将要查看的四本书第一页摘要的四条命令如下:

# Alice in Wonderland
pluto.df_t5_carroll = pluto.print_aug_ai_t5(
  pluto.orig_carroll_page,
  bsize=1)
# Tale of Two Cities
pluto.df_t5_dickens = pluto.print_aug_ai_t5(
  pluto.orig_dickens_page,
  bsize=1)
# Moby Dick
pluto.df_t5_melville = pluto.print_aug_ai_t5(
  pluto.orig_melville_page,
  bsize=1)
# This chapter first page
pluto.df_t5_self = pluto.print_aug_ai_t5(
  pluto.orig_self,
  bsize=1)

打乱顺序的结果如下:

图 6.20 – 摘要 T5 NLP 引擎 – 1

图 6.20 – 摘要 T5 NLP 引擎 – 1

第二个输出如下:

图 6.21 – 摘要 T5 NLP 引擎 – 2

图 6.21 – 摘要 T5 NLP 引擎 – 2

第三个输出如下:

图 6.22 – 摘要 T5 NLP 引擎 – 3

图 6.22 – 摘要 T5 NLP 引擎 – 3

第四个输出如下:

图 6.23 – 摘要 T5 NLP 引擎 – 4

图 6.23 – 摘要 T5 NLP 引擎 – 4

有趣的挑战

你能将摘要与书籍匹配起来吗?T5 引擎并不像 OpenAI GPT3、GPT4 或 Google Bard 那样是一个生成型人工智能引擎,但它的摘要非常准确。

双城记书籍,如图 6.19所示,是一本相对较难读的书,普鲁托觉得非常有趣的是,现代政治评论员大卫·罗斯科普夫竟然与狄更斯的这本书有关联。书的第一页确实提到了英国臣民在美国的议会。因此,罗斯科普夫先生的关联是一个很好的猜测,也许普鲁托应该将章节的前 10 页输入到T5 NLP 引擎中,并查看摘要。

白鲸的第一页摘要非常到位,如图 6.20所示。它可以与人类作家的作品相媲美,第一页的第一个词是以实马利。普鲁托希望T5 NLP 模型能在他上学的早期就出现。

普鲁托的人类伙伴高兴地承认,这一章节第一页的摘要更为精准且易于阅读,如图 6.21所示。也许T5 NLP 引擎应该和普鲁托一起共写这本书,这样他的伙伴就能在阳光明媚的下午享受追逐松鼠的乐趣。

爱丽丝梦游仙境的第一页摘要完美无缺,如图 6.22所示。T5 NLP 引擎无误地捕捉到了开篇的内容。作为额外奖励,普鲁托只输入了前五句话。输出如下:

图 6.24 – 摘要 T5 NLP 引擎 – 《爱丽丝梦游仙境》前五行

图 6.24 – 总结 T5 NLP 引擎 – 《爱丽丝梦游仙境》的前五行

图 6.23中,T5如何知道白兔是故事中的关键?兔子只在输入文本的最后一句话中出现,称爱丽丝为雏菊链的制造者非常有趣。

句子增强的下一步是将这些摘要输入到方法中。

总结到流技术

流技术中的顺序方法按顺序应用增强列表。Pluto 创建了两个文本增强方法,如下所示:

# augment using uloVe
pluto.ai_aug_glove = nlpaug.augmenter.word.WordEmbsAug(
    model_type='glove', model_path='glove.6B.300d.txt',
    action="substitute")
# augment using BERT
pluto.ai_aug_bert = nlpaug.augmenter.word.ContextualWordEmbsAug(
  model_path='bert-base-uncased',
  action='substitute',
  top_k=20)

第一个使用print_aug_ai_sequential()包装函数,它使用增强列表和关键代码行,如下所示:

# augment using sequential
aug_func = nlpaug.flow.Sequential(
  [self.ai_aug_bert, self.ai_aug_glove])

Pluto 将四个摘要输入流方法,如下所示:

# Alice in Wonderland
pluto.print_aug_ai_sequential(pluto.df_t5_carroll)
# Tale of Two Cities
pluto.print_aug_ai_sequential(pluto.df_t5_dickens)
# Moby Dick
pluto.print_aug_ai_sequential(pluto.df_t5_melville)
# This chapter
pluto.print_aug_ai_sequential(pluto.df_t5_self)

让我们来看一下结果。

*《爱丽丝梦游仙境》*的增强摘要输出如下:

图 6.25 – 总结到流方法,爱丽丝梦游仙境

图 6.25 – 总结到流方法,爱丽丝梦游仙境

*《双城记》*的增强摘要输出如下:

图 6.26 – 总结到流方法,双城记

图 6.26 – 总结到流方法,双城记

*《白鲸》*的增强摘要输出如下:

图 6.27 – 总结到流方法,白鲸

图 6.27 – 总结到流方法,白鲸

本章的增强摘要输出如下:

图 6.28 – 总结到流方法,本章

图 6.28 – 总结到流方法,本章

Pluto 喜欢阅读增强后的摘要。有些聪明,有些夸张,但对于增强文本来说,它们足够了。

下一步是print_aug_ai_sometime()包装函数,位于 Python Notebook 中,但他认为在这一章解释结果不会带来更多的洞察。你可以在 Python Notebook 中运行这个包装函数并查看结果。

有趣的挑战

Pluto 挑战你重构Pluto 类,使其更快、更紧凑。你还应包含前几章的所有图片包装器和辅助函数。Pluto 鼓励你创建并上传你的库到GitHubPyPI.org。此外,你不必将类命名为PacktDataAug,但如果你引用或提到这本书,Pluto 和他的人类伙伴会露出灿烂的笑容。代码目标是为了易于理解、可重用的模式,以及在Python Notebook中的教学。因此,将代码重构为 Python 库会相对轻松且有趣。

总结到流技术是本章最后将介绍的方法。现在,让我们总结一下这一章。

摘要

使用机器学习(ML)进行文本增强是一项高级技术。我们使用了一个预训练的 ML 模型来创建额外的训练 NLP 数据。

在输入前三个段落后,T5 NLP ML 引擎为本章写出了前面的总结。它非常完美,体现了本章的精神。因此,Pluto 保留了这个总结不做更改。

此外,我们讨论了 14 种 NLP ML 模型和四种词语增强方法。它们分别是Word2VecBERTRoBERTa回译

Pluto 展示了 BERT 和 RoBERTa 能与人类写作相媲美。增强后的文本不仅仅是合适的,还富有启发性,例如将这是愚蠢的时代替换为死亡是爱的时代,或者将这是信仰的时代替换为这是青春的时代

对于回译方法,Pluto 使用 Facebook 或 Meta 的 AI NLP 模型将文本翻译成德语和俄语,然后再翻译回英语。

对于句子增强,Pluto 通过 T5 NLP ML 引擎精准总结了三本经典书籍的第一页,给大家留下了深刻印象。此外,他还开创了从总结到流的文本增强概念。Pluto 可能是第一个实现从总结到流策略的人。

在本章中,有许多有趣的事实有趣的挑战。Pluto 希望你能充分利用这些内容,拓展你的经验,超越本章的范围。

下一章将讨论音频增强,这将带来不同的挑战,但 Pluto 已经准备好应对它们。

第四部分:音频数据增强

本部分包括以下章节:

  • 第七章音频数据增强

  • 第八章使用谱图进行音频数据增强