Keras использует слишком много памяти GPU при вызове train_on_batch, fit и т. Д.

Я возился с Keras и так до сих пор. У меня одна большая проблема при работе с довольно глубокими сетями: при вызове model.train_on_batch или model.fit и т. Д. Keras выделяет значительно больше памяти GPU, чем сама модель. Это не вызвано попыткой тренироваться на некоторых действительно больших изображениях, сама модель сети, похоже, требует много памяти GPU. Я создал этот игрушечный пример, чтобы показать, что я имею в виду. Вот что происходит:

Сначала создаю довольно глубокую сеть и использую model.summary (), чтобы получить общее количество параметров, необходимых для сети (в данном случае 206538153, что соответствует примерно 826 МБ). Затем я использую nvidia-smi, чтобы узнать, сколько выделяет память GPU Keras, и я вижу, что это имеет смысл (849 МБ).

Затем я компилирую сеть и могу подтвердить, что это не увеличивает использование памяти GPU. И, как мы видим в этом случае, на данный момент у меня есть почти 1 ГБ VRAM.

Затем я пытаюсь подавать в сеть простое изображение 16×16 и 1×1 прав на землю, а затем все взрывается, потому что Keras снова начинает выделять много памяти, без всякой причины, которая очевидна для меня. Что-то об обучении сети, похоже, требует гораздо больше памяти, чем просто наличие модели, что для меня не имеет смысла. Я тренировал значительно более глубокие сети на этом графическом процессоре в других рамках, так что это заставляет меня думать, что я неправильно использую Keras (или что-то не так в моей настройке или в Keras, но, конечно, это трудно понять наверняка).

Вот код:

from scipy import misc import numpy as np from keras.models import Sequential from keras.layers import Dense, Activation, Convolution2D, MaxPooling2D, Reshape, Flatten, ZeroPadding2D, Dropout import os model = Sequential() model.add(Convolution2D(256, 3, 3, border_mode='same', input_shape=(16,16,1))) model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2))) model.add(Convolution2D(512, 3, 3, border_mode='same')) model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2))) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(Convolution2D(1024, 3, 3, border_mode='same')) model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2))) model.add(Convolution2D(256, 3, 3, border_mode='same')) model.add(Convolution2D(32, 3, 3, border_mode='same')) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dense(4)) model.add(Dense(1)) model.summary() os.system("nvidia-smi") raw_input("Press Enter to continue...") model.compile(optimizer='sgd', loss='mse', metrics=['accuracy']) os.system("nvidia-smi") raw_input("Compiled model. Press Enter to continue...") n_batches = 1 batch_size = 1 for ibatch in range(n_batches): x = np.random.rand(batch_size, 16,16,1) y = np.random.rand(batch_size, 1) os.system("nvidia-smi") raw_input("About to train one iteration. Press Enter to continue...") model.train_on_batch(x, y) print("Trained one iteration") 

