阅读理解实战(一)
BIDAF基线模型 【阅读理解实战(一)】基线系统实现
数据集分析 数据集是DuReader,特点是一个问题对应着多篇文章,我们要从多篇文章中抽取出正确的答案。
一条训练数据样式如下:
文章图片
预处理 这里使用的是训练好的sgns.wiki.word的词向量
下载地址为sgns.wiki.word
也可以建立词表,随机初始化词向量
def prepare(args):
"""
checks data, creates the directories, prepare the vocabulary and embeddings
检查数据,创建目录,准备词汇表和嵌入
"""
logger = logging.getLogger("brc")
logger.info('Checking the data files...')
#检查路径是否存在
for data_path in args.train_files + args.dev_files + args.test_files:
assert os.path.exists(data_path), '{} file does not exist.'.format(data_path)
logger.info('Preparing the directories...')
#准备路径,不存在则创建目录
for dir_path in [args.vocab_dir, args.model_dir, args.result_dir, args.summary_dir]:
if not os.path.exists(dir_path):
os.makedirs(dir_path)
#建立词表
logger.info('Building vocabulary...')
brc_data = https://www.it610.com/article/BRCDataset(args.max_p_num, args.max_p_len, args.max_q_len,
args.train_files, args.dev_files, args.test_files)
vocab = Vocab(lower=True)
for word in brc_data.word_iter('train'):#将训练集中的问题和文章中的token加入到vocab中
vocab.add(word)unfiltered_vocab_size = vocab.size()#没有过滤的词表大小
vocab.filter_tokens_by_cnt(min_cnt=2) #过滤频次小于2的token
filtered_num = unfiltered_vocab_size - vocab.size()#filtered过滤的token 数量
logger.info('After filter {} tokens, the final vocab size is {}'.format(filtered_num,
vocab.size()))
#经过多少个token的过滤,最后词表的规模是
logger.info('Assigning embeddings...')#构建词向量 ,随机初始化词向量
#vocab.randomly_init_embeddings(args.embed_size)
vocab.load_pretrained_embeddings('../data/sgns.wiki.word')logger.info('Saving vocab...')
with open(os.path.join(args.vocab_dir, 'vocab.data'), 'wb') as fout:#写入
pickle.dump(vocab, fout)logger.info('Done with preparing!') #准备完成
同时因为加载的wiki第一排显示的是词表大小和维度,所以要注意跳过词表的第一行
def load_pretrained_embeddings(self, embedding_path):
"""
loads the pretrained embeddings from embedding_path,
tokens not in pretrained embeddings will be filtered
Args:
embedding_path: the path of the pretrained embedding file
"""
trained_embeddings = {}
#字典
with open(embedding_path, 'r') as fin:
for i,line in enumerate(fin):
if i==0:
continue
contents = line.strip().split() #split 以空格为分隔符切片
token = contents[0]#.decode('utf8')
#contents[0]是token单词
if token not in self.token2id:
#若原先训练好的词没有在新建立的词表中,则跳过本次循环,相当于过滤掉原先训练好词表中在训练集没有出现的词
continue
trained_embeddings[token] = list(map(float, contents[1:]))#将一组向量转换成float
#token对应embedding建立映射
if self.embed_dim is None:
self.embed_dim = len(contents) - 1
filtered_tokens = trained_embeddings.keys()#过滤掉后剩余的词
#也就是筛选出训练好的词向量与训练集词表重合的词向量trained_embeddings = {}
# rebuild the token x id map重新建立映射
self.token2id = {}
self.id2token = {}
for token in self.initial_tokens: #向token2id,id2token中增加特殊字符
self.add(token, cnt=0)
for token in filtered_tokens:#遍历筛选出的token加入token2id,id2token
self.add(token, cnt=0)
# load embeddings加载embedding
self.embeddings = np.zeros([self.size(), self.embed_dim])
for token in self.token2id.keys():
if token in trained_embeddings: #若token在训练好的trained_embeddings中
self.embeddings[self.get_id(token)] = trained_embeddings[token]
#建立该词新ID和embedding的映射
第一步,词表建立完成,准备完成!

文章图片
推荐阅读
- 一个人的旅行,三亚
- 一个小故事,我的思考。
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 开学第一天(下)
- 一个人的碎碎念
- 2018年11月19日|2018年11月19日 星期一 亲子日记第144篇
- 遇到一哭二闹三打滚的孩子,怎么办┃山伯教育
- 第326天
- Y房东的后半生14
- 奔向你的城市