Здесь есть несколько вопросов, о которых стоит подумать.
Если вы запустите код на графическом процессоре, он никогда не будет работать, поскольку графические процессоры не предназначены для хранения, а скорее для быстрых вычислений, поэтому пространство на графическом процессоременьше, чем процессор.Однако этот код может вызвать ошибку памяти и на процессоре, как и на моей машине.Поэтому сначала мы попытаемся преодолеть это.
Преодоление ошибки MemoryErp на процессоре:
Строка, производящая MemoryError
, является самой строкой 1:
In [1]: frequency = np.random.choice([i for i in range (10**7)],16**10,p=[0.0000
...: 001 for i in range(10**7)])
...:
---------------------------------------------------------------------------
MemoryError Traceback (most recent call last)
Причина этого заключается в том, что выходные данные строки 1 не имеют размер 10**7
, а 16**10
.Так как именно это и вызывает MemoryError, цель никогда не должна создавать список такого размера.
Для этого мы уменьшаем размер выборки с коэффициентом и зацикливаем блок factor
количество раз, чтобы его можно было хранить.На моей машине коэффициент 1000000
делает свое дело.Как только мы создали образец, мы используем Counter, чтобы превратить его в словарь частот.Преимущество состоит в том, что мы знаем, что словарь частот при преобразовании в список или массив с пустыми значениями никогда не будет превышать размер 10**7
, что не приводит к ошибке памяти.
Как некоторые из элементовможет не каждый раз находиться в массиве выборки, вместо преобразования словаря счетчика в список напрямую, мы обновим этот словарь, используя словарь на предыдущей итерации, чтобы сохранить частоты конкретных элементов.
Однажды весьцикл завершен, мы конвертируем созданный словарь в список.Я добавил индикатор выполнения, чтобы отслеживать прогресс, поскольку вычисления могут занять много времени.Кроме того, вам не нужно добавлять параметр p
к функции np.random.choice()
в вашем конкретном случае, так как распределение в любом случае равномерно.
import numpy as np
import tensorflow as tf
from click import progressbar
from collections import Counter
def large_uniform_sample_frequencies(factor=1000000, total_elements=10**7, sample_size=16**10):
# Initialising progressbar
bar = range(factor)
# Initialise an empty dictionary which
# will be updated in each iteration
counter_dict = {}
for iteration in bar:
# Generate a random sample of size (16 ** 10) / factor
frequency = np.random.choice([i for i in range (total_elements)],
sample_size / factor)
# Update the frequency dictionary
new_counter = Counter(frequency)
counter_dict.update(new_counter)
return np.fromiter(counter_dict.values(), dtype=np.float32)
Использование tennsflow-gpu:
Как вы упомянули tensorflow-gpu
Я могу предположить, что вы либо хотите избавиться от MemoryError
с помощью tensorflow-gpu
, либо запустить его вместе с tensorflow-gpu
при использовании графического процессора.
Чтобы решить MemoryError
, вы можете попробовать функцию tf.multinomial()
с тем же эффектом, что и np.random.choice()
с , показанным здесь , но вряд ли это поможет преодолеть проблему, которая хранитсяданные определенного размера и не выполняющие некоторые альтернативные вычисления.
Если вы хотите выполнить это как часть обучения некоторой модели, например, вы можете использовать Distributed Tensorflow, чтобы поместить эту часть графика вычислений в CPU какЗадача PS с использованием кода, приведенного выше.Вот окончательный код для этого:
# Mention the devices for PS and worker tasks
ps_dev = '/cpu:0'
worker_dev = '/gpu:0'
# Toggle True to place computation on CPU
# and False to place it on the least loaded GPU
is_ps_task = True
# Set device for a PS task
if (is_ps_task):
device_setter = tf.train.replica_device_setter(worker_device=worker_dev,
ps_device=ps_dev,
ps_tasks=1)
# Allocate the computation to CPU
with tf.device(device_setter):
freqs = large_uniform_sample_frequencies()