Что дает мне следующий результат:

 Using Theano backend. Using gpu device 0: GeForce GTX 960 (CNMeM is disabled, cuDNN 5103) /usr/local/lib/python2.7/dist-packages/theano/sandbox/cuda/__init__.py:600: UserWarning: Your cuDNN version is more recent than the one Theano officially supports. If you see any problems, try updating Theano or downgrading cuDNN to version 5. warnings.warn(warn) ____________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ==================================================================================================== convolution2d_1 (Convolution2D) (None, 16, 16, 256) 2560 convolution2d_input_1[0][0] ____________________________________________________________________________________________________ maxpooling2d_1 (MaxPooling2D) (None, 8, 8, 256) 0 convolution2d_1[0][0] ____________________________________________________________________________________________________ convolution2d_2 (Convolution2D) (None, 8, 8, 512) 1180160 maxpooling2d_1[0][0] ____________________________________________________________________________________________________ maxpooling2d_2 (MaxPooling2D) (None, 4, 4, 512) 0 convolution2d_2[0][0] ____________________________________________________________________________________________________ convolution2d_3 (Convolution2D) (None, 4, 4, 1024) 4719616 maxpooling2d_2[0][0] ____________________________________________________________________________________________________ convolution2d_4 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_3[0][0] ____________________________________________________________________________________________________ convolution2d_5 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_4[0][0] ____________________________________________________________________________________________________ convolution2d_6 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_5[0][0] ____________________________________________________________________________________________________ convolution2d_7 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_6[0][0] ____________________________________________________________________________________________________ convolution2d_8 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_7[0][0] ____________________________________________________________________________________________________ convolution2d_9 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_8[0][0] ____________________________________________________________________________________________________ convolution2d_10 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_9[0][0] ____________________________________________________________________________________________________ convolution2d_11 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_10[0][0] ____________________________________________________________________________________________________ convolution2d_12 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_11[0][0] ____________________________________________________________________________________________________ convolution2d_13 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_12[0][0] ____________________________________________________________________________________________________ convolution2d_14 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_13[0][0] ____________________________________________________________________________________________________ convolution2d_15 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_14[0][0] ____________________________________________________________________________________________________ convolution2d_16 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_15[0][0] ____________________________________________________________________________________________________ convolution2d_17 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_16[0][0] ____________________________________________________________________________________________________ convolution2d_18 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_17[0][0] ____________________________________________________________________________________________________ convolution2d_19 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_18[0][0] ____________________________________________________________________________________________________ convolution2d_20 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_19[0][0] ____________________________________________________________________________________________________ convolution2d_21 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_20[0][0] ____________________________________________________________________________________________________ convolution2d_22 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_21[0][0] ____________________________________________________________________________________________________ convolution2d_23 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_22[0][0] ____________________________________________________________________________________________________ convolution2d_24 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_23[0][0] ____________________________________________________________________________________________________ maxpooling2d_3 (MaxPooling2D) (None, 2, 2, 1024) 0 convolution2d_24[0][0] ____________________________________________________________________________________________________ convolution2d_25 (Convolution2D) (None, 2, 2, 256) 2359552 maxpooling2d_3[0][0] ____________________________________________________________________________________________________ convolution2d_26 (Convolution2D) (None, 2, 2, 32) 73760 convolution2d_25[0][0] ____________________________________________________________________________________________________ maxpooling2d_4 (MaxPooling2D) (None, 1, 1, 32) 0 convolution2d_26[0][0] ____________________________________________________________________________________________________ flatten_1 (Flatten) (None, 32) 0 maxpooling2d_4[0][0] ____________________________________________________________________________________________________ dense_1 (Dense) (None, 4) 132 flatten_1[0][0] ____________________________________________________________________________________________________ dense_2 (Dense) (None, 1) 5 dense_1[0][0] ==================================================================================================== Total params: 206538153 ____________________________________________________________________________________________________ None Thu Oct 6 09:05:42 2016 +------------------------------------------------------+ | NVIDIA-SMI 352.63 Driver Version: 352.63 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GTX 960 Off | 0000:01:00.0 On | N/A | | 30% 37C P2 28W / 120W | 1082MiB / 2044MiB | 9% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 1796 G /usr/bin/X 155MiB | | 0 2597 G compiz 65MiB | | 0 5966 C python 849MiB | +-----------------------------------------------------------------------------+ Press Enter to continue... Thu Oct 6 09:05:44 2016 +------------------------------------------------------+ | NVIDIA-SMI 352.63 Driver Version: 352.63 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GTX 960 Off | 0000:01:00.0 On | N/A | | 30% 38C P2 28W / 120W | 1082MiB / 2044MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 1796 G /usr/bin/X 155MiB | | 0 2597 G compiz 65MiB | | 0 5966 C python 849MiB | +-----------------------------------------------------------------------------+ Compiled model. Press Enter to continue... Thu Oct 6 09:05:44 2016 +------------------------------------------------------+ | NVIDIA-SMI 352.63 Driver Version: 352.63 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GTX 960 Off | 0000:01:00.0 On | N/A | | 30% 38C P2 28W / 120W | 1082MiB / 2044MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 1796 G /usr/bin/X 155MiB | | 0 2597 G compiz 65MiB | | 0 5966 C python 849MiB | +-----------------------------------------------------------------------------+ About to train one iteration. Press Enter to continue... Error allocating 37748736 bytes of device memory (out of memory). Driver report 34205696 bytes free and 2144010240 bytes total Traceback (most recent call last): File "memtest.py", line 65, in <module> model.train_on_batch(x, y) File "/usr/local/lib/python2.7/dist-packages/keras/models.py", line 712, in train_on_batch class_weight=class_weight) File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1221, in train_on_batch outputs = self.train_function(ins) File "/usr/local/lib/python2.7/dist-packages/keras/backend/theano_backend.py", line 717, in __call__ return self.function(*inputs) File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 871, in __call__ storage_map=getattr(self.fn, 'storage_map', None)) File "/usr/local/lib/python2.7/dist-packages/theano/gof/link.py", line 314, in raise_with_op reraise(exc_type, exc_value, exc_trace) File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 859, in __call__ outputs = self.fn() MemoryError: Error allocating 37748736 bytes of device memory (out of memory). Apply node that caused the error: GpuContiguous(GpuDimShuffle{3,2,0,1}.0) Toposort index: 338 Inputs types: [CudaNdarrayType(float32, 4D)] Inputs shapes: [(1024, 1024, 3, 3)] Inputs strides: [(1, 1024, 3145728, 1048576)] Inputs values: ['not shown'] Outputs clients: [[GpuDnnConv{algo='small', inplace=True}(GpuContiguous.0, GpuContiguous.0, GpuAllocEmpty.0, GpuDnnConvDesc{border_mode='half', subsample=(1, 1), conv_mode='conv', precision='float32'}.0, Constant{1.0}, Constant{0.0}), GpuDnnConvGradI{algo='none', inplace=True}(GpuContiguous.0, GpuContiguous.0, GpuAllocEmpty.0, GpuDnnConvDesc{border_mode='half', subsample=(1, 1), conv_mode='conv', precision='float32'}.0, Constant{1.0}, Constant{0.0})]] HINT: Re-running with most Theano optimization disabled could give you a back-trace of when this node was created. This can be done with by setting the Theano flag 'optimizer=fast_compile'. If that does not work, Theano optimizations can be disabled with 'optimizer=None'. HINT: Use the Theano flag 'exception_verbosity=high' for a debugprint and storage map footprint of this apply node. 

