def POST(self): super(UpdateLeadController, self).POST() params = web.input() lead = self.store.get_item(Lead, dict(lead_url=params.lead_url, date_created=int(params.date_created))) source = self.store.get_item(Source, dict(source_name=lead.source_name)) parser = find_class(source.parser)() lead = parser.populate_lead(lead) self.store.update(lead) return json.dumps(lead._asdict())
def __init__(self, task_name, parameters=None, other_options=None): self.count = -1 task_class = utils.find_class( task_name, class_folder='tasks', inherited_class=Task, excluded_files=['taskTemplate', '__init__', 'taskGenerator']) valid_task_args = utils.get_class_args(task_class) self.task_class = task_class if not parameters: parameters = {} parameter_keys = list(parameters.keys()) for p in parameter_keys: if p not in valid_task_args: raise KeyError( '{} is not a valid property for model ``{}``. Use {}'. format(p, task_name, valid_task_args)) parameter_combinations = [] for p in utils.listMergeGen(*list(parameters.values())): pc = {k: copy.copy(v) for k, v in zip(parameter_keys, p)} parameter_combinations.append(pc) self.parameter_combinations = parameter_combinations if other_options: checked_options = {} for k, v in other_options.items(): if k not in valid_task_args: raise KeyError( '{} is not a valid property for task ``{}``. Use {}'. format(k, task_name, valid_task_args)) elif k in parameter_keys: warnings.warn( "task parameter {} has been defined twice".format(k)) else: checked_options[k] = v self.other_options = checked_options else: self.other_options = {} if parameter_combinations: self.count_max = len(parameter_combinations) else: self.count_max = 1
def create_model(session, exp_settings, data_set, forward_only): """Create model and initialize or load parameters in session. Args: session: (tf.Session) The session used to run tensorflow models exp_settings: (dictionary) The dictionary containing the model settings. data_set: (Raw_data) The dataset used to build the input layer. forward_only: Set true to conduct prediction only, false to conduct training. """ model = utils.find_class(exp_settings['learning_algorithm'])(data_set, exp_settings, forward_only) ckpt = tf.train.get_checkpoint_state(FLAGS.model_dir) if ckpt: print("Reading model parameters from %s" % ckpt.model_checkpoint_path) model.saver.restore(session, ckpt.model_checkpoint_path) else: print("Created model with fresh parameters.") session.run(tf.global_variables_initializer()) return model
def get_ranking_scores(self, input_id_list, is_training=False, scope=None): """Compute ranking scores with the given inputs. Args: input_id_list: (list<tf.Tensor>) A list of tensors containing document ids. Each tensor must have a shape of [None]. is_training: (bool) A flag indicating whether the model is running in training mode. scope: (string) The name of the variable scope. Returns: A tensor with the same shape of input_docids. """ with tf.variable_scope(scope or "ranking_model"): # Build feature padding PAD_embed = tf.zeros([1,self.feature_size],dtype=tf.float32) letor_features = tf.concat(axis=0,values=[self.letor_features, PAD_embed]) input_feature_list = [] model = utils.find_class(self.exp_settings['ranking_model'])(self.exp_settings['ranking_model_hparams']) for i in range(len(input_id_list)): input_feature_list.append(tf.nn.embedding_lookup(letor_features, input_id_list[i])) return model.build(input_feature_list, is_training)
def __init__(self, model_name, parameters=None, other_options=None): self.count = -1 if parameters is None: parameters = {} if other_options is None: other_options = {} model_class = utils.find_class( model_name, class_folder='model', inherited_class=Model, excluded_files=['modelTemplate', '__init__', 'modelGenerator']) valid_model_args = utils.get_class_args(model_class) valid_args = copy.copy(valid_model_args) if 'stimulus_shaper_name' in parameters: raise NotImplementedError( "This system has not been created for changing stimulus shapers. Please put it in the ``other_options``" ) stimulus_shaper_name = other_options.pop('stimulus_shaper_name', None) if stimulus_shaper_name: stimFunc = utils.find_class( stimulus_shaper_name, class_folder='tasks', inherited_class=Stimulus, excluded_files=['taskTemplate', '__init__', 'taskGenerator']) valid_stimulus_args = utils.get_class_attributes( stimFunc, ignore=['processStimulus']) valid_args.extend(valid_stimulus_args) else: stimFunc = None if 'reward_shaper_name' in parameters: raise NotImplementedError( "This system has not been created for changing reward shapers. Please put it in the ``other_options``" ) reward_shaper_name = other_options.pop('reward_shaper_name', None) if reward_shaper_name: rewardFunc = utils.find_class( reward_shaper_name, class_folder='tasks', inherited_class=Rewards, excluded_files=['taskTemplate', '__init__', 'taskGenerator']) valid_reward_args = utils.get_class_attributes( rewardFunc, ignore=['processFeedback']) valid_args.extend(valid_reward_args) else: rewardFunc = None if 'decision_function_name' in parameters: raise NotImplementedError( "This system has not been created for changing decision functions. Please put it in the ``other_options``" ) decision_function_name = other_options.pop('decision_function_name', None) if decision_function_name: decisionFunc = utils.find_function(decision_function_name, 'model/decision', excluded_files=['__init__']) valid_decision_args = utils.get_function_args(decisionFunc) valid_args.extend(valid_decision_args) else: decisionFunc = None self.model_class = model_class if not parameters: parameters = {} parameter_keys = list(parameters.keys()) for p in parameter_keys: if p not in valid_args and len( model_class.pattern_parameters_match(p)) == 0: raise KeyError( '{} is not a valid property for model ``{}``. Those available are {}' .format(p, model_name, valid_args)) parameter_combinations = [] for p in utils.listMergeGen(*list(parameters.values())): pc = {k: copy.copy(v) for k, v in zip(parameter_keys, p)} parameter_combinations.append(pc) self.parameter_combinations = parameter_combinations if other_options: checked_options = {} for k, v in other_options.items(): if k not in valid_args: raise KeyError( '{} is not a valid property for model ``{}``. Those available are {}' .format(k, model_name, valid_args)) elif k in parameter_keys: warnings.warn( "model parameter {} has been defined twice".format(k)) else: checked_options[k] = v self.other_options = checked_options self.other_options[ 'stimulus_shaper_properties'] = valid_stimulus_args self.other_options['reward_shaper_properties'] = valid_reward_args self.other_options[ 'decision_function_properties'] = valid_decision_args else: self.other_options = {} if stimFunc: self.other_options['stimulus_shaper'] = stimFunc if rewardFunc: self.other_options['reward_shaper'] = rewardFunc if decisionFunc: self.other_options['decision_function'] = decisionFunc if parameter_combinations: self.count_max = len(parameter_combinations) else: self.count_max = 1
def __init__(self, data_set, exp_settings, forward_only=False): """Create the model. Args: data_set: (Raw_data) The dataset used to build the input layer. exp_settings: (dictionary) The dictionary containing the model settings. forward_only: Set true to conduct prediction only, false to conduct training. """ self.hparams = tf.contrib.training.HParams( propensity_estimator_type= 'utils.propensity_estimator.RandomizedPropensityEstimator', propensity_estimator_json= './example/PropensityEstimator/randomized_pbm_0.1_1.0_4_1.0.json', # the setting file for the predefined click models. learning_rate=0.05, # Learning rate. max_gradient_norm=5.0, # Clip gradients to this norm. loss_func= 'click_weighted_softmax_cross_entropy', # Select Loss function l2_loss=0.0, # Set strength for L2 regularization. grad_strategy='ada', # Select gradient strategy ) print(exp_settings['learning_algorithm_hparams']) self.hparams.parse(exp_settings['learning_algorithm_hparams']) self.exp_settings = exp_settings self.propensity_estimator = utils.find_class( self.hparams.propensity_estimator_type)( self.hparams.propensity_estimator_json) self.max_candidate_num = exp_settings['max_candidate_num'] self.feature_size = data_set.feature_size self.learning_rate = tf.Variable(float(self.hparams.learning_rate), trainable=False) self.global_step = tf.Variable(0, trainable=False) # Feeds for inputs. self.is_training = tf.placeholder(tf.bool, name="is_train") self.docid_inputs = [] # a list of top documents self.letor_features = tf.placeholder( tf.float32, shape=[None, self.feature_size], name="letor_features") # the letor features for the documents self.labels = [] # the labels for the documents (e.g., clicks) for i in range(self.max_candidate_num): self.docid_inputs.append( tf.placeholder(tf.int64, shape=[None], name="docid_input{0}".format(i))) self.labels.append( tf.placeholder(tf.float32, shape=[None], name="label{0}".format(i))) self.PAD_embed = tf.zeros([1, self.feature_size], dtype=tf.float32) # Build model self.output = self.ranking_model(self.max_candidate_num, scope='ranking_model') reshaped_labels = tf.transpose( tf.convert_to_tensor(self.labels) ) # reshape from [max_candidate_num, ?] to [?, max_candidate_num] pad_removed_output = self.remove_padding_for_metric_eval( self.docid_inputs, self.output) for metric in self.exp_settings['metrics']: for topn in self.exp_settings['metrics_topn']: metric_value = utils.make_ranking_metric_fn(metric, topn)( reshaped_labels, pad_removed_output, None) tf.summary.scalar('%s_%d' % (metric, topn), metric_value, collections=['eval']) # Gradients and SGD update operation for training the model. if not forward_only: # Training outputs and losses. self.rank_list_size = exp_settings['train_list_cutoff'] train_output = self.ranking_model(self.rank_list_size, scope='ranking_model') train_labels = self.labels[:self.rank_list_size] self.propensity_weights = [] for i in range(self.rank_list_size): self.propensity_weights.append( tf.placeholder(tf.float32, shape=[None], name="propensity_weights{0}".format(i))) tf.summary.scalar('Propensity weights %d' % i, tf.reduce_max(self.propensity_weights[i]), collections=['train']) print('Loss Function is ' + self.hparams.loss_func) self.loss = None reshaped_train_labels = tf.transpose( tf.convert_to_tensor(train_labels) ) # reshape from [rank_list_size, ?] to [?, rank_list_size] reshaped_propensity = tf.transpose( tf.convert_to_tensor(self.propensity_weights) ) # reshape from [rank_list_size, ?] to [?, rank_list_size] if self.hparams.loss_func == 'softmax': self.loss = self.softmax_loss(train_output, reshaped_train_labels, reshaped_propensity) elif self.hparams.loss_func == 'click_weighted_softmax_cross_entropy': self.loss = self.click_weighted_softmax_loss( train_output, reshaped_train_labels, reshaped_propensity) elif self.hparams.loss_func == 'click_weighted_pairwise_loss': self.loss = self.click_weighted_pairwise_loss( train_output, reshaped_train_labels, reshaped_propensity) else: self.loss = self.sigmoid_loss(train_output, reshaped_train_labels, reshaped_propensity) params = tf.trainable_variables() if self.hparams.l2_loss > 0: for p in params: self.loss += self.hparams.l2_loss * tf.nn.l2_loss(p) # Select optimizer self.optimizer_func = tf.train.AdagradOptimizer if self.hparams.grad_strategy == 'sgd': self.optimizer_func = tf.train.GradientDescentOptimizer opt = self.optimizer_func(self.hparams.learning_rate) self.gradients = tf.gradients(self.loss, params) if self.hparams.max_gradient_norm > 0: self.clipped_gradients, self.norm = tf.clip_by_global_norm( self.gradients, self.hparams.max_gradient_norm) self.updates = opt.apply_gradients( zip(self.clipped_gradients, params), global_step=self.global_step) else: self.norm = None self.updates = opt.apply_gradients( zip(self.gradients, params), global_step=self.global_step) tf.summary.scalar('Learning Rate', self.learning_rate, collections=['train']) tf.summary.scalar('Loss', tf.reduce_mean(self.loss), collections=['train']) clipped_labels = tf.clip_by_value(reshaped_train_labels, clip_value_min=0, clip_value_max=1) pad_removed_train_output = self.remove_padding_for_metric_eval( self.docid_inputs, train_output) for metric in self.exp_settings['metrics']: for topn in self.exp_settings['metrics_topn']: list_weights = tf.reduce_mean(reshaped_propensity * clipped_labels, axis=1, keep_dims=True) metric_value = utils.make_ranking_metric_fn(metric, topn)( reshaped_train_labels, pad_removed_train_output, None) tf.summary.scalar('%s_%d' % (metric, topn), metric_value, collections=['train']) weighted_metric_value = utils.make_ranking_metric_fn( metric, topn)(reshaped_train_labels, pad_removed_train_output, list_weights) tf.summary.scalar('Weighted_%s_%d' % (metric, topn), weighted_metric_value, collections=['train']) self.train_summary = tf.summary.merge_all(key='train') self.eval_summary = tf.summary.merge_all(key='eval') self.saver = tf.train.Saver(tf.global_variables())
def run(data_folder='./', data_format='csv', data_file_filter=None, data_file_terminal_ID=True, data_read_options=None, data_split_by=None, data_group_by=None, data_extra_processing=None, model_name='QLearn', model_changing_properties=None, model_constant_properties=None, participantID="Name", participant_choices='Actions', participant_rewards='Rewards', model_fit_value='ActionProb', fit_subset=None, task_stimuli=None, participant_action_options=None, fit_method='Evolutionary', fit_method_args=None, fit_measure='-loge', fit_measure_args=None, fit_extra_measures=None, participant_varying_model_parameters=None, label=None, save_fitting_progress=False, config_file=None, output_path=None, pickle=False, boundary_excess_cost_function=None, min_log_level='INFO', numpy_error_level="log", fit_float_error_response_value=1 / 1e100, calculate_covariance=False ): """ A framework for fitting models to data for tasks, along with recording the data associated with the fits. Parameters ---------- data_folder : string or list of strings, optional The folder where the data can be found. Default is the current folder. data_format : string, optional The file type of the data, from ``mat``, ``csv``, ``xlsx`` and ``pkl``. Default is ``csv`` data_file_filter : callable, string, list of strings or None, optional A function to process the file names or a list of possible prefixes as strings or a single string. Default ``None``, no file names removed data_file_terminal_ID : bool, optional Is there an ID number at the end of the filename? If not then a more general search will be performed. Default ``True`` data_read_options : dict, optional The keyword arguments for the data importing method chosen data_split_by : string or list of strings, optional If multiple participant datasets are in one file sheet, this specifies the column or columns that can distinguish and identify the rows for each participant. Default ``None`` data_group_by : list of strings, optional A list of parts of filenames that are repeated across participants, identifying all the files that should be grouped together to form one participants data. The rest of the filename is assumed to identify the participant. Default is ``None`` data_extra_processing : callable, optional A function that modifies the dictionary of data read for each participant in such that it is appropriate for fitting. Default is ``None`` model_name : string, optional The name of the file where a model.modelTemplate.Model class can be found. Default ``QLearn`` model_changing_properties : dictionary with values of tuple of two floats, optional Parameters are the options that you allow to vary across model fits. Each model parameter is specified as a dict key. The value is a tuple containing the upper and lower search bounds, e.g. ``alpha`` has the bounds (0, 1). Default ``None`` model_constant_properties : dictionary of float, string or binary valued elements, optional These contain all the the model options that define the version of the model being studied. Default ``None`` participantID : str, optional The key (label) used to identify each participant. Default ``Name`` participant_choices : string, optional The participant data key of their action choices. Default ``'Actions'`` participant_rewards : string, optional The participant data key of the participant reward data. Default ``'Rewards'`` model_fit_value : string, optional The key to be compared in the model data. Default ``'ActionProb'`` fit_subset : ``float('Nan')``, ``None``, ``"rewarded"``, ``"unrewarded"``, ``"all"`` or list of int, optional Describes which, if any, subset of trials will be used to evaluate the performance of the model. This can either be described as a list of trial numbers or, by passing - ``"all"`` for fitting all trials - ``float('Nan')`` or ``"unrewarded"`` for all those trials whose feedback was ``float('Nan')`` - ``"rewarded"`` for those who had feedback that was not ``float('Nan')`` Default ``None``, which means all trials will be used. task_stimuli : list of strings or None, optional The keys containing the observational parameters seen by the participant before taking a decision on an action. Default ``None`` participant_action_options : string or list of strings or None or one element list with a list, optional If a string or list of strings these are treated as dict keys where the valid actions for each trial can be found. If None then all trials will use all available actions. If the list contains one list then it will be treated as a list of valid actions for each trialstep. Default ``'None'`` fit_method : string, optional The fitting method to be used. The names accepted are those of the modules in the folder fitAlgs containing a FitAlg class. Default ``'evolutionary'`` fit_method_args : dict, optional A dictionary of arguments specific to the fitting method. Default ``None`` fit_measure : string, optional The name of the function used to calculate the quality of the fit. The value it returns provides the fitter with its fitting guide. Default ``-loge`` fit_measure_args : dict, optional The parameters used to initialise fitMeasure and extraFitMeasures. Default ``None`` fit_extra_measures : list of strings, optional List of fit measures not used to fit the model, but to provide more information. Any arguments needed for these measures should be placed in fitMeasureArgs. Default ``None`` participant_varying_model_parameters : dict of string, optional A dictionary of model settings whose values should vary from participant to participant based on the values found in the imported participant data files. The key is the label given in the participant data file, as a string, and the value is the associated label in the model, also as a string. Default ``{}`` label : string, optional The label for the data fitting. Default ``None`` will mean no data is saved to files. save_fitting_progress : bool, optional Specifies if the results from each iteration of the fitting process should be returned. Default ``False`` config_file : string, optional The file name and path of a ``.yaml`` configuration file. Overrides all other parameters if found. Default ``None`` output_path : string, optional The path that will be used for the run output. Default ``None`` pickle : bool, optional If true the data for each model, and participant is recorded. Default is ``False`` boundary_excess_cost_function : str or callable returning a function, optional The function is used to calculate the penalty for exceeding the boundaries. Default is ``boundFunc.scalarBound()`` min_log_level : str, optional Defines the level of the log from (``DEBUG``, ``INFO``, ``WARNING``, ``ERROR``, ``CRITICAL``). Default ``INFO`` numpy_error_level : {'log', 'raise'} Defines the response to numpy errors. Default ``log``. See numpy.seterr fit_float_error_response_value : float, optional If a floating point error occurs when running a fit the fitter function will return a value for each element of fpRespVal. Default is ``1/1e100` calculate_covariance : bool, optional Is the covariance calculated. Default ``False`` See Also -------- modelGenerator : The model factory outputting : The outputting functions fitAlgs.fitAlg.FitAlg : General class for a method of fitting data fitAlgs.fitSims.fitSim : General class for a method of simulating the fitting of data data.Data : Data import class """ config = copy.deepcopy(locals()) if participant_varying_model_parameters is None: model_changing_variables = {} else: model_changing_variables = participant_varying_model_parameters # TODO : Validate model_changing_properties with the data and the model participants = data.Data.load_data(file_type=data_format, folders=data_folder, file_name_filter=data_file_filter, terminal_ID=data_file_terminal_ID, split_by=data_split_by, participantID=participantID, choices=participant_choices, feedbacks=participant_rewards, stimuli=task_stimuli, action_options=participant_action_options, group_by=data_group_by, extra_processing=data_extra_processing, data_read_options=data_read_options) if model_changing_properties: model_parameters = {} for key, value in model_changing_properties.items(): if len(value) == 2: v1, v2 = value if v2 < v1: raise OrderError('The bounds specified for model parameter ``{}`` must have the lower bound first'.format(key)) else: model_parameters[key] = (v1 + v2) / 2 else: raise LengthError("The parameter values for the ``model_changing_properties`` must be presented as a list of the maximum and minimum values. Review those of ``{}``".format(key)) else: model_parameters = model_changing_properties models = ModelGen(model_name=model_name, parameters=model_parameters, other_options=model_constant_properties) model_simulator = FitSim(participant_choice_property=participants.choices, participant_reward_property=participants.feedbacks, model_fitting_variable=model_fit_value, fit_subset=fit_subset, task_stimuli_property=participants.stimuli, action_options_property=participants.action_options, float_error_response_value=fit_float_error_response_value ) fitting_method = utils.find_class(fit_method, class_folder='fitAlgs', inherited_class=FitAlg, excluded_files=['boundFunc', 'qualityFunc', 'fitSims']) if fit_method_args is None: fit_method_args = {} fitter = fitting_method(fit_sim=model_simulator, fit_measure=fit_measure, extra_fit_measures=fit_extra_measures, fit_measure_args=fit_measure_args, bounds=model_changing_properties, boundary_excess_cost=boundary_excess_cost_function, calculate_covariance=calculate_covariance, **fit_method_args) with outputting.Saving(config=config) as file_name_generator: logger = logging.getLogger('Fitting') log_fitting_parameters(fitter.info()) message = 'Beginning the data fitting' logger.info(message) model_ID = 0 # Initialise the stores of information participant_fits = collections.defaultdict(list) # type: collections.defaultdict[Any, list] for model, model_parameter_variables, model_static_args in models.iter_details(): for v in model_changing_variables.values(): model_static_args[v] = "<Varies for each participant>" log_model_fitting_parameters(model, model_parameter_variables, model_static_args) participantID = participants.participantID for participant in participants: participant_name = participant[participantID] if isinstance(participant_name, (list, tuple)): participant_name = participant_name[0] for k, v in model_changing_variables.items(): model_static_args[v] = participant[k] # Find the best model values from those proposed message = "Beginning participant fit for participant {}".format(participant_name) logger.info(message) model_fitted, fit_quality, fitting_data = fitter.participant(model, model_parameter_variables, model_static_args, participant) message = "Participant fitted" logger.debug(message) log_model_fitted_parameters(model_parameter_variables, model_fitted.params(), fit_quality, participant_name) participant_fits = record_participant_fit(participant, participant_name, model_fitted.returnTaskState(), str(model_ID), fitting_data, model_changing_variables, participant_fits, fileNameGen=file_name_generator, pickleData=pickle, saveFittingProgress=save_fitting_progress) model_ID += 1 fit_record(participant_fits, file_name_generator)
def __init__(self, number_actions=2, number_cues=1, number_critics=None, action_codes=None, non_action='None', prior=None, stimulus_shaper=None, stimulus_shaper_name=None, stimulus_shaper_properties=None, reward_shaper=None, reward_shaper_name=None, reward_shaper_properties=None, decision_function=None, decision_function_name=None, decision_function_properties=None, **kwargs): """""" self.Name = self.get_name() self.pattern_parameters = self.kwarg_pattern_parameters(kwargs) for k, v in self.pattern_parameters.items(): setattr(self, k, v) self.pattern_parameters = self.kwarg_pattern_parameters(kwargs) for k, v in self.pattern_parameters.items(): setattr(self, k, v) self.number_actions = number_actions self.number_cues = number_cues if number_critics is None: number_critics = self.number_actions * self.number_cues self.number_critics = number_critics if action_codes is None: action_codes = {k: k for k in range(self.number_actions)} self.actionCode = action_codes self.defaultNonAction = non_action if prior is None: prior = np.ones(self.number_actions) / self.number_actions self.prior = prior self.stimuli = np.ones(self.number_cues) self.stimuliFilter = np.ones(self.number_cues) self.currAction = None self.decision = None self.validActions = None self.lastObservation = None self.probabilities = np.array(self.prior) self.decProbabilities = np.array(self.prior) self.expectedRewards = np.ones(self.number_actions) self.expectedReward = np.array([1]) if stimulus_shaper is not None and issubclass(stimulus_shaper, Stimulus): if stimulus_shaper_properties is not None: stimulus_shaper_kwargs = { k: v for k, v in kwargs.items() if k in stimulus_shaper_properties } else: stimulus_shaper_kwargs = kwargs.copy() self.stimulus_shaper = stimulus_shaper(**stimulus_shaper_kwargs) elif isinstance(stimulus_shaper_name, str): stimulus_class = utils.find_class( stimulus_shaper_name, class_folder='tasks', inherited_class=Stimulus, excluded_files=['taskTemplate', '__init__', 'taskGenerator']) stimulus_shaper_kwargs = { k: v for k, v in kwargs.items() if k in utils.get_class_args(stimulus_class) } self.stimulus_shaper = stimulus_class(**stimulus_shaper_kwargs) else: self.stimulus_shaper = Stimulus() if reward_shaper is not None and issubclass(reward_shaper, Rewards): if reward_shaper_properties is not None: reward_shaper_kwargs = { k: v for k, v in kwargs.items() if k in reward_shaper_properties } else: reward_shaper_kwargs = kwargs.copy() self.reward_shaper = reward_shaper(**reward_shaper_kwargs) elif isinstance(reward_shaper_name, str): reward_class = utils.find_class( reward_shaper_name, class_folder='tasks', inherited_class=Rewards, excluded_files=['taskTemplate', '__init__', 'taskGenerator']) reward_shaper_kwargs = { k: v for k, v in kwargs.items() if k in utils.get_class_args(reward_class) } self.reward_shaper = reward_class.processFeedback( **reward_shaper_kwargs) else: self.reward_shaper = Rewards() if callable(decision_function): if decision_function_properties is not None: decision_shaper_kwargs = { k: v for k, v in kwargs.items() if k in decision_function_properties } else: decision_shaper_kwargs = kwargs.copy() self.decision_function = decision_function( **decision_shaper_kwargs) elif isinstance(decision_function_name, str): decision_function = utils.find_function(decision_function_name, 'model/decision') decision_function_kwargs = { k: v for k, v in kwargs.items() if k in utils.get_function_args(decision_function) } self.decision_function = decision_function( **decision_function_kwargs) else: self.decision_function = weightProb( list(range(self.number_actions))) self.parameters = { "Name": self.Name, "number_actions": self.number_actions, "number_cues": self.number_cues, "number_critics": self.number_critics, "prior": copy.copy(self.prior), "non_action": self.defaultNonAction, "actionCode": copy.copy(self.actionCode), "stimulus_shaper": self.stimulus_shaper.details(), "reward_shaper": self.reward_shaper.details(), "decision_function": utils.callableDetailsString(self.decision_function) } self.parameters.update(self.pattern_parameters) # Recorded information self.recAction = [] self.recActionSymbol = [] self.recStimuli = [] self.recReward = [] self.recExpectations = [] self.recExpectedReward = [] self.recExpectedRewards = [] self.recValidActions = [] self.recDecision = [] self.recProbabilities = [] self.recActionProbs = [] self.recActionProb = [] self.simID = None
def train(exp_settings): # Prepare data. print("Reading data in %s" % FLAGS.data_dir) train_set = utils.read_data(FLAGS.data_dir, 'train', FLAGS.max_list_cutoff) valid_set = utils.read_data(FLAGS.data_dir, 'valid', FLAGS.max_list_cutoff) print("Train Rank list size %d" % train_set.rank_list_size) print("Valid Rank list size %d" % valid_set.rank_list_size) exp_settings['max_candidate_num'] = max(train_set.rank_list_size, valid_set.rank_list_size) test_set = None if FLAGS.test_while_train: test_set = utils.read_data(FLAGS.data_dir, 'test', FLAGS.max_list_cutoff) print("Test Rank list size %d" % test_set.rank_list_size) exp_settings['max_candidate_num'] = max( test_set.rank_list_size, exp_settings['max_candidate_num']) exp_settings['train_list_cutoff'] = min( FLAGS.train_list_cutoff, exp_settings['max_candidate_num'] ) if FLAGS.train_list_cutoff > 0 else exp_settings['max_candidate_num'] # Pad data train_set.pad(exp_settings['max_candidate_num']) valid_set.pad(exp_settings['max_candidate_num']) if FLAGS.test_while_train: test_set.pad(exp_settings['max_candidate_num']) config = tf.ConfigProto() config.gpu_options.allow_growth = True with tf.Session(config=config) as sess: # Create model based on the input layer. print("Creating model...") model = create_model(sess, exp_settings, train_set, False) #model.print_info() # Create data feed train_input_feed = utils.find_class(exp_settings['train_input_feed'])( model, FLAGS.batch_size, exp_settings['train_input_hparams'], sess) valid_input_feed = utils.find_class(exp_settings['valid_input_feed'])( model, FLAGS.batch_size, exp_settings['valid_input_hparams'], sess) test_input_feed = None if FLAGS.test_while_train: test_input_feed = utils.find_class( exp_settings['test_input_feed'])( model, FLAGS.batch_size, exp_settings['test_input_hparams'], sess) # Create tensorboard summarizations. train_writer = tf.summary.FileWriter(FLAGS.model_dir + '/train_log', sess.graph) valid_writer = tf.summary.FileWriter(FLAGS.model_dir + '/valid_log') test_writer = None if FLAGS.test_while_train: test_writer = tf.summary.FileWriter(FLAGS.model_dir + '/test_log') # This is the training loop. step_time, loss = 0.0, 0.0 current_step = 0 previous_losses = [] best_perf = None while True: # Get a batch and make a step. start_time = time.time() input_feed, _ = train_input_feed.get_batch(train_set, check_validation=True) step_loss, _, summary = model.step(sess, input_feed, False) step_time += (time.time() - start_time) / FLAGS.steps_per_checkpoint loss += step_loss / FLAGS.steps_per_checkpoint current_step += 1 train_writer.add_summary(summary, model.global_step.eval()) # Once in a while, we save checkpoint, print statistics, and run evals. if current_step % FLAGS.steps_per_checkpoint == 0: # Print statistics for the previous epoch. print("global step %d learning rate %.4f step-time %.2f loss " "%.4f" % (model.global_step.eval(), model.learning_rate.eval(), step_time, loss)) previous_losses.append(loss) # Validate model def validate_model(data_set, data_input_feed): it = 0 count_batch = 0.0 summary_list = [] batch_size_list = [] while it < len(data_set.initial_list): input_feed, info_map = data_input_feed.get_next_batch( it, data_set, check_validation=False) _, _, summary = model.step(sess, input_feed, True) summary_list.append(summary) batch_size_list.append(len(info_map['input_list'])) it += batch_size_list[-1] count_batch += 1.0 return utils.merge_TFSummary(summary_list, batch_size_list) valid_summary = validate_model(valid_set, valid_input_feed) valid_writer.add_summary(valid_summary, model.global_step.eval()) print(" valid: %s" % (' '.join([ '%s:%.3f' % (x.tag, x.simple_value) for x in valid_summary.value ]))) if FLAGS.test_while_train: test_summary = validate_model(test_set, test_input_feed) test_writer.add_summary(test_summary, model.global_step.eval()) print(" test: %s" % (' '.join([ '%s:%.3f' % (x.tag, x.simple_value) for x in test_summary.value ]))) # Save checkpoint if the objective metric on the validation set is better if "objective_metric" in exp_settings: for x in valid_summary.value: if x.tag == exp_settings["objective_metric"]: if current_step > FLAGS.start_saving_iteration: if best_perf == None or best_perf < x.simple_value: checkpoint_path = os.path.join( FLAGS.model_dir, "%s.ckpt" % exp_settings['learning_algorithm']) model.saver.save( sess, checkpoint_path, global_step=model.global_step) best_perf = x.simple_value print('Save model, valid %s:%.3f' % (x.tag, best_perf)) break # Save checkpoint if there is no objective metic if best_perf == None and current_step > FLAGS.start_saving_iteration: checkpoint_path = os.path.join( FLAGS.model_dir, "%s.ckpt" % exp_settings['learning_algorithm']) model.saver.save(sess, checkpoint_path, global_step=model.global_step) if loss == float('inf'): break step_time, loss = 0.0, 0.0 sys.stdout.flush() if FLAGS.max_train_iteration > 0 and current_step > FLAGS.max_train_iteration: break
def test(exp_settings): config = tf.ConfigProto() config.gpu_options.allow_growth = True with tf.Session(config=config) as sess: # Load test data. print("Reading data in %s" % FLAGS.data_dir) test_set = utils.read_data(FLAGS.data_dir, 'test', FLAGS.max_list_cutoff) exp_settings['max_candidate_num'] = test_set.rank_list_size test_set.pad(exp_settings['max_candidate_num']) # Create model and load parameters. model = create_model(sess, exp_settings, test_set, True) # Create input feed #test_input_feed = utils.find_class(exp_settings['test_input_feed'])(model, 1, exp_settings['test_input_hparams'], sess) test_input_feed = utils.find_class(exp_settings['test_input_feed'])( model, FLAGS.batch_size, exp_settings['test_input_hparams'], sess) test_writer = tf.summary.FileWriter(FLAGS.model_dir + '/test_log') rerank_scores = [] summary_list = [] # Start testing. it = 0 count_batch = 0.0 batch_size_list = [] while it < len(test_set.initial_list): input_feed, info_map = test_input_feed.get_next_batch( it, test_set, check_validation=False) _, output_logits, summary = model.step(sess, input_feed, True) summary_list.append(summary) batch_size_list.append(len(info_map['input_list'])) for x in range(batch_size_list[-1]): rerank_scores.append(output_logits[x]) it += batch_size_list[-1] count_batch += 1.0 print("Testing {:.0%} finished".format( float(it) / len(test_set.initial_list)), end="\r", flush=True) print("\n[Done]") test_summary = utils.merge_TFSummary(summary_list, batch_size_list) test_writer.add_summary(test_summary, it) print(" eval: %s" % (' '.join( ['%s:%.3f' % (x.tag, x.simple_value) for x in test_summary.value]))) #get rerank indexes with new scores rerank_lists = [] for i in range(len(rerank_scores)): scores = rerank_scores[i] rerank_lists.append( sorted(range(len(scores)), key=lambda k: scores[k], reverse=True)) if not os.path.exists(FLAGS.output_dir): os.makedirs(FLAGS.output_dir) utils.output_ranklist(test_set, rerank_scores, FLAGS.output_dir, 'test') return
def __init__(self, source): self.parser = find_class(source.parser)() self.params = json.loads(source.params) self.source = source super(SourceAggregatorThread, self).__init__()