实验性的CBOW代码

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在起作用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容