RAM истощается слишком быстро - PullRequest
1 голос
/ 26 апреля 2020

Поэтому я пытаюсь использовать модифицированную версию этого кода

(https://github.com/snf/keras-fractalnet)

, которая использует плотные слои 512, 128, 32, 8 вместо слоев свертки. Я полагаю, что оригинал использует (63,3,3), (128,3,3), (256,3,3), (512,3,3), (512,3,3). Поскольку используется 4 блока шириной 3, в моей версии используется 4536 узлов, если я прав. Кроме того, все слои используют активацию tanh, за исключением последней строки последнего блока.

Я работаю на Ubuntu 18.04 с 16 ГБ ОЗУ, но я заметил это после него (запускаю керасы и TF2) выполняет train_on_batch, доступная память уменьшается с 13232 по команде free -m до 9718 и продолжает уменьшаться в аналогичных количествах при каждом первом вызове train_on_batch после каждых 20 эпизодов.

Теперь я довольно новичок в Tensorflow, но сброс около 3 ГБ (если я правильно читаю) каждый раз, когда вызывается train_on_batch, кажется мне немного экстремальным, поэтому я надеялся, что кто-нибудь скажет мне, если мое число узлов выглядит немного экстремально? Или, возможно, мог бы указать мне правильное направление, чтобы искать вещи? Если хотите, я могу опубликовать свои коды, но я также попытался использовать модифицированную версию кода TRPO pat-coady, которая использует PyBullet для построения NN, что означает, что он довольно длинный, но при необходимости я могу хотя бы поделиться им на github.

Обновление: Вот гистограмма графика того, как выглядят входные данные. histogram of input data

Обновление 2:

Благодаря prouast меня указали в правильном направлении, но я все еще немного сбит с толку. Пытаясь переключиться на float16 вместо float32, я обнаружил, что при каждом вызове фрактала _net создается 1000 новых плотных слоев. Однако я смог увидеть это только через предупреждения, которые начали появляться в моем коде о том, что значения float32 и float16 используются одновременно. Поэтому я изменил код, чтобы инициализировать 20 плотных слоев один раз, а затем использовать их каждый раз, когда вызывается фрактал _net. Похоже, это работает, так как становится реже терять 2 ГБ ОЗУ на вызовы train_on_batch. Но это все еще происходит здесь и там.

Так что мой следующий вопрос: есть ли в любом случае отчет о подклассе модели, сколько плотных слоев в настоящее время используются и занимают ОЗУ? Я попытаюсь снова создать предупреждения float16 против предупреждений float32, потому что я забыл, как они создавались, но я предпочел бы иметь более прямой способ увидеть размер модели.

I проверил веса до и после вызова train_on_batch, и веса не обновляются, как я боялся.

Ответы [ 2 ]

0 голосов
/ 07 мая 2020

Я наконец-то обнаружил виновника того, почему память используется так резко. Оказывается, проблема была в строке кода: tf.random.shuffle (arr, seed)

Я все еще немного не уверен, почему это вызывает столько проблем, но у меня есть гипотеза. Я предполагаю, что, поскольку остальная часть кода использует бэкэнд Keras, а эта часть использует Tensorflow напрямую, а не через Keras, это вызывает множество причудливых проблем. Может быть, кто-то еще лучше объяснит, что происходит, когда вы пытаетесь использовать как Tensorflow напрямую, так и обновление Keras

: кажется, что иногда использование внутреннего интерфейса Keras также влечет за собой большие штрафы за использование памяти. Но только для определенных команд. Например, в моем коде K.switch, K.not_equal, K.equal и K.random_binomial, казалось, (менее радикально) увеличивали использование памяти с течением времени. Однако этого не произошло, когда я заменил эти части только командами numpy (вначале он потерял память больше, но потом перестал бы потреблять больше памяти).

Это странно, потому что не все Команды бэкэнда сократили использование памяти. Например, K.in_train_phase, похоже, не сильно повлиял на это.

Последний комментарий: я не уверен, имеет ли это какое-то отношение к этому или нет, но каждый раз, когда инициализируется другой класс, это может Я тоже был причиной, поэтому я удалил ненужные классы, которые вызывались бы тысячи раз.

0 голосов
/ 26 апреля 2020

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

Если вы хотите уменьшить объем памяти, используемый во время обучения, вы можете попробовать

  • Уменьшение размера партии
  • Уменьшение количества единиц в плотных слоях или количества плотных слоев
  • Возвращение к использованию сверточных слоев
  • Использование более низкой точности с плавающей точкой (например, fp16 вместо fp32), но это требует больше усилий, чем другие возможности
...