You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@madlib.apache.org by GitBox <gi...@apache.org> on 2020/09/22 16:45:00 UTC

[GitHub] [madlib] Advitya17 opened a new pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Advitya17 opened a new pull request #518:
URL: https://github.com/apache/madlib/pull/518


   JIRA: MADLIB-1453
   
   We expand AutoML capabilities in MADlib by adding support for Hyperopt, another hyperparameter optimization method to minimize losses with awkward search spaces. The user can declaratively specify the automl method name with the related automl params (with all other argument declarations staying the same across different AutoML methods) and our API handles the exploration and execution components with the algorithm workload info displayed to the user.
   
   We implement Hyperopt for Massively Parallel Processing (MPP) to perform model selection on top of our existing Model hOpper (MOP) infrastructure for model training/evaluation. Our API currently offers declarative support for Random Search and Tree-structured Parzen Estimator (TPE), a Bayesian Optimization like approach.
   
   This PR also includes:
   1. Code re-factor to add additional classes (inheriting from the AutoML super class) for any future AutoML methods.
   2. 'best-so-far' console info for each AutoML method currently supported (i.e. Hyperband and Hyperopt)
   3. Disabling automl method argument prefixing (while still retaining case insensitivity).
   
   
   


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-715643042


   (100)
   error msg
   ```
   madlib=# SELECT madlib.madlib_keras_automl('iris_train_packed',                -- source table
   madlib(#                                   'automl_output',                    -- model output table
   madlib(#                                   'model_arch_library',               -- model architecture table
   madlib(#                                   'automl_mst_table',                 -- model selection output table
   madlib(#                                   ARRAY[1,2],                         -- model IDs
   madlib(#                                   $${
   madlib$#                                       'loss': ['categorical_crossentropy'], 
   madlib$#                                       'optimizer_params_list': [ 
   madlib$#                                           {'optimizer': ['Adam'],'lr': [0.001, 0.1, 'log']},
   madlib$#                                           {'optimizer': ['RMSprop'],'lr': [0.001, 0.1, 'log']}
   madlib$#                                       ],
   madlib$#                                       'metrics': ['accuracy']
   madlib$#                                   } $$,                               -- compile param grid
   madlib(#                                   $${'batch_size': [4, 8], 'epochs': [1]}$$,  -- fit params grid
   madlib(#                                   'hyperband',                        -- autoML method
   madlib(#                                   'num_configs=6, num_iterations=3, algorithm=rand',  -- autoML params
   madlib(#                                   NULL,                               -- random state
   madlib(#                                   NULL,                               -- object table
   madlib(#                                   FALSE,                              -- use GPUs
   madlib(#                                   'iris_test_packed',                 -- validation table
   madlib(#                                   1,                                  -- metrics compute freq
   madlib(#                                   NULL,                               -- name
   madlib(#                                   NULL);                              -- descr
   ERROR:  ValueError: invalid literal for int() with base 10: 'rand' (plpython.c:5038)
   CONTEXT:  Traceback (most recent call last):
     PL/Python function "madlib_keras_automl", line 23, in <module>
       schedule_loader = madlib_keras_automl_hyperband.AutoMLHyperband(**globals())
     PL/Python function "madlib_keras_automl", line 164, in __init__
     PL/Python function "madlib_keras_automl", line 174, in validate_and_define_inputs
   PL/Python function "madlib_keras_automl"
   ```
   this message confused me for awhile till I realized I asked for hyperband but gave hyperopt params accidentally
   
   (101)
   error msg
   ```
   madlib=# SELECT madlib.madlib_keras_automl('iris_train_packed',                -- source table
   madlib(#                                   'automl_output',                    -- model output table
   madlib(#                                   'model_arch_library',               -- model architecture table
   madlib(#                                   'automl_mst_table',                 -- model selection output table
   madlib(#                                   ARRAY[1,2],                         -- model IDs
   madlib(#                                   $${
   madlib$#                                       'loss': ['categorical_crossentropy'], 
   madlib$#                                       'optimizer_params_list': [ 
   madlib$#                                           {'optimizer': ['Adam'],'lr': [0.001, 0.1, 'log']},
   madlib$#                                           {'optimizer': ['RMSprop'],'lr': [0.001, 0.1, 'log']}
   madlib$#                                       ],
   madlib$#                                       'metrics': ['accuracy']
   madlib$#                                   } $$,                               -- compile param grid
   madlib(#                                   $${'batch_size': [4, 8], 'epochs': [1]}$$,  -- fit params grid
   madlib(#                                   'hyperopt',                        -- autoML method
   madlib(#                                   'R=9, eta=3, skip_last=0',          -- autoML params
   madlib(#                                   NULL,                               -- random state
   madlib(#                                   NULL,                               -- object table
   madlib(#                                   FALSE,                              -- use GPUs
   madlib(#                                   'iris_test_packed',                 -- validation table
   madlib(#                                   1,                                  -- metrics compute freq
   madlib(#                                   NULL,                               -- name
   madlib(#                                   NULL);                              -- descr
   ERROR:  plpy.Error: madlib_keras_automl: skip_last is an invalid automl param (plpython.c:5038)
   CONTEXT:  Traceback (most recent call last):
     PL/Python function "madlib_keras_automl", line 45, in <module>
       schedule_loader = madlib_keras_automl_hyperopt.AutoMLHyperopt(**globals())
     PL/Python function "madlib_keras_automl", line 69, in __init__
     PL/Python function "madlib_keras_automl", line 115, in validate_and_define_inputs
   PL/Python function "madlib_keras_automl"
   ```
   likewise this could be improved if I asked for hyperopt but gave hyperband params accidentally.  Because skip_last is valid but only for hyberband.
   


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] orhankislal commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
orhankislal commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r493744195



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works
+                else:
+                    plpy.error("DL: algorithm in 'automl_params' must be 'rand', 'tpe'") # , or 'atpe'
+            else:
+                plpy.error("DL: {0} is an invalid automl param".format(i))
+        _assert(self.num_models > 0 and self.num_iters > 0, "DL: num_models and num_iters in 'automl_params' "
+                                                            "must be positive")
+        _assert(self._is_valid_metrics_compute_frequency(self.num_iters), "DL: 'metrics_compute_frequency' "
+                                                                          "out of iteration range")
+
+    def find_hyperopt_config(self):
         """
-        Drops and re-create the mst table to only include the best performing model configuration.
+        Executes hyperopt on top of MOP.
         """
-        drop_tables([self.model_selection_table])
 
-        # only retaining best performing config
-        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT mst_key, model_id, compile_params, " \
-                     "fit_params FROM {self.model_info_table} " \
-                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self, AutoMLSchema=AutoMLSchema))
+        make_mst_summary = True
+        trials = Trials()
+        domain = Domain(None, self.get_search_space())
+        rand_state = np.random.RandomState(self.random_state)
+        configs_lst = self.get_configs_list()
 
-    def generate_model_output_summary_table(self, model_training):
+        self.start_training_time = self.get_current_timestamp()
+        for low, high in configs_lst:
+            i, n = low, high - low + 1
+
+            # Using HyperOpt TPE/ATPE to generate parameters
+            hyperopt_params = []
+            sampled_params = []
+            for j in range(i, i + n):
+                new_param = self.algorithm.suggest([j], domain, trials, rand_state.randint(0, 2 ** 31 - 1))

Review comment:
       I don't think we should calculate 2**31 every time we run this. Setting an INT_MAX constant would be better.




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707399640


   >  mst_key |                 metrics_elapsed_time                 
   > ---------+------------------------------------------------------
   >        1 | {627.882262945175,1264.80915999413,1896.74943590164}
   >        2 | {614.573877811432,1251.1022670269,1883.14707994461}
   >        3 | {638.407788038254,1286.73397421837,1939.58357810974}
   >        4 | {624.925609111786,1273.55782914162,1925.82674407959}
   >        5 | {650.984225034714,1307.78145503998,1962.8148560524}
   >        6 | {637.914520978928,1294.23532605171,1949.12843108177}
   >        7 | {651.188719987869,1301.32990193367,1948.88206887245}
   >        8 | {637.525157928467,1288.19901585579,1935.65923500061}
   >        9 | {651.277820110321,1301.09531402588,1947.13559818268}
   >       10 | {637.898158073425,1287.54387116432,1933.5972070694}
   >       11 | {650.482151985168,1309.5760037899,1961.18471598625}
   >       12 | {637.149097919464,1295.67461585999,1947.66235399246}
   >       13 | {651.543440818787,1299.3868060112,1948.78301692009}
   >       14 | {638.292811870575,1285.66767001152,1935.02927088737}
   >       15 | {650.077238082886,1305.37611913681,1962.8950419426}
   >       16 | {636.498329162598,1291.3173930645,1948.41972708702}
   >       17 | {649.946799993515,1303.33863401413,1949.58992981911}
   >       18 | {636.373380899429,1289.27607584,1936.36742186546}
   >       19 | {647.414880990982,1297.31931090355,1945.65248298645}
   >       20 | {634.09289598465,1284.170140028,1932.07456684113}
   
   It may be possible to do the following to get the graph:
   
   1. Have a 'time offset' like variable (initially set to zero)
   2. Time the individual fit multiple function calls (in seconds I presume) (for adding the recorded times to the offset variable each time). 
   3. After 1 run of fit multiple, write an update like query to update `metrics_elapsed_time` by adding the total offset to every element of the array value (for the first run, an offset of 0 would be added, i.e. no offset) for the model configs trained in that round (this may be determined by the `mst_key` ranges).
   4. Update the offset variable by incrementing it by the recorded time for the most recent loop run (i.e. fit multiple function call).
   
   Let me know if anything doesn't seem clear.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698557841


   (3)
   ```
   PL/Python function "madlib_keras_automl"
   ERROR:  plpy.Error: DL: Please choose a valid distribution type for 'momentum_3': ['linear', 'log'] (plpython.c:5038)
   ```
   Should not report `_3` or `_4` or whatever in messages since user does not know what these are.  Should just report:
   ```
   PL/Python function "madlib_keras_automl"
   ERROR:  plpy.Error: DL: Please choose a valid distribution type for 'momentum': ['linear', 'log'] (plpython.c:5038)
   ```
   etc.
   


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] orhankislal commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
orhankislal commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r494129949



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -291,9 +338,100 @@ class KerasAutoML():
                (self.metrics_compute_frequency >= 1 and \
                 self.metrics_compute_frequency <= num_iterations)
 
