第七章 基于 RNN 的生成文本

news2025/6/10 3:32:26

目录

  • 7.1 使用语言模型生成文本
    • 7.1.1 使用 RNN 生成文本的步骤
    • 7.1.2 文本生成的实现
    • 7.1.3 更好的文本生成
  • 7.2 seq2seq 模型
    • 7.2.1 seq2seq 的原理
    • 7.2.2 时序数据转换的简单尝试
    • 7.2.3 可变长度的时序数据
    • 7.2.4 加法数据集
  • 7.3 seq2seq 的实现
    • 7.3.1 Encoder类
    • 7.3.2 Decoder类
    • 7.3.3 Seq2seq类
    • 7.3.4 seq2seq的评价
  • 7.4 seq2seq的改进
    • 7.4.1 反转输入数据(Reverse)
    • 7.4.2 偷窥(Peeky)
  • 7.5 seq2seq的应用
    • 7.5.1 聊天机器人
    • 7.5.2 算法学习
    • 7.5.3 自动图像描述

在第 5 章和第 6 章中,我们仔细研究了 RNN 和 LSTM 的结构及其实现。现在我们已经在代码层面理解了它们。

首先,本章将使用语言模型进行文本生成。具体来说,就是使用在语料库上训练好的语言模型生成新的文本。然后,我们将了解如何使用改进过的语言模型生成更加自然的文本。通过这项工作,我们可以(简单地)体验基于 AI 的文本创作。

另外,本章还会介绍一种结构名为 seq2seq 的新神经网络。seq2seq 是 “(from) sequence to sequence”(从时序到时序)的意思,即将一个时序数据转换为另一个时序数据。本章我们将看到,通过组合两个 RNN,可以轻松实现 seq2seq。seq2seq 可以应用于多个应用,比如机器翻译、聊天机器人和邮件自动回复等。通过理解这个简单但聪明强大的 seq2seq,应用深度学习的可能性将进一步扩大。

7.1 使用语言模型生成文本

7.1.1 使用 RNN 生成文本的步骤

在上一章中,我们使用 LSTM 层实现了语言模型,这个语言模型的网络结构如图 7-1 所示。顺便说一下,我们还实现了整体处理(T 个)时序数据的 Time LSTM 层和 Time Affine 层。

***插入图7-1***

现在我们来说明一下语言模型生成文本的顺序。这里仍以 “you say goobye and i say hello.” 这一在语料库上学习好的语言模型为例,考虑将单词 i i i 赋给这个语言模型的情况。此时,这个语言模型输出图 7-2 中的概率分布。

***插入图7-2***

语言模型根据已经出现的单词输出下一个出现的单词的概率分布。在图 7-2 的例子中,语言模型输出了当给定单词 i i i 时下一个出现的单词的概率分布。那么,它如何生成下一个新单词呢?

一种可能的方法是选择概率最高的单词。在这种情况下,因为选择的是概率最高的单词,所以结果能唯一确定。也就是说,这是一种 “确定性的” 方法。另一种方法是 “概率性地” 进行选择。根据概率分布进行选择,这样概率高的单词容易被选到,概率低的单词难以被选到。在这种情况下,被选到的单词(被采样到的单词)每次都不一样。

这里我们想让每次生成的文本有所不同,这样一来,生成的文本富有变化,会更有趣。因此,我们通过后一种方法(概率性地选择的方法)来选择单词。回到我们的例子中,如图 7-3 所示,假设(概率性地)选择了单词 say。

***插入图7-3***

图 7-3 中显示了根据概率分布进行采样后结果为 say 的例子。在图 7-3 的概率分布中,say 的概率最高,所以它被采样到的概率也最高。不过请注意,这里选到 say 并不是必然的(不是确定性的),而是概率性的。因此,say 以外的其他单词根据出现的概率也可能被采样到。

“确定性的” 是指(算法的)结果是唯一确定的,是可预测的。在上例中, 假设选择概率最高的单词,那么这就是一种确定性的算法。而 “概率性的” 算法则概率性地确定结果,因此每次实验时选到的单词都会有所变化(或者说,存在变化的可能性)。

接下来,采样第 2 个单词。这只需要重复一下刚才的操作。也就是说,将生成的单词 say 输入语言模型,获得单词的概率分布,然后再根据这个概率分布采样下一个出现的单词,如图 7-4 所示。