Несколько замечаний:

  • Я попробовал и Theano, и TensorFlow. Оба имеют те же проблемы, и заканчиваются на одной и той же строке. В TensorFlow кажется, что Keras предопределяет много памяти (около 1,5 ГБ), поэтому nvidia-smi не помогает нам отслеживать, что там происходит, но я получаю такие же исключения из памяти. Опять же, это указывает на ошибку в (моем использовании) Keras (хотя трудно быть уверенным в таких вещах, это может быть что-то с моей настройкой).
  • Я пробовал использовать CNMEM в Theano, который ведет себя как TensorFlow: он выделяет большой объем памяти (около 1,5 ГБ), но все же падает в одном месте.
  • Есть некоторые предупреждения о версии CudNN. Я попробовал запустить Theano backend с CUDA, но не CudNN, и я получил те же ошибки, что и не является источником проблемы.
  • Если вы хотите протестировать это на своем собственном графическом процессоре, вы можете сделать сеть более глубокой / более мелкой в ​​зависимости от того, сколько памяти GPU вам нужно проверить.
  • Моя конфигурация выглядит следующим образом: Ubuntu 14.04, GeForce GTX 960, CUDA 7.5.18, CudNN 5.1.3, Python 2.7, Keras 1.1.0 (устанавливается через pip)
  • Я попытался изменить компиляцию модели, чтобы использовать разные оптимизаторы и потери, но это ничего не меняет.
  • Я попытался изменить функцию train_on_batch, чтобы использовать ее, но у нее такая же проблема.
  • Я видел один похожий вопрос здесь на StackOverflow. Почему эта модель Keras требует более 6 ГБ памяти? – но насколько я могу судить, у меня нет таких проблем в моей конфигурации. У меня никогда не было нескольких версий CUDA, и я дважды проверял переменные PATH, LD_LIBRARY_PATH и CUDA_ROOT больше раз, чем могу считать.
  • Джулиус предположил, что сами параметры активации занимают память GPU. Если это правда, может кто-нибудь объяснить это более четко? Я попытался изменить функцию активации моих сверточных слоев на функции, которые явно жестко закодированы, без каких-либо обучаемых параметров, насколько я могу судить, и это ничего не меняет. Кроме того, маловероятно, что эти параметры занимают почти столько же памяти, сколько и остальная часть самой сети.
  • После тщательного тестирования самая большая сеть, которую я смогу обучить, составляет около 453 МБ параметров, из моего ~ 2 ГБ ОЗУ GPU. Это нормально?
  • После тестирования Keras на некоторых более мелких CNN, которые соответствуют моему графическому процессору, я вижу, что в использовании GPU очень резкие скачки. Если я запускаю сеть со 100 МБ параметров, то в 99% случаев во время тренировки будет использоваться менее 200 МБ ОЗУ GPU. Но время от времени использование памяти увеличивается примерно до 1,3 ГБ. Кажется безопасным предположить, что именно эти шипы вызывают мои проблемы. Я никогда не видел этих шипов в других рамках, но они могут быть там по уважительной причине? Если кто-то знает, что их вызывает, и если есть способ избежать их, пожалуйста, звоните!

