【5】深度学习之Pytorch——如何使用张量处理文本数据集(语料库数据集)

在计算机领域,不断崛起的两个领域,一个是CV一个是NLP,下面我们可以探索一下深度学习在NLP的应用和特点。

深度学习在自然语言处理(NLP)领域有广泛的应用。以下是一些主要的应用和特点:

  • 语音识别:深度学习模型可以通过语音数据训练,学习如何将语音转换为文本。

  • 文本分类:深度学习模型可以根据文本内容将文本分为不同的类别。例如,情感分析、主题分类等。

  • 机器翻译:深度学习模型可以将一种语言翻译成另一种语言。神经机器翻译是一种基于深度学习的翻译方法。

  • 语言生成:深度学习模型可以生成自然语言文本。例如,文本摘要、对话系统等。

  • 命名实体识别:深度学习模型可以识别文本中的命名实体,例如人名、地名、组织名等。

  • 语言模型:深度学习模型可以学习自然语言的规律和概率分布,用于文本生成、语音识别等任务。

在NLP领域中,深度学习的主要特点包括:

  • 端到端学习:深度学习模型可以直接从原始数据学习,不需要手工提取特征。这使得深度学习在NLP领域中的应用更加灵活和高效。

  • 高度表征:深度学习模型可以学习文本的高级表征,这些表征可以帮助解决NLP任务中的挑战,例如语义理解、上下文处理等。

  • 多层次抽象:深度学习模型可以通过多层次抽象学习文本的语义信息,从而实现对复杂NLP任务的处理。

  • 可扩展性:深度学习模型可以通过增加层数、节点等方式增强其性能,这使得它们适用于各种规模的NLP任务。

深度学习席卷了自然语言处理(natural language processing, NLP)领域,尤其是通过使用不断消耗输入和模型先前输出相结合的模型。这种模型称为递归神经网络(recurrent neural networks, RNN),它已被成功应用于文本分类、文本生成和自动翻译系统。在这之前的NLP工作的特点是复杂的多阶段处理流程,包括编码语言语法的规则。

目前,最先进的(state-of-the-art)工作在大型语料库上端到端地从头开始训练网络,让这些规则从数据中浮现出来。在过去的几年中,互联网上最常用的自动翻译系统服务就是基于深度学习的。

网络在两个级别上对文本进行操作:在字符级别上一次处理一个字符而在单词级别上单词是网络中最细粒度的实体。无论是在字符级别还是在单词级别操作,将文本信息编码为张量形式的技术都是相同的,这种就是独热编码。

本期文章的数据集,可以是一本书籍。任意的名著都可以,中英文的数据都可以进行。

读取数据集

with open('./other.txt', encoding='utf8') as f:
    text = f.read()

注意一个细节:编码(encoding)。编码是一个宽泛的词,因此我们现在要做的就是实际“触摸”它。每个字符都由一个代码表示,该代码是一系列适当长度的比特(bit)位,它可以唯一地标识每个字符。最简单的这种编码是ASCII(American Standard Code for Information Interchange),其历史可以追溯到1960年代。ASCII使用128个整数对128个字符进行编码。例如,字母“a”对应于二进制1100001或十进制97;字母“b”对应于二进制1100010或十进制98,依此类推。该编码刚好8位,这在1965年是一个很大的收获。

注意:显然,128个字符不足以正确表示除英语之外的其他书面文字所需的所有字形、字音、连字等等。为此,其他编码被开发了出来,用更多的比特位代码表示更大范围的字符。更大范围的字符被标准化为Unicode编码,它将所有已知字符映射为数字,这些数字的位表示由特定编码提供。流行的编码包括UTF-8、UTF-16和UTF-32,对应数字分别是8位、16位或32位整数的序列。 Python 3.x中的字符串是Unicode字符串。

你将对字符进行独热编码,以将独热编码限制为对要分析的文本有用的字符集。在本例中,因为你以英文加载了文本,所以使用ASCII这种小型编码是非常安全的。你也可以将所有字符都转换为小写,以减少编码中的字符数。同样,你还可以筛选出与预期的文本类型无关的标点符号、数字和其他字符,这可能会也可能不会对你的神经网络产生实际的影响。

这就是在进行数据的一个预处理过程,一般中文中,我们可以使用jieba分词库,然后使用一些停用词过滤掉那些无意义的字符。

每个字符将由一个长度等于编码中字符数的向量表示。该向量除了有一个元素是1外其他全为0,这个1的索引对应该字符在字符集中的位置。

将每一行的数据作为一个元素,用列表的形式存储起来

lines = text.split('\n')
line = lines[200]
line
'“Impossible, Mr. Bennet, impossible, when I am not acquainted with him'

创建一个张量,该张量可以容纳整行的独热编码的字符总数:

letter_tensor = torch.zeros(len(line), 128) # 128是由于ASCII的限制
letter_tensor.shape
torch.Size([70, 128])

letter_tensor每行将要表示一个独热编码字符。现在在每一行正确位置上设置成1,以使每一行代表正确的字符。设置1的索引对应于编码中字符的索引:

for i, letter in enumerate(line.lower().strip()):
    # 文本里含有双引号,不是有效的ASCII,因此在此处将其屏蔽
    letter_index = ord(letter) if ord(letter) < 128 else 0
    letter_tensor[i][letter_index] = 1

你已经将句子独热编码成神经网络可以使用的表示形式。你也可以沿张量的行,通过建立词汇表来在词级别(word-level)对句子(即词序列)进行独热编码(也就是分词)。由于词汇表包含许多单词,因此该方法会产生可能不是很实际的很宽的编码向量。

定义clean_words函数,它接受文本并将其返回小写并删除标点符号。在“Impossible, Mr. Bennet”行上调用它时,会得到以下信息:

def clean_words(input_str):
    punctuation = '.,;:"!?”“_-'
    word_list = input_str.lower().replace('\n',' ').split()
    word_list = [word.strip(punctuation) for word in word_list]
    return word_list
words_in_line = clean_words(line)
line, words_in_line
('“Impossible, Mr. Bennet, impossible, when I am not acquainted with him',
 ['impossible',
  'mr',
  'bennet',
  'impossible',
  'when',
  'i',
  'am',
  'not',
  'acquainted',
  'with',
  'him'])

接下来,在编码中建立单词到索引的映射:

word_list = sorted(set(clean_words(text)))
word2index_dict = {
    
    word: i for (i, word) in enumerate(word_list)}
len(word2index_dict), word2index_dict['impossible']
(7261, 3394)

请注意,word2index_dict现在是一个字典,其中单词作为键,而整数作为值。独热编码时,你将使用此词典来有效地找到单词的索引。

现在专注于句子,将其分解为单词并对其进行独热编码(即对每个单词使用一个独热编码向量来填充张量)。先创建一个空向量,然后赋值成句子中的单词的独热编码:

word_tensor = torch.zeros(len(words_in_line), len(word2index_dict))
for i, word in enumerate(words_in_line):
    word_index = word2index_dict[word]
    word_tensor[i][word_index] = 1
    print('{:2} {:4} {}'.format(i, word_index, word))

print(word_tensor.shape)
 0 3394 impossible
 1 4305 mr
 2  813 bennet
 3 3394 impossible
 4 7078 when
 5 3315 i
 6  415 am
 7 4436 not
 8  239 acquainted
 9 7148 with
10 3215 him
torch.Size([11, 7261])

此时,word_tensor表示长度为11编码长度为7261(这是字典中单词的数量)的一个句子。

每文一语

时间也会带给你成长的!

猜你喜欢

转载自blog.csdn.net/weixin_47723732/article/details/129167940
今日推荐