fast.ai 深度学习笔记(五)(3)

简介: fast.ai 深度学习笔记(五)

fast.ai 深度学习笔记(五)(2)https://developer.aliyun.com/article/1482704

分类器

trn_clas = np.load(CLAS_PATH/'tmp'/'trn_ids.npy')
val_clas = np.load(CLAS_PATH/'tmp'/'val_ids.npy')
trn_labels = np.squeeze(np.load(CLAS_PATH/'tmp'/'trn_labels.npy'))
val_labels = np.squeeze(np.load(CLAS_PATH/'tmp'/'val_labels.npy'))

模型超参数的构建是相同的。我们可以更改丢失率。选择一个尽可能大的批量大小,以防内存不足。

bptt,em_sz,nh,nl = 70,400,1150,3
vs = len(itos)
opt_fn = partial(optim.Adam, betas=(0.8, 0.99))
bs = 48
min_lbl = trn_labels.min()
trn_labels -= min_lbl
val_labels -= min_lbl
c=int(trn_labels.max())+1

TextDataset

这一部分很有趣。这里有一些有趣的东西。

trn_ds = TextDataset(trn_clas, trn_labels)
val_ds = TextDataset(val_clas, val_labels)

这里的基本思想是,对于分类器,我们确实希望查看一个文档。这个文档是积极的还是消极的?所以我们确实希望打乱文档。但是这些文档的长度不同,所以如果我们把它们全部放入一个批次中(这是 fastai 为您做的一个方便的事情)- 您可以将不同长度的东西放入一个批次中,它会自动填充它们,所以您不必担心这个问题。但是如果它们的长度差异很大,那么您将浪费大量的计算时间。如果有一件事是 2000 个字长,而其他所有东西都是 50 个字长,那意味着您最终会得到一个 2000 宽的张量。这相当恼人。所以詹姆斯·布拉德伯里是斯蒂芬·梅里蒂的同事之一,也是提出 torchtext 的人,他提出了一个聪明的想法,即“让我们按长度对数据集进行排序”。因此,使得列表中的前几个东西总体上比最后的东西短,但也有一点随机性。

这是 Jeremy 如何实现的。我们需要的第一件事是一个数据集。因此,我们有一个传递文档及其标签的数据集。这里有一个继承自 Dataset 的 TextDataSet,下面还显示了 PyTorch 中的 Dataset:


实际上,Dataset 什么也不做。它说如果您没有__getitem__,您将会收到一个错误。对于__len__也是如此。因此,这是一个抽象类。对于 TextDataset,我们将传入我们的 x 和 y,__getitem__将获取 x 和 y,并将它们返回-这不能更简单。可选地,1.他们可以颠倒它,2.在末尾添加一个流的结束,3.在开头添加一个流的开始。但我们没有做这些事情,所以我们实际上所做的就是将 x 和 y 放在一起,__getitem__将它们作为元组返回。长度是 x 的长度。这就是 Dataset 的全部内容-一个具有长度的东西,您可以对其进行索引。

将其转换为 DataLoader

trn_samp = SortishSampler(
    trn_clas, 
    key=lambda x: len(trn_clas[x]), 
    bs=bs//2
)
val_samp = SortSampler(val_clas, key=lambda x: len(val_clas[x]))
trn_dl = DataLoader(
    trn_ds, bs//2, 
    transpose=True, 
    num_workers=1,
    pad_idx=1, 
    sampler=trn_samp
)
val_dl = DataLoader(
    val_ds, bs, 
    transpose=True, 
    num_workers=1, 
    pad_idx=1, 
    sampler=val_samp
)
md = ModelData(PATH, trn_dl, val_dl)

要将其转换为 DataLoader,您只需将数据集传递给 DataLoader 构造函数,现在它将每次给您一个批次。通常您可以说 shuffle 等于 true 或 shuffle 等于 false,它会决定是否为您随机化。但在这种情况下,我们实际上将传递一个 sampler 参数,sampler 是一个我们将定义的类,告诉数据加载器如何进行洗牌。

  • 对于验证集,我们将定义一个实际上只是排序的东西。它只是确定性地对其进行排序,以便所有最短的文档将在开头,所有最长的文档将在末尾,这将最小化填充的数量。
  • 对于训练采样器,我们将创建一个称为 sort-ish 采样器的东西,它也进行排序(ish!)


