Last active
March 26, 2019 15:00
-
-
Save DannyWeitekamp/fc4dcc3124af98da73d4d0bd7d23049f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Chris Questions: | |
| # Calling all inputs and outputs 'foas' is a little confusing? | |
| # In training why does HowSearch run at the beginning and then only get used when there are no explanations? | |
| # Nitty Gritty Questions: | |
| # Does the when learner need to include foas & selection in search? | |
| # -How do we support the possibility that it does/doesn't | |
| # -are there accuracy/opp differences if only operating on the state without expanding / querying over all the foas/selections? | |
| # Opinions/Notes | |
| # -Each Learner Should own its own parts. Should not be kept in skills -> makes things more modular. | |
| class ModularAgent(BaseAgent): | |
| def __init__(self, feature_set, function_set, | |
| when_learner='trestle', where_learner='MostSpecific', | |
| search_depth=1, numerical_epsilon=0.0): | |
| self.where = get_where_learner(where_learner) | |
| self.when = get_when_learner(when_learner) | |
| self.skills = {} | |
| self.examples = {} | |
| self.feature_set = feature_set | |
| self.function_set = function_set | |
| self.search_depth = search_depth | |
| self.epsilon = numerical_epsilon | |
| #######-----------------------MISC----------------------------########## | |
| def apply_featureset(self, state): | |
| ####----------Definitely Vectorizable -------------###### | |
| pass | |
| #######---------------Needs to be implemented elsewhere--------------------########## | |
| def when_learner.applicable_skills(state,skills=None): | |
| pass | |
| def which_learner.most_relevant(explanations): | |
| pass | |
| def which_learner.cull_how(explanations): | |
| pass | |
| #####-----------------------REQUEST--------------------------########### | |
| def applicable_explanations(self,state,skills=None):# -> returns list<Explanation> | |
| if(skills == None): skills = self.skills | |
| #order here might need to be switched depending on when learner implementation (see nitty gritty questions below) | |
| skills = when_learner.applicable_skills(state, skills=skills) | |
| explanations = [] | |
| ######## ------------------ Vectorizable-----------------------####### | |
| for skill in skills: | |
| for match in where_learner.get_matches(skill,state): | |
| explanation = Explanation(skill,match) | |
| if(explanation.conditions_apply()): | |
| explanations.append(explanation) | |
| ######## -------------------------------------------------------####### | |
| return explanations | |
| def request(state): #-> Returns sai | |
| state_featurized = apply_featureset(state) | |
| explanations = applicable_explanations(state_featurized) | |
| return which_learner.most_relevant(explanations).to_sai() | |
| #####-----------------------TRAIN --------------------------########### | |
| def where_matches(self,explanations): #-> list<Explanation>, list<Explanation> | |
| matching_explanations, nonmatching_explanations = [], [] | |
| for exp in explanations: | |
| if(where_learner.check_match(exp)): | |
| matching_explanations.append(exp) | |
| else: | |
| nonmatching_explanations.append(exp) | |
| return matching_explanations, nonmatching_explanations | |
| def explanations_from_skills(self,state, sai,skills): # -> return Iterator<skill> | |
| for skill in skills: | |
| ######## ------------------ Vectorizable-----------------------####### | |
| for match in explain_sai(knowledge_base, exp, sai, self.epsilon): | |
| explanation = Explanation(skill,match) | |
| if(explanation.output_selection == sai.selection && explanation.compute(state) == sai.input): | |
| yield explanation | |
| ######## -------------------------------------------------------####### | |
| def explanations_from_how_search(self,state, sai):# -> return Iterator<skill> | |
| return how_learner.how_search(state,sai) | |
| def add_skill(self,skill): #-> return None | |
| self.skills.append(skill) | |
| where_learner.add_skill(skill) | |
| when_learner.add_skill(skill) | |
| def fit(self,explanations, state, reward): #-> return None | |
| for exp in explanations: | |
| when_learner.ifit(exp.skill, state, reward) | |
| where_learner.ifit(exp.skill, reward) | |
| def train(self,state, sai, reward, skill_label, foci_of_attention):# -> return None | |
| state_featurized = apply_featureset(state) | |
| explanations = explanations_from_skills(state,sai,self.skills) | |
| explanations, nonmatching_explanations = where_matches(explanations) | |
| if(len(explanations) == 0 ): | |
| if(len(nonmatching_explanations) > 0): | |
| explanations = [choice(nonmatching_explanations)] | |
| else: | |
| explanations = explanations_from_how_search(state,sai) | |
| explanations = which_learner.cull_how(skills) #Choose all or just the most parsimonious | |
| for exp in explanations: | |
| self.add_skill(exp.skill) | |
| # skill = which_learner.most_relevant(skills) | |
| fit(explanations,state_featurized,reward) | |
| #####--------------------------CHECK-----------------------------########### | |
| def check(self, state, sai): | |
| state_featurized = apply_featureset(state) | |
| explanations = explanations_from_skills(state,sai,self.skills) | |
| explanations, nonmatching_explanations = where_matches(explanations) | |
| return len(explanations) > 0 | |
| #####--------------------------CLASS DEFINITIONS-----------------------------########### | |
| class SAI(object): | |
| def __init__(self,selection, action, inp): | |
| self.selection = selection | |
| self.action = action | |
| self.input = inp# functions that return boolean | |
| class Operator(object): | |
| def __init__(self,args, function, conditions): | |
| self.num_inputs = len(args) | |
| self.function = function | |
| self.conditions = conditions# functions that return boolean | |
| def compute(self, args): | |
| return function(**args) | |
| def conditions_met(self, args): | |
| for c in conditions: | |
| if(not c(...args)): | |
| return False | |
| return True | |
| class Skill(object): | |
| def __init__(conditions, action, operator_chain, input_selections, output_selection): | |
| self.conditions = conditions | |
| self.action = action | |
| self.operator_chain = operator_chain | |
| self.input_selections = input_selections | |
| self.output_selection = output_selection | |
| def to_xml(self,agent=None): #-> needs some way of representing itself including its when/where parts | |
| class Explanation(object): | |
| def __init__(skill, mapping): | |
| self.skill = skill | |
| self.selections_mapping = mapping | |
| self.input_selections = [mapping[s] for s in skill.input_selections]#The Literal | |
| self.output_selection = mapping[skill.output_selection] | |
| def compute(self): | |
| return operator_chain(input_selections) | |
| def conditions_apply(): | |
| for c in self.skill.conditions: | |
| c.applies(...) | |
| def to_sai(): | |
| return SAI(self.input_selections,self.skill.action, self.compute) | |
| def to_xml(self,agent=None): #-> needs some way of representing itself including its when/where parts | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment