Skip to content
This repository has been archived by the owner on Oct 11, 2023. It is now read-only.

Commit

Permalink
2021-01-04 15:45:31
Browse files Browse the repository at this point in the history
  • Loading branch information
wizardforcel committed Jan 4, 2021
1 parent 29c2afe commit 7a98200
Showing 1 changed file with 10 additions and 10 deletions.
20 changes: 10 additions & 10 deletions docs/7.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

我们还介绍了自然语言生成作为序列预测应用的任务,并探讨了输出序列在某种程度上受到约束的条件生成。

## ")The Problem with Vanilla RNNs (or Elman RNNs)
## 原始 RNN(Elman RNNs)的问题

尽管在第 6 章中讨论的普通 RNN/Elman-RNN 非常适合于建模序列,但它有两个问题使其不适用于许多任务:无法保留用于长期预测的信息,以及梯度稳定性。为了理解这两个问题,回想一下,在它们的核心,rnn 在每个时间步上使用前一个时间步的隐藏状态向量和当前时间步上的输入向量计算一个隐藏状态向量。正是这种核心计算使得 RNN 如此强大,但也产生了大量的数值问题。

Expand All @@ -28,7 +28,7 @@ Elman RNNs 的第二个问题是,它们会导致梯度螺旋地失去控制,

在一般的神经网络中,有解决这些梯度问题的方法,如使用校正的线性单元(relu)、梯度裁剪和小心初始化。但是没有一种解决方案能像门控技术那样可靠地工作。

## Gating as a Solution to a Vanilla RNN’s Challenges
## 原始 RNN 的挑战的门控解决方案

为了直观地理解门控,假设您添加了两个量,`a``b`,但是您想控制`b`放入和的多少。数学上,你可以把`a + b`的和改写成`a+λb``λ`是一个值在 0 和 1 之间。如果`λ = 0`,`b`没有贡献,如果`λ = 1`,`b`完全贡献。这种方式看,你可以解释λ充当一个“开关”或“门”控制的`b`进入之和。这就是门控机制背后的直觉。现在,让我们重新访问 Elman RNN,看看如何将门控与普通的 RNN 合并以进行条件更新。如果前面的隐藏状态是`h[t−1]`和当前输入`x[t]`, Elman RNN 的周期性更新看起来像

Expand All @@ -44,15 +44,15 @@ LSTM 只是 RNN 的许多门控变体之一。另一种越来越流行的门控

门控机制是“普通 RNNs(或 Elman RNNs)问题”中列举的问题的有效解决方案。它不仅可以控制更新,还可以控制梯度问题,使训练相对容易。不再赘述,我们将使用两个示例来展示这些封闭体系结构的实际应用。

## Example: A Character-RNN for Generating Surnames
## 示例:用于生成姓氏的字符 RNN

在本例中,我们将完成一个简单的序列预测任务:使用 RNNs 生成姓氏。在实践中,这意味着对于每个时间步骤,RNN 都在计算姓氏中可能的字符集的概率分布。使用这些概率分布,我们可以优化网络来改进它的预测(假设我们知道应该预测哪些字符),也可以使用它们来生成全新的姓氏!

虽然这个任务的数据集已经在前面的例子中使用过,看起来很熟悉,但是在构建用于序列预测的每个数据样本的方式上有一些不同。在描述了数据集和任务之后,概述了支持通过系统簿记进行序列预测的数据结构。

在描述了数据集、任务和支持数据结构之后,我们引入了两个生成姓氏的模型:无条件姓氏生成模型和条件姓氏生成模型。该模型在不了解姓氏的情况下,对姓氏序列进行预测。与此相反,条件模型利用特定的国籍嵌入作为 RNN 的初始隐藏状态,从而使模型对序列的预测产生偏差。

### The SurnamesDataset
### `SurnamesDataset`

姓氏数据集是姓氏及其来源国的集合,最早出现在“带有多层感知器的姓氏分类”中。到目前为止,该数据集已经被用于一个分类任务——给出一个新的姓氏,正确地将姓氏来自哪个国家。然而,在本例中,我们将展示如何使用数据集来训练一个模型,该模型可以为字符序列分配概率并生成新的序列。

Expand Down Expand Up @@ -97,7 +97,7 @@ class SurnameDataset(Dataset):

```

### The Vectorization Data Structures
### 向量化数据结构

与前面的示例一样,有三种主要的数据结构将每个姓氏的字符序列转换为其向量化形式:`SequenceVocabulary`将单个标记映射到整数,`SurnameVectorizer`协调整数映射,`DataLoader``SurnameVectorizer`的结果分组为小批。由于`DataLoader`实现及其使用在本例中保持不变,我们将跳过其实现细节。

Expand Down Expand Up @@ -165,11 +165,11 @@ class SurnameVectorizer(object):

```

