TowardsDataScience 博客中文翻译 2020(八十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

使用 Python 探索机器学习

原文:https://towardsdatascience.com/adventure-into-machine-learning-using-python-7a85fce81b7d?source=collection_archive---------32-----------------------

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

弗兰基·查马基在 Unsplash 上拍摄的照片

近年来,机器学习引起了前所未有的关注。机器学习的一个吸引人的方面是它能够从原始数据中释放大量有用的信息,这些信息可以在许多商业和研究环境中驱动决策过程。例如,沃尔玛是使用机器学习来提高销售业绩的零售企业领导者之一。

[## 沃尔玛:利用大数据、机器学习、人工智能和物联网提升零售业绩

沃尔玛可能自 20 世纪 60 年代就已经存在,但在寻找新方法方面,该公司仍处于领先地位…

www.bernardmarr.com](https://www.bernardmarr.com/default.asp?contentID=1276)

虽然我们可能已经听说了许多关于机器学习应用的成功和令人兴奋的故事,但我们应该如何开始利用这项强大的技术呢?

好消息是,这不需要投入大量成本来开始构建机器学习应用程序。我们可以免费使用许多开源开发工具。我们所需要的只是一台能上网的个人电脑。在这篇文章中,我将分享一个使用开源 Python 库的机器学习的示例工作流。

什么是机器学习?

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

亚历山大·奈特Unsplash 上拍照

在我们讨论机器学习的技术方面之前,让我们回顾一下机器学习的概念,以确保我们意识到我们将要做的工作。

首先,机器学习不一定是为如上图所示的自主机器人编程的实践。让我们看看人工智能(AI)先驱亚瑟·塞缪尔(创造了“机器学习”这个术语的计算机科学家)给出的定义:

“机器学习是一个研究领域,它赋予计算机无需显式编程就能学习的能力”阿瑟·塞缪尔,1959

在机器环境中解释“学习”可能很棘手。有人可能会问,机器怎么可能“学习”?我们是不是在试图给我们的计算机 CPU 植入某种极其强大的芯片,使它能够像人一样思考?后一个问题的答案是一个简单的“不”。为了回答第一个问题,我将用一个非常简单的例子来说明如下的概念。

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

假设你是一名数据分析师,你的任务是创建一个模型,仅基于两个因素来预测单位面积的房价:地理位置和到最近的 MRT 的距离。你会得到一个房价数据集,其中还包括地理位置和到最近的捷运站的距离的详细信息。对数据集的第一印象可能会让你想到房价和地理位置+ MRT 距离之间可能存在相关性(见下文)。

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

显示房价和地理位置+到最近的 MRT 的距离之间的相关性的数据集片段

很明显,如果单位位于市区,离捷运较近,单位面积的房价就越来越高。此外,地理位置的因素比到最近的捷运站的距离具有更高的权重。此时,一个非常简单的模型可以表述如下:

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

预测房地产价值的简单模型

然而,问题是你如何确定 w1 和 w2 的值?一种方法是使用数据集通过反复调整 w1 和 w2 来训练机器学习模型,直到模型能够以期望的精度预测房地产价值。

简单地说,我们可以将机器学习模型视为黑盒机器,当它被输入数据集时,可以被调整以给出优化的预测输出。这个黑盒机器可以通过训练周期的循环来训练,以保持更新 w1 和 w2。当 w1 & w2 被优化以预期精度预测房地产价值时,黑匣子机器被认为是已学习的

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

训练机器学习算法的简单说明

训练机器学习模型的一种常见方法是监督学习。在本文中,我将介绍监督学习方法。

亲自动手

现在,我们对机器学习有了一些想法,我们准备转向实用方面,开始训练机器学习模型。

1.目标

本项目的目标是对新店区的房价进行价值评估。台湾新北市。为了实现目标,我们将训练一个机器学习模型来预测房价。

2。数据集的采集

我们将使用可以从 UCL 机器学习库获得的房地产估价数据。房地产数据存储在 Excel 文件中。

一般来说,机器学习的数据来源主要有两个:1)我们自己的收集,2)公共数据。我们倾向于将公共数据用于学习或实验目的,因为这可以节省我们自己收集数据的大量时间。感谢数据科学社区的慷慨,我们可以很容易地从诸如 KaggleUCL 机器学习库开放数据等网站获得公共数据,仅举几例。

3。设置机器学习工作空间

准备好原始数据后,我们可以开始设置我们的机器学习工作区。

3.1 硬件要求

我们不需要一台安装了 NVIDIA GPU 的高成本电脑来运行这个机器学习项目。配备 i5 或 i7 处理器和 8GB 内存的 PC 或 Mac 电脑足以满足这个简单项目的硬件要求。

3.2 软件要求

我们将为这个项目使用基于 Python 的机器学习和数据处理库,因此我们的计算机将准备好:

获得所有这些 Python 库的最简单的方法是在我们的计算机上安装 Anaconda 包。Anaconda 在一个包中提供了大多数基于 Python 的机器学习和数据处理库。

4.探索数据

这对于我们在使用数据来训练我们的机器学习模型之前对数据有一个大致的了解是很重要的。为了探索我们的数据,我们将使用 Jupyter Notebook 作为我们的编辑器,并开始编写 Python 代码。

首先,我们可以创建一个笔记本,并使用熊猫来读取我们的房地产数据。(请注意我已经将 Excel 文件重命名为“Real _ estate _ data . xlsx”)。

从 Excel 文件中读取数据的代码片段

我们使用 Pandas head()和 info() 方法来快速浏览我们的数据。

查看前五条记录的代码片段

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

前五条记录

head() 方法显示前五条记录。

获取数据快速描述的代码片段

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

数据描述

Pandas info() 方法给了我们一个快速描述数据的方法。例如:

  • 条目总数
  • 总列数
  • 每列中的数据类型

我们的房地产数据只有 414 个条目。这被认为是基于机器学习标准的非常小的数据集。然而,用它作为样本数据来启动一个简单的项目还是不错的。

这一点也值得强调,数据中的房价是以台币单位面积价格(新台币 $ )为基础的。

每列中的特征都是数字的。然而,并不是所有的特征都对训练机器学习模型有用。例如,第一列“No”只不过是一个记录索引。显然,它并没有显示出与房价有任何强相关性。因此,我们稍后将通过特性选择过程简单地过滤掉这个特性。

此外,我们的数据的许多列名太长,这将给使用 Pandas 提取单个列来分析它们带来一些困难。我们必须将这些列重命名为更简洁的名称,以简化我们的数据处理工作。

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

有问题的列名

5。预处理数据

在这个阶段,我们将再次使用 Python Pandas 库来过滤和清理我们的数据,然后才能将其用于训练我们的机器学习模型。

5.1 重命名列

我们通过重命名房地产数据中除“No”列之外的所有列名来开始我们的数据预处理步骤。为此,我们可以使用 Pandas rename() 方法。

重命名列的代码片段

要重命名列,我们只需创建一个列映射器, new_names (第 1–7 行)。我们将新的列名映射到原始名称,然后将整个列映射器设置为参数“columns”(第 9 行)。

接下来,我们再次使用 head() 方法来可视化前五条记录(第 10 行),我们将看到如下输出:

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

重命名的列

5.2 特征选择

如上所述,并非我们数据中的所有特征都将用于训练机器学习模型。只有那些与房价有良好相关性的特征才会被选择用于机器学习。此外,特征选择对于节省训练机器学习模型的计算成本和提高模型性能也很重要。

Pandas dataframe 提供了一种简便的方法, corr() ,来计算我们数据中存在的每一对特征之间的标准相关系数( Pearson’s r )。

计算标准相关系数的代码片段

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

标准系数的结果

为了解释如上所示的结果,我们需要理解几个重要的事实:

  • 相关系数的范围总是从-1 到 1
  • 如果该值接近 1,则意味着特定的一对要素之间存在强正相关性(例如,conv 商店与房屋价格)
  • 如果该值接近-1,则意味着在特定的一对要素(例如 dist_mrt vs house_price)之间存在一个强负相关性
  • 如果该值接近 0,则意味着该特定特征对之间没有线性相关性(例如,No vs house_price)。

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

结果表明,特征***【conv _ 商店】*** 和 dist_mrt 对房价的影响最大,因为它们分别具有最高的正相关性和负相关性。这个结果是有道理的,因为房价通常取决于周围设施的可用性。其中一个重要的设施是便利店。另一方面,当房地产远离公共交通服务时,房地产价值会大大降低(这就是为什么 dist_mrthouse_price 显示出强烈的负相关性)。

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

此外,我们不应该低估由特征 latlng 所代表的地理位置的影响。 latlng 的相关性分析表明,东北地区的房价往往更高。根据地理位置可视化房价分布的一种方法是使用 Python Matplotlib 库绘制散点图。

根据地理位置绘制房价分布散点图的代码片段

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

显示房价分布的散点图

散点图中的彩色地图显示,大多数高成本房地产集中在红圈区域。虽然并非所有高成本房地产都位于该地区,但仍显示出一种总体密度模式,即房地产价格往往高于其他地区。

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

此外,特征 房龄 也可以是影响房地产价格的一个重要因素,尽管这种影响比不上的 dist_mrt 和 conv_stores。

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

另一方面,特征 Notrans_date 显示与房价相关性差(接近于零)。

维度的诅咒

虽然数据集中至少有五个特征对训练我们的模型来说足够重要,但我们的数据集非常小,只有 414 个条目。根据 维数灾难 ,我们用来训练模型的特征越多,我们需要的数据集往往会呈指数级增长。总的来说,我们需要的数据集

1 特性= 10,

2 个特征= 10 * 10 = 100,

3 个特征= 10 * 10 * 10 = 1000 等等…

给定只有数百个条目的有限数据集,我们只能选择两个最相关的特征来训练我们的模型。于是,让我们挑选正负相关性最高的特征:conv _ 商店dist_mrt。

简而言之,基于相关性分析的结果和对维数灾难的考虑,只选择两个特征作为机器学习的输入特征

我们将使用 Pandas drop() 方法从数据集中删除特征 No、trans_date、lat、lng 和 house _ age*。此外,我们还需要从输入特性列表中排除“house_price”。*

从原始数据集中删除列的代码段

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

用作输入要素的剩余列

5.3 数据转换

在这个阶段,我们已经完成了特征选择,但是我们还没有准备好使用输入特征来训练我们的模型。在开始训练我们的模型之前,仍然需要完成几个预处理步骤。

我们需要将我们的输入特征转换成一个 Numpy 数组。此外,我们还需要从原始数据集中提取“house_price”并将其用作输出特征标签。输出要素也应该转换为 Numpy 数组。

要将输入要素和输出要素转换为 Numpy 数组,我们可以使用 Pandas 数据框 属性

将输入要素和输出要素转换为 Numpy 数组的代码片段

按照惯例,输入特征应存储在名为 X 的变量中,输出特征存储在名为 y 的变量中。

5.4 特征缩放

如果我们再次观察我们的输入特征 X,我们会发现它们是不同尺度的数值。

dist_mrt(最小值:23.38–最大值:6488)

conv 商店(最低:0–最高:10)

重新调整输入要素的比例以使它们共享相同的比例非常重要。为了获得优化的输出,特征缩放在许多机器学习算法中是重要的。功能缩放有几种方法,我们将使用的方法是标准化标准化是一个重新调整要素的过程,因此所有要素都具有均值为 0、标准差为 1 的标准正态分布。

Scikit-learn 提供了一个有用的模块,standard scaler类对输入特征执行标准化。

使用标准化执行数据缩放的代码片段

5.5 将数据集拆分为训练集和测试集

接下来,我们将把输入特征 X 和输出特征 y 分成两个独立的集合:训练集和测试集。顾名思义,训练集用于训练机器学习模型,而测试集用于在稍后阶段评估已训练的模型。

Scikit-learn 提供了另一个有用的模块, train_test_split ,它使我们能够用几行代码轻松地将数据分成一个训练集和一个测试集。

将数据集分成训练集和测试集的代码片段

*这里我们使用通用的命名惯例来创建几个名为 *X_train,X_test,y_train,*和 *y_test,*的变量来保存输入特征和输出特征的训练集和测试集的数组。请注意, train_test_split() 函数中的 **test_size=0.2、*参数会将 80%的数据作为训练集,另外 20%作为测试集。

6.培训模式

最后,我们准备好训练我们的第一个机器学习模型。让我们试一个简单的模型, 线性回归 模型。线性回归是一种建模方法,用于定义因变量和一个或多个自变量之间的线性关系。

我们可以使用 Scikit-Learn 的 LinearRegression 模块来创建一个线性回归模型,并用它来拟合我们的训练数据。

用于定型线性模型的代码片段

几秒钟后,一个训练好的线性模型就产生了,我们可以使用 predict() 方法用我们的测试集测试这个模型。

使用测试集测试已定型模型的代码片段

测试集的预测值如下:

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

单位面积预测房价

7.评估模型

现在,我们已经准备好了第一个模型,并用它来预测测试集的单位面积房价。然而,我们如何知道模型预测的准确性呢?线性模型对房价的预测有多好?

让我们来看一个分组条形图,它显示了真实值(y_test)和它们对应的预测值(y_pred)的比较。

绘制组条形图以比较真实 y 值和预测 y 值的代码片段

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

显示真实 Y 和预测 Y 的组合条形图(蓝色:真实 Y,橙色:预测 Y)

上面的分组条形图给了我们一个总的概念,一些预测值非常接近它们对应的真实值,但是一些预测值彼此相差很远。

现在,我们将通过成本函数使用定量方法来衡量线性模型的性能。成本函数是量化真实值( y_test )和预测值( y_pred )之间的差异的公式。

在预测房价这样的回归问题中,有两个常见的选项我们可以考虑:【RMSE】或者 平均绝对误差(MAE)

上面的两个成本函数计算真实值和预测值之间的差值的平均值。但是,RMSE 对数据集中可能存在的异常值非常敏感,会影响评估结果。因此,我们选择 MAE 作为我们的选择。

幸运的是,我们可以很容易地再次使用 Scikit-Learn 模块来调用 mean_absolute_error() 方法来评估模型。

使用 MAE 测量线性模型性能的代码片段

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

MAE(线性回归模型)的结果

所得到的 MAE 度量约为 6.344。这意味着每单位面积的预测房价与真实价格之间的平均绝对差异约为新台币 6.344 元(这可能表明我们可能会考虑尝试另一种模式以获得更好的结果)。

8。尝试新模式

在本节中,我们将训练和评估一个决策树模型。我们所需要的只是重复上面第 6 节& 7 中介绍的类似步骤。

我们可以使用 Scikit-Learn 中的 DecisionTreeRegressor 模块来创建决策树模型,并用它来拟合我们的训练数据。我们再次使用 MAE 成本函数来衡量模型的性能。

用于训练决策树和评估模型的代码片段

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

MAE(决策树模型)的结果

由此产生的 MAE 度量约为 4.84。这表明,与线性回归模型相比,决策树模型提供了更准确的房价预测。

如果我们仍然对当前模型的准确性不满意,我们可以考虑以下几种方法:

  1. 尝试另一种新的机器学习模型
  2. 获取更多数据集来为模型提供信息
  3. 尝试其他输入功能(例如 house_age )

结论

机器学习工作流本身就是一个决策过程,我们需要做出自己的判断来决定使用哪个模型来解决特定的问题。最耗时的部分不是训练模型,而是清理数据和选择适当的输入特征来训练模型的初步步骤。数据预处理步骤不仅仅是例行工作,因为它们都依赖于我们获得的数据的数量和质量以及我们要解决的问题的性质。

没有终极的工作流程可以适应所有类型的机器学习任务。

然而,我们仍然可以学习和遵循一些共同的原则来完成我们的机器学习项目。此外,我们还可以充分利用强大的 Python 或 R 包来启动我们的项目,而不需要任何额外的成本,因为它们是开源的。机器学习对我们来说是一种有益的体验,可以从原始数据中获得令人兴奋和有见地的输出。

源代码

为这个房价估值项目开发的 Jupyter 笔记本可以在 Github 找到。

参考

  1. https://www.bernardmarr.com/default.asp?contentID=1276
  2. https://www . kdnugges . com/2017/04/must-know-curse-dimensionality . html
  3. https://sci kit-learn . org/stable/auto _ examples/preprocessing/plot _ scaling _ importance . html
  4. http://sci kit-learn . org/stable/modules/generated/sk learn . preprocessing . standard scaler . html
  5. https://en.wikipedia.org/wiki/Linear_regression
  6. https://en.wikipedia.org/wiki/Root-mean-square_deviation
  7. https://en.wikipedia.org/wiki/Mean_absolute_error
  8. https://en.wikipedia.org/wiki/Decision_tree_learning

神经网络训练背后的数学

原文:https://towardsdatascience.com/adventure-of-the-neurons-theory-behind-the-neural-networks-5d19c594ca16?source=collection_archive---------11-----------------------

用一个例子清楚地解释神经网络和训练阶段背后的数学

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

罗马法师在 Unsplash 上拍摄的照片

神经网络广泛应用于人工智能领域。由于其可伸缩性和灵活性,它可以成为大多数预测问题的解决方案。可以解决回归、分类、预测、对象识别、语音识别、NLP 等复杂问题。那么,什么是神经网络,是什么使它们能够解决所有这些问题,以及它是如何学习进行预测的?为了理解这些,我们需要了解更多关于神经元及其背后的数学。在这篇文章中,我将解释神经元如何从给定的数据中学习并用于预测。我们将从头到尾考察神经网络和训练过程背后的理论。

  • 什么是神经元,它们的职责是什么?
  • 神经网络中的神经元是如何连接的?
  • 神经网络如何根据给定的数据进行预测?
  • 网络中的每次迭代会发生什么?
  • 每次迭代后会发生什么?
  • 一个神经网络在训练过程中会发生什么变化?
  • 培训过程应该在什么时候停止?