***插入图7-4***

之后根据需要重复此过程即可(或者直到出现 < e o s > <eos> <eos> 这一结尾记号)。这样一来,我们就可以生成新的文本。这里需要注意的是,像上面这样生成的新文本是训练数据中没有的新生成的文本。因为语言模型并不是背诵了训练数据,而是学习了训练数据中单词的排列模式。如果语言模型通过语料库正确学习了单词的出现模式,我们就可以期待该语言模型生成的文本对人类而言是自然的、有意义的。

7.1.2 文本生成的实现

见书

7.1.3 更好的文本生成

如果有更好的语言模型,就可能有更好的文本。在上一章中,我们改进 了简单的 RNNLM,实现了“更好的 RNNLM”,将模型的困惑度从 136 降 至 75。现在,我们看一下这个 “更好的 RNNLM” 生成文本的能力。

其余见书

7.2 seq2seq 模型

这个世界充满了时序数据。文本数据、音频数据和视频数据都是时序数据。另外,还存在许多需要将一种时序数据转换为另一种时序数据的任务, 比如机器翻译、语音识别等。其他的还有进行对话的聊天机器人应用、将源代码转为机器语言的编译器等。

像这样,世界上存在许多输入输出均为时序数据的任务。从现在开始, 我们会考察将时序数据转换为其他时序数据的模型。作为它的实现方法,我 们将介绍使用两个 RNN 的 seq2seq 模型。

7.2.1 seq2seq 的原理

seq2seq 模型也称为 Encoder-Decoder 模型。顾名思义,这个模型有两个模块——Encoder(编码器)和 Decoder(解码器)。编码器对输入数据进行编码,解码器对被编码的数据进行解码。

现在,我们举一个具体的例子来说明 seq2seq 的机制。这里考虑将日语翻译为英语,比如将 “吾輩は猫である” 翻译为 “I am a cat”。此时,如图 7-5 所示,seq2seq 基于编码器和解码器进行时序数据的转换。

***插入图7-5***

如图 7-5 所示,编码器首先对 “吾輩は猫である” 这句话进行编码,然后将编码好的信息传递给解码器,由解码器生成目标文本。此时,编码器编码的信息浓缩了翻译所必需的信息,解码器基于这个浓缩的信息生成目标文本。

以上就是 seq2seq 的全貌图。编码器和解码器协作,将一个时序数据转换为另一个时序数据。另外,在这些编码器和解码器内部可以使用 RNN。 下面我们来看一下细节。首先来看编码器,它的层结构如图 7-6 所示。

***插入图7-6***

由图 7-6 可以看出,编码器利用 RNN 将时序数据转换为隐藏状态 h h h。 这里的RNN使用的是 LSTM,不过也可以使用 “简单RNN” 或者GRU等。 另外,这里考虑的是将日语句子分割为单词进行输入的情况。

图 7-6 的编码器输出的向量 h h h 是 LSTM 层的最后一个隐藏状态,其中编码了翻译输入文本所需的信息。这里的重点是,LSTM 的隐藏状态 h h h 是 一个固定长度的向量。说到底,编码就是将任意长度的文本转换为一个固定长度的向量(图 7-7)。

***插入图7-7***

如图 7-7 所示,编码器将文本转换为固定长度的向量。那么,解码器是如何 “处理” 这个编码好的向量,从而生成目标文本的呢?其实,我们已经知道答案了。因为我们只需要直接使用上一节讨论的进行文本生成的模型即可,如图 7-8 所示。

***插入图7-8***

从图 7-8 中可以看出,解码器的结构和上一节的神经网络完全相同。 不过它和上一节的模型存在一点差异,就是 LSTM 层会接收向量 h。在上一节的语言模型中,LSTM 层不接收任何信息(硬要说的话,也可以说 LSTM 的隐藏状态接收 “0 向量” )。这个唯一的、微小的改变使得普通的语言模型进化为可以驾驭翻译的解码器。

图 7-8 中使用了 < e o s > <eos> <eos> 这一分隔符(特殊符号)。这个分隔符被用作通知解码器开始生成文本的信号。另外,解码器采样到出现 < e o s > <eos> <eos> 为止,所以它也是结束信号。也就是说,分隔符可以用来指示解码器的 “开始 / 结束”。在其他文献中,也有使用 、 或者 “_”(下划线)作为分隔符的例子。

