From d7f23b76edef946e33a27a2b2e682c967ab2a205 Mon Sep 17 00:00:00 2001 From: wnma3mz Date: Thu, 18 Oct 2018 17:42:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=A1=E9=AA=8Cdl10.md=20=E7=9A=84=201/4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zh/dl10.md | 96 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/zh/dl10.md b/zh/dl10.md index f3fdb76..9aa02d0 100644 --- a/zh/dl10.md +++ b/zh/dl10.md @@ -6,12 +6,12 @@ #### 回顾上周 [[0:16](https://youtu.be/h5Tz7gZT9FoY%3Ft%3D16s)] -* 许多学生正在努力学习上周的材料,所以如果你觉得很难,那很好。 杰里米预先把它放在那里的原因是我们有一些东西要思考,思考,并逐渐努力,所以在第14课,你将得到第二个裂缝。 -* 要理解这些碎片,你需要了解卷积层输出,感受域和损失函数的形状 - 无论如何,这些都是你需要了解的所有深度学习研究的内容。 -* 一个关键的问题是我们从简单的东西开始 - 单个对象分类器,没有分类器的单个对象边界框,然后是单个对象分类器和边界框。 除了我们首先必须解决匹配问题之外,我们去多个对象的位实际上几乎相同。 我们最终创建了比我们的基础真实边界框所需的激活更多的激活,因此我们将每个地面实况对象与这些激活的子集相匹配。 一旦我们完成了这个,我们对每个匹配对做的损失函数几乎与这个损失函数(即单个对象分类器和边界框的一个)相同。 -* 如果你感觉困难,请返回第8课,确保你了解数据集,DataLoader,最重要的是了解损失函数。 -* 因此,一旦我们有一些可以预测一个对象的类和边界框的东西,我们通过创建更多激活来进入多个对象 [[2:40](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D2m40s)] 。 然后我们必须处理匹配问题,处理了一个匹配问题,然后我们将每个锚箱移入和移出一点点左右,所以他们试图与特定的地面实例对象进行对齐。 -* 我们谈到了我们如何利用网络的卷积性质来尝试进行具有与我们预测的基本事实对象类似的接受场的激活。 Chloe提供了以下精彩图片来讨论SSD_MultiHead.forward一行一行: +* 许多学生正在努力学习上周的材料,所以如果你觉得很难,那很好。杰里米预先把它放在那里的是因为我们有一些东西要不断思考,并慢慢努力,所以在第14课,你将得到第二个飞跃。 +* 要理解这些碎片,你需要理解卷积层输出、感受野和损失函数的维度 - 无论如何,这些都是你所有需要了解的深度学习研究的内容。 +* 一个关键的问题是我们从简单的东西开始 - 单个对象分类器,没有分类器的单个对象边界框,然后是单个对象分类器和边界框。 除了首先我们必须解决匹配问题之外,我们迁移到多个对象上实际几乎相同。 我们最终创建了比我们的基础真实边界框所需的激活更多的激活数量,因此我们将每个地面实况对象与这些激活的子集相匹配。 一旦我们完成了这个,我们对每个匹配所做的损失函数几乎与这个损失函数(即单个对象分类器和边界框的损失函数)相同。 +* 如果你感觉困难,请返回第8课,确保你了解了数据集,DataLoader,最重要的是了解损失函数。 +* 因此,一旦我们有了可以预测一个对象的类和边界框的东西,我们通过创建更多的激活来进入多个对象 [[2:40](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D2m40s)] 。 之后,我们必须处理匹配问题,处理了一个匹配问题之后,我们将每个锚箱移入移出一点,再移到周围一点,所以他们试图与特定的地面实例对象进行对齐。 +* 我们谈到了我们如何利用网络的卷积性质来尝试激活具有与我们所预测的基本事实对象类似的接受场。 Chloe提供了以下奇妙的图片来讨论什么是SSD_MultiHead.forward,一行一行地看: ![](../img/1_BbxbH3gWu8RHMTuXZlDasA.png) @@ -19,46 +19,46 @@ -Chloe在这里所做的是她特别关注路径中每个点处张量的维数,因为我们使用步幅2卷积逐渐下采样,确保她理解为什么这些网格大小发生然后理解输出是如何产生的。 +Chloe在这里所做的是她特别关注路径中每个点处张量的维数,因为我们使用2个步长的卷积逐渐下采样,确保她理解为什么会出现这些网格,然后理解是如何产生输出的。 ![](../img/1_gwvD-lSxiUH_EFq9n-ofOQ.png) -* 这是你必须记住这个`pbd.set_trace()` 。 我刚刚上课前进入`SSD_MultiHead.forward`并输入了`pdb.set_trace()`然后我运行了一个批处理。 然后我可以打印出所有这些的大小。 我们犯了错误,这就是为什么我们有调试器并且知道如何检查事物并一路上做一些小事。 -* 然后我们讨论了增加_k_ [[5:49](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D5m49s)] ,这是每个卷积网格单元的锚箱数量,我们可以用不同的缩放比例,宽高比进行处理,这给我们提供了大量的激活,因此预测了边界框。 -* 然后我们使用非最大抑制去了一个小数字。 -* 非最大抑制是一种hacky,丑陋和完全启发式,我们甚至没有谈论代码,因为它看起来很可怕。 最近有人提出了一篇论文,试图用一个端到端的转发网来取代那个NMS( [https://arxiv.org/abs/1705.02950](https://arxiv.org/abs/1705.02950) )。 +* 这是你必须记住这个`pbd.set_trace()`的地方 。 我刚刚上课前进入`SSD_MultiHead.forward`并输入了`pdb.set_trace()`,然后运行了一个批处理。 之后我可以打印出所有这些的大小。我们可能有错误,这就是为什么我们有调试器并知道如何检查过程中的一些很小的问题。 +* 然后我们讨论了增加_k_ [[5:49](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D5m49s)] ,这是每个卷积网格单元的锚箱数量,我们可以用不同的缩放比、宽高比进行处理,这给我们提供了大量的激活,因此预测了边界框。 +* 然后我们使用非最大抑制来减小数值。 +* 非最大抑制是一种粗糙的、丑陋的和完全的启发式,我们甚至没有讨论代码,因为它看起来很可怕。 最近有人提出了一篇论文,试图用一个端到端的卷积网来取代那个NMS( [https://arxiv.org/abs/1705.02950](https://arxiv.org/abs/1705.02950) )。 ![](../img/1_PadSMuPPUl1W0fPhIdylYQ.png) -* 没有足够的人在阅读论文! 我们现在在课堂上所做的是实施论文,论文是真正的基本事实。 而且我想你通过与人们交谈了解人们不读纸的原因很多,因为很多人都不认为他们有能力读报纸。 他们认为他们不是那种阅读论文的人,但你是。 你在这里。 我们上周开始查看一篇论文,我们读到的是英文单词,我们对它们有很大的了解。 如果你仔细看看上面的图片,你会发现`SSD_MultiHead.forward`没有做同样的事情。 然后你可能想知道这是否更好。 我的回答可能是。 因为SSD_MultiHead.forward是我尝试过的第一件事。 在这篇与YOLO3论文之间,它们可能是更好的方法。 -* 有一点你会特别注意到他们使用较小的k,但他们有更多的网格组1x1,3x3,5x5,10x10,19x19,38x38 - 8732每个级别。 比我们更多,所以这将是一个有趣的实验。 -* 我注意到的另一件事是我们有4x4,2x2,1c1这意味着有很多重叠 - 每一组都适合每一组。 在这种情况下你有1,3,5,你没有那个重叠。 所以它实际上可能更容易学习。 你可以玩很多有趣的东西。 +* 没有足够的人阅读了论文! 我们现在在课堂上所做的是实现论文,论文是真正的基本事实。而且我想你通过与人们交谈,了解了人们不读论文的原因有很多,因为很多人都不认为他们有能力读论文。他们认为他们不是那种阅读论文的人,但你是。你在这里。 我们上周开始阅读一篇论文,我们读到的是英文单词,我们对很了解它们。如果你仔细看看上面的图片,你会发现`SSD_MultiHead.forward`没有做同样的事情。然后你可能就想知道,这样是否是更好的。我的回答可能是yes。因为SSD_MultiHead.forward是我尝试过的第一件事。 在这篇与YOLO3论文之间,它们可能是更好的方法。 +* 有一点你会特别注意到,他们使用了较小的k,但他们有更多的网格组1x1,3x3,5x5,10x10,19x19,38x38 - 8732每个级别。比我们更多,所以这将是一个有趣的实验。 +* 我注意到的另一件事是我们有4x4,2x2,1c1这意味着有很多重叠 - 每一组都与其他组相匹配。 在这种情况下你有1,3,5,没有重叠。所以它实际上可能更容易被学习到。你可以做很多有趣的东西。 ![](../img/1_1AG_zIXUouogXB5--BFuzw.png) -* 也许我建议最重要的是将代码和方程式放在一起。 你是数学家或代码人。 通过将它们并排放置,你将学习到另一个。 +* 也许我建议最重要的是将代码和方程放在一起。你是数学家或程序员。通过将它们并排放置,你将学习到另一类知识。 * 学习数学很难,因为符号似乎很难查找,但有很好的资源,如[维基百科](https://en.wikipedia.org/wiki/List_of_mathematical_symbols) 。 -* 你应该尝试做的另一件事是重新创建你在论文中看到的东西。 这是焦点损失论文中关键的最重要的数字1。 +* 你应该尝试做的另一件事是重新创建你在论文中看到的东西。下图是关键,损失论文中关键的最重要的图1。 ![](../img/1_NJ8DKEP6qwePIi9hGhvhAg.png) ![](../img/1_WhwnGf2r6-aboRYEDWrOUA.png) -* 上周我确实在我的代码中发现了一个小错误 [[12:14](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D12m14s)] - 我对卷积激活的讨论方式并不符合我在丢失函数中使用它们的方式,并且修复它使它更好一些。 +* 上周我确实在我的代码中发现了一个小错误 [[12:14](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D12m14s)] - 我对卷积激活的讨论方式并不符合我在丢失(loss)函数中使用它们的方式,我修复了它,并使它更好一些。 ![](../img/1_B_pXi5zpN2EGnhATYo-ZWg.png) -**问题** :通常,当我们下采样时,我们会增加滤波器的数量或深度。 当我们从7x7到4x4等进行采样时,为什么我们将数字从512减少到256? 为什么不降低SSD头的尺寸? (表现相关?) [[12:58](https://youtu.be/_ercfViGrgY%3Ft%3D12m58s)] 我们有许多外出路径,我们希望每个路径都相同,所以我们不希望每个路径都有不同数量的过滤器,这也就是论文的内容我试图与之相匹配。 拥有这256个 - 这是一个不同的概念,因为我们不仅利用了最后一层,而且利用了之前的层。 如果我们让它们更加一致,生活会更容易。 +**问题** :通常,当我们下采样时,我们会增加滤波器的数量或深度。当我们从7x7到4x4等进行采样时,为什么我们要将数字从512减少到256? 为什么不降低SSD头的尺寸?(性能相关?) [[12:58](https://youtu.be/_ercfViGrgY%3Ft%3D12m58s)] 我们有许多输出路径,我们希望每个路径都相同,所以我们不希望每个路径都有不同数量的过滤器,这也就是论文所作的,我试图与之相匹配。 有了这256个 - 这是一个不同的概念,因为我们不仅利用了最后一层,还利用了之前的层。如果我们让它们更加一致,生活会更容易。 * * * ### 自然语言处理 [[14:10](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D14m10s)] -#### 我们要去的地方: +#### 我们要做的: -我们在每节课中都看到过采用预先训练过的模型的想法,在顶部掀起一些东西,用新的东西替换它,并让它做类似的事情。 我们已经有点潜入了与`ConvLearner.pretrained`更深入的内容。 `ConvLearner.pretrained`它有一种标准的方式将东西粘在顶部,这是一个特定的事情(即分类)。 然后我们了解到实际上我们可以在最后使用我们喜欢的任何PyTorch模块并让它用`custom_head`做任何我们喜欢的`custom_head` ,所以突然你发现我们可以做一些非常有趣的事情。 +我们在每节课中都看到过采用预训练过的好的模型的想法,在顶部快速的去掉一些东西,用一些新的东西替换它,并让它做类似的事情。 我们稍微深入讨论一下这个问题,让我们来谈谈了与`ConvLearner.pretrained`相关内容。 `ConvLearner.pretrained`它有一种标准的方式将东西粘在顶部,这是一个特定的事情(比如分类)。 然后我们了解到实际上我们可以在最后使用我们喜欢的任何PyTorch模块,并让它用`custom_head`做任何我们喜欢的事情 ,所以突然你就发现我们可以做一些非常有趣的事。 -事实上,杨璐说“如果我们做了不同类型的自定义头怎么办?”并且不同的自定义头是让我们拍摄原始图片,旋转它们,并使我们的因变量与旋转相反,看它是否可以学习解旋它。 这是一个非常有用的东西,事实上,我认为Google照片现在有这个选项,它实际上会自动为你旋转你的照片。 但是很酷的是,正如他在这里展示的那样,你可以通过与我们上一课完全相同的方式建立这个网络。 但是你的自定义头是一个输出一个数字的头部,它可以旋转多少,而你的数据集有一个因变量,你可以旋转多少。 +事实上,杨璐说“如果我们做了不同类型的自定义头怎么办?”并且不同的自定义头是让我们拍摄原始图片,旋转它们,并使我们的因变量与旋转相反,看它是否可以学习解旋它。这是一个非常有用的东西,事实上,我认为Google照片现在有这个选项,实际上它会自动为你旋转你的照片。但是很酷的是,正如他在这里展示的那样,你可以通过与我们上一课完全相同的方式建立这个网络。但是你的自定义头是输出单个数字的头部,定义它可以旋转的量,而你的数据集有一个因变量就是你可以旋转的量。 ![](../img/1_4MNEdvVzjzHbbtlub98chw.png) @@ -69,27 +69,27 @@ Chloe在这里所做的是她特别关注路径中每个点处张量的维数, 所以你突然意识到这个主干和定制头的想法,你几乎可以做任何你能想到的事情 [[16:30](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D16m30s)] 。 * 今天,我们将看看同样的想法,看看它如何适用于NLP。 -* 在下一课中,我们将进一步说明NLP和计算机视觉是否可以让你做同样的基本想法,我们如何将两者结合起来。 我们将学习一个实际上可以学习从图像中找到单词结构,从单词结构中找到图像或从图像中找到图像的模型。 如果你想进一步做一些事情,比如从一个图像到一个句子(即图像字幕),或者从一个句子到一个我们开始做的图像,一个短语到图像,那将构成基础。 -* 从那里开始,我们必须更深入地进入计算机视觉,思考我们可以用预先训练的网络和定制头的想法做些什么。 因此,我们将研究各种图像增强,例如增加低分辨率照片的分辨率以猜测缺少的内容或在照片上添加艺术滤镜,或将马的照片更改为斑马照片等。 -* 最后,这将再次带我们回到边界框。 为了达到这个目的,我们首先要学习分割,这不仅仅是找出边界框的位置,而是要弄清楚图像中每个像素的一部分 - 所以这个像素是一个部分人,这个像素是汽车的一部分。 然后我们将使用这个想法,特别是一个名为UNet的想法,结果证明了这个UNet的想法,我们可以应用于边界框 - 它被称为特征金字塔。 我们将使用它来获得带有边界框的非常好的结果。 这是我们从这里开始的道路。 这一切都将相互依赖,但将我们带入许多不同的领域。 +* 在下一课中,我们将进一步说明NLP和计算机视觉是否可以让你实现同样的基本想法,我们如何将两者结合起来。 实际上,我们将学习一个可以学习从图像中找到单词结构,从单词结构中找到图像或从图像中找到图像的模型。 如果你想进一步做一些事情,比如从一个图像到一个句子(即图像字幕),或者从一个句子到一个我们开始做的图像,一个短语到图像,那上面内容将构成基础。 +* 从那里之后,我们必须更深入地进入计算机视觉,思考我们可以用预训练的网络和定制头的想法做些什么。 因此,我们将研究各种图像增强,例如增加低分辨率照片的分辨率以猜测缺少的内容或在照片上添加艺术滤镜,或将马的照片更改为斑马照片等。 +* 最后,这将再次带我们回到边界框。为了达到这个目的,我们首先要学习分割,这不仅仅是找出边界框的位置,而是要弄清楚图像中每个像素的一部分 - 所以这个像素是一个人的一部分,这个像素是一辆车的一部分。 然后我们将用这个想法,特别是一个名为UNet的想法,结果证明了这个UNet的想法可以应用于边界框 - 它被称为特征金字塔。 我们将使用它来获得非常好的带有边界框的结果。这是我们从这里开始的路。 这一切都将建立在彼此的基础上,但将我们带入许多不同的领域。 #### torchtext to fastai.text [[18:56](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D18m56s)] : ![](../img/1_E9I4m0Oj7vpWbf0DlnyFmw.png) -对于NLP,最后一部分,我们依赖于一个名为torchtext的库,但是从那时起,我从那时起就发现它的局限性太难以继续使用了。 正如你们很多人在论坛上抱怨的那样,部分原因是因为它没有进行并行处理,部分是因为它不记得你上次做了什么,而是从头开始重新做了。 然后很难做出相当简单的事情,比如很多你试图进入Kaggle的有毒评论竞赛,这是一个多标签问题,并试图用 PyTorch 文本做到这一点,我最终得到它的工作,但它带我像一个一周的黑客攻击有点荒谬。 为了解决所有这些问题,我们创建了一个名为fastai.text的新库。 Fastai.text是torchtext和fastai.nlp组合的替代品。 所以不要再使用fastai.nlp - 这已经过时了。 它更慢,更混乱,在各方面都不太好,但有很多重叠。 有意地,许多类和函数具有相同的名称,但这是非torchtext版本。 +对于NLP,最后一部分,我们依赖于一个名为torchtext的库,尽管它很好,但我从某个时刻起就发现它的局限性,难以继续使用了。正如你们很多人在论坛上抱怨的那样,它非常慢,部分原因是它没有并行处理,部分原因是它不记得你上次做了什么,而是从头开始重新做。然后很难做相当简单的事情,比如很多你试图进入Kaggle的不良评论竞赛,这是一个多标签问题,并试图用 PyTorch 文本做到这一点,我最终用它完成了工作,但我花了一周的时间,这有点荒谬。 为了解决所有这些问题,我们创建了一个名为fastai.text的新库。Fastai.text是torchtext和fastai.nlp组合的替代品。所以不要再使用fastai.nlp - 这已经过时了。它更慢,更混乱,在各方面都不太好,但是有很多重叠部分。 有意地,许多类和函数具有相同的名称,但这是非torchtext版本。 #### IMDb [[20:32](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D20m32s)] [笔记本](https://github.com/fastai/fastai/blob/master/courses/dl2/imdb.ipynb) -我们将再次与IMDb合作。 对于那些已经忘记的人,请回去看看第[4课](https://medium.com/%40hiromi_suenaga/deep-learning-2-part-1-lesson-4-2048a26d58aa) 。 这是一个电影评论的数据集,我们用它来确定我们是否可以享受Zombiegeddon,我们认为可能是我的事情。 +我们将再次与IMDb合作。对于那些已经忘记的人,请回去看看第[4课](https://medium.com/%40hiromi_suenaga/deep-learning-2-part-1-lesson-4-2048a26d58aa) 。这是一个电影评论的数据集,我们用它来确定我们是否可以喜欢Zombiegeddon,我们认为也许是我喜欢的那种。 ``` **from** **fastai.text** **import** * **import** **html** ``` -> 我们需要从这个网站下载IMDB大型电影评论: [http](http://ai.stanford.edu/~amaas/data/sentiment/) : [//ai.stanford.edu/~amaas/data/sentiment/](http://ai.stanford.edu/~amaas/data/sentiment/)直接链接: [链接](http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz) +> 我们需要从这个网站下载IMDB大型电影评论: [http](http://ai.stanford.edu/~amaas/data/sentiment/):[//ai.stanford.edu/~amaas/data/sentiment/](http://ai.stanford.edu/~amaas/data/sentiment/)直接链接: [链接](http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz) ``` BOS = 'xbos' _# beginning-of-sentence tag_ FLD = 'xfld' _# data field tag_ @@ -101,7 +101,7 @@ Chloe在这里所做的是她特别关注路径中每个点处张量的维数, #### 标准化格式 [[21:27](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D21m27s)] -NLP的基本路径是我们必须采用句子并将它们转换为数字,并且有几个要到达那里。 目前,有些故意,fastai.text没有提供那么多辅助函数。 它的设计更多是为了让你以相当灵活的方式处理事物。 +NLP的基本方法是我们必须把句子并将它们转换为数字,并且有一对要到达那里。目前,有意地,fastai.text没有提供那么多辅助函数。 它的设计更多是为了让你以相当灵活的方式处理事物。 ``` CLAS_PATH=Path('data/imdb_clas/') CLAS_PATH.mkdir(exist_ok= **True** ) @@ -111,7 +111,7 @@ NLP的基本路径是我们必须采用句子并将它们转换为数字,并 LM_PATH=Path('data/imdb_lm/') LM_PATH.mkdir(exist_ok= **True** ) ``` -正如你在这里 [[21:59](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D21m59s)] 所看到的,我写了一些叫做get_texts的东西,它贯穿了`CLASSES`每一件事。 IMDb中有三个类:负数,正数,然后还有另一个文件夹“无人监督”,其中包含尚未标记的文件夹 - 所以我们现在只称它为一个类。 所以我们只需浏览这些类中的每一个,然后查找该文件夹中的每个文件,打开它,读取它,然后将它放入数组的末尾。 正如你所看到的,使用pathlib,抓取内容并将其拉入内容非常容易,然后标签就是我们到目前为止所处的任何类别。 我们将为训练集和测试集做到这一点。 +正如你在这里 [[21:59](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D21m59s)] 所看到的,我写了一些叫做get_texts的东西,它贯穿了`CLASSES`每一件事。 IMDb中有三个类:负数,正数,然后还有另一个文件夹“无人监督”,其中包含尚未标记的文件夹 - 所以我们现在只称它为一个类。 所以我们只需浏览这些类中的每一个,然后查找该文件夹中的每个文件,打开它,读取它,然后将它放入数组的末尾。 正如你所看到的,使用pathlib,非常容易地抓取内容并将其放入内容,然后标签就是我们到目前为止所做的任何类。我们将为训练集和测试集做这样相同的操作。 ``` CLASSES = ['neg', 'pos', 'unsup'] @@ -133,19 +133,20 @@ NLP的基本路径是我们必须采用句子并将它们转换为数字,并 _(75000, 25000)_ ``` -列车有75,000,测试有25,000。 火车组中的50,000个是无人监管的,当我们进入分类时,我们实际上无法使用它们。 Jeremy发现这比使用大量层和包装器的torch.text方法更容易,因为最后阅读文本文件并不那么难。 +训练集有75,000,测试集有25,000。 训练集中的50,000个是无人监管的,当我们进入分类时,我们实际上无法使用它们。 Jeremy发现这比使用大量层和包装器的torch.text方法更容易,因为最后阅读文本文件并不那么难。 ``` col_names = ['labels','text'] ``` -有一点总是好主意是随机排序 [[23:19](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D23m19s)] 。 知道这个随机排序的简单技巧很有用,特别是当你有多个东西需要以同样的方式排序时。 在这种情况下,你有标签和`texts. np.random.permutation` `texts. np.random.permutation` ,如果你给它一个整数,它会给你一个0到0之间的随机列表,不包括你以某种随机顺序给它的数字。 +有一点总是好主意是随机排序 [[23:19](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D23m19s)] 。 知道这个随机排序的简单技巧很有用,特别是当你有多个东西需要以同样的方式排序时。在这种情况下,你有标签和`texts. np.random.permutation` `texts. np.random.permutation` ,如果你给它一个整数,它会给你一个从0到不包括你给它的随机顺序的随机列表。 ``` - np.random.seed(42) trn_idx = np.random.permutation(len(trn_texts)) val_idx = np.random.permutation(len(val_texts)) + np.random.seed(42) + trn_idx = np.random.permutation(len(trn_texts)) val_idx = np.random.permutation(len(val_texts)) ``` -你可以将它作为索引器传递给你一个按随机顺序排序的列表。 所以在这种情况下,它将以相同的随机方式对`trn_texts`和`trn_labels`进行排序。 所以这是一个有用的小习惯用法。 +你可以将它作为索引器传递给你一个按随机顺序排序的列表。 所以在这种情况下,它将以相同的随机方式对`trn_texts`和`trn_labels`进行排序。 所以这是一个有用的小习惯写法。 ``` trn_texts = trn_texts[trn_idx] val_texts = val_texts[val_idx] @@ -155,29 +156,31 @@ NLP的基本路径是我们必须采用句子并将它们转换为数字,并 trn_labels = trn_labels[trn_idx] val_labels = val_labels[val_idx] ``` -现在我们将文本和标签排序,我们可以从它们创建数据[框](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D24m7s) [[24:07](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D24m7s)] 。 我们为什么这样做? 原因是因为文本分类数据集开始出现一些标准的方法,即将训练设置为首先带有标签的CSV文件,然后是NLP文档的文本。 所以它基本上是这样的: +现在我们已经对文本和标签进行了排序,我们可以从它们中创建[dataframe](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D24m7s) [[24:07](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D24m7s)] 。 我们为什么这样做? 原因是文本分类数据集开始出现一些标准的方法,即将训练设置为首先带有标签的CSV文件,然后是NLP文档的文本。 所以它基本上是这样的: ![](../img/1_KUPgEBboQilVi7wcp6RO0Q.png) ``` - df_trn = pd.DataFrame({'text':trn_texts, 'labels':trn_labels}, columns=col_names) df_val = pd.DataFrame({'text':val_texts, 'labels':val_labels}, columns=col_names) +df_trn = pd.DataFrame({'text':trn_texts, 'labels':trn_labels}, columns=col_names) df_val = pd.DataFrame({'text':val_texts, 'labels':val_labels}, columns=col_names) ``` ``` - df_trn[df_trn['labels']!=2].to_csv(CLAS_PATH/'train.csv', header= **False** , index= **False** ) df_val.to_csv(CLAS_PATH/'test.csv', header= **False** , index= **False** ) +df_trn[df_trn['labels']!=2].to_csv(CLAS_PATH/'train.csv', header= **False** , index= **False** ) +df_val.to_csv(CLAS_PATH/'test.csv', header= **False** , index= **False** ) ``` ``` - (CLAS_PATH/'classes.txt').open('w') .writelines(f' **{o}\n** ' **for** o **in** CLASSES) (CLAS_PATH/'classes.txt').open().readlines() + (CLAS_PATH/'classes.txt').open('w') .writelines(f' **{o}\n** ' **for** o **in** CLASSES) + (CLAS_PATH/'classes.txt').open().readlines() ``` ``` - _['neg\n', 'pos\n', 'unsup\n']_ + ['neg\n', 'pos\n', 'unsup\n'] ``` -所以你有你的标签和文本,然后是一个名为classes.txt的文件,它只列出了类。 我说有点标准,因为在最近的一篇学术论文中,Yann LeCun和一个研究小组研究了不少数据集,并且他们使用这种格式。 所以这就是我最近开始使用的论文。 你会发现这款笔记本,如果你把数据放到这种格式,整个笔记本每次都会工作 [[25:17](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D25m17s)] 。 因此,我只是选择一种标准格式,而不是拥有一千种不同的格式,而你的工作就是将数据放入CSV文件格式。 默认情况下,CSV文件没有标头。 +所以你有标签和文本,然后是一个名为classes.txt的文件,它只列出了类。 我说有点标准,因为在最近的一篇学术论文中,Yann LeCun和一个研究小组研究了不少数据集,并且他们使用这种格式。 所以这就是我最近的论文用到的。 你会发现这个笔记本,如果你把数据放到这种格式,整个笔记本每次都会工作 [[25:17](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D25m17s)] 。因此,我只是选择一种标准格式,而不是拥有一千种不同的格式,而你的工作就是将数据放入CSV文件格式。 默认情况下,CSV文件没有标头。 -你会注意到一开始我们有两条不同的路径 [[25:51](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D25m51s)] 。 一个是分类路径,另一个是语言模型路径。 在NLP中,你会一直看到LM。 LM意味着语言模型。 分类路径将包含我们将用于创建情绪分析模型的信息。 语言模型路径将包含创建语言模型所需的信息。 所以他们有点不同。 有一点不同的是,当我们在分类路径中创建train.csv时,我们会删除标签为2的所有内容,因为标签2是“无人监督”而我们无法使用它。 +你会注意到一开始我们有两条不同的路径 [[25:51](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D25m51s)] 。 一个是分类路径,另一个是语言模型路径。在NLP中,你会一直看到LM。 LM意味着语言模型。 分类路径将包含我们将用于创建情绪分析模型的信息。语言模型路径将包含创建语言模型所需的信息。所以他们有点不同。有一点不同的是,当我们在分类路径中创建train.csv时,我们会删除标签为2的所有内容,因为标签2是“无监督的”,而我们无法使用它。 ![](../img/1_CdwPQjBC0mmDYXXRQh6xMA.png) @@ -193,27 +196,28 @@ NLP的基本路径是我们必须采用句子并将它们转换为数字,并 _(90000, 10000)_ ``` -第二个区别是标签 [[26:51](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D26m51s)] 。 对于分类路径,标签是实际标签,但对于语言模型,没有标签,所以我们只使用一堆零,这使得它更容易,因为我们可以使用一致的数据帧/ CSV格式。 +第二个区别是标签 [[26:51](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D26m51s)] 。 对于分类路径,标签是实际标签,但对于语言模型,没有标签,所以我们只使用一堆零,这使得它更容易,因为我们可以使用一致的dataframe/ CSV格式。 -现在是语言模型,我们可以创建自己的验证集,所以你现在可能已经遇到过, `sklearn.model_selection.train_test_split`这是一个非常简单的函数,可以抓取数据集并随机将其拆分为训练集和验证集根据你指定的比例。 在这种情况下,我们将分类训练和验证结合在一起,将其拆分10%,现在我们有90,000次训练,10,000次验证我们的语言模型。 这样我们的语言模型和分类器就会以标准格式获取数据。 +现在是语言模型,我们可以创建自己的验证集,所以你现在可能已经遇到过, `sklearn.model_selection.train_test_split`这是一个非常简单的函数,可以选中数据集并根据你指定的比例,随机将其拆分为训练集和验证集。在这种情况下,我们将分类训练和验证结合在一起,将其拆分10%,现在我们有90,000次训练,10,000次验证我们的语言模型。这样我们的语言模型和分类器就会以标准格式获取数据。 ``` - df_trn = pd.DataFrame({'text':trn_texts, 'labels': [0]*len(trn_texts)}, columns=col_names) df_val = pd.DataFrame({'text':val_texts, 'labels': [0]*len(val_texts)}, columns=col_names) + df_trn = pd.DataFrame({'text':trn_texts, 'labels': [0]*len(trn_texts)}, columns=col_names) + df_val = pd.DataFrame({'text':val_texts, 'labels': [0]*len(val_texts)}, columns=col_names) ``` ``` - df_trn.to_csv(LM_PATH/'train.csv', header= **False** , index= **False** ) df_val.to_csv(LM_PATH/'test.csv', header= **False** , index= **False** ) +df_trn.to_csv(LM_PATH/'train.csv', header= **False** , index= **False** ) df_val.to_csv(LM_PATH/'test.csv', header= **False** , index= **False** ) ``` #### 语言模型标记 [[28:03](https://youtu.be/h5Tz7gZT9Fo%3Ft%3D28m3s)] -接下来我们要做的就是分词。 分词意味着在这个阶段,对于文档(即电影评论),我们有一个很长的字符串,我们想把它变成一个标记列表,类似于单词列表但不完全。 例如, `don't`希望它是`do`而`n't` ,我们可能希望完全停止成为标记,等等。 分词是我们传递给一个名为spaCy的极好的库 - 部分非常棒,因为澳大利亚人写了它并且部分非常棒,因为它擅长它的功能。 我们在spaCy上添加了一些东西,但绝大部分工作都是由spaCy完成的。 +接下来我们要做的就是分词。 分词意味着在这个阶段,对于文档(即电影评论),我们有一个很长的字符串,我们想把它变成一个标记列表,类似于单词列表但不完全相同。 例如, `don't`希望它是`do`和`n't` ,我们可能希望完全停止成为标记,等等。 分词是我们传递给一个名为spaCy的极好的库 - 一部分是因为澳大利亚人完成了它并且非常棒,因为它擅长做它的应有的功能。 我们在spaCy上添加了一些东西,但绝大部分工作都是由spaCy完成的。 ``` chunksize=24000 ``` -在我们将它传递给spaCy之前,Jeremy编写了这个简单的修复功能,每次他查看不同的数据集(大约十几个建立这个)时,每个人都有不同的奇怪的东西需要被替换。 所以这是他到目前为止所提出的所有内容,希望这也会帮助你。 所有的实体都是未转义的html,我们会替换更多的东西。 看一下在你输入的文本上运行它的结果,并确保那里没有更多奇怪的标记。 +在我们将它传递给spaCy之前,Jeremy编写了这个简单的修复功能,每次他查看不同的数据集(大约十几个建立这个)时,每个数据集都有不同的奇怪的东西需要替换。 所以这是他到目前为止所提出的所有内容,希望这也会帮助你。 所有的实体都是未转义的html,我们还替换了很多东西。看一下在你输入的文本上运行它的结果,并确保那里没有任何奇怪的标记。 ``` re1 = re.compile(r' +') -- GitLab