diff --git a/README.md b/README.md
index 7624393b01..1bc716d1a8 100644
--- a/README.md
+++ b/README.md
@@ -11,12 +11,12 @@ DeepPavlov is designed for
## Quick Links
-* Demo [*demo.ipavlov.ai*](https://demo.ipavlov.ai/)
+* Demo [*demo.deeppavlov.ai*](https://demo.deeppavlov.ai/)
* Documentation [*docs.deeppavlov.ai*](http://docs.deeppavlov.ai/)
* Model List [*docs:features/*](http://docs.deeppavlov.ai/en/master/features/overview.html)
* Contribution Guide [*docs:contribution_guide/*](http://docs.deeppavlov.ai/en/master/devguides/contribution_guide.html)
* Issues [*github/issues/*](https://github.com/deepmipt/DeepPavlov/issues)
-* Forum [*forum.ipavlov.ai*](https://forum.ipavlov.ai/)
+* Forum [*forum.deeppavlov.ai*](https://forum.deeppavlov.ai/)
* Blogs [*medium.com/deeppavlov*](https://medium.com/deeppavlov)
* Tutorials [*examples/*](https://github.com/deepmipt/DeepPavlov/tree/master/examples) and [extended colab tutorials](https://github.com/deepmipt/dp_tutorials)
* Docker Hub [*hub.docker.com/u/deeppavlov/*](https://hub.docker.com/u/deeppavlov/)
diff --git a/deeppavlov/__init__.py b/deeppavlov/__init__.py
index 8d259ea039..9b773df304 100644
--- a/deeppavlov/__init__.py
+++ b/deeppavlov/__init__.py
@@ -37,7 +37,7 @@ def evaluate_model(config: [str, Path, dict], download: bool = False, recursive:
except ImportError:
'Assuming that requirements are not yet installed'
-__version__ = '0.6.0'
+__version__ = '0.6.1'
__author__ = 'Neural Networks and Deep Learning lab, MIPT'
__description__ = 'An open source library for building end-to-end dialog systems and training chatbots.'
__keywords__ = ['NLP', 'NER', 'SQUAD', 'Intents', 'Chatbot']
diff --git a/deeppavlov/configs/go_bot/gobot_dstc2_minimal.json b/deeppavlov/configs/go_bot/gobot_dstc2_minimal.json
index c210b0c108..eeadeadc31 100644
--- a/deeppavlov/configs/go_bot/gobot_dstc2_minimal.json
+++ b/deeppavlov/configs/go_bot/gobot_dstc2_minimal.json
@@ -1,7 +1,7 @@
{
"dataset_reader": {
"class_name": "dstc2_reader",
- "data_path": "{DOWNLOADS_PATH}/dstc2"
+ "data_path": "{DATA_PATH}"
},
"dataset_iterator": {
"class_name": "dialog_iterator"
@@ -21,49 +21,41 @@
"id": "word_vocab",
"class_name": "simple_vocab",
"fit_on": ["x_tokens"],
- "save_path": "{MODELS_PATH}/gobot_dstc2_minimal/word.dict",
- "load_path": "{MODELS_PATH}/gobot_dstc2_minimal/word.dict"
- },
- {
- "id": "restaurant_database",
- "class_name": "sqlite_database",
- "table_name": "mytable",
- "primary_keys": ["name"],
- "save_path": "{DOWNLOADS_PATH}/dstc2/resto.sqlite"
+ "save_path": "{MODEL_PATH}/word.dict",
+ "load_path": "{MODEL_PATH}/word.dict"
},
{
"class_name": "go_bot",
- "load_path": "{MODELS_PATH}/gobot_dstc2_minimal/model",
- "save_path": "{MODELS_PATH}/gobot_dstc2_minimal/model",
+ "load_path": "{MODEL_PATH}/model",
+ "save_path": "{MODEL_PATH}/model",
"in": ["x"],
"in_y": ["y"],
"out": ["y_predicted"],
"main": true,
"debug": false,
- "learning_rate": [2e-3, 2e-2],
- "learning_rate_decay": "1cycle",
- "learning_rate_decay_epochs": 20,
+ "learning_rate": 0.003,
+ "learning_rate_drop_patience": 5,
+ "learning_rate_drop_div": 10.0,
"momentum": 0.95,
"optimizer": "tensorflow.train:AdamOptimizer",
"clip_norm": 2.0,
- "dropout_rate": 0.3,
- "l2_reg_coef": 1e-4,
+ "dropout_rate": 0.4,
+ "l2_reg_coef": 3e-4,
"hidden_size": 128,
- "dense_size": 64,
+ "dense_size": 160,
"word_vocab": "#word_vocab",
- "template_path": "{DOWNLOADS_PATH}/dstc2/dstc2-templates.txt",
- "template_type": "DualTemplate",
- "database": "#restaurant_database",
- "api_call_action": "api_call",
+ "template_path": "{DATA_PATH}/dstc2-templates.txt",
+ "template_type": "DefaultTemplate",
+ "database": null,
+ "api_call_action": null,
"use_action_mask": false,
"slot_filler": null,
"intent_classifier": null,
- "embedder": null,
- "bow_embedder": {
- "class_name": "bow",
- "depth": "#word_vocab.__len__()",
- "with_counts": true
+ "embedder": {
+ "class_name": "glove",
+ "load_path": "{DOWNLOADS_PATH}/embeddings/glove.6B.100d.txt"
},
+ "bow_embedder": null,
"tokenizer": {
"class_name": "stream_spacy_tokenizer",
"lowercase": false
@@ -81,10 +73,10 @@
"metrics": ["per_item_dialog_accuracy"],
"validation_patience": 10,
- "val_every_n_epochs": 1,
+ "val_every_n_batches": 15,
- "log_every_n_batches": -1,
- "log_every_n_epochs": 1,
+ "log_every_n_batches": 15,
+ "log_on_k_batches": -1,
"show_examples": false,
"evaluation_targets": [
"valid",
@@ -95,12 +87,15 @@
"metadata": {
"variables": {
"ROOT_PATH": "~/.deeppavlov",
+ "CONFIGS_PATH": "{DEEPPAVLOV_PATH}/configs",
"DOWNLOADS_PATH": "{ROOT_PATH}/downloads",
- "MODELS_PATH": "{ROOT_PATH}/models"
+ "DATA_PATH": "{DOWNLOADS_PATH}/dstc2",
+ "MODELS_PATH": "{ROOT_PATH}/models",
+ "MODEL_PATH": "{MODELS_PATH}/gobot_dstc2_minimal"
},
"requirements": [
"{DEEPPAVLOV_PATH}/requirements/tf.txt",
- "{DEEPPAVLOV_PATH}/requirements/fasttext.txt",
+ "{DEEPPAVLOV_PATH}/requirements/gensim.txt",
"{DEEPPAVLOV_PATH}/requirements/spacy.txt",
"{DEEPPAVLOV_PATH}/requirements/en_core_web_sm.txt"
],
@@ -109,9 +104,17 @@
"server_utils": "GoalOrientedBot"
},
"download": [
+ {
+ "url": "http://files.deeppavlov.ai/deeppavlov_data/gobot_dstc2_v9.tar.gz",
+ "subdir": "{MODELS_PATH}"
+ },
+ {
+ "url": "http://files.deeppavlov.ai/embeddings/glove.6B.100d.txt",
+ "subdir": "{DOWNLOADS_PATH}/embeddings"
+ },
{
"url": "http://files.deeppavlov.ai/datasets/dstc2_v2.tar.gz",
- "subdir": "{DOWNLOADS_PATH}/dstc2"
+ "subdir": "{DATA_PATH}"
}
]
}
diff --git a/deeppavlov/dataset_readers/conll2003_reader.py b/deeppavlov/dataset_readers/conll2003_reader.py
index c204ddb4c4..19d2bc1d87 100644
--- a/deeppavlov/dataset_readers/conll2003_reader.py
+++ b/deeppavlov/dataset_readers/conll2003_reader.py
@@ -1,9 +1,11 @@
from pathlib import Path
+from logging import getLogger
from deeppavlov.core.common.registry import register
from deeppavlov.core.data.dataset_reader import DatasetReader
from deeppavlov.core.data.utils import download_decompress
+log = getLogger(__name__)
@register('conll2003_reader')
class Conll2003DatasetReader(DatasetReader):
@@ -80,10 +82,19 @@ def parse_ner_file(self, file_name: Path):
tags = []
else:
if self.provide_pos:
- token, pos, *_, tag = line.split()
- pos_tags.append(pos)
+ try:
+ token, pos, *_, tag = line.split()
+ pos_tags.append(pos)
+ except:
+ log.warning('Skip {}, splitted as {}'.format(repr(line), repr(line.split())))
+ continue
else:
- token, *_, tag = line.split()
+ try:
+ token, *_, tag = line.split()
+ except:
+ log.warning('Skip {}, splitted as {}'.format(repr(line), repr(line.split())))
+ continue
+
tags.append(tag)
tokens.append(token)
@@ -111,4 +122,3 @@ def _iob2_to_iob(tags):
iob_tags.append(tag)
return iob_tags
-
diff --git a/deeppavlov/utils/server/server.py b/deeppavlov/utils/server/server.py
index 65a4439925..1c66e91cf8 100644
--- a/deeppavlov/utils/server/server.py
+++ b/deeppavlov/utils/server/server.py
@@ -12,14 +12,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import ssl
-from logging import getLogger, Filter, LogRecord
+import logging
from pathlib import Path
-from typing import List, Tuple
+from ssl import PROTOCOL_TLSv1_2
+from typing import Dict, List, Optional
-from flasgger import Swagger, swag_from
-from flask import Flask, request, jsonify, redirect, Response
-from flask_cors import CORS
+import uvicorn
+from fastapi import FastAPI, HTTPException
+from fastapi.utils import generate_operation_id_for_path
+from pydantic import BaseConfig, BaseModel, Schema
+from pydantic.fields import Field
+from pydantic.main import MetaModel
+from starlette.responses import JSONResponse, RedirectResponse
from deeppavlov.core.agent.dialog_logger import DialogLogger
from deeppavlov.core.commands.infer import build_model
@@ -32,24 +36,22 @@
SERVER_CONFIG_FILENAME = 'server_config.json'
-class PollerFilter(Filter):
- """PollerFilter class is used to filter POST requests to /probe endpoint from logs."""
- def filter(self, record: LogRecord) -> bool:
+class ProbeFilter(logging.Filter):
+ """ProbeFilter class is used to filter POST requests to /probe endpoint from logs."""
+ def filter(self, record: logging.LogRecord) -> bool:
"""To log the record method should return True."""
return 'POST /probe HTTP' not in record.getMessage()
-log = getLogger(__name__)
-werklog = getLogger('werkzeug')
-werklog.addFilter(PollerFilter())
-
-app = Flask(__name__)
-CORS(app)
+log = logging.getLogger(__name__)
+uvicorn_log = logging.getLogger('uvicorn')
+uvicorn_log.addFilter(ProbeFilter())
+app = FastAPI(__file__)
dialog_logger = DialogLogger(agent_name='dp_api')
-def get_server_params(server_config_path, model_config):
+def get_server_params(server_config_path: Path, model_config: Path) -> Dict:
server_config = read_json(server_config_path)
model_config = parse_config(model_config)
@@ -64,44 +66,34 @@ def get_server_params(server_config_path, model_config):
server_params[param_name] = model_defaults[param_name]
server_params['model_endpoint'] = server_params.get('model_endpoint', '/model')
- server_params['model_args_names'] = server_params['model_args_names'] or model_config['chainer']['in']
-
- return server_params
+ arg_names = server_params['model_args_names'] or model_config['chainer']['in']
+ if isinstance(arg_names, str):
+ arg_names = [arg_names]
+ server_params['model_args_names'] = arg_names
-def interact(model: Chainer, params_names: List[str]) -> Tuple[Response, int]:
- if not request.is_json:
- log.error("request Content-Type header is not application/json")
- return jsonify({
- "error": "request Content-Type header is not application/json"
- }), 400
-
- model_args = []
+ return server_params
- data = request.get_json()
- dialog_logger.log_in(data)
- for param_name in params_names:
- param_value = data.get(param_name)
- if param_value is None or (isinstance(param_value, list) and len(param_value) > 0):
- model_args.append(param_value)
- else:
- log.error(f"nonempty array expected but got '{param_name}'={repr(param_value)}")
- return jsonify({'error': f"nonempty array expected but got '{param_name}'={repr(param_value)}"}), 400
- lengths = {len(i) for i in model_args if i is not None}
+def interact(model: Chainer, payload: Dict[str, Optional[List]]) -> JSONResponse:
+ model_args = payload.values()
+ dialog_logger.log_in(payload)
+ error_msg = None
+ lengths = {len(model_arg) for model_arg in model_args if model_arg is not None}
if not lengths:
- log.error('got empty request')
- return jsonify({'error': 'got empty request'}), 400
+ error_msg = 'got empty request'
+ elif 0 in lengths:
+ error_msg = 'dot empty array as model argument'
elif len(lengths) > 1:
- log.error('got several different batch sizes')
- return jsonify({'error': 'got several different batch sizes'}), 400
+ error_msg = 'got several different batch sizes'
- batch_size = list(lengths)[0]
- model_args = [arg or [None] * batch_size for arg in model_args]
+ if error_msg is not None:
+ log.error(error_msg)
+ raise HTTPException(status_code=400, detail=error_msg)
- # in case when some parameters were not described in model_args
- model_args += [[None] * batch_size for _ in range(len(model.in_x) - len(model_args))]
+ batch_size = next(iter(lengths))
+ model_args = [arg or [None] * batch_size for arg in model_args]
prediction = model(*model_args)
if len(model.out_params) == 1:
@@ -109,23 +101,20 @@ def interact(model: Chainer, params_names: List[str]) -> Tuple[Response, int]:
prediction = list(zip(*prediction))
result = jsonify_data(prediction)
dialog_logger.log_out(result)
- return jsonify(result), 200
+ return JSONResponse(result)
-def test_interact(model: Chainer, params_names: List[str]) -> Tuple[Response, int]:
- data = request.get_json()
- if not data:
- model_args = [["Test string."] for _ in params_names]
- else:
- model_args = [data.get(param_name) for param_name in params_names]
+def test_interact(model: Chainer, payload: Dict[str, Optional[List]]) -> JSONResponse:
+ model_args = [arg or ["Test string."] for arg in payload.values()]
try:
_ = model(*model_args)
- return Response('["Test passed"]\n'), 200
- except Exception:
- return Response('["Test failed"]\n'), 400
+ return JSONResponse(["Test passed"])
+ except Exception as e:
+ raise HTTPException(status_code=400, detail=e)
-def start_model_server(model_config, https=False, ssl_key=None, ssl_cert=None, port=None):
+def start_model_server(model_config: Path, https: bool = False, ssl_key: Optional[str] = None,
+ ssl_cert: Optional[str] = None, port: Optional[int] = None) -> None:
server_config_path = get_settings_path() / SERVER_CONFIG_FILENAME
server_params = get_server_params(server_config_path, model_config)
@@ -135,9 +124,6 @@ def start_model_server(model_config, https=False, ssl_key=None, ssl_cert=None, p
docs_endpoint = server_params['docs_endpoint']
model_args_names = server_params['model_args_names']
- Swagger.DEFAULT_CONFIG['specs_route'] = docs_endpoint
- Swagger(app)
-
https = https or server_params['https']
if https:
@@ -155,45 +141,44 @@ def start_model_server(model_config, https=False, ssl_key=None, ssl_cert=None, p
log.error(e)
raise e
- ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
- ssl_context.load_cert_chain(ssh_cert_path, ssh_key_path)
+ ssl_version = PROTOCOL_TLSv1_2
+ ssl_keyfile = str(ssh_key_path)
+ ssl_certfile = str(ssh_cert_path)
else:
- ssl_context = None
+ ssl_version = None
+ ssl_keyfile = None
+ ssl_certfile = None
model = build_model(model_config)
- @app.route('/')
- def index():
- return redirect(docs_endpoint)
-
- endpoint_description = {
- 'description': 'A model endpoint',
- 'parameters': [
- {
- 'name': 'data',
- 'in': 'body',
- 'required': 'true',
- 'example': {arg: ['value'] for arg in model_args_names}
- }
- ],
- 'responses': {
- "200": {
- "description": "A model response"
- }
- }
- }
-
- @app.route(model_endpoint, methods=['POST'])
- @swag_from(endpoint_description)
- def answer():
- return interact(model, model_args_names)
-
- @app.route('/probe', methods=['POST'])
- def probe():
- return test_interact(model, model_args_names)
-
- @app.route('/api', methods=['GET'])
- def api():
- return jsonify(model_args_names), 200
-
- app.run(host=host, port=port, threaded=False, ssl_context=ssl_context)
+ def batch_decorator(cls: MetaModel) -> MetaModel:
+ cls.__annotations__ = {arg_name: List[str] for arg_name in model_args_names}
+ cls.__fields__ = {arg_name: Field(name=arg_name, type_=List[str], class_validators=None,
+ model_config=BaseConfig, required=False, schema=Schema(None))
+ for arg_name in model_args_names}
+ return cls
+
+ @batch_decorator
+ class Batch(BaseModel):
+ pass
+
+ @app.get('/', include_in_schema=False)
+ async def redirect_to_docs() -> RedirectResponse:
+ operation_id = generate_operation_id_for_path(name='answer', path=model_endpoint, method='post')
+ response = RedirectResponse(url=f'{docs_endpoint}#/default/{operation_id}')
+ return response
+
+ @app.post(model_endpoint, status_code=200, summary='A model endpoint')
+ async def answer(item: Batch) -> JSONResponse:
+ return interact(model, item.dict())
+
+ @app.post('/probe', status_code=200, include_in_schema=False)
+ async def probe(item: Batch) -> JSONResponse:
+ return test_interact(model, item.dict())
+
+ @app.get('/api', status_code=200, summary='Model argument names')
+ async def api() -> JSONResponse:
+ return JSONResponse(model_args_names)
+
+ uvicorn.run(app, host=host, port=port, logger=uvicorn_log,
+ ssl_version=ssl_version, ssl_keyfile=ssl_keyfile, ssl_certfile=ssl_certfile)
diff --git a/deeppavlov/utils/settings/log_config.json b/deeppavlov/utils/settings/log_config.json
index b3d030928c..0f25e18038 100644
--- a/deeppavlov/utils/settings/log_config.json
+++ b/deeppavlov/utils/settings/log_config.json
@@ -8,12 +8,23 @@
"stderr"
],
"propagate": true
+ },
+ "uvicorn": {
+ "level": "INFO",
+ "handlers": [
+ "uvicorn_handler"
+ ],
+ "propagate": true
}
},
"formatters": {
"default": {
"format": "%(asctime)s.%(msecs)d %(levelname)s in '%(name)s'['%(module)s'] at line %(lineno)d: %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S"
+ },
+ "uvicorn_fmt": {
+ "format":"%(asctime)s %(message)s",
+ "datefmt": "%Y-%m-%d %H:%M:%S"
}
},
"handlers": {
@@ -34,6 +45,12 @@
"level": "DEBUG",
"formatter": "default",
"stream": "ext://sys.stderr"
+ },
+ "uvicorn_handler": {
+ "class": "logging.StreamHandler",
+ "level": "INFO",
+ "formatter": "uvicorn_fmt",
+ "stream": "ext://sys.stdout"
}
}
}
diff --git a/deeppavlov/utils/settings/server_config.json b/deeppavlov/utils/settings/server_config.json
index 2b63e04e3e..4dd43c9a13 100644
--- a/deeppavlov/utils/settings/server_config.json
+++ b/deeppavlov/utils/settings/server_config.json
@@ -2,7 +2,7 @@
"common_defaults": {
"host": "0.0.0.0",
"port": 5000,
- "docs_endpoint": "/docs/",
+ "docs_endpoint": "/docs",
"model_args_names": "",
"https": false,
"https_cert_path": "",
diff --git a/docs/_templates/footer.html b/docs/_templates/footer.html
index 56c16abd8b..c2b05c38af 100644
--- a/docs/_templates/footer.html
+++ b/docs/_templates/footer.html
@@ -16,7 +16,7 @@
{%- block extrafooter %}
-
Problem? Ask a Question or try our Demo
+
Problem? Ask a Question or try our Demo
diff --git a/docs/devguides/contribution_guide.rst b/docs/devguides/contribution_guide.rst
index 8ea975255e..fb5197ef4e 100644
--- a/docs/devguides/contribution_guide.rst
+++ b/docs/devguides/contribution_guide.rst
@@ -105,7 +105,7 @@ added to the framework. Your research will become a part of a common big work
and other people will happily use it and thank you :D
If you still have any questions, either on the contribution process or about
-the framework itself, please ask us at our forum ``_.
+the framework itself, please ask us at our forum ``_.
Follow us on Facebook to get news on releases, new features, approved
contributions and resolved issues ``_
diff --git a/docs/index.rst b/docs/index.rst
index 867822c649..6e2cef9165 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -5,8 +5,8 @@ Welcome to DeepPavlov's documentation!
:glob:
:maxdepth: 1
- QuickStart
Installation
+ QuickStart
General concepts
Configuration file
Models/Skills overview
diff --git a/docs/intro/quick_start.rst b/docs/intro/quick_start.rst
index db70fdc193..e4b3b29aed 100644
--- a/docs/intro/quick_start.rst
+++ b/docs/intro/quick_start.rst
@@ -1,11 +1,13 @@
QuickStart
------------
-There is a bunch of great pre-trained NLP models in DeepPavlov. Each model is
-determined by its config file.
+First, follow instructions on :doc:`Installation page `
+to install ``deeppavlov`` package for Python 3.6/3.7.
-List of models is available on :doc:`the doc page ` or in
-the ``deeppavlov.configs`` (Python):
+DeepPavlov contains a bunch of great pre-trained NLP models. Each model is
+determined by it's config file. List of models is available on
+:doc:`the doc page ` or in
+the ``deeppavlov.configs``:
.. code:: python
@@ -130,3 +132,123 @@ There are also available integrations with various messengers, see
:doc:`Telegram Bot doc page ` and others in the
Integrations section for more info.
+
+Pretrained models
+~~~~~~~~~~~~~~~~~
+
+DeepPavlov provides a wide range of pretrained models and skills.
+See :doc:`features overview ` for more info. Please
+note that most of our models are trained on specific datasets for
+specific tasks and may require further training on you data.
+You can find a list of our out-of-the-box models `below <#out-of-the-box-pretrained-models>`_.
+
+
+Docker images
+~~~~~~~~~~~~~
+
+You can run DeepPavlov models in :doc:`riseapi ` mode
+via Docker without installing DP. Both your CPU and GPU (we support NVIDIA graphic
+processors) can be utilised, please refer our `CPU `_
+and `GPU `_ Docker images run instructions.
+
+
+Out-of-the-box pretrained models
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+While the best way to solve most of the NLP tasks lies through collecting datasets
+and training models according to the domain and an actual task itself, DeepPavlov
+offers several pretrained models, which can be strong baselines for a wide range of tasks.
+
+You can run these models `via Docker <#docker-images>`_ or in ``riseapi``/``risesocket`` mode to use in
+solutions. See :doc:`riseapi ` and :doc:`risesocket `
+modes documentation for API details.
+
+
+Text Question Answering
+=======================
+
+Text Question Answering component answers a question based on a given context (e.g,
+a paragraph of text), where the answer to the question is a segment of the context.
+
+.. table::
+ :widths: auto
+
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | Language | DeepPavlov config | Demo |
+ +==========+================================================================================================+===========================================+
+ | Multi | :config:`squad_bert_multilingual_freezed_emb ` | https://demo.deeppavlov.ai/#/mu/textqa |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | En | :config:`squad_bert_infer ` | https://demo.deeppavlov.ai/#/en/textqa |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | Ru | :config:`squad_ru_bert_infer ` | https://demo.deeppavlov.ai/#/ru/textqa |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+
+
+Name Entity Recognition
+=======================
+
+Named Entity Recognition (NER) classifies tokens in text into predefined categories
+(tags), such as person names, quantity expressions, percentage expressions, names
+of locations, organizations, as well as expression of time, currency and others.
+
+.. table::
+ :widths: auto
+
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | Language | DeepPavlov config | Demo |
+ +==========+================================================================================================+===========================================+
+ | Multi | :config:`ner_ontonotes_bert_mult ` | https://demo.deeppavlov.ai/#/mu/ner |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | En | :config:`ner_ontonotes_bert_mult ` | https://demo.deeppavlov.ai/#/en/ner |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | Ru | :config:`ner_rus_bert ` | https://demo.deeppavlov.ai/#/ru/ner |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+
+
+Insult Detection
+================
+
+Insult detection predicts whether a text (e.g, post or speech in some
+public discussion) is considered insulting to one of the persons it is
+related to.
+
+.. table::
+ :widths: auto
+
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | Language | DeepPavlov config | Demo |
+ +==========+================================================================================================+===========================================+
+ | En | :config:`insults_kaggle_conv_bert ` | https://demo.deeppavlov.ai/#/en/insult |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+
+
+Sentiment Analysis
+==================
+
+Classify text according to a prevailing emotion (positive, negative, etc.) in it.
+
+.. table::
+ :widths: auto
+
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | Language | DeepPavlov config | Demo |
+ +==========+================================================================================================+===========================================+
+ | Ru | :config:`rusentiment_elmo_twitter_cnn ` | https://demo.deeppavlov.ai/#/ru/sentiment |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+
+
+Paraphrase Detection
+====================
+
+Detect if two given texts have the same meaning.
+
+.. table::
+ :widths: auto
+
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | Language | DeepPavlov config | Demo |
+ +==========+================================================================================================+===========================================+
+ | En | :config:`paraphraser_bert ` | None |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
+ | Ru | :config:`paraphraser_rubert ` | None |
+ +----------+------------------------------------------------------------------------------------------------+-------------------------------------------+
diff --git a/examples/Pseudo-labeling for classification.ipynb b/examples/Pseudo-labeling for classification.ipynb
index 45029bf491..8d01922069 100644
--- a/examples/Pseudo-labeling for classification.ipynb
+++ b/examples/Pseudo-labeling for classification.ipynb
@@ -188,10 +188,10 @@
],
"metadata": {
"kernelspec": {
- "display_name": "deep36",
- "language": "python",
- "name": "deep36"
+ "display_name": "Python 3",
+ "name": "python3"
},
+ "accelerator": "GPU",
"language_info": {
"codemirror_mode": {
"name": "ipython",
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000000..e3da3b553d
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,23 @@
+# Examples & Tutorials
+
+* Tutorial for simple bot [[notebook]](gobot_tutorial.ipynb) [[colab]](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/gobot_tutorial.ipynb)
+
+* Tutorial for advanced goal-oriented bot [[notebook]](gobot_extended_tutorial.ipynb) [[colab]](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/gobot_extended_tutorial.ipynb)
+
+* Tutorial for intent classifier [[notebook]](classification_tutorial.ipynb) [[colab]](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/classification_tutorial.ipynb)
+
+* Morphotagger model usage example [[notebook]](morphotagger_example.ipynb) [[colab]](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/morphotagger_example.ipynb)
+
+* Results for neural parameter evolution [[notebook]](evolution_results_analysis.ipynb) [[colab]](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/evolution_results_analysis.ipynb)
+
+* Pseudo-labeling for classication task [[notebook]](Pseudo-labeling%20for%20classification.ipynb) [[colab]](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/Pseudo-labeling%20for%20classification.ipynb)
+
+* Optimal learning rate search in DeepPavlov [[notebook]](super_convergence_tutorial.ipynb) [[colab]](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/super_convergence_tutorial.ipynb)
+
+* Integration of FAQ skill with Yandex Alice (RU) [[notebook]](yandex_faq_ru.ipynb) [[colab]](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/yandex_faq_ru.ipynb)
+
+# Links
+
+More examples are available:
+* [github.com/deepmipt/dp_tutorials/](https://github.com/deepmipt/dp_tutorials)
+* [github.com/deepmipt/db_notebooks/](https://github.com/deepmipt/dp_notebooks).
diff --git a/examples/classification_tutorial.ipynb b/examples/classification_tutorial.ipynb
index b0c7915b1d..e0ab7dccba 100644
--- a/examples/classification_tutorial.ipynb
+++ b/examples/classification_tutorial.ipynb
@@ -2940,10 +2940,10 @@
],
"metadata": {
"kernelspec": {
- "display_name": "tensorflow_kernel2",
- "language": "python",
- "name": "tensorflow_kernel2"
+ "display_name": "Python 3",
+ "name": "python3"
},
+ "accelerator": "GPU",
"language_info": {
"codemirror_mode": {
"name": "ipython",
diff --git a/examples/evolution_results_analysis.ipynb b/examples/evolution_results_analysis.ipynb
index fd8d272f3f..83a7e89e28 100644
--- a/examples/evolution_results_analysis.ipynb
+++ b/examples/evolution_results_analysis.ipynb
@@ -339,10 +339,10 @@
],
"metadata": {
"kernelspec": {
- "display_name": "deep36",
- "language": "python",
- "name": "deep36"
+ "display_name": "Python 3",
+ "name": "python3"
},
+ "accelerator": "GPU",
"language_info": {
"codemirror_mode": {
"name": "ipython",
diff --git a/examples/gobot_extended_tutorial.ipynb b/examples/gobot_extended_tutorial.ipynb
new file mode 100644
index 0000000000..d2ae991dae
--- /dev/null
+++ b/examples/gobot_extended_tutorial.ipynb
@@ -0,0 +1,1386 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "K7nBJnADTgUw"
+ },
+ "source": [
+ "### You can also run the notebook in [COLAB](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/gobot_tutorial.ipynb)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "iPbAiv8KTgU4"
+ },
+ "source": [
+ "# Goal-oriented bot in DeepPavlov"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "us6IsTUETgU5"
+ },
+ "source": [
+ "This tutorial describes how to build a goal/task-oriented dialogue system with DeepPavlov framework. It covers the following steps:\n",
+ "\n",
+ "0. [Data preparation](#0.-Data-Preparation)\n",
+ "1. [Build Database of items](#1.-Build-Database-of-items)\n",
+ "2. [Build Slot Filler](#2.-Build-Slot-Filler)\n",
+ "3. [Build and Train a Bot](#3.-Build-and-Train-a-Bot)\n",
+ "4. [Interact with bot](#4.-Interact-with-Bot)\n",
+ "\n",
+ "An example of the final model served as a telegram bot:\n",
+ "\n",
+ "![gobot_example.png](https://github.com/deepmipt/DeepPavlov/blob/master/examples/img/gobot_example.png?raw=1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 806
+ },
+ "colab_type": "code",
+ "id": "Vtu-7ns2TgUz",
+ "outputId": "8cdc252f-1a35-4ed3-bf0a-f54046d8c6a8"
+ },
+ "outputs": [],
+ "source": [
+ "!pip install deeppavlov"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "4R066YWhTgU6"
+ },
+ "source": [
+ "## 0. Data Preparation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "gppbVe-HTgU7"
+ },
+ "source": [
+ "In this tutorial we build a chatbot for restaurant booking. To train our chatbot we use [Dialogue State Tracking Challenge 2 (DSTC-2)](http://camdial.org/~mh521/dstc/) dataset. DSTC-2 provides dialogues of a human talking to a booking system labelled with slots and dialogue actions. These labels will be used for training a dialogue policy network.\n",
+ "\n",
+ "First of all let's take a quick look at the data for the task. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 137
+ },
+ "colab_type": "code",
+ "id": "K9lF3QFJTgU8",
+ "outputId": "6ab259e2-3f88-4b25-9371-21d3f38fcef3"
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov.dataset_readers.dstc2_reader import SimpleDSTC2DatasetReader\n",
+ "\n",
+ "data = SimpleDSTC2DatasetReader().read('my_data')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 50
+ },
+ "colab_type": "code",
+ "id": "uu56jAGJTgVD",
+ "outputId": "1536bb2c-6c1f-45a6-c0a7-a92106ed7dfe"
+ },
+ "outputs": [],
+ "source": [
+ "!ls my_data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "HmNmE80MTgVG"
+ },
+ "source": [
+ "The training/validation/test data are stored in json files (`simple-dstc2-trn.json`, `simple-dstc2-val.json` and `simple-dstc2-tst.json`):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ },
+ "colab_type": "code",
+ "id": "LIm9DQyzTgVH",
+ "outputId": "0a82c3f1-8afb-42d5-e3e3-0e9dd9178a20"
+ },
+ "outputs": [],
+ "source": [
+ "!head -n 101 my_data/simple-dstc2-trn.json"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "zO4CWg0XYNSw"
+ },
+ "source": [
+ "To iterate over batches of preprocessed DSTC-2 we need to import `DatasetIterator`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "piBBcw9ZTgVK",
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov.dataset_iterators.dialog_iterator import DialogDatasetIterator\n",
+ "\n",
+ "iterator = DialogDatasetIterator(data)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "jVU5JGnTTgVM"
+ },
+ "source": [
+ "You can now iterate over batches of preprocessed DSTC-2 dialogs:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ },
+ "colab_type": "code",
+ "id": "1RSwEH3CTgVN",
+ "outputId": "b2a0ecdb-89d1-4784-eeb9-749f7b754ff6"
+ },
+ "outputs": [],
+ "source": [
+ "from pprint import pprint\n",
+ "\n",
+ "for dialog in iterator.gen_batches(batch_size=1, data_type='train'):\n",
+ " turns_x, turns_y = dialog\n",
+ " \n",
+ " print(\"User utterances:\\n----------------\\n\")\n",
+ " pprint(turns_x[0], indent=4)\n",
+ " print(\"\\nSystem responses:\\n-----------------\\n\")\n",
+ " pprint(turns_y[0], indent=4)\n",
+ " \n",
+ " break"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "AKTZWtm8ZtPi"
+ },
+ "source": [
+ "In real-life annotation of data is expensive. To make our tutorial closer to production use-cases we take only 50 dialogues for training."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "UlappYTbTgVT"
+ },
+ "outputs": [],
+ "source": [
+ "!cp my_data/simple-dstc2-trn.json my_data/simple-dstc2-trn.full.json"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 33
+ },
+ "colab_type": "code",
+ "id": "tTU9yM-CTgVX",
+ "outputId": "1568aaed-7f8e-4f77-a637-cda5a9556740"
+ },
+ "outputs": [],
+ "source": [
+ "import json\n",
+ "\n",
+ "NUM_TRAIN = 50\n",
+ "\n",
+ "with open('my_data/simple-dstc2-trn.full.json', 'rt') as fin:\n",
+ " data = json.load(fin)\n",
+ "with open('my_data/simple-dstc2-trn.json', 'wt') as fout:\n",
+ " json.dump(data[:NUM_TRAIN], fout, indent=2)\n",
+ "print(f\"Train set is reduced to {NUM_TRAIN} dialogues (out of {len(data)}).\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "l5mjRphbTgVb"
+ },
+ "source": [
+ "## 1. Build Database of items"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "n597CLhqjqcd"
+ },
+ "source": [
+ "### Building database of restaurants"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "nJFkgfjTTgVf"
+ },
+ "source": [
+ "To assist with restaurant booking the chatbot should have access to a `database` of restaurants. The `database` contains task-specific information such as type of food, price range, location, etc.\n",
+ "\n",
+ " >> database([{'pricerange': 'cheap', 'area': 'south'}])\n",
+ " \n",
+ " Out[1]: \n",
+ " [[{'name': 'the lucky star',\n",
+ " 'food': 'chinese',\n",
+ " 'pricerange': 'cheap',\n",
+ " 'area': 'south',\n",
+ " 'addr': 'cambridge leisure park clifton way cherry hinton',\n",
+ " 'phone': '01223 244277',\n",
+ " 'postcode': 'c.b 1, 7 d.y'},\n",
+ " {'name': 'nandos',\n",
+ " 'food': 'portuguese',\n",
+ " 'pricerange': 'cheap',\n",
+ " 'area': 'south',\n",
+ " 'addr': 'cambridge leisure park clifton way',\n",
+ " 'phone': '01223 327908',\n",
+ " 'postcode': 'c.b 1, 7 d.y'}]]\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "rNpewHp-TgVd"
+ },
+ "source": [
+ " \n",
+ "![gobot_database.png](https://github.com/deepmipt/DeepPavlov/blob/master/examples/img/gobot_database.png?raw=1)\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "-TU-NLnNa9tk"
+ },
+ "source": [
+ "The chatbot should be trained to make api calls. For this, training dataset contains a `\"db_result\"` dictionary key. It annotates turns where system performs an api call to the database of items. Rusulting value is stored in `\"db_result\"`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "EVNRZmeiTgVh",
+ "outputId": "edba5e2b-235f-423f-8bfa-8d02506c4c7e"
+ },
+ "outputs": [],
+ "source": [
+ "!head -n 78 my_data/simple-dstc2-trn.json | tail +51"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "GT4YBHMnl0Xd"
+ },
+ "source": [
+ "Set `primary_keys` to a list of slot names that have unique values for different items (common SQL term). For the case of DSTC-2, the primary slot is a restaurant name."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "JjKbIAyaTgVk",
+ "outputId": "07620401-80f5-490a-cff2-5d5f013a365b"
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov.core.data.sqlite_database import Sqlite3Database\n",
+ "\n",
+ "database = Sqlite3Database(primary_keys=[\"name\"],\n",
+ " save_path=\"my_bot/db.sqlite\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "a2e1u-z0TgVo"
+ },
+ "source": [
+ "\n",
+ "Let's find all `\"db_result\"` api call results and add them to our database of restaurants:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "RlKg5UtqTgVp",
+ "outputId": "a387df1f-4418-498b-a125-9e351a8e0cf9"
+ },
+ "outputs": [],
+ "source": [
+ "db_results = []\n",
+ "\n",
+ "for dialog in iterator.gen_batches(batch_size=1, data_type='all'):\n",
+ " turns_x, turns_y = dialog\n",
+ " db_results.extend(x['db_result'] for x in turns_x[0] if x.get('db_result'))\n",
+ "\n",
+ "print(f\"Adding {len(db_results)} items.\")\n",
+ "if db_results:\n",
+ " database.fit(db_results)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "XeJMI9qaTgVt"
+ },
+ "source": [
+ "### Interacting with database"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "2JLUF2b_TgVu"
+ },
+ "source": [
+ "We can now play with the database and make requests to it:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "VRCU_MJnTgVv",
+ "outputId": "017803c4-36ab-49bc-ae40-7df87356f5c2"
+ },
+ "outputs": [],
+ "source": [
+ "database([{'pricerange': 'cheap', 'area': 'south'}])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "U2wOAIlpTgV1",
+ "outputId": "e83e53b9-3431-4d1c-9bed-0e841d2b6fc4"
+ },
+ "outputs": [],
+ "source": [
+ "!ls my_bot"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "mBoO34NzTgV4"
+ },
+ "source": [
+ "## 2. Build Slot Filler"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "TGlJRwTCYkiQ"
+ },
+ "source": [
+ "`Slot Filler` is a component that finds slot values in user input:\n",
+ "\n",
+ " >> slot_filler(['I would like some chineese food'])\n",
+ " \n",
+ " Out[1]: [{'food': 'chinese'}]\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "5RqXeLdTTgV4"
+ },
+ "source": [
+ " \n",
+ "![gobot_slotfiller.png](https://github.com/deepmipt/DeepPavlov/blob/master/examples/img/gobot_slotfiller.png?raw=1)\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "TcJGPFq4TgV5"
+ },
+ "source": [
+ "To implement a `Slot Filler` you need to provide\n",
+ " \n",
+ " - **slot types**,\n",
+ " - all possible **slot values**,\n",
+ " - also, it is good to have examples of mentions for every value of each slot.\n",
+ " \n",
+ "In this tutorial, a schema for `slot types` and `slot values` should be defined in `slot_vals.json` with the following format:\n",
+ "\n",
+ " {\n",
+ " 'food': {\n",
+ " 'chinese': ['chinese', 'chineese', 'chines'],\n",
+ " 'french': ['french', 'freench'],\n",
+ " 'dontcare': ['any food', 'any type of food']\n",
+ " }\n",
+ " }\n",
+ " \n",
+ "\n",
+ "Let's use a simple non-trainable slot filler that relies on Levenshtein distance."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "zVi5XynnTgV6",
+ "outputId": "e9d68c8c-3bbb-4f80-98a5-92cbfe0eb5ac"
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov.download import download_decompress\n",
+ "\n",
+ "download_decompress(url='http://files.deeppavlov.ai/deeppavlov_data/dstc_slot_vals.tar.gz',\n",
+ " download_path='my_bot/slotfill')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "NR1S3PXCTgV9",
+ "outputId": "013e9dba-427c-4255-aad5-0627477157e8"
+ },
+ "outputs": [],
+ "source": [
+ "!ls my_bot/slotfill"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "-OZ9TqDKZ6Fv"
+ },
+ "source": [
+ "Print some `slot types` and `slot values`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "KqgfYr4RTgWE",
+ "outputId": "a6830aa3-0bcc-4011-a4ab-5b5e48e6a20f"
+ },
+ "outputs": [],
+ "source": [
+ "!head -n 10 my_bot/slotfill/dstc_slot_vals.json"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "eIufDAvATgWN"
+ },
+ "source": [
+ "Check performance of our slot filler on DSTC-2 dataset."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "XUSj5R3uTgWP"
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov import configs\n",
+ "from deeppavlov.core.common.file import read_json\n",
+ "\n",
+ "slotfill_config = read_json(configs.ner.slotfill_simple_dstc2_raw)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "pFda6_LBTgWT"
+ },
+ "source": [
+ "We take [original DSTC2 slot-filling config](https://github.com/deepmipt/DeepPavlov/blob/master/deeppavlov/configs/ner/slotfill_dstc2_raw.json) from DeepPavlov and change variables determining data paths:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "yr8MbFLwTgWV"
+ },
+ "outputs": [],
+ "source": [
+ "slotfill_config['metadata']['variables']['DATA_PATH'] = 'my_data'\n",
+ "slotfill_config['metadata']['variables']['SLOT_VALS_PATH'] = 'my_bot/slotfill/dstc_slot_vals.json'"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "ZxMTySrpaZVP"
+ },
+ "source": [
+ "Run evaluation."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "CdrDW4bVTgWZ",
+ "outputId": "ac56ae74-b368-437e-c70f-01b418ba883f"
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov import evaluate_model\n",
+ "\n",
+ "slotfill = evaluate_model(slotfill_config);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "azulujiLTgWb"
+ },
+ "source": [
+ "We've got slot accuracy of **93% on valid** set and **95% on test** set."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "FkZvQ-yNig1u"
+ },
+ "source": [
+ "Building `Slot Filler` model from DeepPavlov config."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "uWeXTtVhTgWc"
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov import build_model\n",
+ "\n",
+ "slotfill = build_model(slotfill_config)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "ihi4lpXUi-_V"
+ },
+ "source": [
+ "Testing the model."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "bMRSU_bnTgWf",
+ "outputId": "d224e4be-1537-428d-ff67-55076224946d"
+ },
+ "outputs": [],
+ "source": [
+ "slotfill(['i want cheap chinee food'])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "U2PUxB5fTgWl"
+ },
+ "source": [
+ "Saving slotfill config file to disk (we will require it's path later)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "5MyFaEM7TgWl"
+ },
+ "outputs": [],
+ "source": [
+ "import json\n",
+ "\n",
+ "json.dump(slotfill_config, open('my_bot/slotfill_config.json', 'wt'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "colab_type": "code",
+ "id": "_ZlRvicuTgWo",
+ "outputId": "4f1c3d46-d3b1-4923-823e-e2df1027fc6f"
+ },
+ "outputs": [],
+ "source": [
+ "!ls my_bot"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "E_InRKO6TgWt"
+ },
+ "source": [
+ "## 3. Build and Train a Bot"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "ySe2m9-5m6iW"
+ },
+ "source": [
+ "### Dialogue policy and response templates"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "qjwbkeDl3TBg"
+ },
+ "source": [
+ "A policy module of the bot decides what action should be taken in the current dialogue state. The policy in our bot is implemented as a recurrent neural network (recurrency over user utterances) followed by a dense layer with softmax function on top. The network classifies user input into one of predefined system actions. Examples of possible actions are to say hello, to request user's location or to make api call to a database. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "wLE1iebG3WJc"
+ },
+ "source": [
+ "![gobot_policy.png](https://github.com/deepmipt/DeepPavlov/blob/master/examples/img/gobot_policy.png?raw=1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "ghF-W56m3iW-"
+ },
+ "source": [
+ "All actions available for the system should be listed in a `simple-dstc2-templates.txt` file. Also, every action should be associated with a template string of the corresponding system response."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "TjDnGyiN3nIr"
+ },
+ "source": [
+ "![gobot_templates.png](https://github.com/deepmipt/DeepPavlov/blob/master/examples/img/gobot_templates.png?raw=1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "-xqGKtXBTgWu"
+ },
+ "source": [
+ "Templates for responses should be in the format `TAB`, where `` is a dialogue action and `` is the corresponding response. The response text might contain slot type names, where every `#slot_type` will be filled with the slot value from the current dialogue state."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 204
+ },
+ "colab_type": "code",
+ "id": "bNyliD8PTgWw",
+ "outputId": "15434eda-f87e-4b19-ac1a-59c4ba345344"
+ },
+ "outputs": [],
+ "source": [
+ "!head -n 10 my_data/simple-dstc2-templates.txt"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "TWG40VysTgW0"
+ },
+ "source": [
+ "In essense, the dialogue policy module solves classification task, where a set of classes is defined in `simple-dstc2-templates.txt`. So, to train the dialogue policy network you need action label for each system's turn in training dialogues. The DSTC-2 provides `\"act\"` dictionary key that contains action associated with current response. Here is an example of training data for the policy network."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 438
+ },
+ "colab_type": "code",
+ "id": "eeeqFeWkTgW1",
+ "outputId": "c05f6279-a589-4b54-be62-0400251e840a"
+ },
+ "outputs": [],
+ "source": [
+ "!head -n 24 my_data/simple-dstc2-trn.json"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "k9d67KtlTgW5"
+ },
+ "source": [
+ "Now we configure a full data processing pipline for the restaurant bot.\n",
+ "\n",
+ "As a starting point, let's take a [default DSTC2 bot config](https://github.com/deepmipt/DeepPavlov/blob/master/deeppavlov/configs/go_bot/gobot_dstc2.json) ([more configs](https://github.com/deepmipt/DeepPavlov/blob/master/deeppavlov/configs/go_bot) are available) from DeepPavlov and, then change sections responsible for:\n",
+ "- embeddings, \n",
+ "- database,\n",
+ "- slot filler,\n",
+ "- templates,\n",
+ "- data and model load/save paths.\n",
+ "\n",
+ "Loading bot:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "db9_ozwnTgW5"
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov import configs\n",
+ "from deeppavlov.core.common.file import read_json\n",
+ "\n",
+ "gobot_config = read_json(configs.go_bot.gobot_simple_dstc2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "QFQFQ7_bTgXa"
+ },
+ "source": [
+ "Set default bag-of-words embedder:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "fLgZuzQgTgXc"
+ },
+ "outputs": [],
+ "source": [
+ "gobot_config['chainer']['pipe'][-1]['embedder'] = None"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "oNGj-ARxTgW-"
+ },
+ "source": [
+ "Configure bot to use our database:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "VanrlHZZTgXB"
+ },
+ "outputs": [],
+ "source": [
+ "gobot_config['chainer']['pipe'][-1]['database'] = {\n",
+ " 'class_name': 'sqlite_database',\n",
+ " 'primary_keys': [\"name\"],\n",
+ " 'save_path': 'my_bot/db.sqlite'\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "nQ_YE904TgXQ"
+ },
+ "source": [
+ "Configure bot to use levenshtein distance based slot filler:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "rNVubPKdTgXU"
+ },
+ "outputs": [],
+ "source": [
+ "gobot_config['chainer']['pipe'][-1]['slot_filler']['config_path'] = 'my_bot/slotfill_config.json'"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "ug76yN8sWUga"
+ },
+ "source": [
+ "To maintain values of slots of the whole conversation, we first detect slot values mentioned in the latest utterance and then apply `tracker` module which updates current global slot values, so called dialogue state:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "KJ8P-mHOWtZq"
+ },
+ "outputs": [],
+ "source": [
+ "gobot_config['chainer']['pipe'][-1]['tracker']['slot_names'] = ['pricerange', 'this', 'area', 'food']"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "6l6H_t1iTgW7"
+ },
+ "source": [
+ "Configure bot to use templates:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "209m3f6yTgW8"
+ },
+ "outputs": [],
+ "source": [
+ "gobot_config['chainer']['pipe'][-1]['template_type'] = 'DefaultTemplate'\n",
+ "gobot_config['chainer']['pipe'][-1]['template_path'] = 'my_data/simple-dstc2-templates.txt'"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "HMXih1roTgXi"
+ },
+ "source": [
+ "Specify train/valid/test data path and path to save the final bot model:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "vTUdrrQVTgXi"
+ },
+ "outputs": [],
+ "source": [
+ "gobot_config['metadata']['variables']['DATA_PATH'] = 'my_data'\n",
+ "gobot_config['metadata']['variables']['MODEL_PATH'] = 'my_bot'"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "2WDWC18cTgXm"
+ },
+ "source": [
+ "The whole dialogue system pipeline looks like this:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "nQmue0vIGdA0"
+ },
+ "source": [
+ " \n",
+ "![gobot_pipeline.png](https://github.com/deepmipt/DeepPavlov/blob/master/examples/img/gobot_pipeline.png?raw=1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "X0cFEvYTTgXo"
+ },
+ "source": [
+ "### Training policy network"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ },
+ "colab_type": "code",
+ "id": "X9wXKXuHTgXr",
+ "outputId": "3ae99954-a888-40fb-8c21-74e3a5876a5d"
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov import train_model\n",
+ "\n",
+ "gobot_config['train']['batch_size'] = 8 # batch size\n",
+ "gobot_config['train']['max_batches'] = 250 # maximum number of training batches\n",
+ "gobot_config['train']['log_on_k_batches'] = 20\n",
+ "gobot_config['train']['val_every_n_batches'] = 40 # evaluate on full 'valid' split each n batches\n",
+ "gobot_config['train']['log_every_n_batches'] = 40 # evaluate on 20 batches of 'train' split every n batches\n",
+ "\n",
+ "train_model(gobot_config);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "fGGRzuacTgX0"
+ },
+ "source": [
+ "Training on 50 dialogues takes from 5 to 20 minutes depending on gpu/cpu hrdware. Training on 1000 dialogues takes 10-30 mins.\n",
+ "\n",
+ "See DeepPavlov [config doc page](http://docs.deeppavlov.ai/en/master/intro/configuration.html) for advanced configuration of the training process."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "ldfDa9dUTgX1"
+ },
+ "source": [
+ "### Evaluation of training"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "k-z7wZjOTgX6"
+ },
+ "source": [
+ "Calculating **accuracy** of trained bot: whether predicted system responses match true responses (full string match)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 338
+ },
+ "colab_type": "code",
+ "id": "EpPmQkTvTgX8",
+ "outputId": "60071240-296f-4cec-d7e8-da2371e0fe90",
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov import evaluate_model\n",
+ "\n",
+ "evaluate_model(gobot_config);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "1wZOqmYBTgYB"
+ },
+ "source": [
+ "With settings of `max_batches=250`, valid accuracy `= 0.5` and test accuracy is `~ 0.5`."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "ElGD1tnJTgYC"
+ },
+ "source": [
+ "## 4. Interact with Bot"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 204
+ },
+ "colab_type": "code",
+ "id": "m9sJXOPPTgYF",
+ "outputId": "34c4627f-6be1-44d3-893e-5c65f7bd3689"
+ },
+ "outputs": [],
+ "source": [
+ "from deeppavlov import build_model\n",
+ "\n",
+ "bot = build_model(gobot_config)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 33
+ },
+ "colab_type": "code",
+ "id": "DXSYe_S1TgYL",
+ "outputId": "2afc564c-45df-45b5-a5f3-68d9fae1b287"
+ },
+ "outputs": [],
+ "source": [
+ "bot(['hi, i want to eat, can you suggest a place to go?'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 70
+ },
+ "colab_type": "code",
+ "id": "zfYYMHFATgYO",
+ "outputId": "dbf7c44b-d4b9-4ac0-808e-d84e427dc7c1"
+ },
+ "outputs": [],
+ "source": [
+ "bot(['i want cheap food'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 70
+ },
+ "colab_type": "code",
+ "id": "7lqjO0qXTgYQ",
+ "outputId": "1a2fd9ef-d023-45f4-cea7-0b88c704c9a6"
+ },
+ "outputs": [],
+ "source": [
+ "bot(['chinese food'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 33
+ },
+ "colab_type": "code",
+ "id": "sdSgK3JFTgYV",
+ "outputId": "2deddb0b-1bc1-432e-dcf6-22c39fa21832"
+ },
+ "outputs": [],
+ "source": [
+ "bot(['thanks, give me their address'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 33
+ },
+ "colab_type": "code",
+ "id": "bWWfPY7FTgYb",
+ "outputId": "17fc9dae-f768-4875-e81d-e72bf80c7372"
+ },
+ "outputs": [],
+ "source": [
+ "bot(['i want their phone number too'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 33
+ },
+ "colab_type": "code",
+ "id": "0nSDyEXwTgYe",
+ "outputId": "46260e7d-dd83-4415-b95a-95246d6176bb"
+ },
+ "outputs": [],
+ "source": [
+ "bot(['bye'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "MlwvZCPJTgYh"
+ },
+ "outputs": [],
+ "source": [
+ "bot.reset()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 53
+ },
+ "colab_type": "code",
+ "id": "tvTZI4PKTgYl",
+ "outputId": "e75d3136-4581-451d-d121-829c7dd28256"
+ },
+ "outputs": [],
+ "source": [
+ "bot(['hi, is there any cheap restaurant?'])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "You can also train a Simple bot following [gobot_tutorial.ipynb](https://github.com/deepmipt/DeepPavlov/blob/master/examples/gobot_tutorial.ipynb)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "7An-mcu8TgYq"
+ },
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "colab": {
+ "collapsed_sections": [
+ "l5mjRphbTgVb",
+ "n597CLhqjqcd",
+ "XeJMI9qaTgVt",
+ "mBoO34NzTgV4"
+ ],
+ "name": "gobot_tutorial(MB).ipynb",
+ "provenance": [],
+ "version": "0.3.2"
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "name": "python3"
+ },
+ "accelerator": "GPU",
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.7.4"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/examples/gobot_tutorial.ipynb b/examples/gobot_tutorial.ipynb
index 8d7e6f14a1..17544ae73b 100644
--- a/examples/gobot_tutorial.ipynb
+++ b/examples/gobot_tutorial.ipynb
@@ -2,1538 +2,657 @@
"cells": [
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "xYxEKPhTgRif"
+ },
"source": [
"### You can also run the notebook in [COLAB](https://colab.research.google.com/github/deepmipt/DeepPavlov/blob/master/examples/gobot_tutorial.ipynb)."
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "!pip install deeppavlov"
- ]
- },
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "-NIf_5W0gRkj"
+ },
"source": [
- "# Goal-oriented bot in DeepPavlov"
+ "# Simple bot in DeepPavlov"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "GjTJTYIqgRk2"
+ },
"source": [
- "The tutor is focused on building a goal-oriented dialogue system:\n",
+ "This tutorial describes how to build a simple trainable dialogue system with DeepPavlov framework. It shows one of the easiest ways to create a chatbot. All you need is just a dozen of dialogs from your domain with bot responses annotated for dialogue acts. The tutorial covers the following steps:\n",
"\n",
"0. [Data preparation](#0.-Data-Preparation)\n",
- "1. [Build database of items](#1.-Build-database-of-items)\n",
- "2. [Build Slot Filler](#2.-Build-Slot-Filler)\n",
- "3. [Train bot](#3.-Train-bot)\n",
+ "1. [Train bot](#1.-Train-bot)\n",
+ "2. [Interact with bot](#2.-Interact-with-bot)\n",
"\n",
- "An example of the final model served as a telegram bot is:\n",
"\n",
- "![gobot_example.png](img/gobot_example.png)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 0. Data Preparation"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The tutor's dialogue system will be on the domain of restaurant booking. [Dialogue State Tracking Challenge 2 (DSTC-2)](http://camdial.org/~mh521/dstc/) dataset provides dialogues of a human talking to a booking system labelled with slots and dialogue actions. The labels are will be used for training a dialogue policy network.\n",
- "\n",
- "See below a small chunk of the data. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:40:33.370 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 269: [PosixPath('my_data/simple-dstc2-val.json'), PosixPath('my_data/simple-dstc2-tst.json')]]\n",
- "2019-09-04 14:40:33.371 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 270: [downloading data from http://files.deeppavlov.ai/datasets/simple_dstc2.tar.gz to my_data]\n",
- "2019-09-04 14:40:33.399 INFO in 'deeppavlov.core.data.utils'['utils'] at line 63: Downloading from http://files.deeppavlov.ai/datasets/simple_dstc2.tar.gz to my_data/simple_dstc2.tar.gz\n",
- "100%|██████████| 497k/497k [00:00<00:00, 67.5MB/s]\n",
- "2019-09-04 14:40:33.410 INFO in 'deeppavlov.core.data.utils'['utils'] at line 201: Extracting my_data/simple_dstc2.tar.gz archive into my_data\n",
- "2019-09-04 14:40:33.442 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from my_data/simple-dstc2-trn.json]\n",
- "2019-09-04 14:40:33.534 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from my_data/simple-dstc2-val.json]\n",
- "2019-09-04 14:40:33.604 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from my_data/simple-dstc2-tst.json]\n",
- "2019-09-04 14:40:33.652 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 282: There are 9115 samples in train split.\n",
- "2019-09-04 14:40:33.652 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 283: There are 6231 samples in valid split.\n",
- "2019-09-04 14:40:33.653 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 284: There are 6345 samples in test split.\n"
- ]
- }
- ],
- "source": [
- "from deeppavlov.dataset_readers.dstc2_reader import SimpleDSTC2DatasetReader\n",
+ "An example of the final model served as a telegram bot is:\n",
"\n",
- "data = SimpleDSTC2DatasetReader().read('my_data')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "simple-dstc2-templates.txt simple-dstc2-tst.json\r\n",
- "simple-dstc2-trn.json\t simple-dstc2-val.json\r\n"
- ]
- }
- ],
- "source": [
- "!ls my_data"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The training/validation/test data is stored in json files (`simple-dstc2-trn.json`, `simple-dstc2-val.json` and `simple-dstc2-tst.json`):"
+ "![gobot_simple_example.png](img/gobot_simple_example.png)"
]
},
{
"cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[\r\n",
- " [\r\n",
- " {\r\n",
- " \"speaker\": 2,\r\n",
- " \"text\": \"Hello, welcome to the Cambridge restaurant system. You can ask for restaurants by area, price range or food type. How may I help you?\",\r\n",
- " \"slots\": [],\r\n",
- " \"act\": \"welcomemsg\"\r\n",
- " },\r\n",
- " {\r\n",
- " \"speaker\": 1,\r\n",
- " \"text\": \"cheap restaurant\",\r\n",
- " \"slots\": [\r\n",
- " [\r\n",
- " \"pricerange\",\r\n",
- " \"cheap\"\r\n",
- " ]\r\n",
- " ]\r\n",
- " },\r\n",
- " {\r\n",
- " \"speaker\": 2,\r\n",
- " \"text\": \"What kind of food would you like?\",\r\n",
- " \"slots\": [],\r\n",
- " \"act\": \"request_food\"\r\n",
- " },\r\n",
- " {\r\n",
- " \"speaker\": 1,\r\n",
- " \"text\": \"any\",\r\n",
- " \"slots\": [\r\n",
- " [\r\n",
- " \"this\",\r\n",
- " \"dontcare\"\r\n",
- " ]\r\n",
- " ]\r\n",
- " },\r\n",
- " {\r\n",
- " \"speaker\": 2,\r\n",
- " \"text\": \"What part of town do you have in mind?\",\r\n",
- " \"slots\": [],\r\n",
- " \"act\": \"request_area\"\r\n",
- " },\r\n",
- " {\r\n",
- " \"speaker\": 1,\r\n",
- " \"text\": \"south\",\r\n",
- " \"slots\": [\r\n",
- " [\r\n",
- " \"area\",\r\n",
- " \"south\"\r\n",
- " ]\r\n",
- " ]\r\n",
- " },\r\n",
- " {\r\n",
- " \"speaker\": 2,\r\n",
- " \"text\": \"api_call area=\\\"south\\\" food=\\\"dontcare\\\" pricerange=\\\"cheap\\\"\",\r\n",
- " \"db_result\": {\r\n",
- " \"food\": \"chinese\",\r\n",
- " \"pricerange\": \"cheap\",\r\n",
- " \"area\": \"south\",\r\n",
- " \"addr\": \"cambridge leisure park clifton way cherry hinton\",\r\n",
- " \"phone\": \"01223 244277\",\r\n",
- " \"postcode\": \"c.b 1, 7 d.y\",\r\n",
- " \"name\": \"the lucky star\"\r\n",
- " },\r\n",
- " \"slots\": [\r\n",
- " [\r\n",
- " \"area\",\r\n",
- " \"south\"\r\n",
- " ],\r\n",
- " [\r\n",
- " \"pricerange\",\r\n",
- " \"cheap\"\r\n",
- " ],\r\n",
- " [\r\n",
- " \"food\",\r\n",
- " \"dontcare\"\r\n",
- " ]\r\n",
- " ],\r\n",
- " \"act\": \"api_call\"\r\n",
- " },\r\n",
- " {\r\n",
- " \"speaker\": 2,\r\n",
- " \"text\": \"The lucky star is a nice place in the south of town serving tasty chinese food.\",\r\n",
- " \"slots\": [\r\n",
- " [\r\n",
- " \"area\",\r\n",
- " \"south\"\r\n",
- " ],\r\n",
- " [\r\n",
- " \"pricerange\",\r\n",
- " \"cheap\"\r\n",
- " ],\r\n",
- " [\r\n",
- " \"name\",\r\n",
- " \"the lucky star\"\r\n",
- " ],\r\n",
- " [\r\n",
- " \"food\",\r\n",
- " \"chinese\"\r\n",
- " ]\r\n",
- " ],\r\n",
- " \"act\": \"inform_area+inform_food+offer_name\"\r\n",
- " },\r\n"
- ]
- }
- ],
- "source": [
- "!head -n 101 my_data/simple-dstc2-trn.json"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
+ "execution_count": null,
"metadata": {
- "scrolled": true
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ },
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 44268,
+ "status": "ok",
+ "timestamp": 1568799332537,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
+ },
+ "user_tz": -180
+ },
+ "id": "JeSE4a-SgRjo",
+ "outputId": "bde9888c-654d-4e0f-dd4f-0dbc416aa283"
},
"outputs": [],
"source": [
- "from deeppavlov.dataset_iterators.dialog_iterator import DialogDatasetIterator\n",
- "\n",
- "iterator = DialogDatasetIterator(data)"
+ "!pip install deeppavlov"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "fbv3rMFngRlH"
+ },
"source": [
- "You can now iterate over batches of preprocessed DSTC-2 dialogs:"
+ "## 0. Data Preparation"
]
},
{
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "User utterances:\n",
- "----------------\n",
- "\n",
- "[ {'prev_resp_act': None, 'text': ''},\n",
- " { 'prev_resp_act': 'welcomemsg',\n",
- " 'slots': [['pricerange', 'moderate'], ['area', 'north']],\n",
- " 'text': 'im looking for a moderately priced restaurant in the north '\n",
- " 'part of town'},\n",
- " { 'db_result': { 'addr': '7 milton road chesterton',\n",
- " 'area': 'north',\n",
- " 'food': 'indian',\n",
- " 'name': 'the nirala',\n",
- " 'phone': '01223 360966',\n",
- " 'postcode': 'c.b 4, 1 u.y',\n",
- " 'pricerange': 'moderate'},\n",
- " 'prev_resp_act': 'api_call',\n",
- " 'slots': [['pricerange', 'moderate'], ['area', 'north']],\n",
- " 'text': 'im looking for a moderately priced restaurant in the north '\n",
- " 'part of town'},\n",
- " { 'prev_resp_act': 'inform_area+inform_pricerange+offer_name',\n",
- " 'slots': [['slot', 'phone']],\n",
- " 'text': 'what is the phone number'},\n",
- " {'prev_resp_act': 'inform_phone+offer_name', 'text': 'thank you goodbye'}]\n",
- "\n",
- "System responses:\n",
- "-----------------\n",
- "\n",
- "[ { 'act': 'welcomemsg',\n",
- " 'text': 'Hello, welcome to the Cambridge restaurant system. You can '\n",
- " 'ask for restaurants by area, price range or food type. How '\n",
- " 'may I help you?'},\n",
- " { 'act': 'api_call',\n",
- " 'slots': [['pricerange', 'moderate'], ['area', 'north']],\n",
- " 'text': 'api_call area=\"north\" food=\"dontcare\" pricerange=\"moderate\"'},\n",
- " { 'act': 'inform_area+inform_pricerange+offer_name',\n",
- " 'slots': [ ['pricerange', 'moderate'],\n",
- " ['area', 'north'],\n",
- " ['name', 'the nirala']],\n",
- " 'text': 'The nirala is a nice place in the north of town and the '\n",
- " 'prices are moderate.'},\n",
- " { 'act': 'inform_phone+offer_name',\n",
- " 'slots': [['phone', '01223 360966'], ['name', 'the nirala']],\n",
- " 'text': 'The phone number of the nirala is 01223 360966.'},\n",
- " {'act': 'bye', 'text': 'You are welcome!'}]\n"
- ]
- }
- ],
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "hTpb4EHbgRla"
+ },
"source": [
- "from pprint import pprint\n",
+ "In this tutorial we will build and train a simple chatbot just from 10 dialogues. \n",
"\n",
- "for dialog in iterator.gen_batches(batch_size=1, data_type='train'):\n",
- " turns_x, turns_y = dialog\n",
- " \n",
- " print(\"User utterances:\\n----------------\\n\")\n",
- " pprint(turns_x[0], indent=4)\n",
- " print(\"\\nSystem responses:\\n-----------------\\n\")\n",
- " pprint(turns_y[0], indent=4)\n",
- " \n",
- " break"
+ "Reading data:"
]
},
{
"cell_type": "code",
- "execution_count": 6,
- "metadata": {},
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "B5oak1V5gRlq"
+ },
"outputs": [],
"source": [
- "!cp my_data/simple-dstc2-trn.json my_data/simple-dstc2-trn.full.json"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Train set is reduced to 50 dialogues (out of 967).\n"
- ]
- }
- ],
- "source": [
- "import json\n",
+ "from deeppavlov.dataset_readers.dstc2_reader import SimpleDSTC2DatasetReader\n",
"\n",
- "NUM_TRAIN = 50\n",
"\n",
- "with open('my_data/simple-dstc2-trn.full.json', 'rt') as fin:\n",
- " data = json.load(fin)\n",
- "with open('my_data/simple-dstc2-trn.json', 'wt') as fout:\n",
- " json.dump(data[:NUM_TRAIN], fout, indent=2)\n",
- "print(f\"Train set is reduced to {NUM_TRAIN} dialogues (out of {len(data)}).\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Build database of items"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- " \n",
- "![gobot_database.png](img/gobot_database.png)\n",
- " "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "For a valid goal-oriented bot there should be a `database` of relevant items. In the case of restaurant booking it will contain all available restaurants and their info.\n",
- "\n",
- " >> database([{'pricerange': 'cheap', 'area': 'south'}])\n",
+ "class AssistantDatasetReader(SimpleDSTC2DatasetReader):\n",
" \n",
- " Out[1]: \n",
- " [[{'name': 'the lucky star',\n",
- " 'food': 'chinese',\n",
- " 'pricerange': 'cheap',\n",
- " 'area': 'south',\n",
- " 'addr': 'cambridge leisure park clifton way cherry hinton',\n",
- " 'phone': '01223 244277',\n",
- " 'postcode': 'c.b 1, 7 d.y'},\n",
- " {'name': 'nandos',\n",
- " 'food': 'portuguese',\n",
- " 'pricerange': 'cheap',\n",
- " 'area': 'south',\n",
- " 'addr': 'cambridge leisure park clifton way',\n",
- " 'phone': '01223 327908',\n",
- " 'postcode': 'c.b 1, 7 d.y'}]]\n",
- " \n",
- "The dialogues in the training dataset should contain a `\"db_result\"` dictionary key. It is required for turns where system performs a special type of external action: an api call to the database of items. `\"db_result\"` should contain the result of the api call:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " {\r\n",
- " \"speaker\": 2,\r\n",
- " \"text\": \"api_call area=\\\"south\\\" food=\\\"dontcare\\\" pricerange=\\\"cheap\\\"\",\r\n",
- " \"db_result\": {\r\n",
- " \"food\": \"chinese\",\r\n",
- " \"pricerange\": \"cheap\",\r\n",
- " \"area\": \"south\",\r\n",
- " \"addr\": \"cambridge leisure park clifton way cherry hinton\",\r\n",
- " \"phone\": \"01223 244277\",\r\n",
- " \"postcode\": \"c.b 1, 7 d.y\",\r\n",
- " \"name\": \"the lucky star\"\r\n",
- " },\r\n",
- " \"slots\": [\r\n",
- " [\r\n",
- " \"area\",\r\n",
- " \"south\"\r\n",
- " ],\r\n",
- " [\r\n",
- " \"pricerange\",\r\n",
- " \"cheap\"\r\n",
- " ],\r\n",
- " [\r\n",
- " \"food\",\r\n",
- " \"dontcare\"\r\n",
- " ]\r\n",
- " ],\r\n",
- " \"act\": \"api_call\"\r\n",
- " },\r\n"
- ]
- }
- ],
- "source": [
- "!head -n 78 my_data/simple-dstc2-trn.json | tail +51"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:40:49.312 WARNING in 'deeppavlov.core.models.serializable'['serializable'] at line 47: No load path is set for Sqlite3Database in 'infer' mode. Using save path instead\n",
- "2019-09-04 14:40:49.313 INFO in 'deeppavlov.core.data.sqlite_database'['sqlite_database'] at line 70: Initializing empty database on /home/vimary/code-projects/Pilot/examples/my_bot/db.sqlite.\n"
- ]
- }
- ],
- "source": [
- "from deeppavlov.core.data.sqlite_database import Sqlite3Database\n",
- "\n",
- "database = Sqlite3Database(primary_keys=[\"name\"],\n",
- " save_path=\"my_bot/db.sqlite\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Set `primary_keys` to a list of slot names that have unique values for different items (common SQL term). For the case of DSTC-2, the primary slot is restaurant name.\n",
- "\n",
- "Let's find all `\"db_result\"` api call results and add it to our database of restaurants:"
+ " url = \"http://files.deeppavlov.ai/datasets/tutor_assistant_data.tar.gz\"\n",
+ " \n",
+ " @staticmethod\n",
+ " def _data_fname(datatype):\n",
+ " assert datatype in ('val', 'trn', 'tst'), \"wrong datatype name\"\n",
+ " return f\"assistant-{datatype}.json\""
]
},
{
"cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:40:50.332 INFO in 'deeppavlov.core.data.sqlite_database'['sqlite_database'] at line 145: Created table with keys {'food': 'text', 'postcode': 'text', 'pricerange': 'text', 'area': 'text', 'phone': 'text', 'name': 'text', 'addr': 'text'}.\n"
- ]
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 137
},
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Adding 3016 items.\n"
- ]
- }
- ],
- "source": [
- "db_results = []\n",
- "\n",
- "for dialog in iterator.gen_batches(batch_size=1, data_type='all'):\n",
- " turns_x, turns_y = dialog\n",
- " db_results.extend(x['db_result'] for x in turns_x[0] if x.get('db_result'))\n",
- "\n",
- "print(f\"Adding {len(db_results)} items.\")\n",
- "if db_results:\n",
- " database.fit(db_results)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "##### Interacting with database"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We can now play with the database and make requests to it:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[[{'food': 'chinese',\n",
- " 'postcode': 'c.b 1, 7 d.y',\n",
- " 'pricerange': 'cheap',\n",
- " 'area': 'south',\n",
- " 'phone': '01223 244277',\n",
- " 'name': 'the lucky star',\n",
- " 'addr': 'cambridge leisure park clifton way cherry hinton'},\n",
- " {'food': 'portuguese',\n",
- " 'postcode': 'c.b 1, 7 d.y',\n",
- " 'pricerange': 'cheap',\n",
- " 'area': 'south',\n",
- " 'phone': '01223 327908',\n",
- " 'name': 'nandos',\n",
- " 'addr': 'cambridge leisure park clifton way'}]]"
- ]
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 595,
+ "status": "ok",
+ "timestamp": 1568799767898,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
},
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "database([{'pricerange': 'cheap', 'area': 'south'}])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "db.sqlite\r\n"
- ]
- }
- ],
- "source": [
- "!ls my_bot"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Build Slot Filler"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- " \n",
- "![gobot_slotfiller.png](img/gobot_slotfiller.png)\n",
- " "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Slot Filler is component that inputs text and outputs dictionary of slot names and their values:\n",
- "\n",
- " >> slot_filler(['I would like some chineese food'])\n",
- " \n",
- " Out[1]: [{'food': 'chinese'}]\n",
- "\n",
- "To implement a slot filler you need to provide\n",
- " \n",
- " - **slot types**\n",
- " - all possible **slot values**\n",
- " - optionally, it will be good to provide examples of mentions for every value of each slot\n",
- " \n",
- "The data should be in `slot_vals.json` file with the following format:\n",
- "\n",
- " {\n",
- " 'food': {\n",
- " 'chinese': ['chinese', 'chineese', 'chines'],\n",
- " 'french': ['french', 'freench'],\n",
- " 'dontcare': ['any food', 'any type of food']\n",
- " }\n",
- " }\n",
- " \n",
- "\n",
- "Let's use a simple non-trainable slot filler that relies on levenshtein distance:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:40:53.225 INFO in 'deeppavlov.core.data.utils'['utils'] at line 63: Downloading from http://files.deeppavlov.ai/deeppavlov_data/dstc_slot_vals.tar.gz to my_bot/slotfill/dstc_slot_vals.tar.gz\n",
- "100%|██████████| 1.62k/1.62k [00:00<00:00, 11.1MB/s]\n",
- "2019-09-04 14:40:53.227 INFO in 'deeppavlov.core.data.utils'['utils'] at line 201: Extracting my_bot/slotfill/dstc_slot_vals.tar.gz archive into my_bot/slotfill\n"
- ]
- }
- ],
- "source": [
- "from deeppavlov.download import download_decompress\n",
- "\n",
- "download_decompress(url='http://files.deeppavlov.ai/deeppavlov_data/dstc_slot_vals.tar.gz',\n",
- " download_path='my_bot/slotfill')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "dstc_slot_vals.json\r\n"
- ]
- }
- ],
- "source": [
- "!ls my_bot/slotfill"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\r\n",
- " \"food\": {\r\n",
- " \"caribbean\": [\r\n",
- " \"carraibean\",\r\n",
- " \"carribean\",\r\n",
- " \"caribbean\"\r\n",
- " ],\r\n",
- " \"kosher\": [\r\n",
- " \"kosher\"\r\n",
- " ],\r\n"
- ]
- }
- ],
- "source": [
- "!head -n 10 my_bot/slotfill/dstc_slot_vals.json"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "##### Metric scores on valid&test"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's check performance of our slot filler on DSTC-2 dataset:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {},
+ "user_tz": -180
+ },
+ "id": "I-GPAAWjgRmj",
+ "outputId": "05f22005-56c2-48c7-882a-13a9d039b146"
+ },
"outputs": [],
"source": [
- "from deeppavlov import configs\n",
- "from deeppavlov.core.common.file import read_json\n",
- "\n",
- "slotfill_config = read_json(configs.ner.slotfill_simple_dstc2_raw)"
+ "data = AssistantDatasetReader().read('assistant_data')"
]
},
{
"cell_type": "markdown",
- "metadata": {},
- "source": [
- "We take [original DSTC2 slot-filling config](https://github.com/deepmipt/DeepPavlov/blob/master/deeppavlov/configs/ner/slotfill_dstc2_raw.json) and change variables determining data paths:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {},
- "outputs": [],
+ "metadata": {
+ "colab_type": "text",
+ "id": "0dcewhzTgRns"
+ },
"source": [
- "slotfill_config['metadata']['variables']['DATA_PATH'] = 'my_data'\n",
- "slotfill_config['metadata']['variables']['SLOT_VALS_PATH'] = 'my_bot/slotfill/dstc_slot_vals.json'"
+ "The training/validation/test data is stored in json files (`assistant-trn.json`, `assistant-val.json` and `assistant-tst.json`):"
]
},
{
"cell_type": "code",
- "execution_count": 18,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:40:55.992 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-trn.json]\n",
- "2019-09-04 14:40:55.999 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-val.json]\n",
- "2019-09-04 14:40:56.105 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-tst.json]\n",
- "2019-09-04 14:40:56.150 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 282: There are 479 samples in train split.\n",
- "2019-09-04 14:40:56.151 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 283: There are 6231 samples in valid split.\n",
- "2019-09-04 14:40:56.151 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 284: There are 6345 samples in test split.\n",
- "[nltk_data] Downloading package punkt to /home/vimary/nltk_data...\n",
- "[nltk_data] Package punkt is already up-to-date!\n",
- "[nltk_data] Downloading package stopwords to /home/vimary/nltk_data...\n",
- "[nltk_data] Package stopwords is already up-to-date!\n",
- "[nltk_data] Downloading package perluniprops to\n",
- "[nltk_data] /home/vimary/nltk_data...\n",
- "[nltk_data] Package perluniprops is already up-to-date!\n",
- "[nltk_data] Downloading package nonbreaking_prefixes to\n",
- "[nltk_data] /home/vimary/nltk_data...\n",
- "[nltk_data] Package nonbreaking_prefixes is already up-to-date!\n"
- ]
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 50
},
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 1253, \"metrics\": {\"slots_accuracy\": 0.933}, \"time_spent\": \"0:00:34\"}}\n",
- "{\"test\": {\"eval_examples_count\": 1190, \"metrics\": {\"slots_accuracy\": 0.9487}, \"time_spent\": \"0:00:31\"}}\n"
- ]
- }
- ],
- "source": [
- "from deeppavlov import evaluate_model\n",
- "\n",
- "slotfill = evaluate_model(slotfill_config);"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 2259,
+ "status": "ok",
+ "timestamp": 1568799772627,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
+ },
+ "user_tz": -180
+ },
+ "id": "T_q_AMkCgRnO",
+ "outputId": "b57a7fec-16aa-4261-ece7-965f7cdb0718"
+ },
+ "outputs": [],
"source": [
- "We've got slot accuracy of **93% on valid** set and **94% on test** set."
+ "!ls assistant_data"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "5elPwVGH8sFb"
+ },
"source": [
- "##### Interacting with slot filler"
+ "Let's take a look at the training data."
]
},
{
"cell_type": "code",
- "execution_count": 19,
- "metadata": {},
- "outputs": [],
- "source": [
- "from deeppavlov import build_model\n",
- "\n",
- "slotfill = build_model(slotfill_config)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[{'food': 'chinese', 'pricerange': 'cheap'}]"
- ]
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ },
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 1937,
+ "status": "ok",
+ "timestamp": 1568801176503,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
},
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "user_tz": -180
+ },
+ "id": "DOlrNl_9gRn9",
+ "outputId": "966e2c29-8460-471c-ac6c-6951dc8eb7d1"
+ },
+ "outputs": [],
"source": [
- "slotfill(['i want cheap chinee food'])"
+ "!head -n 310 assistant_data/assistant-trn.json"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "HbgaikNS9JY0"
+ },
"source": [
- "##### Dumping slot filler's config"
+ "Create data iterator to organize data processing."
]
},
{
- "cell_type": "markdown",
- "metadata": {},
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 357
+ },
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 668,
+ "status": "error",
+ "timestamp": 1568803282114,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
+ },
+ "user_tz": -180
+ },
+ "id": "9NYptoABgRol",
+ "outputId": "08c1e1b4-46cc-4be9-c4ab-98bc074e54a6",
+ "scrolled": true
+ },
+ "outputs": [],
"source": [
- "Saving slotfill config file to disk (we will require it's path later):"
+ "from deeppavlov.dataset_iterators.dialog_iterator import DialogDatasetIterator\n",
+ "\n",
+ "iterator = DialogDatasetIterator(data)"
]
},
{
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "hYh26FBDgRpL"
+ },
"source": [
- "import json\n",
- "\n",
- "json.dump(slotfill_config, open('my_bot/slotfill_config.json', 'wt'))"
+ "You can now iterate over batches of preprocessed dialogs:"
]
},
{
"cell_type": "code",
- "execution_count": 22,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "db.sqlite slotfill slotfill_config.json\r\n"
- ]
- }
- ],
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 318
+ },
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 762,
+ "status": "ok",
+ "timestamp": 1568799789488,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
+ },
+ "user_tz": -180
+ },
+ "id": "oMLknr2mgRpk",
+ "outputId": "27d39825-3eac-4adb-c7ee-c3d12e8584ef"
+ },
+ "outputs": [],
"source": [
- "!ls my_bot"
+ "from pprint import pprint\n",
+ "\n",
+ "for dialog in iterator.gen_batches(batch_size=1, data_type='train'):\n",
+ " turns_x, turns_y = dialog\n",
+ " \n",
+ " print(\"User utterances:\\n----------------\\n\")\n",
+ " pprint(turns_x[0], indent=4)\n",
+ " print(\"\\nSystem responses:\\n-----------------\\n\")\n",
+ " pprint(turns_y[0], indent=4)\n",
+ " \n",
+ " break\n",
+ "\n",
+ "print(\"\\n-----------------\") \n",
+ "print(f\"{len(iterator.get_instances('train')[0])} dialog(s) in train.\")\n",
+ "print(f\"{len(iterator.get_instances('valid')[0])} dialog(s) in valid.\")\n",
+ "print(f\"{len(iterator.get_instances('test')[0])} dialog(s) in test.\")"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "PbSQDMHfgRqo"
+ },
"source": [
- "## 3. Train bot"
+ "## 1. Train bot"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "TgXWO32vgRqy"
+ },
"source": [
- "Let's assemble all modules together and train the final module: dialogue policy network.\n",
+ "A policy module of the bot decides what action should be taken in the current dialogue state.The policy in our bot is implemented as a recurrent neural network (recurrency over user utterances) followed by a dense layer with softmax function on top. The network classifies user input into one of predefined system actions. Examples of possible actions are to say hello, to ask what is the weather or to suggest to drink tea. \n",
"\n",
" \n",
- "![gobot_policy.png](img/gobot_policy.png)\n",
+ "![gobot_simple_policy.png](img/gobot_simple_policy.png)\n",
" \n",
"\n",
- "Policy network decides which action the system should take on each turn of a dialogue: should it say goodbye, request user's location or make api call to a database.\n",
- "\n",
- "The policy network is a recurrent neural network (recurrent over utterances represented as bags of words) and a dense layer with softmax function on top. The network classifies user utterance into one of predefined system actions.\n",
+ "All actions available for the system should be listed in a `assistant-templates.txt` file. Each action should be associated with a string of the corresponding system response.\n",
"\n",
" \n",
- "![gobot_templates.png](img/gobot_templates.png)\n",
+ "![gobot_simple_templates.png](img/gobot_simple_templates.png)\n",
" \n",
"\n",
- "All actions available for the system should be listed in a `simple-dstc2-templates.txt` file. Each action should be associated with a string of the corresponding system response.\n",
- "\n",
- "Templates should be in the format `TAB`, where `` is a dialogue action and `` is the corresponding response. Response text might contain slot type names, where every `#slot_type` will be filled with the slot value from a dialogue state."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "api_call\tapi_call area=\"#area\" food=\"#food\" pricerange=\"#pricerange\"\r\n",
- "bye\tYou are welcome!\r\n",
- "canthear\tSorry, I can't hear you.\r\n",
- "canthelp_area\tI'm sorry but there is no #area american restaurant in the #area of town.\r\n",
- "canthelp_area_food\tSorry there is no #food restaurant in the #area of town.\r\n",
- "canthelp_area_food_pricerange\tSorry there is no #pricerange restaurant in the #area of town serving #food food.\r\n",
- "canthelp_area_pricerange\tSorry there is no #pricerange restaurant in the #area of town serving #area american food.\r\n",
- "canthelp_food\tI am sorry but there is no #food restaurant that matches your request.\r\n",
- "canthelp_food_pricerange\tSorry there is no #food restaurant in the #pricerange price range.\r\n",
- "confirm-domain\tYou are looking for a restaurant is that right?\r\n"
- ]
- }
- ],
- "source": [
- "!head -n 10 my_data/simple-dstc2-templates.txt"
+ "Templates should be in the format `TAB`, where `` is a dialogue action and `` is the corresponding response."
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "c6Ra1TzW-WGU"
+ },
"source": [
- "So, actions are actually classes we classify over. And `simple-dstc2-templates.txt` contains the set of classes.\n",
- "\n",
- "To train the dialogue policy network for classification task you need action label for each system utterance in training dialogues. The DSTC-2 contains `\"act\"` dictionary key that contains action associated with current response.\n",
- "\n",
- "The cell below provides an example of training data for the policy network."
+ "List of actions for our bot:"
]
},
{
"cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[\r\n",
- " [\r\n",
- " {\r\n",
- " \"speaker\": 2,\r\n",
- " \"text\": \"Hello, welcome to the Cambridge restaurant system. You can ask for restaurants by area, price range or food type. How may I help you?\",\r\n",
- " \"slots\": [],\r\n",
- " \"act\": \"welcomemsg\"\r\n",
- " },\r\n",
- " {\r\n",
- " \"speaker\": 1,\r\n",
- " \"text\": \"cheap restaurant\",\r\n",
- " \"slots\": [\r\n",
- " [\r\n",
- " \"pricerange\",\r\n",
- " \"cheap\"\r\n",
- " ]\r\n",
- " ]\r\n",
- " },\r\n",
- " {\r\n",
- " \"speaker\": 2,\r\n",
- " \"text\": \"What kind of food would you like?\",\r\n",
- " \"slots\": [],\r\n",
- " \"act\": \"request_food\"\r\n",
- " },\r\n"
- ]
- }
- ],
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 100
+ },
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 1948,
+ "status": "ok",
+ "timestamp": 1568799821700,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
+ },
+ "user_tz": -180
+ },
+ "id": "lqg_cbfegRrJ",
+ "outputId": "9da7386c-b783-41fa-8280-d1c22ecb6958"
+ },
+ "outputs": [],
"source": [
- "!head -n 24 my_data/simple-dstc2-trn.json"
+ "!head -n 10 assistant_data/assistant-templates.txt"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "0EB74TkogRse"
+ },
"source": [
- "Let's **construct the final pipeline** of a dialogue system.\n",
- "\n",
- "We take [default DSTC2 bot config](https://github.com/deepmipt/DeepPavlov/blob/master/deeppavlov/configs/go_bot/gobot_dstc2.json) ([more configs](https://github.com/deepmipt/DeepPavlov/blob/master/deeppavlov/configs/go_bot) are available) and change sections responsible for \n",
- "- templates,\n",
- "- database,\n",
- "- slot filler,\n",
- "- embeddings,\n",
- "- data and model load/save paths."
+ "In essense, the dialogue policy module solves classification task, where a set of classes is defined in `assistant-templates.txt`. So, to train the dialogue policy network you need action label for each system's turn in training dialogues. Our assistant dataset provides `\"act\"` dictionary key that contains action associated with current response. Here is an example of training data for the policy network."
]
},
{
"cell_type": "code",
- "execution_count": 3,
- "metadata": {},
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 535
+ },
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 2172,
+ "status": "ok",
+ "timestamp": 1568799833831,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
+ },
+ "user_tz": -180
+ },
+ "id": "o-Ny-LEYgRsq",
+ "outputId": "87f7a2b9-0d62-4ba7-bd3c-14cb1f697208"
+ },
"outputs": [],
"source": [
- "from deeppavlov import configs\n",
- "from deeppavlov.core.common.file import read_json\n",
- "\n",
- "gobot_config = read_json(configs.go_bot.gobot_simple_dstc2)"
+ "!head -n 31 assistant_data/assistant-trn.json"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "o5P9piXwgRtl"
+ },
"source": [
- "**Configure** bot to use **templates**:"
+ "For our bot we will use ML pipline for task-oriented conversational skill from DeepPavlov. We will train this skill with our dialogue data. \n",
+ "\n",
+ "Skills in DeepPavlov are defined by configuration files. So, we will use [default DSTC2 bot config](https://github.com/deepmipt/DeepPavlov/blob/master/deeppavlov/configs/go_bot/gobot_dstc2.json) ([more configs](https://github.com/deepmipt/DeepPavlov/blob/master/deeppavlov/configs/go_bot) are available) and change sections responsible for \n",
+ "- embeddings,\n",
+ "- response templates,\n",
+ "- data and model load/save paths.\n",
+ "\n",
+ "Loading bot:"
]
},
{
"cell_type": "code",
- "execution_count": 4,
- "metadata": {},
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "X59MSkmBgRt3"
+ },
"outputs": [],
"source": [
- "gobot_config['chainer']['pipe'][-1]['template_type'] = 'DefaultTemplate'\n",
- "gobot_config['chainer']['pipe'][-1]['template_path'] = 'my_data/simple-dstc2-templates.txt'"
+ "from deeppavlov import configs\n",
+ "from deeppavlov.core.common.file import read_json\n",
+ "\n",
+ "gobot_config = read_json(configs.go_bot.gobot_dstc2_minimal)"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "BVFgvwKFBKv0"
+ },
"source": [
- "**Configure** bot to use our built **database**:"
+ "Download pre-trained GLOVe embeddings:"
]
},
{
"cell_type": "code",
- "execution_count": 5,
- "metadata": {},
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 53
+ },
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 1691,
+ "status": "ok",
+ "timestamp": 1568800095199,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
+ },
+ "user_tz": -180
+ },
+ "id": "XouQ1IBegRvR",
+ "outputId": "8bbeac1b-72d8-45a6-87b6-673ee71f5cb4"
+ },
"outputs": [],
"source": [
- "gobot_config['chainer']['pipe'][-1]['database'] = {\n",
- " 'class_name': 'sqlite_database',\n",
- " 'primary_keys': [\"name\"],\n",
- " 'save_path': 'my_bot/db.sqlite'\n",
- "}"
+ "from deeppavlov.download import download_resource\n",
+ "\n",
+ "download_resource(url=\"http://files.deeppavlov.ai/embeddings/glove.6B.100d.txt\",\n",
+ " dest_paths=['assistant_bot/'])"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "KFhdvuWUBz5T"
+ },
"source": [
- "**Configure** bot to use levenshtein distance based **slot filler**:"
+ "Configure bot to use downloaded embeddings:"
]
},
{
"cell_type": "code",
- "execution_count": 6,
- "metadata": {},
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "FElG1xfjgRvq"
+ },
"outputs": [],
"source": [
- "gobot_config['chainer']['pipe'][-1]['slot_filler']['config_path'] = 'my_bot/slotfill_config.json'\n",
- "\n",
- "gobot_config['chainer']['pipe'][-1]['tracker']['slot_names'] = ['pricerange', 'this', 'area', 'food']"
+ "gobot_config['chainer']['pipe'][-1]['embedder'] = {\n",
+ " \"class_name\": \"glove\",\n",
+ " \"load_path\": \"assistant_bot/glove.6B.100d.txt\"\n",
+ "}"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "KU0o9uM5gRui"
+ },
"source": [
- "You can use a simple **bag-of-words as embedder** (by default):"
+ "Configure bot to use templates:"
]
},
{
"cell_type": "code",
- "execution_count": 7,
- "metadata": {},
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "yAACg0IAgRuq"
+ },
"outputs": [],
"source": [
- "gobot_config['chainer']['pipe'][-1]['embedder'] = None"
+ "gobot_config['chainer']['pipe'][-1]['template_path'] = 'assistant_data/assistant-templates.txt'"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "JV27LFatgRwE"
+ },
"source": [
- "Specify train/valid/test **data path** and **path to save** the final bot model:"
+ "Specify train/valid/test data path and path to save the final bot model:"
]
},
{
"cell_type": "code",
- "execution_count": 8,
- "metadata": {},
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "pqhscSbhgRwK"
+ },
"outputs": [],
"source": [
- "gobot_config['metadata']['variables']['DATA_PATH'] = 'my_data'\n",
+ "gobot_config['dataset_reader']['class_name'] = '__main__:AssistantDatasetReader'\n",
+ "gobot_config['metadata']['variables']['DATA_PATH'] = 'assistant_data'\n",
"\n",
- "gobot_config['metadata']['variables']['MODEL_PATH'] = 'my_bot'"
+ "gobot_config['metadata']['variables']['MODEL_PATH'] = 'assistant_bot'"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "44c_Y8HsgR4l"
+ },
"source": [
"The whole dialogue system pipeline looks like this:\n",
" \n",
- "![gobot_pipeline.png](img/gobot_pipeline.png)"
+ "![gobot_simple_pipeline.png](img/gobot_simple_pipeline.png)"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "kirToS-DgR4v"
+ },
"source": [
- "##### Training policy network"
+ "Train policy network:"
]
},
{
"cell_type": "code",
- "execution_count": 31,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:43:07.476 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-trn.json]\n",
- "2019-09-04 14:43:07.482 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-val.json]\n",
- "2019-09-04 14:43:07.663 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-tst.json]\n",
- "2019-09-04 14:43:07.718 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 282: There are 479 samples in train split.\n",
- "2019-09-04 14:43:07.718 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 283: There are 6231 samples in valid split.\n",
- "2019-09-04 14:43:07.719 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 284: There are 6345 samples in test split.\n",
- "2019-09-04 14:43:07.732 INFO in 'deeppavlov.core.data.simple_vocab'['simple_vocab'] at line 98: [saving vocabulary to /home/vimary/code-projects/Pilot/examples/my_bot/word.dict]\n",
- "2019-09-04 14:43:08.959 WARNING in 'deeppavlov.core.models.serializable'['serializable'] at line 50: No load path is set for Sqlite3Database!\n",
- "2019-09-04 14:43:08.960 INFO in 'deeppavlov.core.data.sqlite_database'['sqlite_database'] at line 66: Loading database from /home/vimary/code-projects/Pilot/examples/my_bot/db.sqlite.\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "WARNING:tensorflow:From /home/vimary/dp_env/lib/python3.7/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Colocations handled automatically by placer.\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "Using TensorFlow backend.\n",
- "2019-09-04 14:43:09.274 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 161: [loading templates from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-templates.txt]\n",
- "2019-09-04 14:43:09.275 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 164: 46 templates loaded.\n",
- "2019-09-04 14:43:09.276 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 210: Calculated input size for `GoalOrientedBotNetwork` is 205\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "WARNING:tensorflow:From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:684: dense (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Use keras.layers.dense instead.\n",
- "WARNING:tensorflow:From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:734: LSTMCell.__init__ (from tensorflow.python.ops.rnn_cell_impl) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "This class is equivalent as tf.keras.layers.LSTMCell, and will be replaced by that in Tensorflow 2.0.\n",
- "WARNING:tensorflow:From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:743: dynamic_rnn (from tensorflow.python.ops.rnn) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Please use `keras.layers.RNN(cell)`, which is equivalent to this API\n",
- "WARNING:tensorflow:From /home/vimary/dp_env/lib/python3.7/site-packages/tensorflow/python/ops/rnn.py:626: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Use tf.cast instead.\n",
- "WARNING:tensorflow:From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:247: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Use standard file APIs to check for files with this prefix.\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:43:10.56 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 251: [initializing `GoalOrientedBot` from scratch]\n",
- "2019-09-04 14:44:50.985 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 164: New best per_item_dialog_accuracy of 0.0072\n",
- "2019-09-04 14:44:50.986 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 166: Saving model\n",
- "2019-09-04 14:44:50.987 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 76: [saving model to /home/vimary/code-projects/Pilot/examples/my_bot/model]\n",
- "2019-09-04 14:44:51.75 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 763: [saving parameters to /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.0072}, \"time_spent\": \"0:01:41\", \"epochs_done\": 0, \"batches_seen\": 0, \"train_examples_seen\": 0, \"impatience\": 0, \"patience_limit\": 10}}\n",
- "{\"train\": {\"eval_examples_count\": 50, \"metrics\": {\"per_item_dialog_accuracy\": 0.4739}, \"time_spent\": \"0:02:36\", \"epochs_done\": 5, \"batches_seen\": 40, \"train_examples_seen\": 290, \"learning_rate\": 0.003, \"momentum\": 0.95, \"loss\": 1.5252028942108153}}\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:47:26.484 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 164: New best per_item_dialog_accuracy of 0.3385\n",
- "2019-09-04 14:47:26.485 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 166: Saving model\n",
- "2019-09-04 14:47:26.486 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 76: [saving model to /home/vimary/code-projects/Pilot/examples/my_bot/model]\n",
- "2019-09-04 14:47:26.577 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 763: [saving parameters to /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.3385}, \"time_spent\": \"0:04:17\", \"epochs_done\": 5, \"batches_seen\": 40, \"train_examples_seen\": 290, \"impatience\": 0, \"patience_limit\": 10}}\n",
- "{\"train\": {\"eval_examples_count\": 50, \"metrics\": {\"per_item_dialog_accuracy\": 0.6534}, \"time_spent\": \"0:05:10\", \"epochs_done\": 11, \"batches_seen\": 80, \"train_examples_seen\": 574, \"learning_rate\": 0.003, \"momentum\": 0.95, \"loss\": 0.6621031060814857}}\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:50:03.925 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 164: New best per_item_dialog_accuracy of 0.3911\n",
- "2019-09-04 14:50:03.926 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 166: Saving model\n",
- "2019-09-04 14:50:03.926 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 76: [saving model to /home/vimary/code-projects/Pilot/examples/my_bot/model]\n",
- "2019-09-04 14:50:04.22 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 763: [saving parameters to /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.3911}, \"time_spent\": \"0:06:54\", \"epochs_done\": 11, \"batches_seen\": 80, \"train_examples_seen\": 574, \"impatience\": 0, \"patience_limit\": 10}}\n",
- "{\"train\": {\"eval_examples_count\": 50, \"metrics\": {\"per_item_dialog_accuracy\": 0.7265}, \"time_spent\": \"0:07:48\", \"epochs_done\": 17, \"batches_seen\": 120, \"train_examples_seen\": 858, \"learning_rate\": 0.003, \"momentum\": 0.95, \"loss\": 0.3516967486590147}}\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:52:39.128 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 164: New best per_item_dialog_accuracy of 0.3977\n",
- "2019-09-04 14:52:39.128 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 166: Saving model\n",
- "2019-09-04 14:52:39.129 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 76: [saving model to /home/vimary/code-projects/Pilot/examples/my_bot/model]\n",
- "2019-09-04 14:52:39.237 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 763: [saving parameters to /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.3977}, \"time_spent\": \"0:09:30\", \"epochs_done\": 17, \"batches_seen\": 120, \"train_examples_seen\": 858, \"impatience\": 0, \"patience_limit\": 10}}\n",
- "{\"train\": {\"eval_examples_count\": 50, \"metrics\": {\"per_item_dialog_accuracy\": 0.7328}, \"time_spent\": \"0:10:24\", \"epochs_done\": 22, \"batches_seen\": 160, \"train_examples_seen\": 1148, \"learning_rate\": 0.003, \"momentum\": 0.95, \"loss\": 0.24322099350392817}}\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:55:13.907 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 164: New best per_item_dialog_accuracy of 0.398\n",
- "2019-09-04 14:55:13.908 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 166: Saving model\n",
- "2019-09-04 14:55:13.909 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 76: [saving model to /home/vimary/code-projects/Pilot/examples/my_bot/model]\n",
- "2019-09-04 14:55:14.6 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 763: [saving parameters to /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.398}, \"time_spent\": \"0:12:04\", \"epochs_done\": 22, \"batches_seen\": 160, \"train_examples_seen\": 1148, \"impatience\": 0, \"patience_limit\": 10}}\n",
- "{\"train\": {\"eval_examples_count\": 50, \"metrics\": {\"per_item_dialog_accuracy\": 0.7745}, \"time_spent\": \"0:12:57\", \"epochs_done\": 28, \"batches_seen\": 200, \"train_examples_seen\": 1432, \"learning_rate\": 0.003, \"momentum\": 0.95, \"loss\": 0.15927621349692345}}\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 14:57:48.387 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 164: New best per_item_dialog_accuracy of 0.4113\n",
- "2019-09-04 14:57:48.387 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 166: Saving model\n",
- "2019-09-04 14:57:48.388 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 76: [saving model to /home/vimary/code-projects/Pilot/examples/my_bot/model]\n",
- "2019-09-04 14:57:48.490 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 763: [saving parameters to /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.4113}, \"time_spent\": \"0:14:39\", \"epochs_done\": 28, \"batches_seen\": 200, \"train_examples_seen\": 1432, \"impatience\": 0, \"patience_limit\": 10}}\n",
- "{\"train\": {\"eval_examples_count\": 50, \"metrics\": {\"per_item_dialog_accuracy\": 0.7724}, \"time_spent\": \"0:15:34\", \"epochs_done\": 34, \"batches_seen\": 240, \"train_examples_seen\": 1716, \"learning_rate\": 0.003, \"momentum\": 0.95, \"loss\": 0.12735621742904185}}\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 15:00:27.605 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 170: Did not improve on the per_item_dialog_accuracy of 0.4113\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.3918}, \"time_spent\": \"0:17:18\", \"epochs_done\": 34, \"batches_seen\": 240, \"train_examples_seen\": 1716, \"impatience\": 1, \"patience_limit\": 10}}\n",
- "{\"train\": {\"eval_examples_count\": 50, \"metrics\": {\"per_item_dialog_accuracy\": 0.7808}, \"time_spent\": \"0:18:11\", \"epochs_done\": 39, \"batches_seen\": 280, \"train_examples_seen\": 2000, \"learning_rate\": 0.003, \"momentum\": 0.95, \"loss\": 0.10291412714868783}}\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 15:03:04.202 INFO in 'deeppavlov.core.trainers.nn_trainer'['nn_trainer'] at line 170: Did not improve on the per_item_dialog_accuracy of 0.4113\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.4017}, \"time_spent\": \"0:19:55\", \"epochs_done\": 39, \"batches_seen\": 280, \"train_examples_seen\": 2000, \"impatience\": 2, \"patience_limit\": 10}}\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 15:03:29.98 INFO in 'deeppavlov.core.data.simple_vocab'['simple_vocab'] at line 112: [loading vocabulary from /home/vimary/code-projects/Pilot/examples/my_bot/word.dict]\n",
- "2019-09-04 15:03:29.100 WARNING in 'deeppavlov.core.models.serializable'['serializable'] at line 47: No load path is set for Sqlite3Database in 'infer' mode. Using save path instead\n",
- "2019-09-04 15:03:29.100 INFO in 'deeppavlov.core.data.sqlite_database'['sqlite_database'] at line 66: Loading database from /home/vimary/code-projects/Pilot/examples/my_bot/db.sqlite.\n",
- "2019-09-04 15:03:29.214 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 161: [loading templates from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-templates.txt]\n",
- "2019-09-04 15:03:29.215 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 164: 46 templates loaded.\n",
- "2019-09-04 15:03:29.216 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 210: Calculated input size for `GoalOrientedBotNetwork` is 205\n",
- "2019-09-04 15:03:29.936 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 248: [initializing `GoalOrientedBot` from saved]\n",
- "2019-09-04 15:03:29.937 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 769: [loading parameters from /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n",
- "2019-09-04 15:03:29.940 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 52: [loading model from /home/vimary/code-projects/Pilot/examples/my_bot/model]\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "INFO:tensorflow:Restoring parameters from /home/vimary/code-projects/Pilot/examples/my_bot/model\n",
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.4113}, \"time_spent\": \"0:01:41\"}}\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 15:06:47.967 INFO in 'deeppavlov.core.data.simple_vocab'['simple_vocab'] at line 112: [loading vocabulary from /home/vimary/code-projects/Pilot/examples/my_bot/word.dict]\n",
- "2019-09-04 15:06:47.969 WARNING in 'deeppavlov.core.models.serializable'['serializable'] at line 47: No load path is set for Sqlite3Database in 'infer' mode. Using save path instead\n",
- "2019-09-04 15:06:47.970 INFO in 'deeppavlov.core.data.sqlite_database'['sqlite_database'] at line 66: Loading database from /home/vimary/code-projects/Pilot/examples/my_bot/db.sqlite.\n",
- "2019-09-04 15:06:48.86 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 161: [loading templates from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-templates.txt]\n",
- "2019-09-04 15:06:48.87 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 164: 46 templates loaded.\n",
- "2019-09-04 15:06:48.87 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 210: Calculated input size for `GoalOrientedBotNetwork` is 205\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"test\": {\"eval_examples_count\": 576, \"metrics\": {\"per_item_dialog_accuracy\": 0.4065}, \"time_spent\": \"0:01:38\"}}\n"
- ]
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 792
},
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 15:06:48.683 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 248: [initializing `GoalOrientedBot` from saved]\n",
- "2019-09-04 15:06:48.684 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 769: [loading parameters from /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n",
- "2019-09-04 15:06:48.686 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 52: [loading model from /home/vimary/code-projects/Pilot/examples/my_bot/model]\n"
- ]
+ "colab_type": "code",
+ "executionInfo": {
+ "elapsed": 40132,
+ "status": "error",
+ "timestamp": 1568800144573,
+ "user": {
+ "displayName": "Mikhail Burtsev",
+ "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mD-UjGT1Q2KIGGrL9KU-xXovwU2v8j7wSsrT1Tj9Q=s64",
+ "userId": "02998805542659340239"
+ },
+ "user_tz": -180
},
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "INFO:tensorflow:Restoring parameters from /home/vimary/code-projects/Pilot/examples/my_bot/model\n"
- ]
- }
- ],
+ "id": "ZRcmJBcvgR5D",
+ "outputId": "d1ad0b56-d45a-4ae6-c7dc-cc88931dfed6"
+ },
+ "outputs": [],
"source": [
"from deeppavlov import train_model\n",
"\n",
- "gobot_config['train']['batch_size'] = 8 # set batch size\n",
- "gobot_config['train']['max_batches'] = 250 # maximum number of training batches\n",
- "gobot_config['train']['val_every_n_batches'] = 40 # evaluate on full 'valid' split each 30 batches\n",
- "gobot_config['train']['log_every_n_batches'] = 40 # evaluate on 20 batches of 'train' split every 30 batches\n",
- "gobot_config['train']['log_on_k_batches'] = 20\n",
+ "gobot_config['train']['batch_size'] = 4 # set batch size\n",
+ "gobot_config['train']['max_batches'] = 30 # maximum number of training batches\n",
+ "gobot_config['train']['val_every_n_batches'] = 30 # evaluate on full 'valid' split every 30 epochs\n",
+ "gobot_config['train']['log_every_n_batches'] = 5 # evaluate on full 'train' split every 5 batches\n",
"\n",
"train_model(gobot_config);"
]
},
{
"cell_type": "markdown",
- "metadata": {},
- "source": [
- "Training on 50 dialogues takes from 5 to 20 minutes depending on gpu/cpu. Training on full data takes 10-30 mins.\n",
- "\n",
- "See [config doc page](http://docs.deeppavlov.ai/en/master/intro/configuration.html) for advanced configuration of the training process."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "##### Metric scores on valid&test"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Calculating **accuracy** of trained bot: whether predicted system responses match true responses (full string match)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
"metadata": {
- "scrolled": true
+ "colab_type": "text",
+ "id": "BMYLonE_gR_Q"
},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 15:57:48.233 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-trn.json]\n",
- "2019-09-04 15:57:48.237 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-val.json]\n",
- "2019-09-04 15:57:48.300 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 290: [loading dialogs from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-tst.json]\n",
- "2019-09-04 15:57:48.343 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 282: There are 479 samples in train split.\n",
- "2019-09-04 15:57:48.344 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 283: There are 6231 samples in valid split.\n",
- "2019-09-04 15:57:48.344 INFO in 'deeppavlov.dataset_readers.dstc2_reader'['dstc2_reader'] at line 284: There are 6345 samples in test split.\n",
- "[nltk_data] Error loading punkt: [Errno 104] Connection reset by peer\n",
- "[nltk_data] Downloading package stopwords to /home/vimary/nltk_data...\n",
- "[nltk_data] Package stopwords is already up-to-date!\n",
- "[nltk_data] Downloading package perluniprops to\n",
- "[nltk_data] /home/vimary/nltk_data...\n",
- "[nltk_data] Package perluniprops is already up-to-date!\n",
- "[nltk_data] Downloading package nonbreaking_prefixes to\n",
- "[nltk_data] /home/vimary/nltk_data...\n",
- "[nltk_data] Package nonbreaking_prefixes is already up-to-date!\n",
- "2019-09-04 15:57:52.422 INFO in 'deeppavlov.core.data.simple_vocab'['simple_vocab'] at line 112: [loading vocabulary from /home/vimary/code-projects/Pilot/examples/my_bot/word.dict]\n",
- "WARNING: Logging before flag parsing goes to stderr.\n",
- "W0904 15:57:53.651001 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/core/models/tf_model.py:38: The name tf.Session is deprecated. Please use tf.compat.v1.Session instead.\n",
- "\n",
- "W0904 15:57:53.652002 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/core/models/tf_model.py:223: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.\n",
- "\n",
- "W0904 15:57:53.652476 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/core/models/tf_model.py:223: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.\n",
- "\n",
- "2019-09-04 15:57:53.654 WARNING in 'deeppavlov.core.models.serializable'['serializable'] at line 47: No load path is set for Sqlite3Database in 'infer' mode. Using save path instead\n",
- "W0904 15:57:53.654331 140389567809152 serializable.py:47] No load path is set for Sqlite3Database in 'infer' mode. Using save path instead\n",
- "2019-09-04 15:57:53.655 INFO in 'deeppavlov.core.data.sqlite_database'['sqlite_database'] at line 66: Loading database from /home/vimary/code-projects/Pilot/examples/my_bot/db.sqlite.\n",
- "I0904 15:57:53.655865 140389567809152 sqlite_database.py:66] Loading database from /home/vimary/code-projects/Pilot/examples/my_bot/db.sqlite.\n",
- "Using TensorFlow backend.\n",
- "W0904 15:57:54.006649 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/core/common/registry.py:40: The name tf.train.AdamOptimizer is deprecated. Please use tf.compat.v1.train.AdamOptimizer instead.\n",
- "\n",
- "W0904 15:57:54.007156 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/core/models/tf_model.py:195: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.\n",
- "\n",
- "2019-09-04 15:57:54.12 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 161: [loading templates from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-templates.txt]\n",
- "I0904 15:57:54.012057 140389567809152 network.py:161] [loading templates from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-templates.txt]\n",
- "2019-09-04 15:57:54.13 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 164: 46 templates loaded.\n",
- "I0904 15:57:54.013284 140389567809152 network.py:164] 46 templates loaded.\n",
- "2019-09-04 15:57:54.13 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 210: Calculated input size for `GoalOrientedBotNetwork` is 205\n",
- "I0904 15:57:54.013964 140389567809152 network.py:210] Calculated input size for `GoalOrientedBotNetwork` is 205\n",
- "W0904 15:57:54.014632 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:644: The name tf.placeholder_with_default is deprecated. Please use tf.compat.v1.placeholder_with_default instead.\n",
- "\n",
- "W0904 15:57:54.026143 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:665: The name tf.nn.rnn_cell.LSTMStateTuple is deprecated. Please use tf.compat.v1.nn.rnn_cell.LSTMStateTuple instead.\n",
- "\n",
- "W0904 15:57:54.026710 140389567809152 deprecation.py:323] From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:681: dense (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Use keras.layers.dense instead.\n",
- "W0904 15:57:54.235459 140389567809152 deprecation.py:323] From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:731: LSTMCell.__init__ (from tensorflow.python.ops.rnn_cell_impl) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "This class is equivalent as tf.keras.layers.LSTMCell, and will be replaced by that in Tensorflow 2.0.\n",
- "W0904 15:57:54.237989 140389567809152 deprecation.py:323] From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:740: dynamic_rnn (from tensorflow.python.ops.rnn) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Please use `keras.layers.RNN(cell)`, which is equivalent to this API\n",
- "W0904 15:57:54.287045 140389567809152 deprecation.py:506] From /home/vimary/dp_env/lib/python3.7/site-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Call initializer instance with the dtype argument instead of passing it to the constructor\n",
- "W0904 15:57:54.294301 140389567809152 deprecation.py:506] From /home/vimary/dp_env/lib/python3.7/site-packages/tensorflow/python/ops/rnn_cell_impl.py:961: calling Zeros.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Call initializer instance with the dtype argument instead of passing it to the constructor\n",
- "W0904 15:57:54.683625 140389567809152 deprecation.py:323] From /home/vimary/dp_env/lib/python3.7/site-packages/tensorflow/python/ops/rnn.py:244: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Use tf.where in 2.0, which has the same broadcast rule as np.where\n",
- "W0904 15:57:54.752373 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:640: The name tf.losses.get_regularization_loss is deprecated. Please use tf.compat.v1.losses.get_regularization_loss instead.\n",
- "\n",
- "W0904 15:57:54.754825 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/core/models/tf_model.py:123: The name tf.variable_scope is deprecated. Please use tf.compat.v1.variable_scope instead.\n",
- "\n",
- "W0904 15:57:54.755474 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/core/models/tf_model.py:128: The name tf.get_collection is deprecated. Please use tf.compat.v1.get_collection instead.\n",
- "\n",
- "W0904 15:57:55.111044 140389567809152 deprecation.py:323] From /home/vimary/dp_env/lib/python3.7/site-packages/tensorflow/python/ops/variables.py:2618: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "W0904 15:57:55.873465 140389567809152 deprecation.py:323] From /home/vimary/code-projects/Pilot/deeppavlov/models/go_bot/network.py:247: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
- "Instructions for updating:\n",
- "Use standard file APIs to check for files with this prefix.\n",
- "2019-09-04 15:57:55.875 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 248: [initializing `GoalOrientedBot` from saved]\n",
- "I0904 15:57:55.875579 140389567809152 network.py:248] [initializing `GoalOrientedBot` from saved]\n",
- "2019-09-04 15:57:55.876 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 766: [loading parameters from /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n",
- "I0904 15:57:55.876817 140389567809152 network.py:766] [loading parameters from /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n",
- "2019-09-04 15:57:55.880 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 52: [loading model from /home/vimary/code-projects/Pilot/examples/my_bot/model]\n",
- "I0904 15:57:55.880907 140389567809152 tf_model.py:52] [loading model from /home/vimary/code-projects/Pilot/examples/my_bot/model]\n",
- "W0904 15:57:55.882345 140389567809152 deprecation_wrapper.py:119] From /home/vimary/code-projects/Pilot/deeppavlov/core/models/tf_model.py:55: The name tf.train.Saver is deprecated. Please use tf.compat.v1.train.Saver instead.\n",
- "\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{\"valid\": {\"eval_examples_count\": 575, \"metrics\": {\"per_item_dialog_accuracy\": 0.5009}, \"time_spent\": \"0:01:37\"}}\n",
- "{\"test\": {\"eval_examples_count\": 576, \"metrics\": {\"per_item_dialog_accuracy\": 0.4927}, \"time_spent\": \"0:01:52\"}}\n"
- ]
- }
- ],
- "source": [
- "from deeppavlov import evaluate_model\n",
- "\n",
- "evaluate_model(gobot_config);"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
"source": [
- "With settings of `max_batches=200`, valid accuracy `= 0.5` and test accuracy is `~ 0.5`."
+ "Training on the dataset takes up to 5 minutes depending on gpu/cpu. See [config doc page](http://docs.deeppavlov.ai/en/master/intro/configuration.html) for advanced configuration of the training process."
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "colab_type": "text",
+ "id": "8CNlZyfSgSAi"
+ },
"source": [
- "##### Chatting with bot"
+ "# 2. Interact with bot"
]
},
{
"cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 16:08:37.948 INFO in 'deeppavlov.core.data.simple_vocab'['simple_vocab'] at line 112: [loading vocabulary from /home/vimary/code-projects/Pilot/examples/my_bot/word.dict]\n",
- "I0904 16:08:37.948703 140389567809152 simple_vocab.py:112] [loading vocabulary from /home/vimary/code-projects/Pilot/examples/my_bot/word.dict]\n",
- "2019-09-04 16:08:37.950 WARNING in 'deeppavlov.core.models.serializable'['serializable'] at line 47: No load path is set for Sqlite3Database in 'infer' mode. Using save path instead\n",
- "W0904 16:08:37.950447 140389567809152 serializable.py:47] No load path is set for Sqlite3Database in 'infer' mode. Using save path instead\n",
- "2019-09-04 16:08:37.951 INFO in 'deeppavlov.core.data.sqlite_database'['sqlite_database'] at line 66: Loading database from /home/vimary/code-projects/Pilot/examples/my_bot/db.sqlite.\n",
- "I0904 16:08:37.951788 140389567809152 sqlite_database.py:66] Loading database from /home/vimary/code-projects/Pilot/examples/my_bot/db.sqlite.\n",
- "2019-09-04 16:08:38.50 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 161: [loading templates from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-templates.txt]\n",
- "I0904 16:08:38.050452 140389567809152 network.py:161] [loading templates from /home/vimary/code-projects/Pilot/examples/my_data/simple-dstc2-templates.txt]\n",
- "2019-09-04 16:08:38.51 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 164: 46 templates loaded.\n",
- "I0904 16:08:38.051369 140389567809152 network.py:164] 46 templates loaded.\n",
- "2019-09-04 16:08:38.52 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 210: Calculated input size for `GoalOrientedBotNetwork` is 205\n",
- "I0904 16:08:38.052139 140389567809152 network.py:210] Calculated input size for `GoalOrientedBotNetwork` is 205\n",
- "2019-09-04 16:08:38.679 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 248: [initializing `GoalOrientedBot` from saved]\n",
- "I0904 16:08:38.679202 140389567809152 network.py:248] [initializing `GoalOrientedBot` from saved]\n",
- "2019-09-04 16:08:38.680 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 766: [loading parameters from /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n",
- "I0904 16:08:38.680273 140389567809152 network.py:766] [loading parameters from /home/vimary/code-projects/Pilot/examples/my_bot/model.json]\n",
- "2019-09-04 16:08:38.681 INFO in 'deeppavlov.core.models.tf_model'['tf_model'] at line 52: [loading model from /home/vimary/code-projects/Pilot/examples/my_bot/model]\n",
- "I0904 16:08:38.681917 140389567809152 tf_model.py:52] [loading model from /home/vimary/code-projects/Pilot/examples/my_bot/model]\n"
- ]
- }
- ],
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "kaUTLCl_gSAm"
+ },
+ "outputs": [],
"source": [
"from deeppavlov import build_model\n",
"\n",
@@ -1542,159 +661,104 @@
},
{
"cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['Hello, welcome to the Cambridge restaurant system. You can ask for restaurants by area, price range or food type. How may I help you?']"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "1UTvHL01gSA5"
+ },
+ "outputs": [],
"source": [
- "bot(['hi, i want to eat, can you suggest a place to go?'])"
+ "bot(['good evening, bot'])"
]
},
{
"cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['What kind of food would you like?']"
- ]
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "YY_BdF-egSBT"
+ },
+ "outputs": [],
"source": [
- "bot(['i want cheap food'])"
+ "bot(['the weather is clooudy and gloooomy'])"
]
},
{
"cell_type": "code",
- "execution_count": 13,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2019-09-04 16:08:41.145 INFO in 'deeppavlov.models.go_bot.network'['network'] at line 488: Made api_call with {'pricerange': 'cheap', 'food': 'chinese'}, got 4 results.\n",
- "I0904 16:08:41.145185 140389567809152 network.py:488] Made api_call with {'pricerange': 'cheap', 'food': 'chinese'}, got 4 results.\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "['The lucky star serves chinese food.']"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "-Xf1gCdmgSBr"
+ },
+ "outputs": [],
"source": [
- "bot(['chinese food'])"
+ "bot([\"nice idea, thanks!\"])"
]
},
{
"cell_type": "code",
- "execution_count": 14,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['Sure, the lucky star is on cambridge leisure park clifton way cherry hinton.']"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "Ad_GDanAgSCi"
+ },
+ "outputs": [],
"source": [
- "bot(['thanks, give me their address'])"
+ "bot.reset()"
]
},
{
"cell_type": "code",
- "execution_count": 15,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['The phone number of the lucky star is 01223 244277.']"
- ]
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "r5312Df1gSC0"
+ },
+ "outputs": [],
"source": [
- "bot(['i want their phone number too'])"
+ "bot(['hi bot'])"
]
},
{
"cell_type": "code",
- "execution_count": 16,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['You are welcome!']"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "jXQw_11jgSDM"
+ },
+ "outputs": [],
"source": [
- "bot(['bye'])"
+ "bot([\"looks ok, the sun is bright and yesterday's rain stopped already\"])"
]
},
{
"cell_type": "code",
- "execution_count": 17,
- "metadata": {},
+ "execution_count": null,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "-SKJicTCgSDe"
+ },
"outputs": [],
"source": [
- "bot.reset()"
+ "bot(['i dont wanna'])"
]
},
{
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['What kind of food would you like?']"
- ]
- },
- "execution_count": 18,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "cell_type": "markdown",
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "wdg4wl0dgSD9"
+ },
"source": [
- "bot(['hi, is there any cheap restaurant?'])"
+ "You can also train a more advanced goal-oriented bot following [gobot_extended_tutorial.ipynb](https://github.com/deepmipt/DeepPavlov/blob/master/examples/gobot_extended_tutorial.ipynb)"
]
},
{
@@ -1706,11 +770,16 @@
}
],
"metadata": {
+ "colab": {
+ "name": "gobot_tutorial_simple(MB).ipynb",
+ "provenance": [],
+ "version": "0.3.2"
+ },
"kernelspec": {
- "display_name": "Python (dp_env)",
- "language": "python",
- "name": "dp_env"
+ "display_name": "Python 3",
+ "name": "python3"
},
+ "accelerator": "GPU",
"language_info": {
"codemirror_mode": {
"name": "ipython",
@@ -1721,9 +790,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.7.3"
+ "version": "3.7.4"
}
},
"nbformat": 4,
- "nbformat_minor": 2
+ "nbformat_minor": 1
}
diff --git a/examples/img/gobot_simple_example.png b/examples/img/gobot_simple_example.png
new file mode 100644
index 0000000000..8508e8a052
Binary files /dev/null and b/examples/img/gobot_simple_example.png differ
diff --git a/examples/img/gobot_simple_pipeline.png b/examples/img/gobot_simple_pipeline.png
new file mode 100644
index 0000000000..84b8db1dea
Binary files /dev/null and b/examples/img/gobot_simple_pipeline.png differ
diff --git a/examples/img/gobot_simple_policy.png b/examples/img/gobot_simple_policy.png
new file mode 100644
index 0000000000..54d616060d
Binary files /dev/null and b/examples/img/gobot_simple_policy.png differ
diff --git a/examples/img/gobot_simple_templates.png b/examples/img/gobot_simple_templates.png
new file mode 100644
index 0000000000..f1ae4e83ed
Binary files /dev/null and b/examples/img/gobot_simple_templates.png differ
diff --git a/examples/morphotagger_example.ipynb b/examples/morphotagger_example.ipynb
index 5e5ba21438..c02da8ee23 100644
--- a/examples/morphotagger_example.ipynb
+++ b/examples/morphotagger_example.ipynb
@@ -294,9 +294,9 @@
"metadata": {
"kernelspec": {
"display_name": "Python 3",
- "language": "python",
"name": "python3"
},
+ "accelerator": "GPU",
"language_info": {
"codemirror_mode": {
"name": "ipython",
diff --git a/examples/super_convergence_tutorial.ipynb b/examples/super_convergence_tutorial.ipynb
index 9b0544cb80..80ad8298a8 100644
--- a/examples/super_convergence_tutorial.ipynb
+++ b/examples/super_convergence_tutorial.ipynb
@@ -589,10 +589,10 @@
],
"metadata": {
"kernelspec": {
- "display_name": "tensorflow_kernel2",
- "language": "python",
- "name": "tensorflow_kernel2"
+ "display_name": "Python 3",
+ "name": "python3"
},
+ "accelerator": "GPU",
"language_info": {
"codemirror_mode": {
"name": "ipython",
diff --git a/examples/yandex_faq_ru.ipynb b/examples/yandex_faq_ru.ipynb
index dadb28ff82..3b87b2eccf 100644
--- a/examples/yandex_faq_ru.ipynb
+++ b/examples/yandex_faq_ru.ipynb
@@ -161,7 +161,7 @@
"\n",
"[DeepPavlov repository](https://github.com/deepmipt/DeepPavlov)\n",
"\n",
- "[DeepPavlov demo page](https://demo.ipavlov.ai)\n",
+ "[DeepPavlov demo page](https://demo.deeppavlov.ai)\n",
"\n",
"[DeepPavlov documentation](https://docs.deeppavlov.ai)\n",
"\n",
@@ -186,6 +186,15 @@
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.8"
+ },
+ "pycharm": {
+ "stem_cell": {
+ "cell_type": "raw",
+ "source": [],
+ "metadata": {
+ "collapsed": false
+ }
+ }
}
},
"nbformat": 4,
diff --git a/requirements.txt b/requirements.txt
index 268a61795a..da2d078c7b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,20 +1,22 @@
Cython==0.29.12
-overrides==1.9
-numpy==1.16.4
-pandas==0.24.2
-nltk==3.2.5
-tqdm==4.32.2
-scipy==1.3.0
+fastapi==0.38.1
+flasgger==0.9.2
+flask==1.1.1
+flask_cors==3.0.8
+fuzzywuzzy==0.17.0
h5py==2.9.0
keras==2.2.4
-scikit-learn==0.21.2
-fuzzywuzzy==0.17.0
+nltk==3.2.5
+numpy==1.16.4
+overrides==1.9
+pandas==0.24.2
pymorphy2==0.8
pymorphy2-dicts-ru
-requests==2.22.0
+pyopenssl==19.0.0
pytelegrambotapi==3.6.6
-flask==1.1.1
-flasgger==0.9.2
-flask_cors==3.0.8
+requests==2.22.0
rusenttokenize==0.0.5
-pyopenssl==19.0.0
\ No newline at end of file
+scikit-learn==0.21.2
+scipy==1.3.0
+tqdm==4.32.2
+uvicorn==0.9.0
\ No newline at end of file
diff --git a/tests/test_quick_start.py b/tests/test_quick_start.py
index 5e995d1f88..4215a6027e 100644
--- a/tests/test_quick_start.py
+++ b/tests/test_quick_start.py
@@ -385,18 +385,12 @@ def interact_api(config_path):
server_conf_file = get_settings_path() / SERVER_CONFIG_FILENAME
server_params = get_server_params(server_conf_file, config_path)
- model_args_names = server_params['model_args_names']
- url_base = 'http://{}:{}/'.format(server_params['host'], api_port or server_params['port'])
+ url_base = 'http://{}:{}'.format(server_params['host'], api_port or server_params['port'])
url = urljoin(url_base.replace('http://0.0.0.0:', 'http://127.0.0.1:'), server_params['model_endpoint'])
post_headers = {'Accept': 'application/json'}
- post_payload = {}
- for arg_name in model_args_names:
- arg_value = ' '.join(['qwerty'] * 10)
- post_payload[arg_name] = [arg_value]
-
logfile = io.BytesIO(b'')
args = [sys.executable, "-m", "deeppavlov", "riseapi", str(config_path)]
if api_port:
@@ -405,6 +399,18 @@ def interact_api(config_path):
timeout=None, logfile=logfile)
try:
p.expect(url_base)
+
+ get_url = urljoin(url_base.replace('http://0.0.0.0:', 'http://127.0.0.1:'), '/api')
+ get_response = requests.get(get_url)
+ response_code = get_response.status_code
+ assert response_code == 200, f"GET /api request returned error code {response_code} with {config_path}"
+
+ model_args_names = get_response.json()
+ post_payload = dict()
+ for arg_name in model_args_names:
+ arg_value = ' '.join(['qwerty'] * 10)
+ post_payload[arg_name] = [arg_value]
+
post_response = requests.post(url, json=post_payload, headers=post_headers)
response_code = post_response.status_code
assert response_code == 200, f"POST request returned error code {response_code} with {config_path}"