我尝试使用大约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
我的问题是:预计会出现在没有大量可用内存的机器上(比如我的),我应该获得更多内存或以更小的方式训练模型?或看起来我的设置没有正确配置(或我的代码效率低下)?
提前谢谢。
答案 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_count
和sample
的不同值后您的词汇量,子采样语料库和预期内存使用量的大小。 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