+    def print_best_so_far(self):
+        """
+        Prints mst keys with best train/val losses at a given point.
+        """
+        best_so_far = '\n'
+        best_so_far += self.print_best_helper('training')
+        if self.validation_table:
+            best_so_far += self.print_best_helper('validation')
+        plpy.info(best_so_far)
+
+    def print_best_helper(self, keyword):
+        """
+        Helper function to Prints mst keys with best train/val losses at a given point.
+        :param keyword: column prefix ('training' or 'validation')
+        :return:
+        """
+        metrics_word, loss_word = keyword + '_metrics_final', keyword + '_loss_final'
+
+        res_str = 'Best {keyword} loss so far:\n'.format(keyword=keyword)
+        best_value = plpy.execute("SELECT {ModelSelectionSchema.MST_KEY}, {metrics_word}, " \
+                                  "{loss_word} FROM {self.model_info_table} ORDER BY " \
+                                  "{loss_word} LIMIT 1".format(self=self, ModelSelectionSchema=ModelSelectionSchema,
+                                                               metrics_word=metrics_word, loss_word=loss_word))[0]
+        mst_key_value, metric_value, loss_value = best_value[ModelSelectionSchema.MST_KEY], \
+                                                  best_value[metrics_word], best_value[loss_word]
+        res_str += ModelSelectionSchema.MST_KEY + '=' + str(mst_key_value) + ': metric=' + str(metric_value) + \
+                   ', loss=' + str(loss_value) + '\n'
+        return res_str
+
+    def get_current_timestamp(self):
+        """for start and end times for the chosen AutoML algorithm. Showcased in the output summary table"""
+        return datetime.fromtimestamp(time()).strftime('%Y-%m-%d %H:%M:%S')
+
+    def remove_temp_tables(self, model_training):
+        """
+        Remove all intermediate tables created for AutoML runs/updates.
+        :param model_training: Fit Multiple function call object.
+        """
+        drop_tables([model_training.original_model_output_table, model_training.model_info_table,
+                     model_training.model_summary_table, AutoMLSchema.TEMP_MST_TABLE,
+                     AutoMLSchema.TEMP_MST_SUMMARY_TABLE])
+
+# @MinWarning("warning")
+class AutoMLHyperband(KerasAutoML):
+    """
+    This class implements Hyperband, an infinite-arm bandit based algorithm that speeds up random search
+    through adaptive resource allocation, successive halving (SHA) and early stopping.
+
+    This class showcases and novel hyperband implementation by executing the hyperband rounds 'diagonally'

Review comment:
       I meant this: 
   `This class showcases and novel hyperband` -> `This class showcases a novel hyperband`




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707417107


   Let's be consistent with the output for hyperband and add it to the info table, even if the value will be the same for all mst keys.  The table is small so that is not a problem and it may change in the future if we learn something new about how it should be presented.
    


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-700952240


   > (6)
   > fmin definition
   > https://github.com/hyperopt/hyperopt/wiki/FMin
   > fmin(loss, space, algo, max_evals)
   > 
   > Looks like this PR is setting max_evals = num_models/num_segments in `get_configs_list()`. For one thing I'm not sure that
   > 
   > ```
   > self.num_workers = get_seg_number() * get_segments_per_host()
   > ```
   > 
   > gives total number of workers? On a 1 host, 2 segments-per-host database this returned 4 instead of the expected 2. Also this needs to be consistent with the distribution rules set in the mini-batch preprocessor.
   > 
   > (7)
   > The function `get_configs_list()` may not be distributing the workload correctly to the segments.
   > For
   > 
   > ```
   >     num_models = 3
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 3)]` which seems OK. But for
   > 
   > ```
   >     num_models = 5
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 5)]` which does not seem OK. It will not do any hyperopt updates if all 5 configs are grouped together. I would have expected `[(1, 3), (4, 5)]`. For
   > 
   > ```
   >     num_models = 20
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 4), (5, 8), (9, 11), (12, 14), (15, 17), (18, 20)]` which means it is running 4 configs on 3 segments multiple times which does not seem efficient. I would have expected something like `[(1, 3), (4, 6), (7, 9), (10, 12), (13, 15), (16, 18),(19, 20)]` which runs 3 configs at a time on the 3 segments.
   > 
   > (8)
   > In `find_hyperopt_config()` confirm that the loss for _each_ model that passed to hyperopt after training, and not just the best one from the group.
   > 
   > (9)
   > defaults
   > Seems like hyperband defaults are being used for hyperopt in the case that use does not specify hyperband is not specified. That will probably throw an error
   
   @fmcquillan99 
   
   (7) 
   
   (a) As per my discussions with @reductionista , the current implementation seems to run more than 1 rounds when `number of models >= 2 * number of segments/workers in the cluster`. Sure, though the latter `[(1, 3), (4, 5)]` may have an idle worker, it may be a better approach for Hyperopt.
   
   (b) In reference to the 2nd example, I believe this was as per our discussions to minimize number of model training function calls (and to make the schedule look relatively more 'balanced'). Observe that the former schedule runs 4 configs on 3 workers for 2 rounds/runs and continues with the 3 configs on 3 workers for all other rounds (as 3 doesn't perfectly divide 20). The latter only runs 2 configs on 3 workers at the end which also thus has an idle worker (apart from 1 more model training function call compared to the former approach).
   
   (8) I believe all the losses are already passed on to hyperopt as part of my implementation, in the `Hyperopt TPE Update` for loop.
   
   (9) Yes I did observe that. I tried to change the global defaults in the SQL file as per chosen automl method, but ran into errors in the process. As per my current implementation, the hyperband params are defaults and the user may need to explicitly specify hyperopt params when using hyperopt.
   
   (10) The name changes sound good to me.
   
   Let me know if there're more areas I could address.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r495088887



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -835,10 +835,10 @@ class AutoMLHyperopt(KerasAutoML):
             if param_value_list[-1] == 'linear':
                 return hp.uniform(cp, param_value_list[0], param_value_list[1])
             elif param_value_list[-1] == 'log':
-                return hp.loguniform(cp, param_value_list[0], param_value_list[1])
+                return hp.loguniform(cp, np.log(param_value_list[0]), np.log(param_value_list[1]))
             else:
                 plpy.error("DL: Please choose a valid distribution type for '{0}': {1}".format(
-                    cp, ['linear', 'log']))
+                    cp[:-2], ['linear', 'log']))

Review comment:
       Good point, though a rare occurrence. I've made a general purpose function to deal with all of these cases.




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-716772313


   (1) install of Hyperopt component
   - needs to be installed on master
   - is only needed if hyperopt is called (not if only hyperband is called)
   - I added a note to user docs (next commit)
   
   (2) detailed NOTICE and CONTEXT messages can be supressed
   - OK, supressed
   
   (3) Should not report _3 or _4 or whatever in messages since user does not know what these are.
   - OK, message fixed
   
   (4) (5) hyperopt is not learning
   - OK, learning now
   
   (6) correctly set number of workers
   - OK, computed correctly now
   
   (7)
   
   (8) confirm loss values reported to hyperopt for all configs (not best from group)
   - OK, confirmed
   
   (9) setting default values
   - OK, set properly now
   
   (10) param naming suggestions
   - OK, fixed naming 
   
   (11) cumulative times
   ```
    mst_key |                                                                            metrics_elapsed_time                                                                             
   ---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
          1 | {3.44599199295044,5.5086510181427,7.59378290176392,9.76283192634583,11.7568578720093,14.0877909660339,16.2628719806671,18.3627188205719,20.6051309108734,22.6256680488586}
          2 | {3.64783596992493,5.74869298934937,7.73203301429749,9.90109395980835,11.9493429660797,14.2302348613739,16.4116108417511,18.5028810501099,20.7483429908752,22.9229199886322}
          3 | {25.3283171653748,27.2733652591705,29.2196431159973,31.2333950996399,33.013738155365,35.0193402767181,36.8298072814941,38.8312292098999,40.8666622638702,42.6906530857086}
          4 | {25.4672672748566,27.4201622009277,29.3609321117401,31.3780810832977,33.1518592834473,35.1660552024841,37.1421611309052,38.971488237381,41.0169200897217,42.8317811489105}
          5 | {45.613331079483,47.5778069496155,49.7638850212097,51.9869689941406,53.9853930473328,56.2250180244446,58.5185329914093,60.7617180347443,63.0875821113586,65.1909580230713}
          6 | {45.7591459751129,47.7180619239807,49.9061949253082,52.1345801353455,54.1592149734497,56.3740320205688,58.6804759502411,60.9120979309082,63.2361199855804,65.3321549892426}
          7 | {68.48650598526,71.0383489131927,73.7156028747559,76.0485279560089,78.6191580295563,81.2393538951874,83.7727980613708,86.2238938808441,88.8117818832397,91.40256690979}
          8 | {68.6526188850403,71.2017469406128,73.8855209350586,76.213299036026,78.8485488891602,81.4080820083618,83.9574830532074,86.3879079818726,88.9709119796753,91.6372621059418}
          9 | {94.9169039726257,97.4595720767975,100.022624015808,102.602681159973,104.947999954224,107.506361961365,110.27393913269,112.921897172928,115.296147108078,117.905650138855}
         10 | {95.0961761474609,97.620619058609,100.199231147766,102.778658151627,105.320446014404,107.670147180557,110.440493106842,113.101521015167,115.461306095123,118.067128181458}
         11 | {121.154954195023,123.238182067871,125.558053016663,127.94621014595,130.058441162109,132.456755161285,134.789571046829,136.911457061768,139.302124023438,141.447726964951}
         12 | {121.302850008011,123.383195161819,125.702442169189,128.096446990967,130.208800077438,132.607058048248,134.943905115128,137.053812026978,139.451186180115,141.589867115021}
         13 | {144.590404987335,146.865453958511,148.973741054535,151.335968017578,153.698374986649,155.985013008118,158.293015003204,160.394205093384,162.702248096466,164.992741107941}
         14 | {144.756483078003,147.041687965393,149.141814947128,151.50594997406,153.962126970291,156.153010129929,158.461601018906,160.565253019333,162.872231960297,165.163074016571}
         15 | {168.281131982803,170.96831202507,173.619775056839,176.261294126511,178.772081136703,181.430242061615,184.221279144287,186.935801029205,189.439113140106,192.158553123474}
         16 | {168.455712080002,171.14265704155,173.794762134552,176.440241098404,178.940042972565,181.715918064117,184.400903940201,187.127205133438,189.61900305748,192.334141969681}
         17 | {195.59405207634,197.74609208107,200.189806938171,202.618988990784,204.730000972748,207.099671125412,209.533874988556,211.708842992783,214.096724033356,216.496123075485}
         18 | {195.76095199585,197.90920996666,200.347979068756,202.780756950378,204.888078927994,207.249115943909,209.746890068054,211.860005140305,214.24716591835,216.653197050095}
         19 | {219.868572473526,222.539808273315,225.132962465286,227.739342451096,230.226921319962,233.084603309631,235.675887346268,238.05983042717,240.733500480652,243.349875450134}
         20 | {220.287011384964,222.718561410904,225.308660268784,227.940581321716,230.405136346817,233.260821342468,235.855934381485,238.236332416534,240.908479452133,243.594557285309}
   (20 rows)
   
   ```
   - OK
   
   (12) metrics_iters missing from info table
   ```
   \d automl_output_info
                Table "public.automl_output_info"
             Column          |        Type        | Modifiers 
   --------------------------+--------------------+-----------
    mst_key                  | integer            | not null
    model_id                 | integer            | 
    compile_params           | text               | 
    fit_params               | text               | 
    model_type               | text               | 
    model_size               | double precision   | 
    metrics_elapsed_time     | double precision[] | 
    metrics_type             | text[]             | 
    loss_type                | text               | 
    training_metrics_final   | double precision   | 
    training_loss_final      | double precision   | 
    training_metrics         | double precision[] | 
    training_loss            | double precision[] | 
    validation_metrics_final | double precision   | 
    validation_loss_final    | double precision   | 
    validation_metrics       | double precision[] | 
    validation_loss          | double precision[] | 
    metrics_iters            | integer[]          | 
   ```
   - OK, added


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r495022842



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -835,10 +835,10 @@ class AutoMLHyperopt(KerasAutoML):
             if param_value_list[-1] == 'linear':
                 return hp.uniform(cp, param_value_list[0], param_value_list[1])
             elif param_value_list[-1] == 'log':
-                return hp.loguniform(cp, param_value_list[0], param_value_list[1])
+                return hp.loguniform(cp, np.log(param_value_list[0]), np.log(param_value_list[1]))
             else:
                 plpy.error("DL: Please choose a valid distribution type for '{0}': {1}".format(
-                    cp, ['linear', 'log']))
+                    cp[:-2], ['linear', 'log']))

Review comment:
       Would this work for `momentum_15`  or `momentum_111` etc.?




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-716774952


   ![image](https://user-images.githubusercontent.com/10538173/97219402-314bb100-1787-11eb-8e6b-fbfbe5b2666b.png)
   this one a bit easier to read


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698536437


   These 2 methods seems to want `hyperopt` module installed even if I don't call it.  It should only error out if I select to use `hyperopt` as an autoML method.
   ```
   %%sql
   DROP TABLE IF EXISTS hb_schedule;
   SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);
   SELECT * FROM hb_schedule ORDER BY s DESC, i;
   ```
   produces
   ```
   InternalError: (psycopg2.errors.InternalError_) ImportError: No module named hyperopt (plpython.c:5038)
   CONTEXT:  Traceback (most recent call last):
     PL/Python function "hyperband_schedule", line 7, in <module>
       from deep_learning import madlib_keras_automl
     PL/Python function "hyperband_schedule", line 21, in <module>
   PL/Python function "hyperband_schedule"
   
   [SQL: SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);]
   ```
   
   Same happens with `madlib_keras_automl` when I select `hyperband` as the method I want


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-699189947


   I wonder if we need a `num_trials` type parameter for this method.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707396551


   (12)
   ```
   \d hopt_cifar10_output_info_c100n3tperun1
      Table "public.hopt_cifar10_output_info_c100n3tperun1"
             Column          |        Type        | Modifiers 
   --------------------------+--------------------+-----------
    mst_key                  | integer            | not null
    model_id                 | integer            | 
    compile_params           | text               | 
    fit_params               | text               | 
    model_type               | text               | 
    model_size               | double precision   | 
    metrics_elapsed_time     | double precision[] | 
    metrics_type             | text[]             | 
    loss_type                | text               | 
    training_metrics_final   | double precision   | 
    training_loss_final      | double precision   | 
    training_metrics         | double precision[] | 
    training_loss            | double precision[] | 
    validation_metrics_final | double precision   | 
    validation_loss_final    | double precision   | 
    validation_metrics       | double precision[] | 
    validation_loss          | double precision[] | 
   ```
   is missing from the bottom:
   ```
   metrics_iters            | integer[]          | 
   ```


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707397232


   > (12)
   > 
   > ```
   > \d hopt_cifar10_output_info_c100n3tperun1
   >    Table "public.hopt_cifar10_output_info_c100n3tperun1"
   >           Column          |        Type        | Modifiers 
   > --------------------------+--------------------+-----------
   >  mst_key                  | integer            | not null
   >  model_id                 | integer            | 
   >  compile_params           | text               | 
   >  fit_params               | text               | 
   >  model_type               | text               | 
   >  model_size               | double precision   | 
   >  metrics_elapsed_time     | double precision[] | 
   >  metrics_type             | text[]             | 
   >  loss_type                | text               | 
   >  training_metrics_final   | double precision   | 
   >  training_loss_final      | double precision   | 
   >  training_metrics         | double precision[] | 
   >  training_loss            | double precision[] | 
   >  validation_metrics_final | double precision   | 
   >  validation_loss_final    | double precision   | 
   >  validation_metrics       | double precision[] | 
   >  validation_loss          | double precision[] | 
   > ```
   > 
   > is missing from the bottom:
   > 
   > ```
   > metrics_iters            | integer[]          | 
   > ```
   
   `metrics_iters` is mentioned in the summary table itself, as its value is the same for all configs (if I recall correctly).


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-699189947


   (6)
   fmin definition
   https://github.com/hyperopt/hyperopt/wiki/FMin
   fmin(loss, space, algo, max_evals)
   
   (a)
   Looks like this PR is setting max_evals =  num_models/num_segments.  For one thing I'm not sure that 
   ```
   self.num_workers = get_seg_number() * get_segments_per_host()
   ```
   gives total number of workers?  On a 1 host, 2 segments-per-host database this returned 4 instead of the expected 2.
   
   (b)
   Looks like the logic is for each eval to find the losses for multiple models (= num segments) in parallel, then return the best loss value to hyperopt, then get a new set of params for multiple models from hyperopt.  Or does it pass the loss for *each* model that is trained to hyperopt?  If it is the former, then it seems like that might confuse affect hyperband in unknown ways if we are chunking/grouping like in this way.
   
   (7)
   We should re-look at the madlib hyperopt params to see if we have defined them in the right way.  Do we need an option for an explicit `max_evals` ?
   
   (8)
   defaults
   Seems like hyperband defaults are being used for hyperopt in the case that use does not specify hyperband is not specified.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-716773016


   ![image](https://user-images.githubusercontent.com/10538173/97219034-b1254b80-1786-11eb-898b-2ce559e2f71e.png)
    cumulative time looks OK


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698536437


   (1) 
   These 2 methods seems to want `hyperopt` module installed even if I don't call it.  It should only error out if I select to use `hyperopt` as an autoML method:
   
   - `madlib_keras_automl`
   - `hyperband_schedule`
   
   E.g.,
   ```
   %%sql
   DROP TABLE IF EXISTS hb_schedule;
   SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);
   SELECT * FROM hb_schedule ORDER BY s DESC, i;
   ```
   produces
   ```
   InternalError: (psycopg2.errors.InternalError_) ImportError: No module named hyperopt (plpython.c:5038)
   CONTEXT:  Traceback (most recent call last):
     PL/Python function "hyperband_schedule", line 7, in <module>
       from deep_learning import madlib_keras_automl
     PL/Python function "hyperband_schedule", line 21, in <module>
   PL/Python function "hyperband_schedule"
   
   [SQL: SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);]
   ```
   
   Same happens with `madlib_keras_automl` when I select `hyperband` as the method I want


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698586366


   (4)
   `hyperopt` is not learning in the tests I have done so far with `rand` 
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperopt', 
                                     'num_models=3, num_iters=5, algorithm=rand',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces no-learning result with labels:
   ```
   INFO:  ***Evaluating 3 newly suggested model configurations***
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 659.287541866 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0988999977708, loss=14.5240154266
   	mst_key=2: metric=0.10000000149, loss=nan
   	Validation set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 2: 663.107329845 sec
   DETAIL:  
   	Training set after iteration 2:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   	Validation set after iteration 2:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   CONTEXT:  PL/Python function "madlib_keras_automl"
   etc.
   ```
   When I run `hyperband` with same models/hyperparams, it does learn:
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperband', 
                                     'R=6, eta=3, skip_last=0',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces
   ```
   PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 655.647205114 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.34889999032, loss=1.83796536922
   	mst_key=1: metric=0.468120008707, loss=1.481554389
   	mst_key=2: metric=0.475380003452, loss=1.63904440403
   	Validation set after iteration 1:
   	mst_key=3: metric=0.355800002813, loss=1.83082151413
   	mst_key=1: metric=0.470499992371, loss=1.47972774506
   	mst_key=2: metric=0.470200002193, loss=1.66988003254
   CONTEXT:  PL/Python function "madlib_keras_automl"
   
   etc.
   ```


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707396551


   (12)
   ```
   \d hopt_cifar10_output_info_c100n3tperun1
      Table "public.hopt_cifar10_output_info_c100n3tperun1"
             Column          |        Type        | Modifiers 
   --------------------------+--------------------+-----------
    mst_key                  | integer            | not null
    model_id                 | integer            | 
    compile_params           | text               | 
    fit_params               | text               | 
    model_type               | text               | 
    model_size               | double precision   | 
    metrics_elapsed_time     | double precision[] | 
    metrics_type             | text[]             | 
    loss_type                | text               | 
    training_metrics_final   | double precision   | 
    training_loss_final      | double precision   | 
    training_metrics         | double precision[] | 
    training_loss            | double precision[] | 
    validation_metrics_final | double precision   | 
    validation_loss_final    | double precision   | 
    validation_metrics       | double precision[] | 
    validation_loss          | double precision[] | 
   ```
   is missing from the bottom:
   ```
   metrics_iters            | integer[]          | 
   ```
   I think that metrics_iters is *not* cumulative because that concept does not seem to make sense for hyperopt.  The output table would look like:
   ```
    mst_key |     metrics_iters.   |            metrics_elapsed_time                 
   ---------+------------------------------------------------------
          1 | {1,4,7} | {627.882262945175,1264.80915999413,1896.74943590164}
          2 | {1,4,7} | {614.573877811432,1251.1022670269,1883.14707994461}
          3 | {1,4,7} | {638.407788038254,1286.73397421837,1939.58357810974}


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] orhankislal commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
orhankislal commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r493746682



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works
+                else:
+                    plpy.error("DL: algorithm in 'automl_params' must be 'rand', 'tpe'") # , or 'atpe'
+            else:
+                plpy.error("DL: {0} is an invalid automl param".format(i))
+        _assert(self.num_models > 0 and self.num_iters > 0, "DL: num_models and num_iters in 'automl_params' "
+                                                            "must be positive")
+        _assert(self._is_valid_metrics_compute_frequency(self.num_iters), "DL: 'metrics_compute_frequency' "
+                                                                          "out of iteration range")
+
+    def find_hyperopt_config(self):
         """
-        Drops and re-create the mst table to only include the best performing model configuration.
+        Executes hyperopt on top of MOP.
         """
-        drop_tables([self.model_selection_table])
 
-        # only retaining best performing config
-        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT mst_key, model_id, compile_params, " \
-                     "fit_params FROM {self.model_info_table} " \
-                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self, AutoMLSchema=AutoMLSchema))
+        make_mst_summary = True
+        trials = Trials()
+        domain = Domain(None, self.get_search_space())
+        rand_state = np.random.RandomState(self.random_state)
+        configs_lst = self.get_configs_list()
 
-    def generate_model_output_summary_table(self, model_training):
+        self.start_training_time = self.get_current_timestamp()
+        for low, high in configs_lst:
+            i, n = low, high - low + 1
+
+            # Using HyperOpt TPE/ATPE to generate parameters
+            hyperopt_params = []
+            sampled_params = []
+            for j in range(i, i + n):
+                new_param = self.algorithm.suggest([j], domain, trials, rand_state.randint(0, 2 ** 31 - 1))
+                new_param[0]['status'] = STATUS_RUNNING
+
+                trials.insert_trial_docs(new_param)
+                trials.refresh()
+                hyperopt_params.append(new_param[0])
+                sampled_params.append(new_param[0]['misc']['vals'])
+
+            model_id_list, compile_params, fit_params = self.extract_param_vals(sampled_params)
+            msts_list = self.generate_msts(model_id_list, compile_params, fit_params)
+            try:
+                self.remove_temp_tables(model_training)
+            except:
+                pass
+            self.populate_temp_mst_table(i, msts_list)
+
+            plpy.info("***Evaluating {n} newly suggested model configurations***".format(n=n))
+            model_training = FitMultipleModel(self.schema_madlib, self.source_table, AutoMLSchema.TEMP_OUTPUT_TABLE,
+                             AutoMLSchema.TEMP_MST_TABLE, self.num_iters, self.use_gpus, self.validation_table,
+                             self.metrics_compute_frequency, False, self.name, self.description)
+            if make_mst_summary:
+                self.generate_mst_summary_table(self.model_selection_summary_table)
+                make_mst_summary = False
+
+            # HyperOpt TPE update
+            for k, hyperopt_param in enumerate(hyperopt_params, i):
+                loss_val = plpy.execute("SELECT {AutoMLSchema.LOSS_METRIC} FROM {model_training.model_info_table} " \
+                             "WHERE {ModelSelectionSchema.MST_KEY}={k}".format(AutoMLSchema=AutoMLSchema,
+                                                                               ModelSelectionSchema=ModelSelectionSchema,
+                                                                               **locals()))[0][AutoMLSchema.LOSS_METRIC]
+
+                hyperopt_param['status'] = STATUS_OK

Review comment:
       Do we use this `status`? I don't see it getting referenced and the dictionary already has it.




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] orhankislal commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
orhankislal commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r493674295



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -17,27 +17,41 @@
 # specific language governing permissions and limitations
 # under the License.
 
+from ast import literal_eval
 from datetime import datetime
-import plpy
+from hyperopt import hp, rand, tpe, atpe, Trials, STATUS_OK, STATUS_RUNNING
+from hyperopt.base import Domain
 import math
+import numpy as np
+import plpy
 from time import time
 
 from madlib_keras_validator import MstLoaderInputValidator
-from utilities.utilities import unique_string, add_postfix, extract_keyvalue_params, \
-    _assert, _assert_equal, rename_table
+from utilities.utilities import get_seg_number, get_segments_per_host, unique_string, add_postfix, \
+    extract_keyvalue_params, _assert, _assert_equal, rename_table
 from utilities.control import MinWarning, SetGUC
 from madlib_keras_fit_multiple_model import FitMultipleModel
 from madlib_keras_model_selection import MstSearch, ModelSelectionSchema
 from keras_model_arch_table import ModelArchSchema
 from utilities.validate_args import table_exists, drop_tables
 
+import inspect
+
+def decallmethods(decorator, prefix='test_'):

Review comment:
       We should use `_` in the function name. I wasn't sure if this was meant to be `de-call methods` or `dec all methods`. Also a short explanation on what this function and the inner class doing would be great.

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -158,11 +174,10 @@ class HyperbandSchedule():
                                       **locals())
             plpy.execute(insert_query)
 
-@MinWarning("warning")
-class KerasAutoML():
-    """The core AutoML function for running AutoML algorithms such as Hyperband.
-    This function executes the hyperband rounds 'diagonally' to evaluate multiple configurations together
-    and leverage the compute power of MPP databases such as Greenplum.
+# @MinWarning("warning")

Review comment:
       Should we revert these commented lines back? 

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -291,9 +338,100 @@ class KerasAutoML():
                (self.metrics_compute_frequency >= 1 and \
                 self.metrics_compute_frequency <= num_iterations)
 
+    def print_best_so_far(self):
+        """
+        Prints mst keys with best train/val losses at a given point.
+        """
+        best_so_far = '\n'
+        best_so_far += self.print_best_helper('training')
+        if self.validation_table:
+            best_so_far += self.print_best_helper('validation')
+        plpy.info(best_so_far)
+
+    def print_best_helper(self, keyword):

Review comment:
       Same as before.

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -291,9 +338,100 @@ class KerasAutoML():
                (self.metrics_compute_frequency >= 1 and \
                 self.metrics_compute_frequency <= num_iterations)
 
+    def print_best_so_far(self):
+        """
+        Prints mst keys with best train/val losses at a given point.
+        """
+        best_so_far = '\n'
+        best_so_far += self.print_best_helper('training')
+        if self.validation_table:
+            best_so_far += self.print_best_helper('validation')
+        plpy.info(best_so_far)
+
+    def print_best_helper(self, keyword):
+        """
+        Helper function to Prints mst keys with best train/val losses at a given point.
+        :param keyword: column prefix ('training' or 'validation')
+        :return:
+        """
+        metrics_word, loss_word = keyword + '_metrics_final', keyword + '_loss_final'
+
+        res_str = 'Best {keyword} loss so far:\n'.format(keyword=keyword)
+        best_value = plpy.execute("SELECT {ModelSelectionSchema.MST_KEY}, {metrics_word}, " \
+                                  "{loss_word} FROM {self.model_info_table} ORDER BY " \
+                                  "{loss_word} LIMIT 1".format(self=self, ModelSelectionSchema=ModelSelectionSchema,
+                                                               metrics_word=metrics_word, loss_word=loss_word))[0]
+        mst_key_value, metric_value, loss_value = best_value[ModelSelectionSchema.MST_KEY], \
+                                                  best_value[metrics_word], best_value[loss_word]
+        res_str += ModelSelectionSchema.MST_KEY + '=' + str(mst_key_value) + ': metric=' + str(metric_value) + \
+                   ', loss=' + str(loss_value) + '\n'
+        return res_str
+
+    def get_current_timestamp(self):