现在我们连接编码器和解码器,并给出它的层结构,具体如图 7-9 所示。

***插入图7-9***

如图 7-9 所示,seq2seq 由两个 LSTM 层构成,即编码器的 LSTM 和 解码器的 LSTM。此时,LSTM 层的隐藏状态是编码器和解码器的 “桥梁”。 在正向传播时,编码器的编码信息通过 LSTM 层的隐藏状态传递给解码器; 在反向传播时,解码器的梯度通过这个 “桥梁” 传递给编码器。

7.2.2 时序数据转换的简单尝试

下面我们来实现 seq2seq,不过在此之前,首先说明一下我们要处理的问题。这里我们将 “加法” 视为一个时序转换问题。具体来说,如图 7-10 所示,在 seq2seq 学习后,如果输入字符串 “57 + 5”,seq2seq 要能正确回答 “62”。顺便说一下,这种为了评价机器学习而创建的简单问题,称为 “toy problem”。

***插入图7-10***

在我们看来,这里做的加法运算是非常简单的问题,但是 seq2seq 对加法(更确切地说是加法的逻辑)一无所知。seq2seq 从加法的例子(样本) 中学习出现的字符模式,这样真的可以学习到加法运算的规则吗?这正是本次实验的看头。

顺便说一下,在之前的 word2vec 和语言模型中,我们都把文本以单词为单位进行了分割,但并非必须这样做。对于本节的这个问题,我们将不以单词为单位,而是以字符为单位进行分割。在以字符为单位进行分割的情况 下,“57 + 5” 这样的输入会被处理为 [‘5’, ‘7’, ‘+’, ‘5’] 这样的列表。

7.2.3 可变长度的时序数据

我们将 “加法” 视为字符(数字)列表。这里需要注意的是,不同的加法问题(“57 + 5” 或者 “628 + 521” 等)及其回答(“62” 或者 “1149” 等) 的字符数是不同的。比如,“57 + 5” 共有 4 个字符,而 “628 + 521” 共有 7 个字符。

如此,在加法问题中,每个样本在时间方向上的大小不同。也就是说,加法问题处理的是可变长度的时序数据。因此,在神经网络的学习中,在进行 mini-batch 处理时,需要想一些应对办法。

在使用批数据进行学习时,会一起处理多个样本。此时,(在我们的 实现中)需要保证一个批次内各个样本的数据形状是一致的。

在基于 mini-batch 学习可变长度的时序数据时,最简单的方法是使用填充(padding)。所谓填充,就是用无效(无意义)数据填入原始数据,从而使数据长度对齐。就上面这个加法的例子来说,如图 7-11 所示,在多余位置插入无效字符(这里是空白字符),从而使所有输入数据的长度对齐。

***插入图7-11***

本次的问题处理的是 0 ∼ 999 0 \sim 999 0999 的两个数的加法。因此,包括 “+” 在内,输入的最大字符数是 7 7 7。另外,加法的结果最大是 4 4 4 个字符(最大为 “999 + 999 = 1998” )。因此,对监督数据也进行类似的填充,从而对齐所有样本数据的长度。另外,在本次的问题中,在输出的开始处加上了分隔符 “_”(下划线),使得输出数据的字符数统一为 5。这个分隔符作为通知解码器开始生成文本的信号使用。

对于解码器的输出,可以在监督标签中插入表示字符输出结束的分隔符(比如 “ _ 62 _ \_ 62\_ _62_” 或 “ _ 1149 _ \_ 1149 \_ _1149_” )。但是,简单起见,这里我们不使用表示字符输出结束的分隔符。也就是说,在解码器生成字符串时,始终输出固定数量的字符(这里是包括开始处的 “_” 在内的 5 个字符)

像这样,通过填充对齐数据的大小,可以处理可变长度的时序数据。但是,因为使用了填充,seq2seq 需要处理原本不存在的填充用字符,所以如果追求严谨,使用填充时需要向 seq2seq 添加一些填充专用的处理。比如,在解码器中输入填充时,不应计算其损失(这可以通过向 Softmax with Loss 层添加 mask 功能来解决)。再比如,在编码器中输入填充时,LSTM 层应按原样输出上一时刻的输入。这样一来,LSTM 层就可以像不存在填充一样对输入数据进行编码。

