6.4pytorch实现skipgram模型(代码片段)

王小小小草 王小小小草     2023-02-14     357

关键词:

欢迎订阅本专栏:《PyTorch深度学习实践》
订阅地址:https://blog.csdn.net/sinat_33761963/category_9720080.html

  • 第二章:认识Tensor的类型、创建、存储、api等,打好Tensor的基础,是进行PyTorch深度学习实践的重中之重的基础。
  • 第三章:学习PyTorch如何读入各种外部数据
  • 第四章:利用PyTorch从头到尾创建、训练、评估一个模型,理解与熟悉PyTorch实现模型的每个步骤,用到的模块与方法。
  • 第五章:学习如何利用PyTorch提供的3种方法去创建各种模型结构。
  • 第六章:利用PyTorch实现简单与经典的模型全过程:简单二分类、手写字体识别、词向量的实现、自编码器实现。
  • 第七章:利用PyTorch实现复杂模型:翻译机(nlp领域)、生成对抗网络(GAN)、强化学习(RL)、风格迁移(cv领域)。
  • 第八章:PyTorch的其他高级用法:模型在不同框架之间的迁移、可视化、多个GPU并行计算。

skipgram是很经典的词向量模型,在大量的语料上进行训练,得到每个词的嵌入向量。

相关论文

  • “Distributed Representations of Sentences and Documents”
  • “Efficient estimation of word representations in vector space”

相关博客

  • 网上搜索“word2vec","skipgram"一搜一大把
  • 对词向量的系统了解可以参考我的博客:https://blog.csdn.net/sinat_33761963/article/details/53521149

现在来看看PyTorch如何实现Skipgram并训练后获取词向量。

6.4.1 准备数据

准备语料:一般情况下语料会存储在文本文件中,一句话为一行,用python都进来后存放在一个list中,每个元素是文本中的一行。接着对每行为本做分词,英文可以直接按照空格分,中文就需要用到分词器了,分割后就得到了以下代码中的corpus_list。

构建词典:这一步不可或缺,我们要将每个词都转换成数字代表的索引,方便模型识别,而模型输出的索引,也需要再转变为文字,方便人查看。因此,需要建立两个dict, 一个是索引:词, 一个是词:索引,即代码中的ix2word, word2ix。

构建训练对:语料一方面用于构建词典,另一方面需要预处理成模型可以读入的训练对(x,y), skipgram是输入中心词,预测上下文词,因此其数据对应为(center_word, contenx_word),且需要转换成索引形式(center_word_ix, contenx_word_ix)

import torch
import torch.nn as nn
import torch.nn.functional as F

# 准备语料
corpus = ['he is a king',
          'she is a queen',
          'he is a man',
          'she is a woman',
          'warsaw is poland capital',
          'berlin is germany capital',
          'paris is france capital']
corpus_list = [sentence.split() for sentence in corpus]


# 构建词典
word2ix = 
for sentence in corpus:
    for word in sentence.split():
        if word not in word2ix:
            word2ix[word] = len(word2ix)  # 为每个词都匹配一个索引
ix2word = v:k for k, v in word2ix.items()  # 将dict中的key与value互换位置
voc_size = len(word2ix)


# 构建训练对
WINDOWS = 2  # 取左右窗口的词作为context_word
pairs = []  # 存放训练对

for sentence in corpus_list:
    for center_word_index in range(len(sentence)):
        center_word_ix = word2ix[sentence[center_word_index]]
        for win in range(-WINDOWS, WINDOWS+1):
            contenx_word_index = center_word_index + win
            if 0 <= contenx_word_index <= len(sentence)-1 and contenx_word_index != center_word_index:
                context_word_ix = word2ix[sentence[contenx_word_index]]
                pairs.append((center_word_ix, context_word_ix))

6.4.2 构建SkipGram网络结构

x: 输入的x是一个大小为voc_dim的one-hot向量[0,0,…,1,…0]

嵌入矩阵:构建一个嵌入矩阵,它的大小是(emb_dim, voc_dim),emb_dim是词向量的维度, voc_dim是词典的大小。这个矩阵中的值是我们最终要求取的数据,因此它是参数,可以用nn.Parameter()来创建这个矩阵参数。
该矩阵乘以x会得到一个emb_dim大小的向量,就是forward函数中的变量emb

线性计算:参数W乘以emb,是一个线性计算的过程,输出voc_dim大小的向量

softmax计算:线性计算的输出再经过一个softmax后,输出大小与输入保持一致,但向量中的值变成了0-1的概率,即得到了词典中所有词作为输出x的下文词的概率。

前向计算结束。

注意:torch.nn.init.xavier_normal是初始化参数的一种方式,以避免参数过大或过小而阻碍正常训练。