Review comment:
       Should be in utilities

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -291,9 +338,100 @@ class KerasAutoML():
                (self.metrics_compute_frequency >= 1 and \
                 self.metrics_compute_frequency <= num_iterations)
 
+    def print_best_so_far(self):

Review comment:
       Generic name, print_best_mst_so_far would be better.

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works

Review comment:
       Add TODO to draw attention.

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -223,10 +231,13 @@ class KerasAutoML():
                                      {ModelArchSchema.MODEL_ARCH} JSON)
                                     """.format(self=self, ModelSelectionSchema=ModelSelectionSchema,
                                                ModelArchSchema=ModelArchSchema)
-        with MinWarning('warning'):
-            plpy.execute(output_table_create_query)
+        # with MinWarning('warning'):

Review comment:
       Same as before.

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -245,40 +256,76 @@ class KerasAutoML():
                                    validation_metrics_final DOUBLE PRECISION,
                                    validation_loss_final DOUBLE PRECISION,
                                    validation_metrics DOUBLE PRECISION[],
-                                   validation_loss DOUBLE PRECISION[],
-                                   {AutoMLSchema.METRICS_ITERS} INTEGER[])
-                                       """.format(self=self, ModelSelectionSchema=ModelSelectionSchema,
-                                                  ModelArchSchema=ModelArchSchema, AutoMLSchema=AutoMLSchema)
-        with MinWarning('warning'):
-            plpy.execute(info_table_create_query)
+                                   validation_loss DOUBLE PRECISION[]
+                                   """.format(self=self,
+                                              ModelSelectionSchema=ModelSelectionSchema,
+                                              ModelArchSchema=ModelArchSchema,
+                                              AutoMLSchema=AutoMLSchema) + additional_cols + ")"
+        # with MinWarning('warning'):
+        plpy.execute(info_table_create_query)
 
-    def validate_and_define_inputs(self):
+    def update_model_selection_table(self):
+        """
+        Drops and re-create the mst table to only include the best performing model configuration.
+        """
+        drop_tables([self.model_selection_table])
 
-        if AutoMLSchema.HYPERBAND.startswith(self.automl_method.lower()):
-            automl_params_dict = extract_keyvalue_params(self.automl_params,
-                                                         default_values={'R': 6, 'eta': 3, 'skip_last': 0},
-                                                         lower_case_names=False)
-            # casting dict values to int
-            for i in automl_params_dict:
-                automl_params_dict[i] = int(automl_params_dict[i])
-            _assert(len(automl_params_dict) >= 1 or len(automl_params_dict) <= 3,
-                    "DL: Only R, eta, and skip_last may be specified")
-            for i in automl_params_dict:
-                if i == AutoMLSchema.R:
-                    self.R = automl_params_dict[AutoMLSchema.R]
-                elif i == AutoMLSchema.ETA:
-                    self.eta = automl_params_dict[AutoMLSchema.ETA]
-                elif i == AutoMLSchema.SKIP_LAST:
-                    self.skip_last = automl_params_dict[AutoMLSchema.SKIP_LAST]
-                else:
-                    plpy.error("DL: {0} is an invalid param".format(i))
-            _assert(self.eta > 1, "DL: eta must be greater than 1")
-            _assert(self.R >= self.eta, "DL: R should not be less than eta")
-            self.s_max = int(math.floor(math.log(self.R, self.eta)))
-            _assert(self.skip_last >= 0 and self.skip_last < self.s_max+1, "DL: skip_last must be " +
-                    "non-negative and less than {0}".format(self.s_max))
-        else:
-            plpy.error("DL: Only hyperband is currently supported as the automl method")
+        # only retaining best performing config
+        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT {ModelSelectionSchema.MST_KEY}, " \
+                     "{ModelSelectionSchema.MODEL_ID}, {ModelSelectionSchema.COMPILE_PARAMS}, " \
+                     "{ModelSelectionSchema.FIT_PARAMS} FROM {self.model_info_table} " \
+                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self,
+                                                                          AutoMLSchema=AutoMLSchema,
+                                                                          ModelSelectionSchema=ModelSelectionSchema))
+
+    def generate_model_output_summary_table(self, model_training):
+        """
+        Creates and populates static values related to the AutoML workload.
+        :param model_training: Fit Multiple function call object.
+        """
+        create_query = plpy.prepare("""
+                CREATE TABLE {self.model_summary_table} AS
+                SELECT
+                    $MAD${self.source_table}$MAD$::TEXT AS source_table,
+                    $MAD${self.validation_table}$MAD$::TEXT AS validation_table,
+                    $MAD${self.model_output_table}$MAD$::TEXT AS model,
+                    $MAD${self.model_info_table}$MAD$::TEXT AS model_info,
+                    (SELECT dependent_varname FROM {model_training.model_summary_table})
+                    AS dependent_varname,
+                    (SELECT independent_varname FROM {model_training.model_summary_table})
+                    AS independent_varname,
+                    $MAD${self.model_arch_table}$MAD$::TEXT AS model_arch_table,
+                    $MAD${self.model_selection_table}$MAD$::TEXT AS model_selection_table,
+                    $MAD${self.automl_method}$MAD$::TEXT AS automl_method,
+                    $MAD${self.automl_params}$MAD$::TEXT AS automl_params,
+                    $MAD${self.random_state}$MAD$::TEXT AS random_state,
+                    $MAD${self.object_table}$MAD$::TEXT AS object_table,
+                    {self.use_gpus} AS use_gpus,
+                    (SELECT metrics_compute_frequency FROM {model_training.model_summary_table})::INTEGER 
+                    AS metrics_compute_frequency,
+                    $MAD${self.name}$MAD$::TEXT AS name,
+                    $MAD${self.description}$MAD$::TEXT AS description,
+                    '{self.start_training_time}'::TIMESTAMP AS start_training_time,
+                    '{self.end_training_time}'::TIMESTAMP AS end_training_time,
+                    (SELECT madlib_version FROM {model_training.model_summary_table}) AS madlib_version,
+                    (SELECT num_classes FROM {model_training.model_summary_table})::INTEGER AS num_classes,
+                    (SELECT class_values FROM {model_training.model_summary_table}) AS class_values,
+                    (SELECT dependent_vartype FROM {model_training.model_summary_table}) 
+                    AS dependent_vartype,
+                    (SELECT normalizing_const FROM {model_training.model_summary_table}) 
+                    AS normalizing_const
+            """.format(self=self, model_training=model_training))
+
+        # with MinWarning('warning'):
+        plpy.execute(create_query)
+
+    def is_method(self, method_name):

Review comment:
       `is_method` is a very generic function name, `is_automl_method` would be better.

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -291,9 +338,100 @@ class KerasAutoML():
                (self.metrics_compute_frequency >= 1 and \
                 self.metrics_compute_frequency <= num_iterations)
 
+    def print_best_so_far(self):
+        """
+        Prints mst keys with best train/val losses at a given point.
+        """
+        best_so_far = '\n'
+        best_so_far += self.print_best_helper('training')
+        if self.validation_table:
+            best_so_far += self.print_best_helper('validation')
+        plpy.info(best_so_far)
+
+    def print_best_helper(self, keyword):
+        """
+        Helper function to Prints mst keys with best train/val losses at a given point.
+        :param keyword: column prefix ('training' or 'validation')
+        :return:
+        """
+        metrics_word, loss_word = keyword + '_metrics_final', keyword + '_loss_final'
+
+        res_str = 'Best {keyword} loss so far:\n'.format(keyword=keyword)
+        best_value = plpy.execute("SELECT {ModelSelectionSchema.MST_KEY}, {metrics_word}, " \
+                                  "{loss_word} FROM {self.model_info_table} ORDER BY " \
+                                  "{loss_word} LIMIT 1".format(self=self, ModelSelectionSchema=ModelSelectionSchema,
+                                                               metrics_word=metrics_word, loss_word=loss_word))[0]
+        mst_key_value, metric_value, loss_value = best_value[ModelSelectionSchema.MST_KEY], \
+                                                  best_value[metrics_word], best_value[loss_word]
+        res_str += ModelSelectionSchema.MST_KEY + '=' + str(mst_key_value) + ': metric=' + str(metric_value) + \
+                   ', loss=' + str(loss_value) + '\n'
+        return res_str
+
+    def get_current_timestamp(self):
+        """for start and end times for the chosen AutoML algorithm. Showcased in the output summary table"""
+        return datetime.fromtimestamp(time()).strftime('%Y-%m-%d %H:%M:%S')
+
+    def remove_temp_tables(self, model_training):

Review comment:
       Generic name, a similar function already exists in utilities (cleanup_madlib_temp_tables, utilities.sql_in line 101).

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -404,24 +544,30 @@ class KerasAutoML():
                                   model_id=ModelSelectionSchema.MODEL_ID,
                                   compile_params=ModelSelectionSchema.COMPILE_PARAMS,
                                   fit_params=ModelSelectionSchema.FIT_PARAMS)
-        with MinWarning('warning'):
-            plpy.execute(create_query)
+        # with MinWarning('warning'):

Review comment:
       Same as before

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -291,9 +338,100 @@ class KerasAutoML():
                (self.metrics_compute_frequency >= 1 and \
                 self.metrics_compute_frequency <= num_iterations)
 
+    def print_best_so_far(self):
+        """
+        Prints mst keys with best train/val losses at a given point.
+        """
+        best_so_far = '\n'
+        best_so_far += self.print_best_helper('training')
+        if self.validation_table:
+            best_so_far += self.print_best_helper('validation')
+        plpy.info(best_so_far)
+
+    def print_best_helper(self, keyword):
+        """
+        Helper function to Prints mst keys with best train/val losses at a given point.
+        :param keyword: column prefix ('training' or 'validation')
+        :return:
+        """
+        metrics_word, loss_word = keyword + '_metrics_final', keyword + '_loss_final'
+
+        res_str = 'Best {keyword} loss so far:\n'.format(keyword=keyword)
+        best_value = plpy.execute("SELECT {ModelSelectionSchema.MST_KEY}, {metrics_word}, " \
+                                  "{loss_word} FROM {self.model_info_table} ORDER BY " \
+                                  "{loss_word} LIMIT 1".format(self=self, ModelSelectionSchema=ModelSelectionSchema,
+                                                               metrics_word=metrics_word, loss_word=loss_word))[0]
+        mst_key_value, metric_value, loss_value = best_value[ModelSelectionSchema.MST_KEY], \
+                                                  best_value[metrics_word], best_value[loss_word]
+        res_str += ModelSelectionSchema.MST_KEY + '=' + str(mst_key_value) + ': metric=' + str(metric_value) + \
+                   ', loss=' + str(loss_value) + '\n'
+        return res_str
+
+    def get_current_timestamp(self):
+        """for start and end times for the chosen AutoML algorithm. Showcased in the output summary table"""
+        return datetime.fromtimestamp(time()).strftime('%Y-%m-%d %H:%M:%S')
+
+    def remove_temp_tables(self, model_training):
+        """
+        Remove all intermediate tables created for AutoML runs/updates.
+        :param model_training: Fit Multiple function call object.
+        """
+        drop_tables([model_training.original_model_output_table, model_training.model_info_table,
+                     model_training.model_summary_table, AutoMLSchema.TEMP_MST_TABLE,
+                     AutoMLSchema.TEMP_MST_SUMMARY_TABLE])
+
+# @MinWarning("warning")
+class AutoMLHyperband(KerasAutoML):
+    """
+    This class implements Hyperband, an infinite-arm bandit based algorithm that speeds up random search
+    through adaptive resource allocation, successive halving (SHA) and early stopping.
+
+    This class showcases and novel hyperband implementation by executing the hyperband rounds 'diagonally'

Review comment:
       Possible typo, and -> a ?




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r493920534



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works
+                else:
+                    plpy.error("DL: algorithm in 'automl_params' must be 'rand', 'tpe'") # , or 'atpe'
+            else:
+                plpy.error("DL: {0} is an invalid automl param".format(i))
+        _assert(self.num_models > 0 and self.num_iters > 0, "DL: num_models and num_iters in 'automl_params' "
+                                                            "must be positive")
+        _assert(self._is_valid_metrics_compute_frequency(self.num_iters), "DL: 'metrics_compute_frequency' "
+                                                                          "out of iteration range")
+
+    def find_hyperopt_config(self):
         """
-        Drops and re-create the mst table to only include the best performing model configuration.
+        Executes hyperopt on top of MOP.
         """
-        drop_tables([self.model_selection_table])
 
-        # only retaining best performing config
-        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT mst_key, model_id, compile_params, " \
-                     "fit_params FROM {self.model_info_table} " \
-                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self, AutoMLSchema=AutoMLSchema))
+        make_mst_summary = True
+        trials = Trials()
+        domain = Domain(None, self.get_search_space())
+        rand_state = np.random.RandomState(self.random_state)
+        configs_lst = self.get_configs_list()
 
-    def generate_model_output_summary_table(self, model_training):
+        self.start_training_time = self.get_current_timestamp()
+        for low, high in configs_lst:
+            i, n = low, high - low + 1
+
+            # Using HyperOpt TPE/ATPE to generate parameters
+            hyperopt_params = []
+            sampled_params = []
+            for j in range(i, i + n):
+                new_param = self.algorithm.suggest([j], domain, trials, rand_state.randint(0, 2 ** 31 - 1))
+                new_param[0]['status'] = STATUS_RUNNING
+
+                trials.insert_trial_docs(new_param)
+                trials.refresh()
+                hyperopt_params.append(new_param[0])
+                sampled_params.append(new_param[0]['misc']['vals'])
+
+            model_id_list, compile_params, fit_params = self.extract_param_vals(sampled_params)
+            msts_list = self.generate_msts(model_id_list, compile_params, fit_params)
+            try:
+                self.remove_temp_tables(model_training)
+            except:
+                pass
+            self.populate_temp_mst_table(i, msts_list)
+
+            plpy.info("***Evaluating {n} newly suggested model configurations***".format(n=n))
+            model_training = FitMultipleModel(self.schema_madlib, self.source_table, AutoMLSchema.TEMP_OUTPUT_TABLE,
+                             AutoMLSchema.TEMP_MST_TABLE, self.num_iters, self.use_gpus, self.validation_table,
+                             self.metrics_compute_frequency, False, self.name, self.description)
+            if make_mst_summary:
+                self.generate_mst_summary_table(self.model_selection_summary_table)
+                make_mst_summary = False
+
+            # HyperOpt TPE update
+            for k, hyperopt_param in enumerate(hyperopt_params, i):
+                loss_val = plpy.execute("SELECT {AutoMLSchema.LOSS_METRIC} FROM {model_training.model_info_table} " \
+                             "WHERE {ModelSelectionSchema.MST_KEY}={k}".format(AutoMLSchema=AutoMLSchema,
+                                                                               ModelSelectionSchema=ModelSelectionSchema,
+                                                                               **locals()))[0][AutoMLSchema.LOSS_METRIC]
+
+                hyperopt_param['status'] = STATUS_OK

Review comment:
       Also there's `hyperopt_param['status']` and `hyperopt_param['result']['status']` in the API to be updated it seems.

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works
+                else:
+                    plpy.error("DL: algorithm in 'automl_params' must be 'rand', 'tpe'") # , or 'atpe'
+            else:
+                plpy.error("DL: {0} is an invalid automl param".format(i))
+        _assert(self.num_models > 0 and self.num_iters > 0, "DL: num_models and num_iters in 'automl_params' "
+                                                            "must be positive")
+        _assert(self._is_valid_metrics_compute_frequency(self.num_iters), "DL: 'metrics_compute_frequency' "
+                                                                          "out of iteration range")
+
+    def find_hyperopt_config(self):
         """
-        Drops and re-create the mst table to only include the best performing model configuration.
+        Executes hyperopt on top of MOP.
         """
-        drop_tables([self.model_selection_table])
 
-        # only retaining best performing config
-        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT mst_key, model_id, compile_params, " \
-                     "fit_params FROM {self.model_info_table} " \
-                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self, AutoMLSchema=AutoMLSchema))
+        make_mst_summary = True
+        trials = Trials()
+        domain = Domain(None, self.get_search_space())
+        rand_state = np.random.RandomState(self.random_state)
+        configs_lst = self.get_configs_list()
 
-    def generate_model_output_summary_table(self, model_training):
+        self.start_training_time = self.get_current_timestamp()
+        for low, high in configs_lst:
+            i, n = low, high - low + 1
+
+            # Using HyperOpt TPE/ATPE to generate parameters
+            hyperopt_params = []
+            sampled_params = []
+            for j in range(i, i + n):
+                new_param = self.algorithm.suggest([j], domain, trials, rand_state.randint(0, 2 ** 31 - 1))
+                new_param[0]['status'] = STATUS_RUNNING
+
+                trials.insert_trial_docs(new_param)
+                trials.refresh()
+                hyperopt_params.append(new_param[0])
+                sampled_params.append(new_param[0]['misc']['vals'])
+
+            model_id_list, compile_params, fit_params = self.extract_param_vals(sampled_params)
+            msts_list = self.generate_msts(model_id_list, compile_params, fit_params)
+            try:
+                self.remove_temp_tables(model_training)
+            except:
+                pass
+            self.populate_temp_mst_table(i, msts_list)
+
+            plpy.info("***Evaluating {n} newly suggested model configurations***".format(n=n))
+            model_training = FitMultipleModel(self.schema_madlib, self.source_table, AutoMLSchema.TEMP_OUTPUT_TABLE,
+                             AutoMLSchema.TEMP_MST_TABLE, self.num_iters, self.use_gpus, self.validation_table,
+                             self.metrics_compute_frequency, False, self.name, self.description)
+            if make_mst_summary:
+                self.generate_mst_summary_table(self.model_selection_summary_table)
+                make_mst_summary = False
+
+            # HyperOpt TPE update
+            for k, hyperopt_param in enumerate(hyperopt_params, i):
+                loss_val = plpy.execute("SELECT {AutoMLSchema.LOSS_METRIC} FROM {model_training.model_info_table} " \
+                             "WHERE {ModelSelectionSchema.MST_KEY}={k}".format(AutoMLSchema=AutoMLSchema,
+                                                                               ModelSelectionSchema=ModelSelectionSchema,
+                                                                               **locals()))[0][AutoMLSchema.LOSS_METRIC]
+
+                hyperopt_param['status'] = STATUS_OK