7.2.4 加法数据集

见书

7.3 seq2seq 的实现

seq2seq 是组合了两个 RNN 的神经网络。这里我们首先将这两个 RNN 实现为 Encoder 类和 Decoder 类,然后将这两个类组合起来,来实现 seq2seq 类。

7.3.1 Encoder类

见书

7.3.2 Decoder类

见书

7.3.3 Seq2seq类

见书

7.3.4 seq2seq的评价

正确率(正确回答了多少问题),具体来说,就是针对每个 epoch 对正确回答了测试数据中的多少问题进行统计。

实现见书

7.4 seq2seq的改进

7.4.1 反转输入数据(Reverse)

第一个改进方案是非常简单的技巧。如图 7-23 所示,反转输入数据的 顺序。

***插入图7-23***

据研究,在许多情况 下,使用这个技巧后,学习进展得更快,最终的精度也有提高。

实现见书

为什么反转数据后,学习进展变快,精度提高了呢?虽然理论上不是很清楚,但是直观上可以认为,反转数据后梯度的传播可以更平滑。比如,考虑将“吾輩 は 猫 で ある” 翻译成 “I am a cat” 这一问题,单词 “吾輩” 和单词 “I” 之间有转换关系。此时,从 “吾輩” 到 “I” 的路程必须经过 “は” “猫” “で” “ある” 这 4 个单词的 LSTM 层。因此,在反向传播时, 梯度从 “I” 抵达 “吾輩”,也要受到这个距离的影响。

那么,如果反转输入语句,也就是变为 “あるで猫は吾輩”,结果 会怎样呢?此时,“吾輩” 和 “I” 彼此相邻,梯度可以直接传递。如此,因 为通过反转,输入语句的开始部分和对应的转换后的单词之间的距离变近 (这样的情况变多),所以梯度的传播变得更容易,学习效率也更高。不过,在反转输入数据后,单词之间的 “平均” 距离并不会发生改变。

7.4.2 偷窥(Peeky)

如前所述,编码器将输入语句转换为固定长度的向量 h h h,这个 h h h 集中了解码器所需的全部信息。也就是说,它是解码器唯一的信息源。但 是,如图 7-25 所示,当前的 seq2seq 只有最开始时刻的 LSTM 层利用了 h h h。 我们能更加充分地利用这个 h 吗?

***插入图7-25***

为了达成该目标,seq2seq 的第二个改进方案就应运而生了。具体来说,就是将这个集中了重要信息的编码器的输出 h h h 分配给解码器的其他层。我们的解码器可以考虑图 7-26 中的网络结构。

***插入图7-26***

如图 7-26 所示,将编码器的输出 h h h 分配给所有时刻的 Affine 层和 LSTM 层。比较图 7-26 和图 7-25 可知,之前 LSTM 层专用的重要信息 h h h 现在在多个层(在这个例子中有 8 个层)中共享了。重要的信息不是一个人专有,而是多人共享,这样我们或许可以做出更加正确的判断。

这里的改进是将编码好的信息分配给解码器的其他层,这可以解释为其他层也能 “偷窥” 到编码信息。因为 “偷窥” 的英语是 peek,所 以将这个改进了的解码器称为 Peeky Decoder。同理,将使用了 Peeky Decoder 的 seq2seq 称为 Peeky seq2seq。

在图 7-26 中,有两个向量同时被输入到了 LSTM 层和 Affine 层,这实际上表示两个向量的拼接(concatenate)。因此,在刚才的图中,如果使用 concat 节点拼接两个向量,则正确的计算图可以绘制成图 7-27。

***插入图7-27***

代码实现见书。

7.5 seq2seq的应用

seq2seq 将某个时序数据转换为另一个时序数据,这个转换时序数据的框架可以应用在各种各样的任务中,比如以下几个例子。

  • 机器翻译:将 “一种语言的文本” 转换为 “另一种语言的文本”
  • 自动摘要:将 “一个长文本” 转换为 “短摘要”
  • 问答系统:将 “问题” 转换为 “答案”
  • 邮件自动回复:将 “接收到的邮件文本” 转换为 “回复文本”