class SkipGram(nn.Module):
    def __init__(self, voc_dim, emb_dim):
        super(SkipGram, self).__init__()
        # 初始化参数
        self.embedding_matrix = nn.Parameter(torch.FloatTensor(emb_dim, voc_dim))
        self.W = nn.Parameter(torch.FloatTensor(voc_dim, emb_dim))
        torch.nn.init.xavier_normal(self.embedding_matrix)
        torch.nn.init.xavier_normal(self.W)

    def forward(self, x):
        emb = torch.matmul(self.embedding_matrix, x)
        h = torch.matmul(self.W, emb)  # [voc_dim]
        log_softmax = F. log_softmax(h)  # [voc_dim]

        return log_softmax

6.4.3开始训练

还是老套路。

注意,这是一个为了演示的小例子,所以epoch, embedding_dim都设置的很小,在实际训练中要根据实际效果去设置,embedding_dim一般可以设置为100.

# 提前设置超参数
epoch = 10
lr = 1e-2
embedding_dim = 5

# 模型、优化器、损失
model = SkipGram(voc_size, embedding_dim)
optim = torch.optim.Adam(model.parameters(), lr=lr)
loss_f = torch.nn.NLLLoss()  

# 这是将索引变成词典大小的One-Hot向量的方法
def get_onehot_vector(ix):
    one_hot_vec = torch.zeros(voc_size).float()
    one_hot_vec[ix] = 1.0
    return one_hot_vec

# 迭代
for e in range(epoch):
    epoch_loss = 0

    for i, (center_ix, context_ix) in enumerate(pairs):
        optim.zero_grad()

        # 预处理好数据结构
        one_hot_vec = get_onehot_vector(center_ix)
        y_true = torch.Tensor([context_ix]).long()

        # 前向
        y_pred = model(one_hot_vec)
        loss = loss_f(y_pred.view(1, -1), y_true)

        # 后向
        loss.backward()
        epoch_loss += loss.data.item()

        # 梯度更新
        optim.step()

    if e % 2 == 0:
        print('epoch: %d, loss: %f' % (e, epoch_loss))
  
C:\\Users\\CC\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:7: UserWarning: nn.init.xavier_normal is now deprecated in favor of nn.init.xavier_normal_.
  import sys
C:\\Users\\CC\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:8: UserWarning: nn.init.xavier_normal is now deprecated in favor of nn.init.xavier_normal_.
  
C:\\Users\\CC\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:13: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.
  del sys.path[0]


epoch: 0, loss: 190.530474
epoch: 2, loss: 178.796980
epoch: 4, loss: 153.809181
epoch: 6, loss: 134.125972
epoch: 8, loss: 126.447176

6.4.4 预测

以上训练结束,我们得到了嵌入矩阵model.embedding_matrix,它的每一列代表一个词的嵌入向量。可以通过以下方式获取。

# # 3.预测:预测单词的向量并计算相似度
v1 = torch.matmul(model.embedding_matrix, get_onehot_vector((word2ix['he'])))
v2 = torch.matmul(model.embedding_matrix, get_onehot_vector((word2ix['she'])))
v3 = torch.matmul(model.embedding_matrix, get_onehot_vector((word2ix['capital'])))

print(v1)
print(v2)
print(v3)

s_v1_v2 = F.cosine_similarity(v1, v2, dim=0)
s_v1_v3 = F.cosine_similarity(v1, v3, dim=0)
print(s_v1_v2)
print(s_v1_v3)
tensor([ 0.7496, -1.2529, -1.1052,  0.3301, -0.9289], grad_fn=<MvBackward>)
tensor([ 0.2016, -1.9385, -0.7472,  0.0589, -0.8677], grad_fn=<MvBackward>)
tensor([-1.1139, -0.1073,  0.2193,  1.3546, -0.8456], grad_fn=<MvBackward>)
tensor(0.8998, grad_fn=<DivBackward1>)
tensor(0.0710, grad_fn=<DivBackward1>)

6.3pytorch实现autoencoder模型(代码片段)

欢迎订阅本专栏:《PyTorch深度学习实践》订阅地址:https://blog.csdn.net/sinat_33761963/category_9720080.html第二章:认识Tensor的类型、创建、存储、api等,打好Tensor的基础,是进行PyTorch深度学习实践的重中之重的基础... 查看详情

lenet模型对cifar-10数据集分类pytorch(代码片段)

LeNet模型对CIFAR-10数据集分类【pytorch】目录LeNet网络模型CIFAR-10数据集Pytorch实现代码目录本文为针对CIFAR-10数据集的基于简单神经网络LeNet分类实现(pytorch实现)LeNet网络模型Tip:(以上为原始LeNet)为了更好的... 查看详情

基于pytorch模型剪枝的实现(极大的减少模型计算参数加快模型运行速度)(代码片段)

深度模型剪枝实现以及一些网络优化技巧模型剪枝:LearningEfficientConvolutionalNetworksThroughNetworkSlimming(ICCV2017).基于论文的代码复现以及拓展:在网络上中加入其它优化方法最强深度学习优化器Rangerwarmup与consinelearningrate为什... 查看详情

pytorch实现tpu版本cnn模型(代码片段)