Review comment:
       Also there's both `hyperopt_param['status']` and `hyperopt_param['result']['status']` in the API to be updated it seems.




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698539283


   (2) 
   please turn off the detailed `NOTICE` and `CONTEXT` messages as they are showing on the console by default.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707400603


   > I don't see it in there
   > 
   > ```
   > \d hopt_cifar10_output_summary_c100n3tperun1;
   >       Table "public.hopt_cifar10_output_summary_c100n3tperun1"
   >           Column           |            Type             | Modifiers 
   > ---------------------------+-----------------------------+-----------
   >  source_table              | text                        | 
   >  validation_table          | text                        | 
   >  model                     | text                        | 
   >  model_info                | text                        | 
   >  dependent_varname         | text                        | 
   >  independent_varname       | text                        | 
   >  model_arch_table          | text                        | 
   >  model_selection_table     | text                        | 
   >  automl_method             | text                        | 
   >  automl_params             | text                        | 
   >  random_state              | text                        | 
   >  object_table              | text                        | 
   >  use_gpus                  | boolean                     | 
   >  metrics_compute_frequency | integer                     | 
   >  name                      | text                        | 
   >  description               | text                        | 
   >  start_training_time       | timestamp without time zone | 
   >  end_training_time         | timestamp without time zone | 
   >  madlib_version            | text                        | 
   >  num_classes               | integer                     | 
   >  class_values              | text[]                      | 
   >  dependent_vartype         | text                        | 
   >  normalizing_const         | real                        | 
   > ```
   
   Okay, then I believe I used the summary table format used earlier in Hyperband (instead of the fit multiple one, which includes the metrics iters). 
   I suppose the column can be added in the summer table generation function where its value is populated by the temp summary table from the fit multiple call. 


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698586366


   (4)
   `hyperopt` is not learning in the tests I have done so far with `rand` 
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperopt', 
                                     'num_models=3, num_iters=5, algorithm=rand',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces 
   ```
   INFO:  ***Evaluating 3 newly suggested model configurations***
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 659.287541866 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0988999977708, loss=14.5240154266
   	mst_key=2: metric=0.10000000149, loss=nan
   	Validation set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 2: 663.107329845 sec
   DETAIL:  
   	Training set after iteration 2:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   	Validation set after iteration 2:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   CONTEXT:  PL/Python function "madlib_keras_automl"
   etc.
   ```
   When I run `hyperband` with same models/hyperparams, it does learn:
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperband', 
                                     'R=6, eta=3, skip_last=0',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces
   ```
   PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 655.647205114 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.34889999032, loss=1.83796536922
   	mst_key=1: metric=0.468120008707, loss=1.481554389
   	mst_key=2: metric=0.475380003452, loss=1.63904440403
   	Validation set after iteration 1:
   	mst_key=3: metric=0.355800002813, loss=1.83082151413
   	mst_key=1: metric=0.470499992371, loss=1.47972774506
   	mst_key=2: metric=0.470200002193, loss=1.66988003254
   CONTEXT:  PL/Python function "madlib_keras_automl"
   
   etc.
   ```


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707396551


   (12)
   ```
   \d hopt_cifar10_output_info_c100n3tperun1
      Table "public.hopt_cifar10_output_info_c100n3tperun1"
             Column          |        Type        | Modifiers 
   --------------------------+--------------------+-----------
    mst_key                  | integer            | not null
    model_id                 | integer            | 
    compile_params           | text               | 
    fit_params               | text               | 
    model_type               | text               | 
    model_size               | double precision   | 
    metrics_elapsed_time     | double precision[] | 
    metrics_type             | text[]             | 
    loss_type                | text               | 
    training_metrics_final   | double precision   | 
    training_loss_final      | double precision   | 
    training_metrics         | double precision[] | 
    training_loss            | double precision[] | 
    validation_metrics_final | double precision   | 
    validation_loss_final    | double precision   | 
    validation_metrics       | double precision[] | 
    validation_loss          | double precision[] | 
   ```
   is missing from the bottom:
   ```
   metrics_iters            | integer[]          | 
   ```
   I think that metrics_iters is *not* cumulative because that concept does not seem to make sense for hyperopt.  The output table would look like:
   ```
    mst_key |     metrics_iters.   |            metrics_elapsed_time                 
   ---------+------------------------------------------------------
          1 | {1,4,7} | {627.882262945175,1264.80915999413,1896.74943590164}
          2 | {1,4,7} | {614.573877811432,1251.1022670269,1883.14707994461}
          3 | {1,4,7} | {638.407788038254,1286.73397421837,1939.58357810974}
   ```
   or `{1,2,3}` or  `{5,10,12}` etc. depending on metrics compute freq and number of itns.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-700935101


   (10) param naming suggestions
   
   change `num_models` to `num_configs` since this is what we use in `generate_model_configs()`  - this is effectively the number of trials.  Hyperopt calls this `max_evals`
   
   change `num_iters` to `num_iterations` which is what we use elsewhere


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707398631


   I don't see it in there
   ```
   \d hopt_cifar10_output_summary_c100n3tperun1;
         Table "public.hopt_cifar10_output_summary_c100n3tperun1"
             Column           |            Type             | Modifiers 
   ---------------------------+-----------------------------+-----------
    source_table              | text                        | 
    validation_table          | text                        | 
    model                     | text                        | 
    model_info                | text                        | 
    dependent_varname         | text                        | 
    independent_varname       | text                        | 
    model_arch_table          | text                        | 
    model_selection_table     | text                        | 
    automl_method             | text                        | 
    automl_params             | text                        | 
    random_state              | text                        | 
    object_table              | text                        | 
    use_gpus                  | boolean                     | 
    metrics_compute_frequency | integer                     | 
    name                      | text                        | 
    description               | text                        | 
    start_training_time       | timestamp without time zone | 
    end_training_time         | timestamp without time zone | 
    madlib_version            | text                        | 
    num_classes               | integer                     | 
    class_values              | text[]                      | 
    dependent_vartype         | text                        | 
    normalizing_const         | real                        | 
   ```
   


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] khannaekta commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
khannaekta commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707411308


   In the current implementation `metrics_iters` is not being populated for hyperopt. 
   @fmcquillan99 I can make the change to add it to the summary table as it is same for all the models or if we want to be consistent with the output for hyperband we can add it to the info table (it will be the same value for all the models though).


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707399640


   >  mst_key |                 metrics_elapsed_time                 
   > ---------+------------------------------------------------------
   >        1 | {627.882262945175,1264.80915999413,1896.74943590164}
   >        2 | {614.573877811432,1251.1022670269,1883.14707994461}
   >        3 | {638.407788038254,1286.73397421837,1939.58357810974}
   >        4 | {624.925609111786,1273.55782914162,1925.82674407959}
   >        5 | {650.984225034714,1307.78145503998,1962.8148560524}
   >        6 | {637.914520978928,1294.23532605171,1949.12843108177}
   >        7 | {651.188719987869,1301.32990193367,1948.88206887245}
   >        8 | {637.525157928467,1288.19901585579,1935.65923500061}
   >        9 | {651.277820110321,1301.09531402588,1947.13559818268}
   >       10 | {637.898158073425,1287.54387116432,1933.5972070694}
   >       11 | {650.482151985168,1309.5760037899,1961.18471598625}
   >       12 | {637.149097919464,1295.67461585999,1947.66235399246}
   >       13 | {651.543440818787,1299.3868060112,1948.78301692009}
   >       14 | {638.292811870575,1285.66767001152,1935.02927088737}
   >       15 | {650.077238082886,1305.37611913681,1962.8950419426}
   >       16 | {636.498329162598,1291.3173930645,1948.41972708702}
   >       17 | {649.946799993515,1303.33863401413,1949.58992981911}
   >       18 | {636.373380899429,1289.27607584,1936.36742186546}
   >       19 | {647.414880990982,1297.31931090355,1945.65248298645}
   >       20 | {634.09289598465,1284.170140028,1932.07456684113}
   
   It may be possible to do the following to get the graph:
   
   1. Have a 'time offset' like variable (initially set to zero)
   2. Time the individual fit multiple function calls (in seconds I presume) (for adding the recorded times to the offset variable each time). 
   3. After a run of fit multiple, write an update like query to update `metrics_elapsed_time` by adding the total offset to every element of the array value (for the first run, an offset of 0 would be added, i.e. no offset) for the model configs trained in that round (this may be determined by the `mst_key` ranges).
   4. Update the offset variable by incrementing it by the recorded time for the most recent loop run (i.e. fit multiple function call).
   
   Let me know if anything doesn't seem clear.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707400603


   > I don't see it in there
   > 
   > ```
   > \d hopt_cifar10_output_summary_c100n3tperun1;
   >       Table "public.hopt_cifar10_output_summary_c100n3tperun1"
   >           Column           |            Type             | Modifiers 
   > ---------------------------+-----------------------------+-----------
   >  source_table              | text                        | 
   >  validation_table          | text                        | 
   >  model                     | text                        | 
   >  model_info                | text                        | 
   >  dependent_varname         | text                        | 
   >  independent_varname       | text                        | 
   >  model_arch_table          | text                        | 
   >  model_selection_table     | text                        | 
   >  automl_method             | text                        | 
   >  automl_params             | text                        | 
   >  random_state              | text                        | 
   >  object_table              | text                        | 
   >  use_gpus                  | boolean                     | 
   >  metrics_compute_frequency | integer                     | 
   >  name                      | text                        | 
   >  description               | text                        | 
   >  start_training_time       | timestamp without time zone | 
   >  end_training_time         | timestamp without time zone | 
   >  madlib_version            | text                        | 
   >  num_classes               | integer                     | 
   >  class_values              | text[]                      | 
   >  dependent_vartype         | text                        | 
   >  normalizing_const         | real                        | 
   > ```
   
   Okay, in that case I suppose I used the summary table format used earlier in Hyperband (instead of the fit multiple one, which includes the metrics iters). 
   I suppose the column can be added in the summer table generation function where its value is populated by the temp summary table from the fit multiple call. 


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698536437






----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698536437


   These 2 methods seems to want `hyperopt` module installed even if I don't call it.  It should only error out if I select to use `hyperopt` as an autoML method:
   
   - `madlib_keras_automl`
   - `hyperband_schedule`
   
   ```
   %%sql
   DROP TABLE IF EXISTS hb_schedule;
   SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);
   SELECT * FROM hb_schedule ORDER BY s DESC, i;
   ```
   produces
   ```
   InternalError: (psycopg2.errors.InternalError_) ImportError: No module named hyperopt (plpython.c:5038)
   CONTEXT:  Traceback (most recent call last):
     PL/Python function "hyperband_schedule", line 7, in <module>
       from deep_learning import madlib_keras_automl
     PL/Python function "hyperband_schedule", line 21, in <module>
   PL/Python function "hyperband_schedule"
   
   [SQL: SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);]
   ```
   
   Same happens with `madlib_keras_automl` when I select `hyperband` as the method I want


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698536437


   (1) 
   These 2 methods seems to want `hyperopt` module installed even if I don't call it.  It should only error out if I select to use `hyperopt` as an autoML method:
   
   - `madlib_keras_automl`
   - `hyperband_schedule`
   
   E.g.,
   ```
   %%sql
   DROP TABLE IF EXISTS hb_schedule;
   SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);
   SELECT * FROM hb_schedule ORDER BY s DESC, i;
   ```
   produces
   ```
   InternalError: (psycopg2.errors.InternalError_) ImportError: No module named hyperopt (plpython.c:5038)
   CONTEXT:  Traceback (most recent call last):
     PL/Python function "hyperband_schedule", line 7, in <module>
       from deep_learning import madlib_keras_automl
     PL/Python function "hyperband_schedule", line 21, in <module>
   PL/Python function "hyperband_schedule"
   
   [SQL: SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);]
   ```
   
   Same happens with `madlib_keras_automl` when I select `hyperband` as the method I want.  So we need to figure out how hyperopt is installed with madlib.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] khannaekta merged pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
khannaekta merged pull request #518:
URL: https://github.com/apache/madlib/pull/518


   


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] khannaekta commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
khannaekta commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707404066


   @Advitya17 Thanks for looking into this! Yes, that is one of the ways we can do to fix the times. I will go ahead and make the necessary changes.
   


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698612856


   output tables 
   ```
   madlib=# select * from automl_cifar10_output_summary;
   -[ RECORD 1 ]-------------+-----------------------------------------
   source_table              | cifar10_train_packed
   validation_table          | cifar10_val_packed
   model                     | automl_cifar10_output
   model_info                | automl_cifar10_output_info
   dependent_varname         | y
   independent_varname       | x
   model_arch_table          | model_arch_library
   model_selection_table     | automl_cifar10_mst_table
   automl_method             | hyperopt
   automl_params             | num_models=4, num_iters=2, algorithm=tpe
   random_state              | None
   object_table              | None
   use_gpus                  | f
   metrics_compute_frequency | 1
   name                      | None
   description               | None
   start_training_time       | 2020-09-24 21:27:43
   end_training_time         | 2020-09-24 21:57:21
   madlib_version            | 1.18.0-dev
   num_classes               | 10
   class_values              | {0,1,2,3,4,5,6,7,8,9}
   dependent_vartype         | text
   normalizing_const         | 256
   ```
   and
   ```
   madlib=# select * from automl_cifar10_output_info;
   -[ RECORD 1 ]------------+-----------------------------------------------------------------------------------------------------------------------
   mst_key                  | 1
   model_id                 | 1
   compile_params           | optimizer='SGD(lr=1.0060862144391352,momentum=2.477852193264555)',metrics=['accuracy'],loss='categorical_crossentropy'
   fit_params               | epochs=1,batch_size=128
   model_type               | madlib_keras
   model_size               | 4886.20019531
   metrics_elapsed_time     | {854.796041965485,1740.91218686104}
   metrics_type             | {accuracy}
   loss_type                | categorical_crossentropy
   training_metrics_final   | 0.100000001490116
   training_loss_final      | NaN
   training_metrics         | {0.100000001490116,0.100000001490116}
   training_loss            | {NaN,NaN}
   validation_metrics_final | 0.100000001490116
   validation_loss_final    | NaN
   validation_metrics       | {0.100000001490116,0.100000001490116}
   validation_loss          | {NaN,NaN}
   -[ RECORD 2 ]------------+-----------------------------------------------------------------------------------------------------------------------
   mst_key                  | 3
   model_id                 | 2
   compile_params           | optimizer='SGD(lr=1.0019632479006402,momentum=2.468115689403145)',metrics=['accuracy'],loss='categorical_crossentropy'
   fit_params               | epochs=1,batch_size=128
   model_type               | madlib_keras
   model_size               | 2159.70019531
   metrics_elapsed_time     | {867.580676794052,1753.89660692215}
   metrics_type             | {accuracy}
   loss_type                | categorical_crossentropy
   training_metrics_final   | 0.100000001490116
   training_loss_final      | NaN
   training_metrics         | {0.100000001490116,0.100000001490116}
   training_loss            | {NaN,NaN}
   validation_metrics_final | 0.100000001490116
   validation_loss_final    | NaN
   validation_metrics       | {0.100000001490116,0.100000001490116}
   validation_loss          | {NaN,NaN}
   -[ RECORD 3 ]------------+-----------------------------------------------------------------------------------------------------------------------
   mst_key                  | 4
   model_id                 | 2
   compile_params           | optimizer='Adam(lr=1.009549897036113)',metrics=['accuracy'],loss='categorical_crossentropy'
   fit_params               | epochs=1,batch_size=64
   model_type               | madlib_keras
   model_size               | 2159.70019531
   metrics_elapsed_time     | {880.187488794327,1766.73845982552}
   metrics_type             | {accuracy}
   loss_type                | categorical_crossentropy
   training_metrics_final   | 0.0999400019645691
   training_loss_final      | 14.5072526931763
   training_metrics         | {0.0996000021696091,0.0999400019645691}
   training_loss            | {14.5127325057983,14.5072526931763}
   validation_metrics_final | 0.100100003182888
   validation_loss_final    | 14.5046730041504
   validation_metrics       | {0.101099997758865,0.100100003182888}
   validation_loss          | {14.4885559082031,14.5046730041504}
   -[ RECORD 4 ]------------+-----------------------------------------------------------------------------------------------------------------------
   mst_key                  | 2
   model_id                 | 1
   compile_params           | optimizer='SGD(lr=1.0039632314582876,momentum=2.466481495072043)',metrics=['accuracy'],loss='categorical_crossentropy'
   fit_params               | epochs=1,batch_size=64
   model_type               | madlib_keras
   model_size               | 4886.20019531
   metrics_elapsed_time     | {885.122605800629,1772.07805681229}
   metrics_type             | {accuracy}
   loss_type                | categorical_crossentropy
   training_metrics_final   | 0.100000001490116
   training_loss_final      | NaN
   training_metrics         | {0.100000001490116,0.100000001490116}
   training_loss            | {NaN,NaN}
   validation_metrics_final | 0.100000001490116
   validation_loss_final    | NaN
   validation_metrics       | {0.100000001490116,0.100000001490116}
   validation_loss          | {NaN,NaN}
   ```
   


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698612856


   output tables 
   ```
   madlib=# select * from automl_cifar10_output_summary;
   -[ RECORD 1 ]-------------+-----------------------------------------
   source_table              | cifar10_train_packed
   validation_table          | cifar10_val_packed
   model                     | automl_cifar10_output
   model_info                | automl_cifar10_output_info
   dependent_varname         | y
   independent_varname       | x
   model_arch_table          | model_arch_library
   model_selection_table     | automl_cifar10_mst_table
   automl_method             | hyperopt
   automl_params             | num_models=4, num_iters=2, algorithm=tpe
   random_state              | None
   object_table              | None
   use_gpus                  | f
   metrics_compute_frequency | 1
   name                      | None
   description               | None
   start_training_time       | 2020-09-24 21:27:43
   end_training_time         | 2020-09-24 21:57:21
   madlib_version            | 1.18.0-dev
   num_classes               | 10
   class_values              | {0,1,2,3,4,5,6,7,8,9}
   dependent_vartype         | text
   normalizing_const         | 256
   ```
   and
   ```
   madlib=# select * from automl_cifar10_output_info;
   -[ RECORD 1 ]------------+-----------------------------------------------------------------------------------------------------------------------
   mst_key                  | 1
   model_id                 | 1
   compile_params           | optimizer='SGD(lr=1.0060862144391352,momentum=2.477852193264555)',metrics=['accuracy'],loss='categorical_crossentropy'
   fit_params               | epochs=1,batch_size=128
   model_type               | madlib_keras
   model_size               | 4886.20019531
   metrics_elapsed_time     | {854.796041965485,1740.91218686104}
   metrics_type             | {accuracy}
   loss_type                | categorical_crossentropy
   training_metrics_final   | 0.100000001490116
   training_loss_final      | NaN
   training_metrics         | {0.100000001490116,0.100000001490116}
   training_loss            | {NaN,NaN}
   validation_metrics_final | 0.100000001490116
   validation_loss_final    | NaN
   validation_metrics       | {0.100000001490116,0.100000001490116}
   validation_loss          | {NaN,NaN}
   -[ RECORD 2 ]------------+-----------------------------------------------------------------------------------------------------------------------
   mst_key                  | 3
   model_id                 | 2
   compile_params           | optimizer='SGD(lr=1.0019632479006402,momentum=2.468115689403145)',metrics=['accuracy'],loss='categorical_crossentropy'
   fit_params               | epochs=1,batch_size=128
   model_type               | madlib_keras
   model_size               | 2159.70019531
   metrics_elapsed_time     | {867.580676794052,1753.89660692215}
   metrics_type             | {accuracy}
   loss_type                | categorical_crossentropy
   training_metrics_final   | 0.100000001490116
   training_loss_final      | NaN
   training_metrics         | {0.100000001490116,0.100000001490116}
   training_loss            | {NaN,NaN}
   validation_metrics_final | 0.100000001490116
   validation_loss_final    | NaN
   validation_metrics       | {0.100000001490116,0.100000001490116}
   validation_loss          | {NaN,NaN}
   -[ RECORD 3 ]------------+-----------------------------------------------------------------------------------------------------------------------
   mst_key                  | 4
   model_id                 | 2
   compile_params           | optimizer='Adam(lr=1.009549897036113)',metrics=['accuracy'],loss='categorical_crossentropy'
   fit_params               | epochs=1,batch_size=64
   model_type               | madlib_keras
   model_size               | 2159.70019531
   metrics_elapsed_time     | {880.187488794327,1766.73845982552}
   metrics_type             | {accuracy}
   loss_type                | categorical_crossentropy
   training_metrics_final   | 0.0999400019645691
   training_loss_final      | 14.5072526931763
   training_metrics         | {0.0996000021696091,0.0999400019645691}
   training_loss            | {14.5127325057983,14.5072526931763}
   validation_metrics_final | 0.100100003182888
   validation_loss_final    | 14.5046730041504
   validation_metrics       | {0.101099997758865,0.100100003182888}
   validation_loss          | {14.4885559082031,14.5046730041504}
   -[ RECORD 4 ]------------+-----------------------------------------------------------------------------------------------------------------------
   mst_key                  | 2
   model_id                 | 1
   compile_params           | optimizer='SGD(lr=1.0039632314582876,momentum=2.466481495072043)',metrics=['accuracy'],loss='categorical_crossentropy'
   fit_params               | epochs=1,batch_size=64
   model_type               | madlib_keras
   model_size               | 4886.20019531
   metrics_elapsed_time     | {885.122605800629,1772.07805681229}
   metrics_type             | {accuracy}
   loss_type                | categorical_crossentropy
   training_metrics_final   | 0.100000001490116
   training_loss_final      | NaN
   training_metrics         | {0.100000001490116,0.100000001490116}
   training_loss            | {NaN,NaN}
   validation_metrics_final | 0.100000001490116
   validation_loss_final    | NaN
   validation_metrics       | {0.100000001490116,0.100000001490116}
   validation_loss          | {NaN,NaN}
   ```
   ```
   madlib=# select * from automl_cifar10_mst_table;
   -[ RECORD 1 ]--+--------------------------------------------------------------------------------------------
   mst_key        | 4
   model_id       | 2
   compile_params | optimizer='Adam(lr=1.009549897036113)',metrics=['accuracy'],loss='categorical_crossentropy'
   fit_params     | epochs=1,batch_size=64
   ```


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698536437






