购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.3 基础篇实战:自编码架构的拼音汉字生成模型

前面我们深入探讨了注意力的核心架构及其关键组件,并成功实现了基于注意力机制的编码器。本节将综合运用前两节的知识,通过实战来检验编码器的性能,具体任务是完成拼音与汉字之间的转换训练,效果如图3-17所示。

图3-17 拼音和汉字

这种能够直接将一种序列转换为另一种序列的模型,在实际应用中被称为自编码生成模型。

接下来,我们将详细阐述如何使用这个自编码生成模型来完成拼音与汉字的转换。首先,我们需要准备相应的训练数据,即拼音与对应汉字的配对数据集。这些数据将作为模型的输入和期望输出,帮助模型学习从拼音到汉字的映射关系。

在模型训练过程中,编码器将接收拼音序列作为输入,并尝试生成与之对应的汉字序列。通过不断地调整模型参数,优化损失函数,模型将逐渐学会捕捉拼音与汉字之间的内在联系和规律。

值得注意的是,由于汉字的数量远多于拼音,并且存在多音字、同音字等复杂情况,因此这项任务对模型的生成能力和泛化能力提出了较高要求。

3.3.1 汉字拼音数据集处理

首先是对数据集的准备和处理,在本例中作者准备了15万条汉字和拼音对应数据。

第一步:数据集展示

汉字拼音数据集如下:

简单做一下介绍。数据集中的数据分成3部分,每部分使用特定空格键隔开:

A11_10 … … … ke3 shei2 … … …可 谁 … … …

● 第一部分A11_i为序号,表示序列的条数和行号。

● 第二部分是拼音编号,这里使用的是汉语拼音,与真实的拼音标注不同的是,去除了拼音原始标注,而使用数字1、2、3、4来替代,分别代表当前读音的第一声到第四声,这点请读者注意。

● 第三部分是汉字的序列,这里是与第二部分的拼音部分一一对应的。

第二步:获取字库和训练数据

获取数据集中字库的个数也是一个非常重要的问题,一个非常好的办法是:使用set格式的数据读取全部字库中的不同字符。

创建字库和训练数据的完整代码如下:

这里做一个说明,首先context读取了全部数据集中的内容,之后根据空格将其分成3部分。

除此之外,在对序列的处理上,还需要加上一个特定符号PAD,这是为了对单行序列进行补全的操作。最终的数据如下:

['liu2', 'yong3' , … … … , 'gan1', 'PAD', 'PAD' , … … …]
['柳', '永' , … … … , '感', 'PAD', 'PAD' , … … …]

pinyin_list和hanzi_list是两个列表,分别用来存放对应的拼音和汉字训练数据。最后不要忘记在字库中加上PAD符号。

第三步:根据字库生成Token数据

获取的拼音标注和汉字标注的训练数据并不能直接用于模型训练,模型需要转换成token的一系列数字列表,代码如下:

def get_dataset():
    pinyin_tokens_ids = [ ]
    hanzi_tokens_ids = [ ]
for pinyin,hanzi in zip(tqdm(pinyin_list),hanzi_list):
    pinyin_tokens_ids.append([vocab.index(char) for char in pinyin])
    hanzi_tokens_ids.append([vocab.index(char) for char in hanzi])
return pinyin_tokens_ids,hanzi_tokens_ids

代码中创建了两个新的列表,分别对拼音和汉字的token进行存储,而获取根据字库序号编号后新的序列token。

第四步:PyTorch中的数据输入类

在对数据的具体使用上,读者可以通过for循环的形式将数据载入模型中。而在PyTorch中,也给我们提供了一种专用的数据输入类:

这里的TextSamplerDataset继承自torch.utils.data.Dataset,目的是完成数据输入类的显式声明,而在具体使用上,__getitem__函数用于完成对数据的按序号输出。

3.3.2 搭建文本与向量的桥梁——Embedding

在1.3.1节中,作者为文本内容中的每个汉字或拼音分配了一个独特的数字编号,旨在将文本数据输入深度学习模型中进行处理。然而,仅仅依靠单一的数字编号,深度学习模型难以深度理解文本内容。同时,这种映射方式也可能引发一些潜在问题。

那么,我们是否可以考虑采用另一种方法,比如使用one-hot编码来表示每个“词”或“字”呢?答案是肯定的。

以包含5个词的词汇表为例,若词"Queen"在表中的序号为2,则其词向量可表示为(0,1,0,0,0)。同理,词"king"的词向量就是(0,0,0,1,0)。这种编码方式被称为1-of- N representation,或称为one-hot编码。

尽管one-hot编码在表示词向量时简单明了,但也存在诸多问题。最显著的问题是,当词汇表规模庞大,如达到百万级别时,使用百万维度的向量来表示每个词显然是不切实际的。此外,这种编码方式产生的向量除一个位置为1外,其余位置均为0,表达效率极低,且在卷积神经网络中使用时可能导致网络难以收敛。

