如何在深度学习过程中使用预训练的词表征(持续更新ing...)

诸神缄默不语-个人CSDN博文目录

本文介绍在深度学习中如何应用预训练的词表征(word2vec等),应用到的框架包括numpy、PyTorch和TensorFlow

不同形式,见到了就补充总结一下。

最近更新时间:2023.3.3
最早更新时间:2022.12.15

1. 将预训练文件加载为numpy.ndarray/torch.Tensor格式的矩阵对象

这两类很容易互相转换,所以我就混着写了。

padding向量(PaddingBLANK)一般都是全0(这样叠mask方便)
UNK向量可以是其他向量的平均池化,也可以随便初始化一个向量

  1. word2id字典文件(用pickle保存)和预训练权重矩阵(用np.save保存)(范例:LADAN)
    1. 写法1(这是LADAN自己写的)
with open('w2id_thulac.pkl', 'rb') as f:
    word2id_dict = pk.load(f)
    f.close()

emb_path='cail_thulac.npy'
word_embedding=np.cast[np.float32](np.load(emb_path))

   2. 写法2(这是我自己写的,我觉得能比较明显地看出,我在代码简练程度上的这个,匮乏……)

with open('w2id_thulac.pkl', 'rb') as f:
    word2id_dict = pickle.load(f)
embedding_file_path='cail_thulac.npy'
embedding_weight=np.load(embedding_file_path)
embedding_dim=embedding_weight.shape[1]  #词向量维度
embedding_weight[word2id_dict['BLANK']]=[0 for _ in range(embedding_dim)]
  1. word2vec.json文件和idx2word.json文件(word2id.json文件也行,反正就是直接翻过来)(范例:NeurJudge)
    需要注意的是,不能直接用np.ndarraytorch.FloatTensor来表征后不进行初始化,可以用zeros()zero_()等函数来初始为全0
    1. 写法1
word2vec = json.load(open('./word2vec.json', "r"))
word2vec['UNK'] = np.random.randn(200).tolist() 
word2vec['Padding'] = [0. for i in range(200)]
embedding = torch.FloatTensor(339503, 200).zero_()
idx2word = json.load(open('./idx2word.json', "r"))
for i in tqdm(range(339503)):
    word = idx2word[str(i)]
    result = list(map(float, word2vec[word]))
    embedding[i] = torch.from_numpy(np.array(result))

   2. 写法2

word2id=json.load(open('word2vec/word2id.json'))
word2vec=json.load(open('word2vec/word2vec.json'))
word2vec['UNK'] = np.random.randn(200).tolist() 
word2vec['Padding'] = [0. for i in range(200)]
embedding=np.zeros((339503,200))
for k in word2id:
    embedding[word2id[k],:]=[float(factor) for factor in word2vec[k]]
embedding=torch.from_numpy(embedding)

2. 建立模型中的表征层

2.1 TensorFlow 1.14

示例代码改自LADAN项目

扫描二维码关注公众号,回复: 14935172 查看本文章
description_layer=tf.nn.embedding_lookup(word_embedding,num_input)

word_embedding是np.ndarray格式的词向量矩阵,num_input是转换为数字格式并padding好的文本矩阵

2.2 PyTorch

示例代码改自NeurJudge项目
torch.nn.Module子类__init__()中:
(本代码是不在训练过程中更新embedding权重的意思)

self.embs = nn.Embedding(339503, 200)
self.embs.weight.data.copy_(embedding)
self.embs.weight.requires_grad = False

改自CECP项目

word_embedding = embedding_weight.astype(np.float32)

2.3 直接池化为文档表征

这个主要是比如说KNN、SVM之类的传统机器学习模型,可以一波塞进去(跳过将文本转换为数字这一步,直接进行平均值池化)

total_vector=np.zeros((sample_num,300))
for i in range(len(segmentated_names)):  #分词好的文本列表
    segmentated_name=segmentated_names[i]
    id_list=[]
    for j in segmentated_name:
        if j in word2id:  #对于词表中存在的词
            id_list.append(embedding_weight[word2id[j]])
        else:
            id_list.append(embedding_weight[word2id['UNK']])
    
    if len(id_list)==0:
        total_vector[i,:]=embedding_weight[word2id['UNK']]
    else:
        total_vector[i,:]=np.mean(np.array(id_list),axis=0)
print(total_vector)

3. 将文本转换为数字

  1. 分词后使用word2id词典:改自LADAN
    遍历每个样本,在每个样本内:
for j in range(int(min(len(fact), max_length))):  #遍历最长句长内的每个词
    if fact[j] in word2id_dict:  #对于词表中存在的词
        id_list.append(int(word2id_dict[fact[j]]))
    else:
        id_list.append(int(word2id_dict['UNK']))
while len(id_list) < 512:  #padding
    id_list.append(int(word2id_dict['BLANK']))
  1. NeurJudge版的实现,是将整个过程打包成了很多小环节
def transform(self, word):
	"""将词语转换为索引"""
    if not (word in self.word2id.keys()):
        return self.word2id["UNK"]
    else:
        return self.word2id[word]

def seq2tensor(self, sents, max_len=350):
	"""将句子序列转换为词索引tensor,注意这里句子序列每个元素是一个已经分词好的list"""
    sent_len_max = max([len(s) for s in sents])
    sent_len_max = min(sent_len_max, max_len)

    sent_tensor = torch.LongTensor(len(sents), sent_len_max).zero_()

    sent_len = torch.LongTensor(len(sents)).zero_()
    for s_id, sent in enumerate(sents):
        sent_len[s_id] = len(sent)
        for w_id, word in enumerate(sent):
            if w_id >= sent_len_max: break
            sent_tensor[s_id][w_id] = self.transform(word) 
    return sent_tensor,sent_len

猜你喜欢

转载自blog.csdn.net/PolarisRisingWar/article/details/128329325