像这样,seq2seq 可以用于处理成对的时序数据的问题。除了自然语言之外,也可以用于语音、视频等数据。有些乍一看不属于 seq2seq 的问题,通过对输入输出数据进行预处理,也可以应用 seq2seq。本节将介绍几个使 用 seq2seq 的应用。如果读者能由此感受到 seq2seq 的潜力和乐趣,那就再好不过了。

7.5.1 聊天机器人

见书

7.5.2 算法学习

见书

7.5.3 自动图像描述

见书

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/412397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

静态时序分析Static Timing Analysis3——特殊路径(多周期、半周期、伪路径)的时序检查

文章目录前言一、多周期路径1、建立时间检查2、保持时间检查二、半周期路径1、建立时间检查2、保持时间检查三、伪路径前言 2023.4.12 一、多周期路径 对于建立时间&#xff0c;要设置为N&#xff08;向后移&#xff09;&#xff1b;对于保持时间&#xff0c;要设置为N-1&…

9.8.0.32:ProEssentials数据可视化2D和3D图表:Crack

下面是我们的Winforms、Wpf、C MFC、VCL、ActiveX图表组件示例项目中的屏幕捕获。 有关下图&#xff0c;请参见我们的示例项目和演示中的030。 ProEssentials Winforms 图表, WPF 图表, C/MFC/VCL 图表. Gigasoft拥有20多年帮助企业开发大型客户端和嵌入式图表项目的经验。图…

JavaScript基础-02

常量&#xff08;字面量&#xff09;&#xff1a;数字和字符串 常量也称之为“字面量”&#xff0c;是固定值&#xff0c;不可改变。看见什么&#xff0c;它就是什么。 常量有下面这几种&#xff1a; 数字常量&#xff08;数值常量&#xff09;字符串常量布尔常量自定义常量…

传输线的物理基础(九):N 截面集总电路模型

理想的传输线电路元件是一种分布式元件&#xff0c;可以非常准确地预测实际互连的测量性能。下图显示了 1 英寸长传输线在频域中的实测阻抗和仿真阻抗对比。我们看到甚至高达 5 GHz 的测量带宽也能达成出色的协议。 1英寸长、50欧姆传输线的测量&#xff08;圆圈&#xff09;和…

Java实现hdfs的8个api操作

Java实现hdfs的8个api操作一、预处理准备1. 配置本地hadoop3.1.3目录文件2. 配置环境变量二、Maven项目依赖三、Java源代码四、api操作的实现1. 实现前的准备2. 创建hdfs上的路径3. 删除hdfs上的路径4. 创建hdfs文件并写入数据5. 删除hdfs上的文件6. hdfs上的文件移动路径并改名…

算法笔记:Frechet距离度量

曲线之间相似性的度量&#xff0c;它考虑了沿曲线的点的位置和顺序 1 概念 1.1 直观理解 主人走路径A&#xff0c;狗走路径B&#xff0c;他们有不同的配速方案主人和狗各自走完这两条路径过程中所需要的最短狗绳长度 &#xff08;在某一种配速下需要的狗绳长度&#xff09;&a…

MySQL-高可用MHA(二)

目录 &#x1f341;通过keepalived方式 &#x1f342;安装keepalived &#x1f343;防火墙策略 &#x1f343;keep配置文件 &#x1f342;MHA应用keepalived &#x1f343;停止MHA &#x1f343;启动MHA &#x1f343;检查状态 &#x1f343;测试 &#x1f341;通过脚本实现VIP…

数据结构——线段树

线段树的结构 线段树是一棵二叉树&#xff0c;其结点是一条“线段”——[a,b]&#xff0c;它的左儿子和右儿子分别是这条线段的左半段和右半段&#xff0c;即[a, (ab)/2 ]和[(ab)/2 ,b]。线段树的叶子结点是长度为1的单位线段[a,a1]。下图就是一棵根为[1,10]的线段树&#xff1…

真题详解(UML图)-软件设计(四十七)

真题详解(Flynn分类)-软件设计&#xff08;四十六)https://blog.csdn.net/ke1ying/article/details/130072198 某搜索引擎在使用过程中&#xff0c;若要增加接受语音输入的功能&#xff0c;使用户可以通过语音来进行搜索&#xff0c;此时对应系统进行____维护&#xff1f; 正确…

