使用gensim的Word2vec培训在100K句子后开始交换

时间:2015-06-25 23:06:57

标签: python numpy blas gensim word2vec

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

我想我可能代表一个特殊的用例,因为"句子"有任意字符串而不是字典单词。每个句子(行)有大约100个单词,每个单词和#34;有大约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)

事情是,事情真的快速达到100K句子(我的RAM稳步上升)然后我用完RAM而且我可以看到我的电脑已经开始交换,并且训练停止了。在开始交换之前,我没有大量可用的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

我的问题是:预计会出现在没有大量可用内存的机器上(比如我的),我应该获得更多内存或以更小的方式训练模型?看起来我的设置没有正确配置(或我的代码效率低下)?

提前谢谢。

2 个答案:

答案 0 :(得分:3)

作为第一个原则,如果您的预算和机器可以管理它,您应该总是获得更多内存。它节省了很多时间和时间。麻烦。

其次,不清楚你是否意味着在超过100K句子的数据集上,训练在遇到前100K句子后开始减速,或者如果你的意思是使用任何大于100K句子的数据集经历减速。我怀疑是后者,因为......

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

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

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

可以使用scale_vocab(...)参数调用dry_run=True步骤,该参数可以预览min_countsample的不同值后您的词汇量,子采样语料库和预期内存使用量的大小。 scale_vocab(...)个参数。当您发现值似乎可管理的值时,您可以使用这些选定的参数调用dry_run,而不使用finalize_vocab(),将它们应用于您的模型(然后instantiateViewControllerWithIdentifier()初始化大型数组)。

答案 1 :(得分:2)

  

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

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

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

3)但是,我认为4 GB的RAM可能是你的主要问题(除了你的操作系统,你可能只有1-2 GB可以被进程/线程实际使用。我真的会考虑投资在更多的RAM中。例如,现在你可以获得价值<100美元的16 Gb RAM套件,但是,如果你有一些资金可以用于普通的ML /&#34;数据科学&#34;任务,那么, #39; d建议&gt; 64 GB