2 Solutions collect form web for “Keras использует слишком много памяти GPU при вызове train_on_batch, fit и т. Д.”

Очень часто приходится забывать, что активация и градиенты также принимают vram, а не только параметры, что увеличивает использование памяти. Расчеты заднего пролета делают это так, что фаза тренировки принимает почти вдвое больше VRAM использования прямой / выводной нейронной сети.

Итак, в начале, когда сеть создана, выделяются только параметры. Однако, когда начинается тренировка, активация (раз каждый мини-канал) распределяется, давая поведение, которое вы наблюдаете.

Оба Theano и Tensorflow дополняют созданный символический граф, хотя и по-разному.

Чтобы проанализировать, как происходит потребление памяти, вы можете начать с меньшей модели и увеличить ее, чтобы увидеть соответствующий рост в памяти. Аналогично, вы можете увеличить batch_size чтобы увидеть соответствующий рост в памяти.

Вот фрагмент кода для увеличения batch_size на основе исходного кода:

 from scipy import misc import numpy as np from keras.models import Sequential from keras.layers import Dense, Activation, Convolution2D, MaxPooling2D, Reshape, Flatten, ZeroPadding2D, Dropout import os import matplotlib.pyplot as plt def gpu_memory(): out = os.popen("nvidia-smi").read() ret = '0MiB' for item in out.split("\n"): if str(os.getpid()) in item and 'python' in item: ret = item.strip().split(' ')[-2] return float(ret[:-3]) gpu_mem = [] gpu_mem.append(gpu_memory()) model = Sequential() model.add(Convolution2D(100, 3, 3, border_mode='same', input_shape=(16,16,1))) model.add(Convolution2D(256, 3, 3, border_mode='same')) model.add(Convolution2D(32, 3, 3, border_mode='same')) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dense(4)) model.add(Dense(1)) model.summary() gpu_mem.append(gpu_memory()) model.compile(optimizer='sgd', loss='mse', metrics=['accuracy']) gpu_mem.append(gpu_memory()) batches = [] n_batches = 20 batch_size = 1 for ibatch in range(n_batches): batch_size = (ibatch+1)*10 batches.append(batch_size) x = np.random.rand(batch_size, 16,16,1) y = np.random.rand(batch_size, 1) print y.shape model.train_on_batch(x, y) print("Trained one iteration") gpu_mem.append(gpu_memory()) fig = plt.figure() plt.plot([-100, -50, 0]+batches, gpu_mem) plt.show() 