----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-699189947


   (6)
   fmin definition
   https://github.com/hyperopt/hyperopt/wiki/FMin
   fmin(loss, space, algo, max_evals)
   
   Looks like this PR is setting max_evals =  num_models/num_segments in `get_configs_list()`.  For one thing I'm not sure that 
   ```
   self.num_workers = get_seg_number() * get_segments_per_host()
   ```
   gives total number of workers?  On a 1 host, 2 segments-per-host database this returned 4 instead of the expected 2.  Also this needs to be consistent with the distribution rules set in the mini-batch preprocessor.
   
   (7)
   The function `get_configs_list()` may not be distributing the workload correctly to the segments.  
   For 
   ```
       num_models = 3
       num_workers = 3
   ```
   it returns `[(1, 3)]` which seems OK.  But for 
   ```
       num_models = 5
       num_workers = 3
   ```
   it returns `[(1, 5)]` which does not seem OK.  It will not do any hyperopt updates if all 5 configs are grouped together.  I would have expected `[(1, 3), (4, 5)]`.   For 
   ```
       num_models = 20
       num_workers = 3
   ```
   it returns `[(1, 4), (5, 8), (9, 11), (12, 14), (15, 17), (18, 20)]` which means it is running 4 configs on 3 segments multiple times which does not seem efficient.  I would have expected something like `[(1, 3), (4, 6), (7, 9), (10, 12), (13, 15), (16, 18),(19, 20)]` which runs 3 configs at a time on the 3 segments.
   
   (8)
   In `find_hyperopt_config()` confirm that the loss for *each* model that passed to hyperopt after training, and not just the best one from the group.
   
   (9)
   defaults
   Seems like hyperband defaults are being used for hyperopt in the case that use does not specify hyperband is not specified.  That will probably throw an error


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-716773016






----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-700952240


   > (6)
   > fmin definition
   > https://github.com/hyperopt/hyperopt/wiki/FMin
   > fmin(loss, space, algo, max_evals)
   > 
   > Looks like this PR is setting max_evals = num_models/num_segments in `get_configs_list()`. For one thing I'm not sure that
   > 
   > ```
   > self.num_workers = get_seg_number() * get_segments_per_host()
   > ```
   > 
   > gives total number of workers? On a 1 host, 2 segments-per-host database this returned 4 instead of the expected 2. Also this needs to be consistent with the distribution rules set in the mini-batch preprocessor.
   > 
   > (7)
   > The function `get_configs_list()` may not be distributing the workload correctly to the segments.
   > For
   > 
   > ```
   >     num_models = 3
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 3)]` which seems OK. But for
   > 
   > ```
   >     num_models = 5
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 5)]` which does not seem OK. It will not do any hyperopt updates if all 5 configs are grouped together. I would have expected `[(1, 3), (4, 5)]`. For
   > 
   > ```
   >     num_models = 20
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 4), (5, 8), (9, 11), (12, 14), (15, 17), (18, 20)]` which means it is running 4 configs on 3 segments multiple times which does not seem efficient. I would have expected something like `[(1, 3), (4, 6), (7, 9), (10, 12), (13, 15), (16, 18),(19, 20)]` which runs 3 configs at a time on the 3 segments.
   > 
   > (8)
   > In `find_hyperopt_config()` confirm that the loss for _each_ model that passed to hyperopt after training, and not just the best one from the group.
   > 
   > (9)
   > defaults
   > Seems like hyperband defaults are being used for hyperopt in the case that use does not specify hyperband is not specified. That will probably throw an error
   
   @fmcquillan99 
   
   (7) 
   
   (a) As per my discussions with @reductionista , the current implementation seems to run more than 1 rounds when `number of models >= 2 * number of segments/workers in the cluster`. Sure, though the latter `[(1, 3), (4, 5)]` may have an idle worker, it may be a better approach for Hyperopt.
   
   (b) In reference to the 2nd example, I believe this was as per our discussions to minimize number of model training function calls (and to make the schedule look relatively more 'balanced'). Observe that the former schedule runs 4 configs on 3 workers for 2 rounds/runs and continues with the 3 configs on 3 workers for all other rounds (as 3 doesn't perfectly divide 20). The latter runs 2 configs on 3 workers at the end which also thus has an idle worker (apart from 1 more model training function call compared to the former approach).
   
   (8) I believe all the losses are already passed on to hyperopt as part of my implementation, in the `Hyperopt TPE Update` for loop.
   
   (9) Yes I did observe that. I tried to change the global defaults in the SQL file as per chosen automl method, but ran into errors in the process. As per my current implementation, the hyperband params are defaults and the user may need to explicitly specify hyperopt params when using hyperopt.
   
   (10) The name changes sound good to me.
   
   Let me know if there're more areas I could address.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r493918825



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works
+                else:
+                    plpy.error("DL: algorithm in 'automl_params' must be 'rand', 'tpe'") # , or 'atpe'
+            else:
+                plpy.error("DL: {0} is an invalid automl param".format(i))
+        _assert(self.num_models > 0 and self.num_iters > 0, "DL: num_models and num_iters in 'automl_params' "
+                                                            "must be positive")
+        _assert(self._is_valid_metrics_compute_frequency(self.num_iters), "DL: 'metrics_compute_frequency' "
+                                                                          "out of iteration range")
+
+    def find_hyperopt_config(self):
         """
-        Drops and re-create the mst table to only include the best performing model configuration.
+        Executes hyperopt on top of MOP.
         """
-        drop_tables([self.model_selection_table])
 
-        # only retaining best performing config
-        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT mst_key, model_id, compile_params, " \
-                     "fit_params FROM {self.model_info_table} " \
-                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self, AutoMLSchema=AutoMLSchema))
+        make_mst_summary = True
+        trials = Trials()
+        domain = Domain(None, self.get_search_space())
+        rand_state = np.random.RandomState(self.random_state)
+        configs_lst = self.get_configs_list()
 
-    def generate_model_output_summary_table(self, model_training):
+        self.start_training_time = self.get_current_timestamp()
+        for low, high in configs_lst:
+            i, n = low, high - low + 1
+
+            # Using HyperOpt TPE/ATPE to generate parameters
+            hyperopt_params = []
+            sampled_params = []
+            for j in range(i, i + n):
+                new_param = self.algorithm.suggest([j], domain, trials, rand_state.randint(0, 2 ** 31 - 1))
+                new_param[0]['status'] = STATUS_RUNNING
+
+                trials.insert_trial_docs(new_param)
+                trials.refresh()
+                hyperopt_params.append(new_param[0])
+                sampled_params.append(new_param[0]['misc']['vals'])
+
+            model_id_list, compile_params, fit_params = self.extract_param_vals(sampled_params)
+            msts_list = self.generate_msts(model_id_list, compile_params, fit_params)
+            try:
+                self.remove_temp_tables(model_training)
+            except:
+                pass
+            self.populate_temp_mst_table(i, msts_list)
+
+            plpy.info("***Evaluating {n} newly suggested model configurations***".format(n=n))
+            model_training = FitMultipleModel(self.schema_madlib, self.source_table, AutoMLSchema.TEMP_OUTPUT_TABLE,
+                             AutoMLSchema.TEMP_MST_TABLE, self.num_iters, self.use_gpus, self.validation_table,
+                             self.metrics_compute_frequency, False, self.name, self.description)
+            if make_mst_summary:
+                self.generate_mst_summary_table(self.model_selection_summary_table)
+                make_mst_summary = False
+
+            # HyperOpt TPE update
+            for k, hyperopt_param in enumerate(hyperopt_params, i):
+                loss_val = plpy.execute("SELECT {AutoMLSchema.LOSS_METRIC} FROM {model_training.model_info_table} " \
+                             "WHERE {ModelSelectionSchema.MST_KEY}={k}".format(AutoMLSchema=AutoMLSchema,
+                                                                               ModelSelectionSchema=ModelSelectionSchema,
+                                                                               **locals()))[0][AutoMLSchema.LOSS_METRIC]
+
+                hyperopt_param['status'] = STATUS_OK

Review comment:
       Yeah it seems it's apparently used internally by the hyperopt module during `refresh` and to explore further configs.




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r493918484



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -17,27 +17,41 @@
 # specific language governing permissions and limitations
 # under the License.
 
+from ast import literal_eval
 from datetime import datetime
-import plpy
+from hyperopt import hp, rand, tpe, atpe, Trials, STATUS_OK, STATUS_RUNNING
+from hyperopt.base import Domain
 import math
+import numpy as np
+import plpy
 from time import time
 
 from madlib_keras_validator import MstLoaderInputValidator
-from utilities.utilities import unique_string, add_postfix, extract_keyvalue_params, \
-    _assert, _assert_equal, rename_table
+from utilities.utilities import get_seg_number, get_segments_per_host, unique_string, add_postfix, \
+    extract_keyvalue_params, _assert, _assert_equal, rename_table
 from utilities.control import MinWarning, SetGUC
 from madlib_keras_fit_multiple_model import FitMultipleModel
 from madlib_keras_model_selection import MstSearch, ModelSelectionSchema
 from keras_model_arch_table import ModelArchSchema
 from utilities.validate_args import table_exists, drop_tables
 
+import inspect
+
+def decallmethods(decorator, prefix='test_'):

Review comment:
       I inserted this to make the class inheritance work earlier. On further inspection, it seems I may not need this function.

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -158,11 +174,10 @@ class HyperbandSchedule():
                                       **locals())
             plpy.execute(insert_query)
 
-@MinWarning("warning")
-class KerasAutoML():
-    """The core AutoML function for running AutoML algorithms such as Hyperband.
-    This function executes the hyperband rounds 'diagonally' to evaluate multiple configurations together
-    and leverage the compute power of MPP databases such as Greenplum.
+# @MinWarning("warning")

Review comment:
       They error out if I do that:
   ```
   ERROR:  TypeError: Error when calling the metaclass bases
       function() argument 1 must be code, not str (plpy_elog.c:121)
   ```




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] orhankislal commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
orhankislal commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r494130605



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works
+                else:
+                    plpy.error("DL: algorithm in 'automl_params' must be 'rand', 'tpe'") # , or 'atpe'
+            else:
+                plpy.error("DL: {0} is an invalid automl param".format(i))
+        _assert(self.num_models > 0 and self.num_iters > 0, "DL: num_models and num_iters in 'automl_params' "
+                                                            "must be positive")
+        _assert(self._is_valid_metrics_compute_frequency(self.num_iters), "DL: 'metrics_compute_frequency' "
+                                                                          "out of iteration range")
+
+    def find_hyperopt_config(self):
         """
-        Drops and re-create the mst table to only include the best performing model configuration.
+        Executes hyperopt on top of MOP.
         """
-        drop_tables([self.model_selection_table])
 
-        # only retaining best performing config
-        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT mst_key, model_id, compile_params, " \
-                     "fit_params FROM {self.model_info_table} " \
-                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self, AutoMLSchema=AutoMLSchema))
+        make_mst_summary = True
+        trials = Trials()
+        domain = Domain(None, self.get_search_space())
+        rand_state = np.random.RandomState(self.random_state)
+        configs_lst = self.get_configs_list()
 
-    def generate_model_output_summary_table(self, model_training):
+        self.start_training_time = self.get_current_timestamp()
+        for low, high in configs_lst:
+            i, n = low, high - low + 1
+
+            # Using HyperOpt TPE/ATPE to generate parameters
+            hyperopt_params = []
+            sampled_params = []
+            for j in range(i, i + n):
+                new_param = self.algorithm.suggest([j], domain, trials, rand_state.randint(0, 2 ** 31 - 1))
+                new_param[0]['status'] = STATUS_RUNNING
+
+                trials.insert_trial_docs(new_param)
+                trials.refresh()
+                hyperopt_params.append(new_param[0])
+                sampled_params.append(new_param[0]['misc']['vals'])
+
+            model_id_list, compile_params, fit_params = self.extract_param_vals(sampled_params)
+            msts_list = self.generate_msts(model_id_list, compile_params, fit_params)
+            try:
+                self.remove_temp_tables(model_training)
+            except:
+                pass
+            self.populate_temp_mst_table(i, msts_list)
+
+            plpy.info("***Evaluating {n} newly suggested model configurations***".format(n=n))
+            model_training = FitMultipleModel(self.schema_madlib, self.source_table, AutoMLSchema.TEMP_OUTPUT_TABLE,
+                             AutoMLSchema.TEMP_MST_TABLE, self.num_iters, self.use_gpus, self.validation_table,
+                             self.metrics_compute_frequency, False, self.name, self.description)
+            if make_mst_summary:
+                self.generate_mst_summary_table(self.model_selection_summary_table)
+                make_mst_summary = False
+
+            # HyperOpt TPE update
+            for k, hyperopt_param in enumerate(hyperopt_params, i):
+                loss_val = plpy.execute("SELECT {AutoMLSchema.LOSS_METRIC} FROM {model_training.model_info_table} " \
+                             "WHERE {ModelSelectionSchema.MST_KEY}={k}".format(AutoMLSchema=AutoMLSchema,
+                                                                               ModelSelectionSchema=ModelSelectionSchema,
+                                                                               **locals()))[0][AutoMLSchema.LOSS_METRIC]
+
+                hyperopt_param['status'] = STATUS_OK

Review comment:
       OK we should leave a short comment to make sure it doesn't get refactored out in the future




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r495189361



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -291,9 +338,100 @@ class KerasAutoML():
                (self.metrics_compute_frequency >= 1 and \
                 self.metrics_compute_frequency <= num_iterations)
 
+    def print_best_so_far(self):
+        """
+        Prints mst keys with best train/val losses at a given point.
+        """
+        best_so_far = '\n'
+        best_so_far += self.print_best_helper('training')
+        if self.validation_table:
+            best_so_far += self.print_best_helper('validation')
+        plpy.info(best_so_far)
+
+    def print_best_helper(self, keyword):
+        """
+        Helper function to Prints mst keys with best train/val losses at a given point.
+        :param keyword: column prefix ('training' or 'validation')
+        :return:
+        """
+        metrics_word, loss_word = keyword + '_metrics_final', keyword + '_loss_final'
+
+        res_str = 'Best {keyword} loss so far:\n'.format(keyword=keyword)
+        best_value = plpy.execute("SELECT {ModelSelectionSchema.MST_KEY}, {metrics_word}, " \
+                                  "{loss_word} FROM {self.model_info_table} ORDER BY " \
+                                  "{loss_word} LIMIT 1".format(self=self, ModelSelectionSchema=ModelSelectionSchema,
+                                                               metrics_word=metrics_word, loss_word=loss_word))[0]
+        mst_key_value, metric_value, loss_value = best_value[ModelSelectionSchema.MST_KEY], \
+                                                  best_value[metrics_word], best_value[loss_word]
+        res_str += ModelSelectionSchema.MST_KEY + '=' + str(mst_key_value) + ': metric=' + str(metric_value) + \
+                   ', loss=' + str(loss_value) + '\n'
+        return res_str
+
+    def get_current_timestamp(self):
+        """for start and end times for the chosen AutoML algorithm. Showcased in the output summary table"""
+        return datetime.fromtimestamp(time()).strftime('%Y-%m-%d %H:%M:%S')
+
+    def remove_temp_tables(self, model_training):

Review comment:
       I reverted back to my function as I was unfortunately facing pipeline issues with the utility function. I've still commented out the related lines in case anyone wants to experiment with it. 




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707400603


   > I don't see it in there
   > 
   > ```
   > \d hopt_cifar10_output_summary_c100n3tperun1;
   >       Table "public.hopt_cifar10_output_summary_c100n3tperun1"
   >           Column           |            Type             | Modifiers 
   > ---------------------------+-----------------------------+-----------
   >  source_table              | text                        | 
   >  validation_table          | text                        | 
   >  model                     | text                        | 
   >  model_info                | text                        | 
   >  dependent_varname         | text                        | 
   >  independent_varname       | text                        | 
   >  model_arch_table          | text                        | 
   >  model_selection_table     | text                        | 
   >  automl_method             | text                        | 
   >  automl_params             | text                        | 
   >  random_state              | text                        | 
   >  object_table              | text                        | 
   >  use_gpus                  | boolean                     | 
   >  metrics_compute_frequency | integer                     | 
   >  name                      | text                        | 
   >  description               | text                        | 
   >  start_training_time       | timestamp without time zone | 
   >  end_training_time         | timestamp without time zone | 
   >  madlib_version            | text                        | 
   >  num_classes               | integer                     | 
   >  class_values              | text[]                      | 
   >  dependent_vartype         | text                        | 
   >  normalizing_const         | real                        | 
   > ```
   
   Okay, in that case I suppose I used the summary table format used earlier in Hyperband (instead of the fit multiple one, which includes the metrics iters). 
   I suppose the column can be added in the summary table generation function where its value is populated by the temp summary table from the fit multiple call. 


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-700952240


   > (6)
   > fmin definition
   > https://github.com/hyperopt/hyperopt/wiki/FMin
   > fmin(loss, space, algo, max_evals)
   > 
   > Looks like this PR is setting max_evals = num_models/num_segments in `get_configs_list()`. For one thing I'm not sure that
   > 
   > ```
   > self.num_workers = get_seg_number() * get_segments_per_host()
   > ```
   > 
   > gives total number of workers? On a 1 host, 2 segments-per-host database this returned 4 instead of the expected 2. Also this needs to be consistent with the distribution rules set in the mini-batch preprocessor.
   > 
   > (7)
   > The function `get_configs_list()` may not be distributing the workload correctly to the segments.
   > For
   > 
   > ```
   >     num_models = 3
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 3)]` which seems OK. But for
   > 
   > ```
   >     num_models = 5
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 5)]` which does not seem OK. It will not do any hyperopt updates if all 5 configs are grouped together. I would have expected `[(1, 3), (4, 5)]`. For
   > 
   > ```
   >     num_models = 20
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 4), (5, 8), (9, 11), (12, 14), (15, 17), (18, 20)]` which means it is running 4 configs on 3 segments multiple times which does not seem efficient. I would have expected something like `[(1, 3), (4, 6), (7, 9), (10, 12), (13, 15), (16, 18),(19, 20)]` which runs 3 configs at a time on the 3 segments.
   > 
   > (8)
   > In `find_hyperopt_config()` confirm that the loss for _each_ model that passed to hyperopt after training, and not just the best one from the group.
   > 
   > (9)
   > defaults
   > Seems like hyperband defaults are being used for hyperopt in the case that use does not specify hyperband is not specified. That will probably throw an error
   
   @fmcquillan99 
   
   (7) 
   
   (a) As per my discussions with @reductionista , the current implementation seems to run more than 1 rounds when `number of models >= 2 * number of segments/workers in the cluster`. Sure, though the latter `[(1, 3), (4, 5)]` may have an idle worker, it may be a better approach for Hyperopt.
   
   (b) In reference to the 2nd example, I believe this was as per our discussions to minimize number of model training function calls (and to make the schedule look relatively more 'balanced'). Observe that the former schedule runs 4 configs on 3 workers for 2 rounds/runs and continues with the 3 configs on 3 workers for all other rounds (as 3 doesn't perfectly divide 20). The latter runs 2 configs on 3 workers at the end which also thus has an idle worker (apart from 1 more model training function call compared to the former approach).
   
   (8) I believe all the losses are already passed on to hyperopt as part of my implementation, in the `Hyperopt TPE Update` for loop (starting line 753 of the AutoML python file).
   
   (9) Yes I did observe that. I tried to change the global defaults in the SQL file as per chosen automl method, but ran into errors in the process. As per my current implementation, the hyperband params are defaults and the user may need to explicitly specify hyperopt params when using hyperopt.
   
   (10) The name changes sound good to me.
   
   Let me know if there're more areas I could address.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] orhankislal commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
orhankislal commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r494129949



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -291,9 +338,100 @@ class KerasAutoML():
                (self.metrics_compute_frequency >= 1 and \
                 self.metrics_compute_frequency <= num_iterations)
 
+    def print_best_so_far(self):
+        """
+        Prints mst keys with best train/val losses at a given point.
+        """
+        best_so_far = '\n'
+        best_so_far += self.print_best_helper('training')
+        if self.validation_table:
+            best_so_far += self.print_best_helper('validation')
+        plpy.info(best_so_far)
+
+    def print_best_helper(self, keyword):
+        """
+        Helper function to Prints mst keys with best train/val losses at a given point.
+        :param keyword: column prefix ('training' or 'validation')
+        :return:
+        """
+        metrics_word, loss_word = keyword + '_metrics_final', keyword + '_loss_final'
+
+        res_str = 'Best {keyword} loss so far:\n'.format(keyword=keyword)
+        best_value = plpy.execute("SELECT {ModelSelectionSchema.MST_KEY}, {metrics_word}, " \
+                                  "{loss_word} FROM {self.model_info_table} ORDER BY " \
+                                  "{loss_word} LIMIT 1".format(self=self, ModelSelectionSchema=ModelSelectionSchema,
+                                                               metrics_word=metrics_word, loss_word=loss_word))[0]
+        mst_key_value, metric_value, loss_value = best_value[ModelSelectionSchema.MST_KEY], \
+                                                  best_value[metrics_word], best_value[loss_word]
+        res_str += ModelSelectionSchema.MST_KEY + '=' + str(mst_key_value) + ': metric=' + str(metric_value) + \
+                   ', loss=' + str(loss_value) + '\n'
+        return res_str
+
+    def get_current_timestamp(self):
+        """for start and end times for the chosen AutoML algorithm. Showcased in the output summary table"""
+        return datetime.fromtimestamp(time()).strftime('%Y-%m-%d %H:%M:%S')
+
+    def remove_temp_tables(self, model_training):
+        """
+        Remove all intermediate tables created for AutoML runs/updates.
+        :param model_training: Fit Multiple function call object.
+        """
+        drop_tables([model_training.original_model_output_table, model_training.model_info_table,
+                     model_training.model_summary_table, AutoMLSchema.TEMP_MST_TABLE,
+                     AutoMLSchema.TEMP_MST_SUMMARY_TABLE])
+
+# @MinWarning("warning")
+class AutoMLHyperband(KerasAutoML):
+    """
+    This class implements Hyperband, an infinite-arm bandit based algorithm that speeds up random search
+    through adaptive resource allocation, successive halving (SHA) and early stopping.
+
+    This class showcases and novel hyperband implementation by executing the hyperband rounds 'diagonally'

