Tensorflow ResNet 模型加载使用 **~5 GB 的 RAM** - 而从权重加载仅使用 ~200 MB
Tensorflow ResNet model loading uses **~5 GB of RAM** - while loading from weights uses only ~200 MB
我使用 Tensorflow 2.0 通过迁移学习训练了一个 ResNet50 模型。我稍微修改了架构(新分类层)并在训练期间使用 ModelCheckpoint 回调 https://keras.io/callbacks/#modelcheckpoint 保存了模型。训练很好。回调保存的模型占用硬盘约 206 MB。
使用我做的模型进行预测:
我开始使用 Jupyter Lab notebook。我使用 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 - 编辑: 多亏了这个 ,我进行了一系列测试:
我在JupyterLab中使用了!free
命令来测量每次测试前后的可用内存。由于我 get_weights
returns 一个列表,所以我使用 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
检查点和JSON+权重的区别在于优化器:
- 检查点或
model.save()
保存优化器及其权重(load_model
编译模型)
- JSON + 权重不保存优化器
除非您使用的是非常简单的优化器,否则它具有与模型大致相同数量的权重是正常的(例如,每个权重张量的张量为 "momentum")。
一些优化器可能需要模型大小的两倍,因为每个模型权重张量都有两个优化器权重张量。
如果您想继续训练,保存和加载优化器很重要。使用没有适当权重的新优化器重新开始训练会破坏模型的性能(至少在开始时)。
现在,5GB 对我来说不是很清楚。但我想:
- 保存的权重应该有很多压缩
- 这可能与为所有梯度和反向传播操作分配内存有关
有趣的测试:
- 压缩:检查
model.get_weights()
和model.optimizer.get_weights()
的结果使用了多少内存。这些权重将是 numpy,从原始张量复制
- Grandient/Backpropagation:检查使用了多少内存:
load_model(name, compile=True)
load_model(name, compile=False)
我尝试加载的最新模型遇到了非常相似的问题。不管怎样,这已经是一年前的问题了,所以我不确定我的解决方案是否适合您。但是,正在阅读 keras documentation 保存的模型。
我发现这段代码非常有用:
physical_devices = tf.config.list_physical_devices('GPU')
for device in physical_devices:
tf.config.experimental.set_memory_growth(device, True)
Can anyone explain the huge RAM usage, and the difference in size of the models on the hard drive?
事实证明,在我的情况下,加载的模型耗尽了所有 GPU 内存并导致问题,因此这迫使它使用物理设备内存,或者至少这是我的结论。
我使用 Tensorflow 2.0 通过迁移学习训练了一个 ResNet50 模型。我稍微修改了架构(新分类层)并在训练期间使用 ModelCheckpoint 回调 https://keras.io/callbacks/#modelcheckpoint 保存了模型。训练很好。回调保存的模型占用硬盘约 206 MB。
使用我做的模型进行预测:
我开始使用 Jupyter Lab notebook。我使用
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 - 编辑: 多亏了这个
我在JupyterLab中使用了!free
命令来测量每次测试前后的可用内存。由于我 get_weights
returns 一个列表,所以我使用 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
检查点和JSON+权重的区别在于优化器:
- 检查点或
model.save()
保存优化器及其权重(load_model
编译模型) - JSON + 权重不保存优化器
除非您使用的是非常简单的优化器,否则它具有与模型大致相同数量的权重是正常的(例如,每个权重张量的张量为 "momentum")。
一些优化器可能需要模型大小的两倍,因为每个模型权重张量都有两个优化器权重张量。
如果您想继续训练,保存和加载优化器很重要。使用没有适当权重的新优化器重新开始训练会破坏模型的性能(至少在开始时)。
现在,5GB 对我来说不是很清楚。但我想:
- 保存的权重应该有很多压缩
- 这可能与为所有梯度和反向传播操作分配内存有关
有趣的测试:
- 压缩:检查
model.get_weights()
和model.optimizer.get_weights()
的结果使用了多少内存。这些权重将是 numpy,从原始张量复制 - Grandient/Backpropagation:检查使用了多少内存:
load_model(name, compile=True)
load_model(name, compile=False)
我尝试加载的最新模型遇到了非常相似的问题。不管怎样,这已经是一年前的问题了,所以我不确定我的解决方案是否适合您。但是,正在阅读 keras documentation 保存的模型。
我发现这段代码非常有用:
physical_devices = tf.config.list_physical_devices('GPU')
for device in physical_devices:
tf.config.experimental.set_memory_growth(device, True)
Can anyone explain the huge RAM usage, and the difference in size of the models on the hard drive?
事实证明,在我的情况下,加载的模型耗尽了所有 GPU 内存并导致问题,因此这迫使它使用物理设备内存,或者至少这是我的结论。