网络中的神经元

神经元是神经网络的重要组成部分。更准确地说,神经网络是通过将一个神经元连接到另一个神经元而形成的。与人类神经系统不同,神经网络中的神经元通过层相互连接。如果我们考虑到每个神经元都与其他神经元相连,那么处理时间将会非常长。为了减少处理时间和节省计算机的计算能力,在神经网络中使用了层。由于有了层,一层中的每个神经元都与下一层中的神经元相连。下图显示了具有三层的神经网络的基本结构。

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

作者图片

从上图可以看出,有 3 层作为输入、隐藏和输出。这三层是神经网络的主要层。输入层中的神经元代表数据集中的每个变量。输出层中的神经元表示输入值传入隐藏层中的每个神经元后的最终预测值。虽然只有一个输入和输出层,但隐藏层的数量可以增加。因此,神经网络的性能取决于层数和每层中神经元的数量。具有 3 个隐藏层且每层中有 3 个神经元的网络和具有一层一个神经元的网络之间的预测性能可能不同。那么,如果我们再增加一个 3 个神经元的隐藏层,网络会是什么样子呢?下图显示了一个有两个隐藏层的网络。

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

作者图片

我们可以在网络中增加更多的隐藏层和神经元。没有任何限制。但是,我们不应该忘记,增加更多的层和神经元并不意味着我们的网络会预测得更好。但是,当我们增加隐藏层和神经元的数量时,由于每个神经元中的计算,训练时间会增加。我们需要做的是为我们的网络找到最佳的网络结构。

喂养神经元

神经网络通过迭代工作,每次迭代训练模型以达到最佳预测。因此,喂养神经元是训练我们网络的主要运动。这种运动在神经网络中被称为“前馈”。它的意思是从先前连接的神经元获取数据,用这些数据进行计算,并将结果发送给下一个连接的神经元。当在输出神经元中完成最后的计算时,从数据集中获取另一个观察值,并再次进行馈送。这个过程一直持续下去,直到我们网络的预测真正接近已经预测的实际值。这里最重要的是在神经元中进行什么样的计算。我们基本上可以称这些计算为加权。我们不应该忘记,我们将利用这个网络进行预测。因此,我们需要对神经元进行加权,以做出最佳预测。

好了,让我们深入考察一下这个喂食过程。假设我们有一个神经网络,1 个输入层有 2 个输入神经元,1 个隐藏层有 2 个神经元,1 个输出层有 1 个神经元。所以,首先我们可以考察隐藏层中一个神经元的进食过程;

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

作者图片

在上图中,输入层有两个神经元。这意味着我们的数据集中有两个变量将用于训练。如你所见,输入神经元和隐层神经元之间的每个连接都有“W”值。这些“W”值代表单个神经元为每一个供给自身的神经元保存的值。在第一步,“W”和“b”值可以在 0 和 1 之间随机生成。在迭代(步骤)期间,这些值将被更新,以便达到最佳预测值。我们将在接下来的章节中看到这些迭代。

H1 神经元由 X1 和 X2 神经元馈给,因此它对于 X1 和 X2 具有 W1 和 W2 权重。如果你看到计算部分,来自输入层的每个神经元的值乘以它的权重,然后我们对所有的值求和。然而,还有一个表示为“b”的值。这个值是神经元的截距,我们将这个值与相乘的权重相加。也可以称之为“偏向”。在求和操作之后,结果从激活函数传递过来。激活函数进行一种变换操作。从激活函数获得的值将是该神经元在当前步骤的最终值。

激活功能

根据我们想要预测的值,我们可以选择不同的激活函数。让我们假设我们想要预测表示为 0 和 1 的两个类。所以,我们需要一个介于 0 和 1 之间的概率值来决定预测的类别。如果预测值小于 0.5(这意味着它接近 0 类),我们可以说是预测为 0。如果它大于 0.5,我们可以说它被预测为 1。但是,在没有激活函数的情况下,可以从 0 和 1 中获得预测值。为了理清这个问题,我们可以使用一个使神经元值保持在 0 和 1 之间的激活函数。这个激活函数被称为“Sigmoid”。其他常用的激活功能如下图所示。

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

作者图片

我已经解释过什么时候我们应该使用 sigmoid 函数。如果你看上面的图,还有其他的激活功能。比如双曲正切函数,当我们需要-1 到 1 之间的输出时就可以使用。如果输出不应小于 0,可以使用 ReLU 函数,identify 函数将输出原样返回。这意味着在神经元中计算的值将作为其本身。根据将要预测的变量,应该选择这些函数中的一个。

训练网络示例案例

好吧!我们可以用一个实例来设置整个网络。假设我们要训练一个网络,通过使用树的长度和宽度来预测树的年龄。这意味着我们将使用两个变量作为预测值,一个变量作为预测值。将用于培训的数据集如下所示。

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

作者图片

正如我们之前提到的,神经网络通过迭代得到训练。因此,在每次迭代(步骤)中,它从数据集中提取样本,并在神经元中进行计算。只能进行一次观察或小批量观察。在本例中,我们将对一个步骤取一个样本(观察值),这将是我们数据集的第一个观察值。

我们还应该决定在网络中使用哪个激活功能。如前所述,这取决于你使用这个网络想要预测什么。如果我们查找我们的数据集,年龄,这是一个因变量,包括数值。所以,我们不会预测树的类型,我们会预测它们的年龄。这一推论使我们得出输出将是线性的激活函数。第一个选项是 ReLU,第二个选项是 Identity。因为,这些函数不会将值转换为 0 到 1 之间的值。它们之间的区别当 Identity 函数按原样返回输入值时,ReLU 函数如果输入为负则返回值 0,如果输入不为负则按原样返回值。但是,年龄不能是负数,所以使用 ReLU 函数是有意义的。但是我想让这个教程尽可能的简单。这就是为什么我要用身份函数作为激活。这种格式更容易理解。这听起来很奇怪,但使用身份功能意味着你不会使用任何激活功能。因此,在下面的图中我没有添加任何激活函数过程(因为,它原样返回计算值)。

下图显示了第一次迭代的神经网络和计算。可以看到,输入层有两个神经元,分别是“宽度”和“长度”。因为是第一次迭代,所以“宽度”和“长度”的值来自第一次观察,为 5 和 7。隐藏层也有 2 个神经元,输出层有 1 个神经元。如果你仔细观察,神经元之间的每个连接都有“w”权重值。正如我们之前提到的,权重可以在 0 和 1 之间随机选择。它可以超出此范围,但最好在第一步设置在 0 和 1 之间。在接下来的迭代中,它们无论如何都会被改变。这些随机分配给连接的权重值也显示在神经元上方。我们可以用这样的说法——这些权重用于每一个连接——有时,但它们存储在神经元中。在实践中,我们不为连接分配权重。这意味着每个神经元为来自矩阵结构中前一层的每个连接存储“w”值。实际上,我们也可以使用 ReLU 激活功能。因为,我们要预测树的年龄,年龄不能是负数。但我只想让这个例子尽可能简单。因此,我决定使用身份激活功能,下图中没有任何激活功能流程。因为单位函数对于在神经元中计算的值没有任何变换。它让它们保持原样。

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

作者图片

在神经元中计算之后,发现 6.25 是第一次迭代的最终结果。从技术上来说,我们可以说这是根据给定的第一次观察的宽度和长度值的第一次预测的“年龄”值。下一步我们应该做的是将这个结果与实际年龄进行比较。第一次观察的树龄为 5 年。这意味着我们离实际值相差 1.5 岁,我们需要根据这个距离更新神经元的权重。这个过程被称为反向传播,我们将在下一节看到它。但在此之前,我想向你们展示一下,如果我们在这个人工神经网络中使用两个隐藏层,每个隐藏层中有两个神经元,会发生什么。因为你可能想知道在这种情况下我们如何计算。

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

作者图片

在上图中,你可以看到在之前的网络中又增加了一层。所以我们的预测值果然变了 5.68。这只是一个例子,我们将在下面的章节中使用以前的网络结构。

将神经元升级到更高级别

这一部分可能是本文最重要的部分。因为我会解释神经元的权重是如何改变的,以便做出好的预测。我将这一部分命名为“将神经元升级到更高水平”,因为在网络的每次迭代之后,我们都会改变神经元的权重值。因此,我们将它们升级到更高的水平,以做出更好的预测。

如前一节所述,在一次迭代完成后,需要通过考虑预测值和实际值之间的差异来更新神经元的权重和偏差(截距)。这个过程在人工神经网络中被称为反向传播,我们将使用的算法是随机梯度下降。在每次前馈(迭代)之后,反向传播也必须在训练期间完成。借助反向传播网络得到训练。下图显示了反向传播过程。

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

作者图片

为了更新权重和偏差,首先我们应该找出实际值和预测值之间的差异。有两个函数常用于计算实际值和预测值之间的差异。这些被称为均方误差和交叉熵。在某些情况下,也使用误差平方和。这些函数统称为损失函数成本函数。虽然对于回归问题可以优选均方误差,但是对于分类问题可以优选交叉熵。在这个例子中,我们试图估计树龄,而不是树的类型。这就是为什么我们可以用均方差。

下图显示了均方误差的函数;

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

作者图片

现在,我们可以通过使用 MSE 来计算实际值和前面示例中预测值之间的差异。第一次观察的预测年龄为 6.25 岁,实际年龄为 5 岁。因为我们在一次迭代中只取一个样本,所以“n”将等于 1。

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

作者图片

根据上述数学运算,MSE 为 1.5625。我们可以用术语损失来表示这个值。此外,如果我们在每次迭代中取 32 个观测值,我们将不得不从 32 个观测值的预测值和实际值中计算 MSE。

好了,我们有了失败的结果,下一步是什么?现在,我们必须通过考虑权重和偏差对损失的影响,来找出如何改变权重和偏差。所以,我们需要一个能做到的方法。这种方法在数学上叫做偏导数。带有权重和偏差的损失函数 L (MSE)的偏导数可以提供权重和偏差如何影响损失的信息。所以,这就是我们要找的。我们需要做以下偏导数运算;

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

上图显示了每个权重和偏差的偏导数。当我们有偏导数时,我们应该把它乘以学习率。在那之后,我们应该从它的重量中减去结果。这里的学习率表示权重将如何变化。高学习率下的体重变化将比低学习率下的体重变化大得多。因此,我们需要为我们的网络设置最佳的学习速率。

现在是时候学习如何求偏导数了。这在数学上有点深奥,如果你对偏导数没有任何概念,你可以看这个视频。我们将对 W1 (dL/dW1)进行导数运算。为了找到这个偏导数,我们可以做一个转换,如下式所示。代表 H1 神经元加权运算后的值,y 预测 代表 O1 神经元的结果,w1 为神经元中用于树宽的权值(输入层的第一个神经元)。**

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

为了解决上述均衡,我们需要继续使用y 预测H1L 损失的公式。然后我们可以得到所有的偏导数。如果我们看一下一阶偏导数 YPrediction 公式,我们可以看到它是 O1 神经元预测值的最终计算。

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

我们发现 H1 神经元的值的公式是:

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

我们需要的最后一个公式是损失函数 MSE (L)的公式。我们不应该忘记在每一步中我们只进行一次观察。所以,“n”的值将等于 1;

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

好吧!现在,我们可以走了。我们可以开始一个一个地求偏导数。我们可以从一阶偏导数“dL/dYPrediction”开始;

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

上图中已经进行了偏导数运算。这种操作背后的基本思想是发现损失如何受到预测的影响。如前所述,你可以观看这个视频来了解这些操作。下一个偏导数是“dYpred/dH1”。通常,H1 是一个返回激活函数的值的函数。在这种情况下,在取偏导数时,我们应该对 H1 求导。但是,在这种情况下,我们使用了恒等函数,恒等函数的导数 f(x) = x 等于 1。因此,我们可以假设 H1 只是 YPrediction 的一个参数值。如果我们使用 Sigmoid 函数,我们应该对它求导(这是另一种情况)。

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

最后一个导数是“dH1/dw1”;

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

现在,我们有了所有的均衡来寻找损失对“W1”重量的偏导数。我们需要做的就是把这些碎片拼在一起。

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

接下来我们应该做的是把 YTrue,YPrediction,w5 和 x1 的值放入上面的公式中;

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

随机梯度下降

耶!我们知道 w1 值如何影响损耗。接下来,我们要做的是决定如何改变“W1”值,以使损失最小化。因此,我们将使用称为随机梯度下降(SGD)的算法。实际上,偏导数运算是我们在上一节中做过的梯度下降的一部分。我们基本上可以说,我们正在通过使用反向传播作为随机梯度计算技术来训练我们的网络。在 SGD 中,我们从数据中提取单个样本,将它们传递到网络中,找出我们将如何改变权重和截距,以最小化损失。这个过程在每次迭代中进行,直到我们达到最小阈值。这意味着如果我们不能在一段时间后得到任何超过阈值的损失,我们可以停止训练。为了理解它,我们可以看到下图;

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

作者图片

在新币;在我们找到所有权重和截距的偏导数后,我们应该将它们乘以学习率,并从它们的旧权重和截距中减去。我们目前只找到了“w1”的偏导数。因此,我们可以进行以下操作,以找出新的更新“w1”值;

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

从上面的操作中可以看出,我们的新 W1 值为-0.1125。这意味着我们将用-0.1125 替换旧的“W1”值(位于 H1 神经元中),并且我们将在下一次迭代中使用该值。到目前为止,我们只找到了新的 W1 值。我们还必须找到其他 W 值和截距的新值。在上图中,还有 W 和截距值的其他偏导数;

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

现在,我们可以计算新的权重,以便完成第一个反向传播过程;

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

在第一次反向传播之后,我们有了所有新的“w”和“b”值。让我们看看我们的网络与新的价值观及其结果后,前馈步骤;

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

作者图片

从结果中可以看出,预测值为-3.33,为负值。我们需要担心吗?答案是 nop!我们刚刚用数据集的第一个样本完成了第一次迭代。我们的数据中有更多样本需要网络处理。此外,神经网络需要与其他样本进行更多的迭代才能得到训练。主要问题可能是:需要完成多少次迭代,或者我们的培训过程应该在什么时候停止?答案就藏在 SDG 的背后。

培训过程应该在什么时候停止?

迭代的目的是达到损失最小减少的阈值。我们应该在网络的训练阶段之前定义这个阈值。假设我们将阈值定义为 0.05,最大迭代次数定义为 10000。这意味着我们计划在最大 10000 次迭代中减少 0.05。在第一次迭代中,损耗的降低会更高。但是过了一段时间,减少将开始改变不太多,并且当网络达到最小阈值时,训练将停止。

比如在 8909。迭代我们取样本并传递到网络中,发现损失为 0.3559,在 8910。迭代我们再举一个例子,发现损失 0.3315,在 89111。迭代我们取了另一个样本,发现损失为 0.35080。损失的平均减少在 0.0244 和 0.0026 之间。这些值小于我们的阈值 0.05。所以,我们可以停止训练。然而,我们也可以定义一个最小误差来停止我们网络的训练。网络保持训练以达到给定的最小误差,即损失(当然我们也定义了最大迭代次数)。

还有一个我们需要担心的问题。这是一个过拟合问题。当我们的 ML 模型在训练集上表现完美,而在新数据(测试数据)上表现不佳时,就会出现这个问题。这意味着我们的网络可以在数千次迭代后达到最小损失,但它在测试集上表现不佳,为了评估性能,我们将测试集排除在训练集之外。在这种情况下,我们可以从我们的数据中定义一个验证部分,并控制该部分的损失量。如果验证集的损失不断增加,而训练集的损失不断减少,我们也可以停止训练。我们可以从下图了解一下;

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

作者图片

结论

在本文中,我们了解了神经网络模型的训练过程。当然,这只是一个具有基本网络结构的基本示例。本文的目的是学习神经网络背后的思想和数学。可以设置更复杂的网络结构。在编程语言的帮助下,数学运算可以在这些结构中轻松完成。但是它们也需要机器有更多的计算能力。如果你有编程语言的知识,你可以应用这些步骤,从头开始创建一个神经网络模型。

之后呢?在你完全理解了这篇文章中的操作之后,你可以更进一步。你可以检查其他反向传播和梯度下降方法,不同类型的神经网络,如 CNN,RNN,LSTM 等。为了解决不同的问题,已经开发了每一种其他的算法或方法。

我希望它是有帮助的,请不要犹豫问问题…

数据科学访谈中的冒险和不幸

原文:https://towardsdatascience.com/adventures-and-misadventures-in-data-science-interviews-1670881254df?source=collection_archive---------38-----------------------

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

https://unsplash.com/photos/bwki71ap-y8

数据科学求职的现实

我一直在等着发表这篇文章,但我想写一下我面试数据科学工作的经历。这是我的故事,我在博思艾伦工作了近 7 年,但我觉得是时候改变了。我非常喜欢博思艾伦公司,如果有人有兴趣在那里工作,请不要犹豫联系我。但是我觉得我已经准备好迎接不同的挑战,并开始在其他地方寻找工作。

既然我开始了一个新的职位,我想我应该分享一些我在许多公司面试时学到的观察。我没有跟踪我面试了多少家公司,但确实很多。我有丰富的政府工作经验,并从政府承包公司获得了许多工作机会。然而,我得出的结论是,就职业发展而言,加入另一家政府承包公司不是我想要的。

