AI智能
改变未来

《TensorFlow 实战Google深度学习框架 》学习 20190809

选用PTB数据集

首先将这10000个不同的词汇分别映射到0~9999之间的整数编号。下面代码为每个词汇分配一个编号,然后将词汇表保存到一个独立的vocab文件中。

# -*- coding: utf-8 -*-import codecsimport collectionsfrom operator import itemgetterRAW_DATA=\"E:/PTB数据集/simple-examples/simple-examples/data/ptb.train.txt\"VOCAB_OUTPUT=\"ptb.vocab\"#输出的词汇表文件counter=collections.Counter()#统计单词出现的频率with codecs.open(RAW_DATA, \"r\", \"utf-8\") as f:for line in f:for word in line.strip().split():counter[word]+=1#print(counter)#Counter({\'the\': 50770, \'<unk>\': 45020, \'N\': 32481, \'of\': 24400, \'to\': 23638,.....})#按照词频顺序对单词进行排序sorted_word_to_cnt = sorted(counter.items(),key=itemgetter(1),reverse=True)sorted_words = [x[0] for x in sorted_word_to_cnt]#print(sorted_words)#[\'the\', \'<unk>\', \'N\', \'of\', \'to\', \'a\', \'in\', \'and\', \"\'s\",sorted_words = [\"<eos>\"]+ sorted_words#print(sorted_words)#[\'<eos>\', \'the\', \'<unk>\', \'N\', \'owith codecs.open(VOCAB_OUTPUT,\"w\",\"utf-8\") as file_output:for word in sorted_words:file_output.write(word+\'\\n\')print(sorted_words)

vocab文件如下所示,共10000个词:

确定词汇表后,将表中词汇转化为单词编号

# -*- coding: utf-8 -*-import codecsimport sysRAW_DATA=\"E:/PTB数据集/simple-examples/simple-examples/data/ptb.train.txt\"VOCAB=\"ptb.vocab\"OUTPUT_DATA=\"ptb.train\"#将单词替换为数字编号后的输出文件with codecs.open(VOCAB, \"r\", \"utf-8\") as f_vocab:vocab = [w.strip() for w in f_vocab.readlines()]word_to_id = {k: v for (k,v) in zip (vocab, range(len(vocab)))}#print(word_to_id)#{\'<eos>\': 0, \'the\': 1, \'<unk>\': 2, \'N\': 3, \'of\': 4, \'to\': 5, \'a\': 6, \'in\': 7, \'and\': 8,...}def get_id(word):#如果出现了被删除的低频词,则替换为\"<unk>\"return word_to_id[word] if word in word_to_id else word_to_id[\"<unk>\"]fin = codecs.open(RAW_DATA, \"r\", \"utf-8\")fout = codecs.open(OUTPUT_DATA,\"w\",\"utf-8\")for line in fin:words = line.strip().split() + [\"<eos>\"]#读取单词并添加<eos>结束符out_line=\' \'.join([str(get_id(w)) for w in words]) +\'\\n\' #将每个单词替换为词汇表中的编号,并给词之间加上空格fout.write(out_line)fin.close()fout.close()

 处理好的ptb.train如下图所示

从上图可以看出,每个句子的长度是不一样的,生成的数字序列长度也是不一样的,因此在对文本数据进行batching时需要采取一些特殊操作,比如填充(padding),将同一batch内的句子长度补齐。

在喂数据时候,不可能将所有句子连接起来一起送入网络,序列过长可能导致训练中梯度爆炸的问题。对此问题的解决方法是,将长序列切割为固定长度的子序列。

循环神经网络在处理完一个子序列后,它最终的隐藏状态将复制到下一个序列中作为初值,这样在前向计算时,效果等同于一次性顺序地读取了整个文档。

为了利于计算时的并行能力,我们希望每一次可以对多个句子进行并行处理,同时又要尽量保证batch之间的上下文连续。解决方法是,先将整个文档且分为若干连续段落,再让batch中的每一个位置负责其中一段。例如,如果batch大小是4,则先将整个文档平均分成4个子序列,让batch中的每一个位置负责其中一个子序列,这样子序列内部的所有数据仍可以被顺序处理。

 

转载于:https://www.cnblogs.com/beautifulchenxi/p/11328207.html

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 《TensorFlow 实战Google深度学习框架 》学习 20190809