Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
fastai-ml-dl-notes-zh
提交
25ddac15
F
fastai-ml-dl-notes-zh
项目概览
OpenDocCN
/
fastai-ml-dl-notes-zh
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
fastai-ml-dl-notes-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
25ddac15
编写于
11月 06, 2018
作者:
W
wizardforcel
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dl7 fix
上级
7c405d94
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
40 addition
and
42 deletion
+40
-42
zh/dl11.md
zh/dl11.md
+1
-1
zh/dl12.md
zh/dl12.md
+1
-1
zh/dl13.md
zh/dl13.md
+2
-2
zh/dl7.md
zh/dl7.md
+34
-36
zh/dl8.md
zh/dl8.md
+2
-2
未找到文件。
zh/dl11.md
浏览文件 @
25ddac15
...
...
@@ -331,7 +331,7 @@ pytext中没有fasttext Python库,但这是一个方便的技巧 [[35:03](http
#### 训练集和验证集 [[39:03](https://youtu.be/tY0n9OT5_nA%3Ft%3D39m3s)]
现在我们需要获取我们的英语和法语ID并获得训练集和验证集。 关于互联网上很多代码令人非常失望的事情之一就是他们没有遵循一些简单的最佳实践。 例如,如果你去PyTorch网站,他们有一个序列到序列翻译的例子部分。 他们的示例没有单独的验证集。 Jeremy根据他们的设置尝试了训练,并使用验证装置对其进行了测试,结果发现它大量过度。 所以这不仅仅是一个理论问题 - 实际的PyTorch repo具有序列翻译实例的实际官方序列,它不会检查过拟合和过拟合
[
[39:41
](
https://youtu.be/tY0n9OT5_nA%3Ft%3D39m41s
)
] 。 此外,它无法使用
迷你批次
,因此它实际上无法利用任何PyTorch的效率。 即使你在官方PyTorch回购中找到代码,也不要认为它有任何好处。 你会注意到的另一件事是,几乎所有其他序列模型Jeremy在PyTorch中在互联网上的任何地方找到的都清楚地复制了那个糟糕的PyTorch仓库,因为它们都有相同的变量名,它有相同的问题,它有同样的错误。
现在我们需要获取我们的英语和法语ID并获得训练集和验证集。 关于互联网上很多代码令人非常失望的事情之一就是他们没有遵循一些简单的最佳实践。 例如,如果你去PyTorch网站,他们有一个序列到序列翻译的例子部分。 他们的示例没有单独的验证集。 Jeremy根据他们的设置尝试了训练,并使用验证装置对其进行了测试,结果发现它大量过度。 所以这不仅仅是一个理论问题 - 实际的PyTorch repo具有序列翻译实例的实际官方序列,它不会检查过拟合和过拟合
[
[39:41
](
https://youtu.be/tY0n9OT5_nA%3Ft%3D39m41s
)
] 。 此外,它无法使用
小批量
,因此它实际上无法利用任何PyTorch的效率。 即使你在官方PyTorch回购中找到代码,也不要认为它有任何好处。 你会注意到的另一件事是,几乎所有其他序列模型Jeremy在PyTorch中在互联网上的任何地方找到的都清楚地复制了那个糟糕的PyTorch仓库,因为它们都有相同的变量名,它有相同的问题,它有同样的错误。
另一个例子是Jeremy发现的几乎每个PyTorch卷积神经网络都没有使用自适应汇集层
[
[40:27
](
https://youtu.be/tY0n9OT5_nA%3Ft%3D40m27s
)
] 。 换句话说,最后一层总是平均池(7,7)。 他们假设前一层是7乘7,如果你使用任何其他大小的输入,你会得到一个例外,因此几乎所有Jeremy所说的使用PyTorch的人认为CNN的基本限制是它们与输入相关联尺寸,自VGG以来一直没有。 因此,每当Jeremy抓住一个新模型并将其粘贴在fastai repo中时,他必须去搜索“pool”并在开始时添加“adaptive”,并用1替换7,现在它适用于任何大小的对象。 所以要小心。 它还处于早期阶段并且信不信由你,尽管你们大多数人在去年开始了深度学习之旅,但你们对许多重要的实践方面的了解远远超过绝大多数人在官方回购中出版和撰写文章。 因此,在阅读其他人的代码时,你需要比自己预期的更自信。 如果你发现自己认为“看起来很奇怪”,那不一定是你。
...
...
zh/dl12.md
浏览文件 @
25ddac15
...
...
@@ -664,7 +664,7 @@ data_loader = CreateDataLoader(opt)dataset = data_loader.load_data()data
1334
```
我们有一个数据加载器,所以我们可以将数据加载到它
[
[2:06:17
](
https://youtu.be/ondivPiwQho%3Ft%3D2h6m17s
)
] 。这将告诉我们其中有多少个
迷你批次
(这是PyTorch中数据加载器的长度)。
我们有一个数据加载器,所以我们可以将数据加载到它
[
[2:06:17
](
https://youtu.be/ondivPiwQho%3Ft%3D2h6m17s
)
] 。这将告诉我们其中有多少个
小批量
(这是PyTorch中数据加载器的长度)。
下一步是创建模型。同样的想法,我们有不同类型的模型,我们将做一个循环GAN。
...
...
zh/dl13.md
浏览文件 @
25ddac15
...
...
@@ -420,7 +420,7 @@ VGG网络是接收输入并将其粘贴到多个层中的东西,我将把它
m_vgg = nn.Sequential(*children(m_vgg)[:37])
```
我们将毫无特别地使用第37层VGG。 如果你打印出VGG网络(你只需键入
`m_vgg`
并将其打印出来),你就会看到这是中后期层。 所以我们可以抓住前37层并将其转换为顺序模型。 所以现在我们有一个VGG的子集将输出一些中间层激活,这就是模型将要发生的事情。 所以我们可以拍摄我们的实际鸟类图像,我们想要制作一个小批量的一个。 请记住,如果你使用
`None`
(也称为
`np.newaxis`
Numpy,则会在该点引入新的单位轴。 在这里,我想创建一个大小为1的轴,说这是一个尺寸为1的
迷你批次
。 所以就像我在这里做的那样切片(
`opt_img_v = V(opt_img[ **None** ], requires_grad= **True** )`
)以获得前面的一个单位轴。 然后我们把它变成一个变量,这个不需要更新,所以我们用
`VV`
说你不需要这个人的梯度。 这样就可以为我们提供目标激活。
我们将毫无特别地使用第37层VGG。 如果你打印出VGG网络(你只需键入
`m_vgg`
并将其打印出来),你就会看到这是中后期层。 所以我们可以抓住前37层并将其转换为顺序模型。 所以现在我们有一个VGG的子集将输出一些中间层激活,这就是模型将要发生的事情。 所以我们可以拍摄我们的实际鸟类图像,我们想要制作一个小批量的一个。 请记住,如果你使用
`None`
(也称为
`np.newaxis`
Numpy,则会在该点引入新的单位轴。 在这里,我想创建一个大小为1的轴,说这是一个尺寸为1的
小批量
。 所以就像我在这里做的那样切片(
`opt_img_v = V(opt_img[ **None** ], requires_grad= **True** )`
)以获得前面的一个单位轴。 然后我们把它变成一个变量,这个不需要更新,所以我们用
`VV`
说你不需要这个人的梯度。 这样就可以为我们提供目标激活。
*
我们采取了我们的鸟形象
*
把它变成一个变量
...
...
@@ -455,7 +455,7 @@ VGG网络是接收输入并将其粘贴到多个层中的东西,我将把它
换句话说,它有多弯曲? 基本的想法是,如果你知道它不是很弯曲,那么你可能会跳得更远。 但如果它很弯曲那么你可能不想跳得那么远。 因此,在更高的维度中,梯度称为雅可比行列式,而二阶导数称为Hessian。 你会一直看到这些词,但这就是他们的意思。 同样,数学家也必须为所有事物发明你的话语。 他们就像深度学习研究人员 - 可能更加傲慢。 使用BFGS,我们将尝试计算二阶导数,然后我们将使用它来确定要走的路线和走多远 - 所以它不再是未知的疯狂跳跃。
现在的问题是,实际计算Hessian(二阶导数)几乎肯定不是一个好主意
[
[1:24:15
](
https://youtu.be/xXXiC4YRGrQ%3Ft%3D1h24m15s
)
] 。 因为在你要去的每个可能的方向上,对于你测量梯度的每个方向,你还必须在每个方向上计算Hessian。 它变得非常大。 因此,我们不是实际计算它,而是采取一些步骤,我们基本上看看每个步骤中梯度的变化程度,并使用这个小函数近似Hessian。 再说一遍,这似乎是一件非常明显的事情,但是直到很久以后有人出人意料地没有人想到它。 跟踪你所采取的每一步都需要大量的记忆,所以,不要跟踪你采取的每一步 - 只需保留最后十或二十。 而那里的第二位,就是L到LBFGS。 因此,有限记忆BFGS意味着保留最后10或20个梯度,使用它来近似曲率,然后使用梯度曲率来估计行进方向和距离。 出于多种原因,这在深度学习中通常不是一个好主意。 显然比做Adam或SGD更新要做的工作要多得多,并且它也使用更多的内存 - 当你有一个GPU来存储它并且有数亿个权重时,内存就更成了一个大问题。 但更重要的是,
迷你批次
是非常颠簸的,所以弄清楚曲率来确定行程的确切距离正如我们所说的那样(是的,澳大利亚和英国的表达 - 你明白了)。 有趣的是,事实证明,实际上使用二阶导数信息就像是鞍点的磁铁。 所以有一些有趣的理论结果,基本上说如果你使用二阶导数信息,它实际上会将你发送到函数的令人讨厌的平坦区域。 所以通常不是一个好主意。
现在的问题是,实际计算Hessian(二阶导数)几乎肯定不是一个好主意
[
[1:24:15
](
https://youtu.be/xXXiC4YRGrQ%3Ft%3D1h24m15s
)
] 。 因为在你要去的每个可能的方向上,对于你测量梯度的每个方向,你还必须在每个方向上计算Hessian。 它变得非常大。 因此,我们不是实际计算它,而是采取一些步骤,我们基本上看看每个步骤中梯度的变化程度,并使用这个小函数近似Hessian。 再说一遍,这似乎是一件非常明显的事情,但是直到很久以后有人出人意料地没有人想到它。 跟踪你所采取的每一步都需要大量的记忆,所以,不要跟踪你采取的每一步 - 只需保留最后十或二十。 而那里的第二位,就是L到LBFGS。 因此,有限记忆BFGS意味着保留最后10或20个梯度,使用它来近似曲率,然后使用梯度曲率来估计行进方向和距离。 出于多种原因,这在深度学习中通常不是一个好主意。 显然比做Adam或SGD更新要做的工作要多得多,并且它也使用更多的内存 - 当你有一个GPU来存储它并且有数亿个权重时,内存就更成了一个大问题。 但更重要的是,
小批量
是非常颠簸的,所以弄清楚曲率来确定行程的确切距离正如我们所说的那样(是的,澳大利亚和英国的表达 - 你明白了)。 有趣的是,事实证明,实际上使用二阶导数信息就像是鞍点的磁铁。 所以有一些有趣的理论结果,基本上说如果你使用二阶导数信息,它实际上会将你发送到函数的令人讨厌的平坦区域。 所以通常不是一个好主意。
```
**def** actn_loss(x): **return** F.mse_loss(m_vgg(x), targ_v)*1000
...
...
zh/dl7.md
浏览文件 @
25ddac15
...
...
@@ -10,22 +10,20 @@
课程的第 2 部分:
*
重点是生成建模,这意味着预测“很多事情” - 例如,
创建一个句子,如在神经翻译,图像字幕或问题回答中创建图像,如风格转移,超分辨率,分割等
。
*
重点是生成建模,这意味着预测“很多事情” - 例如,
在在神经翻译,图像字幕,或问题回答中创建一个句子,在风格转移,超分辨率,分割中创建图像
。
*
不是最好的做法,而是从最近可能没有经过全面测试的论文中获得更多的推测。
####
审查Char3Model
[[02:49](https://youtu.be/H3g26EVADgY%3Ft%3D2m49s)]
####
回顾 Char3Model
[[02:49](https://youtu.be/H3g26EVADgY%3Ft%3D2m49s)]
提醒:RNN
没有任何不同或异常或神奇 - 只是一个标准的完
全连接网络。
提醒:RNN
没有任何不同或异常或神奇 - 只是一个标准的
全连接网络。
![](
../img/1_9XXQ3J7G3rD92tFkusi4bA.png
)
标准的全连接网络
*
箭头表示一个或多个层操作 - 一般来说是线性的,后跟非线性函数,在这种情况下,矩阵乘法后跟
`relu`
或
`tanh`
*
相同颜色的箭头表示使用的完全相同的权重矩阵。
*
与之前的一个细微差别是第二和第三层有输入。 我们尝试了两种方法 - 将这些输入连接
并
添加到当前激活中。
*
与之前的一个细微差别是第二和第三层有输入。 我们尝试了两种方法 - 将这些输入连接
和
添加到当前激活中。
```
class Char3Model(nn.Module):
...
...
@@ -55,8 +53,8 @@ class Char3Model(nn.Module):
return F.log_softmax(self.l_out(h))
```
*
通过使用
`nn.Linear`
我们可以
免费
获得权重矩阵和偏置向量。
*
为了处理第一个椭圆没有橙色箭头的事实,我们
发明
了一个空矩阵
*
通过使用
`nn.Linear`
我们可以获得权重矩阵和偏置向量。
*
为了处理第一个椭圆没有橙色箭头的事实,我们
创建
了一个空矩阵
```
class CharLoopModel(nn.Module):
...
...
@@ -97,18 +95,18 @@ class CharRnn(nn.Module):
return F.log_softmax(self.l_out(outp[-1]), dim=-1)
```
*
PyTorch
版本
`nn.RNN`
将创建循环并跟踪
`h`
跟踪
。
*
我们使用白色
部分来预测绿色字符 - 这看起来很浪费,因为下一部分主要与当前部分
重叠。
*
PyTorch
版本
`nn.RNN`
将创建循环并跟踪
`h`
。
*
我们使用白色
片段来预测绿色字符 - 这看起来很浪费,因为下个片段的大部分与当前片段
重叠。
![](
../img/1_4v68iwTS32RHplB8c-egmg.png
)
*
然后,我们尝试将其拆分为多输出模型中的非重叠
部分
:
*
然后,我们尝试将其拆分为多输出模型中的非重叠
片段
:
![](
../img/1_5LY1Sdql1_VLHDfdd2e8lw.png
)
*
在这种方法中,我们在处理每个
部分后开始抛弃我们的
`h`
激活并开始一个新的激活。 为了使用下一节中的第一个字符预测第二个字符,它没有任何内容可以继续,而是默认激活。 我们不要扔掉
。
*
在这种方法中,我们在处理每个
片段后扔掉我们的
`h`
激活并开始一个新的激活。 为了使用下一片段中的第一个字符预测第二个字符,它没有任何内容可以继续,而是默认激活。 我们不要扔掉
`h`
。
#### 有状态的
RNN
[[08:52](https://youtu.be/H3g26EVADgY%3Ft%3D8m52s)]
#### 有状态的
RNN
[[08:52](https://youtu.be/H3g26EVADgY%3Ft%3D8m52s)]
```
class CharSeqStatefulRnn(nn.Module):
...
...
@@ -131,44 +129,44 @@ class CharSeqStatefulRnn(nn.Module):
```
*
构造函数中的另一行。
`self.init_hidden(bs)`
将
`self.h`
设置为一堆零。
*
**Wrinkle
#1**
[
[10:51
](
https://youtu.be/H3g26EVADgY%3Ft%3D10m51s
)
] - 如果我们只是做
`self.h = h`
,并且我们训练了一个长度为一百万字符的文档,那么RNN的展开版本的大小有一百万层(省略号) 。 一百万层完全连接的网络将占用大量内存,因为为了实现链规则,我们必须增加一百万个层,同时记住每批100
万个梯度。
*
为避免这种情况,我们会不时地忘记它的历史。 我们仍然可以记住状态(隐藏矩阵中的值)而不记得我们如何到达那里的一切。
*
**Wrinkle
#1**
[
[10:51
](
https://youtu.be/H3g26EVADgY%3Ft%3D10m51s
)
] - 如果我们只是执行
`self.h = h`
,并且我们在长度为一百万字符的文档上训练,那么 RNN 的展开版本的大小有一百万层(省略号) 。 一百万层全连接网络将占用大量内存,因为为了实现链式规则,我们必须增加一百万个层,同时记住每批的 100
万个梯度。
*
为避免这种情况,我们会不时地忘记它的历史。 我们仍然可以记住状态(隐藏矩阵中的值)而不记得我们如何到达那里的一切
事情
。
```
def repackage_var(h):
return Variable(h.data) if type(h) == Variable else tuple(repackage_var(v) for v in h)
```
*
从
`Variable
`
`h`
取出张量(记住,张量本身没有任何历史概念),并从中创建一个新的
`Variable`
。
新变量具有相同的值但没有操作历史记录,因此当它尝试反向传播时,它将停在那里。
*
`forward`
将处理
8个字符,然后返回传播通过8个层,跟踪隐藏状态中的值,但它将丢弃其操作历史。 这称为
**反向支撑通过时间(bptt)**
。
*
换句话说,在
`for`
循环之后,只需丢弃操作历史并重新开始。 所以我们保持隐藏
的状态,但我们没有保持隐藏的
状态历史。
*
不
通过太多层反向传播的另一个好理由是,如果你有任何类型的梯度不稳定性(例如梯度爆炸或梯度消失),你拥有的层数越多,网络训练越难(速度越慢,弹性越小)
。
*
另一方面,较长的
`bptt`
意味着你可以显式捕获更长的
内存
和更多的状态。
*
**Wrinkle
#2**
[
[16:00
](
https://youtu.be/H3g26EVADgY%3Ft%3D16m
)
] - 如何创建迷你批次。 我们不希望一次处理一个部分,而是一次并行处理一个部分
。
*
当我们第一次开始关注
TorchText时,我们谈到了它如何创建这些迷你批次
。
*
Jeremy
说我们整整一份长文件,包括Nietzsche的整个作品或所有IMDB评论连在一起,我们把它分成64个相同大小的块(不是64块大小
的块)。
*
从
`Variable
h`
取出张量(记住,张量本身没有任何历史概念),并从中创建一个新的
`Variable`
。
新变量具有相同的值但没有操作历史记录,因此当它尝试反向传播时,它将停在那里。
*
`forward`
将处理
8 个字符,然后在 8 个层中反向传播,跟踪隐藏状态中的值,但它将丢弃其操作历史。 这称为
**沿时间的反向传播(bptt)**
。
*
换句话说,在
`for`
循环之后,只需丢弃操作历史并重新开始。 所以我们保持隐藏
状态,但我们没有保持隐藏
状态历史。
*
不
在太多层中反向传播的另一个好理由是,如果你有任何类型的梯度不稳定性(例如梯度爆炸或梯度消失),你拥有的层数越多,网络训练越难(速度更慢,弹性更小)
。
*
另一方面,较长的
`bptt`
意味着你可以显式捕获更长的
记忆
和更多的状态。
*
**Wrinkle
#2**
[
[16:00
](
https://youtu.be/H3g26EVADgY%3Ft%3D16m
)
] - 如何创建小批量。 我们不希望一次处理一个片段,而是一次并行处理一堆片段
。
*
当我们第一次开始关注
TorchText 时,我们谈到了它如何创建这些小批量
。
*
Jeremy
说我们选取整个长文档,包括 Nietzsche 的整个作品,或连在一起的所有 IMDB 评论,我们把它分成 64 个相同大小的块(不是大小为 64
的块)。
![](
../img/1_YOUoCz-p7semcNuDFZqp_w.png
)
*
对于长度为
6400万个字符的文档,每个“块”将是100万个字符。 我们将它们堆叠在一起,现在用
`bptt`
分割它们 - 1个mini-bach由64
个
`bptt`
矩阵组成。
*
第二个块(第
1,000,001个字符)的第一个字符可能位于句子的中间。 但它没关系,因为它每百万个字符
只发生一次。
*
对于长度为
6400 万个字符的文档,每个“块”将是 100 万个字符。 我们将它们堆叠在一起,现在用
`bptt`
分割它们 - 1 个小批量由 64
个
`bptt`
矩阵组成。
*
第二个块(第
1,000,001 个字符)的第一个字符可能位于句子的中间。 但它没关系,因为对于每百万个字符,它
只发生一次。
#### 问题:
此类数据集的数据增强?
[[20:34](https://youtu.be/H3g26EVADgY%3Ft%3D20m34s)]
#### 问题:
用于此类数据集的数据增强?
[[20:34](https://youtu.be/H3g26EVADgY%3Ft%3D20m34s)]
没有已知的好方法。 有人最近通过数据增强赢得了
Kaggle比赛,随机插入了不同行的部分 - 这样的东西可能会有用。 但是,最近没有任何最新的NLP
论文正在进行这种数据增强。
没有已知的好方法。 有人最近通过数据增强赢得了
Kaggle 比赛,随机插入了不同行的部分 - 这样的东西可能会有用。 但是,最近没有任何最新的 NLP
论文正在进行这种数据增强。
#### 问题:我们如何选择
bptt的大小?
[[21:36](https://youtu.be/H3g26EVADgY%3Ft%3D21m36s)]
#### 问题:我们如何选择
`bptt`的大小?
[[21:36](https://youtu.be/H3g26EVADgY%3Ft%3D21m36s)]
有几件事要考虑:
*
首先,
迷你批量矩阵的大小为
`bptt`
(块数#),因此你的GPU RAM必须能够通过嵌入矩阵拟合。 因此,如果你得到CUDA内存不足
错误,你需要减少其中一个。
*
如果你的训练不稳定(例如你的
`bptt`
突然
向NaN射击),那么你可以尝试减少你的
`bptt`
因为你有更少的层来
梯度爆炸。
*
如果它太慢
[
[22:44
](
https://youtu.be/H3g26EVADgY%3Ft%3D22m44s
)
] ,请尝试减少你的
`bptt`
因为它会一次执行其中一个步骤。
`for`
循环无法并行化(对于当前版本)。 最近有一种称为
QRNN(准递归神经网络)的东西,它将它并行化,我们希望在第2
部分中介绍。
*
首先,
小批量矩阵的大小为
`bptt`
(块数),因此你的 GPU RAM 必须能够把它放进嵌入矩阵。 因此,如果你得到 CUDA 内存不足的
错误,你需要减少其中一个。
*
如果你的训练不稳定(例如你的
`bptt`
突然
变成
`NaN`
),那么你可以尝试减少你的
`bptt`
,因为你有更少的层来避免
梯度爆炸。
*
如果它太慢
[
[22:44
](
https://youtu.be/H3g26EVADgY%3Ft%3D22m44s
)
] ,请尝试减少你的
`bptt`
因为它会一次执行其中一个步骤。
`for`
循环无法并行化(对于当前版本)。 最近有一种称为
QRNN(准循环神经网络)的东西,它将它并行化,我们希望在第 2
部分中介绍。
*
所以选择满足所有这些的最高数字。
#### 有状态的
RNN和TorchText
[[23:23](https://youtu.be/H3g26EVADgY%3Ft%3D23m23s)]
#### 有状态的
RNN 和 TorchText
[[23:23](https://youtu.be/H3g26EVADgY%3Ft%3D23m23s)]
当使用希望数据为特定格式的现有
API时,你可以更改数据以适合该格式,也可以编写自己的数据集子类来处理数据已经存在的格式。要么很好,要么在这种情况下,我们将以TorchText格式提供我们的数据。 围绕TorchText的Fast.ai包装器已经具有可以具有训练路径和验证路径的东西,并且每个路径中的一个或多个文本文件包含为你的语言模型连接在一起的一堆文本
。
当使用希望数据为特定格式的现有
API 时,你可以更改数据来适合该格式,也可以编写自己的数据集子类来处理数据已有的格式。两个都很好,但在这种情况下,我们将以 TorchText 格式提供我们的数据。TorchText 的 Fast.ai 包装器,已经有了一些东西,你可以通过它获取训练路径和验证路径,并且每个路径中的一个或多个文本文件包含一堆文本,它们为你的语言模型连接在一起
。
```
from torchtext import vocab, data
...
...
@@ -190,9 +188,9 @@ models/ nietzsche.txt trn/ val/
trn.txt
```
*
制作了
Nietzsche文件的副本,粘贴到训练和验证目录中。 然后从训练集中删除了最后20%的行,并删除了验证集
[
[25:15
](
https://youtu.be/H3g26EVADgY%3Ft%3D25m15s
)
] 中除最后20%
之外的所有行。
*
这样做的另一个好处是,拥有一个
不是随机混乱的文本行集的验证集
似乎更为现实,但它完全是语料库的一部分。
*
在
进行
语言模型时,实际上并不需要单独的文件。 你可以拥有多个文件,但无论如何它们只是连在一起。
*
制作了
Nietzsche 文件的副本,粘贴到训练和验证目录中。 然后从训练集中删除了最后 20% 的行,并删除了验证集
[
[25:15
](
https://youtu.be/H3g26EVADgY%3Ft%3D25m15s
)
] 中除最后 20%
之外的所有行。
*
这样做的另一个好处是,拥有一个
验证集,它不是随机混乱的文本行的集合,
似乎更为现实,但它完全是语料库的一部分。
*
在
处理
语言模型时,实际上并不需要单独的文件。 你可以拥有多个文件,但无论如何它们只是连在一起。
```
TEXT = data.Field(lower=True, tokenize=list)
...
...
zh/dl8.md
浏览文件 @
25ddac15
...
...
@@ -517,7 +517,7 @@ Matplotlib之所以如此命名是因为它最初是Matlab绘图库的克隆。
#### 数据加载器 [[1:33:04](https://youtu.be/Z0ssNAbe81M%3Ft%3D1h33m4s)]
你已经知道在模型数据对象内部,我们有很多东西,包括训练数据加载器和训练数据集。 关于数据加载器的主要知识是它是一个迭代器,每次你从中获取下一个东西的迭代时,你得到一个迷你批处理。 你获得的
迷你
批量是你要求的任何大小,默认情况下批量大小为64.在Python中,你从迭代器中获取下一个东西的方式是下`
next(md.trn_dl)
`但你不能只做那。 你不能说这是因为你需要说“现在开始一个新迭代”。 通常,不仅在PyTorch中,而且对于任何Python迭代器,你都需要说“请从序列的开始处开始”。 你这么说就是使用`
iter(md.trn_dl)
`来获取`
iter(md.trn_dl)
`一个迭代器 - 特别是我们稍后会学到的,这意味着这个类必须定义一个`
__iter__
`方法,它返回一些不同的对象,然后有一个`
__next__
`方法。
你已经知道在模型数据对象内部,我们有很多东西,包括训练数据加载器和训练数据集。 关于数据加载器的主要知识是它是一个迭代器,每次你从中获取下一个东西的迭代时,你得到一个迷你批处理。 你获得的
小
批量是你要求的任何大小,默认情况下批量大小为64.在Python中,你从迭代器中获取下一个东西的方式是下`
next(md.trn_dl)
`但你不能只做那。 你不能说这是因为你需要说“现在开始一个新迭代”。 通常,不仅在PyTorch中,而且对于任何Python迭代器,你都需要说“请从序列的开始处开始”。 你这么说就是使用`
iter(md.trn_dl)
`来获取`
iter(md.trn_dl)
`一个迭代器 - 特别是我们稍后会学到的,这意味着这个类必须定义一个`
__iter__
`方法,它返回一些不同的对象,然后有一个`
__next__
`方法。
如果你想只抓一个批处理,你就是这样做的( `
x
` :自变量, `
y
` :因变量):
...
...
@@ -547,7 +547,7 @@ Matplotlib之所以如此命名是因为它最初是Matlab绘图库的克隆。
![](../img/1_oZe5esLqorSwfDyN9ld3Rw.png)
我们故意删除前几个点和最后几个点 [[1:38:54](https://youtu.be/Z0ssNAbe81M%3Ft%3D1h38m54s)] ,因为通常最后几个点向无限远射高,你看不到任何东西,所以这通常是一个好主意。 但是当你的
迷你批次
非常少时,这不是一个好主意。 当你的LR查找器图形如上所示时,你可以在每一端要求更多点(你也可以使批量大小非常小):
我们故意删除前几个点和最后几个点 [[1:38:54](https://youtu.be/Z0ssNAbe81M%3Ft%3D1h38m54s)] ,因为通常最后几个点向无限远射高,你看不到任何东西,所以这通常是一个好主意。 但是当你的
小批量
非常少时,这不是一个好主意。 当你的LR查找器图形如上所示时,你可以在每一端要求更多点(你也可以使批量大小非常小):
```
learn.sched.plot(n_skip=5, n_skip_end=1)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录