以下是我学到的…

我从求职中学到了什么

在你开始展示自己之前,真的花了很多心思在你想要的职位上。认真考虑所有因素,如公司文化、地点、职责、头衔等。很明显,没有一份工作是完美的,但是要将这份工作与你的需求清单进行比较,确保这个职位非常适合你。最重要的是,不要让招聘人员或其他人说服你去做不适合你的工作。如果你对一家公司感觉不好,跟着感觉走,然后离开。

网上申请是浪费时间

我发现申请数据科学的工作是浪费时间。我刚开始找工作的时候,一晚上申请了 10 到 15 份我认为自己有资格胜任的工作。我想到了我申请的 50 或 60 份工作,我可能得到了 3 或 4 次面试机会。我在 LinkedIn 上的人脉要好得多。老实说,这是我给所有求职者的最好建议,尤其是在科技行业。在 LinkedIn 和任何你知道的地方与人交流。你会比盲目应聘职位做得好很多。

不要在面试流程糟糕的公司浪费时间

面试过程是了解公司的一个窗口。如果一家公司永远不回复你,或者给你一个报价,或者其他什么,这就是你在那里工作时公司的运作方式。他们会行动迟缓,反应迟钝。我会说这是我在德意志银行正在做的事情。在写这篇文章的时候,我正打算雇佣几名 Splunk 工程师。我和我们的人力资源团队一起工作,我们在 2-3 天内就找到了候选人,进行了面试并给出了录用通知。这告诉候选人,我们真的需要他们,并表明我们可以把事情做好。与此形成鲜明对比的是,在一家公司向我发出邀请之前,我被这家公司骗了几个月,而在那之前,我已经接受了德意志银行的职位。

诚实和道德很重要

对我来说,我不想为从事不道德行为的公司工作,或者有不道德的经理等等。当我在德意志银行面试时,给我留下深刻印象的一件事是,人们对公司文化和他们所面临的挑战是多么坦率。没有人试图把一切都描绘成完美和令人惊奇的。(仅供参考,每家公司都有自己的 BS)众所周知,银行受到严格监管,国际银行必须应对极其复杂的监管制度。这是有充分理由的。当我在德意志银行面试时,给我留下深刻印象的是,每个面试者都与我讨论过在一家不能对数据为所欲为的银行工作是什么感觉。

我现在拒绝做编码考试

原则上,我确实喜欢把编码考试带回家的想法,然而作为一名考生,我发现它们相当令人沮丧,而且是一个主要的障碍。如果你试图评估候选人的编码能力,有许多方法可以做到这一点,我认为公司应该提供一个编码挑战,但我们中的许多人都有自己编写并公开提供的代码组合。现在无论何时有人问我,我只是让他们去我的 github 页面,或者提供我可以分享的项目样本代码。

我在一家公司面试,经过几轮电话面试后,招聘人员告诉我,在他们让我参加最后的面试之前,他们希望我参加两次编码考试,一次一小时的考试,然后是三小时的考试。这些考试是有时间限制的。我通过了这两个考试,但这是 12 月中旬,招聘人员告诉我,他不能安排面对面的面试,直到 1 月。我再也没有他或那家公司的消息。那时,我决定如果编码考试超过一个小时,我就不去做了。

我又为另一家公司做了一次编码考试。考试本身很简单,因为他们没有要求 NDA,所以问题大概是这样的。写一个函数把十进制转换成罗马数字
2。编写计算列表中项目出现次数的代码。
3。写一个函数来判断一个字符串是否是回文

我提交了使用 python 模块的代码和没有模块的代码。我写了大量的评论等等。代码符合规范,并且有很好的文档记录。我认为这证明了我既可以使用预先存在的模块,又可以从头开始编写功能代码。一周后,招聘人员告诉我,我没有通过编码考试。

从那以后,我决定不再在编码挑战上浪费时间。我采访的一家公司发给我一个编码挑战,他们说至少需要 8 个小时才能完成。对不起,伙计们…我为了生活而工作,有孩子,有更好的事情要做。

如果我正在招聘并决定使用编码考试,我会尝试首先为考试设定明确的目标,然后让候选人知道这些目标。你只是在寻找有用的代码吗?或者您想要文档精美并且使用正确设计模式的代码吗?

在我看来,编码考试应该设计为不超过一个小时。候选人不为你工作,让他们做冗长的编码考试只会让那些忙碌又受追捧的候选人望而却步。基本上,我会问一两个问题,只是为了确定候选人可以编码,可以写相当好的代码质量。

哦…让我们来谈谈 HackerRank。这个网站很烂。**烂透了!!!**没有别的说法了。T4 简直糟透了。没试过就不要!HackerRank 向您展示了一个编码挑战。你可以在他们的环境中,用许多预先选择的语言中的任何一种来编写代码,然后你的代码将会在你看不到的用例中被测试。为什么这很糟糕?仅仅是因为你没有办法调试你的代码。我为两个潜在雇主这样做了,虽然我通过了这些测试,但我发现它们真的很烦人,而且不必要的耗费时间。我花了大概 30 分钟调试一些代码,如果我能看到测试用例和输出,这可能需要 30 秒。我对 HackerRank 的另一个问题是人工环境。我现在做的大部分工作,都是用 Python 3 做的。我使用了很多标准的模块,比如 Pandas、Seaborn、Scikit-learn 等。当您进行 HackerRank 挑战时,您可能会被迫使用不熟悉的 Python 版本,而不使用您的标准模块。虽然我可以用 Python 2.7 编码,但是我没有用 Py 3 那么快,同样我也完全可以不用标准模块来编码,但是这需要更多的时间。底线是,如果你正在招聘,请不要使用 HackerRank。

虽然我们的主题是编码挑战,但我并不喜欢 BS 挑战。不要让我写一个非递归的二叉树遍历,因为我可以谷歌一下,你对我的编码能力一无所知。依我看,在现场采访中对某人这样做也是一件很不理智的事情。因此,如果我正在采访你,我要求你写代码,实现立方根函数,你知道你在烦我。

最后,如果你打算让某人为数据科学职位编码,你应该记住编码挑战不是戏弄。它们是评估候选人编码能力的一种手段。因此,编码挑战应该反映您实际上希望他们做的事情。如果我要为 DB-CSO 的数据科学家实现一个编码挑战,我会给他们一些样本安全数据,让他们使用他们喜欢的任何工具进行一些 ETL 和探索性数据分析。根据时间的长短,我可能会要求他们构建一个模型并评估其性能,同样,使用他们喜欢的任何工具。

另一种方法是简单地给候选人一些相对简单的挑战,只是为了验证他们可以编码,我认为这也是一个完全可以接受的方法。

实际采访:

让我说,在你职业生涯的某个时刻,我强烈建议你花时间做采访,就像为你的公司做采访一样。我认为这真的有助于你为面试做好准备,因为你对面试官想要什么有一个明确的想法。

如果你不幸被我面试,我现在就告诉你,我寻找的人是:聪明,知道如何把事情做好,并且对他们的工作充满热情。再多的准备也不会让你为此做好准备。当我面试候选人时,我会努力挖掘候选人的长处。如果这些优势与我们当时寻求的一致,那么恭喜你!通常我不会带人来面试,除非我确信我会雇用那个人,所以如果你得到了我的面试机会,这是一个好的迹象。我喜欢开放式问题,让候选人展示他们的思维过程。以下是我常问的一些问题:

  • 如果你是一名恐怖分子或罪犯,你会使用什么技术来混淆你与监控机构的通信?(完全开放式,让候选人展示他们对网络和电信技术的理解)(这是针对网络分析师职位的)
  • 我会请候选人向我介绍设计一个系统来检测欺诈性信用卡交易的过程。视时间而定,我将深入讨论这个问题,询问设计约束等。
  • 向高级经理解释您将如何评估数据科学项目 X 的价值。我真的很喜欢这个问题,因为它迫使候选人从战略角度思考特定项目的影响。

最佳面试: CapitalOne,Orbital Insight,Kensha。在这些公司中,我实际上只收到了其中一家公司的邀请,但我真的对公司的流程和公司印象深刻。

**最差面试:**我被要求使用 Map-Reduce 实现 K 均值聚类。这次面试让我很恼火,因为我对自己知道什么和不知道什么非常坦率,而这位面试官就是个混蛋。我不会在我的简历中声称有 MapReduce 的开发经验。 Pro **提示:**如果候选人说他们不知道 X,不要问他们一百万个关于 X 的问题,那只是做个混蛋。相反,找到候选人擅长什么,看看这些优势是否符合你的要求。

**最尴尬的时刻:**在一次疲劳的时刻,一家公司的人事经理问我想找什么样的工作,我告诉她“我不会无聊到发疯。”我得到了这家公司的一份工作,但是我很不好意思那样做。**专业提示:**避免在面试中扔 f 弹。

**最发人深省的问题:**告诉我你会如何设计一辆无人驾驶汽车

**最奇怪的面试:**任何一个想要在酒店大厅见我的小型政府承包商。

最大的失望:我参加了一家大型金融公司的面试,这家公司有一间漂亮的办公室,离我家大约 10 分钟路程,是一个非常棒的职位。我面试了潜在的同事和两位董事总经理。在我走向电梯的时候,总经理告诉我,他认为我会成为团队的一员,并期待着与我合作。我完全认为我已经稳操胜券了,但是在欺骗了我几个星期之后,我没有得到任何机会。**专家提示:**包里从来没有东西。我参加过一些面试,我以为自己搞定了,却没有得到工作机会;还有一些面试,我以为自己搞砸了,却得到了工作机会。世事难料。

**最大的挫折:**我最大的挫折是公司和我之间缺乏沟通。我总是担心坚持会被理解为绝望或讨厌。在这个过程中,有两家公司拖了我好几个月。如果你已经面试了一位候选人,你应该给他们一个回应……任何回应。

我遇到的另一个大挫折是公司通常不尊重我的时间。我住在东海岸——DC 地区。有几家公司想让我飞到旧金山或硅谷,为 DC 的一个职位与“家乡团队”进行面试。我认为这是一个好主意,但要认识到从东海岸出去一天实际上是两三天的旅行,除非你做红眼航班或其他疯狂的安排。所以,公司们,如果你想雇佣一个东海岸的候选人,让他们飞去参加面试,请尊重候选人的时间表…不要让他们支付机票费用。你可以将这样的面试安排在周一或周五,这样候选人可以尽量减少下班时间。

最后

总之,我想说的是,在寻找数据科学家的工作时,确保你(候选人)知道你在寻找什么,不要偏离太远。对公司:知道你在寻找什么,尊重候选人。如果你雇佣了一个人,却不知道自己到底想要什么,这对你自己和候选人都是极大的伤害。我在这个过程中意识到,在招聘时,许多人都在寻找一个理想化的自我认知。这意味着如果面试官认为自己是一个努力工作的人,他们会在应聘者身上寻找这种品质。如果面试官认为自己是主题 X 的专家,他们会问很多关于主题 X 的问题。祝你面试好运,如果你想和我进行模拟数据科学面试,请不要犹豫联系我

基于 PyTorch、Captum 和 ONNX 深度学习的鸟类图像分类

原文:https://towardsdatascience.com/adventures-in-pytorch-image-classification-with-caltech-birds-200-part-1-the-dataset-6e5433e9897c?source=collection_archive---------18-----------------------

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

(图片由作者提供)

PyTorch 历险记

第 0 部分:介绍图像分类、深度学习和加州理工学院鸟类 200 数据集

本系列将探索脸书人工智能研究所(FAIR)强大的神经网络和机器学习架构 PyTorch 的强大功能。在这一系列文章中,我们将探索 PyTorch 在图像分类问题中的应用能力,通过使用各种 CNN 架构,包括 GoogLeNet、ResNet152 和 ResNeXt101 等,使用 CalTech 200 birds 数据集识别 200 种北美鸟类。

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

加州理工学院加州大学圣迭戈分校鸟类 200 数据集()韦林德 p、布兰森 s、塔米 t、华 c、施罗夫 f、贝隆吉 s、佩罗娜 p .“加州理工学院-加州大学圣迭戈分校鸟类 200”。加州理工学院。CNS-TR-2010–001。2010 年

介绍

在这组文章中,我将探讨我们如何使用脸书人工智能研究所的神经网络库 PyTorch 来解决一个多类的图像分类问题。这个广泛的库,带有一系列与发行版打包在一起的现有工具,从使用 torch.nn 模块(相当于 Keras 的 PyTorch)的高级抽象,到低级自动签名函数和基于 GPU 的高效操作,允许设计和快速实现最先进的机器学习架构。在最基本的层面上,PyTorch 可以被认为是众所周知的 python 数组包 Numpy 的一个高度优化的多维版本。

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

图 1:加州理工学院鸟类分类研讨会工作流程。本系列的每一篇文章都将关注这个工作流的一个单独的阶段。用于生成这些文章的笔记本,以及经过训练的模型可以在 this Github repository 中找到。(图片由作者提供)

将要进行的工作流程如图 1 所示,每篇文章都将关注该工作流程的一个特定方面,包括:

  1. 数据探索和分类问题介绍。
  2. 准备图像分类卷积神经网络(CNN)并在以下架构上训练:
    A) Torchvision 预训练网络。
    B)第三方预培训网络。
  3. 使用传统方法(分类报告、度量、混淆矩阵、精确召回曲线等)评估分类模型性能。
  4. 使用神经网络激活图的域缩减和流形技术(例如 t -SNEUMAP )评估网络分类性能。
  5. 迁移学习,使用经过训练的神经网络作为特征提取器,作为其他分类算法(XGBoost,内核 SVM)的输入。
  6. 神经网络卷积滤波器的特性可视化(神经元、空间和层激活),使用 Lucent python 包 ( Lucid for PyTorch)。
  7. 通过将 PyTorch 模型对象转换为 ONNX(开放式神经网络交换)格式来部署训练模型,并使用 ONNX 运行时环境演示推理。

在这个系列的介绍中,我们将从机器学习的角度来回顾什么是分类,我们所说的图像分类是什么,特别是什么是使用深度学习技术的图像分类。接下来,我们将介绍鸟类分类的细粒度图像分类问题,并回顾我们稍后将用来演示这些技术的所选数据集。最后,我们将对过去几年中开发的最先进的卷积神经网络所获得的结果进行总结,在接下来的系列文章中,我们将揭示如何实现这些结果。

什么是预测模型,什么是分类?

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

图 2:机器学习算法适合两个一般领域,分类和回归。(图片由作者提供)

预测建模是利用历史数据开发一个模型,在我们没有答案的情况下对新数据进行预测的问题。预测建模可以被描述为从输入变量(X)到输出变量(y)逼近映射函数(f)的数学问题。这就是所谓的函数逼近问题。

建模算法的工作是在给定时间和可用资源的情况下找到最佳映射函数。

从根本上说,分类和回归的区别在于,一个旨在预测一个标签或类别,而另一个旨在预测一个数量。

图 2 清楚地说明了这两种方法之间的差异,其中分类模型根据给定数据点相对于类边界的位置来预测其类值,例如支持向量机(SVM)分类器。然而,回归模型被设计成在给定一组预测因子(数据列)的情况下预测某事物的实际数量。

分类预测建模是从输入变量(X)到离散输出变量(y)近似映射函数(f)的任务。输出变量通常被称为标签或类别。映射函数预测给定观察值的类别或种类。例如,文本电子邮件可以被分类为属于两类之一:“垃圾邮件*”*和“非垃圾邮件”。

  • 分类问题要求将示例分为两类或更多类中的一类。
  • 分类可以有实值或离散输入变量。
  • 有两类的问题通常被称为两类或二元分类问题。
  • 具有两个以上类别的问题通常被称为多类别分类问题。
  • 一个例子被分配多个类别的问题称为多标签分类问题。

分类模型通常将连续值预测为给定示例属于每个输出类的概率。概率可以解释为属于每个类别的给定示例的可能性或置信度。通过选择具有最高概率的类标签,可以将预测概率转换为类值。

在这些文章中,我们要关注的是分类,以及一个叫做图像分类的问题的特殊子集,我们将在下一节更详细地讨论这个问题。

什么是图像分类?

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

图 3:对象的图像分类,其中根据图像的内容对图像进行分类。(图片由作者提供)

图像分类是一般分类问题的一个子域。为图像分类设计的算法接受图像作为其输入,并产生图像类别的预测作为输出。输出可以采取标签或类别的形式,或者表示属于图像的每个潜在类别的可能性的一组实值概率的形式。图 3 中的漫画显示了一种算法,该算法设计用于识别食物图像是冰淇淋、冰棍还是蛋糕,将食物图像作为输入,并提供一个类别标签作为预测。

为了成功地对图像进行分类,一种算法需要从输入图像中提取代表性的“特征”,并学习相应的模式,以允许它根据图像的内容区分类别(图 4A)。这些“特征”可以通过迭代和交互的设计过程手动创建,目的是产生最好的分类特征。然而,这种手动方法有以下潜在的缺点:

  1. 人力密集。
  2. 容易出错。
  3. 穷尽过程。
  4. 无法保证能够最佳区分不同类别的独特特征。

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

图 4A:使用(上)具有手工制作特征的机器学习和(下)使用 CNN 在一个过程中自动导出理想化特征和分类器的深度学习的不同图像分类方法。(图片由作者提供)

另一种在过去 10 年中广泛发展并在图像分类性能方面取得显著进步的方法是深度学习的使用,特别是卷积神经网络(CNN)。这些类型的方法试图同时解决优化设计的特征提取和预测对象类别的分类器的问题。在其最简单的形式中,CNN 可以被认为是一个巨大的,自动导出(或学习)的特征提取系统,末端有一个分类器。

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

