This function loads model architectures and weights into a table for use by deep learning algorithms.
Model architecture is in JSON form and model weights are in the form of PostgreSQL binary data types (bytea). If the output table already exists, a new row is inserted into the table so it can act as a repository for multiple model architectures and weights.
There is also a function to delete a model from the table.
MADlib's deep learning methods are designed to use the TensorFlow package and its built in Keras functions. To ensure consistency, please use tensorflow.keras objects (models, layers, etc.) instead of importing Keras and using its objects.
load_keras_model( keras_model_arch_table, model_arch, model_weights, name, description )
Arguments
VARCHAR. Output table to load keras model architecture and weights.
JSON. JSON of the model architecture to load.
bytea. Model weights to load as a PostgreSQL binary data type.
TEXT, default: NULL. Free text string to provide a name, if desired.
TEXT, default: NULL. Free text string to provide a description, if desired.
Output table
The output table contains the following columns:
model_id | SERIAL PRIMARY KEY. Model ID. |
---|---|
model_arch | JSON. JSON blob of the model architecture. |
model_weights | BYTEA. Weights of the model which may be used for warm start or transfer learning. Weights are stored as a PostgreSQL binary data type. |
name | TEXT. Name of model (free text). |
description | TEXT. Description of model (free text). |
__internal_madlib_id__ | TEXT. Unique id for model arch. This is an id used internally be MADlib. |
delete_keras_model( keras_model_arch_table model_id )
Arguments
VARCHAR. Table containing model architectures and weights.
import keras from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense model_simple = Sequential() model_simple.add(Dense(10, activation='relu', input_shape=(4,))) model_simple.add(Dense(10, activation='relu')) model_simple.add(Dense(3, activation='softmax')) model_simple.summary()Export the model to JSON:_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_1 (Dense) (None, 10) 50 _________________________________________________________________ dense_2 (Dense) (None, 10) 110 _________________________________________________________________ dense_3 (Dense) (None, 3) 33 ================================================================= Total params: 193 Trainable params: 193 Non-trainable params: 0
model_simple.to_json()
'{"class_name": "Sequential", "keras_version": "2.1.6", "config": [{"class_name": "Dense", "config": {"kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "scale": 1.0, "seed": null, "mode": "fan_avg"}}, "name": "dense_1", "kernel_constraint": null, "bias_regularizer": null, "bias_constraint": null, "dtype": "float32", "activation": "relu", "trainable": true, "kernel_regularizer": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "units": 10, "batch_input_shape": [null, 4], "use_bias": true, "activity_regularizer": null}}, {"class_name": "Dense", "config": {"kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "scale": 1.0, "seed": null, "mode": "fan_avg"}}, "name": "dense_2", "kernel_constraint": null, "bias_regularizer": null, "bias_constraint": null, "activation": "relu", "trainable": true, "kernel_regularizer": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "units": 10, "use_bias": true, "activity_regularizer": null}}, {"class_name": "Dense", "config": {"kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "scale": 1.0, "seed": null, "mode": "fan_avg"}}, "name": "dense_3", "kernel_constraint": null, "bias_regularizer": null, "bias_constraint": null, "activation": "softmax", "trainable": true, "kernel_regularizer": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "units": 3, "use_bias": true, "activity_regularizer": null}}], "backend": "tensorflow"}'
DROP TABLE IF EXISTS model_arch_library; SELECT madlib.load_keras_model('model_arch_library', -- Output table, $$ {"class_name": "Sequential", "keras_version": "2.1.6", "config": [{"class_name": "Dense", "config": {"kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "scale": 1.0, "seed": null, "mode": "fan_avg"}}, "name": "dense_1", "kernel_constraint": null, "bias_regularizer": null, "bias_constraint": null, "dtype": "float32", "activation": "relu", "trainable": true, "kernel_regularizer": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "units": 10, "batch_input_shape": [null, 4], "use_bias": true, "activity_regularizer": null}}, {"class_name": "Dense", "config": {"kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "scale": 1.0, "seed": null, "mode": "fan_avg"}}, "name": "dense_2", "kernel_constraint": null, "bias_regularizer": null, "bias_constraint": null, "activation": "relu", "trainable": true, "kernel_regularizer": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "units": 10, "use_bias": true, "activity_regularizer": null}}, {"class_name": "Dense", "config": {"kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "scale": 1.0, "seed": null, "mode": "fan_avg"}}, "name": "dense_3", "kernel_constraint": null, "bias_regularizer": null, "bias_constraint": null, "activation": "softmax", "trainable": true, "kernel_regularizer": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "units": 3, "use_bias": true, "activity_regularizer": null}}], "backend": "tensorflow"} $$ ::json, -- JSON blob NULL, -- Weights 'Sophie', -- Name 'A simple model' -- Descr ); SELECT COUNT(*) FROM model_arch_library;
count -------+ 1Load another model architecture:
SELECT madlib.load_keras_model('model_arch_library', -- Output table, $$ {"class_name": "Sequential", "keras_version": "2.1.6", "config": [{"class_name": "Dense", "config": {"kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "scale": 1.0, "seed": null, "mode": "fan_avg"}}, "name": "dense_1", "kernel_constraint": null, "bias_regularizer": null, "bias_constraint": null, "dtype": "float32", "activation": "relu", "trainable": true, "kernel_regularizer": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "units": 10, "batch_input_shape": [null, 4], "use_bias": true, "activity_regularizer": null}}, {"class_name": "Dense", "config": {"kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "scale": 1.0, "seed": null, "mode": "fan_avg"}}, "name": "dense_2", "kernel_constraint": null, "bias_regularizer": null, "bias_constraint": null, "activation": "relu", "trainable": true, "kernel_regularizer": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "units": 10, "use_bias": true, "activity_regularizer": null}}, {"class_name": "Dense", "config": {"kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "scale": 1.0, "seed": null, "mode": "fan_avg"}}, "name": "dense_3", "kernel_constraint": null, "bias_regularizer": null, "bias_constraint": null, "activation": "softmax", "trainable": true, "kernel_regularizer": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "units": 3, "use_bias": true, "activity_regularizer": null}}], "backend": "tensorflow"} $$ ::json, -- JSON blob NULL, -- Weights 'Maria', -- Name 'Also a simple model' -- Descr ); SELECT COUNT(*) FROM model_arch_library;
count -------+ 2
UPDATE model_arch_library SET model_weights = model_weights FROM iris_model WHERE model_id = 2; SELECT model_id, name, description, (model_weights IS NOT NULL) AS has_model_weights FROM model_arch_library ORDER BY model_id;
model_id | name | description | has_model_weights ----------+--------+---------------------+------------------- 1 | Sophie | A simple model | f 2 | Maria | Also a simple model | t
CREATE OR REPLACE FUNCTION load_weights() RETURNS VOID AS $$ import keras from tensorflow.keras.layers import * from tensorflow.keras import Sequential import numpy as np import plpy # # create model model = Sequential() model.add(Dense(10, activation='relu', input_shape=(4,))) model.add(Dense(10, activation='relu')) model.add(Dense(3, activation='softmax')) # # get weights, flatten and serialize weights = model.get_weights() weights_flat = [w.flatten() for w in weights] weights1d = np.concatenate(weights_flat).ravel() weights_bytea = weights1d.tostring() # # load query load_query = plpy.prepare("""SELECT madlib.load_keras_model( 'model_arch_library', $1, $2) """, ['json','bytea']) plpy.execute(load_query, [model.to_json(), weights_bytea]) $$ language plpython3u; -- Call load function SELECT load_weights(); SELECT model_id, name, description, (model_weights IS NOT NULL) AS has_model_weights FROM model_arch_library ORDER BY model_id;
model_id | name | description | has_model_weights ----------+--------+---------------------+------------------- 1 | Sophie | A simple model | f 2 | Maria | Also a simple model | t 3 | Ella | Model x | t
import psycopg2 import psycopg2 as p2 conn = p2.connect('postgresql://gpadmin@35.239.240.26:5432/madlib') cur = conn.cursor() from tensorflow.keras.layers import * from tensorflow.keras import Sequential import numpy as np # # create model model = Sequential() model.add(Dense(10, activation='relu', input_shape=(4,))) model.add(Dense(10, activation='relu')) model.add(Dense(3, activation='softmax')) # # get weights, flatten and serialize weights = model.get_weights() weights_flat = [w.flatten() for w in weights] weights1d = np.concatenate(weights_flat).ravel() weights_bytea = psycopg2.Binary(weights1d.tostring()) # # load query query = "SELECT madlib.load_keras_model('model_arch_library', %s,%s)" cur.execute(query,[model.to_json(),weights_bytea]) conn.commit() SELECT model_id, name, description, (model_weights IS NOT NULL) AS has_model_weights FROM model_arch_library ORDER BY model_id;
model_id | name | description | has_model_weights ----------+--------+---------------------+------------------- 1 | Sophie | A simple model | f 2 | Maria | Also a simple model | t 3 | Ella | Model x | t 4 | Grace | Model y | t
SELECT madlib.delete_keras_model('model_arch_library', -- Output table 1 -- Model id ); SELECT model_id, name, description, (model_weights IS NOT NULL) AS has_model_weights FROM model_arch_library ORDER BY model_id;
model_id | name | description | has_model_weights ----------+-------+---------------------+------------------- 2 | Maria | Also a simple model | t 3 | Ella | Model x | t 4 | Grace | Model y | t