PyTorch 的一个伟大之处在于,他们为数据加载器提出了一个 API 的想法,我们可以通过其中的新类来使其以不同的方式运行。SortSampler 是一个具有数据源长度的长度和一个迭代器的东西,迭代器只是一个按长度排序的数据源的迭代器(作为 key 传入)。对于 SortishSampler,它基本上做了同样的事情,稍微有些随机性。这只是 PyTorch 中 Jeremy 发现的另一个美丽设计。他可以采用詹姆斯·布拉德伯里的想法,他围绕这个想法写了一整套新的类,并且可以在 PyTorch 内部使用内置的钩子。您会注意到数据加载器实际上不是 PyTorch 的数据加载器-它实际上是 fastai 的数据加载器。但它基本上几乎完全抄袭了 PyTorch,但在某些方面进行了定制,以使其更快,主要是使用多线程而不是多处理。

问题:预训练的 LSTM 深度和bptt需要与我们正在训练的新模型匹配吗[1:39:00]?不,bptt根本不需要匹配。这就像我们一次看多少东西。这与架构无关。

现在我们可以调用我们之前看到的get_rnn_classifier函数[1:39:16]。它将创建几乎完全相同的编码器,我们将传入与之前相同的架构细节。但这次,我们添加的头部有一些额外的功能。其中一个是你可以添加多个隐藏层。在layers=[em_sz*3, 50, c]中:

  • em_sz * 3:这是我头部(即分类器部分)的输入。
  • 50:这是第一层的输出
  • c:这是第二层的输出

你可以添加任意数量的层。所以你基本上可以在最后创建一个小型多层神经网络分类器。同样,对于drops=[dps[4], 0.1],这些是在每个层之后要进行的丢弃。

# part 1
dps = np.array([0.4, 0.5, 0.05, 0.3, 0.1])
dps = np.array([0.4,0.5,0.05,0.3,0.4])*0.5
m = get_rnn_classifer(
    bptt, 20*70, c, vs, 
    emb_sz=em_sz, 
    n_hid=nh, 
    n_layers=nl, 
    pad_token=1,
    layers=[em_sz*3, 50, c], 
    drops=[dps[4], 0.1],
    dropouti=dps[0], 
    wdrop=dps[1],        
    dropoute=dps[2], 
    dropouth=dps[3]
)
opt_fn = partial(optim.Adam, betas=(0.7, 0.99))

我们将像以前一样使用 RNN_Learner。

learn = RNN_Learner(md, TextModel(to_gpu(m)), opt_fn=opt_fn)
learn.reg_fn = partial(seq2seq_reg, alpha=2, beta=1)
learn.clip=25.
learn.metrics = [accuracy]

我们将为不同层使用判别学习率[1:40:20]。

lr=3e-3
lrm = 2.6
lrs = np.array([lr/(lrm**4), lr/(lrm**3), lr/(lrm**2), lr/lrm, lr])
lrs=np.array([1e-4,1e-4,1e-4,1e-3,1e-2])

你可以尝试使用权重衰减或不使用。Jeremy 已经在尝试一些东西。

wd = 1e-7
wd = 0
learn.load_encoder('lm2_enc')

我们开始只训练最后一层,得到 92.9%的准确率:

learn.freeze_to(-1)
learn.lr_find(lrs/1000)
learn.sched.plot()
learn.fit(lrs, 1, wds=wd, cycle_len=1, use_clr=(8,3))
'''
epoch      trn_loss   val_loss   accuracy                      
    0      0.365457   0.185553   0.928719
[0.18555279, 0.9287188090884525]
'''
learn.save('clas_0')
learn.load('clas_0')

然后我们再解冻一层,得到 93.3%的准确率:

