深度学习(DL)(一) — 探析
介绍
在语音识别中,您将获得一个输入音频片段
在情绪分类中,输入DNA
序列分析也非常有用。DNA
通过四个字母A、C、G
和T
表示。因此,给定一个DNA
序列,您能否标记该DNA
序列的哪一部分对应于蛋白质。在机器翻译中,您会得到一个输入句子,voulez-vou chante avec moi?
然后要求以不同的语言输出翻译。在视频活动识别中,您可能会得到一系列视频帧并被要求识别活动。在名称实体识别中,您可能会得到一个句子并被要求识别该句子中的人。因此,所有这些问题都可以作为监督学习来解决,标签数据
循环神经网络(RNN)
现在,让我们讨论如何构建模型,构建神经网络来学习从0
或1
,这些值会告诉您每个单词是否是人名的一部分。但这种方法效果不佳,并且实际上存在两个主要问题:第一个问题是输入和输出的长度可能不同,并且示例也不同。因此,并不是每个示例都具有相同的输入长度Harry
出现在位置1
上,那是人名的一部分,如果它能自动找出Harry
出现在其他位置
什么是循环神经网络?如果你从左到右阅读句子,你读到的第一个词,比如1
中激活值会传递到时间步骤2
。然后在下一个时间步骤,循环神经网络输入第三个单词
循环神经网络从左到右扫描数据。它在每个时间步骤使用的参数是共享的。在这个循环神经网络中,当对RNN
的一个弱点是它只使用序列中较早的信息进行预测。特别是,当预测Teddy
这个词是否是某人名字的一部分,不仅要知道前两个单词的信息,还要知道句子中后面的单词的信息,因为这个句子也可能是,“他说泰迪熊正在打折。”所以只给出前三个单词是不可能确定Teddy
这个词是否是某人名字的一部分。在第一个例子中,它是。在第二个例子中,它不是。但是如果你只看前三个词,你就无法分辨出区别。所以这个特定的神经网络结构的一个限制是,在某个时间的预测使用输入或使用序列中较早的输入信息,但不使用序列中较晚的信息。现在需要明确说明这个神经网络所做的计算。正如之前提到的,从输入1
,这将是某个激活函数,与上面的激活函数不同。使用这些矩阵的底数的符号约定,例如RNN
中,用于计算激活函数是sigmoid
激活函数,或者它可能是softmax
,如果是一个k
路分类问题,激活函数的选择将取决于输出01
,第二个S
型激活函数。如果您想区分不同的激活函数,可以写t
,
现在,为了开发更复杂的神经网络,要采用这种符号并对其进行一些简化。为了简化符号,要采用一种稍微简单的方式书写。因此,把它写成100
维数,而示例中10,000
维数,那么100
维的。Wa 将是一个-1
处的向量,也就是100
维,并将其叠加在上面,最终是一个10100
维向量。则
一个RNN
架构,其中输入的数量等于输出数量1~5
之间的数值,也可能是0
或1
。是正面评论或负面评论,也可能是是一星、两星、三星、四星还是五星评论?在这种情况下,我们可以按如下方式简化神经网络架构。将输入RNN
读入整个句子,并在最后一个时间步输入整个句子后输出RNN
输出第一个值,然后,第二个值,然后继续输出。第三个值,依此类推,直到您合成乐曲的最后一个音符。如果您愿意,您也可以输入
反向传播
循环神经网络中的反向传播是如何工作的?通常,当您在某个编程框架中实现此功能时,编程框架通常会自动处理反向传播。您已经了解了前向传播,在神经网络中按如下方式从左到右计算这些激活,因此您输出了所有预测。在反向传播中,正如您可能已经猜到的那样,最终会与前向传播箭头相反的方向进行反向传播计算。所以,让我们来看看前向传播计算。这个输入序列0.1
。把它定义为标准逻辑回归损失,也称为交叉熵损失。这是与单个单词在单个位置或单个时间集
语言模型和序列生成
语言建模是自然语言处理中最基本任务之一。这也是RNN
非常擅长的任务之一。什么是语言模型?假设您正在构建一个语音识别系统,并且您听到这句话,“苹果梨沙拉很好吃”。你刚才听到我说了什么?我说的是苹果配对沙拉吗?还是我说的是苹果梨沙拉?您可能认为第二句话更有可能。事实上,这是一个好的语音识别系统会输出的结果,即使这两个句子听起来完全一样。语音识别系统选择第二句话的方式是使用了语言模型,该模型告诉它这两个句子中任何一个的概率是多少。例如,语言模型可能会说,第一句出现的概率是
如何构建语言模型?要使用RNN
构建这样的模型,您首先需要一个训练集,其中包含大量您想要构建语言模型的任何语言文本。语料库一词是NLP
术语,表示大量的任何语言句子。假设您在训练集中得到一个句子,如下所示,“猫平均每天睡15
个小时”。您要做的第一件事是标记该句子,意味着将形成一个词汇表,然后将每个单词映射到one-hot
向量或词汇表中的索引。您可能还想做的一件事是模拟句子的结束时间。另一个常见的做法是添加一个额外的标记,称为EOS
,代表句子的结束,这可以帮助您确定句子的结束时间。如果您希望模型捕获句子的结束时间,则可以将EOS
标记附加到训练集中每个句子的末尾。在这个例子中,我们有9
个输入。执行标记化步骤时,您可以决定句号是否也应该是标记。在这个例子中,我忽略了标点符号,因此我只是使用日作为另一个标记并省略了句号。如果您想将句号或其他标点符号视为显式标记,那么您也可以将句号添加到您的词汇表中。现在,另一个细节是,如果训练集中的某些单词不在您的词汇表中怎么办?如果您的词汇表使用了10,000
个单词,可能是英语中最常见的10,000
个单词,那么Mau
一词作为决策,Mau
的猫品种,可能不在您的前10,000
个标记中。在这种情况下,您可以将单词Mau
替换为一个称为UNK
的独特标记,它代表未知单词,我们只模拟未知单词而不是特定单词Mau
的概率。执行标记化步骤后,意味着将输入句子映射到词汇表中的各个标记或各个单词,接下来,让我们构建一个RNN
来模拟这些不同序列的概率。这将是RNN
架构。在时间步为0
的位置计算激活softmax
预测,试图找出第一个单词softmax
,因此它会预测字典中任何单词的概率,第一个单词cats
的概率是多少,一直到第一个单词是Zulu
的概率是多少,或者第一个单词出现在句子中的概率是多少。softmax
输出的,它只是预测第一个单词最终的概率。在例子中,一个较大的单词10,000
路softmax
输出。如果你有10,000
个单词的词汇表,这个句子有两个额外的标记。RNN
前进到下一步,并在下一步中激活softmax
预测,RNN
的工作是预测单词的概率,是A
还是Aaron
,是cats
还是Zulu
,是未知单词还是EOS
,然后进入RNN
的下一步,现在计算RNN
中的每一步都会查看一些前面的单词集,例如,给定前三个单词,下一个单词的分布是什么?RNN
学习从左到右一次预测一个单词。为了通过网络训练它,我们将定义成本函数。在某个时间t
,如果真实单词是softmax
预测某个
如果你在一个大型训练集上训练这个RNN
,给定任何初始单词集,它都可以预测下一个单词的概率。给定一个新句子,比如softmax
告诉你RNN
训练语言模型的基本结构。
序列采样
首先对模型生成的第一个单词进行抽样。输入通常是Aaron
的概率是多少?Zulu
的概率是多少,第一个单词是未知单词标记的概率是多少。然后使用numpy
命令np.random.choice
根据这个向量概率定义的分布进行采样,这样你就可以对第一个单词进行采样。接下来,继续第二个时间步,第二个时间步需要the
”。然后将“the
”作为EOS
标记。或者,如果词汇表中没有包含这个,那么也可以决定采样20
个单词或100
个单词,然后继续进行,直到达到该时间步数。这个过程有时会生成一个未知的单词标记。如果你想确保算法永远不会生成这个标记,你可以做拒绝任何作为未知单词标记出现的样本,并继续从词汇表中重新采样,直到你得到一个不是未知单词。这就是从RNN
语言模型中生成随机句子的方法。到目前为止,一直在构建一个单词级RNN
。根据你的应用程序,你可以构建一个字符级RNN
。所以在这种情况下,你的词汇表将只是字母。最多是a~z
,以及空格、标点符号,数字0~9
。如果你想区分大写和小写,你也可以包括大写字母。如果你构建的是字符级语言模型而不是单词级语言模型,那么你的序列cats
平均每天睡眠15
小时。在此示例中,mau
这样的序列分配非零概率。而如果mau
不在你的单词级语言模型词汇表中,你只需为其分配未知的单词标记。但字符级语言模型的主要缺点是会得到更长的序列。许多英文句子会有10~20
个单词,但可能会有几十个字符。因此在捕捉句子前半部分如何影响后半部分的长距离依赖关系方面,字符语言模型不如词级语言模型。而且字符级模型的训练成本也更高。看到的自然语言处理趋势是,在大多数情况下,词级语言模型仍在使用,但随着计算机速度的提高,越来越多的应用程序,至少在某些特殊情况下,人们开始关注字符级模型。但它们往往需要更多的硬件,训练成本更高,因此目前尚未得到广泛使用。除非是需要大量处理未知单词或其他词汇的专业应用程序。这就是RNN
,以及如何使用它构建语言模型,以及从训练过的语言模型中采样。
RNN梯度消失
RNN
的问题之一是遇到梯度消失问题。假设您看到这句话。“The cat, which already ate and maybe already ate a bunch of food that was delicious, dot dot, dot, dot, dot was full
”。其中较早的措辞会影响句子中较晚的内容。迄今为止看到的RNN
并不擅长捕捉长期依赖关系。之前关于训练非常深的神经网络的讨论,谈到了梯度消失的问题。这是一个非常非常深的神经网络,比如说100层甚至更深。然后你将从左到右进行前向传播,然后进行反向传播。如果这是一个非常深的神经网络,那么来自这个输出RNN
,从左到右的前向传播,然后从右到左的反向传播。由于梯度消失问题,与后续时间步相关的误差输出很难影响较早的计算。让神经网络意识到它需要记忆可能很困难。你看到了单数名词还是复数名词,因此在后面的序列中它可以生成was
或 were
,具体取决于它是单数还是复数。请注意,在英语中,中间的内容可能很长。你可能需要花很长时间记住单数/复数,然后才能使用这些信息。由于这个问题,RNN
模型有许多局部影响,意味着输出RNN
的一个弱点,RNN
往往不太擅长捕捉长距离依赖关系。在进行反向传播时,不应该只是呈指数下降,随着经过的层数呈指数增加。事实证明,梯度消失往往是训练RNN
的最大问题。当发生梯度爆炸时,它可能是灾难性的,因为指数级大的梯度会导致参数变得很大,以至于神经网络参数变得非常混乱。梯度爆炸更容易被发现,因为参数会爆炸。你可能经常看到NaN
,而不是数值,这是因为神经网络计算中数值溢出的结果。如果看到了梯度爆炸,一种解决方案是使用梯度裁剪。查看梯度向量,如果它大于某个阈值,则重新缩放某些梯度向量,使其不会太大,以便根据某个最大值进行裁剪。这是一个强大的解决方案,可以解决梯度爆炸问题。但梯度消失更难解决。
总结一下,训练一个非常深的神经网络。你可能会遇到梯度消失或梯度爆炸问题,其中导数要么呈指数下降,要么呈指数增长。RNN
,比如说处理超过1,000
次集合或超过10,000
次集合的数据的RNN
,基本上就是1,000
层或10,000
层的神经网络。可以使用梯度裁剪来解决梯度爆炸问题。
门控循环单元(GRU)
您已经了解了RNN
的工作原理。门控循环单元(GRU
)对RNN
隐藏层进行了修改,使其能够更好地捕获长距离连接,并对梯度消失问题有很大帮助。您已经看到了计算RNN
在时间GRU
的许多想法分别来自Junyoung Chung、Caglar、Gulcehre、KyungHyun Cho
和 Yoshua Bengio
的这两篇论文。GRU
有一个名为cat
是单数还是复数,这样当它深入句子时,它仍然可以考虑句子的主语是单数还是复数。在时间GRU
单元将输出GRU
来说,GRU
单元计算的方程。在每个时间步中,考虑用0
和1
之间的值。S
型函数看起来像这样,值始终在0
和1
之间。S
型函数要么非常接近0
,要么非常接近1
。为了直观起见,可以认为0
或1
。
GRU
的关键部分是这个方程0
或1
,这取决于你保存的单词,实际上是句子的主语是单数还是复数。因为它是单数,所以我们假设将其设置为1
,如果是复数,我们将其设置为0
,然后GRU
单元将一直记住1
,这表明它是单数,因此选择was
。门(the cat
时,句子cat
的主语。这将是更新此位的好时机,然后the cat was full
,那么知道不再需要记忆了,可以忘记它。如果1
,那么就是将1
,然后继续更新该位。对于中间的所有这些值,你应该让门等于0
,不要更新它,只需保留旧值,如果0
时,不要更新它,只需保留该值,不要忘记它的值是什么,一直将GRU
单元输入sigmoid
激活函数,这给了softmax
或其他东西来对GRU
单元。它非常擅长的是通过门来决定,当从左到右扫描句子时,假设这是更新记忆单元的好时机,然后输入,而不是更改它,直到你到达你真正需要使用你在句子中更早设置的这个记忆单元的点。因为只要这个量是一个很大的负值,门就很容易设置为0
,然后直到数值舍入,更新门为0
,非常接近零。如果是这种情况,那么这个更新方程0
,可以是0.000001
甚至更小。它不会受到梯度消失问题的影响,因为假设0
,这基本上变成cat
和was
是相关的,即使它们中间有很多词分开。在方程式中,100
维的隐藏激活值,那么100
维。在这种情况下,这里,如果门是100
维向量,它实际上是100
维的位向量,值主要是0
和1
,这是你想要更新的位。当然在实践中,0
和1
。这些元素乘法的作用只是告诉GRU
,在每个时间步中要更新的记忆单元向量的维度是什么。您可以选择在更新其他位时保持某些位不变。例如,您会使用一位来记住单数或复数猫,也许您会使用其他一些位来意识到您正在谈论食物。因为我们谈到了吃东西和食物,所以您会期望稍后谈论猫是否吃饱。您可以使用不同的位,并且在每个时间点只更改位的子集。现在您了解了GRU
最重要的思想。
你可以想象,有多种方法来设计这些类型的神经网络,事实证明,研究人员已经尝试了许多不同的版本来设计这些单元,拥有更长距离的连接。尝试对长距离效应进行建模,同时解决梯度消失问题。GRU
是最常用的版本之一,研究人员已经将其融合在一起,然后发现它对于许多不同的问题来说强大且有用的。GRU
是一个标准的,只是常用的单元。这就是GRU
,即门控循环单元。它是为了更好地捕捉非常长的依赖关系,从而使RNN
更加有效。
长短期记忆(LSTM)
长短期记忆单元(LSTM
)。比GRU
更强大,对于GRU
,有LSTM
是GRU
的一个更强大、更通用的版本。对于LSTM
,我们将不再有GRU
相同的更新门。S
型函数LSTM
的方程式。可以看出它有三个门(更新门,遗忘门,输出门)。因此,它有点复杂,并且位置略有不同。
双向RNN
双向RNN
可以在某个时间点从序列的早期和后期获取信息。例如要弄清楚第三个单词Teddy
是否是人名的一部分,仅查看句子的第一部分是不够的。您需要的信息不仅仅是前几个单词。因为前三个词并没有告诉你他们是在谈论泰迪熊,还是在谈论美国前总统泰迪·罗斯福。无论这些单元是标准RNN
块,还是有GRU
块,还是是LSTM
块,所有这些块都是前向的。双向RNN
的作用是解决这个问题。双向RNN
的工作原理如下。使用简化的四个输入句子,Teddy Roosevelt...
来预测Teddy
是否是某人名字的一部分。你需要考虑过去和未来的信息。所以这是双向循环神经网络。这里的这些块不仅可以是标准的RNN
块,还可以是GRU
块或LSTM
块。对于许多NLP
问题、许多文本或自然语言处理问题,双向RNN
和LSTM
似乎被广泛使用。因此,如果您有一个NLP
问题,并且您有一个完整的句子,您试图在句子中标记事物,那么首先尝试使用LSTM
块,然后再向后移动的双向RNN
将是相当合理的选择。这就是双向RNN
。可以对基本RNN
架构、GRU
或LSTM
进行的修改。通过更改,可以拥有一个使用 RNN、GRU、LSTM
的模型,并且能够在序列中间的任何地方进行预测,但会考虑来自整个序列的信息。双向RNN
的缺点是:您需要整个数据序列才能在任何地方进行预测。
深度RNN
对于一个标准的神经网络,你会有一个输入RNN
有点像这样,不再将0
,而是添加了[1]
来表示这是第一层。使用的符号是<t>
来表示它与时间RNN
,拥有三层已经很多了。由于时间维度,即使只有少数几层,这些网络也已经变得非常大。你还可以构建双向RNN
的深度版本,但训练计算成本非常高。