Я использую Tensorflow 2.0 с API-интерфейсами keras.Есть ситуации, когда мне нужно создать несколько моделей в рамках одного и того же выполнения программы (скажем, ситуация перекрестной проверки).Когда я генерирую эти модели без указания формы ввода, как в следующем фрагменте кода, утечка памяти отсутствует.
import time
from tensorflow import keras
for _ in range(100):
model = keras.model.Sequential()
model.add(keras.kayers.Dense(120, activation='relu'))
model.compile(loss='binary_crossentropy',
optimizer=keras.optimizers.SGD())
time.sleep(0.1)
![Total memory with no input shape specified](https://i.stack.imgur.com/BPNgA.png)
Однако,если я указываю форму ввода при добавлении первого слоя модели, кажется, что модели накапливаются в памяти, без разрушения, когда в этом нет необходимости.Также кажется, что время выполнения значительно увеличивается.
import time
from tensorflow import keras
for _ in range(100):
model = keras.model.Sequential()
model.add(keras.kayers.Dense(120, activation='relu', input_shape=(10, 10)))
model.compile(loss='binary_crossentropy',
optimizer=keras.optimizers.SGD())
time.sleep(0.1)
![Total memory with input shape specified](https://i.stack.imgur.com/zjUri.png)
Я также сгенерировал список всех объектов для 2 фрагментов кода, используя Pympler
.
from pympler import muppy
from pympler import summary
...
all_objects = muppy.get_objects()
occupancy = summary.summarize(all_objects)
summary.print_(occupancy)
Для моделей, сгенерированных без входной формы, вот результат:
types | # objects | total size
======================================================================== | =========== | ============
<class 'str | 79278 | 14.02 MB
<class 'dict | 14468 | 6.93 MB
<class 'code | 25252 | 3.49 MB
<class 'type | 2582 | 2.57 MB
<class 'list | 8573 | 944.06 KB
<class 'tuple | 12079 | 796.21 KB
<class 'set | 732 | 466.12 KB
<class 'weakref | 4475 | 349.61 KB
<class 'abc.ABCMeta | 341 | 346.27 KB
<class 'tensorflow.core.framework.op_def_pb2.ArgDef | 3822 | 328.45 KB
<class 'google.protobuf.pyext.cpp_message.GeneratedProtocolMessageType | 369 | 320.16 KB
<class 'cell | 5921 | 277.55 KB
function (__init__) | 1694 | 224.98 KB
<class 'property | 2466 | 192.66 KB
<class 'wrapper_descriptor | 2353 | 183.83 KB
А вот снимок для моделей, сгенерированных с входной формой.
types | # objects | total size
================================================================ | =========== | ============
<class 'tuple | 296304 | 26.77 MB
<class 'dict | 71296 | 16.14 MB
<class 'str | 84828 | 14.54 MB
<class 'int | 395032 | 10.55 MB
<class 'list | 98027 | 9.89 MB
<class 'code | 25281 | 3.49 MB
<class 'type | 2587 | 2.58 MB
<class 'set | 2944 | 975.00 KB
<class 'tensorflow.python.framework.ops.Operation | 14100 | 771.09 KB
<class 'tensorflow.python.framework.ops.Operation._InputList | 14100 | 771.09 KB
<class 'tensorflow.python.framework.ops.Tensor | 14100 | 771.09 KB
<class 'tensorflow.python.pywrap_tensorflow_internal.TF_Output | 13200 | 721.88 KB
<class 'SwigPyObject | 14100 | 660.94 KB
<class 'collections.OrderedDict | 1262 | 622.22 KB
<class 'weakref | 6127 | 478.67 KB
Что-то не так я делаю?Согласно соответствующей документации keras форма входа должна быть каким-то образом предоставлена слою (документация Tensorflow о форме ввода говорит, что если слой имеет несколько входов, форма не нужна), однако, мой код по-прежнему работает без указания формы ввода.Боюсь, что это может быть ошибкой в Tensorflow 2, но, честно говоря, я действительно не знаю, в чем дело.
Примечания
- Сгенерированы графики памятис пакетом
memory_profiler
. - Снимки памяти создаются с пакетом
Pympler
. - Используется Python 3.7.1.
- ОС - элементарный Linux (Ubuntu).
Спасибо за вашу поддержку.