基于pytorch 自己训练文本词向量
如今的NLP自然语言处理,大多以及抛弃TF-IDF词频逆文档处理模型,而是通过训练word2vec词向量模型;目前开源的词向量模型数据集公认较好的是腾讯词向量,不过该数据集超过16G,一般配置可能都无法打开使用,
因此可以根据实际需求自行训练需要的词向量模型,这里提供一种训练词向量的一个实例,不过语料库一定要多,效果更好。
结果图片如下:
词向量结果(此处选择5维,一般为300维)
大王==>[-1.1550105810165405, -2.516174077987671, -4.601747035980225, 5.313472270965576, -2.1049396991729736]
罪名==>
女魔头==>
以怨==>[-0.009275288321077824, -1.6428550481796265, 1.7217854261398315, 3.149597644805908, -0.4327169954776764]
良苦==>
扇求==>[-0.5084913372993469, -5.254477024078369, -4.2640275955200195, -3.659550666809082, -2.7392685413360596]
大理==>[-1.827543020248413, 2.1979267597198486, 1.2208789587020874, 3.172173261642456, -0.9367401599884033]
并立==>[-1.6337153911590576, 4.030898571014404, 2.178544044494629, 3.914534568786621, -0.7697797417640686]
穿帘==>
云南==>
天龙八部==>
文斗==>[-2.192509651184082, 0.4625106155872345, 1.490928053855896, -1.5388060808181763, -3.8620612621307373]
普通==>[-0.038421038538217545, 1.416630744934082, -1.1946618556976318, 2.9260082244873047, 5.175168037414551]
代码:
import torch
import numpy as np
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as Data
import jieba
dtype = torch.FloatTensor
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
np.random.seed(123)
#1.初步整理训练数据 ()
#### 注:语料库尽可能的大,尽可能包含实验或者项目的所有文档,对话,等各种文本资料(此处主要体现训练的过程,以及设备的限制(gpu:GTX1060))
docments = ["重庆工商大学统计学院重庆理工大学",
"山村赘婿李子安偶得西周方士传承,大惰随身炉傍身,医、卜、星、相样样精通,要风得龙卷,要雨发大水。软饭也是饭,但得讲究个吃法。李子安吃软饭,那姿势讲究可就大了",
"私生子文斗奸臣,武斗胡人。内忧外患的双重打击,让南宋大厦摇摇欲坠",
"买哪里看小说免费上万能的淘宝!优享品质,惊喜价格!",
"《天龙八部》一书以北宋、辽、西夏、大理并立的历史为宏大背景,将儒释道、琴棋书画等中国传统文化融会贯通其中,书中人物繁多,个性鲜明,情节离奇,尽显芸芸众生百态。丐帮帮主乔峰与大理国王子段誉、少林弟子虚竹结为兄弟。他身为大宋武林第一大帮帮主,发现自己竟是契丹人,虽受尽中原武林人士唾弃而不肯以怨报怨;他身为辽国南院大王,却甘愿背上叛族罪名,最终以悲壮的自杀来阻止辽国发兵攻宋,不愧为顶天立地的大英雄",
"这是金庸先生最后一部武侠小说,也是登峰造极之作!小说讲的是一个从小在扬州妓院长大的小孩韦小宝,他以不会任何武功之姿态闯江湖各大帮会、周旋皇帝朝臣之间并奉旨远征云南、俄罗斯之故事,书中充满精彩绝倒的对白及逆思考的事件!金庸先生将韦小宝的个人经历与历史密密切合,大玩历史哈哈镜的手法,令人赞叹,几乎信以为真,而小宝的做人方法及毫不留情的揭出人生各阶层黑暗面这种做法,使得这部书成了不是武侠小说的武侠小说,到了无剑胜有剑的境地。韦小宝是个最最普通的人,好像也就是在你我身边的那些人一样。",
"连夕阳照进来,都变成一种不吉祥的死灰色",
"《云海玉弓缘》是梁氏武侠天山系列最出名的两部小说之一(另一部是《白发魔女传》),故事发生在清朝中期。主要是厉胜男向魔头孟神通复仇并借此成为另一个“女魔头”的故事",
"灯火阑珊,暗香浮动,伊人何处?露白葭苍,曾是旧时行路。清梦已随潮咽尽,怅望家山云树。恨鸿爪还留,盟鸥非旧,又西飞去。记宝扇求诗,香巾索字,见笑当年崔护。燕子穿帘,早入王堂谢户。凌波微步姗姗远,肠断江郎别浦。怕桃叶桃根,他年重见,此心良苦",
]
word_cuts = jieba.lcut(" ".join(docments))
# #停用词处理 (根据需求整理停用词)
stop_lst =
word_sequence =
vocab = list(set(word_sequence))
word2idx = {w:i for i,w in enumerate(vocab) if w}
#2.参数设置
epochs = 200#根据训练的实际情况自行调整
batch_size = 16
embedding_size = 5# 每次词语5维向量表示 (可以自行设置,通常工业界设置为300维,或150维)
C = 2 # 前后几个词语预测
voc_size = len(vocab) #词向量大小(即词语总数)
#3.通过skip 模型 整理训练数据
# skip_grams: [,,,,,...]
skip_grams = []
for idx in range(C, len(word_sequence) - C):
center = word2idx] # center word
context_idx = list(range(idx - C, idx)) + list(range(idx + 1, idx + C + 1)) # context word idx
context = ] for i in context_idx]
for w in context:
skip_grams.append()
print(skip_grams[:2])
def make_data(skip_grams):
input_data = []
output_data = []
for i in range(len(skip_grams)):
input_data.append(np.eye(voc_size)]) # central word
output_data.append(skip_grams) # background word
return input_data, output_data
# 4.整理最终需要训练的数据
input_data, output_data = make_data(skip_grams)
input_data, output_data = torch.Tensor(input_data), torch.LongTensor(output_data)
dataset = Data.TensorDataset(input_data, output_data)
loader = Data.DataLoader(dataset, batch_size, True)
5.构建网络结构 Model
class Word2Vec(nn.Module):
def __init__(self):
super(Word2Vec, self).__init__()
# W and V is not Traspose relationship
self.W = nn.Parameter(torch.randn(voc_size, embedding_size).type(dtype))
self.V = nn.Parameter(torch.randn(embedding_size, voc_size).type(dtype))
def forward(self, X):
# X : one-hot
# torch.mm only for 2 dim matrix, but torch.matmul can use to any dim
hidden_layer = torch.matmul(X, self.W) # hidden_layer :
output_layer = torch.matmul(hidden_layer, self.V) # output_layer :
return output_layer
model = Word2Vec().to(device)
criterion = nn.CrossEntropyLoss().to(device)
optimizer = optim.Adam(model.parameters(), lr=1e-3)
#6.正式训练
for epoch in range(epochs):
for i, (batch_x, batch_y) in enumerate(loader):
batch_x = batch_x.to(device)
batch_y = batch_y.to(device)
#print('batch_x:',batch_x)
#print('batch_y:',batch_y)
pred = model(batch_x)
loss = criterion(pred, batch_y)
if (epoch + 1) % 100 == 0:
print(epoch + 1, i, loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
#7.可视化展示,直观查看训练结果 (可选步骤,训练数据太大,图中效果不明显)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(10,8))
for i, label in enumerate(vocab):
W, WT = model.parameters()
x,y = float(W), float(W)
plt.scatter(x, y)
plt.annotate(label, xy=(x, y), xytext=(5, 2), textcoords='offset points', ha='right', va='bottom')
if i > 50:
break
plt.show()
#查询训练结果len(docments)* embedding_size
W, WT = model.parameters()
word_vec = {voc:w for voc,w in zip(vocab,W.tolist())}
for name,words in word_vec.items():
print("{}==>{}".format(name,words)) 感谢分享 现在做词向量不是都用BERT、Transformer....之类的吗 感谢分享 感谢分享学习经历 苏晓宇c 发表于 2021-9-30 20:26
现在做词向量不是都用BERT、Transformer....之类的吗
主要BERT,Transformer尤其GPT2,GPT3出现后,个人机器基本无法跑,(当然Bert,Transformer目前应用都是微调)
当然如果你能跑腾讯的词向量了, 你的算力也可以做很多事情了;
主要考虑个人机器可以玩一玩
感谢分享学习一下
页:
[1]