Здесь есть несколько вопросов, о которых следует подумать.
Если вы запускаете код на графическом процессоре, он никогда не будет работать, потому что графические процессоры предназначены не для хранения, а для быстрых вычислений, поэтому пространство на графическом процессоре меньше, чем на процессоре. Однако этот код может вызвать ошибку памяти и на ЦП, как это было на моей машине. Итак, мы сначала пытаемся преодолеть это.
Устранение ошибки MemoryError на ЦП:
Строка, производящая 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, чтобы превратить его в словарь частот. Преимущество в том, что мы знаем, что словарь частот при преобразовании в список или массив numpy никогда не превысит размер 10**7
, что не дает ошибки памяти.
Поскольку некоторые элементы каждый раз могут отсутствовать в выборочном массиве, вместо прямого преобразования словаря Counter в список мы будем обновлять этот словарь, используя словарь в предыдущей итерации, чтобы сохранить частоты определенных элементов.
Как только весь цикл завершен, мы преобразуем созданный словарь в список. Я добавил индикатор выполнения, чтобы отслеживать прогресс, поскольку вычисления могут занять много времени. Кроме того, вам не нужно добавлять параметр 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)
Использование tensorflow-gpu:
Как вы упомянули tensorflow-gpu
, я могу предположить, что вы либо хотите избавиться от MemoryError
с помощью tensorflow-gpu
, либо запустить это в сочетании с tensorflow-gpu
при использовании графического процессора.
Чтобы решить MemoryError
, вы можете попробовать функцию tf.multinomial()
с тем же эффектом, что и np.random.choice()
, как показан здесь, но вряд ли он поможет преодолеть проблему, заключающуюся в хранении данных определенного размера и невыполнении каких-то альтернативных вычислений.
Если вы хотите запустить это как часть обучения какой-либо модели, например, вы можете использовать Distributed Tensorflow, чтобы поместить эту часть графа вычислений на ЦП в качестве задачи 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()
person
Vedang Waradpande
schedule
22.09.2018