图 4B:从头开始培训的概念(上图)与迁移学习的概念(下图)。在迁移学习中,通过移除最终层分类器并将提取的特征输出用作新分类器的输入,预训练的网络被用作特征提取网络(新分类器不必基于神经网络)。(图片由作者提供)

事实上,正是这种结构允许采用所谓的“迁移学习”方法(图 4B)。这是移除网络基础上的分类层,并将网络用作特征提取器的过程。然后,该特征提取网络的输出可以被馈送到另一个分类器中,该分类器的选择可以是任何机器学习分类器(例如,SVM、核 SVM、基于决策树的集成,如 XGBoost),以执行分类预测。在这种情况下,分类器的输入不是图像,而是从图像中提取的特征(有时称为激活)的集合,分类器通过这些特征学习识别和预测图像类别。

正是这些方法,我们将在下面的系列文章中展示如何使用 PyTorch 构建一个最先进的图像分类器。

数据集—加州理工学院 UCSD 200 鸟类数据库(CUB-200–2011)

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

图 5:来自 CUB-200–2011 的相似物种(莺)的例子,显示了鸟类物种识别的复杂性和困难性。即使有了图 6 所示的物种图,人类也很难预测具体的鸟类物种。

CUB-200–2011 数据集包含来自 200 个不同物种的北美鸟类图像。这是一个具有挑战性的问题,因为许多鸟类都有一定程度的视觉相似性。鸟类物种识别对人类来说是具有挑战性的,更不用说计算机视觉算法了,因此这种类型的问题通常被称为大规模细粒度的。例如,用图 6 中的物种图来识别图 5 中两种鸟的正确林莺物种,对人类来说仍然是一个非常困难和复杂的问题。

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

图 6:北美林莺物种示例图( 凯特·多拉莫尔艺术 ) )。

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

图 7:CUB-200–2011 数据集属性(在 之后的)计算&神经系统技术报告,CNS-TR-2011–001**)。

该数据集最初产生于 2010 年( CUB-200 ),包含 200 类鸟类的约 6000 张图像。伴随它的是附加标签数据,包括边界框、粗略分割和附加属性。这在 2011 年进行了更新(CUB-200–2011),增加了额外的图像,使数据集中的图像总数达到近 12,000 张。可用的属性也被更新为包括 15 个零件位置、312 个二进制属性和每个图像的边界框(图 7)。在本系列的大部分时间里,我们将简单地使用图像和类别标签来开发和训练预测鸟类类别的网络。

关于 CUB-200–2011 的部分已发布结果

W ah 等人(2010) 报道了使用 RGB 颜色直方图和向量量化 SIFT 描述符的直方图与线性 SVM,他们获得了 17.3%的分类精度。这是作为与更高级的技术(包括深度学习方法)进行比较的基础而产生的,并且是使用手工制作的特征和机器学习来解决图像分类问题的方法的示例(如图 4 的上图所示)。

使用完整的未裁剪图像,他们实现了 10.3%的总体平均分类精度。在 2014 年, Goring 等人 提出了一种基于非参数标签转移技术的细粒度识别方法,该方法从具有相似全局形状的对象中转移部分星座,实现了 57.8%的平均分类准确率。

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

图 8:CUB-200–2011 数据集上表现最好的模型,来自paperswithcode.com

