Tensorflow ResNet模型加载使用**〜5 GB RAM **-从重量加载仅使用〜200 MB

时间:2019-12-06 12:38:21

标签: tensorflow keras tensorflow2.0

我通过迁移学习使用Tensorflow 2.0训练了ResNet50模型。我在训练期间对架构(新的分类层)进行了少许修改,并使用ModelCheckpoint回调https://keras.io/callbacks/#modelcheckpoint保存了模型。训练很好。回调保存的模型在硬盘上大约需要206 MB。

要预测使用我所做的模型,

  • 我启动了Jupyter Lab笔记本。我使用my_model = tf.keras.models.load_model('../models_using/my_model.hdf5')来加载模型。 (顺便说一句,使用IPython也会发生这种情况。)

  • 我使用了free linux命令行工具来测量加载前后的可用RAM。 加载模型需要大约5 GB的RAM

  • 我将模型和配置的权重保存为json。这大约需要105 MB。

  • 我从json配置和权重加载了模型。这大约需要200 MB的RAM。

  • 比较了两个模型的预测。完全一样。

  • 我用稍有不同的体系结构(用相同的方法训练)测试了相同的过程,结果是相同的。

谁能解释巨大的RAM使用情况,以及硬盘驱动器上型号的差异?

顺便说一句,给定Keras中的模型,您能找出编译过程(优化器..)吗? Model.summary()没有帮助。.

2019-12-07-编辑:由于此answer,我进行了一系列测试:

我在JupyterLab中使用了!free命令来测量每次测试前后的可用内存。由于我get_weights返回了一个列表,因此我使用copy.deepcopy来真正复制对象。请注意,以下命令是单独的Jupyter单元,并且仅为此答案添加了内存注释。

!free

model = tf.keras.models.load_model('model.hdf5', compile=True)
# 25278624 - 21491888 = 3786.736 MB used

!free

weights = copy.deepcopy(model.get_weights())
# 21491888 - 21440272 = 51.616 MB used

!free


optimizer_weights = copy.deepcopy(model.optimizer.get_weights())
# 21440272 - 21339404 = 100.868 MB used

!free

model2 = tf.keras.models.load_model('model.hdf5', compile=False)
# 21339404 - 21140176 = 199.228 MB used

!free

从json加载模型:

!free
# loading from json
with open('model_json.json') as f:
    model_json_weights = tf.keras.models.model_from_json(f.read())

model_json_weights.load_weights('model_weights.h5')
!free

# 21132664 - 20971616 = 161.048 MB used

2 个答案:

答案 0 :(得分:3)

检查点和JSON + Weights之间的区别在于优化器:

  • 检查点或model.save()保存优化器及其权重(load_model编译模型)
  • JSON +权重不能保存优化器

除非您使用一个非常简单的优化器,否则它具有与模型相同数量的权重是正常的(例如,每个权重张量的“动量”张量)。

某些优化器可能占用模型大小的两倍,因为每个模型权重的张量都有两个优化器权重张量。

如果要继续训练,保存和加载优化器很重要。在没有适当权重的情况下,使用新的优化器重新开始训练会破坏模型的性能(至少在开始时如此)。

现在,对我来说5GB还不是很清楚。但我认为:

  • 减轻的重量应该压缩很多
  • 可能还需要为所有梯度和反向传播操作分配内存

有趣的测试:

  • 压缩:检查model.get_weights()model.optimizer.get_weights()的结果使用了多少内存。这些权重将为numpy,并从原始张量
  • 复制而来
  • 横向/反向传播:检查以下人员使用了多少内存:
    • load_model(name, compile=True)
    • load_model(name, compile=False)

答案 1 :(得分:1)

我尝试加载的最近模型遇到了非常相似的问题。无论如何,这是一个老问题,所以我不确定我的解决方案是否适合您。但是,阅读已保存模型的 keras documentation

我发现这段代码非常有用:

physical_devices = tf.config.list_physical_devices('GPU')
for device in physical_devices:
   tf.config.experimental.set_memory_growth(device, True)
<块引用>

谁能解释一下巨大的内存使用量,以及硬盘驱动器上模型大小的差异?

事实证明,在我的案例中,加载的模型耗尽了所有 GPU 内存并导致了问题,因此这迫使它使用物理设备内存,或者至少这是我的结论。