10

我正在尝试使用大约 170K 行的文件来训练 word2vec 模型,每行一个句子。

我想我可能代表一个特殊的用例,因为“句子”有任意字符串而不是字典单词。每个句子(行)大约有 100 个单词,每个“单词”大约有 20 个字符,包括字符"/"和数字。

训练代码很简单:

# as shown in http://rare-technologies.com/word2vec-tutorial/
import gensim, logging, os

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

class MySentences(object):
    def __init__(self, dirname):
        self.dirname = dirname

    def __iter__(self):
        for fname in os.listdir(self.dirname):
            for line in open(os.path.join(self.dirname, fname)):
                yield line.split()

current_dir = os.path.dirname(os.path.realpath(__file__))

# each line represents a full chess match
input_dir = current_dir+"/../fen_output"
output_file = current_dir+"/../learned_vectors/output.model.bin"

sentences = MySentences(input_dir)

model = gensim.models.Word2Vec(sentences,workers=8)

事情是,事情真的很快,最多 10 万个句子(我的 RAM 稳步上升),但后来我的 RAM 用完了,我可以看到我的 PC 已经开始交换,并且训练停止了。我没有很多可用的 RAM,只有大约 4GB,word2vec并且在开始交换之前用完了所有内存。

我认为我已将 OpenBLAS 正确链接到 numpy:这就是numpy.show_config()告诉我的:

blas_info:
  libraries = ['blas']
  library_dirs = ['/usr/lib']
  language = f77
lapack_info:
  libraries = ['lapack']
  library_dirs = ['/usr/lib']
  language = f77
atlas_threads_info:
  NOT AVAILABLE
blas_opt_info:
  libraries = ['openblas']
  library_dirs = ['/usr/lib']
  language = f77
openblas_info:
  libraries = ['openblas']
  library_dirs = ['/usr/lib']
  language = f77
lapack_opt_info:
  libraries = ['lapack', 'blas']
  library_dirs = ['/usr/lib']
  language = f77
  define_macros = [('NO_ATLAS_INFO', 1)]
openblas_lapack_info:
  NOT AVAILABLE
lapack_mkl_info:
  NOT AVAILABLE
atlas_3_10_threads_info:
  NOT AVAILABLE
atlas_info:
  NOT AVAILABLE
atlas_3_10_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
mkl_info:
  NOT AVAILABLE

我的问题是:这在没有大量可用 RAM 的机器(如我的)上是预期的,我应该获得更多的 RAM 或以更小的部分训练模型吗?还是看起来我的设置配置不正确(或者我的代码效率低下)?

先感谢您。

4

2 回答 2

3

作为首要原则,如果您的预算和机器可以管理它,您应该始终获得更多 RAM。它节省了很多时间和麻烦。

其次,不清楚您的意思是在超过 10 万个句子的数据集上,在遇到前 10 万个句子后训练开始减慢,或者您的意思是使用任何超过 10 万个句子的数据集都会出现减慢。我怀疑是后者,因为...

Word2Vec 内存使用是词汇量(令牌计数)的函数,而不是用于训练的数据总量。因此,您可能希望使用更大的min_count,以减少跟踪的单词数,以限制训练期间的 RAM 使用量。(模型未跟踪的单词将在训练过程中默默地丢弃,就好像它们不存在一样 - 对稀有单词这样做并不会造成太大伤害,有时甚至会有所帮助,因为可以让其他单词彼此靠近。)

最后,您可能希望避免在构造函数中提供语料库语句(它会自动扫描和训练),而是在模型构建后自己显式调用build_vocab()train()步骤,以检查模型的状态/大小并根据需要调整参数。

特别是在最新版本的 gensim 中,您还可以将build_vocab(corpus)step up 拆分为三个 step scan_vocab(corpus)scale_vocab(...)、 和finalize_vocab()

可以使用一个参数调用该scale_vocab(...)步骤,该dry_run=True参数可以预览在尝试不同的min_countsample参数值后您的词汇量、二次采样的语料库和预期的内存使用量将有多大。当您找到看起来易于管理的值时,您可以scale_vocab(...)使用这些选择的参数调用,而不使用dry_run,将它们应用于您的模型(然后finalize_vocab()初始化大型数组)。

于 2015-09-30T01:42:53.530 回答
2

看起来我的设置没有正确配置(或者我的代码效率低下)?

1)总的来说,我会说不。但是,鉴于您只有少量 RAM,我会使用较少数量的工人。它会减慢训练速度,但也许你可以通过这种方式避免交换。

2)您可以尝试词干或更好:词形还原。您将减少单词的数量,例如,单数和复数形式将被视为同一个单词

3)但是,我认为 4 GB 的 RAM 可能是您的主要问题(除了您的操作系统,您可能只有 1-2 GB 可以实际由进程/线程使用。我真的会考虑投资更多的 RAM . 例如,现在您可以以 < 100 美元的价格获得优质的 16 Gb RAM 套件,但是,如果您有一些钱可以为常见的 ML/“数据科学”任务投资购买体面的 RAM,我建议 > 64 GB

于 2015-07-25T07:20:06.353 回答