Почему тензорный поток потребляет так много памяти?

  • У меня есть простая CNN (4 слоя conv-pool-lrelu и 2 полносвязных).
  • Я использую TensorFlow только на процессоре (без графического процессора).
  • У меня есть ~ 6 ГБ доступной памяти.
  • Мои партии состоят из 56 изображений размером 640x640 пикселей ( ‹ 100 МБ ).

И TensorFlow потребляет больше доступной памяти (что, очевидно, приводит к сбою программы).

Мой вопрос: почему TensorFlow требует столько памяти для запуска моей сети? Я не понимаю, что занимает так много места (может быть, кэширование данных несколько раз для оптимизации вычислений свертки? Сохранение всех скрытых выходных данных для целей обратного распространения?). И есть ли способ предотвратить использование TensorFlow такого большого объема памяти?

Побочные примечания:

  • Я не могу уменьшить размер пакета, я пытаюсь провести обучение с несколькими экземплярами, поэтому мне нужно вычислить все мои патчи за один прогон.
  • Я использую AdamOptimizer
  • Все мои свертки - это окна 5x5, шаг 1x1, с (от 1-го до последнего) 32, 64, 128 и 256 функциями. Я использую дырявые ReLU и максимальный пул 2x2. Слои FC состоят из 64 и 3 нейронов.
  • Использование Ubuntu 16.4/Python 3.6.4/TensorFlow 1.6.0

person Motiss    schedule 30.04.2018    source источник


Ответы (1)


Как вы упомянули:

Все мои свертки - это окна 5x5, шаг 1x1, с (от 1-го до последнего) 32, 64, 128 и 256 функциями. Я использую дырявые ReLU и максимальный пул 2x2. Слои FC состоят из 64 и 3 нейронов.

Итак, потребление памяти в вашей сети выглядит следующим образом:

Input: 640x640x3 = 1200 (in KB)

C1: 636x636x32 = 12,5 МБ (шаг=1 работал)

P1: 635x635x32 = 12,3 МБ (шаг=1 работал)

C2: 631x631x64 = 24.3 MB

P2: 630x630x64 = 24.2 MB

C3: 626x626x128 = 47.83 MB

P3: 625x625x128 = 47.68 MB

C4: 621x621x256 = 94.15 MB

P4: 620x620x256 = 93.84 MB

FC1: 64 = 0,0625 КБ (незначительно)

FC2: 3 = 0,003 КБ (незначительно)

Total for one image = ~ 358 MB

For batch of 56 image = 56 x 358 ~19.6 GB

Вот почему ваша сеть не работает на 6 GB. Попробуйте с помощью higher stride или lower sized image настроить его на 6 GB пространство. И это должно работать.

Вы можете обратиться к этому, чтобы лучше понять расчет потребления памяти.

person Akash Goyal    schedule 30.04.2018
comment
Хм... Чего я не понимаю, так это того, что после вычисления выхода P1 нам не нужно все еще помнить вывод C1, мы можем его сбросить и освободить нашу память. Так же и для выхода P1, когда был рассчитан выход C2. Таким образом, максимальная выделенная память в данный момент времени никогда не должна быть всей (1200+12800+12640,5+25281+24964+49928+49298+98596+97344+64+3) суммой, а только ее локальной частью. :-/ - person Motiss; 30.04.2018
comment
И кстати, мои слои POOL не перекрываются, поэтому размер данных уменьшается на 4 после каждого POOL. - person Motiss; 30.04.2018
comment
Вы говорите, что у вас есть шаг = 2 для POOL. Таким образом, в этом случае потребление памяти в сети будет составлять ~ 1,6 ГБ за один прямой проход для пакета (также может быть некоторое потребление памяти при обратном проходе). Правильно проверьте все параметры. - person Akash Goyal; 01.05.2018
comment
Хм... Если я посмотрю на ваши расчеты, вы скажете, что FC2=3B, что подразумевает вывод стоимостью 1B, но на самом деле все это какой-то tensorflow.float32, что подразумевает 4B. Если исправить это, у нас может быть 1,6 ГБ * 4 > 6 ГБ. Но это все еще не объясняет мне, почему TensorFlow запоминает все скрытые выходные данные, когда они больше не нужны для вычислений. - person Motiss; 02.05.2018
comment
Если вы делаете только прямое распространение, вам не нужны скрытые выходы. Но все скрытые выходные данные необходимы для вычисления весов при обратном распространении. Проверьте любой пример того, как веса рассчитываются во время обратного распространения. - person Akash Goyal; 02.05.2018
comment
В этот момент я должен винить себя за то, что был таким глупым. :D Большое спасибо! - person Motiss; 02.05.2018