def resolve_ref(element, element_dict): if element is None: return None if '@ref' in element: ref = element['@ref'] logging.debug("Resolving reference: %s %s", ref, element) if ref in element_dict: for parent_key, parent_value in element_dict[ref].items(): if parent_key not in element: # Supply default if not present element[parent_key] = parent_value else: # if key is present, check that all the entries match in name parent_names = set((subelem['@name'] for subelem in force_list(parent_value) if '@name' in subelem)) child_names = set((subelem['@name'] for subelem in force_list(element[parent_key]) if '@name' in subelem)) parent_diff = parent_names.difference(child_names) # if there are named sub-elements in the parent that aren't in the child, # copy them. if len(parent_diff) > 0: subelem_to_copy = [subelem for subelem in force_list(parent_value) if subelem['@name'] in parent_diff] element[parent_key] = force_list(element[parent_key]) + subelem_to_copy else: logging.warn("Unresolved reference %s not found in configuration input", ref) element['error'] = "unresolved reference" return element
def process_alg_parameters(self, alg): """ Processes an algorithm element checking for iteration parameters. Expands at most one, creating multiple subexperiments in the process :param alg: :return: list of algorithms, possibly expanded """ iteration_params = list(itertools.ifilter(lambda (par): safe_xml_path(par, ['@from']), force_list(alg['param']))) other_params = list(itertools.ifilter(lambda (par): not safe_xml_path(par, ['@from']), force_list(alg['param']))) if len(iteration_params) > 1: logging.error("Multiple iteration parameters: %s. Ignoring all but first.", alg['@name']) bad_params = [self.create_iter_elems(param, True) for param in iteration_params[1:]] iteration_params = iteration_params[0:1] other_params = other_params + list(itertools.chain(*bad_params)) # At this point there should only be a maximum of a single iteration parameter. It could be ill-formed. if len(iteration_params) != 0: iter_elems = Config.create_iter_elems(iteration_params[0], False) alg_expand = [] for iter_elem in iter_elems: params = list(other_params).append(iter_elem) # Need to make a copy new_alg = {'@name': alg['@name'], 'param': params} alg_expand.append(new_alg) else: alg_expand = [alg] return alg_expand
def build_exps(self, config_dict): """ Builds the experiment elements. The steps of each experiment will not have been completely resolved in resolve_refs because they are one level deeper in the dictionary. The complexity here comes from handling the possibility of iteration and the ability to run several algorithms at once, which requires that an experiment be split into several sub-experiments. Canonical naming of these sub-experiments is non-trivial, so I am just numbering them, but in the end, this will mean that some experiment changes, like changing the iteration range of a parameter are probably best handled through creating new experiments. Hmm. :param config_dict: :return: """ exps = config_dict['exp'] for eid, exp in exps.items(): data_elem = exp['data'] split_elem = exp['splitter'] alg_elems = force_list(exp['alg']) # Optional elements if safe_xml_path(exp, ["xform"]): xform_elem = exp['xform'] else: xform_elem = None if safe_xml_path(exp, ["metric"]): metric_elems = force_list(exp['metric']) else: metric_elems = [] if safe_xml_path(exp, ["post"]): post_elems = force_list(exp['post']) else: post_elems = [] data_elem = self.resolve_ref(data_elem, config_dict['data']) xform_elem = self.resolve_ref(xform_elem, config_dict['xform']) split_elem = self.resolve_ref(split_elem, config_dict['splitter']) alg_elems = [self.resolve_ref(alg_elem, config_dict['alg']) for alg_elem in alg_elems] metric_elems = [self.resolve_ref(metric_elem, config_dict['metric']) for metric_elem in metric_elems] post_elems = [self.resolve_ref(post_elem, config_dict['post-process']) for post_elem in post_elems] alg_elems = self.expand_iterations(alg_elems) # Create create new experiment ids if there are multiple algorithms. if len(alg_elems) == 1: self.set_experiment_entry(eid, data_elem, xform_elem, split_elem, alg_elems[0], metric_elems, post_elems) else: exp_subids = ["{}-{}".format(eid, i) for i in range(0, len(alg_elems))] # Create sub-experiments for multiple algorithms # The sub-experiments each have their own dictionary entries. The original experiment is replaced # by a list of references. The idea is that if you run that, you are effectively running the collection # of the others. for i in range(0, len(alg_elems)): self.set_experiment_entry(exp_subids[i], data_elem, xform_elem, split_elem, alg_elems[i], metric_elems, post_elems) sub_exp_refs = [{'@ref': subid} for subid in exp_subids] self._exp_dict[eid] = sub_exp_refs
def predict(self, inputs, outputs=None): """ Run a forward pass of the network using the given input :param inputs: The input for the network :param outputs: The output for the network, defaults to self.outputs :return: The network output WARNING: must only call once per state since each call is assumed by LSTM to be a new time step. """ feed_dict = dict(zip(self.inputs, force_list(inputs))) if outputs is None: outputs = self.outputs if self.tp.agent.middleware_type == MiddlewareTypes.LSTM: feed_dict[self.middleware_embedder.c_in] = self.curr_rnn_c_in feed_dict[self.middleware_embedder.h_in] = self.curr_rnn_h_in output, (self.curr_rnn_c_in, self.curr_rnn_h_in) = self.tp.sess.run( [outputs, self.middleware_embedder.state_out], feed_dict=feed_dict) else: output = self.tp.sess.run(outputs, feed_dict) return squeeze_list(output)
def _take_action(self, action_idx): if action_idx is None: action_idx = self.last_action_idx if self.discrete_controls: action = self.actions[action_idx] else: action = action_idx # pendulum-v0 for example expects a list if not self.discrete_controls: # catching cases where the action for continuous control is a number instead of a list the # size of the action space if type(action_idx) == int and action_idx == 0: # deal with the "reset" action 0 action = [0] * self.env.action_space.shape[0] action = np.array(force_list(action)) # removing redundant dimensions such that the action size will match the expected action size from gym if action.shape != self.env.action_space.shape: action = np.squeeze(action) action = np.clip(action, self.action_space_low, self.action_space_high) state, self.reward, self.done, self.info = self.env.step(action) self.state = self._wrap_state(state)
def print_status(exp_path): try: status_dict = utils.xml_load_from_path(exp_path)['librec-auto-status'] print "Experiment", status_dict['exp-no'], ": ", status_dict[ 'message'], " at ", status_dict['date'] for param in utils.force_list(status_dict['param']): print " ", param['name'], ":", param['value'] except: print("Error reading status for" + exp_path)
def __init__(self, tuning_parameters, head_idx=0, loss_weight=1., is_local=True): self.head_idx = head_idx self.name = "head" self.output = [] self.loss = [] self.loss_type = [] self.regularizations = [] self.loss_weight = force_list(loss_weight) self.target = [] self.input = [] self.is_local = is_local
def train_on_batch(self, inputs, targets, scaler=1., additional_fetches=None): """ Given a batch of examples and targets, runs a forward pass & backward pass and then applies the gradients :param additional_fetches: Optional tensors to fetch during the training process :param inputs: The input for the network :param targets: The targets corresponding to the input batch :param scaler: A scaling factor that allows rescaling the gradients before applying them :return: The loss of the network """ if additional_fetches is None: additional_fetches = [] force_list(additional_fetches) loss = self.accumulate_gradients(inputs, targets, additional_fetches=additional_fetches) self.apply_and_reset_gradients(self.accumulated_gradients, scaler) return loss
def __call__(self, input_layer): """ Wrapper for building the module graph including scoping and loss creation :param input_layer: the input to the graph :return: the output of the last layer and the target placeholder """ with tf.variable_scope( self.get_name(), initializer=tf.contrib.layers.xavier_initializer()): self._build_module(input_layer) self.output = force_list(self.output) self.target = force_list(self.target) self.input = force_list(self.input) self.loss_type = force_list(self.loss_type) self.loss = force_list(self.loss) self.regularizations = force_list(self.regularizations) if self.is_local: self.set_loss() self._post_build() if self.is_local: return self.output, self.target, self.input else: return self.output, self.input
def step(self, action_idx): if action_idx is None: action_idx = self.last_action_idx self.last_action_idx = action_idx if self.discrete_controls: action = self.actions[action_idx] else: action = action_idx if hasattr(self.env.env, 'ale'): prev_ale_lives = self.env.env.ale.lives() # pendulum-v0 for example expects a list if not self.discrete_controls: # catching cases where the action for continuous control is a number instead of a list the # size of the action space if type(action_idx) == int and action_idx == 0: # deal with the "reset" action 0 action = [0] * self.env.action_space.shape[0] action = np.array(force_list(action)) # removing redundant dimensions such that the action size will match the expected action size from gym if action.shape != self.env.action_space.shape: action = np.squeeze(action) action = np.clip(action, self.action_space_low, self.action_space_high) self.observation, self.reward, self.done, self.info = self.env.step( action) if hasattr(self.env.env, 'ale') and self.phase == RunPhase.TRAIN: # signal termination for breakout life loss if prev_ale_lives != self.env.env.ale.lives(): self.done = True if any(env in self.env_id for env in ["Breakout", "Pong"]): # crop image self.observation = self.observation[34:195, :, :] if self.is_rendered: self.render() return { 'observation': self.observation, 'reward': self.reward, 'done': self.done, 'action': self.last_action_idx, 'info': self.info }
def __init__(self, tuning_parameters, head_idx=0, loss_weight=1., is_local=True): self.head_idx = head_idx self.name = "head" self.output = [] self.loss = [] self.loss_type = [] self.regularizations = [] self.loss_weight = force_list(loss_weight) self.weights_init = neon.GlorotInit() self.biases_init = neon.ConstantInit() self.target = [] self.input = [] self.is_local = is_local self.batch_size = tuning_parameters.batch_size
def main(): capture = Capture(schema='camara_v1', ) base_url = 'http://www.camara.leg.br/SitCamaraWS/Proposicoes.asmx/ObterVotacaoProposicao?tipo={tipo}&numero={numero}&ano={ano}' url_and_ids, numero_captura = urls_generator(capture, base_url) for url, id_proposicao in url_and_ids: print('----') print(url) # capture data with this try: capture.capture_data(url) data_proposicao = capture.data['proposicao'] data_generic = data_proposicao['Votacoes']['Votacao'] for data_votacao in force_list(data_generic): # orientacao try: print() print('orientacao') data_list = data_votacao['orientacaoBancada']['bancada'] data_list = capture.to_default_dict(data_list) data_list = from_api_to_db_votacao_orientacao( data_list, url, data_proposicao, data_votacao, id_proposicao, numero_captura) capture.insert_data( data_list, table_name='votacao_proposicao_orientacao') except KeyError: pass # deputados print() print('deputados') data_list = data_votacao['votos']['Deputado'] data_list = capture.to_default_dict(data_list) data_list = from_api_to_db_votacao_deputado( data_list, url, data_proposicao, data_votacao, id_proposicao) capture.insert_data(data_list, table_name='votacao_proposicao') except: continue
def predict(self, inputs): """ Run a forward pass of the network using the given input :param inputs: The input for the network :return: The network output """ feed_dict = dict(zip(self.inputs, force_list(inputs))) if self.tp.agent.middleware_type == MiddlewareTypes.LSTM: feed_dict[self.middleware_embedder.c_in] = self.curr_rnn_c_in feed_dict[self.middleware_embedder.h_in] = self.curr_rnn_h_in output, (self.curr_rnn_c_in, self.curr_rnn_h_in) = self.tp.sess.run( [self.outputs, self.middleware_embedder.state_out], feed_dict=feed_dict) else: output = self.tp.sess.run(self.outputs, feed_dict) return squeeze_list(output)
def parse_config(self, config_data): """ Parses the raw configuration dictionary and returns the system-specific data structure. The configuration specification fills out the six entries in the config dictionary: _data_dict _xform_dict _splitter_dict _alg_dict _post_dict _metric_dict _exp_dict If <include> elements are encountered, these are recursively loaded and parsed. Multiple levels of include are not supported. """ raw_configs = [config_data] config_dict = {} if self._XML_HEAD not in config_data: # Incorrect XML logging.warning("XML input is not a librec-auto configuration file.") return config_dict if 'include' in config_data[self._XML_HEAD]: # Get include references for incl in force_list(config_data[self._XML_HEAD]['include']): raw_configs.append(Config._load_from_file(incl)) logging.info("Include file %s loaded.", incl) for element in self._ELEMENTS: logging.debug("Creating entries for element: %s", element) named_elements = Config.create_named(element, raw_configs) resolved_elements = Config.resolve_refs(named_elements) config_dict[element] = resolved_elements self.build_exps(config_dict) return config_dict
def create_named(element, configs): """ Takes an element and a list of configuration dictionaries and extracts the named entities of the given type. :param element: An element name. Expected to be from the _ELEMENTS list :param configs: A list of configuration dictionaries :return: the dictionary mapping ids to element chunks from the configuration dictionary. Elements with id attributes are given generated tokens as ids. """ element_dict = {} for config in configs: if safe_xml_path(config, [Config._XML_HEAD, element]): for chunk in force_list(config[Config._XML_HEAD][element]): if '@id' in chunk: eid = chunk['@id'] else: eid = Config.get_new_id() element_dict[eid] = chunk return element_dict
def status_vals(status): param_specs = utils.force_list(utils.extract_from_path(status, ['librec-auto-status', 'param'])) return [spec['value'] for spec in param_specs]
def accumulate_gradients(self, inputs, targets, additional_fetches=None): """ Runs a forward pass & backward pass, clips gradients if needed and accumulates them into the accumulation placeholders :param additional_fetches: Optional tensors to fetch during gradients calculation :param inputs: The input batch for the network :param targets: The targets corresponding to the input batch :return: A list containing the total loss and the individual network heads losses """ if self.accumulated_gradients is None: self.reset_accumulated_gradients() # feed inputs if additional_fetches is None: additional_fetches = [] inputs = force_list(inputs) feed_dict = dict(zip(self.inputs, inputs)) # feed targets targets = force_list(targets) for placeholder_idx, target in enumerate(targets): feed_dict[self.targets[placeholder_idx]] = target if self.optimizer_type != 'LBFGS': # set the fetches fetches = [self.gradients_norm] if self.tp.clip_gradients: fetches.append(self.clipped_grads) else: fetches.append(self.tensor_gradients) fetches += [self.total_loss, self.losses] if self.tp.agent.middleware_type == MiddlewareTypes.LSTM: fetches.append(self.middleware_embedder.state_out) additional_fetches_start_idx = len(fetches) fetches += additional_fetches # feed the lstm state if necessary if self.tp.agent.middleware_type == MiddlewareTypes.LSTM: # we can't always assume that we are starting from scratch here can we? feed_dict[self.middleware_embedder. c_in] = self.middleware_embedder.c_init feed_dict[self.middleware_embedder. h_in] = self.middleware_embedder.h_init # get grads result = self.tp.sess.run(fetches, feed_dict=feed_dict) # extract the fetches norm_unclipped_grads, grads, total_loss, losses = result[:4] if self.tp.agent.middleware_type == MiddlewareTypes.LSTM: (self.curr_rnn_c_in, self.curr_rnn_h_in) = result[4] fetched_tensors = [] if len(additional_fetches) > 0: fetched_tensors = result[additional_fetches_start_idx:] # accumulate the gradients for idx, grad in enumerate(grads): self.accumulated_gradients[idx] += grad return total_loss, losses, norm_unclipped_grads, fetched_tensors else: self.optimizer.minimize(session=self.tp.sess, feed_dict=feed_dict) return [0]