Обучение Word2vec с использованием gensim начинает замену после предложений 100K
Я пытаюсь обучить модель word2vec, используя файл с примерно 170 К строк, с одним предложением в строке.
Я думаю, что я могу представить специальный случай использования, потому что "предложения" имеют произвольные строки, а не слова слова. Каждое предложение (строка) содержит около 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)
Дело в том, что все работает очень быстро до 100 тыс. предложений (моя оперативная память постоянно растет), но затем у меня заканчивается оперативная память, и я вижу, что мой компьютер начал заменять, и обучение прерывается. У меня нет большого количества оперативной памяти, только около 4 ГБ и 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
Мой вопрос: ожидается на машине, которая не имеет много доступной оперативной памяти (как моя), и я должен получить больше оперативной памяти или обучить модель меньшим частям? или похоже, что моя настройка не настроена должным образом (или мой код неэффективен)?
Спасибо заранее.
Ответы
Ответ 1
Как первый принцип, вы всегда должны получать больше ОЗУ, если ваш бюджет и машина могут управлять им. Это экономит так много времени и проблем.
Во-вторых, неясно, понимаете ли вы, что в наборе данных более чем на 100 тыс. предложений обучение начинает замедляться после того, как встречаются первые 100 тыс. предложений, или если вы имеете в виду, что использование любого набора данных, превышающего 100 КБ, вызывает замедление. Я подозреваю, что это последнее, потому что...
Использование памяти Word2Vec - это функция размера словаря (количество токенов), а не общий объем данных, используемых для обучения. Таким образом, вы можете использовать более крупный min_count
, чтобы уменьшить количество отслеживаемых слов, чтобы ограничить использование ОЗУ во время обучения. (Слова, которые не отслеживаются моделью, будут тихо опущены во время тренировки, как будто их там не было - и делать это для редких слов не сильно больно, а иногда даже помогает, сближая другие слова друг с другом.)
Наконец, вы можете избежать предоставления предложений тела в конструкторе, который автоматически сканирует и обучает, и вместо этого явно вызывать шаги 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()
для инициализации больших массивов).
Ответ 2
похоже, что моя настройка не настроена должным образом (или мой код неэффективная)?
1) В общем, я бы сказал, нет. Однако, учитывая, что у вас есть только небольшое количество оперативной памяти, я бы использовал меньшее количество рабочих. Это замедлит тренировку, но, возможно, вы сможете избежать этого обмена.
2) Вы можете попробовать остановить или лучше: lemmatization. Вы сократите количество слов, поскольку, например, единственные и множественные формы будут считаться одним и тем же словом
3) Тем не менее, я думаю, что 4 ГБ ОЗУ, вероятно, ваша главная проблема здесь (помимо вашей ОС, вероятно, у вас есть только 1-2 ГБ, которые действительно могут использоваться процессами/потоками. Я бы действительно подумал об инвестировании в более оперативной памяти.Например, в настоящее время вы можете получить хорошие 16 ГБ комплекты ОЗУ за 100 долларов США, однако, если у вас есть деньги, чтобы инвестировать в достойную оперативную память для обычной задачи "Наука о данных", я бы рекомендовал > 64 ГБ