learn.freeze_to(-2)
learn.fit(lrs, 1, wds=wd, cycle_len=1, use_clr=(8,3))
'''
epoch      trn_loss   val_loss   accuracy                      
    0      0.340473   0.17319    0.933125
[0.17319041, 0.9331253991245995]
'''
learn.save('clas_1')
learn.load('clas_1')
learn.unfreeze()
learn.fit(lrs, 1, wds=wd, cycle_len=14, use_clr=(32,10))
'''
epoch      trn_loss   val_loss   accuracy                      
    0      0.337347   0.186812   0.930782  
    1      0.284065   0.318038   0.932062                      
    2      0.246721   0.156018   0.941747                      
    3      0.252745   0.157223   0.944106                      
    4      0.24023    0.159444   0.945393                      
    5      0.210046   0.202856   0.942858                      
    6      0.212139   0.149009   0.943746                      
    7      0.21163    0.186739   0.946553                      
    8      0.186233   0.1508     0.945218                      
    9      0.176225   0.150472   0.947985                      
    10     0.198024   0.146215   0.948345                      
    11     0.20324    0.189206   0.948145                      
    12     0.165159   0.151402   0.947745                      
    13     0.165997   0.146615   0.947905
[0.14661488, 0.9479046703071374]
'''
learn.sched.plot_loss()
learn.save('clas_2')

然后我们微调整个模型[1:40:47]。这是在我们的论文出现之前使用预训练模型的主要尝试:

在翻译中学到:上下文化的词向量

他们所做的是他们使用了一个预训练的翻译模型,但他们没有微调整个模型。他们只是取出了翻译模型的激活,当他们尝试 IMDb 时,他们得到了 91.8% —— 而我们只是微调了一个层就轻松超过了这个结果。他们不是最先进的,最先进的是 94.1%,而我们在微调整个模型 3 个 epochs 后达到了 94.8%,这显然是一个巨大的差异,因为从错误率来看,这已经从 5.9%下降到了 4.6%。一个简单的小技巧是回到这个笔记本的开头,颠倒所有文档的顺序,然后重新运行整个过程。当你到达fwd_wt_103这部分时,用bwd替换fwd,即将 forward 替换为 backward。这是一个向后的英语语言模型,学习如何向后阅读英语。因此,如果你重新做这整个过程,将所有文档倒置,并将其更改为向后,你现在有了第二个分类器,根据反向文档的情感将事物分类为正面或负面。然后,你可以取这两个预测的平均值,基本上你就有了一个双向模型(你分别训练了每个部分),这将使你达到 95.4%的准确率。所以我们基本上将它从 5.9%降低到了 4.6%。这种最先进技术的 20%变化几乎是闻所未闻的。这种情况并不经常发生。所以你可以看到使用迁移学习的这个想法,它是非常强大的,每个新领域都认为自己的领域太特殊,无法做到。所以这对我们所有人来说都是一个巨大的机会。

文本分类的通用语言模型微调[1:44:02]


所以我们把这个变成了一篇论文,当我说“我们”时,是和这个家伙 Sebastian Ruder 一起做的。现在你可能记得他的名字,因为在第 5 课时,我告诉过你我实际上和 Sebastian 分享了第 4 课,因为我认为他是一个很棒的研究者,我认为他可能会喜欢。我根本不认识他。令我惊讶的是,他实际上看了这个视频。他看了整个视频并说:

Sebastian:“这实际上相当棒!我们应该把这变成一篇论文。”

Jeremy:“我不写论文。我不关心论文,对论文不感兴趣——那听起来真的很无聊”

Sebastian:“好的,我替你写论文。”

Jeremy:“你现在真的不能写关于这个的论文,因为你必须做研究来将其与其他事物进行比较(称为消融研究),看看哪部分实际起作用。这里没有严谨性,我只是把我脑子里想到的一切都放进去,然后把它们全部放在一起,结果竟然奏效了”

Sebastian:“好的,如果我写所有的论文并做所有你的消融研究,那我们可以写论文吗?”

Jeremy:“嗯,这就像一个我还没有记录的整个库,我现在还不会记录,你也不知道它是如何工作的”