Review comment:
       I meant this: 
   `This class showcases and novel hyperband` -> `This class showcases a novel hyperband`

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works
+                else:
+                    plpy.error("DL: algorithm in 'automl_params' must be 'rand', 'tpe'") # , or 'atpe'
+            else:
+                plpy.error("DL: {0} is an invalid automl param".format(i))
+        _assert(self.num_models > 0 and self.num_iters > 0, "DL: num_models and num_iters in 'automl_params' "
+                                                            "must be positive")
+        _assert(self._is_valid_metrics_compute_frequency(self.num_iters), "DL: 'metrics_compute_frequency' "
+                                                                          "out of iteration range")
+
+    def find_hyperopt_config(self):
         """
-        Drops and re-create the mst table to only include the best performing model configuration.
+        Executes hyperopt on top of MOP.
         """
-        drop_tables([self.model_selection_table])
 
-        # only retaining best performing config
-        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT mst_key, model_id, compile_params, " \
-                     "fit_params FROM {self.model_info_table} " \
-                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self, AutoMLSchema=AutoMLSchema))
+        make_mst_summary = True
+        trials = Trials()
+        domain = Domain(None, self.get_search_space())
+        rand_state = np.random.RandomState(self.random_state)
+        configs_lst = self.get_configs_list()
 
-    def generate_model_output_summary_table(self, model_training):
+        self.start_training_time = self.get_current_timestamp()
+        for low, high in configs_lst:
+            i, n = low, high - low + 1
+
+            # Using HyperOpt TPE/ATPE to generate parameters
+            hyperopt_params = []
+            sampled_params = []
+            for j in range(i, i + n):
+                new_param = self.algorithm.suggest([j], domain, trials, rand_state.randint(0, 2 ** 31 - 1))
+                new_param[0]['status'] = STATUS_RUNNING
+
+                trials.insert_trial_docs(new_param)
+                trials.refresh()
+                hyperopt_params.append(new_param[0])
+                sampled_params.append(new_param[0]['misc']['vals'])
+
+            model_id_list, compile_params, fit_params = self.extract_param_vals(sampled_params)
+            msts_list = self.generate_msts(model_id_list, compile_params, fit_params)
+            try:
+                self.remove_temp_tables(model_training)
+            except:
+                pass
+            self.populate_temp_mst_table(i, msts_list)
+
+            plpy.info("***Evaluating {n} newly suggested model configurations***".format(n=n))
+            model_training = FitMultipleModel(self.schema_madlib, self.source_table, AutoMLSchema.TEMP_OUTPUT_TABLE,
+                             AutoMLSchema.TEMP_MST_TABLE, self.num_iters, self.use_gpus, self.validation_table,
+                             self.metrics_compute_frequency, False, self.name, self.description)
+            if make_mst_summary:
+                self.generate_mst_summary_table(self.model_selection_summary_table)
+                make_mst_summary = False
+
+            # HyperOpt TPE update
+            for k, hyperopt_param in enumerate(hyperopt_params, i):
+                loss_val = plpy.execute("SELECT {AutoMLSchema.LOSS_METRIC} FROM {model_training.model_info_table} " \
+                             "WHERE {ModelSelectionSchema.MST_KEY}={k}".format(AutoMLSchema=AutoMLSchema,
+                                                                               ModelSelectionSchema=ModelSelectionSchema,
+                                                                               **locals()))[0][AutoMLSchema.LOSS_METRIC]
+
+                hyperopt_param['status'] = STATUS_OK

Review comment:
       OK we should leave a short comment to make sure it doesn't get refactored out in the future




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707397232


   > (12)
   > 
   > ```
   > \d hopt_cifar10_output_info_c100n3tperun1
   >    Table "public.hopt_cifar10_output_info_c100n3tperun1"
   >           Column          |        Type        | Modifiers 
   > --------------------------+--------------------+-----------
   >  mst_key                  | integer            | not null
   >  model_id                 | integer            | 
   >  compile_params           | text               | 
   >  fit_params               | text               | 
   >  model_type               | text               | 
   >  model_size               | double precision   | 
   >  metrics_elapsed_time     | double precision[] | 
   >  metrics_type             | text[]             | 
   >  loss_type                | text               | 
   >  training_metrics_final   | double precision   | 
   >  training_loss_final      | double precision   | 
   >  training_metrics         | double precision[] | 
   >  training_loss            | double precision[] | 
   >  validation_metrics_final | double precision   | 
   >  validation_loss_final    | double precision   | 
   >  validation_metrics       | double precision[] | 
   >  validation_loss          | double precision[] | 
   > ```
   > 
   > is missing from the bottom:
   > 
   > ```
   > metrics_iters            | integer[]          | 
   > ```
   
   `metrics_iters` should be mentioned in the summary table itself, as its value is the same for all configs (if I recall correctly).


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-700952240


   > (6)
   > fmin definition
   > https://github.com/hyperopt/hyperopt/wiki/FMin
   > fmin(loss, space, algo, max_evals)
   > 
   > Looks like this PR is setting max_evals = num_models/num_segments in `get_configs_list()`. For one thing I'm not sure that
   > 
   > ```
   > self.num_workers = get_seg_number() * get_segments_per_host()
   > ```
   > 
   > gives total number of workers? On a 1 host, 2 segments-per-host database this returned 4 instead of the expected 2. Also this needs to be consistent with the distribution rules set in the mini-batch preprocessor.
   > 
   > (7)
   > The function `get_configs_list()` may not be distributing the workload correctly to the segments.
   > For
   > 
   > ```
   >     num_models = 3
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 3)]` which seems OK. But for
   > 
   > ```
   >     num_models = 5
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 5)]` which does not seem OK. It will not do any hyperopt updates if all 5 configs are grouped together. I would have expected `[(1, 3), (4, 5)]`. For
   > 
   > ```
   >     num_models = 20
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 4), (5, 8), (9, 11), (12, 14), (15, 17), (18, 20)]` which means it is running 4 configs on 3 segments multiple times which does not seem efficient. I would have expected something like `[(1, 3), (4, 6), (7, 9), (10, 12), (13, 15), (16, 18),(19, 20)]` which runs 3 configs at a time on the 3 segments.
   > 
   > (8)
   > In `find_hyperopt_config()` confirm that the loss for _each_ model that passed to hyperopt after training, and not just the best one from the group.
   > 
   > (9)
   > defaults
   > Seems like hyperband defaults are being used for hyperopt in the case that use does not specify hyperband is not specified. That will probably throw an error
   
   @fmcquillan99 
   
   (7) 
   
   (a) As per my discussions with @reductionista , the current implementation seems to run more than 1 rounds when `number of models >= 2 * number of segments/workers in the cluster`. Sure, though the latter `[(1, 3), (4, 5)]` may have an idle worker, it may be a better approach for Hyperopt.
   
   (b) In reference to the 2nd example, I believe this was as per our discussions to minimize number of model training function calls. Observe that the former schedule runs 4 configs on 3 workers for 2 rounds/runs and continues with the 3 configs on 3 workers for all other rounds (as 3 doesn't perfectly divide 20). The latter only runs 2 configs on 3 workers at the end which also thus has an idle worker (apart from 1 more model training function call compared to the former approach).
   
   (8) I believe all the losses are already passed on to hyperopt as part of my implementation, in the `Hyperopt TPE Update` for loop.
   
   (9) Yes I did observe that. I tried to change the global defaults in the SQL file as per chosen automl method, but ran into errors in the process. As per my current implementation, the hyperband params are defaults and the user may need to explicitly specify hyperopt params when using hyperopt.
   
   (10) The name changes sound good to me.
   
   Let me know if there're more areas I could address.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707396018


   (11)
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[2], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [128], 'epochs': [1]}$$,
                                     'hyperopt', 
                                     'num_configs=100, num_iterations=3, algorithm=tpe',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces
   ```
   select mst_key, metrics_elapsed_time from hopt_cifar10_output_info_c100n3tperun1 order by mst_key;
    mst_key |                 metrics_elapsed_time                 
   ---------+------------------------------------------------------
          1 | {627.882262945175,1264.80915999413,1896.74943590164}
          2 | {614.573877811432,1251.1022670269,1883.14707994461}
          3 | {638.407788038254,1286.73397421837,1939.58357810974}
          4 | {624.925609111786,1273.55782914162,1925.82674407959}
          5 | {650.984225034714,1307.78145503998,1962.8148560524}
          6 | {637.914520978928,1294.23532605171,1949.12843108177}
          7 | {651.188719987869,1301.32990193367,1948.88206887245}
          8 | {637.525157928467,1288.19901585579,1935.65923500061}
          9 | {651.277820110321,1301.09531402588,1947.13559818268}
         10 | {637.898158073425,1287.54387116432,1933.5972070694}
         11 | {650.482151985168,1309.5760037899,1961.18471598625}
         12 | {637.149097919464,1295.67461585999,1947.66235399246}
         13 | {651.543440818787,1299.3868060112,1948.78301692009}
         14 | {638.292811870575,1285.66767001152,1935.02927088737}
         15 | {650.077238082886,1305.37611913681,1962.8950419426}
         16 | {636.498329162598,1291.3173930645,1948.41972708702}
         17 | {649.946799993515,1303.33863401413,1949.58992981911}
         18 | {636.373380899429,1289.27607584,1936.36742186546}
         19 | {647.414880990982,1297.31931090355,1945.65248298645}
         20 | {634.09289598465,1284.170140028,1932.07456684113}
         21 | {684.188683986664,1330.76613283157,1980.06952404976}
         22 | {670.57110285759,1317.26948404312,1966.71574902534}
         23 | {651.919174909592,1304.4483089447,1949.68165898323}
         24 | {637.834177970886,1290.82985186577,1936.79075098038}
         25 | {655.077679872513,1298.5494530201,1945.88967299461}
         26 | {642.029677867889,1285.51564288139,1932.42474102974}
         27 | {647.519994020462,1291.86638307571,1940.63740706444}
         28 | {634.281761884689,1277.6536450386,1927.27670001984}
         29 | {649.227880954742,1295.78293895721,1939.8649418354}
         30 | {635.665500879288,1282.13676691055,1926.41391181946}
         31 | {646.891736984253,1292.39306688309,1939.45323801041}
         32 | {633.289309024811,1278.57114887238,1925.29498195648}
         33 | {645.044659852982,1294.90844988823,1934.83831381798}
         34 | {631.370570898056,1281.09457278252,1921.84612298012}
         35 | {641.974558115005,1287.15608096123,1933.71887016296}
         36 | {628.698891162872,1273.55222702026,1920.55405902863}
         37 | {645.359504938126,1286.81019496918,1936.24443602562}
         38 | {632.138350963593,1273.69606280327,1921.84107279778}
         39 | {645.965959072113,1291.83859109879,1934.28793001175}
         40 | {631.842108011246,1278.0611550808,1921.37190818787}
         41 | {644.744366168976,1284.78299307823,1926.56299805641}
         42 | {631.000986099243,1271.36041498184,1912.94822907448}
         43 | {646.629382133484,1289.81746912003,1938.30674505234}
         44 | {633.08934211731,1276.87801408768,1924.48914599419}
         45 | {645.794209003448,1289.52689504623,1928.10301995277}
         46 | {632.544068098068,1276.46976709366,1915.18053913116}
         47 | {648.967436075211,1296.18764710426,1942.72390508652}
         48 | {635.180493116379,1282.65127015114,1928.7596950531}
         49 | {642.685960054398,1281.86446094513,1924.27530503273}
         50 | {628.867849111557,1268.81643414497,1910.81892299652}
         51 | {642.25784611702,1285.31040906906,1931.93548893929}
         52 | {628.323985099792,1271.58122897148,1918.26403403282}
         53 | {641.810137033463,1285.25560903549,1929.13687109947}
         54 | {628.287924051285,1271.25157594681,1915.76375198364}
         55 | {645.721904993057,1285.12515211105,1928.89319014549}
         56 | {632.100169181824,1271.49339413643,1915.78533101082}
         57 | {639.617475986481,1275.61342597008,1915.39825177193}
         58 | {626.503052949905,1262.02722096443,1901.32048177719}
         59 | {635.73348903656,1280.25348901749,1919.08957004547}
         60 | {622.708857059479,1266.27361917496,1905.91475009918}
         61 | {640.503421068192,1279.74774312973,1920.75052404404}
         62 | {627.23721909523,1266.51659917831,1906.79211616516}
         63 | {642.081022977829,1277.49766278267,1916.42965888977}
         64 | {628.109483957291,1264.7400097847,1903.20749592781}
         65 | {640.490365028381,1283.00291013718,1924.50952506065}
         66 | {627.058392047882,1269.47951006889,1910.89861011505}
         67 | {636.89220905304,1277.09766602516,1910.96581101418}
         68 | {624.116094112396,1263.90056610107,1898.12311601639}
         69 | {635.469167947769,1269.55181598663,1904.01561403275}
         70 | {622.43970489502,1256.59510493279,1890.07668590546}
         71 | {636.119792938232,1276.15144109726,1913.03098011017}
         72 | {622.38174700737,1262.04434704781,1899.77307701111}
         73 | {635.743231058121,1276.63025021553,1917.14123606682}
         74 | {622.766848087311,1263.39644908905,1903.07419419289}
         75 | {630.598103046417,1267.86923599243,1899.72781896591}
         76 | {617.88782787323,1254.63754701614,1886.25667786598}
         77 | {632.587329149246,1270.71484613419,1902.50029301643}
         78 | {619.189999103546,1257.35159301758,1889.55543804169}
         79 | {631.962325811386,1268.57928681374,1901.31368494034}
         80 | {618.959751844406,1255.32190680504,1888.31697797775}
         81 | {634.275179862976,1261.66588997841,1895.5607509613}
         82 | {619.90931391716,1248.77173399925,1882.48632383347}
         83 | {633.14914894104,1265.85549592972,1897.17652893066}
         84 | {619.785959005356,1252.29544901848,1884.09737896919}
         85 | {627.898339033127,1261.44491815567,1893.74317097664}
         86 | {615.068039178848,1248.09124517441,1879.57727813721}
         87 | {633.1245470047,1268.63815689087,1904.82987594604}
         88 | {619.971349954605,1255.54224300385,1891.63547801971}
         89 | {634.308418035507,1267.44264101982,1903.04254603386}
         90 | {621.244497060776,1254.47942519188,1889.07282710075}
         91 | {638.813256025314,1286.2553050518,1923.13115119934}
         92 | {624.587430000305,1271.47850799561,1909.81140208244}
         93 | {635.323696136475,1271.31673598289,1910.10420203209}
         94 | {622.143538951874,1258.46868395805,1896.75948596001}
         95 | {636.06889295578,1269.57318091393,1905.99937295914}
         96 | {621.923580884933,1255.54979085922,1892.35493183136}
         97 | {635.867208957672,1275.91143798828,1907.85138106346}
         98 | {622.153614997864,1262.45370602608,1895.00853896141}
         99 | {632.058423995972,1264.59007382393,1902.03439188004}
        100 | {618.850169897079,1251.59025883675,1889.0108628273}
   (100 rows)
   ```
   These times should be cumulative, not relative to when the trial started.  We want to be able to do a plot that looks like:
   
   ![image](https://user-images.githubusercontent.com/10538173/95799055-5846b500-0ca8-11eb-9f3a-b2dc35b416d0.png)
   


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-699189947


   (6)
   fmin definition
   https://github.com/hyperopt/hyperopt/wiki/FMin
   fmin(loss, space, algo, max_evals)
   
   Looks like this PR is setting max_evals =  num_models/num_segments in `get_configs_list()`.  For one thing I'm not sure that 
   ```
   self.num_workers = get_seg_number() * get_segments_per_host()
   ```
   gives total number of workers?  On a 1 host, 2 segments-per-host database this returned 4 instead of the expected 2.  Also this needs to be consistent with the distribution rules set in the mini-batch preprocessor.
   
   (7)
   The function `get_configs_list()` may not be distributing the workload correctly to the segments.  
   For 
   ```
       num_models = 3
       num_workers = 3
   ```
   it returns `[(1, 3)]` which seems OK.  But for 
   ```
       num_models = 5
       num_workers = 3
   ```
   it returns `[(1, 5)]` which does not seem OK.  It will not do any hyperopt updates if all 5 configs are grouped together.  I would have expected `[(1, 3), (4, 5)]`.   For 
   ```
       num_models = 20
       num_workers = 3
   ```
   it returns `[(1, 4), (5, 8), (9, 11), (12, 14), (15, 17), (18, 20)]` which means it is running 4 configs on 3 segments multiple times which does not seem efficient.  I would have expected something like `[(1, 3), (4, 6), (7, 9), (10, 12), (13, 15), (16, 18),(19, 20)]` which runs 3 configs at a time on the 3 segments.
   
   (8)
   In `find_hyperopt_config()` confirm that the loss for *each* model that passed to hyperopt after training, and not just the best one from the group.
   
   (9)
   defaults
   Seems like hyperband defaults are being used for hyperopt in the case that use does not specify hyperband is not specified.  That will probably throw an error.  Should there be defaults for hyperband and hyperopt, or should they be mandatory?


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-699189947


   (6)
   fmin definition
   https://github.com/hyperopt/hyperopt/wiki/FMin
   fmin(loss, space, algo, max_evals)
   
   (a)
   Looks like this PR is setting max_evals =  num_models/num_segments.  For one thing I'm not sure that 
   ```
   self.num_workers = get_seg_number() * get_segments_per_host()
   ```
   gives total number of workers?  On a 1 host, 2 segments-per-host database this returned 4 instead of the expected 2.  Also this needs to be consistent with the distribution rules set in the mini-batch preprocessor.
   
   (b)
   Looks like the logic is for each eval to find the losses for multiple models (= num segments) in parallel, then return the best loss value to hyperopt, then get a new set of params for multiple models from hyperopt.  Or does it pass the loss for *each* model that is trained to hyperopt?  If it is the former, then it seems like that might confuse affect hyperband in unknown ways if we are chunking/grouping like in this way.
   
   (7)
   We should re-look at the madlib hyperopt params to see if we have defined them in the right way.  Do we need an option for an explicit `max_evals` ?
   
   (8)
   defaults
   Seems like hyperband defaults are being used for hyperopt in the case that use does not specify hyperband is not specified.


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-716907845


   (100) and (101)
   - error messages look OK now
   
   LGTM after merge conflicts fixed


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r493918605



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -223,10 +231,13 @@ class KerasAutoML():
                                      {ModelArchSchema.MODEL_ARCH} JSON)
                                     """.format(self=self, ModelSelectionSchema=ModelSelectionSchema,
                                                ModelArchSchema=ModelArchSchema)
-        with MinWarning('warning'):
-            plpy.execute(output_table_create_query)
+        # with MinWarning('warning'):

Review comment:
       See above




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] orhankislal commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
orhankislal commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r493747805



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works
+                else:
+                    plpy.error("DL: algorithm in 'automl_params' must be 'rand', 'tpe'") # , or 'atpe'
+            else:
+                plpy.error("DL: {0} is an invalid automl param".format(i))
+        _assert(self.num_models > 0 and self.num_iters > 0, "DL: num_models and num_iters in 'automl_params' "
+                                                            "must be positive")
+        _assert(self._is_valid_metrics_compute_frequency(self.num_iters), "DL: 'metrics_compute_frequency' "
+                                                                          "out of iteration range")
+
+    def find_hyperopt_config(self):
         """