基于逻辑回归构建肿瘤预测模型

使用逻辑回归构建肿瘤预测模型 描述 乳腺癌数据集包括569个样本&#xff0c;每个样本有30个特征值&#xff08;病灶特征数据&#xff09;&#xff0c;每个样本都属于恶性&#xff08;0&#xff09;或良性&#xff08;1&#xff09;两个类别之一&#xff0c;要求使用逻辑回归&…

Python学习笔记--函数

&#xff08;一&#xff09; 函数介绍 1. 函数&#xff1a;是组织好的&#xff0c;可重复使用的&#xff0c;用来实现特定功能的代码段。 eg. len()&#xff1a;实现统计长度这一特定功能的代码段。 2. 函数好处&#xff1a; * 将功能封装在函数内&#xff0c;可随时随地重复…

eSearch使用教程大全

下载&#xff1a; https://www.xsoftnet.com/share/a0002tNuuOswc.html产品&#xff1a; eSearch 即拥有 截屏OCR搜索翻译贴图以图搜图录屏功能。 截屏 框选裁切 框选大小位置可调整(支持方向键或 WASD) 框选大小栏可输入四则运算式调整 取色器 放大镜 画笔&#xff08;自由画…

Kafka系统整理 一

一、Kafka 概述 1.1 定义 Kafka传统定义&#xff1a;Kafka是一个分布式的基于发布/订阅模式的消息队列 (Message Queue), 主要应用于大数据实时处理领域。 kafka最新定义&#xff1a;kafka是一个开源的分布式事件流平台&#xff08;Event Streaming Platform&#xff09;, 被…

PostgreSQL下载、安装、Problem running post-install step的解决、连接PostgreSQL

我是参考《SQL基础教程》来安装的&#xff0c;关于书的介绍、配套视频、相关代码可以参照下面的链接&#xff1a; SQL基础教程&#xff08;第2版&#xff09; (ituring.com.cn) 一、下载 我直接打开书中的下载链接时&#xff0c;显示的是这个界面&#xff1a; You are not …

Flink的窗口机制

窗口机制 tumble&#xff08;滚动窗口&#xff09; hop&#xff08;滑动窗口&#xff09; session&#xff08;会话窗口&#xff09; cumulate&#xff08;渐进式窗口&#xff09; Over&#xff08;聚合窗口&#xff09; 滚动窗口&#xff08;tumble&#xff09; 概念 滚…

002:Mapbox GL更改大气、空间及星星状态

第002个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中更改大气、空间及星星状态 。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共71行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:…

java截取字符串的方法

在 Java中&#xff0c;截取字符串的方法有多种&#xff0c;下面我们来介绍一下。 第一种方法&#xff0c;在 class中直接获取字符串&#xff0c; class. str是一个内置的字符串类&#xff0c;它有一个方法可以截取字符串&#xff0c;这个方法叫做 class. str &#xff08;&…

linux入门---缓冲区

查看问题 首先大家来看看下面这段代码 1 #include<stdio.h>2 #include<string.h>3 #include<unistd.h>4 int main()5 {6 printf("i am printf\n");7 fprintf(stdout,"i am fprintf\n");8 fputs("i am fputs\n",…

Unity --- 物理引擎 --- 触发器 与 碰撞器详解

碰撞器补充讲解 对第一个条件进行补充 --- 不仅要两者都具有碰撞组件&#xff0c;同时还需要两者的碰撞组件中都没有勾选 Is Trigger属性 1.上一篇文章中说了那么多&#xff0c;其实也可以总结为两个碰撞条件 --- a.两个游戏物体都具有碰撞器组件 &#xff0c;如果没有的话&…

【数据结构】哈希表详解以及代码实现

目录 1.来源&#xff1a; 2.哈希函数 1.哈希函数的设计规则 2.哈希函数的设计思路 3.哈希碰撞 4.解决哈希碰撞的方案 5.负载因子 3.基于开散列方案的HashMap实现 1.HashMap类中的属性 2.哈希函数 3.判断当前哈希表中是否含有指定的key值 4.判断当前哈希表中是否包含…