Rasa Core version: 0.8.0a4
Python version: 3.6.3. (Anaconda venv)
Operating system MacOSX
Issue: When using line code : AttributeError: module '__main__' has no attribute 'RestaurantPolicy' i get same error every time (even with rasa 0.7.9):
Traceback (most recent call last):
File "", line 1, in
File "/Users/dejanmaric/Desktop/rasa_core-master/examples/restaurantbot/rasa_core/rasa_core/agent.py", line 61, in load
ensemble = PolicyEnsemble.load(path, featurizer)
File "/Users/dejanmaric/Desktop/rasa_core-master/examples/restaurantbot/rasa_core/rasa_core/policies/ensemble.py", line 129, in load
policy_cls = utils.class_from_module_path(policy_name)
File "/Users/dejanmaric/Desktop/rasa_core-master/examples/restaurantbot/rasa_core/rasa_core/utils.py", line 32, in class_from_module_path
return getattr(m, class_name)
AttributeError: module '__main__' has no attribute 'RestaurantPolicy'
Same error
Has this issue been solved?
@tmbo I'm trying to solve this issue and I'd really appreciate some advice. (I'm new to Python.)
The following is from utils.py. The module_name is assigned as "__main__" because "__main__.RestaurantPolicy" is passed as the path from policy_metadata in restaurantbot/models/dialogue.
def class_from_module_path(module_path):
"""Given the module name and path of a class, tries to retrieve the class.
The loaded class can be used to instantiate new objects. """
import importlib
# load the module, will raise ImportError if module cannot be loaded
if "." in module_path:
module_name, _, class_name = module_path.rpartition('.')
m = importlib.import_module(module_name)
# get the class, will raise AttributeError if class cannot be found
return getattr(m, class_name)
else:
return globals()[module_path]
That didn't make sense since (I think) we can't really pass "__main__" as a module name. So I changed the policy_metadata file generated inside restaurantbot/models/dialogue. I updated "__main__.RestaurantPolicy" to "rasa_core.policies.RestaurantPolicy.RestaurantPolicy". And I created a file named RestaurantPolicy at rasa_core/policies with only the definition of the class RestaurantPolicy:
from rasa_core.policies.keras_policy import KerasPolicy
class RestaurantPolicy(KerasPolicy):
def model_architecture(self, num_features, num_actions, max_history_len):
"""Build a Keras model and return a compiled model."""
from keras.layers import LSTM, Activation, Masking, Dense
from keras.models import Sequential
n_hidden = 32 # size of hidden layer in LSTM
# Build Model
batch_shape = (None, max_history_len, num_features)
model = Sequential()
model.add(Masking(-1, batch_input_shape=batch_shape))
model.add(LSTM(n_hidden, batch_input_shape=batch_shape))
model.add(Dense(input_dim=n_hidden, output_dim=num_actions))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
logger.debug(model.summary())
return model
Now the bot works. Meaning that there is a rasa_core.agent.Agent object running. But any text sent using agent.handle_message("_greet") comes back with an empty output. When I use agent.train_online, I can see that the bot is not trained at all. So good news is that the above solution works, but I'm not sure why the bot isn't trained or isn't responding. These are the probability values when I use agent.train_online:
Message:
Hi
User said: Hi
What intent is this?
0 greet
1 affirm
2 deny
3 inform
4 thankyou
5 request_info
0
------
Chat history:
bot did: None
bot did: action_listen
user said: Hi
whose intent is: greet
we currently have slots: cuisine: None, info: None, location: None, matches: Non
e, people: None, price: None
------
The bot wants to [action_listen] due to the intent. Is this correct?
1. Yes
2. No, intent is right but the action is wrong
3. The intent is wrong
0. Export current conversations as stories and quit
2
------
Chat history:
bot did: None
bot did: action_listen
user said: Hi
whose intent is: greet
we currently have slots: cuisine: None, info: None, location: None, matches: Non
e, people: None, price: None
------
what is the next action for the bot?
0 action_listen 0.12
1 action_restart 0.04
2 utter_greet 0.03
3 utter_goodbye 0.04
4 utter_default 0.03
5 utter_ack_dosearch 0.10
6 utter_ack_findalternatives 0.04
7 utter_ack_makereservation 0.04
8 utter_ask_cuisine 0.03
9 utter_ask_helpmore 0.04
10 utter_ask_howcanhelp 0.05
11 utter_ask_location 0.05
12 utter_ask_moreupdates 0.04
13 utter_ask_numpeople 0.08
14 utter_ask_price 0.08
15 utter_on_it 0.04
16 action_search_restaurants 0.07
17 action_suggest 0.08
2
thanks! The bot will now [utter_greet]
And then it crashes because:
IndexError: too many indices for array
Do let me know if I'm doing something completely wrong. Thank you!
What is the stacktrace for that Indexerror?
Can you please post the commands you execute so that I can try to reproduce this issue? (I mean the commands that lead to AttributeError: module 'main' has no attribute 'RestaurantPolicy')
`from rasa_core.interpreter import RasaNLUInterpreter
from rasa_core.agent import Agent
agent = Agent.load("models/dialogue", interpreter=RasaNLUInterpreter("models/nlu/current"))`
Running agent = Agent.load("models/dialogue", interpreter=RasaNLUInterpreter("models/nlu/default/current")) in a REPL is problematic because models/dialogue/policy_metadata.json points to __main__ (a "relative" concept) rather than a fixed module (in this case bot. When running in a REPL, __main__ is the REPL, so the class loader doesn't find the RestaurantPolicy class defined in bot.py. My solution was to change the metadata.json file to point to bot.RestaurantPolicy rather than __main__.RestaurantPolicy.
But alas, we still have empty output:
>>> agent.handle_message(("_greet"))
[]
Thanks! This worked for me - "My solution was to change the metadata.json file to point to bot.RestaurantPolicy rather than __main__.RestaurantPolicy."
@tmbo
I was able to load the bot successfully but with lots of warning message like this
Hi
/Users/anaconda2/lib/python2.7/site-packages/sklearn/preprocessing/label.py:151: DeprecationWarning: The truth value of an empty array is ambiguous. Returning False, but in future this will result in an error. Use array.size > 0 to check that an array is not empty.
if diff:
how can I help you?
what kind of cuisine would you like?
Mexican
where?
for how many people?
Fremont for 5
if you'd like to modify anything else, please tell me what
Is there a way i can get rid of this warning message ? Any suggestion would be greatly appreciated.Thanks!!
@tmbo Is there an option to deploy the restaurant bot in FB page ? How would i change from one flow to another or make the bot stop or quit ?
This has been fixed in the latest master code.
The issue is the following: A custom policy can not be defined in the same file as the one that is used for training / starting the bot - basically, follow good python style and put the custom policy into its own file / module.
The issue arises when the trained model is persisted. To be able to load that model again, the modul path of the custom policy is stored as part of the persisted model. If the custom policy is placed inside the main script (e.g. bot.py) and the model is trained with something like python bot.py, that persisted path will be main.CustomPolicy instead of bot.CustomPolicy. If the model is now getting loaded again, python can't find the class main.CustomPolicy (makes sense, because it is not in main.py but in bot.py).
TL;DR simply place custom policies in their own file / module.
Most helpful comment
This has been fixed in the latest master code.
The issue is the following: A custom policy can not be defined in the same file as the one that is used for training / starting the bot - basically, follow good python style and put the custom policy into its own file / module.
The issue arises when the trained model is persisted. To be able to load that model again, the modul path of the custom policy is stored as part of the persisted model. If the custom policy is placed inside the main script (e.g.
bot.py) and the model is trained with something likepython bot.py, that persisted path will bemain.CustomPolicyinstead ofbot.CustomPolicy. If the model is now getting loaded again, python can't find the classmain.CustomPolicy(makes sense, because it is not inmain.pybut inbot.py).TL;DR simply place custom policies in their own file / module.