NLP 利器 Gensim 中 word2vec 模型的训练损失计算,和对比基准的选择

本文为系列文章之一,前面的几篇请点击链接:
NLP 利器 gensim 库基本特性介绍和安装方式
NLP 利器 Gensim 库的使用之 Word2Vec 模型案例演示
NLP 利器 Gensim 来训练自己的 word2vec 词向量模型
NLP 利器 Gensim 来训练 word2vec 词向量模型的参数设置
NLP 利器 Gensim 中 word2vec 模型的内存需求,和模型评估方式
NLP 利器 Gensim 中 word2vec 模型的恢复训练:载入存储模型并继续训练


一、训练损失计算

通过设置 compute_loss 可以设定是否计算 loss,然后训练的时候就会自动计算 loss 了。

计算完成的 loss 被存储在 running_training_loss 这一属性中。

我们可以通过 get_latest_training_loss 方法获取。

# instantiating and training the Word2Vec model
model_with_loss = gensim.models.Word2Vec(
    sentences,
    min_count=1,
    compute_loss=True,
    hs=0,
    sg=1,
    seed=42
)

# getting the training loss value
training_loss = model_with_loss.get_latest_training_loss()
print(training_loss)

运行结果:

1371947.25

参数说明:

  • sg ({0**, 1}**, optional) – 训练算法: 1 是 skip-gram; 否则是 CBOW。
  • hs ({0**, 1}**, optional) – 1:使用分级 softmax,0:使用负采样。
  • seed (int*,* optional) – 随机数生成器的种子。

二、比较基准

我们可以运行一些比较基准,看训练时候损失计算代码产生的影响。

用以下两个数据集作为比较基准:

  • Lee Background 语料
  • Text8 语料(为了看不同语料大小的影响,会对前 1MB,10MB,50MB,以及整个语料数据进行评估)
import io
import os

import gensim.models.word2vec
import gensim.downloader as api
import smart_open


def head(path, size):
    with smart_open.open(path) as fin:
        return io.StringIO(fin.read(size))


def generate_input_data():
    lee_path = datapath('lee_background.cor')
    ls = gensim.models.word2vec.LineSentence(lee_path)
    ls.name = '25kB'
    yield ls

    text8_path = api.load('text8').fn
    labels = ('1MB', '10MB', '50MB', '100MB')
    sizes = (1024 ** 2, 10 * 1024 ** 2, 50 * 1024 ** 2, 100 * 1024 ** 2)
    for l, s in zip(labels, sizes):
        ls = gensim.models.word2vec.LineSentence(head(text8_path, s))
        ls.name = l
        yield ls


input_data = list(generate_input_data())

我们可以对比一下训练时间的差别,使用不同的输入数据和训练参数设置。

对于每种组合,我们重复测试几次,以获得测试持续时间的平均值和标准偏差。

import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

# Temporarily reduce logging verbosity
logging.root.level = logging.ERROR

import time
import numpy as np
import pandas as pd

train_time_values = []
seed_val = 42
sg_values = [0, 1]
hs_values = [0, 1]

fast = True
if fast:
    input_data_subset = input_data[:3]
else:
    input_data_subset = input_data


for data in input_data_subset:
    for sg_val in sg_values:
        for hs_val in hs_values:
            for loss_flag in [True, False]:
                time_taken_list = []
                for i in range(3):
                    start_time = time.time()
                    w2v_model = gensim.models.Word2Vec(
                        data,
                        compute_loss=loss_flag,
                        sg=sg_val,
                        hs=hs_val,
                        seed=seed_val,
                    )
                    time_taken_list.append(time.time() - start_time)

                time_taken_list = np.array(time_taken_list)
                time_mean = np.mean(time_taken_list)
                time_std = np.std(time_taken_list)

                model_result = {
                    'train_data': data.name,
                    'compute_loss': loss_flag,
                    'sg': sg_val,
                    'hs': hs_val,
                    'train_time_mean': time_mean,
                    'train_time_std': time_std,
                }
                print("Word2vec model #%i: %s" % (len(train_time_values), model_result))
                train_time_values.append(model_result)

train_times_table = pd.DataFrame(train_time_values)
train_times_table = train_times_table.sort_values(
    by=['train_data', 'sg', 'hs', 'compute_loss'],
    ascending=[False, False, True, False],
)
print(train_times_table)

测试结果:

   train_data  compute_loss  sg  hs  train_time_mean  train_time_std
4        25kB          True   1   0         0.454762        0.012580
5        25kB         False   1   0         0.439228        0.008768
6        25kB          True   1   1         0.951644        0.085889
7        25kB         False   1   1         0.951292        0.039065
0        25kB          True   0   0         0.240479        0.005060
1        25kB         False   0   0         0.250178        0.005493
2        25kB          True   0   1         0.405198        0.009490
3        25kB         False   0   1         0.408087        0.038706
12        1MB          True   1   0         1.655859        0.113092
13        1MB         False   1   0         1.680051        0.189026
14        1MB          True   1   1         3.492107        0.428911
15        1MB         False   1   1         3.093424        0.147582
8         1MB          True   0   0         0.619222        0.037100
9         1MB         False   0   0         0.705076        0.028860
10        1MB          True   0   1         1.168661        0.011428
11        1MB         False   0   1         1.058264        0.020380
20       10MB          True   1   0        24.787724        1.964204
21       10MB         False   1   0        21.996642        0.341242
22       10MB          True   1   1        43.136896        1.458909
23       10MB         False   1   1        46.764473        3.284557
16       10MB          True   0   0         8.531959        0.376124
17       10MB         False   0   0         8.237493        0.313006
18       10MB          True   0   1        16.261160        0.557908
19       10MB         False   0   1        17.740904        1.768709

总结:

  • 语料越大,训练时间越长(显然):10倍语料,对应 13~15 倍训练时间。
  • 计算 loss:影响不大。
  • 训练算法 sg:skip-gram(1)是 CBOW(0)训练时间的 2.5 ~3 倍左右。
  • hs:使用分级 softmax(1)是采用负采样(0)训练时间的 1.8~2 倍左右。
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值