1.10-改进CBOW模型的学习

0引言

  1. 本节将前面实现的改进的CBOW模型在PTB数据集上跑一遍
  2. 由于希望跟书上一样调用GPU,因此需要安装cupy包,途中遇到一些问题,详见下面的安装过程。

1 cupy包的安装

  1. 原本是直接在anaconda3的base环境中使用pip install cupy-cuda11x安装的,但是安装好后执行从cupy数组中获取指定行的数据时报了如下错误:

    1. RuntimeError: CuPy failed to load libnvrtc.so.11.2: OSError: libnvrtc.so.11.2: cannot open shared object file: No such file or directory
  2. 分析发现,这个错误应该是cuda版本的问题,接下来是解决办法;

  3. 需要确认最新版cupy对cuda版本、numpy版本的要求;当然Python版本也要符合要求,因此用到以下资料:

    1. Installation — CuPy 13.2.0 documentation
    2. Previous PyTorch Versions | PyTorch
    3. 版本匹配指南:PyTorch版本、Python版本和pytorch_lightning版本的对应关系_pytorch-lightning版本对应-CSDN博客
  4. 具体而言:

    1. 最新版的numpy为2.0,cupy最新版是支持的;因此可以直接通过pip install numpy

    2. nvidia-smi查看自己电脑的cuda版本,如下图所示;本机支持的最高cuda版本是11.4,因此我这里选择安装11.3版本的cudatoolkit;

      在这里插入图片描述

    3. cudatoolkit=11.3可以安装torch=1.9.0,再看一下torch与Python版本的对应关系,得python=3.9;

  5. 几个版本弄清楚之后就可以开始安装了:

    conda create -n nlp_study pip python=3.9
    conda activate nlp_study
    
    conda install cudatoolkit=11.3 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/linux-64/
    pip install numpy
    pip install cupy-cuda11x
    
  6. 安装好之后执行下面的语句应该就不报错了:

    # 这个函数一开始直接在base环境中使用pip install cupy-cuda11x安装也是不会报错的
    def to_gpu(x):
        import cupy
        
    
        if type(x) == cupy.ndarray:
            return x
        return cupy.asarray(x)
      
    idx = numpy.random.permutation(numpy.arange(data_size))
    x = to_gpu(x)
    x = x[idx] # 是这里会报错;所以进行了上述的安装过程
    
  7. 本书中提供的代码有些许问题,并且参与运算的两个数据一般需要都在gpu上或者都在CPU上;因此代码中额外加入了一些将数据移动到GPU或者CPU的代码,以保证代码能够正确运行。

2解决VScode中matplotlib绘图不显示的问题

  1. 遇到的问题是:vscode中使用juypter时绘图可以显示,但是在代码文件里面写然后运行就不行,而且不报错;
  2. 查了相关博客,以下是有用的:
    1. 参照vscode——matplotlib绘图不显示问题_visualstudio图片怎么出不来plt.plot-CSDN博客:执行了echo $DISPLAYexport DISPLAY=:0.0
    2. 然后又会报解决 UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown plt.show()-CSDN博客中的错误,因此选择保存图片来查看绘图的结果;

3 CBOW模型学习的实现

代码目录:https://1drv.ms/f/s!AvF6gzVaw0cNjpx9BAtQYGAHFT3gZA?e=Eso96F;

  1. 上一篇笔记讲述了改进过的CBOW模型的代码实现,包括初始化、前向计算和反向传播;

  2. 这里学习用的trainer函数和之前一样;

  3. 因此代码上就不过多讲述;区别在于这里将相关数据使用本书提供的to_gputo_cpu方法搬到了GPU上,详见代码中的xxx.to_gpu(xxx)

  4. 主要的几个代码文件如下:

    1. CBOW_train.py:程序入口
    2. CBOW_GPU.py:改进之后的GPU版CBOW模型代码
    3. utils/Embedding_GPU.pyutils/negativeSamplingLayer_GPU.pyutils/trainer_GPU.py:GPU版的Embedding层、Embedding_dot层、UnigramSampler模块、NegativeSamplingLoss层;以及GPU版的训练类;
  5. 由于数据量较大,训练时间较长;这里设置max_epoch = 5看一下结果;

  6. 如下图所示是训练过程中的损失变化曲线;同时保存了训练的参数在cbow_params.pkl文件中。

    在这里插入图片描述

  7. 接着,我们用之前的most_similar计算与输入单词最相似的前5个单词;结果如下:

    1. 可见,CBOW模型确实学习到了单词的分布式表示;
    # 与you最相似的
    we  0.8603515625
    i  0.82861328125
    your  0.74169921875
    else  0.7353515625
    someone  0.71875
    # 与year最相似的
    month  0.90673828125
    spring  0.8525390625
    summer  0.8525390625
    week  0.83837890625
    decade  0.7109375
    

