def test_unpickle_key(): fd, fname = tempfile.mkstemp() with os.fdopen(fd, 'wb') as f: d = ('a', 1) cPickle.dump(d, f) loaded = load("{!pkl: '%s': 50}" % fname) assert_(first_key(loaded) == d) assert_(first_value(loaded) == 50) os.remove(fname)
def setup(self, model, dataset): """ Allows the training algorithm to do some preliminary configuration *before* we actually start training the model. The dataset is provided in case other derived training algorithms need to modify model based on the dataset. Parameters ---------- model : object A Python object representing the model to train. Loosely implementing the interface of models.model.Model. dataset : pylearn2.datasets.dataset.Dataset Dataset object used to draw training data """ self.model = model if self.cost is None: self.cost = model.get_default_cost() try: if self.cost.is_stochastic(): raise TypeError("BGD is not compatible with stochastic " "costs.") except NotImplementedError: warnings.warn("BGD is not compatible with stochastic costs " "and cannot determine whether the current cost is " "stochastic.") if self.batch_size is None: self.batch_size = model.force_batch_size else: batch_size = self.batch_size if self.set_batch_size: model.set_batch_size(batch_size) elif hasattr(model, 'force_batch_size'): if not (model.force_batch_size is None or model.force_batch_size <= 0 or batch_size == model.force_batch_size): raise ValueError("batch_size is %d but " + "model.force_batch_size is %d" % (batch_size, model.force_batch_size)) self.monitor = Monitor.get_monitor(model) self.monitor.set_theano_function_mode(self.theano_function_mode) data_specs = self.cost.get_data_specs(model) mapping = DataSpecsMapping(data_specs) space_tuple = mapping.flatten(data_specs[0], return_tuple=True) source_tuple = mapping.flatten(data_specs[1], return_tuple=True) # Build a flat tuple of Theano Variables, one for each space, # named according to the sources. theano_args = [] for space, source in safe_zip(space_tuple, source_tuple): name = 'BGD_[%s]' % source arg = space.make_theano_batch(name=name) theano_args.append(arg) theano_args = tuple(theano_args) # Methods of `self.cost` need args to be passed in a format compatible # with their data_specs nested_args = mapping.nest(theano_args) fixed_var_descr = self.cost.get_fixed_var_descr(model, nested_args) self.on_load_batch = fixed_var_descr.on_load_batch cost_value = self.cost.expr(model, nested_args, ** fixed_var_descr.fixed_vars) grads, grad_updates = self.cost.get_gradients( model, nested_args, ** fixed_var_descr.fixed_vars) assert isinstance(grads, OrderedDict) assert isinstance(grad_updates, OrderedDict) if cost_value is None: raise ValueError("BGD is incompatible with " + str(self.cost) + " because it is intractable, but BGD uses the " + "cost function value to do line searches.") # obj_prereqs has to be a list of function f called with f(*data), # where data is a data tuple coming from the iterator. # this function enables capturing "mapping" and "f", while # enabling the "*data" syntax def capture(f, mapping=mapping): new_f = lambda *args: f(mapping.flatten(args, return_tuple=True)) return new_f obj_prereqs = [capture(f) for f in fixed_var_descr.on_load_batch] if self.monitoring_dataset is not None: if (self.monitoring_batch_size is None and self.monitoring_batches is None): self.monitoring_batch_size = self.batch_size self.monitoring_batches = self.batches_per_iter self.monitor.setup( dataset=self.monitoring_dataset, cost=self.cost, batch_size=self.monitoring_batch_size, num_batches=self.monitoring_batches, obj_prereqs=obj_prereqs, cost_monitoring_args=fixed_var_descr.fixed_vars) params = model.get_params() self.optimizer = BatchGradientDescent( objective=cost_value, gradients=grads, gradient_updates=grad_updates, params=params, param_constrainers=[model.modify_updates], lr_scalers=model.get_lr_scalers(), inputs=theano_args, verbose=self.verbose_optimization, max_iter=self.updates_per_batch, reset_alpha=self.reset_alpha, conjugate=self.conjugate, reset_conjugate=self.reset_conjugate, min_init_alpha=self.min_init_alpha, line_search_mode=self.line_search_mode, theano_function_mode=self.theano_function_mode, init_alpha=self.init_alpha) # These monitoring channels keep track of shared variables, # which do not need inputs nor data. if self.monitoring_dataset is not None: self.monitor.add_channel( name='ave_step_size', ipt=None, val=self.optimizer.ave_step_size, data_specs=(NullSpace(), ''), dataset=first_value(self.monitoring_dataset)) self.monitor.add_channel( name='ave_grad_size', ipt=None, val=self.optimizer.ave_grad_size, data_specs=(NullSpace(), ''), dataset=first_value(self.monitoring_dataset)) self.monitor.add_channel( name='ave_grad_mult', ipt=None, val=self.optimizer.ave_grad_mult, data_specs=(NullSpace(), ''), dataset=first_value(self.monitoring_dataset)) self.first = True self.bSetup = True