-        Drops and re-create the mst table to only include the best performing model configuration.
+        Executes hyperopt on top of MOP.
         """
-        drop_tables([self.model_selection_table])
 
-        # only retaining best performing config
-        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT mst_key, model_id, compile_params, " \
-                     "fit_params FROM {self.model_info_table} " \
-                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self, AutoMLSchema=AutoMLSchema))
+        make_mst_summary = True
+        trials = Trials()
+        domain = Domain(None, self.get_search_space())
+        rand_state = np.random.RandomState(self.random_state)
+        configs_lst = self.get_configs_list()
 
-    def generate_model_output_summary_table(self, model_training):
+        self.start_training_time = self.get_current_timestamp()
+        for low, high in configs_lst:
+            i, n = low, high - low + 1
+
+            # Using HyperOpt TPE/ATPE to generate parameters
+            hyperopt_params = []
+            sampled_params = []
+            for j in range(i, i + n):
+                new_param = self.algorithm.suggest([j], domain, trials, rand_state.randint(0, 2 ** 31 - 1))
+                new_param[0]['status'] = STATUS_RUNNING
+
+                trials.insert_trial_docs(new_param)
+                trials.refresh()
+                hyperopt_params.append(new_param[0])
+                sampled_params.append(new_param[0]['misc']['vals'])
+
+            model_id_list, compile_params, fit_params = self.extract_param_vals(sampled_params)
+            msts_list = self.generate_msts(model_id_list, compile_params, fit_params)
+            try:
+                self.remove_temp_tables(model_training)
+            except:
+                pass
+            self.populate_temp_mst_table(i, msts_list)
+
+            plpy.info("***Evaluating {n} newly suggested model configurations***".format(n=n))
+            model_training = FitMultipleModel(self.schema_madlib, self.source_table, AutoMLSchema.TEMP_OUTPUT_TABLE,
+                             AutoMLSchema.TEMP_MST_TABLE, self.num_iters, self.use_gpus, self.validation_table,
+                             self.metrics_compute_frequency, False, self.name, self.description)
+            if make_mst_summary:
+                self.generate_mst_summary_table(self.model_selection_summary_table)
+                make_mst_summary = False
+
+            # HyperOpt TPE update
+            for k, hyperopt_param in enumerate(hyperopt_params, i):
+                loss_val = plpy.execute("SELECT {AutoMLSchema.LOSS_METRIC} FROM {model_training.model_info_table} " \
+                             "WHERE {ModelSelectionSchema.MST_KEY}={k}".format(AutoMLSchema=AutoMLSchema,
+                                                                               ModelSelectionSchema=ModelSelectionSchema,
+                                                                               **locals()))[0][AutoMLSchema.LOSS_METRIC]
+
+                hyperopt_param['status'] = STATUS_OK
+                hyperopt_param['result'] = {'loss': loss_val, 'status': STATUS_OK}
+            trials.refresh()
+
+            # stacks info of all model configs together
+            self.update_model_output_and_info_tables(model_training)
+
+            self.print_best_so_far()
+
+        self.end_training_time = self.get_current_timestamp()
+        self.update_model_selection_table()
+        self.generate_model_output_summary_table(model_training)
+        self.remove_temp_tables(model_training)
+
+    def get_configs_list(self):
         """
-        Creates and populates static values related to the AutoML workload.
-        :param model_training: Fit Multiple function call object.
+        Gets schedule to evaluate model configs
+        :return: Model configs evaluation schedule
         """
-        create_query = plpy.prepare("""
-                CREATE TABLE {self.model_summary_table} AS
-                SELECT
-                    $MAD${self.source_table}$MAD$::TEXT AS source_table,
-                    $MAD${self.validation_table}$MAD$::TEXT AS validation_table,
-                    $MAD${self.model_output_table}$MAD$::TEXT AS model,
-                    $MAD${self.model_info_table}$MAD$::TEXT AS model_info,
-                    (SELECT dependent_varname FROM {model_training.model_summary_table})
-                    AS dependent_varname,
-                    (SELECT independent_varname FROM {model_training.model_summary_table})
-                    AS independent_varname,
-                    $MAD${self.model_arch_table}$MAD$::TEXT AS model_arch_table,
-                    $MAD${self.model_selection_table}$MAD$::TEXT AS model_selection_table,
-                    $MAD${self.automl_method}$MAD$::TEXT AS automl_method,
-                    $MAD${self.automl_params}$MAD$::TEXT AS automl_params,
-                    $MAD${self.random_state}$MAD$::TEXT AS random_state,
-                    $MAD${self.object_table}$MAD$::TEXT AS object_table,
-                    {self.use_gpus} AS use_gpus,
-                    (SELECT metrics_compute_frequency FROM {model_training.model_summary_table})::INTEGER 
-                    AS metrics_compute_frequency,
-                    $MAD${self.name}$MAD$::TEXT AS name,
-                    $MAD${self.description}$MAD$::TEXT AS description,
-                    '{self.start_training_time}'::TIMESTAMP AS start_training_time,
-                    '{self.end_training_time}'::TIMESTAMP AS end_training_time,
-                    (SELECT madlib_version FROM {model_training.model_summary_table}) AS madlib_version,
-                    (SELECT num_classes FROM {model_training.model_summary_table})::INTEGER AS num_classes,
-                    (SELECT class_values FROM {model_training.model_summary_table}) AS class_values,
-                    (SELECT dependent_vartype FROM {model_training.model_summary_table}) 
-                    AS dependent_vartype,
-                    (SELECT normalizing_const FROM {model_training.model_summary_table}) 
-                    AS normalizing_const
-            """.format(self=self, model_training=model_training))
+        prop = self.num_models // self.num_workers
+        if prop == 0:
+            return [(1, self.num_models)]
+        lst = [self.num_workers  for _ in range(prop)]
 
-        with MinWarning('warning'):
-            plpy.execute(create_query)
+        # balancing remaining models in initial rounds
+        for i in range(self.num_models - prop * self.num_workers):
+            lst[i%len(lst)] += 1
 
-    def remove_temp_tables(self, model_training):
+        return [(sum(lst[:e])+1, sum(lst[:e])+lst[e]) if e != 0 else (1, lst[e]) for e in range(len(lst))]
+
+    def get_search_space(self):
         """