4 CBOW模型对更复杂模式的捕捉

主要是类推问题。例如:king − man + woman = queen

  1. 由于CBOW模型可以获得单词的分布式表示,即向量;那么想要推出king − man + woman = queen的问题,则可以转换为单词向量之间的加法和减法;

  2. vec(x)表示单词x的向量表示;则需要计算vec(‘king’) + vec(‘woman’) − vec(‘man’) =?;将计算出来的结果向量作为一个不知道的单词,然后使用most_similar计算与该单词最相似的前几个单词,看看有没有queen,以及queen排第几个;当然,这里要使用most_similar需要修改一下,因为此时传进去的query不是单词而是单词向量了(详见代码里的修改);

  3. 然后我们可以得到以下结果:

    1. take:took = go:went类推出来了;
    2. 但由于迭代次数较少,学习的不好;
    3. 因此可以说,CBOW模型不仅捕获了单词含义,还捕获了模式;
    [analogy] king:man = queen:?
     man: 0.89208984375
     balloon: 0.8408203125
     woman: 0.81884765625
     lady: 0.8056640625
     remember: 0.80322265625
    
    [analogy] take:took = go:?
     went: 0.75732421875
     came: 0.6962890625
     lived: 0.65478515625
     ran: 0.63916015625
     goes: 0.6376953125
    
    [analogy] car:cars = child:?
     adults: 0.779296875
     basketball: 0.7783203125
     pieces: 0.77490234375
     women: 0.76806640625
     college: 0.759765625
    
    [analogy] good:better = bad:?
     better: 0.79931640625
     greater: 0.701171875
     more: 0.69384765625
     less: 0.69140625
     rather: 0.65673828125
    

5单词向量的评价方法

  1. 单词的分布式表示的评价往往与实际应用分开进行。此时,经常使用的评价指标有“相似度”和“类推问题”;
    1. 因为单词的分布式表示通常与其他任务相结合做具体的场景任务,那么组合之后的任务可能非常复杂,这个时候想要从整体上去评价其中一个模块的效果,会非常麻烦。
  1. 单词相似度的评价:
    1. 人工给一些单词之间的相似度进行打分
    2. 使用分布式表示模型得到单词的分布式表示,然后计算余弦相似度;
    3. 将两个打分进行比较
  2. 类推问题
    1. 使用上面提到的类推问题,根据类推的结果来评价分布式表示的好坏;
    2. 基于类推问题可以在一定程度上衡量“是否正确理解了单词含义或语法问题”
    3. 但是,单词的分布式表示的优劣对 目标应用贡献多少(或者有无贡献),取决于待处理问题的具体情况,比如应用的类型或语料库的内容等。也就是说,不能保证类推问题的评价高,目标应用的结果就一定好。这一点请一定注意

6总结

部分内容直接来源于书本。

  1. 到此为止,我们改进了word2vec模型,也看到这个模型不仅可以捕获单词含义,还可以捕获模式;但是由于迭代次数以及数据集的规模较小,效果不好。

  2. 在解决自然语言处理任务时,一般不会使用 word2vec 从零开始学习单 词的分布式表示,而是先在大规模语料库(Wikipedia、Google News 等文 本数据)上学习,然后将学习好的分布式表示应用于某个单独的任务;【如同现在的预训练模型+微调的模式】

  3. 以上的模型获得了单词的分布式表示,那文档的表示怎么弄呢?

    1. 最简单的方法是,把文档的各个单词转化为分布式表示,然后求它们的总和。这是一种被称为 bag-of-words 的不考虑单词顺序的模型(思想);【直接相加,当然没有顺序可言】
    2. 但是,后续的循环神经网络,可以以更加优美的方式利用 word2vec 的单词的分布式表示来将文档转化为固定长度的向量【因为RNN是有顺序的,是考虑了上下文的】
  • 18
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值