def predict_action_probabilities(self, tracker, domain): if tracker.latest_action_name == ACTION_LISTEN_NAME: return utils.one_hot( domain.action_names.index('action_search_knowledge_base'), domain.num_actions) else: return np.zeros(domain.num_actions)
def probabilities_using_best_policy(self, tracker, domain): # [feature vector, tracker, domain] -> int # given a state, predict next action via asking a human probabilities = self.base_ensemble.probabilities_using_best_policy( tracker, domain) pred_out = np.argmax(probabilities) latest_action_was_listen = self._print_history(tracker) action_name = domain.action_for_index(pred_out).name() colored_name = utils.wrap_with_color(action_name, utils.bcolors.OKBLUE) if latest_action_was_listen: print("The bot wants to [{}] due to the intent. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "3", "0"], "\t1.\tYes\n" + "\t2.\tNo, intent is right but the action is wrong\n" + "\t3.\tThe intent is wrong\n" + "\t0.\tExport current conversations as stories and quit\n") else: print("The bot wants to [{}]. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "0"], "\t1.\tYes.\n" + "\t2.\tNo, the action is wrong.\n" + "\t0.\tExport current conversations as stories and quit\n") feature_vector = domain.feature_vector_for_tracker( self.featurizer, tracker, self.max_history) X = np.expand_dims(np.array(feature_vector), 0) if user_input == "1": # max prob prediction was correct if action_name == ACTION_LISTEN_NAME: print("Next user input:") return probabilities elif user_input == "2": # max prob prediction was false, new action required # action wrong y = self._request_action(probabilities, domain, tracker) self._fit_example(X, y, domain) self.write_out_story(tracker) return utils.one_hot(y, domain.num_actions) elif user_input == "3": # intent wrong and maybe action wrong intent = self._request_intent(tracker, domain) latest_message = copy.copy(tracker.latest_message) latest_message.intent = intent tracker.update(UserUtteranceReverted()) tracker.update(latest_message) return self.probabilities_using_best_policy(tracker, domain) elif user_input == "0": self._export_stories(tracker) raise TrainingFinishedException() else: raise Exception( "Incorrect user input received '{}'".format(user_input))
def predict_action_probabilities(self, tracker, domain): responses = { "greet": 2, "goodbye": 3, "chat": 4, } if tracker.latest_domain == ACTION_LISTEN_NAME: key = tracker.latest_message.intent("name") action = responses[key] if key in responses else 4 return utils.one_hot(action, domain.num_actions)
def predict_action_probabilities(self, tracker, domain): # type: (DialogueStateTracker, Domain) -> List[float] responses = { "greet": 3, } if tracker.latest_action_name == ACTION_LISTEN_NAME: key = tracker.latest_message.intent["name"] action = responses[key] if key in responses else 2 return utils.one_hot(action, domain.num_actions) else: return np.zeros(domain.num_actions)
def predict_action_probabilities(self, tracker, domain): responses = {'greet': actions['utter_how_can_i_help'], 'affirm': actions['utter_goodbye'], 'deny': actions['action_alternative'], 'accept_topic': actions['utter_invite_to_ask_question'], 'accept_question': actions['action_answer'], 'ask': actions['action_search'] if tracker.get_slot('topic') is not None else actions['utter_suggest_topic'], 'thankyou': actions['utter_goodbye'], 'start': actions['utter_greet'], 'goodbye': actions['utter_goodbye']} if tracker.latest_action_name == ACTION_LISTEN_NAME: # coming from listen state key = tracker.latest_message.intent['name'] action = responses[key] + 2 if key in responses else actions['utter_default'] return utils.one_hot(action, domain.num_actions) elif tracker.latest_action_name == 'utter_goodbye': return utils.one_hot(actions['custom_action_restart'] + 2, domain.num_actions) elif tracker.latest_action_name == 'action_search' and tracker.get_slot('confidence') == 'high': return utils.one_hot(actions['action_answer'] + 2, domain.num_actions) elif tracker.latest_action_name == 'action_answer': return utils.one_hot(actions['utter_ask_if_helpful'] + 2, domain.num_actions) else: # listen return np.zeros(domain.num_actions)
def test_on_hot_out_of_range(): with pytest.raises(ValueError): utils.one_hot(4, 3)
def test_on_hot(): r = utils.one_hot(4, 6) assert (r[[0, 1, 2, 3, 5]] == 0).all() assert r[4] == 1
def probabilities_using_best_policy(self, tracker, domain): # type: (DialogueStateTracker, Domain) -> List[float] # given a state, predict next action via asking a human probabilities = self.base_ensemble.probabilities_using_best_policy( tracker, domain) pred_out = int(np.argmax(probabilities)) latest_action_was_listen = self._print_history(tracker) action_name = domain.action_for_index(pred_out).name() colored_name = utils.wrap_with_color(action_name, utils.bcolors.OKBLUE) if latest_action_was_listen: print("The bot wants to [{}] due to the intent. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "3", "0"], "\t1.\tYes\n" + "\t2.\tNo, intent is right but the action is wrong\n" + "\t3.\tThe intent is wrong\n" + "\t0.\tExport current conversations as stories and quit\n") else: print("The bot wants to [{}]. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "0"], "\t1.\tYes.\n" + "\t2.\tNo, the action is wrong.\n" + "\t0.\tExport current conversations as stories and quit\n") if user_input == "1": # max prob prediction was correct if action_name == ACTION_LISTEN_NAME: print("Next user input:") return probabilities elif user_input == "2": # max prob prediction was false, new action required # action wrong y = self._request_action(probabilities, domain, tracker) # update tracker with new action new_action_name = domain.action_for_index(y).name() # need to copy tracker, because the tracker will be # updated with the new event somewhere else training_tracker = tracker.copy() training_tracker.update(ActionExecuted(new_action_name)) self._fit_example(training_tracker, domain) self.write_out_story(tracker) return utils.one_hot(y, domain.num_actions) elif user_input == "3": # intent wrong and maybe action wrong intent = self._request_intent(tracker, domain) latest_message = copy.copy(tracker.latest_message) latest_message.intent = intent tracker.update(UserUtteranceReverted()) tracker.update(latest_message) for e in domain.slots_for_entities(latest_message.entities): tracker.update(e) return self.probabilities_using_best_policy(tracker, domain) elif user_input == "0": self._export_stories(tracker) raise TrainingFinishedException() else: raise Exception( "Incorrect user input received '{}'".format(user_input))
def probabilities_using_best_policy(self, tracker, domain, inputQueue, outputQueue): # type: (DialogueStateTracker, Domain) -> List[float] # given a state, predict next action via asking a human recipient_id = "cliniciansID" probabilities = self.base_ensemble.probabilities_using_best_policy( tracker, domain) logger.info("second!") pred_out = int(np.argmax(probabilities)) # logger.info("third!") latest_action_was_listen = self._print_history(tracker, inputQueue=inputQueue, outputQueue=outputQueue) # logger.info("fourth!") # sys.stdout.flush() logger.info("\n\nAll messages (at the top): \n\n") logger.info(tracker.export_stories()) action_name = domain.action_for_index(pred_out).name() if latest_action_was_listen: msg = "" msg = "The bot wants to [{}] due to the intent. \n ⬇ Is this correct? ⬇\n".format(action_name) outputQueue.put(["thintBotAction", msg]) # logger.info(msg) sys.stdout.flush() user_input = self.request_input( ["1", "2", "3", "0"], "\t1.\tYes\n" + "\t2.\tNo, intent is right but the action is wrong\n" + "\t3.\tThe intent is wrong\n" + "\t0.\tExport current conversations as stories and quit\n", inputQueue=inputQueue, outputQueue=outputQueue) else: msg = "The bot wants to [{}].\n ⬇ Is this correct? ⬇\n".format(action_name) # logger.info(msg) outputQueue.put(["thintBotAction", msg]) # logger.info(msg) sys.stdout.flush() user_input = self.request_input( ["1", "2", "0"], "\t1.\tYes.\n" + "\t2.\tNo, the action is wrong.\n" + "\t0.\tExport current conversations as stories and quit\n", inputQueue=inputQueue, outputQueue=outputQueue) if user_input == "1": # max prob prediction was correct if action_name == ACTION_LISTEN_NAME: msg = "⬆ Type in your next message above ⬆" outputQueue.put(["thintBotAction", msg]) outputQueue.put(["thintKeyOptions", "\n"]) ## Hack to clear it # logger.info(msg) sys.stdout.flush() return probabilities elif user_input == "2": # max prob prediction was false, new action required # action wrong y = self._request_action(probabilities, domain, tracker, inputQueue=inputQueue, outputQueue=outputQueue) # update tracker with new action new_action_name = domain.action_for_index(y).name() # need to copy tracker, because the tracker will be # updated with the new event somewhere else training_tracker = tracker.copy() training_tracker.update(ActionExecuted(new_action_name)) self._fit_example(training_tracker, domain) self.write_out_story(tracker) return utils.one_hot(y, domain.num_actions) elif user_input == "3": # intent wrong and maybe action wrong logger.info("\n\nJust entered option 3 \n\n") intent = self._request_intent(tracker, domain, inputQueue=inputQueue, outputQueue=outputQueue) latest_message = copy.copy(tracker.latest_message) latest_message.intent = intent tracker.update(UserUtteranceReverted()) tracker.update(latest_message) logger.info("\n\nAll messages (now in 3): \n\n") logger.info(tracker.export_stories()) for e in domain.slots_for_entities(latest_message.entities): tracker.update(e) return self.probabilities_using_best_policy(tracker, domain, inputQueue, outputQueue) elif user_input == "0": # file_prompt = ("File to export to (if file exists, this " # "will append the stories) " # "[{}]: ").format(DEFAULT_FILE_EXPORT_PATH) # export_file_path = self.request_input(prompt=file_prompt, inputQueue=inputQueue, outputQueue=outputQueue) # if not export_file_path: # export_file_path = DEFAULT_FILE_EXPORT_PATH export_file_path = '../data/stories/stories.md' self._export_stories(tracker, export_file_path) outputQueue.put("SHUTDOWN") raise TrainingFinishedException() else: # logger.info("Righty!") raise Exception( "Incorrect user input received '{}'".format(user_input))
def predict_action_probabilities(self, tracker, domain): # These are the arrays of intents associated with each type of action search_movie_intents = [ "media", "movie", "movie_name", "director movie date rating", "director movie rating", "director movie_name", "movie language", ] search_movie_info_intents = [ "language", "country", "genre", "subjects", "budget", "movie budget", "movie date", "release_date", "movie director", "movie subjects", "movie trailer", "trailer", "movie media", "movie_count", "organization", "producer", "producer picture", "producer_count", "movie producer", "movie rating", "rating", "rating rating", "review", "review movie", "review rating", "revenue", "runtime", "synopsis", "theater", "picture", "movie_other", ] search_person_intents = [ "actor", "actor_name", "actor_name character", "character", "composer", "director", "director producer", "director_name", "person", "person_name", "writer", ] search_person_info_intents = [ "birth_date", "award_category_count", "award_count", "award_ceremony award_category", ] # we convert the arrays into dicts so that we can get the specific kind of action related to an intent search_movie_intents = { k: "action_search_movie" for k in search_movie_intents } search_movie_info_intents = { k: "action_search_movie_info" for k in search_movie_info_intents } search_person_intents = { k: "action_search_person" for k in search_person_intents } search_person_info_intents = { k: "action_search_movie_info" for k in search_person_info_intents } # aggregate all into one dict intent_action_map = { **search_movie_intents, **search_movie_info_intents, **search_person_intents, **search_person_info_intents } # dict -> action_name: action_id action_ids = {k: v[0] for k, v in domain.action_map.items()} # the name of the current intent last_intent = tracker.latest_message.intent["name"] # if previous action was "LISTEN" and the current intent is one of the intents we can handle # and the previous action was not one of our custom actions (all start with action_) if tracker.latest_action_name == ACTION_LISTEN_NAME and \ last_intent in intent_action_map.keys() and \ tracker.latest_action_name not in list(intent_action_map.values()) + ["action_fallout_slots"]: action = intent_action_map[last_intent] id_action = action_ids[action] return utils.one_hot(id_action, domain.num_actions) # if last action was one we gave in this policy (ie, a search action) then we want our next # action to be the "Answer" action. elif tracker.latest_action_name in intent_action_map.values(): id_action = action_ids["action_answer"] return utils.one_hot(id_action, domain.num_actions) elif tracker.latest_action_name == "action_answer": return utils.one_hot(action_ids["action_fallout_slots"], domain.num_actions) else: # we can't handle the current intent so just pass control to another policy return np.zeros(domain.num_actions)
def probabilities_using_best_policy(self, tracker, domain): # type: (DialogueStateTracker, Domain) -> List[float] # given a state, predict next action via asking a human probabilities = self.base_ensemble.probabilities_using_best_policy( tracker, domain) pred_out = int(np.argmax(probabilities)) latest_action_was_listen = self._print_history(tracker) action_name = domain.action_for_index(pred_out).name() colored_name = utils.wrap_with_color(action_name, utils.bcolors.OKBLUE) if latest_action_was_listen: print("The bot wants to [{}] due to the intent. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "3", "0"], "\t1.\tYes\n" + "\t2.\tNo, intent is right but the action is wrong\n" + "\t3.\tThe intent is wrong\n" + "\t0.\tExport current conversations as stories and quit\n") else: print("The bot wants to [{}]. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "0"], "\t1.\tYes.\n" + "\t2.\tNo, the action is wrong.\n" + "\t0.\tExport current conversations as stories and quit\n") if user_input == "1": # max prob prediction was correct if action_name == ACTION_LISTEN_NAME: print("Next user input:") return probabilities elif user_input == "2": # max prob prediction was false, new action required # action wrong y = self._request_action(probabilities, domain, tracker) # update tracker with new action new_action_name = domain.action_for_index(y).name() # need to copy tracker, because the tracker will be # updated with the new event somewhere else training_tracker = tracker.copy() training_tracker.update(ActionExecuted(new_action_name)) self._fit_example(training_tracker, domain) self.write_out_story(tracker) return utils.one_hot(y, domain.num_actions) elif user_input == "3": # intent wrong and maybe action wrong intent = self._request_intent(tracker, domain) latest_message = copy.copy(tracker.latest_message) latest_message.intent = intent tracker.update(UserUtteranceReverted()) tracker.update(latest_message) for e in domain.slots_for_entities(latest_message.entities): tracker.update(e) return self.probabilities_using_best_policy(tracker, domain) elif user_input == "0": self._export_stories(tracker) raise TrainingFinishedException() else: raise Exception( "Incorrect user input received '{}'".format(user_input))
def test_on_hot_out_of_range(): with pytest.raises(ValueError): utils.one_hot(4, 3)
def test_on_hot(): r = utils.one_hot(4, 6) assert (r[[0, 1, 2, 3, 5]] == 0).all() assert r[4] == 1