最近对细粒度图像分类的研究主要基于卷积神经网络方法。这些方法取得了相当好的精度,平均分类精度接近 90%(图 8;来自 paperswithcode.com 的关于 CUB-200–2011 的最佳性能算法的图表。例如,崔等(2017)演示了使用现代神经网络架构,获得明显更准确的预测。他们方法成功的关键部分是深度学习网络的使用,结合高分辨率图像训练和处理细粒度问题的长尾分布方面。它们还决定性地显示了使用领域特定的预训练数据集来提高较小的细粒度分类问题(如鸟类物种识别)的准确性的优势。

现代工具有什么可能?

用最少的努力,我听到你说什么是真正可能的?
在这组文章中,我们的目标是展示如何相对简单地访问最先进的图像分类模型,并获得接近当前领先网络的性能。正如本讨论所示,这种在细粒度图像分类问题上的性能在过去几年才成为可能。

在深入研究如何设置、训练和部署 PyTorch CNN 进行图像分类的细节之前,让我们先来看看使用一种相对简单的方法可以获得的结果。在接下来的文章中,我将与您分享为训练这些模型而开发的底层 python 代码的更多细节,但在这里,我想分享我在数据集上训练的所有不同网络架构的最终结果。

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

图 9: PyTorch CNN 图像分类架构使用类宏平均度量的性能比较。在 ImageNet 上进行预训练,并使用 CUB-200–2011 进行进一步训练后,在 CUB-200–2011 数据集的测试集上进行评估。(图片由作者提供)

图 9 显示了许多不同模型架构的性能,所有卷积神经网络(CNN)用于图像分类,在 CUB-200–2011 上训练。这些模型包括最早成功开发更深层次网络的模型架构之一, GoogLeNet ,由 Szegedy 等人(2014)在论文“用卷积深化”中提出,以及最近的网络架构,包括 ResNeXt (谢等人 2017 之后的)和 PNAS 网(刘等人 2018之后的)

这个例子表明,即使在 3 到 4 年的发展空间内,这些网络的性能改进也是相当可观的。这里值得明确指出的是,这些模型之间的唯一区别是网络架构本身。训练和测试图像的选择以及图像增强过程和模型性能的评估对于所有相关的模型都是相同的。正是不同的网络架构使得最新的网络在分类性能方面取得了显著的进步。

请加入我即将发表的一系列文章,在这些文章中,我们将发现如何使用 python 和 PyTorch 来构建一个最先进的鸟类分类器,以产生如上所示的结果,以及了解它如何执行以及它如何做出决策的方法。

用来制作这组文章的代码和笔记本已经发布在 Github 上,也可以在这里 找到。这些数据可以通过 Github 页面上的链接获得。

参考资料:

  1. 塞格迪,C. 用回旋更深入。arXiv:1409.4842【cs】(2014)。
  2. 谢,s .,Girshick,r .,Dollár,p .,Tu,Z. &何,k .深度神经网络的聚合残差变换。arXiv:1611.05431【cs】(2017)。
  3. 刘,s,齐,l,秦,h,石,J. &贾,j .路径聚合网络实例分割。arXiv:1803.01534【cs】(2018)。
  4. Goering,c .、Rodner,e .、Freytag,A. & Denzler,j .用于细粒度识别的非参数零件转移。在 2014 年 IEEE 计算机视觉和模式识别会议2489–2496(IEEE,2014)。doi:10.1109/cvpr . 2014.319

背景阅读:

关于神经网络的背景参考材料,包括理论和实践,感兴趣的读者可以参考以下优秀资源。

深度学习和神经网络实用指南:

  1. Rosebrock,A. 用 Python 进行计算机视觉的深度学习。第 1–3 卷(2017 年)。
  2. Chollet,F. 用 Python 进行深度学习。(曼宁出版公司,2018 年)。

神经网络和深度学习的背景理论:

  1. 神经网络和深度学习:一本教科书。(施普林格,2018)。
  2. 模式识别和机器学习。(斯普林格,2006 年)。
  3. 古德费勒,我,本吉奥,y 和库维尔,A. 深度学习。(麻省理工学院出版社,2016)。
  4. 哈根,M. T .,德穆特,H. B .,比厄,M. H. & De Jesus,O. 神经网络设计(第二版)。(自我出版,2014)。

通用机器学习背景理论与实践:

  1. 数据分类:算法和应用。(查普曼&霍尔/CRC,2015)。
  2. 统计学习的要素。(施普林格,2017)。
  3. Kuhn,m .和 Johnson,K. 应用预测建模。(纽约施普林格出版社,2013 年)。doi:10.1007/978–1–4614–6849–3
  4. 计算机时代的统计推断:算法、证据和数据科学。(剑桥大学出版社,2017)。
  5. 统计学习导论:在 R 中的应用。(施普林格,2013 年)。

PyTorch 中神经网络的对抗性攻击与防御

原文:https://towardsdatascience.com/adversarial-attack-and-defense-on-neural-networks-in-pytorch-82b5bcd9171?source=collection_archive---------8-----------------------

神经网络真的能学习一切吗?

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

图片来源这里这里

深度学习和神经网络的兴起给现代社会带来了各种机会和应用,如对象检测和文本到语音转换。然而,尽管看起来准确度很高,但神经网络(以及几乎所有的机器学习模型)实际上可能会受到数据的影响,即敌对的例子,这些例子是从原始训练样本中非常轻微地操纵的。事实上,过去的研究表明,只要您知道更改数据的“正确”方法,您就可以迫使您的网络在数据上表现不佳,这些数据在人眼看来似乎没有什么不同!这些故意操纵数据以降低模型精度的行为被称为对抗性攻击,攻击和防御之战是机器学习领域正在进行的热门研究课题。

本文将概述一种最简单而有效的攻击——快速梯度签名方法攻击——及其在 PyTorch 中的实现和通过对抗训练进行防御。

边注:本文假设了在 PyTorch 中构建简单神经网络和训练它们的先验知识。如果你不熟悉它们,建议先在 PyTorch 上查看教程。

对抗性例子和攻击的历史

对立的例子可以被定义为为了欺骗机器学习网络而被扰乱的输入或数据。伊恩等人在 ICLR 2015 会议的论文“解释和利用对立的例子”中阐述了这一观点。虽然本文之前的出版物声称这些对立的例子是由机器模型的非线性和过拟合引起的,但 Ian 等人认为,由于架构的高度线性,神经网络实际上容易受到这些例子的影响。LSTMs 之类的模型和 ReLU 之类的激活函数仍然经常以非常线性的方式运行,因此这些模型很容易被线性扰动所欺骗。然后,他接着提供了一个简单快速的一步生成对立例子的方法:快速梯度符号法。

快速梯度符号法

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

图一。FGSM 对熊猫图像的影响。在他们的 2015 年 ICLR 论文

快速梯度符号方法(FGSM)是一种白盒攻击,这意味着攻击是基于给定的网络架构产生的。FGSM 基于这样的想法,即正常网络遵循梯度下降来寻找损耗的最低点,因此,如果我们遵循梯度的符号(沿着与梯度下降相反的方向),我们可以通过添加少量扰动来最大化损耗。

因此,FGSM 可以描述为以下数学表达式:

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

其中 x’是通过添加小常数ε产生的扰动 x,其符号等于损耗 J 相对于 x 的梯度方向。图 1 是计算机视觉领域中 FGSM 攻击的经典图示。由于图像中不到 1%的变化是我们无法视觉识别的,图像从置信度一般的正确分类变成了置信度很高的错误分类。

这些简单的方法实际上可以欺骗深度神经网络的事实进一步证明了由于神经网络的线性而存在对立的例子。

PyTorch 的 FGSM

要在 PyTorch 中构建 FGSM 攻击,我们可以使用由 Ian Goodfellow 和 Nicolas Papernot 提供并精心维护的 CleverHans 库。该库提供了多种攻击和防御,目前广泛用于基准测试。尽管大多数攻击是在 Tensorflow 中实现的,但他们最近也在 PyTorch 中发布了 FGSM 的代码。

可以使用以下命令下载并安装该库:

pip install git+https://github.com/tensorflow/cleverhans.git#egg=cleverhans

我们将使用简单的 MNIST 数据集来演示如何构建攻击。

创建模型和数据加载器

首先,我们必须为 MNIST 数据集创建一个普通的 PyTorch 模型和数据加载器。

为了进行演示,我们将构建一个简单的卷积网络,如下所示:

和数据加载器,如下所示:

之后,我们实现了一种正常的转发方法来根据正常数据训练网络:

通过将批量大小设置为 128,时期数设置为 4,学习率设置为 0.001,网络在训练后成功地在 MNIST 数据集上实现了大约 98%的准确率。

施加攻击

在训练网络之后,我们可以在给定网络架构的情况下应用 FGSM 攻击。

为此,我们必须首先从 CleverHans 导入所需的函数:

from cleverhans.future.torch.attacks.fast_gradient_method import fast_gradient_method

这就允许我们调用 fast_gradient_method()函数,这个函数简单明了:给定模型、一个输入 x、一个ε和一个范数(norm=np.inf,1 或 2),这个函数输出一个扰动的 x。

然后,我们可以通过输入扰动的 x 而不是原始的 x 来稍微改变原始的正向函数,以测量如下结果:

经过测试,上述攻击实际上可以迫使准确率从 98%急剧下降到 4%左右,这证明如果方向正确,小扰动实际上会导致网络性能非常差。

PyTorch 的对抗训练

在 Ian 等人的同一篇论文中,他们提出了对抗训练方法来对抗这些样本。简而言之,从训练集中生成的敌对样本也包括在训练中。

通过将原始的和扰动的训练集同时输入到架构中,这个概念可以很容易地实现到代码中。请注意,这两种类型的数据都应该用于对抗性训练,以防止原始数据集的准确性损失。下面的代码是我对对抗性训练的实现:

请注意,网络从检查点开始,在那里它已经接受了干净数据的训练。在对抗训练期间,干净样本和对抗样本都被输入到网络中,以防止在进一步训练期间干净数据的准确度下降。

使用相同的批量大小、时期和学习率设置,我们实际上可以将对立示例的准确度提高到大约 90%,同时保持干净数据的准确度。

对抗性训练的问题

虽然上述示例说明了如何采用对抗性训练来概括模型架构,但一个主要问题是,它们仅在模型被训练的特定类型的攻击上有效。不同的攻击产生不同的对抗范例,对抗训练方法需要进一步研究和评估,以更好地进行对抗防御。

结论

FGSM 和对抗性训练是最早的攻击和防御之一。最近的攻击(如 C&W 攻击和 DeepFool)以及防御(如蒸馏)为未来的研究和调查提供了新的机会。这篇文章是对对抗性攻击领域的一个介绍,希望能激发您深入研究这个领域的兴趣!要了解更多,这里有另一篇文章,我认为这是一篇很好的短文,可以更好地理解快速梯度符号法。

我的实现的完整代码也发布在我的 Github 中:

[## ttchengab/FGSMAttack

在 GitHub 上创建一个帐户,为 ttchengab/FGSMAttack 开发做贡献。

github.com](https://github.com/ttchengab/FGSMAttack) 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

谢谢你能走到这一步🙏!我将在计算机视觉/深度学习的不同领域发表更多文章,请务必查看我的其他文章和 川林恩 的文章!

对垃圾短信检测器的对抗性攻击

原文:https://towardsdatascience.com/adversarial-attacks-on-sms-spam-detectors-12b16f1e748e?source=collection_archive---------39-----------------------

使用基于雅可比的显著图攻击,探索如何使用对抗性学习来定位垃圾短信检测器

注: 本文讨论的方法背后的方法论源于我和Irene Anthi之间的一个 合作出版物

介绍

垃圾短信经常出现在我们的手机屏幕上。这已经够烦人的了,但情况会变得更糟。给你发垃圾短信的人通常是想诈骗你。大多数垃圾短信不是来自另一部手机。它们通常来自计算机,并通过电子邮件地址或即时消息帐户发送到您的手机。

存在几种自动检测电子邮件或 sms 消息是否是垃圾邮件的安全机制。这些方法通常依赖于机器学习。然而,这种系统的引入也可能受到攻击。

向基于机器学习的系统部署攻击的行为被称为对抗性机器学习(AML)。其目的是利用预训练模型的弱点,该模型在训练期间看到的数据点之间可能有“盲点”。更具体地说,通过自动地将轻微的扰动引入到看不见的数据点,模型可以越过决策边界并将数据分类为不同的类别。因此,模型的有效性会大大降低。

在垃圾短信检测中,AML 可用于操纵文本数据,包括干扰,使垃圾数据被归类为非垃圾数据,从而绕过检测器。

数据集和数据预处理

垃圾短信收集是为垃圾短信研究收集的一组带短信标签的消息。它包含一组 5,574 条英语 SMS 文本消息,根据它们是垃圾邮件(425 条消息)还是非垃圾邮件(3,375 条消息)进行标记。

在我们深入应用任何类型的机器学习技术之前,让我们首先讨论一下我们需要考虑的预处理技术。我们将执行大多数自然语言处理(NLP)问题的标准预处理技术。其中包括:

  • 将文本转换成小写。
  • 去掉标点符号。
  • 删除额外的空白。
  • 删除数字。
  • 删除“the”、“a”、“an”、“in”等停用词。
  • 引理满足。
  • 象征化。

Python 的自然语言工具包(NLTK) 可以处理这些预处理需求。现在,输出应该如下所示:

单词嵌入

单词嵌入是最流行的文本词汇表示方法之一。它能够捕捉文档中某个单词的上下文、其与周围单词的语义和句法相似性以及其与其他单词的关系。

但是如何在上下文中捕捉单词嵌入呢?Word2Vec 是使用两层神经网络学习单词嵌入的最流行的技术之一。神经网络接收文本集,对其进行分析,并为词汇表中的每个单词生成一个数字向量,这些数字向量编码了与单词出现的上下文相关的单词含义的重要信息。

主要有两种模式:连续词袋模式和跳格模式。Word2Vec Skip-gram 模型是一个具有单个隐藏层的浅层神经网络,它接受一个单词作为输入,并试图预测该单词周围单词的上下文作为输出。

在这种情况下,我们将使用 Gensim 的 Word2Vec 来创建模型。一些重要的参数如下:

  • size:嵌入的维数。默认值为 100。
  • 窗口:目标单词与周围单词之间的最大距离。默认窗口是 5。
  • min_count:训练模型时要考虑的最小字数。出现次数少于此计数的单词将被忽略。默认的最小计数是 5。
  • 工人:培训时分区数量。默认工人是 3。
  • sg:训练算法,连续词包(0)或跳格(1)。默认的训练算法是连续单词包。

接下来,我们将看到如何使用 Word2Vec 模型为数据集中的文档生成向量。通过遍历数据集,为训练数据中的每个 SMS 消息生成 Word2Vec 向量。通过简单地对文本消息的每个单词使用该模型,我们检索这些单词的单词嵌入向量。然后,我们通过计算文本中所有单词向量的平均值来表示数据集中的消息。

模型训练和分类

让我们首先对目标标签 spam 和 *not_spam 进行编码。*这包括将分类值转换成数值。然后,我们将把特征分配给变量X,把目标标签分配给变量y。最后,我们将把预处理后的数据分成两个数据集。

  • 训练数据集:用于训练短信文本分类模型。
  • 测试数据集:用于验证模型的性能。

为了将数据分割成两个这样的数据集,我们将从模型选择功能中使用 Scikit-learn 的训练测试分割方法。在这种情况下,我们将数据分为 70%的培训和 30%的测试。

为了这篇文章,我们将使用一个Decision Tree分类器。实际上,您可能希望使用交叉验证来评估各种分类器,以确定哪一个性能最好。“没有免费的午餐”定理表明,不存在普遍最佳的学习算法。换句话说,选择一个合适的算法应该基于它对于特定问题的性能和表征该问题的数据的属性。

一旦模型被训练,当它试图预测测试集的目标标签时,我们可以评估它的性能。分类报告显示,该模型可以预测具有 0.94 的高加权平均 F1 得分的测试样本。

生成对立样本

AML 的一个众所周知的使用案例是在图像分类中。这包括添加人眼可能察觉不到的噪声,这也欺骗了分类器。

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

图像分类中的对抗性机器学习

有各种方法可以产生对立的样本。这些方法在复杂性、生成速度和性能方面各不相同。制作这种样本的简单方法是手动扰动输入数据点。然而,与自动方法相比,人工扰动的产生和评估较慢。

自动生成扰动样本的最流行的技术之一包括基于雅可比的显著图攻击(JSMA)。这些方法依赖于这样一种方法论,即当对原始样本添加小的扰动时,所得到的样本会表现出相反的特征,因为所得到的样本现在被目标模型不同地分类。

JSMA 方法使用显著图生成扰动。显著图标识输入数据的哪些特征与模型决定是一个类别还是另一个类别最相关;这些特征如果被改变,很可能会影响目标值的分类。更具体地,选择初始百分比的特征(γ)以被(θ)量的噪声干扰。然后,该模型确定添加的噪声是否已经导致目标模型的错误分类。如果噪声没有影响模型的性能,则选择另一组特征,并进行新的迭代,直到显著图出现,该显著图可用于生成敌对样本。

预训练的 MLP 被用作生成敌对样本的基础模型。这里,我们探讨 JSMA 参数的不同组合如何影响最初训练的决策树的性能。

估价

为了探索 JSMA 参数的不同组合如何影响训练好的决策树的性能,通过使用伽马和西塔的一系列组合,从测试数据中存在的所有垃圾邮件数据点生成敌对样本。然后,对抗性样本与非垃圾邮件测试数据点相结合,并呈现给训练好的模型。热图报告了 JSMA 的 gamma 和 theta 参数的所有敌对组合的总体加权平均 F1 分数。

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

决策树模型的分类性能实现了所有γ和θ参数的 F1 分数的降低。当γ= 0.3,θ= 0.5 时,模型的分类性能下降了 18 个百分点(F1-score = 0.759)。在这种情况下,基于该数据集,γ= 0.3,θ= 0.5 将是人们用来成功降低基于机器学习的 SMS 垃圾邮件检测器的准确性的最佳参数。

结论

那么,我从这个分析中学到了什么?

由于其有效性和灵活性,基于机器学习的检测器现在被认为是检测 SMS 文本消息是否是垃圾邮件的基本工具。然而,这种系统容易受到攻击,可能会严重破坏或误导它们的能力。在这种基础设施中,对抗性攻击可能会产生严重后果,因为 SMS 文本可能会被修改以绕过检测器。

下一步将是探索这些样本如何支持使用对抗训练的监督模型的鲁棒性。这需要将对立样本包括到训练数据集中,重新训练模型,并评估其在 JSMA 的伽马和θ参数的所有对立组合上的性能。

完整的笔记本,查看下面我的 GitHub 回购:https://GitHub . com/lowri Williams/SMS _ Adversarial _ Machine _ Learning

深度学习中的对立例子——初级读本

原文:https://towardsdatascience.com/adversarial-examples-in-deep-learning-a-primer-feae6153d89?source=collection_archive---------22-----------------------

在深度学习视觉模型中引入对立的例子

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

来源: Pixabay

介绍

自从我们开始获得更大更好的计算(GPU 和 TPU)、更多的数据(ImageNet 等)以来,我们已经看到了最先进的(SOTA)计算机视觉深度学习模型的出现。)以及易于使用的开源软件和工具(TensorFlow 和 PyTorch)。每年(现在每隔几个月!)我们看到下一个 SOTA 深度学习模型在基准数据集的 Top-k 准确性方面击败了上一个模型。下图描绘了一些最新的 SOTA 深度学习视觉模型(并没有描绘一些像谷歌的 BigTransfer!).

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

https://arxiv.org/abs/1905.11946 SOTA 深度学习视觉模型(来源:)

然而,当这些 SOTA 深度学习模型试图对一类特定的图像(称为敌对图像)进行预测时,它们中的大多数都陷入困境。对立例子的整体概念可以是自然例子,也可以是合成例子。我们将通过本文中的几个例子来熟悉不同的对抗性例子和攻击。

对立的例子

自然对立的例子是模型难以理解的自然的、有机的图像。一个合成的对抗性示例是,攻击者(恶意用户)故意将一些噪声注入到图像中,该图像在视觉上与原始图像非常相似,但该模型最终做出了非常不同(并且错误)的预测。让我们更详细地看看其中的几个!

自然对立的例子

这些例子,如论文 【亨德里克斯等人的自然对抗例子】 中所定义的,是现实世界中的、未修改的、自然发生的例子,导致分类器精度显著降低。他们引入了两个新的自然对立例子的数据集。第一个数据集包含 7,500 个 ImageNet 分类器的自然对立示例,用作硬 ImageNet 分类器测试集,称为 IMAGENET-A。下图显示了 ImageNet-A 数据集中的一些对立示例。

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

ResNet-50 在 ImageNet-A 的例子上失败得很惨(来源:https://arxiv.org/abs/1907.07174))

你可以清楚地看到多么错误(和愚蠢!)是最新型(SOTA) ResNet-50 模型对上述示例的预测。事实上,DenseNet-121 预训练模型在 ImageNet-A 上仅获得 2%的准确度!

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

来源:https://github . com/dipanjanS/adversarial-learning-robustness

作者还策划了一个名为 IMAGENET-O 的对抗性分布外检测数据集,他们声称这是第一个为 IMAGENET 模型创建的分布外检测数据集。下图显示了对 ImageNet-O 数据集中的图像进行 ResNet-50 推理的一些有趣示例。

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

ResNet-50 在 ImageNet-O 的例子上非常失败(来源:【https://arxiv.org/abs/1907.07174】T2)

这些例子确实很有趣,并展示了 SOTA 预训练视觉模型在这些图像中的一些图像上的局限性,这些图像对于这些模型来说解释起来更复杂。失败的一些原因可以归因于深度学习模型在对特定图像进行预测时试图关注的内容。让我们看更多的例子来理解这一点。

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

ImageNet-A 中的自然对抗性例子(来源:【https://arxiv.org/abs/1907.07174】T4)

根据上图中展示的例子,很明显,深度学习视觉模型做出了一些特定的模式错误解释。例如:

  • 蜡烛被预测为南瓜灯,尽管没有南瓜,因为模型更关注火焰及其照明等方面
  • 由于模型更注重颜色和纹理,蜻蜓被预测为臭鼬或香蕉
  • 蘑菇被归类为钉子,因为模型学会了将某些元素联系在一起,例如木钉
  • 模型最终也会遭遇泛化问题,比如日晷的阴影

如下图所示,SOTA 深度学习视觉模型在这些示例中的整体性能非常差。

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

SOTA 深度学习视觉模型在 ImageNet-A 上的表现(来源:https://arxiv.org/abs/1907.07174))

可悲的是,强大的对抗训练方法几乎无助于处理与错误解释自然对抗示例相关的问题,如 Hendrycks 等人在同一篇论文中提到的。其中一些方法包括针对特定合成攻击的训练,如投影梯度下降(PGD)和快速梯度符号方法(FGSM),我们将在后续文章中更详细地讨论。幸运的是,这些方法对于处理恶意合成攻击非常有效,而恶意合成攻击通常是一个更大的问题。

合成对立例子

这些例子基本上涉及在输入图像中人工引入一些噪声,使得它在视觉上仍然保持与原始图像非常相似,但是注入的噪声最终降低了分类器的精度。虽然有各种各样的合成对抗性攻击,但所有这些攻击都遵循一些核心原则,如下图所示。

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

来源:https://github . com/dipanjanS/adversarial-learning-robustness

重点始终是找出一种方法来完善噪声\扰动张量(值的矩阵),它可以叠加在原始图像的顶部,使得这些扰动对人眼不可见,但最终使深度学习模型无法做出正确的预测。上面描述的示例展示了一种快速梯度符号方法(FGSM)攻击,其中我们在输入图像的梯度符号中添加了一个小乘数,并叠加了一幅熊猫图像,使模型无法预测图像是一只长臂猿。下图展示了一些更常见的对抗性攻击类型。

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

来源:https://github . com/dipanjanS/adversarial-learning-robustness

下一步是什么?

在接下来的几篇文章中,我们将讨论上述每一种对抗性攻击方法,并通过实际操作的代码示例展示如何欺骗最新和最好的 SOTA 视觉模型。敬请期待!

这篇文章的内容改编自 我最近的博客文章 关于由本人Sayak 完成的对抗性学习,你可以在这个 GitHub 库中找到详细的例子。

喜欢这篇文章吗?请联系我进行更多讨论或提供反馈!

[## Dipanjan Sarkar -数据科学领导-应用材料| LinkedIn

我是一名数据科学家,领导多个垂直领域的 ML\DL\CV\NLP 工作。*专注机器学习,深度…

www.linkedin.com](https://www.linkedin.com/in/dipanzan/)

敌对的潜在自动编码器

原文:https://towardsdatascience.com/adversarial-latent-autoencoders-4ce12c0abbdd?source=collection_archive---------42-----------------------

Python-PyTorch

仅仅通过代码就能生成人脸和表情

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

比安卡·伯格在 Unsplash 上拍摄的照片

几年前,人脸识别模型风靡互联网。人们完全被计算机如何识别一张脸,甚至在某些情况下可以预测年龄而震惊了!人脸识别很快渗透到大众技术中——以至于今天几乎所有的智能手机都有人脸识别功能。人脸识别软件或安全系统的价格昂贵的时代已经一去不复返了!

然而,自从面部检测系统出现以来,技术以前所未有的速度发展。今天的神经网络不仅可以识别或检测人脸,还可以生成人脸——*你我无法从真实人脸中辨别的人脸!*想试试吗?检查一下这个😉。

随着生成对抗网络的出现,人脸生成已经成为计算机视觉领域的一个重要研究领域。在这篇文章中,我将阐述一种特殊类型的自动编码器,它有助于比以往任何时候都更好地生成人脸。)对抗性潜在自动编码器(ALAE)——其 预印本 已于 2020 年 4 月 9 日在Arxiv公开。

为了理解敌对潜在自动编码器(ALAE)背后的概念,让我们先来看看它的灵感模型——生成敌对网络和自动编码器。

生成对抗网络

生成性对抗网络是一个双重网络,这两个部分是鉴别器网络和生成器网络。甘氏综合症的有趣之处在于,发生器和鉴别器网络不断地相互竞争,从而迫使对方发挥出自己最好的一面。

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

GAN 架构—带 SGD

生成器的任务是创建鉴别器无法从真实数据中鉴别的数据*。换句话说,生成器试图形成对真实数据分布的估计。理想的生成器应该能够计算出真实的数据分布,从而能够生成无限的数据。与此同时,鉴别器网络只是一个分类器网络——它试图将传递给它的数据分类为真或假。*

自动编码器

自动编码器在结构上由编码器、解码器和瓶颈组成。这是一种无监督学习算法,它试图学习恒等函数,并给出尽可能接近输入的输出。

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

自动编码器架构

更多关于自动编码器的信息请点击。如果你想在评论中发表一篇关于自动编码器的文章,请告诉我!

既然我们已经有了自动编码器和生成对立网络的基本概念,让我们从对立的潜在自动编码器开始。

ALAE 引入了一种通用的自动编码器架构,在学习更少纠缠的表示时,具有与 GANs 相当的生成能力。为了更好地理解 ALAEs 如何获得这两个世界的优点,让我们来看看模型架构。

体系结构

研究工作通过修改原始 GAN 范式引入了一种新的架构。所提出的架构将发生器和鉴别器定义为两个功能的组合

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

发生器和鉴别器功能—[从左到右]

在定义发生器和鉴别器网络时,已经做了许多重要的假设

  1. 假设 F 和 G 之间以及 E 和 D 之间的界面处的潜在空间是相同的,用 W 表示。
  2. 假设 f 是确定性映射,而 G 和 E 是随机映射。
  3. 还假设 G 可选地依赖于具有已知固定分布的独立噪声输入η。这有助于创建一个更通用的随机生成器。

一般来说,定义自动编码器的常见做法是为潜在空间设置期望的目标潜在分布——编码器被训练来匹配的分布。另一方面,ALAE 不强加潜在分布来匹配特定的目标分布。潜在分布中的唯一约束是 E 的输出分布必须与 g 的输入分布相同。抓住这一约束,学习过程决定什么对模型最好。

让我们来看看这个建筑的图片——

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

https://arxiv.org/abs/2004.04467ALAE 建筑事务所

这是一般的 ALAE 架构。你可能想知道为什么架构是抽象的——为什么它不是用卷积层和激活之类的东西构建的。那是因为这只是 ALAE 架构的一般概念。我们在这里没有定义完整的架构。完整的架构取决于我们在哪里使用 ALAE 作为自动编码器。

花柱翼

StyleALAE 使用基于 StyleGAN 的生成器以及对抗的潜在自动编码器。这个架构可以表达为—

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

*StyleALAE 建筑—【https://arxiv.org/abs/2004.04467 *

发生器是从 StyleGAN 架构改编的网络,而编码器是从 ALAE 改编的架构。编码器被设计成与发生器网络对称,以便从图像中捕获风格信息。添加实例标准化层以获得每个通道的平均值和标准偏差,有效地从每个级别中提取样式表示。

StyleALAE 在 ALAE 和 StyleGAN 的帮助下,利用人工智能提高了人脸和表情生成的标准。StyleALAE 模型的官方实现可以在这里 找到

让我们来看看这个模型能够实现什么——

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

StyleALAE 生成的图像—https://github.com/podgorskiy/ALAE

是的,这是生成的图像!抓到你了,不是吗?😉

从 arxiv 的 预印本 中了解更多关于 ALAE 的信息,并确保也能很好地阅读 StyleGAN 网络。如果你在什么地方卡住了,请告诉我!—乐意帮忙😄。

查看我的博客以获得更快的更新,不要忘记订阅:D 优质内容

* [## 卷积博客

克罗伊斯,吕底亚(小亚细亚)的国王,曾经问特尔斐的神谕,他是否应该对波斯开战…

www.theconvolvedblog.vision](https://www.theconvolvedblog.vision)

Hmrishav Bandyopadhyay 是印度 Jadavpur 大学电子与电信系的二年级本科生。他的兴趣在于深度学习、计算机视觉和图像处理。他的联系方式是:hmrishavbandyopadhyay@gmail.com | |https://hmrishavbandy . github . io*

对抗性机器学习缓解:对抗性学习

原文:https://towardsdatascience.com/adversarial-machine-learning-mitigation-adversarial-learning-9ae04133c137?source=collection_archive---------30-----------------------

一种保护机器学习模型免受恶意攻击的简单方法

文献中有几种针对深度学习模型的攻击,包括快速梯度符号法(FGSM)(BIM)或动量迭代法** (MIM)攻击。这些攻击是攻击者用来躲避分类模型的最纯粹的基于梯度的躲避技术。**

引用代码

如果您认为这些结果有用,请引用本文:

@PROCEEDINGS{catak-adv-ml-2020,
    title = {Deep Neural Network based Malicious Network Activity Detection Under Adversarial Machine Learning Attacks},
    booktitle = {Proc.\ 3rd International Conference on Intelligent Technologies and Applications (INTAP 2020)},
    volume = 5805,
    series = {LNCS},author  = {Ferhat Ozgur Catak},
    publisher = {Springer},
    year = {2020}
    }

介绍

在这项工作中,我将提出一种新的方法来保护恶意活动检测模型免受几种敌对的机器学习攻击。因此,我们探索了应用对抗性训练来建立一个对抗 FGSM 攻击的健壮模型的能力。相应地,(1)用对立的例子增强数据集;(2)使用 KDDCUP99 数据集训练基于深度神经网络的检测模型,以学习基于 FGSM 的攻击模式。我们将这个训练模型应用于基准网络安全数据集。

对抗性机器学习被用来描述对机器学习模型的攻击,它试图通过恶意输入实例误导模型。图中显示了典型的对抗性机器学习攻击。

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

典型的机器学习模型基本上包括两个阶段,即训练时间和决策时间。因此,对抗性机器学习攻击发生在训练时间或决策时间。根据攻击的时间,黑客用于对抗性机器学习的技术可以分为两种:

  • 数据中毒:攻击者改变训练输入实例的一些标签,误导输出模型。
  • 模型中毒:黑客在模型创建后,利用一些被扰动的实例驱动模型产生虚假标签。

我们的模型能够应对黑客使用对抗性机器学习方法进行的模型攻击。该图说明了用于保护模型和正确分类的系统架构。

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

让我们编码吧

我们导入通常的标准库加上一个 cleverhans 库,对深度学习模型进行对抗性攻击。

from sklearn.datasets import fetch_kddcup99
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn import preprocessing
import tensorflow as tf
import pandas as pd
import numpy as np
from keras.utils import np_utils
from cleverhans.future.tf2.attacks import fast_gradient_method, \
    basic_iterative_method, momentum_iterative_method

np.random.seed(10)

在这项工作中,我们将使用标准的 KDDCUP’99 入侵检测数据集来显示结果。我们需要从数据集中提取数字特征。我创建了一个新方法来加载和提取 KDD cup’99 数据集。

COL_NAME = ['duration', 'protocol_type', 'service', 'flag', 'src_bytes',
            'dst_bytes', 'land', 'wrong_fragment', 'urgent', 'hot',
            'num_failed_logins', 'logged_in', 'num_compromised', 'root_shell',
            'su_attempted', 'num_root', 'num_file_creations', 'num_shells',
            'num_access_files', 'num_outbound_cmds', 'is_host_login',
            'is_guest_login', 'count', 'srv_count', 'serror_rate',
            'srv_serror_rate', 'rerror_rate', 'srv_rerror_rate',
            'same_srv_rate', 'diff_srv_rate', 'srv_diff_host_rate',
            'dst_host_count', 'dst_host_srv_count', 'dst_host_same_srv_rate',
            'dst_host_diff_srv_rate', 'dst_host_same_src_port_rate',
            'dst_host_srv_diff_host_rate', 'dst_host_serror_rate',
            'dst_host_srv_serror_rate', 'dst_host_rerror_rate', 'dst_host_srv_rerror_rate']

NUMERIC_COLS = ['duration', 'src_bytes', 'dst_bytes', 'wrong_fragment',
                'urgent', 'hot', 'num_failed_logins', 'num_compromised',
                'root_shell', 'su_attempted', 'num_root', 'num_file_creations',
                'num_shells', 'num_access_files', 'num_outbound_cmds', 'count',
                'srv_count', 'serror_rate', 'srv_serror_rate', 'rerror_rate',
                'srv_rerror_rate', 'same_srv_rate', 'diff_srv_rate',
                'srv_diff_host_rate', 'dst_host_count', 'dst_host_srv_count',
                'dst_host_same_srv_rate', 'dst_host_diff_srv_rate',
                'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate',
                'dst_host_serror_rate', 'dst_host_srv_serror_rate',
                'dst_host_rerror_rate', 'dst_host_srv_rerror_rate']

def get_ds():
    """ get_ds: Get the numeric values of the KDDCUP'99 dataset. """
    x_kddcup, y_kddcup = fetch_kddcup99(return_X_y=True, shuffle=False)
    df_kddcup = pd.DataFrame(x_kddcup, columns=COL_NAME)
    df_kddcup['label'] = y_kddcup
    df_kddcup.drop_duplicates(keep='first', inplace=True)
    df_kddcup['label'] = df_kddcup['label'].apply(lambda d: \
                                    str(d).replace('.', '').replace("b'", "").\
                                        replace("'", ""))

    conversion_dict = {'back':'dos', 'buffer_overflow':'u2r', 'ftp_write':'r2l',
                       'guess_passwd':'r2l', 'imap':'r2l', 'ipsweep':'probe',
                       'land':'dos', 'loadmodule':'u2r', 'multihop':'r2l',
                       'neptune':'dos', 'nmap':'probe', 'perl':'u2r', 'phf':'r2l',
                       'pod':'dos', 'portsweep':'probe', 'rootkit':'u2r',
                       'satan':'probe', 'smurf':'dos', 'spy':'r2l', 'teardrop':'dos',
                       'warezclient':'r2l', 'warezmaster':'r2l'}
    df_kddcup['label'] = df_kddcup['label'].replace(conversion_dict)
    df_kddcup = df_kddcup.query("label != 'u2r'")
    df_y = pd.DataFrame(df_kddcup.label, columns=["label"], dtype="category")
    df_kddcup.drop(["label"], inplace=True, axis=1)
    x_kddcup = df_kddcup[NUMERIC_COLS].values
    x_kddcup = preprocessing.scale(x_kddcup)
    y_kddcup = df_y.label.cat.codes.to_numpy()
    return x_kddcup, y_kddcup

基于张量流的分类模型然后作为练习给出如下:

def create_tf_model(input_size, num_of_class):
    """ This method creates the tensorflow classification model """
    model_kddcup = tf.keras.Sequential([
        tf.keras.layers.Dense(200, input_dim=input_size, activation=tf.nn.relu),
        tf.keras.layers.Dense(500, activation=tf.nn.relu),
        tf.keras.layers.Dense(200, activation=tf.nn.relu),
        tf.keras.layers.Dense(num_of_class),
        # We seperate the activation layer to be able to access
        # the logits of the previous layer later
        tf.keras.layers.Activation(tf.nn.softmax)
        ])
    model_kddcup.compile(loss='categorical_crossentropy',
                         optimizer='adam',
                         metrics=['accuracy'])
    return model_kddcup

下一步是使用 CleverHans 库创建对抗性的机器学习攻击。我对 Tensorflow 库使用了快速梯度符号法**(FGSM)基本迭代法 (BIM)或动量迭代法 (MIM)攻击。我为每次攻击创造了 3 种方法。**

def gen_tf2_fgsm_attack(org_model, x_test):
    """ This method creates adversarial examples with fgsm """
    logits_model = tf.keras.Model(org_model.input, model.layers[-1].output)

    epsilon = 0.1
    adv_fgsm_x = fast_gradient_method(logits_model,
                                      x_test,
                                      epsilon,
                                      np.inf,
                                      targeted=False)
    return adv_fgsm_x

def gen_tf2_bim(org_model, x_test):
    """ This method creates adversarial examples with bim """
    logits_model = tf.keras.Model(org_model.input, model.layers[-1].output)

    epsilon = 0.1
    adv_bim_x = basic_iterative_method(logits_model,
                                       x_test,
                                       epsilon,
                                       0.1,
                                       nb_iter=10,
                                       norm=np.inf,
                                       targeted=True)
    return adv_bim_x

def gen_tf2_mim(org_model, x_test):
    """ This method creates adversarial examples with mim """
    logits_model = tf.keras.Model(org_model.input, model.layers[-1].output)

    epsilon = 0.1
    adv_mim_x = momentum_iterative_method(logits_model,
                                          x_test,
                                          epsilon,
                                          0.1,
                                          nb_iter=100,
                                          norm=np.inf,
                                          targeted=True)
    return adv_mim_x

让我们继续用正常的(未被操纵的)KDDCUP’99 数据集训练攻击检测模型

EPOCH = 50
TEST_RATE = 0.2
VALIDATION_RATE = 0.2

X, y = get_ds()

num_class = len(np.unique(y))

attack_functions = [gen_tf2_bim,
                    gen_tf2_fgsm_attack,
                    gen_tf2_mim]

model = create_tf_model(X.shape[1], num_class)

X_train, X_test, y_train, y_test = train_test_split(X, y, \
                                                    test_size=TEST_RATE)
y_train_cat = np_utils.to_categorical(y_train)
y_test_cat = np_utils.to_categorical(y_test)

history = model.fit(X_train, y_train_cat, epochs=EPOCH,
                    batch_size=50000, verbose=0,
                    validation_split=VALIDATION_RATE)

y_pred = model.predict_classes(X_test)
cm_org = confusion_matrix(y_test, y_pred)
print("*"*50)
print("Original confusion matrix")
print(cm_org)C:\Users\ferhatoc\AppData\Roaming\Python\Python37\site-packages\pandas\core\frame.py:3997: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  errors=errors,

WARNING:tensorflow:AutoGraph could not transform <function Model.make_train_function.<locals>.train_function at 0x0000025288139948> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_train_function.<locals>.train_function at 0x0000025288139948> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function Model.make_test_function.<locals>.test_function at 0x0000025287FF4318> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_test_function.<locals>.test_function at 0x0000025287FF4318> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:From <ipython-input-7-6c756bab0648>:24: Sequential.predict_classes (from tensorflow.python.keras.engine.sequential) is deprecated and will be removed after 2021-01-01.
Instructions for updating:
Please use instead:* `np.argmax(model.predict(x), axis=-1)`,   if your model does multi-class classification   (e.g. if it uses a `softmax` last-layer activation).* `(model.predict(x) > 0.5).astype("int32")`,   if your model does binary classification   (e.g. if it uses a `sigmoid` last-layer activation).
WARNING:tensorflow:AutoGraph could not transform <function Model.make_predict_function.<locals>.predict_function at 0x0000025283D0E798> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_predict_function.<locals>.predict_function at 0x0000025283D0E798> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
**************************************************
Original confusion matrix
[[10873    16     0     0]
 [   16 17528     6    18]
 [    7    20   403    11]
 [    3    23     4   179]]

原始模型的混淆矩阵

这里显示了原始模型的混淆矩阵。根据混淆矩阵,该模型的分类性能相当好。

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

让我们继续攻击,被攻击模型的混淆矩阵和敌对训练模型的混淆矩阵

for attack_function in attack_functions:
        print("*"*20)
        print("Attack function is ", attack_function)

        model = create_tf_model(X.shape[1], num_class)
        history = model.fit(X_train, y_train_cat, epochs=EPOCH,
                            batch_size=50000, verbose=0,
                            validation_split=VALIDATION_RATE)

        X_adv_list = []
        y_adv_list = []

        adv_x = attack_function(model, X_test)
        y_pred = model.predict_classes(adv_x)
        cm_adv = confusion_matrix(y_test, y_pred)
        print("*"*20)
        print("Attacked confusion matrix")
        print(cm_adv)

        print("Adversarial training")
        # define the checkpoint

        adv_x = attack_function(model, X_train)
        adv_x_test = attack_function(model, X_test)

        concat_adv_x = np.concatenate([X_train, adv_x])
        concat_y_train = np.concatenate([y_train_cat, y_train_cat])

        history = model.fit(concat_adv_x, concat_y_train, epochs=EPOCH,
                            batch_size=50000, verbose=0,
                            validation_data=(adv_x_test, y_test_cat))

        y_pred = model.predict_classes(adv_x_test)
        cm_adv = confusion_matrix(y_test, y_pred)
        print("*"*20)
        print("Attacked confusion matrix - adv training")
        print(cm_adv)********************
Attack function is  <function gen_tf2_bim at 0x00000252FCF84A68>
WARNING:tensorflow:AutoGraph could not transform <function Model.make_train_function.<locals>.train_function at 0x00000252FD05FDC8> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_train_function.<locals>.train_function at 0x00000252FD05FDC8> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function Model.make_test_function.<locals>.test_function at 0x00000252877B80D8> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_test_function.<locals>.test_function at 0x00000252877B80D8> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function Model.make_predict_function.<locals>.predict_function at 0x0000025281E8B168> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_predict_function.<locals>.predict_function at 0x0000025281E8B168> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
********************
Attacked confusion matrix
[[10874    15     0     0]
 [   14 17532     7    15]
 [    6    19   404    12]
 [    3    23     5   178]]
Adversarial training
********************
Attacked confusion matrix - adv training
[[10877    12     0     0]
 [   12 17535     6    15]
 [    1    13   425     2]
 [    0    22     3   184]]
********************
Attack function is  <function gen_tf2_fgsm_attack at 0x00000252FCF84B88>
WARNING:tensorflow:AutoGraph could not transform <function Model.make_train_function.<locals>.train_function at 0x0000025281E8B438> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_train_function.<locals>.train_function at 0x0000025281E8B438> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function Model.make_test_function.<locals>.test_function at 0x0000025288BB38B8> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_test_function.<locals>.test_function at 0x0000025288BB38B8> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function Model.make_predict_function.<locals>.predict_function at 0x0000025287EF2558> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_predict_function.<locals>.predict_function at 0x0000025287EF2558> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
********************
Attacked confusion matrix
[[10702   180     6     1]
 [   79 17353    31   105]
 [    9    47   376     9]
 [    3    88     8   110]]
Adversarial training
********************
Attacked confusion matrix - adv training
[[10877    11     0     1]
 [    9 17543     4    12]
 [    1    15   422     3]
 [    2    25     2   180]]
********************
Attack function is  <function gen_tf2_mim at 0x00000252FCF84D38>
WARNING:tensorflow:AutoGraph could not transform <function Model.make_train_function.<locals>.train_function at 0x00000252875459D8> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_train_function.<locals>.train_function at 0x00000252875459D8> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function Model.make_test_function.<locals>.test_function at 0x00000252F9990048> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_test_function.<locals>.test_function at 0x00000252F9990048> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:5 out of the last 14 calls to <function compute_gradient at 0x00000252FCF6A318> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings is likely due to passing python objects instead of tensors. Also, tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. Please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for more details.
WARNING:tensorflow:AutoGraph could not transform <function Model.make_predict_function.<locals>.predict_function at 0x0000025280355A68> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function Model.make_predict_function.<locals>.predict_function at 0x0000025280355A68> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: Bad argument number for Name: 4, expecting 3
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
********************
Attacked confusion matrix
[[10874    15     0     0]
 [   16 17530     5    17]
 [    6    24   400    11]
 [    3    23     5   178]]
Adversarial training
********************
Attacked confusion matrix - adv training
[[10878    11     0     0]
 [   12 17537     4    15]
 [    1    16   420     4]
 [    0    21     2   186]]

对抗性训练结果

基本迭代法(BIM)

被攻击模型的混淆矩阵

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

对抗训练模型的混淆矩阵

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

快速梯度符号法

被攻击模型的混淆矩阵

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

对抗训练模型的混淆矩阵

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

动量迭代法

被攻击模型的混淆矩阵

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

对抗训练模型的混淆矩阵

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

对抗验证

原文:https://towardsdatascience.com/adversarial-validation-ca69303543cd?source=collection_archive---------31-----------------------

过度拟合的诊断工具

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

想和其他学习 ML 的人聊天?加入我们的 新 ML 不和谐服务器

本帖原载于blog.zakjost.com。去那里可以更好地呈现内联代码。

介绍

如果你在 Kaggle 上研究一些竞争获胜的解决方案,你可能会注意到提到“对抗性验证”(就像这个)。这是什么?

简而言之,我们构建一个分类器来尝试预测哪些数据行来自训练集,哪些来自测试集。如果两个数据集来自同一个分布,这应该是不可能的。但是,如果在你的训练和测试数据集的特征值中存在系统差异,那么分类器将能够成功地学会区分它们。你能学会区分它们的模型越好,你的问题就越大。

但好消息是,你可以分析学习过的模型来帮助你诊断问题。一旦你理解了问题,你就可以着手解决它。

这篇文章是为了配合我制作的一个 YouTube 视频来解释对抗性验证的直觉。这篇博文介绍了本视频中示例的代码实现,但是足够完整,可以自成一体。你可以在 github 上找到这篇文章的完整代码。

学习对抗性验证模型

首先,用一些样板导入语句来避免混淆:

import pandas as pd
from catboost import Pool, CatBoostClassifier

数据准备

对于本教程,我们将使用来自 Kaggle 的 IEEE-CIS 信用卡欺诈检测数据集。首先,我假设您已经将训练和测试数据加载到 pandas DataFrames 中,并分别将其命名为df_traindf_test。然后,我们将通过替换丢失的值来进行一些基本的清理。

# Replace missing categoricals with "<UNK>"
df_train.loc[:,cat_cols] = df_train[cat_cols].fillna('<UNK>')
df_test.loc[:,cat_cols] = df_test[cat_cols].fillna('<UNK>')

# Replace missing numeric with -999
df_train = df_train.fillna(-999)
df_test = df_test.fillna(-999)

对于对抗性验证,我们希望学习一个模型来预测哪些行在训练数据集中,哪些行在测试集中。因此,我们创建一个新的目标列,其中测试样本用1标记,训练样本用0标记,如下所示:

df_train['dataset_label'] = 0
df_test['dataset_label'] = 1
target = 'dataset_label'

这是我们将训练一个模型来预测的目标。现在,训练和测试数据集是分开的,每个数据集只有一个目标值标签。如果我们在这个训练集上训练一个模型,它会知道一切都是 0。相反,我们希望重组训练和测试数据集,然后创建新的数据集来拟合和评估对抗性验证模型。我定义了一个用于组合、洗牌和重新分割的函数:

def create_adversarial_data(df_train, df_test, cols, N_val=50000):
    df_master = pd.concat([df_train[cols], df_test[cols]], axis=0)
    adversarial_val = df_master.sample(N_val, replace=False)
    adversarial_train = df_master[
        ~df_master.index.isin(adversarial_val.index)
    ]
    return adversarial_train, adversarial_val

features = cat_cols + numeric_cols + ['TransactionDT']
all_cols = features + [target]
adversarial_train, adversarial_test = create_adversarial_data(df_train, df_test, all_cols)

新数据集adversarial_trainadversarial_test,包括原始训练集和测试集的混合,目标表示原始数据集。注:我在特性列表中添加了 *TransactionDT* 。其原因将变得显而易见。

对于建模,我将使用 Catboost。我通过将数据帧放入 Catboost 池对象来完成数据准备。

train_data = Pool(
    data=adversarial_train[features],
    label=adversarial_train[target],
    cat_features=cat_cols
)
holdout_data = Pool(
    data=adversarial_test[features],
    label=adversarial_test[target],
    cat_features=cat_cols
)

建模

这一部分很简单:我们只需实例化一个 Catboost 分类器,并将其应用于我们的数据:

params = {
    'iterations': 100,
    'eval_metric': 'AUC',
    'od_type': 'Iter',
    'od_wait': 50,
}

model = CatBoostClassifier(**params)
_ = model.fit(train_data, eval_set=holdout_data)

让我们继续在维持数据集上绘制 ROC 曲线:

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

这是一个完美的模型,这意味着有一个明确的方法来判断任何给定的记录是在训练集还是测试集中。这违反了我们的训练集和测试集是同分布的假设。

诊断问题和迭代

为了理解该模型是如何做到这一点的,让我们来看看最重要的特性:

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

TransactionDT 是最重要的特性。考虑到原始的训练和测试数据集来自不同的时间段(测试集出现在训练集的未来),这是完全有意义的。该模型刚刚了解到,如果 TransactionDT 大于上一个训练样本,则它在测试集中。

我包含 TransactionDT 只是为了说明这一点——通常不建议将原始日期作为模型特征。但是好消息是这项技术以如此戏剧性的方式找到了它。这种分析将清楚地帮助您识别这样的错误。

让我们排除 TransactionDT,再次运行这个分析。

params2 = dict(params)
params2.update({"ignored_features": ['TransactionDT']})
model2 = CatBoostClassifier(**params2)
_ = model2.fit(train_data, eval_set=holdout_data)

现在 ROC 曲线看起来像这样:

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

它仍然是一个相当强的模型,AUC > 0.91,但比以前弱了很多。让我们来看看该模型的功能重要性:

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

现在,id_31是最重要的特性。让我们看一些价值观来理解它是什么。

[
    '<UNK>', 'samsung browser 6.2', 'mobile safari 11.0',
    'chrome 62.0', 'chrome 62.0 for android', 'edge 15.0',
    'mobile safari generic', 'chrome 49.0', 'chrome 61.0',
]

该列包含软件版本号。显然,这在概念上类似于包含原始日期,因为特定软件版本的第一次出现将对应于其发布日期。

让我们通过从列中删除任何不是字母的字符来解决这个问题:

def remove_numbers(df_train, df_test, feature):
    df_train.loc[:, feature] = df_train[feature].str.replace(
        r'[^A-Za-z]', '', regex=True
    ) df_test.loc[:, feature] = df_test[feature].str.replace(
        r'[^A-Za-z]', '', regex=True
    )

remove_numbers(df_train, df_test, 'id_31')

现在,我们列的值如下所示:

[
    'UNK', 'samsungbrowser', 'mobilesafari',
    'chrome', 'chromeforandroid', 'edge',
    'mobilesafarigeneric', 'safarigeneric',
]

让我们使用这个清理后的列来训练一个新的对抗性验证模型:

adversarial_train_scrub, adversarial_test_scrub = create_adversarial_data(
    df_train,
    df_test,
    all_cols,
)

train_data_scrub = Pool(
    data=adversarial_train_scrub[features],
    label=adversarial_train_scrub[target],
    cat_features=cat_colsc
)

holdout_data_scrub = Pool(
    data=adversarial_test_scrub[features],
    label=adversarial_test_scrub[target],
    cat_features=cat_colsc
)

model_scrub = CatBoostClassifier(**params2)
_ = model_scrub.fit(train_data_scrub, eval_set=holdout_data_scrub)

ROC 图现在看起来像这样:

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

业绩从 0.917 的 AUC 下降到 0.906。这意味着我们已经使模型更难区分我们的训练和测试数据集,但它仍然非常有能力。

结论

当我们天真地将交易日期放入特性集时,对抗性的验证过程有助于清楚地诊断问题。额外的迭代给了我们更多的线索,即包含软件版本信息的列在训练集和测试集之间有明显的差异。

但是流程不能做的是告诉我们如何修复它。我们仍然需要在这里运用我们的创造力。在本例中,我们只是从软件版本信息中删除了所有数字,但这丢弃了潜在的有用信息,并可能最终损害我们的欺诈建模任务,而这正是我们的真正目标。这个想法是你想删除对预测欺诈不重要的信息,但对分离你的训练和测试集很重要

更好的方法可能是找到一个数据集,给出每个软件版本的软件发布日期,然后创建一个“自发布以来的天数”列来替换原始版本号。这可能有助于更好地匹配训练和测试分布,同时还保持软件版本信息编码的预测能力。

资源

别忘了加入我们的 新 ML 不和谐服务器

原载于 https://blog.zakjost.com

用于一般化真实世界应用的对抗训练分类器

原文:https://towardsdatascience.com/adversarially-trained-classifiers-for-generalizable-real-world-applications-92dbcb24f7f3?source=collection_archive---------50-----------------------

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

凯文·Ku 在 Unsplash 上拍摄的照片

动机:可推广人工智能的目的

计算机视觉领域不断要求提高分类器的准确性。各地的研究人员都试图在某个特定的数据集上以微小的差距打破之前的基准。我们认为这一趋势对于推动人类理解的边缘非常重要,但我们也认为还有一个更大的问题尚未得到充分探索——建立一个可概括的分类器。

那么,什么是广义神经网络呢?为什么概化很重要?既然特异性允许我们对每一项任务保持更高的整体准确性,为什么我们不能每次都对特定的数据集微调我们的神经网络呢?

可推广性指的是机器学习模型对现实世界中可能发生的数据扰动(即背景中的随机对象、图像失真)的抵抗力。对随机性越敏感,就越不具有普适性。当我们部署模型来解决完全未知数据分布的问题时,提高模型的可推广性可以使模型表现得更好。

这非常重要,因为在真实世界的应用中,当最终用户实时向我们提供测试数据时,我们永远不知道底层数据分布何时会改变!出于这个原因,推广神经模型的突破可能会转化为多项机器学习任务(如自动驾驶和语音识别)的性能基准的提高。

因此,我们小组在这个项目中的目标是创建能够对未知扰动下的未知数据进行分类的神经模型。

在本文中,我们将讨论使用对抗示例作为训练数据的方法以及如何生成它们。作为奖励,我们还将探索 CAM 可视化作为解释最后敌对的错误分类行为的一种方式。

模型设计选择

在我们开始设计过程之前,我们考虑了 TensorFlow 2.0 与 Keras 和 PyTorch。最终,我们选择了 TensorFlow 和 Keras,因为它允许更简单的实现和更广泛的预训练模型。我们希望我们的项目最终更加易读和简洁。

我们项目中的主要设计选择包括:

  • 数据扩充与随机翻转、随机裁剪、色彩抖动以及常见的高斯、泊松和椒盐噪声相结合。
  • 选择 MobileNet v2 作为基础模型,对预训练模型中的参数数量比率具有非常高的精度(参见优化选择部分),并为数据集处理的微型 ImageNet** 选择合理的模型大小。**
  • 结合 神经结构化学习(NSL)对抗正则化 通过在训练过程中注入对抗损失来提高鲁棒性。

我们也考虑过通过替代损失最小化(TRADES) 【张等 2019】实现 权衡启发的对抗性防御,但最终没有考虑。

对抗性范例生成的先验研究

尽管最近用于计算机视觉任务的神经网络已经达到了惊人的精度,但它们仍然极易受到人类察觉不到的微小干扰。

此前,研究人员推测这是由于神经网络的非线性组件**,极化了这些激活(想想爆炸梯度)。然而,在解释和利用对立的例子中,作者认为这种脆弱性实际上是由于神经网络的线性组件,即在 LSTM 的 ReLU。即使在非线性 sigmoid 函数的情况下,该模型也常常具有线性范围内的大多数值(即当 x 接近 0 时),进一步支持了这一发现。**

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

图片由 Goodfellow、Shlens 和 Szegedy 提供

在这篇论文中,作者还描述了一种快速的生成对抗性例子的方法,以及我们使用的对抗性训练方法。作者引入了快速梯度符号方法(FGSM)** 来有效地生成对立的例子:计算关于输入的梯度,然后扰动输入,使得:**

input = input + epsilon * sign(gradient)

下面是一个应用于逻辑回归模型的 FGSM 的例子,该模型是在原始论文中对 MNIST 三与七进行训练的。

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

图片由 Goodfellow、Shlens 和 Szegedy 提供

扰动直接应用于 7,并在 3 上反转,以使模型将 7 错误分类。 FGSM 可以直接并入损失函数,间接产生额外的正则化效果。

作者定位了更好的最终模型准确性和增加的稳健性。对抗范例错误率的错误率从基础模型的 89.4%降低到 17.9%。

模型设置:培训和验证

对于我们的模型,我们只在训练期间使用了一个对抗性的包装器。我们不会在这里包括所有的代码,但是一般的框架应该是这样的。

base = **create_model**('base', dim, 2, len(classe))
adv_model = **nsl**.**keras**.**AdversarialRegularization**(base, config, ...)
adv_model.**compile**(optimizer=keras.optimizer.SGD,...))

有一些对包装器最重要的超参数。它们是乘数步长**。乘数对正则化有重要影响,步长用于在验证过程中寻找对立的例子。**

config = **nsl.configs.make_adv_reg_config**(
    **multiplier**=0.2,
    **adv_step_size**=0.2,
    **adv_grad_norm**='infinity',
)

训练时间过程基本上与其他 Keras 模型相同,但是要确保数据集被转换为字典,而不是元组,因为您将数据提供给包装器,而不是实际的分类器。

def **convert**(image, label):
  **return** {IMAGE_INPUT_NAME: image, LABEL_INPUT_NAME: label}train_data_adv = train_data.**map**(convert)
val_data_adv = val_data.**map**(convert)

在验证过程中,一定要创建一个基本的参考模型,以确保您的对抗性包装器训练有效。您应该会看到,在受干扰的数据上,您的对抗性模型的性能显著提高,而在未受干扰的数据上,您的性能只会略微降低。

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

作者提供的图片,对比准确性

最后,在测试和验证期间,记得使用开头中定义的基本模型。对抗性包装模型应该只在训练时使用,即使您使用标准 Keras API 保存对抗性包装模型的权重,它也只会保存基础模型的权重。因此,请确保始终将权重加载到基础模型中,然后添加包装器,否则会出现不匹配的问题。

优化选择

由于以前的经验和论文表明 SGD 更适合 CV 任务,我们使用 SGD 而不是 ADAM。出于同样的原因,我们没有预先决定微调不同层的时期数,而是在训练损失达到稳定状态时转移到更高层。

由于我们选择使用 Keras 作为我们的框架,我们还在其他网络架构上测试了相同的训练方法:

  • 丹塞尼特·雷斯 NeXt
  • 纳斯网,纳斯网移动
  • B6 B4 区 B2 效率网

NASNet 由于参数数量太多而容易过度拟合,我们发现 MobileNet V2 表现最好。EfficientNet 是一个势均力敌的竞争者,但我们无法使用它,因为它后来加入了 TensorFlow(它只在 tf-nightly 中可用,所以我们几乎每天都有新的技术问题)。

我们将跳过选择批量大小和学习速率的过程,因为优化这些的方法在深度学习论文和其他中等帖子中随处可见。我们将简单地指出,它们在培训绩效中发挥了很大的作用,并且在不同的模型中有所不同。

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

图片由作者提供,NASNet 过拟合微型图像网络数据集

[额外]可解释的人工智能挑战

当前的分类方法要求输入并产生类,而没有对上下文或结果的任何可理解的解释。实际上,这使得深度学习算法成为研究人员和工程师的黑匣子。在这个项目中,我们通过提供我们自己对敌对行为和一般错误分类的解释,解决了可解释的人工智能挑战**。**

在接下来的几节中,显著性指的是视觉处理环境中特定输入的一些独特特征。基本上,显著性可视化方法允许强调图像上视觉上吸引人的位置,这些位置可能“有助于”神经工作做出特定的分类决策。

对于我们应该可视化哪种类型的显著性,有许多选择。一些例子包括使用导向传播的线性激活或噪声生成,但是我们在这里不讨论它们。我们简单地将最后一层改为线性激活,看看哪些像素对分类决策的影响最大。我们使用了 keras-vis 模块。这两个显著图分别示出了正梯度和负梯度。

我们将在这里注意到,keras-vis 稍微有些过时,可能无法与 TensorFlow 2.0 Keras 的某些版本一起使用。

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

作者图片

我们的模型能够正确预测蟑螂标签。我们可以看到模型能够很容易地做到这一点,因为最后一层的线性激活最大化清楚地显示了蟑螂的形状。

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

作者图片

我们的模型没有正确分类这个对象。这可以通过以下事实来解释:微小图像网络通常具有较低的分辨率,导致来自具有相似形状的物体的相似激活。这里的错误分类是扫帚**(ImageNet 中的 n02906734)。我们也可以将这归因于我们在训练数据扩充过程中的随机裁剪,我们可能在训练过程中裁剪出了扫帚柄。**

在下面的注射器示例中,这些图像的激活非常相似,因此我们的模型决定在 Oboe注射器扫帚啤酒瓶之间进行选择。这是前五大预测之一。

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

作者图片

这个误分类是一个啤酒瓶(n02823428)** ,合理的猜测吗?**

我们还可视化了我们生成的一些对抗性训练示例。这些物体对人类来说是可识别的,但对神经网络来说,它们通常被某种类型的激活无效所掩盖。在下面的例子中,很明显,这里的激活与之前看到的原始对象形状没有任何相似之处。

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

作者图片

激活和抑制变得随机和扭曲。

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

作者图片

激活和抑制是模糊的。

正确使用虚拟环境的建议和提示

原文:https://towardsdatascience.com/advice-and-tips-to-properly-work-with-virtual-environments-67bbad9ba5b6?source=collection_archive---------19-----------------------

因为虚拟环境能够并且将会让您省心

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

来源:https://unsplash.com/photos/wl5AypUmamo

2020 年初,我正在使用 Keras/Tensorflow 进行一个学校项目。一切都很顺利。然后,我和我的队友分享了我的代码,这样他也可以开始工作了。然而,出于某种原因,这对他不起作用。

我们花了几个小时想弄明白。最终,我们意识到这个问题是由于我们安装了不同版本的包造成的。一旦我们设法让它全部工作,我决定找到一种方法来避免这个问题再次发生。

这就是虚拟环境的用武之地。

如果你已经熟悉虚拟环境,你可以跳到第四部分,在那里我会给出一些建议和技巧来帮助你改进和定制你对虚拟环境的使用。

1.为什么要使用虚拟环境?

随着您对 Python 的掌握越来越好,您将会使用越来越多的包,并且正确处理对早期版本包的依赖性将会越来越困难,因此需要虚拟环境。

可以将虚拟环境想象成一个独立的文件夹,您可以在其中保存特定版本的包,甚至是特定的 Python 版本,而不会影响您的其他项目。

这是一个简单的方法,可以确保你(和其他人)总是运行 Python 脚本而没有依赖问题,也就是说,总是为你的包使用正确的版本。

所有出现的代码都可以直接从 Anaconda 提示符或命令行执行。

2.如何创建虚拟环境

超级简单。首先,确保你安装了 virtualenv,创建虚拟环境的库:pip install virtualenv

然后,下面几行代码将为您的项目创建一个新文件夹,并在其中创建/激活一个虚拟环境。

> mkdir new_folder        **#create new folder for project**
> cd new_folder           **#set current directory to folder** > virtualenv venv         **#Create a virtual environment called venv**
> cd venv/Scripts         **#Set working directory to venv**
> . activate                **#Activate the environment**

从那里,您可以安装您需要的所有软件包及其特定版本:pip install beautifulsoup4==4.9.1

然而,有一个更好的方法可以做到这一点。

3.使用 requirements.txt 文件

通过创建一个需求文件,您可以指定您想要在您的虚拟环境中使用的包和版本。下面是它应该是什么样子的一个例子:

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

然后,在确保文件位于当前工作目录中之后,您可以使用以下代码行安装文件中提到的所有软件包:

> pip install -r requirements.txt

这很好,但是还有一个更好的方法,我将在下一节中介绍。

4.其他有用的提示和技巧

这里有一些提示和技巧,我相信它们会促进甚至改善你对虚拟环境的使用。

  1. 自动创建一个 requirements.txt 文件

不需要手动创建需求文件,您可以(也应该)做的是将您的 Python 脚本放在虚拟环境中,并编写以下代码行:

> pip freeze > requirements.txt

这将为您自动创建它。

另一个选择也是使用pipregs库。您所要做的就是将 Python 脚本的位置设为当前目录,然后键入pipregs

> pip install pipreqs
> pipreqs

这将找到您的 Python 脚本,检测所有正在使用的包(和版本),并从中创建 requirements.txt 文件。

2。用特定的 Python 版本创建虚拟环境

如果您想让您的脚本在特定的 Python 版本上运行,这是很容易做到的。首先,确保您单独下载了您想要使用的版本。

然后,在创建虚拟环境时,将代码的virtualenv venv部分改为这样(例如,如果您想使用 Python 3.7):

> virtualenv venv --python=python3.7

3。不要把你的 Python 脚本放在虚拟环境中

删除虚拟环境最简单的方法是手动删除其文件夹。如果您将 python 脚本和需求文件插入其中,它们将随之被删除,这可能不是您想要做的。

您可能还想为多个项目使用同一个虚拟环境。将一切分开可以避免问题。

最好的办法是将这些文件放在虚拟环境之外,如下所示:

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

4。直接从虚拟环境中运行 Python 代码

如果您想直接从您的虚拟环境中运行您的代码,您只需在您的文件名前添加python,就像这样:

> python flights_scraping.py

我希望这有所帮助。非常感谢你的阅读!

对成功的数据科学职业生涯的建议

原文:https://towardsdatascience.com/advice-for-a-successful-data-science-career-7f07b3586171?source=collection_archive---------22-----------------------

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

图片作者奥瑞西娅·斯图思

我之前写过如何建立数据科学作品集,其中涵盖了**向潜在雇主展示你能做什么的重要性,而不仅仅是告诉他们你能做些什么。**本博客利用 Orysya Stus成功是冰山图作为框架,展示了人们在感知数据科学成功之旅中的几个方面经常被隐藏起来。这个博客旨在表明,大多数人都不得不付出相当多的努力才能达到现在的位置。他们必须努力工作,有时会经历失败,表现出纪律性,坚持不懈,致力于目标,有时会牺牲或冒险。就这样,让我们开始吧!

错误/失败

发推文作者凯特琳·胡登

正如你在上面凯特琳·哈东(在线医疗的首席数据科学家)为她的推特创建的 GIF 图中所看到的,人们在日常模型构建中会犯很多技术错误/失败。

我们大多数编码或从事数据科学的人经常看到彼此工作的最终产品——而不是我们作为过程的一部分所做的草稿、错误和决策。围绕这些步骤的一点透明度将大有帮助。

Jake VanderPlas 在一条关于开源的推文中似乎呼应了类似的观点,人们通常只看到最终产品而不是过程。

在开源中,我们经常看到的是最终产品,而不是过程……这可能会让那些一开始就看到周围完美事物的人感到沮丧。

但是我敢打赌,在任何成功的开源项目的光鲜外表背后,都有大量的痛苦、烦恼和自我怀疑。

除了技术故障,还有其他类型的故障,包括你可以穿的类型(日志拒绝,电子邮件拒绝等)。凯特琳·k·柯比(Caitlin k . Kirby)毫不夸张地说出了她的失败/拒绝。在华盛顿邮报上有一篇文章详细描述了她的裙子是用她在过去五年里收到的 17 封拒绝信(杂志拒绝、电子邮件拒绝等)手工制作的及膝服装。

推特作者凯特琳·k·科比

顺便说一句,如果你想知道更多软件/数据科学相关的拒绝故事,有一个完整的拒绝网站你可以看看,也许会对你有所启发。

努力工作/坚韧不拔

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

推文作者吴恩达

大多数人不得不努力工作才能达到现在的位置。我绝对不是说你必须每周例行工作 70-90 小时,因为这听起来不健康。Rachel Thomas’帖子提到了这种态度是如何具有歧视性和适得其反的。

我们需要尽可能地摆脱工作时间的长短才是最重要的这种肤浅想法。科技行业对长得离谱的工作时间的痴迷不仅对许多残疾人来说是不可及的,而且对每个人的健康和人际关系都是有害的,但正如奥利维亚·戈德希尔石英在工作指出的那样,对生产力的研究表明这只是低效的:

无数研究表明,这根本不是真的。随着工作时间的延长,生产率会急剧下降,一旦人们每周工作 55 个小时,生产率就会完全下降,以至于平均来说,一个人每周工作 70 个小时并不比一个同事少工作 15 个小时。

疯狂的长时间工作在学术界也很常见,正如下面提到的杰克·范德普拉斯推特

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

虽然这条推文不是对吴恩达之前推文的评论,但我认为它表明了成功有不同的方式,而不是持续工作。 Python 数据科学手册的作者似乎做得不错。(发推文发推文杰克·范德普拉斯

与其努力工作,也许我们应该谈论坚韧或坚持,就像杰瑞米·霍华德的新书和西尔万·古格的新书一样。

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

来自推特的内容摘自杰瑞米·霍华德的西尔万·古格的新书

简而言之,我认为最好的方法是:

你将面临许多障碍,既有技术上的,也有(甚至更困难的)你周围不相信你会成功的人。有一种方法肯定会失败,那就是停止尝试。

坚持

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

图片来自我的博客文章

生活中的许多成功都与坚持不懈有关。有很多像 Airbnb 的数据科学家 Kelly Peng 这样的成功人士的故事,他们真的坚持不懈,不断工作和改进。在她的一篇博文中,她回顾了自己申请和面试了多少个职位。

应用:475

电话采访:50 次

完成数据科学带回家的挑战:9

现场面试:8 次

优惠:2

花费的时间:6 个月

她明明申请了很多工作,还一直在坚持。在她的文章中,她甚至提到你需要从面试经历中不断学习。

记下你被问到的所有面试问题,尤其是那些你没有回答的问题。你可以再次失败,但不要在同一个地方失败。你应该一直学习和提高。

纪律/奉献精神

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

推特作者安德里亚斯·麦德森

这篇文章的主题之一是每个人都经历过一些失败。重要的是有些人竭尽全力去实现他们的目标。在 Andreas Madsen 发表的一篇博文中,他描述了进入 AI(通常是计算机科学系)的顶级博士项目有多难。实际上,他采访的所有教授都告诉他,要进入顶级博士项目,他需要“在顶级 ML 领域发表 1-2 篇论文”。他花了 7 个月的时间在一个没有资金和没有导师的研究项目上工作,以产生可以出版的作品。

牺牲/冒险

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

图片由迈克尔·加拉尼克

牺牲和风险可以以多种不同的形式出现。一个风险可能是忽视来自上面的命令。格雷格·林登在亚马逊的时候,他在做几个有趣的项目,尽管他本应该做其他事情。在他的一篇博客文章中,他描述了一个项目:

根据你的亚马逊购物车中的商品进行推荐。添加一些东西,看看有什么发现。再加几个,看看有什么变化…我黑出了一个原型。在一个测试网站上,我修改了 Amazon.com 的购物车页面,以推荐您可能喜欢添加到购物车中的其他商品。在我看来相当不错。我开始四处展示。

有一个问题。

虽然反应是积极的,但也有一些担忧。特别是,一位营销高级副总裁坚决反对……在这一点上,我被告知我被禁止在这方面做任何进一步的工作。我被告知亚马逊还没有准备好推出这项功能。应该就此打住。

相反,我为在线测试准备了这个特性。我相信购物车的推荐。我想衡量销售影响。

我听说 SVP 发现我推出一项测试后很生气。但是,即使是高层管理人员,也很难阻止测试。测量很好。反对测试的唯一有力论据是,负面影响可能非常严重,以至于亚马逊无法承受,这一点很难断言。测试开始了。

结果很明显。它不仅赢了,而且以如此大的优势赢得了这项功能,以至于没有上线让亚马逊付出了相当大的代价。随着新的紧迫性,购物车建议推出…

当时,亚马逊肯定是混乱的,但我怀疑我忽视来自上面的命令是在冒险。尽管亚马逊很好,但它还没有完全接受衡量和辩论的文化。

虽然我不提倡忽视上级的建议,但似乎在某些情况下,冒险对公司和你自己都有好处。

结论

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

图片作者奥瑞西娅·斯图思

希望你能从这篇博客中找到一些建议和例子,对你的数据科学之旅有所帮助。请记住,许多来自成功人士的建议都存在生存偏见。总是半信半疑地接受建议或分享经验。如果你有任何问题,对这篇文章有什么想法,或者只是想分享你自己的经历,欢迎在下面的评论中或者通过推特联系我们。

AES 加密 256 位

原文:https://towardsdatascience.com/aes-encryption-256-bit-a9ae49cde0b6?source=collection_archive---------16-----------------------

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

Bermix 工作室Unsplash 拍摄的照片

统治它们的加密标准

AES(高级加密标准)是使用最广泛的对称加密算法。AES 应用广泛,包括静态数据加密和安全文件传输协议,如 HTTPS。

AES 是 DES 的继承者。数据加密标准(DES)是 IBM 开发的一种对称加密算法。过去,DES 曾是事实上的加密算法。然而,它使用的是 56 位密钥,随着技术的进步,对它的攻击开始变得更加可信。最终,DES 被认为太不安全而不能继续使用。社区过渡到了三重 DES(直到今天仍然存在)。本质上,三重 DES 是连续执行 3 次的 DES。正如所料,三重 DES 比普通 DES 安全 3 倍。然而,它也慢了 3 倍。

美国政府举办了一场竞赛,想出三重 DES 的替代方案。最终,由两位比利时密码学家文森特·里门和琼·代蒙编写的 Rijndael,因其性能和在硬件和软件上的易于实现性,以及其安全级别而被选中。 Rijndael 成为美国的高级加密标准,最终也成为世界其他地区的标准。

AES 加密算法

假设鲍勃想给爱丽丝发一条消息。Bob 的未加密消息首先被分解成 128 位的块。然后将给定块中的字节(总共 16 个)组织成 4x4 矩阵。

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

该块通过以下步骤序列总共 x 次,其中 x 取决于密钥的大小。

  1. 替代字节
  2. 移动行
  3. 混合列
  4. 添加圆形密钥

替代字节

在该步骤中,矩阵中的每个元素被映射到 Rijndael S-box 中的相应字节。

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

S-Box

例如,左上角的元素被映射到d4,因为第一个十六进制是1,另一个十六进制是9

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

对每个元素重复该过程,我们获得以下矩阵:

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

移动行

在第二步中,我们将每个元素向左旋转 x 个元素(字节),其中 x 是行的索引。

  • 第 0 行—左移 0 字节(即不移位)

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

  • 第 1 行—左移 1 个字节

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

  • 第 2 行—左移 2 个字节

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

  • 第 3 行—左移 3 个字节

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

我们以下面的矩阵结束:

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

混合列

我们将每一列乘以一个预定义的矩阵。

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

需要注意的是,这不是常规的矩阵乘法。如果任何一项大于 2 的 8 次幂,我们将该多项式除以伽罗瓦不可约多项式:

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

让我们来看看如何计算d402的乘积。我们首先将每一位转换成二进制算术等价物(多项式形式)。

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

我们将两者相乘。

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

因为乘积大于 2 的 8 次方,所以我们用不可约多项式除它。

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

我们对每个元素重复该过程,并获得以下矩阵:

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

添加圆形密钥

在这一步中,我们在前面步骤中获得的矩阵的列和轮密钥之间执行按位异或运算。在第一次迭代中,轮密钥是密码密钥的前 128 位。

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

圆形钥匙

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

对剩余的列重复该过程,我们得到:

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

前面的矩阵被用作下一轮的输入,并且该过程本身被重复另外的 x 轮。

:最后一轮不包括混合列步骤。

AES 密钥表

计算下一轮新密钥的过程称为密钥表。正如我们前面提到的,轮数取决于初始密钥的长度。

  • 128 位密钥= 10 轮
  • 192 位密钥= 12 轮
  • 256 位密钥= 14 轮

注意:在所有其他方面,算法完全相同。

与 128 位输入模块以状态数组的形式排列的方式相同,该算法以 4 × 4 字节矩阵的形式排列加密密钥的前 16 个字节。下图显示了原始 128 位密钥的四个字被扩展成由 4 x 11 = 44 个字组成的密钥表。加密密钥的前四个字节构成字 w0,接下来的四个字节构成字 w1,依此类推,直到 w3。

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

假设我们有第轮密钥的四个字。

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

我们需要确定下一轮要用的词。

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

该序列中的第一个字计算如下:

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

其中功能 g 由以下三个步骤组成:

  • 对 4 字节字执行一个字节的循环旋转。
  • 使用 16 × 16 查找表替换字中的每个字节
  • 将从上一步中获得的字节与所谓的 循环常数 进行异或运算。

轮的 轮常数 t 表示为Rcon【j】

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

在哪里

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

注意 :添加舍入常数破坏了算法中其他步骤可能引入的任何对称性,从而使其更难破解。

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

第一个操作包括旋转字节。

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

然后,我们使用查找表执行字节替换。

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

替换剩余的字节后,我们得到下面的向量。

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

最后,我们在向量、第一个单词和**【Rcon[1]**之间执行按位异或运算,以获得新单词。

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

然后,我们继续计算轮密钥中的剩余单词。

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

新的 4x4 矩阵(轮密钥)用于下一轮的添加密钥步骤。

10 轮中的每一轮都重复该过程。

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

美学地图:用于空间数据关联上下文的二元图谱

原文:https://towardsdatascience.com/aesthetic-map-bivariate-choropleth-for-association-context-on-spatial-data-45572aba60da?source=collection_archive---------28-----------------------

实践教程

你如何观察这两个变量之间的关系?非空间数据的散点图,空间数据的二元线图。

介绍

新冠肺炎病例与城市密度相关吗?人口密度与经济总量相关吗?GDRP 和污染有什么关系?城市比农村更有生产力吗?

这些问题可以通过分析两个空间数据集来回答。一个简单的散点图可能会很快回答这个问题。但在这篇文章中,我想把重点放在空间方面。这是因为这些问题依赖于要素的地理方面。用散点图截断方面可能会隐藏关于数据实际性质的战略性或有影响力的洞察力。正如托布勒的地理法则第一条所说:

一切事物通常都与所有其他事物相关,但是那些彼此靠近的事物比那些离得远的事物更相关

本文介绍了使用地理空间可视化理解数据之间的关联;即理解两个变量与空间环境之间的相关性。如上所述,这是散点图之外的一个选项,我们将看到地理空间方法有何不同。使用双变量图谱进行描述性分析的方法。

(注:观察空间关系的方法有很多种,这个方法只是其中一种。我选择这种方法是因为它简单,容易理解,而且直观。 再加上,就做出了一张漂亮的地图! )

概括地说空间数据

**空间数据是具有空间维度的数据。**简单来说,我们可以做一个数据图。与典型数据一样,**空间数据可以用电子表格的形式表示。**典型的电子表格数据和空间数据的区别在于,空间数据有一个存储几何信息的几何列。这种几何信息通常以众所周知的文本格式表示(查看链接文章中的表 1,或者查看这个链接)。

例如,下图:雅加达市的行政边界和相应人口的表格。请注意,它有一个存储地理信息的“geometry”列。另外关于数据格式,请参考我的另一篇文章

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

等值区域图

我相信你在生活中一定遇到过 choropleth 地图,只是你不知道它叫“choropleth 地图”。这是一张这样的地图:

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

雅加达人口分布图(来源:作者,2020;数据来源:印度尼西亚统计局,2020 年)

这是以前的电子表格数据的可视化。看起来很整洁,对吗?典型条形图的一个很好的替代品。空间关系是直观的,但提供了定量信息(人口数据)。

“色彩图是阴影图,其中颜色的强度表示所讨论现象的强度。”— 皇家地理学会

这种直方图依赖于将数据分类到几个箱中,就像直方图一样,并且将唯一的颜色分配给这些箱。分类方法确实会影响结果,从而产生不同的解释。更多关于分类的信息可以在这里找到。

这让我想起分类和图表可能会误导信息(请参考下面的视频,这是批评图表/数据可视化的一个很好的指南)。所以,要注意仓的规模和 choropleth 的分类方法。

进一步扩展-二元颜色

现在,上面的例子(地图)只解释了 1 个变量。我们可以再插入一个变量,这样它就变成了二元颜色。由两个变量组成的弦线图称为二元弦线图

让我们看看这个例子,好吗?

二元染色体组

这是我做的最新的双变量 Choropleth 地图。在这里,我想通过观察六边形镶嵌地图中人口总数和人口标准差之间的关系来确定城市化的程度。这张地图是我在 Twitter 上参加 #30DayMapChallenge 的作品。

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

双变量 choropeth(修订)(来源:作者,2020 )

请注意,图例现在有两个变量:标准差和总体总和。六边形包含各个六边形内人口的聚集值;因此,六边形以诸如平均值、中值等统计属性的形式截断。现在,关系由每个变量的颜色组合来表示。混合这些颜色会产生代表变量之间关系的独特颜色组合。此外,六边形地图将数据的空间背景可视化。有了地图,可以直观的看到(地理空间)聚类。

现在,让我们看看散点图是如何可视化这种关系的。我们来做一些对比。

散点图

好的,这是散点图(颜色和地图一样)。

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

散点图分析(来源:作者,2020)

我不知道你怎么想,但是在看了二元图之后,我发现散点图非常奇怪。"我不能简单地说这种关系是线性的,因为数据中存在聚类,而且这种聚类必须加以说明。这使得数据在空间上是相关的,而不是独立的。这是因为散点图不代表数据的地理性质;您无法观察到空间聚类。简单地进行回归分析是错误的,除非该分析是地理加权的。( 聚类)会导致空间自相关,这给假设残差独立 的统计方法带来问题。

结束语

在我看来,简单的散点图不适合非空间数据,即不依赖于空间元素的数据。绘制散点图会隐藏数据的空间元素和关系,如聚类(空间自相关)。解决这个问题的一个方法是制作一个双变量 choropleth 图;两个变量的 choropleth 图。图表的绘图代表地理信息,而颜色代表变量值的强度。使用双变量 choropleth,数据的空间感也被捕获和呈现。

(个人注:还有,地图变美了,至少对我来说!它给人一种微妙的美感,这种美感随着情感而颤动,尤其是一些精心的设计选择。在这种情况下,我认为制图是一种艺术形式,而不仅仅是数据可视化。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值