在我参考的代码中,有直接加载的,一般是进行预处理后进行自定义自己的词库,然后利用 已有预训练好的 词向量进行 编码:
1.glove 模型:
def process_questions(args): ''' Encode question tokens''' print('Loading data')
#加载你的数据集
with open(args.annotation_file, 'r') as dataset_file: instances = json.load(dataset_file) # Either create the vocab or load it from disk
#分情况进行编码,如果是train的话需要制作词汇表,val和test使用train的词汇,为了泛化能力
if args.mode in ['train']: print('Building vocab') answer_cnt = {}
#进行词频统计 for instance in instances: answer = instance['answer'] answer_cnt[answer] = answer_cnt.get(answer, 0) + 1 # dic字典独有的得到词和方式,如果得不到用0填充 answer_token_to_idx = {'<UNK0>': 0, '<UNK1>': 1} answer_counter = Counter(answer_cnt) frequent_answers = answer_counter.most_common(args.answer_top) #选择最多的词汇进行编码,去除低频词,避免过多词训练起来很慢 total_ans = sum(item[1] for item in answer_counter.items()) total_freq_ans = sum(item[1] for item in frequent_answers) print("Number of unique answers:", len(answer_counter)) print("Total number of answers:", total_ans) print("Top %i answers account for %f%%" % (len(frequent_answers), total_freq_ans * 100.0 / total_ans))
#制作答案的词汇表 for token, cnt in Counter(answer_cnt).most_common(args.answer_top): answer_token_to_idx[token] = len(answer_token_to_idx) print('Get answer_token_to_idx, num: %d' % len(answer_token_to_idx)) #制作问题的词汇表,期间进行了 分词操作 question_token_to_idx = {'<NULL>': 0, '<UNK>': 1} for i, instance in enumerate(instances): question = instance['question'].lower()[:-1] for token in nltk.word_tokenize(question): if token not in question_token_to_idx: question_token_to_idx[token] = len(question_token_to_idx) print('Get question_token_to_idx') print(len(question_token_to_idx)) vocab = { 'question_token_to_idx': question_token_to_idx, 'answer_token_to_idx': answer_token_to_idx, 'question_answer_token_to_idx': {'<NULL>': 0, '<UNK>': 1} } #词汇表的存储,以便val和test的时候使用 print('Write into %s' % args.vocab_json.format(args.dataset, args.dataset)) with open(args.vocab_json.format(args.dataset, args.dataset), 'w') as f: json.dump(vocab, f, indent=4) else: print('Loading vocab') with open(args.vocab_json.format(args.dataset, args.dataset), 'r') as f: vocab = json.load(f) # Encode all questions print('Encoding data') questions_encoded = [] questions_len = [] question_ids = [] video_ids_tbw = [] video_names_tbw = [] all_answers = [] for idx, instance in enumerate(instances): question = instance['question'].lower()[:-1] question_tokens = nltk.word_tokenize(question)
#上面一行是进行token处理,下面一行是进行把token转换成数字 question_encoded = utils.encode(question_tokens, vocab['question_token_to_idx'], allow_unk=True) questions_encoded.append(question_encoded) questions_len.append(len(question_encoded)) question_ids.append(idx) im_name = instance['video_id'] video_ids_tbw.append(im_name) video_names_tbw.append(im_name) if instance['answer'] in vocab['answer_token_to_idx']: answer = vocab['answer_token_to_idx'][instance['answer']] elif args.mode in ['train']: answer = 0 elif args.mode in ['val', 'test']: answer = 1 all_answers.append(answer) max_question_length = max(len(x) for x in questions_encoded) for qe in questions_encoded:
#进行填充,让question每一个都是同样大小,相当于pad操作 while len(qe) < max_question_length: qe.append(vocab['question_token_to_idx']['<NULL>']) questions_encoded = np.asarray(questions_encoded, dtype=np.int32) questions_len = np.asarray(questions_len, dtype=np.int32) print(questions_encoded.shape) glove_matrix = None if args.mode == 'train':
#这里利用我们自定义的表,自制预训练的词向量,让它按照我们词汇表的顺序。 token_itow = {i: w for w, i in vocab['question_token_to_idx'].items()} print("Load glove from %s" % args.glove_pt) glove = pickle.load(open(args.glove_pt, 'rb')) dim_word = glove['the'].shape[0] glove_matrix = [] for i in range(len(token_itow)): vector = glove.get(token_itow[i], np.zeros((dim_word,))) #没有的词汇一律变成 0向量 glove_matrix.append(vector) #按照我们自己自定义的词汇表进行编码,所以是这样子进行append glove_matrix = np.asarray(glove_matrix, dtype=np.float32) print(glove_matrix.shape) print('Writing', args.output_pt.format(args.dataset, args.dataset, args.mode)) obj = { 'questions': questions_encoded, 'questions_len': questions_len, 'question_id': question_ids, 'video_ids': np.asarray(video_ids_tbw), 'video_names': np.array(video_names_tbw), 'answers': all_answers, 'glove': glove_matrix, } with open(args.output_pt.format(args.dataset, args.dataset, args.mode), 'wb') as f: pickle.dump(obj, f)
2.