### From the ElmanRNN to the GRU
### `ElmanRNN` GRU

在实践中,从普通的 RNN 转换到门控变体是非常容易的。在以下模型中,虽然我们使用 GRU 代替普通的 RNN,但是使用 LSTM 也同样容易。为了使用 GRU,我们实例化了`torch.nn`。GRU 模块使用与第六章`ElmanRNN`相同的参数。

### Model 1: Unconditioned Surname Generation Model
### 模型 1:非条件姓氏生成模型

第一个模型是无条件的:它在生成姓氏之前不观察国籍。在实践中,非条件意味着 GRU 的计算不偏向任何国籍。在下一个例子(例子 7-3)中,通过初始隐藏向量引入计算偏差。在这个例子中,我们使用一个全为 0 的向量,这样初始的隐藏状态向量就不会影响计算。 通常,`SurnameGenerationModel`嵌入字符索引,使用 GRU 计算其顺序状态,并使用线性层计算标记预测的概率。更明确地说,非条件`SurnameGenerationModel`从初始化嵌入层、GRU 和线性层开始。 与第 6 章的序列模型相似,该模型输入了一个整数矩阵。我们使用一个 PyTorch 嵌入实例`char_embed`将整数转换为一个三维张量(每个批量项的向量序列)。这个张量传递给 GRU, GRU 计算每个序列中每个位置的状态向量。

Expand Down Expand Up @@ -235,7 +235,7 @@ class SurnameGenerationModel(nn.Module):

```

### Model 2: Conditioned Surname Generation Model
### 模型 2:条件姓氏生成模型

第二个模型考虑了要生成的姓氏的国籍。在实践中,这意味着有某种机制允许模型对特定姓氏的行为进行偏差。在本例中,我们通过将每个国籍嵌入为隐藏状态大小的向量来参数化 RNNs 的初始隐藏状态。这意味着模型在调整模型参数的同时,也调整了嵌入矩阵中的值,从而使预测偏于对特定的国籍和姓氏的规律性更加敏感。例如,爱尔兰国籍向量偏向于起始序列`Mc``O`

Expand All @@ -261,7 +261,7 @@ class SurnameGenerationModel(nn.Module):

```

### Training Routine and Results
### 训练例程和结果

在本例中,我们介绍了用于生成姓氏的字符序列预测任务。虽然许多实现细节和训练例程与第 6 章的序列分类示例相似,但有几个主要区别。在这一节中,我们将重点讨论差异、使用的超参数和结果。 与前面的例子相比,计算这个例子中的损失需要两个更改,因为我们在序列中的每一步都要进行预测。首先,我们将三维张量重塑为二维张量(矩阵)以满足计算约束。其次,我们协调掩蔽索引,它允许可变长度序列与损失函数,使损失不使用掩蔽位置在其计算。

Expand Down Expand Up @@ -504,7 +504,7 @@ Sampled for Vietnamese:

```

## Tips and Tricks for Training Sequence Models
## 训练序列模型的提示和技巧

序列模型很难训练,而且在这个过程中会出现许多问题。在这里,我们总结了一些技巧和技巧,我们发现不仅在我们的工作中有用,而且也被其他人在文献报道。 1)如果可能,使用门控变量 门控体系结构通过解决非通配型的许多数值稳定性问题简化了训练。 2)如果可能,请选择 GRUs 而不是 LSTMs GRUs 提供了与 LSTMs 几乎相同的性能,并且使用更少的参数和计算。幸运的是,从 PyTorch 的角度来看,除了简单地使用不同的模块类之外,在 LSTM 上使用 GRU 没有什么可做的。 3)使用 Adam 作为您的优化器 在第 6 章、第 7 章和第 8 章中,我们只使用 Adam 作为优化器,这是有充分理由的:它是可靠的,收敛速度更快。对于序列模型尤其如此。如果由于某些原因,您的模型没有与 Adam 收敛,那么在这种情况下,切换到随机梯度下降可能会有所帮助。 4)梯度剪裁 如果您注意到在应用这些章节中学习到的概念时出现了数字错误,请在训练过程中使用您的代码绘制梯度值。知道愤怒之后,剪掉任何异常值。这将确保更顺利的训练。在 PyTorch 中,有一个有用的实用程序`clip_grad_norm`可以为您完成此工作,如示例 7-12 所示。一般来说,你应该养成剪切渐变的习惯。

Expand Down

0 comments on commit 7a98200

Please sign in to comment.