MemoryError с использованием Python и Doc2Vec - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь обучить Doc2vec для массивных данных. У меня есть 20k файлов с общим количеством 72GB , и я пишу этот код:

def train():
    onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
    data = []
    random.shuffle(onlyfiles)
    tagged_data = []
    t = 0
    try:
        for file_name in onlyfiles:
            with open(mypath+"/"+file_name, 'r', encoding="utf-8") as file:
                txt = file.read()
                tagged_data.append([word_tokenize(txt.lower()), [str(t)]])
                t+=1
    except Exception as e:
        print(t)
        return 
    print("Files Loaded")
    max_epochs = 1000
    vec_size = 500
    alpha = 0.025

    model = Doc2Vec(vector_size=vec_size,
                    alpha=alpha, workers=1,
                    min_alpha=0.00025,
                    min_count=1,
                    dm=1)

    print("Model Works")
    print("Building vocabulary")

    model.build_vocab(tagged_data)
    print("Trainning")
    for epoch in range(max_epochs):
        print("Iteration {0}".format(epoch))
        model.train(tagged_data,
                    total_examples=model.corpus_count,
                    epochs=model.iter)
        model.alpha -= 0.0002
        model.min_alpha = model.alpha

    model.save(model_name)
    print("Model Saved")

Но когда я запускаю этот метод, появляется эта ошибка: Traceback (последний вызов был последним):

File "doc2vec.py", line 20, in train
    tagged_data.append([word_tokenize(txt.lower()), [str(t)]])
MemoryError

И обрабатываются только файлы 3k . Но при просмотре памяти процесс python показывает, что использовалась только 1,7% из памяти. Есть ли какой-нибудь параметр, который я могу сообщить python для решения? Как я могу это исправить?

1 Ответ

0 голосов
/ 29 августа 2018

Вы получаете сообщение об ошибке задолго до того, как даже попытаетесь Doc2Vec, так что на самом деле это не вопрос Doc2Vec - это проблема с обработкой данных Python. Достаточно ли у вас ОЗУ для загрузки 72 ГБ дисковых данных (которые могут немного увеличиться при представлении в строковых объектах Python) в ОЗУ?

Но также вам обычно не нужно вносить весь корпус в память, добавляя в гигантский список, чтобы выполнить любую из этих задач. Читайте вещи по одному и обрабатывайте их из итерируемого / итератора, возможно, записывая промежуточные результаты (например, токенизированный текст) обратно в источники ввода-вывода. Эта статья может быть полезна:

https://rare -technologies.com / данные потокового-в-питон-генераторы-итераторы-итерируемыми /

Наконец, если ваш код действительно перешел в раздел Doc2Vec, у вас возникнут другие проблемы. Какой бы онлайн-пример вы не использовали в качестве модели, он имеет много плохих практик. Например:

  • типичный счетчик взаимодействий составляет 10-20; Вы, конечно, не использовали бы 1000 для набора данных 72 ГБ

  • min_count=1 приводит к гораздо большей модели; обычно отбрасывание низкочастотных слов необходимо и может даже улучшить результирующее векторное качество, а большие наборы данных (и 72 ГБ очень очень большие) имеют тенденцию использовать больше, чем минимальные min_count настройки

  • большинству людей не следует использовать значения не по умолчанию alpha / min_alpha, или пытаться управлять ими своими собственными вычислениями, или даже вызывать train() более одного раза. train() имеет свой собственный параметр epochs, который в случае его использования будет плавно обрабатывать скорость обучения alpha для вас. Насколько я могу судить, 100% людей, которые звонят train() несколько раз в своем собственном цикле, делают это неправильно, и я понятия не имею, где они продолжают получать эти примеры.

  • Тренировка идет намного медленнее с workers=1; особенно с большим набором данных, вы захотите попробовать большие значения workers, а оптимальное значение для пропускной способности обучения в версиях gensim до 3.5.0 обычно находится где-то в диапазоне от 3 до 12 (при условии, что у вас есть по крайней мере так много Ядра процессора).

Таким образом, ваш текущий код, вероятно, приведет к тому, что модель будет больше ОЗУ, обучая один поток медленно и в тысячи раз больше, чем необходимо, причем большая часть обучения будет происходить с бессмысленной отрицательной альфа, которая ухудшает модель с каждым циклом. Если он чудесным образом не MemoryError во время инициализации модели, он будет работать месяцами или годами и в конечном итоге приведет к бессмысленным результатам.

...