-        Remove all intermediate tables created for AutoML runs/updates.
-        :param model_training: Fit Multiple function call object.
+        Converts user inputs to hyperopt search space.
+        :return: Hyperopt search space
         """
-        drop_tables([model_training.original_model_output_table, model_training.model_info_table,
-                     model_training.model_summary_table, AutoMLSchema.TEMP_MST_TABLE,
-                     AutoMLSchema.TEMP_MST_SUMMARY_TABLE])
+
+        # initial params (outside 'optimizer_params_list')
+        hyperopt_search_dict = {}
+        hyperopt_search_dict['model_id'] = self.get_hyperopt_exps('model_id', self.model_id_list)
+
+
+        for j in self.fit_params_grid:
+            hyperopt_search_dict[j] = self.get_hyperopt_exps(j, self.fit_params_grid[j])
+
+        for i in self.compile_params_grid:
+            if i == ModelSelectionSchema.OPTIMIZER_PARAMS_LIST:

Review comment:
       Why not use the opposite of the condition to get rid of continue?




----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-700952240


   > (6)
   > fmin definition
   > https://github.com/hyperopt/hyperopt/wiki/FMin
   > fmin(loss, space, algo, max_evals)
   > 
   > Looks like this PR is setting max_evals = num_models/num_segments in `get_configs_list()`. For one thing I'm not sure that
   > 
   > ```
   > self.num_workers = get_seg_number() * get_segments_per_host()
   > ```
   > 
   > gives total number of workers? On a 1 host, 2 segments-per-host database this returned 4 instead of the expected 2. Also this needs to be consistent with the distribution rules set in the mini-batch preprocessor.
   > 
   > (7)
   > The function `get_configs_list()` may not be distributing the workload correctly to the segments.
   > For
   > 
   > ```
   >     num_models = 3
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 3)]` which seems OK. But for
   > 
   > ```
   >     num_models = 5
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 5)]` which does not seem OK. It will not do any hyperopt updates if all 5 configs are grouped together. I would have expected `[(1, 3), (4, 5)]`. For
   > 
   > ```
   >     num_models = 20
   >     num_workers = 3
   > ```
   > 
   > it returns `[(1, 4), (5, 8), (9, 11), (12, 14), (15, 17), (18, 20)]` which means it is running 4 configs on 3 segments multiple times which does not seem efficient. I would have expected something like `[(1, 3), (4, 6), (7, 9), (10, 12), (13, 15), (16, 18),(19, 20)]` which runs 3 configs at a time on the 3 segments.
   > 
   > (8)
   > In `find_hyperopt_config()` confirm that the loss for _each_ model that passed to hyperopt after training, and not just the best one from the group.
   > 
   > (9)
   > defaults
   > Seems like hyperband defaults are being used for hyperopt in the case that use does not specify hyperband is not specified. That will probably throw an error
   
   (7) 
   
   (a) As per my discussions with Domino, the current implementation seems to run more than 1 rounds when `number of models >= 2 * number of segments/workers in the cluster`. Sure, though the latter `[(1, 3), (4, 5)]` may have an idle worker, it may be a better approach for Hyperopt.
   
   (b) In reference to the 2nd example, I believe this was as per our discussions to minimize number of model training function calls. Observe that the former schedule runs 4 configs on 3 workers for 2 rounds/runs and continues with the 3 configs on 3 workers for all other rounds (as 3 doesn't perfectly divide 20). The latter only runs 2 configs on 3 workers at the end which also thus has an idle worker (apart from 1 more model training function call compared to the former approach).
   
   (8) I believe all the losses are already passed on to hyperopt as part of my implementation, in the `Hyperopt TPE Update` for loop.
   
   (9) Yes I did observe that. I tried to change the global defaults in the SQL file as per chosen automl method, but ran into errors in the process. As per my current implementation, the hyperband params are defaults and the user may need to explicitly specify hyperopt params when using hyperopt.
   
   (10) The name changes sound good to me.
   


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698586366


   (4)
   `hyperopt` is not learning with cifar10 in the tests I have done so far with `rand` 
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperopt', 
                                     'num_models=3, num_iters=5, algorithm=rand',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces no-learning result with labels:
   ```
   INFO:  ***Evaluating 3 newly suggested model configurations***
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 659.287541866 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0988999977708, loss=14.5240154266
   	mst_key=2: metric=0.10000000149, loss=nan
   	Validation set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 2: 663.107329845 sec
   DETAIL:  
   	Training set after iteration 2:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   	Validation set after iteration 2:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   CONTEXT:  PL/Python function "madlib_keras_automl"
   etc.
   ```
   When I run `hyperband` with same models/hyperparams, it does learn:
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperband', 
                                     'R=6, eta=3, skip_last=0',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces
   ```
   PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 655.647205114 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.34889999032, loss=1.83796536922
   	mst_key=1: metric=0.468120008707, loss=1.481554389
   	mst_key=2: metric=0.475380003452, loss=1.63904440403
   	Validation set after iteration 1:
   	mst_key=3: metric=0.355800002813, loss=1.83082151413
   	mst_key=1: metric=0.470499992371, loss=1.47972774506
   	mst_key=2: metric=0.470200002193, loss=1.66988003254
   CONTEXT:  PL/Python function "madlib_keras_automl"
   
   etc.
   ```
   Also `hyperopt` with `tpe` is not learning cifar10
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperopt', 
                                     'num_models=3, num_iters=5, algorithm=tpe',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces
   ```
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 648.608314991 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0999400019646, loss=14.5072526932
   	mst_key=2: metric=0.10000000149, loss=14.5062847137
   	Validation set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.10000000149, loss=14.5062856674
   	mst_key=2: metric=0.10000000149, loss=14.5062847137
   CONTEXT:  PL/Python function "madlib_keras_automl"
   ```


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698536437


   These 2 methods seems to want `hyperopt` module installed even if I don't call it.  It should only error out if I select to use `hyperopt` as an autoML method:
   
   - `madlib_keras_automl`
   - `hyperband_schedule`
   
   E.g.,
   ```
   %%sql
   DROP TABLE IF EXISTS hb_schedule;
   SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);
   SELECT * FROM hb_schedule ORDER BY s DESC, i;
   ```
   produces
   ```
   InternalError: (psycopg2.errors.InternalError_) ImportError: No module named hyperopt (plpython.c:5038)
   CONTEXT:  Traceback (most recent call last):
     PL/Python function "hyperband_schedule", line 7, in <module>
       from deep_learning import madlib_keras_automl
     PL/Python function "hyperband_schedule", line 21, in <module>
   PL/Python function "hyperband_schedule"
   
   [SQL: SELECT madlib.hyperband_schedule ('hb_schedule', 
                                      6,
                                      3,
                                      0);]
   ```
   
   Same happens with `madlib_keras_automl` when I select `hyperband` as the method I want


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-698586366


   (4)
   `hyperopt` is not learning in the tests I have done so far with `rand` 
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperopt', 
                                     'num_models=3, num_iters=5, algorithm=rand',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces no-learning result with labels:
   ```
   INFO:  ***Evaluating 3 newly suggested model configurations***
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 659.287541866 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0988999977708, loss=14.5240154266
   	mst_key=2: metric=0.10000000149, loss=nan
   	Validation set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 2: 663.107329845 sec
   DETAIL:  
   	Training set after iteration 2:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   	Validation set after iteration 2:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0989999994636, loss=14.5224027634
   	mst_key=2: metric=0.10000000149, loss=nan
   CONTEXT:  PL/Python function "madlib_keras_automl"
   etc.
   ```
   When I run `hyperband` with same models/hyperparams, it does learn:
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperband', 
                                     'R=6, eta=3, skip_last=0',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces
   ```
   PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 655.647205114 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.34889999032, loss=1.83796536922
   	mst_key=1: metric=0.468120008707, loss=1.481554389
   	mst_key=2: metric=0.475380003452, loss=1.63904440403
   	Validation set after iteration 1:
   	mst_key=3: metric=0.355800002813, loss=1.83082151413
   	mst_key=1: metric=0.470499992371, loss=1.47972774506
   	mst_key=2: metric=0.470200002193, loss=1.66988003254
   CONTEXT:  PL/Python function "madlib_keras_automl"
   
   etc.
   ```
   Also `hyperopt` with `tpe` is not learning cifar10
   ```
   SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
                                     'automl_cifar10_output', 
                                     'model_arch_library', 
                                     'automl_cifar10_mst_table',
                                     ARRAY[1,2,3], 
                                     $${'loss': ['categorical_crossentropy'], 
                                        'optimizer_params_list': [ 
                                            {'optimizer': ['Adam'],'lr': [0.0001, 0.01, 'log']},
                                            {'optimizer': ['RMSprop'],'lr': [0.0001, 0.01, 'log'], 'decay': [1.0e-7, 1.0e-5, 'log']},
                                            {'optimizer': ['SGD'],'lr': [0.0001, 0.01, 'log'], 'momentum': [0.9, 0.99,'log']}],
                                        'metrics':['accuracy']}$$, 
                                     $${'batch_size': [64,128], 'epochs': [1]}$$,
                                     'hyperopt', 
                                     'num_models=3, num_iters=5, algorithm=tpe',
                                     NULL,                    -- random state
                                     NULL,                  -- object table
                                     FALSE,                 -- use GPUs
                                     'cifar10_val_packed', -- validation table
                                     1,                     -- metrics compute freq
                                     NULL,                  -- name
                                     NULL);                 -- descr
   ```
   produces
   ```
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 648.608314991 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.0999400019646, loss=14.5072526932
   	mst_key=2: metric=0.10000000149, loss=14.5062847137
   	Validation set after iteration 1:
   	mst_key=3: metric=0.10000000149, loss=nan
   	mst_key=1: metric=0.10000000149, loss=14.5062856674
   	mst_key=2: metric=0.10000000149, loss=14.5062847137
   CONTEXT:  PL/Python function "madlib_keras_automl"
   ```


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 edited a comment on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 edited a comment on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-707417107


   Let's be consistent with the output for hyperband and add it to the info table, even if the value will be the same for all mst keys.  The table is small so that is not a problem and it may change in the future if we learn something new about how `metrics_iters` should be presented.
    


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] fmcquillan99 commented on pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
fmcquillan99 commented on pull request #518:
URL: https://github.com/apache/madlib/pull/518#issuecomment-699088843


   (5)
   In this test the 2nd batch is worse than the 1st batch:
   ```
   madlib=# SELECT madlib.madlib_keras_automl('cifar10_train_packed', 
   madlib(#                                   'automl_cifar10_output', 
   madlib(#                                   'model_arch_library', 
   madlib(#                                   'automl_cifar10_mst_table',
   madlib(#                                   ARRAY[1,2], 
   madlib(#                                   $${'loss': ['categorical_crossentropy'], 
   madlib$#                                      'optimizer_params_list': [ 
   madlib$#                                          {'optimizer': ['Adam'],'lr': [0.0005, 0.01, 'log']},
   madlib$#                                          {'optimizer': ['SGD'],'lr': [0.001, 0.01, 'log'], 'momentum': [0.90, 0.91,'log']}],
   madlib$#                                      'metrics':['accuracy']}$$, 
   madlib(#                                   $${'batch_size': [64,128], 'epochs': [1]}$$,
   madlib(#                                   'hyperopt', 
   madlib(#                                   'num_models=10, num_iters=2, algorithm=tpe',
   madlib(#                                   NULL,                    -- random state
   madlib(#                                   NULL,                  -- object table
   madlib(#                                   FALSE,                 -- use GPUs
   madlib(#                                   'cifar10_val_packed', -- validation table
   madlib(#                                   1,                     -- metrics compute freq
   madlib(#                                   NULL,                  -- name
   madlib(#                                   NULL);                 -- descr
   
   
   INFO:  
   	Time for training in iteration 1: 1070.08548617 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=1: metric=0.526019990444, loss=1.5796225071
   	mst_key=5: metric=0.562780022621, loss=1.37457168102
   	mst_key=4: metric=0.65314000845, loss=0.969262957573
   	mst_key=2: metric=0.10000000149, loss=2.30277729034
   	mst_key=3: metric=0.464760005474, loss=1.50251471996
   	Validation set after iteration 1:
   	mst_key=1: metric=0.523299992085, loss=1.60135388374
   	mst_key=5: metric=0.559000015259, loss=1.40086007118
   	mst_key=4: metric=0.640600025654, loss=1.00141870975
   	mst_key=2: metric=0.10000000149, loss=2.30277705193
   	mst_key=3: metric=0.463400006294, loss=1.50355136395
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 2: 1064.05229688 sec
   DETAIL:  
   	Training set after iteration 2:
   	mst_key=1: metric=0.703299999237, loss=0.840497553349
   	mst_key=5: metric=0.664420008659, loss=0.98249232769
   	mst_key=4: metric=0.754859983921, loss=0.701396882534
   	mst_key=2: metric=0.10000000149, loss=2.30290770531
   	mst_key=3: metric=0.535520017147, loss=1.26898431778
   	Validation set after iteration 2:
   	mst_key=1: metric=0.68900001049, loss=0.903733193874
   	mst_key=5: metric=0.653800010681, loss=1.02747094631
   	mst_key=4: metric=0.735899984837, loss=0.765290260315
   	mst_key=2: metric=0.10000000149, loss=2.30290770531
   	mst_key=3: metric=0.530799984932, loss=1.28327465057
   CONTEXT:  PL/Python function "madlib_keras_automl"
   
   INFO:  
   Best training loss so far:
   DETAIL:  
   mst_key=4: metric=0.754859983921, loss=0.701396882534
   Best validation loss so far:
   mst_key=4: metric=0.735899984837, loss=0.765290260315
   
   
   
   INFO:  ***Evaluating 5 newly suggested model configurations***
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 1: 1058.9834702 sec
   DETAIL:  
   	Training set after iteration 1:
   	mst_key=6: metric=0.553560018539, loss=1.41088056564
   	mst_key=10: metric=0.353260010481, loss=1.84440767765
   	mst_key=9: metric=0.519379973412, loss=1.35283255577
   	mst_key=7: metric=0.517820000648, loss=1.31637942791
   	mst_key=8: metric=0.51289999485, loss=1.32810485363
   	Validation set after iteration 1:
   	mst_key=6: metric=0.547699987888, loss=1.44565415382
   	mst_key=10: metric=0.358599990606, loss=1.83988237381
   	mst_key=9: metric=0.518999993801, loss=1.36131703854
   	mst_key=7: metric=0.515799999237, loss=1.32058382034
   	mst_key=8: metric=0.507099986076, loss=1.33919155598
   CONTEXT:  PL/Python function "madlib_keras_automl"
   INFO:  
   	Time for training in iteration 2: 1072.08968186 sec
   DETAIL:  
   	Training set after iteration 2:
   	mst_key=6: metric=0.435039997101, loss=1.98741734028
   	mst_key=10: metric=0.437579989433, loss=1.54891061783
   	mst_key=9: metric=0.606719970703, loss=1.1007784605
   	mst_key=7: metric=0.550220012665, loss=1.23340415955
   	mst_key=8: metric=0.590960025787, loss=1.13847112656
   	Validation set after iteration 2:
   	mst_key=6: metric=0.424100011587, loss=2.0407743454
   	mst_key=10: metric=0.438899993896, loss=1.54700648785
   	mst_key=9: metric=0.595899999142, loss=1.13602638245
   	mst_key=7: metric=0.544099986553, loss=1.24483549595
   	mst_key=8: metric=0.583800017834, loss=1.15895962715
   CONTEXT:  PL/Python function "madlib_keras_automl"
   
   INFO:  
   Best training loss so far:
   DETAIL:  
   mst_key=4: metric=0.754859983921, loss=0.701396882534
   Best validation loss so far:
   mst_key=4: metric=0.735899984837, loss=0.765290260315
   ```


----------------------------------------------------------------
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:
users@infra.apache.org



[GitHub] [madlib] Advitya17 commented on a change in pull request #518: DL: [AutoML] Add support for Hyperopt on top of MOP for MPP + AutoML best-so-far

Posted by GitBox <gi...@apache.org>.
Advitya17 commented on a change in pull request #518:
URL: https://github.com/apache/madlib/pull/518#discussion_r493918741



##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -291,9 +338,100 @@ class KerasAutoML():
                (self.metrics_compute_frequency >= 1 and \
                 self.metrics_compute_frequency <= num_iterations)
 
+    def print_best_so_far(self):
+        """
+        Prints mst keys with best train/val losses at a given point.
+        """
+        best_so_far = '\n'
+        best_so_far += self.print_best_helper('training')
+        if self.validation_table:
+            best_so_far += self.print_best_helper('validation')
+        plpy.info(best_so_far)
+
+    def print_best_helper(self, keyword):
+        """
+        Helper function to Prints mst keys with best train/val losses at a given point.
+        :param keyword: column prefix ('training' or 'validation')
+        :return:
+        """
+        metrics_word, loss_word = keyword + '_metrics_final', keyword + '_loss_final'
+
+        res_str = 'Best {keyword} loss so far:\n'.format(keyword=keyword)
+        best_value = plpy.execute("SELECT {ModelSelectionSchema.MST_KEY}, {metrics_word}, " \
+                                  "{loss_word} FROM {self.model_info_table} ORDER BY " \
+                                  "{loss_word} LIMIT 1".format(self=self, ModelSelectionSchema=ModelSelectionSchema,
+                                                               metrics_word=metrics_word, loss_word=loss_word))[0]
+        mst_key_value, metric_value, loss_value = best_value[ModelSelectionSchema.MST_KEY], \
+                                                  best_value[metrics_word], best_value[loss_word]
+        res_str += ModelSelectionSchema.MST_KEY + '=' + str(mst_key_value) + ': metric=' + str(metric_value) + \
+                   ', loss=' + str(loss_value) + '\n'
+        return res_str
+
+    def get_current_timestamp(self):
+        """for start and end times for the chosen AutoML algorithm. Showcased in the output summary table"""
+        return datetime.fromtimestamp(time()).strftime('%Y-%m-%d %H:%M:%S')
+
+    def remove_temp_tables(self, model_training):
+        """
+        Remove all intermediate tables created for AutoML runs/updates.
+        :param model_training: Fit Multiple function call object.
+        """
+        drop_tables([model_training.original_model_output_table, model_training.model_info_table,
+                     model_training.model_summary_table, AutoMLSchema.TEMP_MST_TABLE,
+                     AutoMLSchema.TEMP_MST_SUMMARY_TABLE])
+
+# @MinWarning("warning")
+class AutoMLHyperband(KerasAutoML):
+    """
+    This class implements Hyperband, an infinite-arm bandit based algorithm that speeds up random search
+    through adaptive resource allocation, successive halving (SHA) and early stopping.
+
+    This class showcases and novel hyperband implementation by executing the hyperband rounds 'diagonally'

Review comment:
       I think I just need to add a comma like this: `through adaptive resource allocation, successive halving (SHA), and early stopping`

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -404,24 +544,30 @@ class KerasAutoML():
                                   model_id=ModelSelectionSchema.MODEL_ID,
                                   compile_params=ModelSelectionSchema.COMPILE_PARAMS,
                                   fit_params=ModelSelectionSchema.FIT_PARAMS)
-        with MinWarning('warning'):
-            plpy.execute(create_query)
+        # with MinWarning('warning'):

Review comment:
       See above

##########
File path: src/ports/postgres/modules/deep_learning/madlib_keras_automl.py_in
##########
@@ -500,63 +648,432 @@ class KerasAutoML():
                 "b (key integer, s_val integer, i_val integer) WHERE t.mst_key=b.key".format(self=self, l=l)
         plpy.execute(query)
 
-    def update_model_selection_table(self):
+# @MinWarning("warning")
+class AutoMLHyperopt(KerasAutoML):
+    """
+    This class implements Hyperopt, another automl method that explores awkward search spaces using
+    Random Search, Tree-structured Parzen Estimator (TPE), or Adaptive TPE.
+
+    This function executes hyperopt on top of our multiple model training infrastructure powered with
+    Model hOpper Parallelism (MOP), a hybrid of data and task parallelism.
+
+    This automl method inherits qualities from the automl class.
+    """
+    def __init__(self, schema_madlib, source_table, model_output_table, model_arch_table, model_selection_table,
+                 model_id_list, compile_params_grid, fit_params_grid, automl_method='hyperopt',
+                 automl_params='num_models=20, num_iters=5, algorithm=tpe', random_state=None, object_table=None,
+                 use_gpus=False, validation_table=None, metrics_compute_frequency=None,
+                 name=None, description=None, **kwargs):
+        KerasAutoML.__init__(self, schema_madlib, source_table, model_output_table, model_arch_table,
+                             model_selection_table, model_id_list, compile_params_grid, fit_params_grid,
+                             automl_method, automl_params, random_state, object_table, use_gpus,
+                             validation_table, metrics_compute_frequency, name, description, **kwargs)
+        self.compile_params_grid = self.compile_params_grid.replace('\n', '').replace(' ', '')
+        self.fit_params_grid = self.fit_params_grid.replace('\n', '').replace(' ', '')
+        try:
+            self.compile_params_grid = literal_eval(self.compile_params_grid)
+
+        except:
+            plpy.error("Invalid syntax in 'compile_params_dict'")
+        try:
+            self.fit_params_grid = literal_eval(self.fit_params_grid)
+        except:
+            plpy.error("Invalid syntax in 'fit_params_dict'")
+        self.validate_and_define_inputs()
+
+        self.num_workers = get_seg_number() * get_segments_per_host()
+
+        self.create_model_output_table()
+        self.create_model_output_info_table()
+        self.find_hyperopt_config()
+
+    def validate_and_define_inputs(self):
+        automl_params_dict = extract_keyvalue_params(self.automl_params,
+                                                     default_values={'num_models': 20,
+                                                                     'num_iters': 5,
+                                                                     'algorithm': 'tpe'},
+                                                     lower_case_names=True)
+        # casting relevant values to int
+        for i in automl_params_dict:
+            try:
+                automl_params_dict[i] = int(automl_params_dict[i])
+            except ValueError:
+                pass
+        _assert(len(automl_params_dict) >= 1 and len(automl_params_dict) <= 3,
+                "DL: Only num_models, num_iters, and algorithm may be specified")
+        for i in automl_params_dict:
+            if i == AutoMLSchema.NUM_MODELS:
+                self.num_models = automl_params_dict[AutoMLSchema.NUM_MODELS]
+            elif i == AutoMLSchema.NUM_ITERS:
+                self.num_iters = automl_params_dict[AutoMLSchema.NUM_ITERS]
+            elif i == AutoMLSchema.ALGORITHM:
+                if automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'rand':
+                    self.algorithm = rand
+                elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'tpe':
+                    self.algorithm = tpe
+                # elif automl_params_dict[AutoMLSchema.ALGORITHM].lower() == 'atpe':
+                #     self.algorithm = atpe
+                # uncomment the above lines after atpe works
+                else:
+                    plpy.error("DL: algorithm in 'automl_params' must be 'rand', 'tpe'") # , or 'atpe'
+            else:
+                plpy.error("DL: {0} is an invalid automl param".format(i))
+        _assert(self.num_models > 0 and self.num_iters > 0, "DL: num_models and num_iters in 'automl_params' "
+                                                            "must be positive")
+        _assert(self._is_valid_metrics_compute_frequency(self.num_iters), "DL: 'metrics_compute_frequency' "
+                                                                          "out of iteration range")
+
+    def find_hyperopt_config(self):
         """
-        Drops and re-create the mst table to only include the best performing model configuration.
+        Executes hyperopt on top of MOP.
         """
-        drop_tables([self.model_selection_table])
 
-        # only retaining best performing config
-        plpy.execute("CREATE TABLE {self.model_selection_table} AS SELECT mst_key, model_id, compile_params, " \
-                     "fit_params FROM {self.model_info_table} " \
-                     "ORDER BY {AutoMLSchema.LOSS_METRIC} LIMIT 1".format(self=self, AutoMLSchema=AutoMLSchema))
+        make_mst_summary = True
+        trials = Trials()
+        domain = Domain(None, self.get_search_space())
+        rand_state = np.random.RandomState(self.random_state)
+        configs_lst = self.get_configs_list()
 
-    def generate_model_output_summary_table(self, model_training):
+        self.start_training_time = self.get_current_timestamp()
+        for low, high in configs_lst:
+            i, n = low, high - low + 1
+
+            # Using HyperOpt TPE/ATPE to generate parameters
+            hyperopt_params = []
+            sampled_params = []
+            for j in range(i, i + n):
+                new_param = self.algorithm.suggest([j], domain, trials, rand_state.randint(0, 2 ** 31 - 1))
+                new_param[0]['status'] = STATUS_RUNNING
+
+                trials.insert_trial_docs(new_param)
+                trials.refresh()
+                hyperopt_params.append(new_param[0])
+                sampled_params.append(new_param[0]['misc']['vals'])
+
+            model_id_list, compile_params, fit_params = self.extract_param_vals(sampled_params)
+            msts_list = self.generate_msts(model_id_list, compile_params, fit_params)
+            try:
+                self.remove_temp_tables(model_training)
+            except:
+                pass
+            self.populate_temp_mst_table(i, msts_list)
+
+            plpy.info("***Evaluating {n} newly suggested model configurations***".format(n=n))
+            model_training = FitMultipleModel(self.schema_madlib, self.source_table, AutoMLSchema.TEMP_OUTPUT_TABLE,
+                             AutoMLSchema.TEMP_MST_TABLE, self.num_iters, self.use_gpus, self.validation_table,
+                             self.metrics_compute_frequency, False, self.name, self.description)
+            if make_mst_summary:
+                self.generate_mst_summary_table(self.model_selection_summary_table)
+                make_mst_summary = False
+
+            # HyperOpt TPE update
+            for k, hyperopt_param in enumerate(hyperopt_params, i):
+                loss_val = plpy.execute("SELECT {AutoMLSchema.LOSS_METRIC} FROM {model_training.model_info_table} " \
+                             "WHERE {ModelSelectionSchema.MST_KEY}={k}".format(AutoMLSchema=AutoMLSchema,
+                                                                               ModelSelectionSchema=ModelSelectionSchema,
+                                                                               **locals()))[0][AutoMLSchema.LOSS_METRIC]
+
+                hyperopt_param['status'] = STATUS_OK

Review comment:
       Yeah it's apparently used internally by the hyperopt module during `refresh`.




----------------------------------------------------------------
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:
users@infra.apache.org