Sebastian:“好的,如果我写了论文,做了消融研究,从头开始弄清楚代码的工作原理而不打扰你,那我们可以写论文吗?”

Jeremy:“嗯……是的,如果你做了所有这些事情,那我们可以写论文。好吧!”

然后两天后,他回来说“好的,我已经起草了论文。” 所以,我分享这个故事是想说,如果你是爱尔兰的某个学生,想做好工作,不要让任何人阻止你。我至少没有鼓励他。但最后,他说“我想做这项工作,我认为会很好,我会弄清楚的”,他写了一篇很棒的论文。他做了消融研究,弄清楚了 fastai 的工作原理,现在我们计划一起写另一篇论文。你必须小心,因为有时我会收到陌生人的消息,说“我有很多好主意,我们可以喝咖啡吗?”——“我不想……我随时可以在办公室喝咖啡,谢谢”。但是,说“嘿,我采纳了你的想法,写了一篇论文,做了一堆实验,弄清楚了你的代码如何工作,并为其添加了文档——我们应该提交到会议上吗?”就很不一样了。你明白我的意思吗?没有什么能阻止你做出惊人的工作,如果你做出了有助于他人的惊人工作,比如这种情况,我很高兴我们有了一篇论文。我并不特别关心论文,但我认为这些想法现在有了这样严谨的研究很酷。

让我展示一下他做了什么。

他拿走了我所有的代码,所以我已经做了所有的 fastai.text,正如你所看到的,它让我们能够处理大型语料库。Sebastian 读书很多,他说“这里有一篇 Yann LeCun 和一些人刚刚发表的论文,他们尝试了很多分类数据集,所以我打算在所有这些数据集上运行你的代码。” 所以这些数据集是:


其中一些文档有成千上万的文件,比我尝试的要大得多——但我认为它应该可以工作。

在我们进行下去的过程中,他有一些好主意,所以你应该确保阅读这篇论文。他说“嗯,你在课程中称之为差异学习率的东西,差异有点意思。也许我们应该重新命名它”,所以我们重新命名了。现在它被称为区分性学习率。所以我们在第一部分学到的这个想法,即对不同层使用不同的学习率,经过一些文献研究,似乎以前没有做过,所以现在正式成为一个事情——区分性学习率。这是我们在第一课中学到的东西,但现在它有了一个带有希腊字母和一切的方程式:


当你看到一个带有希腊字母的方程式时,并不一定意味着它比我们在第一课中做的任何事情更复杂,因为这个并不复杂。

再次,像逐层解冻一样的想法,似乎以前从未做过,所以现在是一个事情,它有一个非常聪明的名字“逐步解冻”。


倾斜三角形学习率

然后,如约,我们将看一下倾斜三角形学习率。这实际上不是我的想法。Leslie Smith,你们现在都知道的我最喜欢的研究人员之一,前段时间给我发了封邮件说:“我对循环学习率已经厌倦了。我不再这样做了。我现在做一个稍微不同的版本,其中有一个快速上升的周期,然后慢慢下降。我经常发现这样效果更好。”我试着回顾我所有的旧数据集,对所有数据集都效果更好——我尝试过的每一个。这就是学习率的样子。你可以通过在fit中添加use_clr=来在 fastai 中使用它。第一个数字是最高学习率和最低学习率之间的比率,因此初始学习率是峰值的 1/32。第二个数字是第一个峰值和最后一个峰值之间的比率。基本思想是,如果你正在进行一个长度为 10 的周期,你希望第一个时期是上升的部分,其他 9 个时期是下降的部分,那么你会使用 10。我发现这样效果非常好,这也是 Leslie 的建议,大约两天前,他写了这篇令人惊叹的论文:神经网络超参数的纪律方法。在这篇论文中,他描述了与此略有不同的内容,但基本思想相同。这是一篇必读的论文。它包含了 fastai 经常深入讨论的各种想法,其他人都没有谈论过。不幸的是,Leslie 在真正有时间编辑它之前不得不离开度假,所以阅读起来有点慢,但不要让这阻止你。它很棒。