...时间的问题,我们使用TPU运行时环境来加速训练。为此,PyTorch一直在通过提供最先进的硬件加速器 查看详情

swintransformer模型转化:pytorch模型转keras。(代码片段)

SwinTransformer官方模型只有pytorch,没有keras,需要转换才可以用。这篇文章记录一下如何实现模型的转化:新建model.py,插入如下代码:这段代码是SwinTransformer模型的keras实现。importtensorflowastffromtensorflow.kerasimportModel,l... 查看详情

6.1pytorch简单二分类模型(代码片段)

欢迎订阅本专栏:《PyTorch深度学习实践》订阅地址:https://blog.csdn.net/sinat_33761963/category_9720080.html第二章:认识Tensor的类型、创建、存储、api等,打好Tensor的基础,是进行PyTorch深度学习实践的重中之重的基础... 查看详情

使用pytorch实现手写数字识别(代码片段)

使用Pytor##标题ch实现手写数字识别思路和流程分析准备数据,这些需要准备DataLoader构建模型,这里可以使用torch构造一个深层的神经网络模型的训练模型的保存,保存模型,后续持续使用模型的评估,使用测... 查看详情

8.1pytorch模型迁移(代码片段)

欢迎订阅本专栏:《PyTorch深度学习实践》订阅地址:https://blog.csdn.net/sinat_33761963/category_9720080.html第二章:认识Tensor的类型、创建、存储、api等,打好Tensor的基础,是进行PyTorch深度学习实践的重中之重的基础... 查看详情

softmax回归的简洁实现(softmax-regression-pytorch)(代码片段)

...上篇(线性回归的简洁实现)中已经了解了使用Pytorch实现模型的便利。下面,让我们再次使用Pytorch来实现一个softmax回归模型。首先导入所需的包或模块。importtorc 查看详情

「深度学习一遍过」必修18:基于pytorch的语义分割模型实现(代码片段)

...型基础上实现膨胀卷积 1自定义5层普通卷积 模型结构 pytorch代码 fromtor 查看详情

pytorch实现基于charrnn的文本分类与生成(代码片段)

Pytorch实现基于CharRNN的文本分类与生成标签:deep-learningpytorchnlp1简介本篇主要介绍使用pytorch实现基于CharRNN来进行文本分类与内容生成所需要的相关知识,并最终给出完整的实现代码。2相关API的说明pytorch框架中每种网络... 查看详情

5pytorch构建模型的三种方式(代码片段)

欢迎订阅本专栏:《PyTorch深度学习实践》订阅地址:https://blog.csdn.net/sinat_33761963/category_9720080.html第二章:认识Tensor的类型、创建、存储、api等,打好Tensor的基础,是进行PyTorch深度学习实践的重中之重的基础... 查看详情

使用pytorch实现深度学习的主要流程(代码片段)

一、使用Pytorch实现深度学习的主要流程使用Pytorch进行深度学习的实现流程主要包含如下几个部分:1、预处理、后处理并确认网络的输入和输出2、创建Dataset3、创建DataLoader4、创建网络模型5、定义正向传播函数(forward... 查看详情

使用 pytorch-lightning 实现 Network in Network CNN 模型

】使用pytorch-lightning实现NetworkinNetworkCNN模型【英文标题】:ImplementaNetworkinNetworkCNNmodelusingpytorch-lightning【发布时间】:2021-08-2721:32:06【问题描述】:我正在尝试实现NiN模型。基本上试图从d2l复制代码这是我的代码。importpandasaspdimp... 查看详情

使用pytorch搭建模型(代码片段)

...并不支持,比如对数组使用列表进行切片,所以只能转战Pytorch了(pytorch是支持的)。还好Pytorch比较容易上手,几乎完美复制了Numpy的特性(但还有一些特性不支持),怪不得热度上升得这么快。模型定义  和TF很像,Pytorch也... 查看详情

pytorch实现线性回归(api完成)(代码片段)

PytorchAPI完成线性回归Pytorch完成基础的模型目标1.Pytorch完成模型常用API1.1nn.Module1.2优化器类1.3损失函数1.4线性回归完整代码2.在GPU上运行代码3.常见的优化算法介绍3.1梯度下降算法(batchgradientdescentBGD)3.2随机梯度下降法(St... 查看详情

pytorch模型fps测试benchmark(参考mmdetection实现)(代码片段)

引言深度学习中,模型的速度和性能具有同等重要的地位,因为这直接关系到模型是否能在实际生产应用中落地。在计算机视觉领域,FPS(模型每秒能够处理的图像帧数)是一个重要且直观地反映模型处理速... 查看详情

pytorch实现基于charrnn的文本分类与生成(代码片段)

Pytorch实现基于CharRNN的文本分类与生成标签:deep-learningpytorchnlp1简介本篇主要介绍使用pytorch实现基于CharRNN来进行文本分类与内容生成所需要的相关知识,并最终给出完整的实现代码。2相关API的说明pytorch框架中每种网络... 查看详情