kaknikhil commented on a change in pull request #399: DL: Enable transfer 
learning
URL: https://github.com/apache/madlib/pull/399#discussion_r288686370
 
 

 ##########
 File path: src/ports/postgres/modules/deep_learning/test/madlib_keras.sql_in
 ##########
 @@ -779,3 +779,93 @@ SELECT madlib_keras_predict(
     'cifar10_predict',
     'prob',
     0);
+
+
+-- Test cases for transfer learning
+-- 1. Create a model arch table with weights all set to 0.008. 0.008 is just a
+-- random number we chose after a few experiments so that we can 
deterministically
+-- assert the loss and metric values reported by madlib_keras_fit.
+-- 2. Run keras fit and then update the model arch table with the output of 
the keras
+-- fit run.
+CREATE OR REPLACE FUNCTION create_model_arch_transfer_learning() RETURNS VOID 
AS $$
+from keras.layers import *
+from keras import Sequential
+import numpy as np
+import plpy
+
+model = Sequential()
+model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', 
input_shape=(32,32,3,)))
+model.add(MaxPooling2D(pool_size=(2, 2)))
+model.add(Dropout(0.25))
+model.add(Flatten())
+model.add(Dense(2, activation='softmax'))
+
+# we don't really need to get the weights from the model and the flatten them 
since
+# we are using np.ones_like to replace all the weights with a constant.
+# We want to keep the flatten code and the concatenation code just for 
reference
+weights = model.get_weights()
+weights_flat = [ w.flatten() for w in weights ]
+weights1d = np.array([j for sub in weights_flat for j in sub])
+# Adjust weights so that the learning for the first iteration can be 
deterministic
+# 0.008 is just a random number we chose after a few experiments
+weights1d = np.ones_like(weights1d)*0.008
+weights_bytea = weights1d.tostring()
+
+model_config = model.to_json()
+
+plan1 = plpy.prepare("""SELECT load_keras_model(
+                        'test_keras_model_arch_table',
+                        $1, $2)
+                    """, ['json','bytea'])
+plpy.execute(plan1, [model_config, weights_bytea])
+
+$$ LANGUAGE plpythonu VOLATILE;
+
+DROP TABLE IF EXISTS test_keras_model_arch_table;
+SELECT create_model_arch_transfer_learning();
+
+DROP TABLE IF EXISTS keras_saved_out, keras_saved_out_summary;
+SELECT madlib_keras_fit(
+    'cifar_10_sample_batched',
+    'keras_saved_out',
+    'test_keras_model_arch_table',
+    1,
+    $$ optimizer=SGD(lr=0.001, decay=1e-6, nesterov=True), 
loss='categorical_crossentropy', metrics=['mae']$$::text,
+    $$ batch_size=2, epochs=1, verbose=0 $$::text,
+    1);
+SELECT training_loss_final FROM keras_saved_out_summary;
+
+-- We want to keep this select in case the assert fails and we need
+-- to know the actual values in the table without re running the entire test
+\x
+select * from keras_saved_out_summary;
+\x
+
+-- This assert is a work in progress (we are hoping that these asserts will 
not be flaky).
+-- We want to be able to assert that the loss/metric for the first iteration is
+-- deterministic if we set weights using the load_keras function. Although we
+-- have seen that the loss/metric values are different in the 3rd/4th decimal
+-- every time we run fit after loading the weights.
+SELECT assert(abs(training_loss_final - 0.6) < 0.1 AND
+              abs(training_metrics_final - 0.4) < 0.1,
+       'Transfer learning test failed.')
+FROM keras_saved_out_summary;
+DROP FUNCTION create_model_arch_transfer_learning();
+
+UPDATE test_keras_model_arch_table SET model_weights = model_data FROM 
keras_saved_out WHERE model_id = 1;
+DROP TABLE IF EXISTS keras_saved_out, keras_saved_out_summary;
+SELECT madlib_keras_fit(
+    'cifar_10_sample_batched',
+    'keras_saved_out',
+    'test_keras_model_arch_table',
+    1,
+    $$ optimizer=SGD(lr=0.001, decay=1e-6, nesterov=True), 
loss='categorical_crossentropy', metrics=['mae']$$::text,
+    $$ batch_size=2, epochs=1, verbose=0 $$::text,
+    3);
+SELECT training_loss_final, training_metrics_final FROM 
keras_saved_out_summary;
+
+--assert training loss and metric deterministic
+SELECT assert(abs(training_loss_final - 0.64) < 0.01 AND
+              abs(training_metrics_final - 0.47) < 0.01,
 
 Review comment:
   +1 for the freezing layers assert.
   I do think that there is value in asserting both weights and the loss/metric 
values. For now I will add a TODO comment to the dev check assert to try out 
the freezing layers idea so that we can do this in a future JIRA. 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to