为了解决one-hot编码带来的向量长度过长和数值稀疏问题,我们可以采用词映射(Embedding)技术。通过训练,该技术能够将每个词映射到一个较短的词向量上,从而构成一个向量空间。在这个空间中,我们可以运用统计学方法来研究词与词之间的关系。

词映射技术能够将高维稀疏的one-hot向量转换为低维稠密向量,使得语义上相近的单词在向量空间中距离更近。作为自然语言处理中的常见技术,词映射为将文本数据转换为计算机可处理的数字形式提供了便利,为后续的处理和分析奠定了基础,如图3-18所示。

图3-18 词映射Embedding

从图3-18可以看到,对于每个单词,可以设定一个固定长度的向量参数,从而用这个向量来表示该词。这样做的好处是,它可以将文本通过一个低维向量来表达,避免了像one-hot编码那样产生高维稀疏向量的问题。此外,语义相似的词在向量空间中也会更接近,这种表示方式具有很强的通用性,可以应用于不同的任务。

在PyTorch中,处理词嵌入(Embedding)的方法是使用torch.nn.Embedding类。这个类可以将离散变量映射到连续的向量空间,将输入的整数序列转换为对应的向量序列,这些向量可以用于后续的神经网络模型中。例如,可以使用以下代码创建一个嵌入层,该层包含5个大小为3的向量:

import torch
embedding_layer = torch.nn.Embedding(num_embeddings=6, embedding_dim=3)

其中,num_embeddings表示embedding_layer层所代表的词典数目(字库大小),embedding_dim表示Embedding向量维度大小。在训练过程中,embedding_layer层中的参数会自动更新。

而对于定义的embedding_layer层的使用,可以用如下方式完成:

embedding = embedding_layer(torch.tensor([3]))
print(embedding.shape)

其中,数字3是字库中序号为3的索引所指代的字符,通过embedding_layer对其向量进行读取。一个完整的例子如下:

首先通过全文本提取到对应的字符组成一个字库,之后根据字库的长度设定num_embeddings的大小,而对于待表达文本中的每个字符,根据其在字库中的位置建立一个索引序列,将其转换为torch的tensor格式后,通过对embedding_layer进行计算从而得到对应的参数矩阵,并打印其维度。请读者自行尝试。

3.3.3 自编码模型的确定

回到模型设计的核心议题。在3.3.1节中,我们已经成功构建了注意力模块的基础框架,该框架在计算模型中可即时投入使用。然而,通常情况下,仅凭单一的注意力层往往难以实现卓越的性能表现。鉴于此,若仅采用一层编码器对数据进行编码处理,其效果在准确率上可能难以与多层编码器相媲美。因此,一个直观且有效的策略便是增加编码器的层数,以便对数据进行更为深入细致的编码处理,从而有望提升模型的整体性能。通过堆叠多层编码器,我们期望模型在捕捉数据内在特征时能够展现出更高的灵敏度和准确性,进而在各项任务中取得更为出色的表现,如图3-19所示。

图3-19 增加更多层的编码器对数据进行编码

在这里,为了节省篇幅,我们将使用3.3.1节完成的编码器BERT实现,仅演示其使用,代码如下:

这里是对前面章节中编码器构建的示例,使用了多头自注意力层和前馈层。需要注意的是,这里只是在编码器层中加入了更多层的“多头自注意力层”和“前馈层”,而不是直接加载了更多的“编码器”。这一点请读者务必注意。

3.3.4 模型训练部分的编写

接下来是模型训练部分的编写。作者在这里采用最简单的模型训练程序编写方式来完成代码的编写。

第一步是数据的获取。由于模型在训练过程中不可能一次性将所有的数据导入,因此需要创建一个“生成器”,将获取的数据按批次发送给训练模型。在这里,我们使用一个for循环来完成数据的输入任务:

     batch_size = 256
     from torch.utils.data import DataLoader
     loader =
DataLoader(TextSamplerDataset(pinyin_tokens_ids,hanzi_tokens_ids),batch_size=batch_size
,shuffle=False)

这段代码用于完成数据的生成工作,即按既定的batch_size大小生成数据batch,之后在每个epoch的循环中将数据输入模型进行迭代训练。

接下来是完整的训练模型代码,具体如下:

通过将训练代码和模型代码组合在一起,即可实现模型的训练,读者可以运行代码查看结果。而最后预测部分,即使用模型进行自定义实战拼音和汉字的转换部分,请读者自行完成。 JEj0RWbTFJBkmwVjVcZO5AZW+FxZ0T5qIOMhWkdGrOzM/we9gzH8hnnslWxgL1Id

点击中间区域
呼出菜单
上一章
目录
下一章
×