右边的方程是我和 Sebastian 的论文中的。Sebastian 问:“Jeremy,你能把你写的代码背后的数学方程发给我吗?”我说:“不行,我只是写了代码。我无法把它转化为数学”,所以他为此找到了数学解。

连接池[1:51:36]

所以你可能已经注意到,我们分类器的第一层等于嵌入大小的 3 倍。为什么是 3 倍?因为,再次强调,这似乎是以前没有人做过的事情,所以一个新的想法“连接池”。我们对激活序列进行平均池化,对激活序列进行最大池化,以及最终的一组激活,并将它们全部连接在一起。这是我们在第一部分讨论过的内容,但在文献中似乎没有出现过,所以现在称为“连接池”,现在有一个方程,但这就是全部的实现。所以你可以阅读这篇论文,看看 fastai 代码如何实现每个部分。


BPT3C[1:52:46]

一个有趣的地方是RNN_Encoder和 MultiBatchRNN 编码器之间的区别。那里有什么不同?关键区别在于,语言模型的普通 RNN 编码器,我们可以一次只做一个bptt块。但是对于分类器,我们需要处理整个文档。在我们决定它是积极的还是消极的之前,我们需要处理整个电影评论。整个电影评论可能很容易就有 2000 个字,而且我无法将 2000 个字的梯度适应我的 GPU 内存中的每一个权重。那我们该怎么办?所以这个想法非常简单,就是我一次处理整个序列长度的一个bptt批次。然后我调用super().forward(换句话说,RNN_Encoder)来获取它的输出,然后我有这个最大序列长度参数,它说“好的,只要你不超过那个序列长度,就开始将其附加到我的输出列表中。”换句话说,它发送回这个池的东西只有我们要求它保留的那么多激活。这样,你可以弄清楚你的特定 GPU 可以处理多少max_seq。所以它仍然使用整个文档,但是假设max_seq是 1000 个字,你最长的文档长度是 2000 个字。它仍然会通过 RNN 为这前 1000 个字创建状态,但实际上不会存储前 1000 个字的激活以进行反向传播。它只会保留最后 1000 个字。这意味着它无法将损失反向传播到在前 1000 个字中创建的任何状态,基本上那已经消失了。所以这是一个非常简单的代码片段,老实说,当我写它时,我没有花太多时间考虑,因为它似乎显而易见这是唯一可能起作用的方式。但是再次,这似乎是一个新事物,所以我们现在有了文本分类的时间反向传播。你可以看到这篇论文中有很多小片段。


结果

结果是什么?在我们尝试的每个数据集上,我们得到的结果都比以往任何一篇学术论文在文本分类方面都要好。各种不同类型。老实说,IMDb 是我花时间尝试优化模型的唯一一个,所以大多数情况下,我们只是用第一个出来的结果。所以如果我们真的花时间在上面,我认为结果会更好。这些比较的对象大多数在每个表格上都不同,因为它们是整体上定制的算法。所以这就是说一个简单的微调算法可以击败这些真正定制的算法。


消融研究

这是 Sebastian 做的消融研究。我非常希望如果要发表一篇论文,我们必须说明它为什么有效。所以 Sebastian 去尝试移除我提到的所有不同贡献。如果我们不使用逐渐冻结会怎样?如果我们不使用区分性学习率会怎样?如果我们使用余弦退火而不是区分性学习率会怎样?如果我们不使用维基百科进行任何预训练会怎样?如果我们不进行任何微调会怎样?对我来说真正有趣的是,如果我们只使用一百个训练样本(与 200、500 等相比),在 IMDb 上的验证错误率是多少。你可以看到,非常有趣的是,这种方法的完整版本在只有一百个训练样本时几乎与完整的 20000 个训练样本一样准确。而如果你从一百开始训练,几乎是随机的。这是我预料到的。我告诉 Sebastian 我真的认为这在没有太多数据时最有益。这就是 fastai 最感兴趣的地方——小数据范围,小计算范围等等。所以他进行了这些研究来检查。


运行消融研究的技巧

技巧#1:VNC