Кроме того, для скорости Tensorflow запускает всю доступную память GPU. Чтобы остановить это, вам нужно добавить config.gpu_options.allow_growth = True в get_session()

 # keras/backend/tensorflow_backend.py def get_session(): global _SESSION if tf.get_default_session() is not None: session = tf.get_default_session() else: if _SESSION is None: if not os.environ.get('OMP_NUM_THREADS'): config = tf.ConfigProto(allow_soft_placement=True, ) else: nb_thread = int(os.environ.get('OMP_NUM_THREADS')) config = tf.ConfigProto(intra_op_parallelism_threads=nb_thread, allow_soft_placement=True) config.gpu_options.allow_growth = True _SESSION = tf.Session(config=config) session = _SESSION if not _MANUAL_VAR_INIT: _initialize_variables() return session 

Теперь, если вы запустили предыдущий фрагмент, вы получите графики:

Theano: Theano Tensorflow: Tenserflow

Theano: После model.compile() независимо от того, какая память нужна, во время начала обучения она почти удваивается. Это связано с тем, что Теано увеличивает символический граф для обратного распространения, и каждый тензор нуждается в соответствующем тензоре для достижения обратного потока градиентов. Потребности в памяти, похоже, не растут с помощью batch_size и это неожиданно для меня, поскольку размер заполнителя должен увеличиваться, чтобы обеспечить приток данных из CPU-> GPU.

Tensorflow: память GPU не выделяется даже после model.compile() поскольку get_session() не вызывает get_session() до того времени, которое фактически вызывает _initialize_variables() . Tensorflow, похоже, загружает память в куски для скорости, и поэтому память не растет линейно с помощью batch_size .

Сказав все, что Tensorflow, похоже, голоден, но для больших графиков он очень быстрый. Theano, с другой стороны, очень эффективен с использованием памяти gpu, но для инициализации графика в начале тренировки уходит много времени. После этого его тоже довольно быстро.

  • Как список Python.remove (value) определяет, какое значение нужно удалить?
  • Подпроцесс Python.Popen с помощью OSError: Невозможно выделить память после периода времени
  • Создание символической ссылки внутри zipfile в памяти с помощью python
  • Что делает «del» в точности?
  • Python: вычисление параллельных расстояний вызывает ошибку памяти
  • Управление использованием памяти podbc
  • Python MemoryError: не может выделять память массива
  • Проблема с памятью Python с помощью BeautifulSoup
  •  
    Interesting Posts for Van-Lav

    Как быстро зашифровать строку пароля в Django без модели пользователя?

    Pandas, Excel-Import и MultiIndex

    Кто-нибудь сочетал soap.py или пеной с python-ntlm?

    Простая, кросс-платформенная MIDI-библиотека для Python

    Проверка открытых файлов с помощью Python в Linux

    Могу ли я получить доступ к переменным класса, используя self?

    Создание словаря из строки

    Python: Итерируя списки с разным количеством измерений, существует общий способ?

    Django (trunk) и основанные на классе общие представления: исходные данные одной формы появляются в другой

    Запрос базы данных Python MySQL Connector с% s не выполняется

    Извлечение Word из Synset с использованием Wordnet в NLTK 3.0

    Каков новейший способ разработки апплетов панели gnome (с использованием python)

    Где выводится интерактивная подсказка «>>>» Python?

    Python – Почему cmp () полезен?

    Получите средний год (среднее количество дней в течение нескольких лет) в Пандах

    Python - лучший язык программирования в мире.