实验性的CBOW代码
2023-06-28 本文已影响0人
圣_狒司机
CBOW是embedding的基础方法,它与skip-gram合称word2vec模型,在gensim里有现成的实现,这里将其实验性的实现一次,然后心安理得的调用已有的语言分析库。
这是被翻烂了的CBOW原理图:
CBOW原理
import torch
from torch.nn import Sequential,Linear,LeakyReLU,CrossEntropyLoss
from torch.optim import Adam
from torch.utils.data import DataLoader
from itertools import chain
import numpy as np
from rich.progress import track
from sklearn.decomposition import PCA
def train(c=1000):
for epoch in track(range(c)):
for x,y in dataset:
opt.zero_grad()
y_onehot = torch.zeros(100,dtype=torch.float32)
y_onehot[y] = 1
x = encoder(torch.tensor(x,dtype=torch.float32).view(-1,1)).sum(axis=0)
y = encoder(torch.tensor(y,dtype=torch.float32).view(1))
y_deocode = decoder(y)
loss = loss_fn(y_deocode,y_onehot) + loss_fn(x,y)
loss.backward()
opt.step()
encoder = Sequential(Linear(1,9),LeakyReLU())
decoder = Sequential(Linear(9,100),LeakyReLU())
loss_fn = CrossEntropyLoss()
opt = Adam(params=chain(encoder.parameters(),decoder.parameters()),lr=1e-3)
corpus = np.random.randint(1,100,size=1000)
dataset = zip(corpus,corpus[1:],corpus[2:])
dataset = [((i[0],i[-1]),i[1]) for i in dataset]
仅仅100个词用1.2G Intel core i5 CPU训练25分钟!用GPU加速也用15分钟,可见没钱不要玩语义大模型训练。
用PCA把做好的embedding层降维成二维的方便展示。
train()
d = encoder(torch.linspace(0,99,100,dtype=torch.float32).view(-1,1),).detach().numpy()
d = PCA(n_components=2).fit_transform(d)
plt.scatter(d[:,0],d[:,1])
output.png
这些点的些许空间结构性就是CBOW在起作用。