第一个技巧是我知道你们都会觉得非常方便的。我知道当你在 Jupyter 笔记本中运行某些东西时,当你失去互联网连接的时间足够长,它会认为你已经离开,然后你的会话消失了,你必须从头开始。那么你该怎么办?有一个非常简单而酷炫的东西叫做 VNC,你可以在您的 AWS 实例或 PaperSpace 上安装它,或者其他地方:

  • X Windows(xorg
  • 轻量级窗口管理器(lxde-core
  • VNC 服务器(tightvncserver
  • Firefox(firefox
  • 终端(lxterminal
  • 一些字体(xfonts-100dpi

将这些行添加到您的./vnc/xstartup配置文件的末尾,然后运行这个命令(tightvncserver :13 -geometry 1200x900):


现在正在运行一个服务器,您可以在您的计算机上运行 TightVNC Viewer 或任何 VNC 查看器,然后将其指向您的服务器。但具体来说,您要做的是使用 SSH 端口转发将:5913 转发到 localhost:5913:

然后连接到本地主机的端口 5013。它会将其发送到服务器上的端口 5913,这是 VNC 端口(因为你说了:13),它会显示一个 X Windows 桌面。然后你可以点击 Linux 的开始按钮,点击 Firefox,现在你有了 Firefox。你在 Firefox 中看到这里写着 localhost,因为这个 Firefox 是在我的 AWS 服务器上运行的。所以你现在运行 Firefox,启动你的东西,然后关闭你的 VNC 查看器,记住 Firefox 显示在这个虚拟 VNC 显示上,而不是在一个真实的显示器上,所以稍后那天,你再次登录 VNC 查看器,它会再次弹出。所以这就像一个持久的桌面,而且速度惊人快。它运行得非常好。有很多不同的 VNC 服务器和客户端,但这个对我来说效果很好。

技巧#2:Google Fire[2:01:27]


技巧#2 是创建 Python 脚本,这就是我们最终做的事情。所以我最终为 Sebastian 创建了一个小 Python 脚本,告诉他这是你需要做的基本步骤,现在你需要为其他所有事情创建不同的版本。我建议他尝试使用一个叫做 Google Fire 的东西。Google Fire 的作用是,你创建一个带有大量参数的函数,这些都是 Sebastian 想要尝试的不同事情 - 不同的 dropout 数量,不同的学习率,我是否使用预训练,我是否使用 CLR,我是否使用区分性学习率等等。所以你创建一个函数,然后添加一些内容说:

if __name__ == '__main__': 
    fire.Fire(train_clas)

你什么都不做 - 你不必添加任何元数据,任何文档字符串,什么都不用添加,然后你调用那个脚本,你现在自动拥有了一个命令行界面。这是在终端中运行许多不同变体的超级简单方法。如果你想要做很多变体,这种方法比使用笔记本更容易,因为你可以编写一个 bash 脚本来尝试所有这些变体并将它们全部输出。

技巧#3:IMDb 脚本[2:02:47]

你会在courses/dl2中找到一个名为imdb_scripts的文件夹,里面有 Sebastian 和我使用的所有脚本。因为我们需要对每个数据集进行标记化和数值化,然后为每个数据集训练一个语言模型和一个分类器。我们必须以各种不同的方式做所有这些事情来进行比较,所以我们为所有这些事情都准备了脚本。你可以查看并看到我们使用的所有脚本。



技巧#4:pip install -e[2:03:32]

当你在做很多脚本时,你会在各个地方得到不同的代码。最终,你可能会感到沮丧,不想一遍又一遍地创建 fastai 库的符号链接。但你可能也不想 pip 安装它,因为那个版本往往有点旧,我们进展如此之快,你想使用 Git 中的当前版本。如果你从 fastai 仓库基础目录运行 pip install -e .,它会做一些相当巧妙的事情,基本上是在 site-packages 目录内创建一个到 fastai 库的符号链接(即你本地克隆的 Git 仓库)。你的 site-packages 目录是你的主 Python 库。所以如果你这样做,你就可以从任何地方访问 fastai,但每次你执行 git pull 时,你都会得到最新版本。这样做的一个缺点是它会安装 pip 中的任何更新版本的包,这可能会让 Conda 有点困惑,所以另一个选择是只需将 fastai 库符号链接到你的 site-packages 库。这同样有效。你可以从任何地方使用 fastai,当你想要在系统的不同目录中运行使用 fastai 的脚本时,这是非常方便的。


技巧 #5: SentencePiece

如果你愿意,这是你可以尝试的东西。你不必进行标记化。你可以标记化所谓的子词单元,而不是标记化单词。例如,“unsupervised”可以被标记化为“un”和“supervised”。“Tokenizer”可以被标记化为[“token”, “izer”]。然后你可以做同样的事情。使用子词单元的语言模型,使用子词单元的分类器等。这样做效果如何?我开始尝试并且没有花太多时间,我得到的分类结果几乎和使用单词级标记化一样好 —— 不完全一样,但几乎一样好。我怀疑通过更仔细的思考和尝试,也许我可以得到同样好甚至更好的结果。但即使我不能,如果你创建一个子词单元维基文本模型,然后 IMDb 语言模型,然后分类器正向和反向,然后将其与正向和反向的单词级模型合并,你应该能够超越我们。所以这是一个你可能能够超越我们最先进结果的方法。


Sebastian 告诉我这个特定项目 —— 谷歌有一个名为 sentence peace 的项目,实际上使用神经网络来找出单词的最佳拆分方式,因此你最终会得到一个子词单元的词汇表。在我的尝试中,我发现创建大约 30,000 个子词单元的词汇表似乎是最佳的。如果你感兴趣,这是你可以尝试的东西。安装起来有点麻烦 —— 它是 C++,没有创建错误消息,但它会工作。有一个 Python 库可以用于此。如果有人尝试这个,我很乐意帮助他们让它工作。对于子词和单词级别分类的集成,几乎没有什么实验,我认为这应该是最佳的方法。

祝你有一个美好的一周!

深度学习 2:第 2 部分第 11 课

原文:medium.com/@hiromi_suenaga/deep-learning-2-part-2-lesson-11-61477d24dc34

译者:飞龙

协议:CC BY-NC-SA 4.0

来自 fast.ai 课程的个人笔记。随着我继续复习课程以“真正”理解它,这些笔记将继续更新和改进。非常感谢 JeremyRachel 给了我这个学习的机会。

链接

论坛 / 视频

开始之前:

  • 1cycle 策略 由 Sylvain Gugger 提出。基于 Leslie Smith 的新论文,该论文结合了之前的两篇关键论文(循环学习率和超级收敛),并通过一系列实验来展示如何实现超级收敛。超级收敛让您训练模型比之前的分阶段方法快五倍(比 CLR 更快,尽管不到五倍)。超级收敛让您可以通过 1 到 3 之间的极高学习率进行训练。超级收敛的有趣之处在于,您在相当大比例的 epochs 中以非常高的学习率进行训练,而在此期间,损失并没有真正得到很大的改善。但诀窍在于它在空间中进行了大量搜索,以找到真正通用的区域。Sylvain 在 fastai 中实现了这一点,通过补充缺失的部分,然后确认他确实在 CIFAR10 上实现了超级收敛。目前称为use_clr_beta,但将来会更名。他还在 fastai 库中添加了循环动量。
  • 如何使用序列到序列模型创建神奇的数据产品 由 Hamel Husain 撰写。他在博客中介绍了训练一个模型来总结 GitHub 问题。这是基于他的博客创建的 Kubeflow 团队的演示

神经机器翻译 [5:36]

让我们构建一个序列到序列模型!我们将致力于机器翻译。机器翻译已经存在很长时间了,但我们将看一种称为神经翻译的方法,它使用神经网络进行翻译。神经机器翻译几年前出现,当时并不像使用经典特征工程和标准 NLP 方法(如词干处理、调整词频、n-gram 等)的统计机器翻译方法那么好。一年后,它比其他所有方法都要好。它基于一个叫做 BLEU 的指标——我们不会讨论这个指标,因为它不是一个很好的指标,也不是很有趣,但每个人都在使用它。


我们看到机器翻译开始沿着我们在 2012 年看到的计算机视觉对象分类的道路前进,后者刚刚超越了最先进技术,现在正在以很快的速度超越它。看这个视频的人不太可能会构建一个机器翻译模型,因为translate.google.com/效果相当不错。那么我们为什么要学习机器翻译呢?我们学习机器翻译的原因是,将一些输入(比如法语句子)转换为任意长度的其他输出(比如英语句子)的一般想法是一件非常有用的事情。例如,正如我们刚才看到的,Hamel 将 GitHub 问题转换为摘要。另一个例子是将视频转换为描述,或者基本上任何你需要输出任意长度输出的地方,通常是一个句子。也许是将 CT 扫描转换为放射学报告——这就是你可以使用序列到序列学习的地方。

fast.ai 深度学习笔记(五)(4)https://developer.aliyun.com/article/1482706

相关文章
|
5天前
|
存储 人工智能 Linux
|
8天前
|
机器学习/深度学习 人工智能 算法
【AI】从零构建深度学习框架实践
【5月更文挑战第16天】 本文介绍了从零构建一个轻量级的深度学习框架tinynn,旨在帮助读者理解深度学习的基本组件和框架设计。构建过程包括设计框架架构、实现基本功能、模型定义、反向传播算法、训练和推理过程以及性能优化。文章详细阐述了网络层、张量、损失函数、优化器等组件的抽象和实现,并给出了一个基于MNIST数据集的分类示例,与TensorFlow进行了简单对比。tinynn的源代码可在GitHub上找到,目前支持多种层、损失函数和优化器,适用于学习和实验新算法。
72 2
|
10天前
|
机器学习/深度学习 人工智能 算法
AI大咖说-关于深度学习的一点思考
周志华教授探讨深度学习的成效,指出其关键在于大量数据、强大算力和训练技巧。深度学习依赖于函数可导性、梯度下降及反向传播算法,尽管硬件和数据集有显著进步,但核心原理保持不变。深度意味着增加模型复杂度,相较于拓宽,加深网络更能增强泛函表达能力,促进表示学习,通过逐层加工处理和内置特征变换实现抽象语义理解。周志华教授还提到了非神经网络的深度学习方法——深度森林。5月更文挑战第12天
38 5
|
11天前
|
机器学习/深度学习 人工智能 算法
构建高效AI系统:深度学习优化技术解析
【5月更文挑战第12天】 随着人工智能技术的飞速发展,深度学习已成为推动创新的核心动力。本文将深入探讨在构建高效AI系统中,如何通过优化算法、调整网络结构及使用新型硬件资源等手段显著提升模型性能。我们将剖析先进的优化策略,如自适应学习率调整、梯度累积技巧以及正则化方法,并讨论其对模型训练稳定性和效率的影响。文中不仅提供理论分析,还结合实例说明如何在实际项目中应用这些优化技术。
|
11天前
|
机器学习/深度学习 敏捷开发 人工智能
吴恩达 x Open AI ChatGPT ——如何写出好的提示词视频核心笔记
吴恩达 x Open AI ChatGPT ——如何写出好的提示词视频核心笔记
232 0
|
11天前
|
机器学习/深度学习 人工智能 算法
【AI 初识】讨论深度学习和机器学习之间的区别
【5月更文挑战第3天】【AI 初识】讨论深度学习和机器学习之间的区别
|
11天前
|
机器学习/深度学习 自然语言处理 PyTorch
fast.ai 深度学习笔记(三)(4)
fast.ai 深度学习笔记(三)(4)
27 0
|
11天前
|
机器学习/深度学习 算法 PyTorch
fast.ai 深度学习笔记(三)(3)
fast.ai 深度学习笔记(三)(3)
34 0
|
11天前
|
机器学习/深度学习 编解码 自然语言处理
fast.ai 深度学习笔记(三)(2)
fast.ai 深度学习笔记(三)(2)
38 0
|
11天前
|
机器学习/深度学习 PyTorch 算法框架/工具
fast.ai 深度学习笔记(三)(1)
fast.ai 深度学习笔记(三)(1)
44 0

热门文章

最新文章