How to determine needed memory of Keras model?
I created a complete function based on the answer of Fabrício Pereira.
def get_model_memory_usage(batch_size, model):
import numpy as np
try:
from keras import backend as K
except:
from tensorflow.keras import backend as K
shapes_mem_count = 0
internal_model_mem_count = 0
for l in model.layers:
layer_type = l.__class__.__name__
if layer_type == 'Model':
internal_model_mem_count += get_model_memory_usage(batch_size, l)
single_layer_mem = 1
out_shape = l.output_shape
if type(out_shape) is list:
out_shape = out_shape[0]
for s in out_shape:
if s is None:
continue
single_layer_mem *= s
shapes_mem_count += single_layer_mem
trainable_count = np.sum([K.count_params(p) for p in model.trainable_weights])
non_trainable_count = np.sum([K.count_params(p) for p in model.non_trainable_weights])
number_size = 4.0
if K.floatx() == 'float16':
number_size = 2.0
if K.floatx() == 'float64':
number_size = 8.0
total_memory = number_size * (batch_size * shapes_mem_count + trainable_count + non_trainable_count)
gbytes = np.round(total_memory / (1024.0 ** 3), 3) + internal_model_mem_count
return gbytes
UPDATE 2019.10.06: Added support for models which contain other models as layers.
UPDATE 2020.07.17: Function now works correctly in TensorFlow v2.
Hope this can help you...
-
Here is how determinate a number of shapes of you Keras model (var
model
), and each shape unit occupies 4 bytes in memory:shapes_count = int(numpy.sum([numpy.prod(numpy.array([s if isinstance(s, int) else 1 for s in l.output_shape])) for l in model.layers]))
memory = shapes_count * 4
-
And here is how determinate a number of params of your Keras model (var
model
):from keras import backend as K
trainable_count = int(numpy.sum([K.count_params(p) for p in set(model.trainable_weights)]))
non_trainable_count = int(numpy.sum([K.count_params(p) for p in set(model.non_trainable_weights)]))
Here is my variant of @ZFTurbo's answer. It offers better handling for nested Keras models, different TensorFlow dtypes, and removes the dependency on NumPy. I've written and tested this on TensorFlow 2.3.0, and it may not work on earlier versions.
def keras_model_memory_usage_in_bytes(model, *, batch_size: int):
"""
Return the estimated memory usage of a given Keras model in bytes.
This includes the model weights and layers, but excludes the dataset.
The model shapes are multipled by the batch size, but the weights are not.
Args:
model: A Keras model.
batch_size: The batch size you intend to run the model with. If you
have already specified the batch size in the model itself, then
pass `1` as the argument here.
Returns:
An estimate of the Keras model's memory usage in bytes.
"""
default_dtype = tf.keras.backend.floatx()
shapes_mem_count = 0
internal_model_mem_count = 0
for layer in model.layers:
if isinstance(layer, tf.keras.Model):
internal_model_mem_count += keras_model_memory_usage_in_bytes(
layer, batch_size=batch_size
)
single_layer_mem = tf.as_dtype(layer.dtype or default_dtype).size
out_shape = layer.output_shape
if isinstance(out_shape, list):
out_shape = out_shape[0]
for s in out_shape:
if s is None:
continue
single_layer_mem *= s
shapes_mem_count += single_layer_mem
trainable_count = sum(
[tf.keras.backend.count_params(p) for p in model.trainable_weights]
)
non_trainable_count = sum(
[tf.keras.backend.count_params(p) for p in model.non_trainable_weights]
)
total_memory = (
batch_size * shapes_mem_count
+ internal_model_mem_count
+ trainable_count
+ non_trainable_count
)
return total_memory