The dialogue bot is based on [1] which introduces Hybrid Code Networks (HCNs) that combine an RNN with domain-specific knowledge and system action templates.
Diagram 1. Dotted lines correspond to unrequired (optional) modules, black squares to trained models, trapezes are modules that depend on a dataset and must be provided by software developer.
Here is a simple example of interaction with a trained dialogue bot (can be downloaded with deeppavlov/download.py):
>> Hello, welcome to the Cambridge restaurant system. You can ask for restaurants by area, price range or food type. How may I help you?
x::hi, i want cheap food
2018-05-16 12:28:48.459 INFO in 'deeppavlov.models.go_bot.bot'['bot'] at line 346: Made api_call with {'pricerange': 'cheap'}, got 22 results.
>> The lucky star serves chinese food in the cheap price range.
x::is there anything with french food?
2018-05-16 12:29:02.795 INFO in 'deeppavlov.models.go_bot.bot'['bot'] at line 346: Made api_call with {'pricerange': 'cheap', 'food': 'french'}, got 0 results.
>> Sorry there is no french restaurant in the cheap price range.
x::ok, maybe there is something in expensive pricerange?
2018-05-16 12:29:23.337 INFO in 'deeppavlov.models.go_bot.bot'['bot'] at line 346: Made api_call with {'pricerange': 'expensive', 'food': 'french'}, got 2 results.
>> Cote serves french food in the expensive price range.
x::in what part of town is it?
2018-05-16 12:29:31.193 INFO in 'deeppavlov.models.go_bot.bot'['bot'] at line 346: Made api_call with {'pricerange': 'expensive', 'food': 'french'}, got 2 results.
>> Restaurant two two is a nice place in the north of town serving tasty french food.
x::ok, give me their phone number
>> The phone number of restaurant two two is 01223 351880.
x::address and post code too
>> Restaurant two two is on 22 chesterton road chesterton, c.b 4, 3 a.x.
x::ok, thank you!
>> Restaurant two two serves french food in the expensive price range.
x::and if i wanted an italian restuarant?
2018-05-16 12:30:15.98 INFO in 'deeppavlov.models.go_bot.bot'['bot'] at line 346: Made api_call with {'pricerange': 'expensive', 'food': 'italian'}, got 4 results.
>> Frankie and bennys serves italian food in the expensive price range.
x::more cheaply priced?
2018-05-16 12:30:36.560 INFO in 'deeppavlov.models.go_bot.bot'['bot'] at line 346: Made api_call with {'pricerange': 'cheap', 'food': 'italian'}, got 5 results.
>> Da vinci pizzeria serves italian food in the cheap price range.
x::ok, give me their phone number and address, please
>> The phone number of da vinci pizzeria is 01223 351707 and it is on 20 milton road chesterton.
x::thanks
>> Da vinci pizzeria serves italian food in the cheap price range.
x::bye
>> You are welcome!
TO TRAIN a go_bot model you should have:
- (optional, but recommended) pretrained named entity recognition model (NER)
- config
deeppavlov/configs/ner/ner_dstc2.jsonis recommended
- config
- (optional, but recommended) pretrained intents classifier model
- config
deeppavlov/configs/intents/intents_dstc2_big.jsonis recommended
- config
- (optional) downloaded english fasttext embeddings trained on wiki (https://s3-us-west-1.amazonaws.com/fasttext-vectors/wiki.en.zip)
- fasttext embeddings can loaded via
python3 deeppavlov/download.py -all - you can use any english embeddings of your choice, but edit go_bot config accordingly
- fasttext embeddings can loaded via
TO INFER from a go_bot model you should additionaly have:
- pretrained vocabulary of dataset utterance tokens
- it is trained in the same config as go_bot model
- pretrained goal-oriented bot model itself
- config
deeppavlov/configs/go_bot/gobot_dstc2.jsonis recommended slot_fillersection of go_bot's config should match NER's configurationintent_classifiersection of go_bot's config should match classifier's configuration- double-check that corresponding
load_paths point to NER and intent classifier model files
- config
namealways equals to"go_bot"word_vocab— vocabulary of tokens from context utterancesname—"default_vocab"(for vocabulary's implementation seedeeppavlov.core.data.vocab)level—"token",tokenizer—{ "name": "split_tokenizer" },save_path—"vocabs/token.dict"load_path—"vocabs/token.dict"
template_path— map from actions to text templates for response generationtemplate_type— type of templates to use ("BaseTemplate"by default) (optional)database– database that will be used during model inference to make "api_call" action and getdb_result(optional)name—"sqlite_database"fromdeeppavlov.core.data.sqlite_database:Sqlite3Databaseor your implementationtable_name– sqlite table nameprimary_keys– list of primary table keys' nameskeys– ordered list of tabke key names, if not set will be infered from loaded database automatically (optional, reccomended not to be used)unknown_value– value used to fill unknown column values (defaults to"UNK") (optional)save_path– path to database filename (will load to it, and save to it)
api_call_action– label of action that corresponds to database api call (the same label that is used to represent the action in yourtemplate_pathfile), during interaction it will be used to getdb_resultfromdatabase(optional)use_action_mask— in case of true, action mask is applied to network output (False, by default)tokenizer— one of tokenizers fromdeeppavlov.models.tokenizersmodulename— tokenizer name- other arguments specific to your tokenizer
bow_embedder—deeppavlov.models.embedders.bow_embedderornull(optional)name— embedder name- other arguments specific to your bag of words embedder
embedder— one of embedders fromdeeppavlov.models.embeddersmodule (optional)name— embedder name ("fasttext"recommended, seedeeppavlov.models.embedders.fasttext_embedder)- other arguments specific to your embedder
tracker— dialogue state tracker fromdeeppavlov.models.trackersname— tracker name ("default_tracker"or"featurized_tracker"recommended)slot_vals— list of slots that should be tracked
network_parameters— parameters for reccurent network that handles dialogue policy managementsave_path— name of the file that the model will be saved toload_path— name of the file that the model will be loaded fromoptimizer– name of tf.train.Optimizer subclass, defaults to"AdamOptimizer"(optional)learning_rate— learning rate during trainingend_learning_rate— if set, learning rate starts fromlearning ratevalue and decays polynomially to value ofend_learning_rate(optional)decay_steps– number of steps for learning rate to decay, defaults to 1000 (optional)decay_power– power used to calculate learning rate decay for polynomial strategy, defaults to 1.0 (optional)dropout_rate— keep probability for dropout layer applied to input features, defaults to 1.0 (optional)l2_reg_coef– l2 regularization coeffitient (applied to input and output layer), defaults to 0.0 (optional)hidden_dim— hidden state dimensiondense_size— LSTM input sizeobs_size— input features size (must be set to number ofbow_embedderfeatures,embedderfeatures,intent_classifierfeatures, context features(=2) plustrackerstate size plus action size), will be calculated automatically if not set (optional)action_size— output action size, will be calculated automatically if not set (optional)attention_mechanism– dict (ornull) that describes attention applied to network inputs:attention_mechanism.type– type of attention mechanism, one of ("general","bahdanau","light_general","light_bahdanau","cs_general","cs_bahdanau")attention_mechanism.hidden_size– attention hidden state sizeattention_mechanism.max_num_tokens– maximum number of input tokens used in attentioattention_mechanism.depth– number of averages used in constrained attentions ("cs_bahdanau"or"cs_general")attention_mechanism.action_as_key– whether to use action from previous timestep as key to attention (defaults tofalse) (optional)attention_mechanism.intent_as_key– whether to use utterance intents as key to attention (defaults tofalse) (optional)attention_mechanism.projected_align– whether to use output projection (defaults tofalse) (optional)
slot_filler— model that predicts slot values for a given utterancename— slot filler name ("dstc_slotfilling"recommended, for implementation seedeeppavlov.models.ner)- other slot filler arguments
intent_classifier— model that outputs intents probability distribution for a given utterancename— intent classifier name ("intent_model"recommended, for implementation seedeeppavlov.models.classifiers.intents)- classifier's other arguments
debug— whether to display debug output (defaults tofalse) (optional)
For a working exemplary config see deeeppavlov/configs/go_bot/gobot_dstc2.json (model without embeddings).
A minimal model without slot_filler, intent_classifier and embedder is configured in deeeppavlov/configs/go_bot/gobot_dstc2_minimal.json.
A full model (with fasttext embeddings) configuration is in deeeppavlov/configs/go_bot/gobot_dstc2_all.json.
The best state-of-the-art model (with attention mechanism, relies on embedder and does not use bag-of-words) is configured in deeeppavlov/configs/go_bot/gobot_dstc2_best.json.
Available pretrained for DSTC2 dataset models:
- model for
deeppavlov/configs/go_bot/gobot_dstc2.json - model for
deeppavlov/configs/go_bot/gobot_dstc2_best.json
To use pretrained model you should firstly download it (if you haven't done it already by python3 deeppavlov/download.py -all):
cd deeppavlov
python3 deep.py interact path/to/config.json -dTo infer from a pretrained model with config path equal to path/to/config.json:
from deeppavlov.core.commands.infer import build_model_from_config
from deeppavlov.core.common.file import read_json
CONFIG_PATH = 'path/to/config.json'
model = build_model_from_config(read_json(CONFIG_PATH))
utterance = ""
while utterance != 'exit':
print(">> " + model([utterance])[0])
utterance = input(':: ')To interact via command line use deeppavlov/deep.py script:
cd deeppavlov
python3 deep.py interact path/to/config.jsonTo train model with config path path/to/config.json you should firstly download all the needed data (if you haven't done it already by python3 deeppavlov/download.py -all):
cd deeppavlov
python3 deep.py train path/to/config.json -dThe script will download needed data (dataset, embeddings) for the particular model.
To be used for training, your config json file should include parameters:
dataset_readername—"your_reader_here"for a custom dataset or"dstc2_v2_reader"to use DSTC2 (for implementation seedeeppavlov.dataset_readers.dstc2_reader)data_path— a path to a dataset file, which in case of"dstc2_v2_reader"will be automatically downloaded from internet and placed todata_pathdirectory
dataset_iterator— it should always be set to{"name": "dialog_iterator"}(for implementation seedeeppavlov.dataset_iterators.dialog_iterator.py)
See deeeppavlov/configs/go_bot/gobot_dstc2.json for details.
The easiest way to run the training is by using deeppavlov/deep.py script:
cd deeppavlov
python3 deep.py train path/to/config.jsonThe Hybrid Code Network model was trained and evaluated on a modification of a dataset from Dialogue State Tracking Challenge 2 [2]. The modifications were as follows:
-
new turns with api calls
- added api_calls to restaurant database (example:
{"text": "api_call area=\"south\" food=\"dontcare\" pricerange=\"cheap\"", "dialog_acts": ["api_call"]})
- added api_calls to restaurant database (example:
-
new actions
- bot dialog actions were concatenated into one action (example:
{"dialog_acts": ["ask", "request"]}->{"dialog_acts": ["ask_request"]}) - if a slot key was associated with the dialog action, the new act was a concatenation of an act and a slot key (example:
{"dialog_acts": ["ask"], "slot_vals": ["area"]}->{"dialog_acts": ["ask_area"]})
- bot dialog actions were concatenated into one action (example:
-
new train/dev/test split
- original dstc2 consisted of three different MDP polices, the original train and dev datasets (consisting of two polices) were merged and randomly split into train/dev/test
-
minor fixes
- fixed several dialogs, where actions were wrongly annotated
- uppercased first letter of bot responses
- unified punctuation for bot responses'
If your model uses DSTC2 and relies on dstc2_v2_reader DSTC2Version2DatasetReader, all needed files, if not present in the dataset_reader.data_path directory, will be downloaded from internet.
If your model needs to be trained on different data, you have several ways of achieving that (sorted by increase in the amount of code):
-
Use
"dialog_iterator"in dataset iterator config section and"dstc2_v2_reader"in dataset reader config section (the simplest, but not the best way):- set
dataset_iterator.data_pathto your data directory; - your data files should have the same format as expected in
deeppavlov.dataset_readers.dstc2_reader:DSTC2Version2DatasetReader.read()function.
- set
-
Use
"dialog_iterator"in dataset iterator config section and"your_dataset_reader"in dataset reader config section (recommended):- clone
deeppavlov.dataset_readers.dstc2_reader:DSTC2Version2DatasetReadertoYourDatasetReader; - register as
"your_dataset_reader"; - rewrite so that it implements the same interface as the origin. Particularly,
YourDatasetReader.read()must have the same output asDSTC2DatasetReader.read():train— training dialog turns consisting of tuples:- first tuple element contains first user's utterance info (as dict with the following fields):
text— utterance stringintents— list of string intents, associated with user's utterancedb_result— a database response (optional)episode_done— set totrue, if current utterance is the start of a new dialog, andfalse(or skipped) otherwise (optional)
- second tuple element contains second user's response info
text— utterance stringact— an act, associated with the user's utterance
- first tuple element contains first user's utterance info (as dict with the following fields):
valid— validation dialog turns in the same formattest— test dialog turns in the same format
- clone
-
Use your own dataset iterator and dataset reader (if 2. doesn't work for you):
- your
YourDatasetIterator.gen_batches()class method output should match the input format for chainer fromconfigs/go_bot/gobot_dstc2.json.
- your
You should provide a maping from actions to text templates in the following format (and set template_type to "BaseTemplate", DSTC2 uses an extention of templates –"DualTemplate", you will probably not need it):
action\ttemplate,- where filled slots in templates should start with "#" and mustn't contain whitespaces.
For example,
bye You are welcome!
canthear Sorry, I can't hear you.
expl-conf_area Did you say you are looking for a restaurant in the #area of town?
inform_area+inform_food+offer_name #name is a nice place in the #area of town serving tasty #food food.If your dataset doesn't imply any api calls to an external database, just do not set database and api_call_action parameters and skip the section below.
Otherwise, you should specify them and
- provide sql table with requested items or
- construct such table from provided in train samples
db_resultitems. This can be done with the following script:
cd deeppavlov
python3 deep.py train configs/go_bot/database_yourdataset.jsonwhere configs/go_bot/database_yourdataset.json is a copy of configs/go_bot/database_dstc2.json with configured save_path, primary_keys and unknown_value.
Scores for different modifications of our bot model:
| Model | Config | Test turn textual accuracy |
|---|---|---|
| basic bot | gobot_dstc2_minimal.json |
0.3809 |
| bot with slot filler & fasttext embeddings | 0.5317 | |
| bot with slot filler & intents | gobot_dstc2.json |
0.5113 |
| bot with slot filler & intents & embeddings | gobot_dstc2_all.json |
0.5145 |
| bot with slot filler & embeddings & attention | gobot_dstc2_best.json |
0.5525 |
There is another modification of DSTC2 dataset called dialog babi Task6 [3]. It differs from ours in train/valid/test split and intent/action labeling.
These are the test scores provided by Williams et al. (2017) [1] (can't be directly compared with above):
| Model | Test turn textual accuracy |
|---|---|
| Bordes and Weston (2016) [4] | 0.411 |
| Perez and Liu (2016) [5] | 0.487 |
| Eric and Manning (2017) [6] | 0.480 |
| Williams et al. (2017) [1] | 0.556 |
#TODO: add dialog accuracies
[2] Dialog State Tracking Challenge 2 dataset
[3] The bAbI project
[4] Antoine Bordes, Y-Lan Boureau & Jason Weston "Learning end-to-end goal-oriented dialog" - 2017
[5] Fei Liu, Julien Perez "Gated End-to-end Memory Networks" - 2016