dst module

This commit is contained in:
s444417 2022-05-26 15:26:58 +02:00
parent b2ccdf7945
commit 27bb98f6be
9 changed files with 1264 additions and 194 deletions

4
.gitignore vendored
View File

@ -213,4 +213,6 @@ fabric.properties
.idea .idea
slot-model slot-model
ConvLab-2

View File

@ -9,7 +9,7 @@
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n", "<div class=\"alert alert-block alert-info\">\n",
"<h1> Systemy Dialogowe </h1>\n", "<h1> Systemy Dialogowe </h1>\n",
"<h2> 9. <i>Zarz\u0105dzanie dialogiem z wykorzystaniem regu\u0142</i> [laboratoria]</h2> \n", "<h2> 9. <i>Zarządzanie dialogiem z wykorzystaniem reguł</i> [laboratoria]</h2> \n",
"<h3> Marek Kubis (2021)</h3>\n", "<h3> Marek Kubis (2021)</h3>\n",
"</div>\n", "</div>\n",
"\n", "\n",
@ -20,30 +20,30 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Zarz\u0105dzanie dialogiem z wykorzystaniem regu\u0142\n", "Zarządzanie dialogiem z wykorzystaniem reguł\n",
"============================================\n", "============================================\n",
"\n", "\n",
"Agent dialogowy wykorzystuje do zarz\u0105dzanie dialogiem dwa modu\u0142y:\n", "Agent dialogowy wykorzystuje do zarządzanie dialogiem dwa moduły:\n",
"\n", "\n",
" - monitor stanu dialogu (dialogue state tracker, DST) \u2014 modu\u0142 odpowiedzialny za \u015bledzenie stanu dialogu.\n", " - monitor stanu dialogu (dialogue state tracker, DST) — moduł odpowiedzialny za śledzenie stanu dialogu.\n",
"\n", "\n",
" - taktyk\u0119 prowadzenia dialogu (dialogue policy) \u2014 modu\u0142, kt\u00f3ry na podstawie stanu dialogu\n", " - taktykę prowadzenia dialogu (dialogue policy) — moduł, który na podstawie stanu dialogu\n",
" podejmuje decyzj\u0119 o tym jak\u0105 akcj\u0119 (akt systemu) agent ma podj\u0105\u0107 w kolejnej turze.\n", " podejmuje decyzję o tym jaką akcję (akt systemu) agent ma podjąć w kolejnej turze.\n",
"\n", "\n",
"Oba modu\u0142y mog\u0105 by\u0107 realizowane zar\u00f3wno z wykorzystaniem regu\u0142 jak i uczenia maszynowego.\n", "Oba moduły mogą być realizowane zarówno z wykorzystaniem reguł jak i uczenia maszynowego.\n",
"Mog\u0105 one zosta\u0107 r\u00f3wnie\u017c po\u0142\u0105czone w pojedynczy modu\u0142 zwany w\u00f3wczas *mened\u017cerem dialogu*.\n", "Mogą one zostać również połączone w pojedynczy moduł zwany wówczas *menedżerem dialogu*.\n",
"\n", "\n",
"Przyk\u0142ad\n", "Przykład\n",
"--------\n", "--------\n",
"\n", "\n",
"Zaimplementujemy regu\u0142owe modu\u0142y monitora stanu dialogu oraz taktyki dialogowej a nast\u0119pnie\n", "Zaimplementujemy regułowe moduły monitora stanu dialogu oraz taktyki dialogowej a następnie\n",
"osadzimy je w \u015brodowisku *[ConvLab-2](https://github.com/thu-coai/ConvLab-2)*,\n", "osadzimy je w środowisku *[ConvLab-2](https://github.com/thu-coai/ConvLab-2)*,\n",
"kt\u00f3re s\u0142u\u017cy do ewaluacji system\u00f3w dialogowych.\n", "które służy do ewaluacji systemów dialogowych.\n",
"\n", "\n",
"**Uwaga:** Niekt\u00f3re modu\u0142y \u015brodowiska *ConvLab-2* nie s\u0105 zgodne z najnowszymi wersjami Pythona,\n", "**Uwaga:** Niektóre moduły środowiska *ConvLab-2* nie są zgodne z najnowszymi wersjami Pythona,\n",
"dlatego przed uruchomieniem poni\u017cszych przyk\u0142ad\u00f3w nale\u017cy si\u0119 upewni\u0107, \u017ce maj\u0105 Pa\u0144stwo interpreter\n", "dlatego przed uruchomieniem poniższych przykładów należy się upewnić, że mają Państwo interpreter\n",
"Pythona w wersji 3.7. W przypadku nowszych wersji Ubuntu Pythona 3.7 mo\u017cna zainstalowa\u0107 z\n", "Pythona w wersji 3.7. W przypadku nowszych wersji Ubuntu Pythona 3.7 można zainstalować z\n",
"repozytorium `deadsnakes`, wykonuj\u0105c polecenia przedstawione poni\u017cej.\n", "repozytorium `deadsnakes`, wykonując polecenia przedstawione poniżej.\n",
"\n", "\n",
"```\n", "```\n",
"sudo add-apt-repository ppa:deadsnakes/ppa\n", "sudo add-apt-repository ppa:deadsnakes/ppa\n",
@ -51,20 +51,20 @@
"sudo apt install python3.7 python3.7-dev python3.7-venv\n", "sudo apt install python3.7 python3.7-dev python3.7-venv\n",
"```\n", "```\n",
"\n", "\n",
"W przypadku innych system\u00f3w mo\u017cna skorzysta\u0107 np. z narz\u0119dzia [pyenv](https://github.com/pyenv/pyenv) lub \u015brodowiska [conda](https://conda.io).\n", "W przypadku innych systemów można skorzystać np. z narzędzia [pyenv](https://github.com/pyenv/pyenv) lub środowiska [conda](https://conda.io).\n",
"\n", "\n",
"Ze wzgl\u0119du na to, \u017ce *ConvLab-2* ma wiele zale\u017cno\u015bci zach\u0119cam r\u00f3wnie\u017c do skorzystania ze \u015brodowiska\n", "Ze względu na to, że *ConvLab-2* ma wiele zależności zachęcam również do skorzystania ze środowiska\n",
"wirtualnego `venv`, w kt\u00f3rym modu\u0142y zale\u017cne mog\u0105 zosta\u0107 zainstalowane.\n", "wirtualnego `venv`, w którym moduły zależne mogą zostać zainstalowane.\n",
"W tym celu nale\u017cy wykona\u0107 nast\u0119puj\u0105ce polecenia\n", "W tym celu należy wykonać następujące polecenia\n",
"\n", "\n",
"```\n", "```\n",
"python3.7 -m venv convenv # utworzenie nowego \u015brodowiska o nazwie convenv\n", "python3.7 -m venv convenv # utworzenie nowego środowiska o nazwie convenv\n",
"source convenv/bin/activate # aktywacja \u015brodowiska w bie\u017c\u0105cej pow\u0142oce\n", "source convenv/bin/activate # aktywacja środowiska w bieżącej powłoce\n",
"pip install --ignore-installed jupyter # instalacja jupytera w \u015brodowisku convenv\n", "pip install --ignore-installed jupyter # instalacja jupytera w środowisku convenv\n",
"```\n", "```\n",
"\n", "\n",
"Po skonfigurowaniu \u015brodowiska mo\u017cna przyst\u0105pi\u0107 do instalacji *ConvLab-2*, korzystaj\u0105c z\n", "Po skonfigurowaniu środowiska można przystąpić do instalacji *ConvLab-2*, korzystając z\n",
"nast\u0119puj\u0105cych polece\u0144\n", "następujących poleceń\n",
"\n", "\n",
"```\n", "```\n",
"mkdir -p l08\n", "mkdir -p l08\n",
@ -76,30 +76,54 @@
"cd ../..\n", "cd ../..\n",
"```\n", "```\n",
"\n", "\n",
"Po zako\u0144czeniu instalacji nale\u017cy ponownie uruchomi\u0107 notatnik w pow\u0142oce, w kt\u00f3rej aktywne jest\n", "Po zakończeniu instalacji należy ponownie uruchomić notatnik w powłoce, w której aktywne jest\n",
"\u015brodowisko wirtualne *convenv*.\n", "środowisko wirtualne *convenv*.\n",
"\n", "\n",
"```\n", "```\n",
"jupyter notebook 08-zarzadzanie-dialogiem-reguly.ipynb\n", "jupyter notebook 08-zarzadzanie-dialogiem-reguly.ipynb\n",
"```\n", "```\n",
"\n", "\n",
"Dzia\u0142anie zaimplementowanych modu\u0142\u00f3w zilustrujemy, korzystaj\u0105c ze zbioru danych\n", "Działanie zaimplementowanych modułów zilustrujemy, korzystając ze zbioru danych\n",
"[MultiWOZ](https://github.com/budzianowski/multiwoz) (Budzianowski i in., 2018), kt\u00f3ry zawiera\n", "[MultiWOZ](https://github.com/budzianowski/multiwoz) (Budzianowski i in., 2018), który zawiera\n",
"wypowiedzi dotycz\u0105ce m.in. rezerwacji pokoi hotelowych, zamawiania bilet\u00f3w kolejowych oraz\n", "wypowiedzi dotyczące m.in. rezerwacji pokoi hotelowych, zamawiania biletów kolejowych oraz\n",
"rezerwacji stolik\u00f3w w restauracji.\n", "rezerwacji stolików w restauracji.\n",
"\n", "\n",
"### Monitor Stanu Dialogu\n", "### Monitor Stanu Dialogu\n",
"\n", "\n",
"Do reprezentowania stanu dialogu u\u017cyjemy struktury danych wykorzystywanej w *ConvLab-2*." "Do reprezentowania stanu dialogu użyjemy struktury danych wykorzystywanej w *ConvLab-2*."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 3,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"data": {
"text/plain": [
"{'user_action': [],\n",
" 'system_action': [],\n",
" 'belief_state': {'cinema': {'book': {'title': '',\n",
" 'date': '',\n",
" 'time': '',\n",
" 'quantity': '',\n",
" 'seats': '',\n",
" 'area': '',\n",
" 'interval': ''},\n",
" 'semi': {'goal': ''}}},\n",
" 'request_state': {},\n",
" 'terminated': False,\n",
" 'history': []}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [ "source": [
"from convlab2.util.multiwoz.state import default_state\n", "# from convlab2.util.multiwoz.state import default_state\n",
"from utils.state import default_state\n",
"default_state()" "default_state()"
] ]
}, },
@ -107,19 +131,30 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Metoda `update` naszego monitora stanu dialogu b\u0119dzie przyjmowa\u0107 akty u\u017cytkownika i odpowiednio\n", "Metoda `update` naszego monitora stanu dialogu będzie przyjmować akty użytkownika i odpowiednio\n",
"modyfikowa\u0107 stan dialogu.\n", "modyfikować stan dialogu.\n",
"W przypadku akt\u00f3w typu `inform` warto\u015bci slot\u00f3w zostan\u0105 zapami\u0119tane w s\u0142ownikach odpowiadaj\u0105cych\n", "W przypadku aktów typu `inform` wartości slotów zostaną zapamiętane w słownikach odpowiadających\n",
"poszczeg\u00f3lnym dziedzinom pod kluczem `belief_state`.\n", "poszczególnym dziedzinom pod kluczem `belief_state`.\n",
"W przypadku akt\u00f3w typu `request` sloty, o kt\u00f3re pyta u\u017cytkownik zostan\u0105 zapisane pod kluczem\n", "W przypadku aktów typu `request` sloty, o które pyta użytkownik zostaną zapisane pod kluczem\n",
"`request_state`.\n" "`request_state`.\n"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 34,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"data": {
"text/plain": [
"\"\\nclass SimpleRuleDST(DST):\\n def __init__(self):\\n DST.__init__(self)\\n self.state = default_state()\\n self.value_dict = json.load(open('l08/ConvLab-2/data/multiwoz/value_dict.json'))\\n\\n def update(self, user_act=None):\\n for intent, domain, slot, value in user_act:\\n domain = domain.lower()\\n intent = intent.lower()\\n\\n if domain in ['unk', 'general', 'booking']:\\n continue\\n\\n if intent == 'inform':\\n k = REF_SYS_DA[domain.capitalize()].get(slot, slot)\\n\\n if k is None:\\n continue\\n\\n domain_dic = self.state['belief_state'][domain]\\n\\n if k in domain_dic['semi']:\\n nvalue = normalize_value(self.value_dict, domain, k, value)\\n self.state['belief_state'][domain]['semi'][k] = nvalue\\n elif k in domain_dic['book']:\\n self.state['belief_state'][domain]['book'][k] = value\\n elif k.lower() in domain_dic['book']:\\n self.state['belief_state'][domain]['book'][k.lower()] = value\\n elif intent == 'request':\\n k = REF_SYS_DA[domain.capitalize()].get(slot, slot)\\n\\n if domain not in self.state['request_state']:\\n self.state['request_state'][domain] = {}\\n if k not in self.state['request_state'][domain]:\\n self.state['request_state'][domain][k] = 0\\n\\n return self.state\\n\\n def init_session(self):\\n self.state = default_state()\\n\""
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [ "source": [
"import json\n", "import json\n",
"import os\n", "import os\n",
@ -127,7 +162,50 @@
"from convlab2.dst.rule.multiwoz.dst_util import normalize_value\n", "from convlab2.dst.rule.multiwoz.dst_util import normalize_value\n",
"from convlab2.util.multiwoz.multiwoz_slot_trans import REF_SYS_DA\n", "from convlab2.util.multiwoz.multiwoz_slot_trans import REF_SYS_DA\n",
"\n", "\n",
"class SimpleRuleDST(DST):\n",
" def __init__(self):\n",
" DST.__init__(self)\n",
" self.state = default_state()\n",
" self.value_dict = json.load(open('utils/value_dict.json'))\n",
"\n", "\n",
" def update(self, user_act=None):\n",
" for intent, domain, slot, value in user_act:\n",
" domain = domain.lower()\n",
" intent = intent.lower()\n",
" value = value.lower()\n",
"\n",
" # if domain in ['unk', 'cinema']:\n",
" # continue\n",
" k = slot\n",
"\n",
" if intent == 'inform':\n",
" # k = REF_SYS_DA[domain.capitalize()].get(slot, slot)\n",
" # if k is None:\n",
" # continue\n",
"\n",
" domain_dic = self.state['belief_state'][domain]\n",
"\n",
" if k in domain_dic['semi']:\n",
" # nvalue = normalize_value(self.value_dict, domain, k, value)\n",
" self.state['belief_state'][domain]['semi'][k] = value\n",
" elif k in domain_dic['book']:\n",
" self.state['belief_state'][domain]['book'][k] = value\n",
" elif k.lower() in domain_dic['book']:\n",
" self.state['belief_state'][domain]['book'][k.lower()] = value\n",
" elif intent == 'request':\n",
" # k = REF_SYS_DA[domain.capitalize()].get(slot, slot)\n",
"\n",
" if domain not in self.state['request_state']:\n",
" self.state['request_state'][domain] = {}\n",
" if k not in self.state['request_state'][domain]:\n",
" self.state['request_state'][domain][k] = 0\n",
"\n",
" return self.state\n",
"\n",
" def init_session(self):\n",
" self.state = default_state()\n",
"\n",
"'''\n",
"class SimpleRuleDST(DST):\n", "class SimpleRuleDST(DST):\n",
" def __init__(self):\n", " def __init__(self):\n",
" DST.__init__(self)\n", " DST.__init__(self)\n",
@ -168,32 +246,56 @@
" return self.state\n", " return self.state\n",
"\n", "\n",
" def init_session(self):\n", " def init_session(self):\n",
" self.state = default_state()\n" " self.state = default_state()\n",
"'''\n"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"W definicji metody `update` zak\u0142adamy, \u017ce akty dialogowe przekazywane do monitora stanu dialogu z\n", "W definicji metody `update` zakładamy, że akty dialogowe przekazywane do monitora stanu dialogu z\n",
"modu\u0142u NLU s\u0105 czteroelementowymi listami z\u0142o\u017conymi z:\n", "modułu NLU są czteroelementowymi listami złożonymi z:\n",
"\n", "\n",
" - nazwy aktu u\u017cytkownika,\n", " - nazwy aktu użytkownika,\n",
" - nazwy dziedziny, kt\u00f3rej dotyczy wypowied\u017a,\n", " - nazwy dziedziny, której dotyczy wypowiedź,\n",
" - nazwy slotu,\n", " - nazwy slotu,\n",
" - warto\u015bci slotu.\n", " - wartości slotu.\n",
"\n", "\n",
"Zobaczmy na kilku prostych przyk\u0142adach jak stan dialogu zmienia si\u0119 pod wp\u0142ywem przekazanych akt\u00f3w\n", "Zobaczmy na kilku prostych przykładach jak stan dialogu zmienia się pod wpływem przekazanych aktów\n",
"u\u017cytkownika." "użytkownika."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 35,
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"data": {
"text/plain": [
"{'user_action': [],\n",
" 'system_action': [],\n",
" 'belief_state': {'cinema': {'book': {'title': '',\n",
" 'date': '',\n",
" 'time': '',\n",
" 'quantity': '',\n",
" 'seats': '',\n",
" 'area': '',\n",
" 'interval': ''},\n",
" 'semi': {'goal': ''}}},\n",
" 'request_state': {},\n",
" 'terminated': False,\n",
" 'history': []}"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [ "source": [
"dst = SimpleRuleDST()\n", "dst = SimpleRuleDST()\n",
"dst.state" "dst.state"
@ -201,37 +303,84 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 36,
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"data": {
"text/plain": [
"{'book': {'title': 'batman',\n",
" 'date': '',\n",
" 'time': '15:00',\n",
" 'quantity': '',\n",
" 'seats': '',\n",
" 'area': '',\n",
" 'interval': ''},\n",
" 'semi': {'goal': ''}}"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [ "source": [
"dst.update([['Inform', 'Hotel', 'Price', 'cheap'], ['Inform', 'Hotel', 'Parking', 'yes']])\n", "dst.update([['Inform', 'Cinema', 'time', '15:00'], ['Inform', 'Cinema', 'title', 'Batman']])\n",
"dst.state['belief_state']['hotel']" "dst.state['belief_state']['cinema']"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 37,
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"data": {
"text/plain": [
"{'book': {'title': 'batman',\n",
" 'date': '',\n",
" 'time': '15:00',\n",
" 'quantity': '',\n",
" 'seats': '',\n",
" 'area': 'na górze na środku',\n",
" 'interval': ''},\n",
" 'semi': {'goal': ''}}"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [ "source": [
"dst.update([['Inform', 'Hotel', 'Area', 'north']])\n", "dst.update([['Inform', 'Cinema', 'area', 'na górze na środku']])\n",
"dst.state['belief_state']['hotel']" "dst.state['belief_state']['cinema']"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 38,
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"data": {
"text/plain": [
"{'cinema': {'date': 0}}"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [ "source": [
"dst.update([['Request', 'Hotel', 'Area', '?']])\n", "dst.update([['Request', 'Cinema', 'date', '?']])\n",
"dst.state['request_state']" "dst.state['request_state']"
] ]
}, },
@ -241,7 +390,28 @@
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"dst.update([['Inform', 'Hotel', 'Day', 'tuesday'], ['Inform', 'Hotel', 'People', '2'], ['Inform', 'Hotel', 'Stay', '4']])\n", "dst.update([['Inform', 'Hotel', 'Day', 'tuesday'], ['Inform', 'Hotel', 'People', '2'], ['Inform', 'Hotel', 'Stay', '4']])\n",
"dst.state['belief_state']['hotel']" "dst.state['belief_state']['hotel']"
@ -249,9 +419,32 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 39,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"data": {
"text/plain": [
"{'user_action': [],\n",
" 'system_action': [],\n",
" 'belief_state': {'cinema': {'book': {'title': 'batman',\n",
" 'date': '',\n",
" 'time': '15:00',\n",
" 'quantity': '',\n",
" 'seats': '',\n",
" 'area': 'na górze na środku',\n",
" 'interval': ''},\n",
" 'semi': {'goal': ''}}},\n",
" 'request_state': {'cinema': {'date': 0}},\n",
" 'terminated': False,\n",
" 'history': []}"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [ "source": [
"dst.state" "dst.state"
] ]
@ -262,25 +455,46 @@
"source": [ "source": [
"### Taktyka Prowadzenia Dialogu\n", "### Taktyka Prowadzenia Dialogu\n",
"\n", "\n",
"Prosta taktyka prowadzenia dialogu dla systemu rezerwacji pokoi hotelowych mo\u017ce sk\u0142ada\u0107 si\u0119 z nast\u0119puj\u0105cych regu\u0142:\n", "Prosta taktyka prowadzenia dialogu dla systemu rezerwacji pokoi hotelowych może składać się z następujących reguł:\n",
"\n", "\n",
" 1. Je\u017celi u\u017cytkownik przekaza\u0142 w ostatniej turze akt typu `Request`, to udziel odpowiedzi na jego\n", " 1. Jeżeli użytkownik przekazał w ostatniej turze akt typu `Request`, to udziel odpowiedzi na jego\n",
" pytanie.\n", " pytanie.\n",
"\n", "\n",
" 2. Je\u017celi u\u017cytkownik przekaza\u0142 w ostatniej turze akt typu `Inform`, to zaproponuj mu hotel\n", " 2. Jeżeli użytkownik przekazał w ostatniej turze akt typu `Inform`, to zaproponuj mu hotel\n",
" spe\u0142niaj\u0105cy zdefiniowane przez niego kryteria.\n", " spełniający zdefiniowane przez niego kryteria.\n",
"\n", "\n",
" 3. Je\u017celi u\u017cytkownik przekaza\u0142 w ostatniej turze akt typu `Inform` zawieraj\u0105cy szczeg\u00f3\u0142y\n", " 3. Jeżeli użytkownik przekazał w ostatniej turze akt typu `Inform` zawierający szczegóły\n",
" rezerwacji, to zarezerwuj pok\u00f3j.\n", " rezerwacji, to zarezerwuj pokój.\n",
"\n", "\n",
"Metoda `predict` taktyki `SimpleRulePolicy` realizuje regu\u0142y przedstawione powy\u017cej." "Metoda `predict` taktyki `SimpleRulePolicy` realizuje reguły przedstawione powyżej."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"from collections import defaultdict\n", "from collections import defaultdict\n",
"import copy\n", "import copy\n",
@ -308,7 +522,7 @@
" for user_act in user_action:\n", " for user_act in user_action:\n",
" self.update_system_action(user_act, user_action, state, system_action)\n", " self.update_system_action(user_act, user_action, state, system_action)\n",
"\n", "\n",
" # Regu\u0142a 3\n", " # Reguła 3\n",
" if any(True for slots in user_action.values() for (slot, _) in slots if slot in ['Stay', 'Day', 'People']):\n", " if any(True for slots in user_action.values() for (slot, _) in slots if slot in ['Stay', 'Day', 'People']):\n",
" if self.results:\n", " if self.results:\n",
" system_action = {('Booking', 'Book'): [[\"Ref\", self.results[0].get('Ref', 'N/A')]]}\n", " system_action = {('Booking', 'Book'): [[\"Ref\", self.results[0].get('Ref', 'N/A')]]}\n",
@ -322,7 +536,7 @@
" constraints = [(slot, value) for slot, value in state['belief_state'][domain.lower()]['semi'].items() if value != '']\n", " constraints = [(slot, value) for slot, value in state['belief_state'][domain.lower()]['semi'].items() if value != '']\n",
" self.results = deepcopy(self.db.query(domain.lower(), constraints))\n", " self.results = deepcopy(self.db.query(domain.lower(), constraints))\n",
"\n", "\n",
" # Regu\u0142a 1\n", " # Reguła 1\n",
" if intent == 'Request':\n", " if intent == 'Request':\n",
" if len(self.results) == 0:\n", " if len(self.results) == 0:\n",
" system_action[(domain, 'NoOffer')] = []\n", " system_action[(domain, 'NoOffer')] = []\n",
@ -333,7 +547,7 @@
" if kb_slot_name in self.results[0]:\n", " if kb_slot_name in self.results[0]:\n",
" system_action[(domain, 'Inform')].append([slot[0], self.results[0].get(kb_slot_name, 'unknown')])\n", " system_action[(domain, 'Inform')].append([slot[0], self.results[0].get(kb_slot_name, 'unknown')])\n",
"\n", "\n",
" # Regu\u0142a 2\n", " # Reguła 2\n",
" elif intent == 'Inform':\n", " elif intent == 'Inform':\n",
" if len(self.results) == 0:\n", " if len(self.results) == 0:\n",
" system_action[(domain, 'NoOffer')] = []\n", " system_action[(domain, 'NoOffer')] = []\n",
@ -349,14 +563,14 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Podobnie jak w przypadku akt\u00f3w u\u017cytkownika akty systemowe przekazywane do modu\u0142u NLG s\u0105 czteroelementowymi listami z\u0142o\u017conymi z:\n", "Podobnie jak w przypadku aktów użytkownika akty systemowe przekazywane do modułu NLG są czteroelementowymi listami złożonymi z:\n",
"\n", "\n",
" - nazwy aktu systemowe,\n", " - nazwy aktu systemowe,\n",
" - nazwy dziedziny, kt\u00f3rej dotyczy wypowied\u017a,\n", " - nazwy dziedziny, której dotyczy wypowiedź,\n",
" - nazwy slotu,\n", " - nazwy slotu,\n",
" - warto\u015bci slotu.\n", " - wartości slotu.\n",
"\n", "\n",
"Sprawd\u017amy jakie akty systemowe zwraca taktyka `SimpleRulePolicy` w odpowiedzi na zmieniaj\u0105cy si\u0119 stan dialogu." "Sprawdźmy jakie akty systemowe zwraca taktyka `SimpleRulePolicy` w odpowiedzi na zmieniający się stan dialogu."
] ]
}, },
{ {
@ -365,7 +579,28 @@
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"from convlab2.dialog_agent import PipelineAgent\n", "from convlab2.dialog_agent import PipelineAgent\n",
"dst.init_session()\n", "dst.init_session()\n",
@ -379,7 +614,28 @@
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"agent.response([['Inform', 'Hotel', 'Price', 'cheap'], ['Inform', 'Hotel', 'Parking', 'yes']])" "agent.response([['Inform', 'Hotel', 'Price', 'cheap'], ['Inform', 'Hotel', 'Parking', 'yes']])"
] ]
@ -390,7 +646,28 @@
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"agent.response([['Inform', 'Hotel', 'Area', 'north']])" "agent.response([['Inform', 'Hotel', 'Area', 'north']])"
] ]
@ -401,7 +678,28 @@
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"agent.response([['Request', 'Hotel', 'Area', '?']])" "agent.response([['Request', 'Hotel', 'Area', '?']])"
] ]
@ -410,7 +708,28 @@
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"agent.response([['Inform', 'Hotel', 'Day', 'tuesday'], ['Inform', 'Hotel', 'People', '2'], ['Inform', 'Hotel', 'Stay', '4']])" "agent.response([['Inform', 'Hotel', 'Day', 'tuesday'], ['Inform', 'Hotel', 'People', '2'], ['Inform', 'Hotel', 'Stay', '4']])"
] ]
@ -421,15 +740,36 @@
"source": [ "source": [
"### Testy End-to-End\n", "### Testy End-to-End\n",
"\n", "\n",
"Na koniec przeprowad\u017amy dialog \u0142\u0105cz\u0105c w potok nasze modu\u0142y\n", "Na koniec przeprowadźmy dialog łącząc w potok nasze moduły\n",
"z modu\u0142ami NLU i NLG dost\u0119pnymi dla MultiWOZ w \u015brodowisku `ConvLab-2`." "z modułami NLU i NLG dostępnymi dla MultiWOZ w środowisku `ConvLab-2`."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"from convlab2.nlu.svm.multiwoz import SVMNLU\n", "from convlab2.nlu.svm.multiwoz import SVMNLU\n",
"from convlab2.nlg.template.multiwoz import TemplateNLG\n", "from convlab2.nlg.template.multiwoz import TemplateNLG\n",
@ -445,7 +785,28 @@
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"agent.response(\"I need a cheap hotel with free parking .\")" "agent.response(\"I need a cheap hotel with free parking .\")"
] ]
@ -456,7 +817,28 @@
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"agent.response(\"Where it is located ?\")" "agent.response(\"Where it is located ?\")"
] ]
@ -467,7 +849,28 @@
"metadata": { "metadata": {
"lines_to_next_cell": 0 "lines_to_next_cell": 0
}, },
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"agent.response(\"I would prefer the hotel be in the north part of town .\")" "agent.response(\"I would prefer the hotel be in the north part of town .\")"
] ]
@ -476,7 +879,28 @@
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n",
"Run the following command to install 'ipykernel' into the Python environment. \n",
"Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'"
]
}
],
"source": [ "source": [
"agent.response(\"Yeah , could you book me a room for 2 people for 4 nights starting Tuesday ?\")" "agent.response(\"Yeah , could you book me a room for 2 people for 4 nights starting Tuesday ?\")"
] ]
@ -485,44 +909,64 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Zauwa\u017cmy, ze nasza prosta taktyka dialogowa zawiera wiele luk, do kt\u00f3rych nale\u017c\u0105 m.in.:\n", "Zauważmy, ze nasza prosta taktyka dialogowa zawiera wiele luk, do których należą m.in.:\n",
"\n", "\n",
" 1. Niezdolno\u015b\u0107 do udzielenia odpowiedzi na przywitanie, pro\u015bb\u0119 o pomoc lub restart.\n", " 1. Niezdolność do udzielenia odpowiedzi na przywitanie, prośbę o pomoc lub restart.\n",
"\n", "\n",
" 2. Brak regu\u0142 dopytuj\u0105cych u\u017cytkownika o szczeg\u00f3\u0142y niezb\u0119dne do dokonania rezerwacji takie, jak d\u0142ugo\u015b\u0107 pobytu czy liczba os\u00f3b.\n", " 2. Brak reguł dopytujących użytkownika o szczegóły niezbędne do dokonania rezerwacji takie, jak długość pobytu czy liczba osób.\n",
"\n", "\n",
"Bardziej zaawansowane modu\u0142y zarz\u0105dzania dialogiem zbudowane z wykorzystaniem regu\u0142 mo\u017cna znale\u017a\u0107 w\n", "Bardziej zaawansowane moduły zarządzania dialogiem zbudowane z wykorzystaniem reguł można znaleźć w\n",
"\u015brodowisku `ConvLab-2`. Nale\u017c\u0105 do nich m.in. monitor [RuleDST](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/dst/rule/multiwoz/dst.py) oraz taktyka [RuleBasedMultiwozBot](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/policy/rule/multiwoz/rule_based_multiwoz_bot.py).\n", "środowisku `ConvLab-2`. Należą do nich m.in. monitor [RuleDST](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/dst/rule/multiwoz/dst.py) oraz taktyka [RuleBasedMultiwozBot](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/policy/rule/multiwoz/rule_based_multiwoz_bot.py).\n",
"\n", "\n",
"Zadania\n", "Zadania\n",
"-------\n", "-------\n",
" 1. Zaimplementowa\u0107 w projekcie monitor stanu dialogu.\n", " 1. Zaimplementować w projekcie monitor stanu dialogu.\n",
"\n", "\n",
" 2. Zaimplementowa\u0107 w projekcie taktyk\u0119 prowadzenia dialogu.\n", " 2. Zaimplementować w projekcie taktykę prowadzenia dialogu.\n",
"\n", "\n",
"Termin: 24.05.2021, godz. 23:59.\n", "Termin: 24.05.2021, godz. 23:59.\n",
"\n", "\n",
"Literatura\n", "Literatura\n",
"----------\n", "----------\n",
" 1. Pawel Budzianowski, Tsung-Hsien Wen, Bo-Hsiang Tseng, I\u00f1igo Casanueva, Stefan Ultes, Osman Ramadan, Milica Gasic, MultiWOZ - A Large-Scale Multi-Domain Wizard-of-Oz Dataset for Task-Oriented Dialogue Modelling. EMNLP 2018, pp. 5016-5026\n", " 1. Pawel Budzianowski, Tsung-Hsien Wen, Bo-Hsiang Tseng, Iñigo Casanueva, Stefan Ultes, Osman Ramadan, Milica Gasic, MultiWOZ - A Large-Scale Multi-Domain Wizard-of-Oz Dataset for Task-Oriented Dialogue Modelling. EMNLP 2018, pp. 5016-5026\n",
" 2. Cathy Pearl, Basic principles for designing voice user interfaces, https://www.oreilly.com/content/basic-principles-for-designing-voice-user-interfaces/ data dost\u0119pu: 21 marca 2021\n", " 2. Cathy Pearl, Basic principles for designing voice user interfaces, https://www.oreilly.com/content/basic-principles-for-designing-voice-user-interfaces/ data dostępu: 21 marca 2021\n",
" 3. Cathy Pearl, Designing Voice User Interfaces, Excerpts from Chapter 5: Advanced Voice User Interface Design, https://www.uxmatters.com/mt/archives/2018/01/designing-voice-user-interfaces.php data dost\u0119pu: 21 marca 2021" " 3. Cathy Pearl, Designing Voice User Interfaces, Excerpts from Chapter 5: Advanced Voice User Interface Design, https://www.uxmatters.com/mt/archives/2018/01/designing-voice-user-interfaces.php data dostępu: 21 marca 2021"
] ]
} }
], ],
"metadata": { "metadata": {
"author": "Marek Kubis",
"email": "mkubis@amu.edu.pl",
"interpreter": {
"hash": "91e2b0d1baa6ebb76863bdb1d11380bf032a6a1fc1b919194f041a5133852891"
},
"jupytext": { "jupytext": {
"cell_metadata_filter": "-all", "cell_metadata_filter": "-all",
"main_language": "python", "main_language": "python",
"notebook_metadata_filter": "-all" "notebook_metadata_filter": "-all"
}, },
"author": "Marek Kubis", "kernelspec": {
"email": "mkubis@amu.edu.pl", "display_name": "Python 3.7.9 ('venv': venv)",
"language": "python",
"name": "python3"
},
"lang": "pl", "lang": "pl",
"subtitle": "9.Zarz\u0105dzanie dialogiem z wykorzystaniem regu\u0142[laboratoria]", "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.9"
},
"subtitle": "9.Zarządzanie dialogiem z wykorzystaniem reguł[laboratoria]",
"title": "Systemy Dialogowe", "title": "Systemy Dialogowe",
"year": "2021" "year": "2021"
}, },
"nbformat": 4, "nbformat": 4,
"nbformat_minor": 4 "nbformat_minor": 4
} }

View File

@ -9,7 +9,7 @@
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n", "<div class=\"alert alert-block alert-info\">\n",
"<h1> Systemy Dialogowe </h1>\n", "<h1> Systemy Dialogowe </h1>\n",
"<h2> 10. <i>Zarz\u0105dzanie dialogiem z wykorzystaniem technik uczenia maszynowego</i> [laboratoria]</h2> \n", "<h2> 10. <i>Zarządzanie dialogiem z wykorzystaniem technik uczenia maszynowego</i> [laboratoria]</h2> \n",
"<h3> Marek Kubis (2021)</h3>\n", "<h3> Marek Kubis (2021)</h3>\n",
"</div>\n", "</div>\n",
"\n", "\n",
@ -20,23 +20,23 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Zarz\u0105dzanie dialogiem z wykorzystaniem technik uczenia maszynowego\n", "Zarządzanie dialogiem z wykorzystaniem technik uczenia maszynowego\n",
"==================================================================\n", "==================================================================\n",
"\n", "\n",
"Uczenie przez wzmacnianie\n", "Uczenie przez wzmacnianie\n",
"-------------------------\n", "-------------------------\n",
"\n", "\n",
"Zamiast r\u0119cznie implementowa\u0107 zbi\u00f3r regu\u0142 odpowiedzialnych za wyznaczenie akcji, kt\u00f3r\u0105 powinien podj\u0105\u0107 agent b\u0119d\u0105c w danym stanie, odpowiedni\u0105 taktyk\u0119 prowadzenia dialogu mo\u017cna zbudowa\u0107, wykorzystuj\u0105c techniki uczenia maszynowego.\n", "Zamiast ręcznie implementować zbiór reguł odpowiedzialnych za wyznaczenie akcji, którą powinien podjąć agent będąc w danym stanie, odpowiednią taktykę prowadzenia dialogu można zbudować, wykorzystując techniki uczenia maszynowego.\n",
"\n", "\n",
"Obok metod uczenia nadzorowanego, kt\u00f3re wykorzystali\u015bmy do zbudowania modelu NLU, do konstruowania taktyk\n", "Obok metod uczenia nadzorowanego, które wykorzystaliśmy do zbudowania modelu NLU, do konstruowania taktyk\n",
"prowadzenia dialogu wykorzystuje si\u0119 r\u00f3wnie\u017c *uczenie przez wzmacnianie* (ang. *reinforcement learning*).\n", "prowadzenia dialogu wykorzystuje się również *uczenie przez wzmacnianie* (ang. *reinforcement learning*).\n",
"\n", "\n",
"W tym uj\u0119ciu szuka\u0107 b\u0119dziemy funkcji $Q*: S \\times A \\to R$, kt\u00f3ra dla stanu dialogu $s \\in S$ oraz aktu\n", "W tym ujęciu szukać będziemy funkcji $Q*: S \\times A \\to R$, która dla stanu dialogu $s \\in S$ oraz aktu\n",
"dialogowego $a \\in A$ zwraca nagrod\u0119 (ang. *reward*) $r \\in R$, tj. warto\u015b\u0107 rzeczywist\u0105 pozwalaj\u0105c\u0105 oceni\u0107 na ile\n", "dialogowego $a \\in A$ zwraca nagrodę (ang. *reward*) $r \\in R$, tj. wartość rzeczywistą pozwalającą ocenić na ile\n",
"podj\u0119cie akcji $a$ w stanie $s$ jest korzystne.\n", "podjęcie akcji $a$ w stanie $s$ jest korzystne.\n",
"\n", "\n",
"Za\u0142o\u017cymy r\u00f3wnie\u017c, \u017ce poszukiwana funkcja powinna maksymalizowa\u0107 *zwrot* (ang. *return*), tj.\n", "Założymy również, że poszukiwana funkcja powinna maksymalizować *zwrot* (ang. *return*), tj.\n",
"skumulowan\u0105 nagrod\u0119 w toku prowadzonego dialogu, czyli dla tury $t_0$ cel uczenia powinien mie\u0107 posta\u0107:\n", "skumulowaną nagrodę w toku prowadzonego dialogu, czyli dla tury $t_0$ cel uczenia powinien mieć postać:\n",
"\n", "\n",
"$$ \\sum_{t=t_0}^{\\infty}{\\gamma^{t-1}r_t} $$\n", "$$ \\sum_{t=t_0}^{\\infty}{\\gamma^{t-1}r_t} $$\n",
"\n", "\n",
@ -46,36 +46,48 @@
"\n", "\n",
" - $r_t$: nagroda w turze $t$,\n", " - $r_t$: nagroda w turze $t$,\n",
"\n", "\n",
" - $\\gamma \\in [0, 1]$: wsp\u00f3\u0142czynnik dyskontowy (w przypadku agent\u00f3w dialogowych bli\u017cej $1$ ni\u017c $0$, por. np. Rieser i Lemon (2011))." " - $\\gamma \\in [0, 1]$: współczynnik dyskontowy (w przypadku agentów dialogowych bliżej $1$ niż $0$, por. np. Rieser i Lemon (2011))."
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Agent dialogowy w procesie uczenia przez wzmacnianie wchodzi w interakcj\u0119 ze *\u015brodowiskiem*, kt\u00f3re\n", "Agent dialogowy w procesie uczenia przez wzmacnianie wchodzi w interakcję ze *środowiskiem*, które\n",
"dla akcji podejmowanej przez taktyk\u0119 prowadzenia dialogu zwraca kolejny stan oraz nagrod\u0119 powi\u0105zan\u0105 z\n", "dla akcji podejmowanej przez taktykę prowadzenia dialogu zwraca kolejny stan oraz nagrodę powiązaną z\n",
"wykonaniem tej akcji w bie\u017c\u0105cym stanie.\n", "wykonaniem tej akcji w bieżącym stanie.\n",
"\n", "\n",
"Spos\u00f3b w jaki informacje pochodz\u0105ce ze \u015brodowiska s\u0105 wykorzystywane do znalezienia funkcji $Q*$\n", "Sposób w jaki informacje pochodzące ze środowiska są wykorzystywane do znalezienia funkcji $Q*$\n",
"zale\u017cy od wybranej metody uczenia.\n", "zależy od wybranej metody uczenia.\n",
"W przyk\u0142adzie przestawionym poni\u017cej skorzystamy z algorytmu $DQN$ (Mnih i in., 2013) co oznacza, \u017ce:\n", "W przykładzie przestawionym poniżej skorzystamy z algorytmu $DQN$ (Mnih i in., 2013) co oznacza, że:\n",
"\n", "\n",
" 1. b\u0119dziemy aproksymowa\u0107 funkcj\u0119 $Q*$ sieci\u0105 neuronow\u0105,\n", " 1. będziemy aproksymować funkcję $Q*$ siecią neuronową,\n",
"\n", "\n",
" 2. wagi sieci b\u0119dziemy wyznacza\u0107 korzystaj\u0105c z metody spadku gradientu.\n", " 2. wagi sieci będziemy wyznaczać korzystając z metody spadku gradientu.\n",
"\n", "\n",
"Przyk\u0142ad\n", "Przykład\n",
"--------\n", "--------\n",
"\n", "\n",
"Taktyk\u0119 prowadzenia dialogu osadzimy w \u015brodowisku *ConvLab-2*." "Taktykę prowadzenia dialogu osadzimy w środowisku *ConvLab-2*."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 2,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"ename": "ModuleNotFoundError",
"evalue": "No module named 'convlab2'",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32mc:\\Develop\\wmi\\AITECH\\sem1\\Systemy dialogowe\\lab\\10-zarzadzanie-dialogiem-uczenie.ipynb Cell 4'\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Develop/wmi/AITECH/sem1/Systemy%20dialogowe/lab/10-zarzadzanie-dialogiem-uczenie.ipynb#ch0000003?line=0'>1</a>\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mconvlab2\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mdialog_agent\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39magent\u001b[39;00m \u001b[39mimport\u001b[39;00m PipelineAgent\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Develop/wmi/AITECH/sem1/Systemy%20dialogowe/lab/10-zarzadzanie-dialogiem-uczenie.ipynb#ch0000003?line=1'>2</a>\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mconvlab2\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mdialog_agent\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39menv\u001b[39;00m \u001b[39mimport\u001b[39;00m Environment\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Develop/wmi/AITECH/sem1/Systemy%20dialogowe/lab/10-zarzadzanie-dialogiem-uczenie.ipynb#ch0000003?line=2'>3</a>\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mconvlab2\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mdst\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mrule\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mmultiwoz\u001b[39;00m \u001b[39mimport\u001b[39;00m RuleDST\n",
"\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'convlab2'"
]
}
],
"source": [ "source": [
"from convlab2.dialog_agent.agent import PipelineAgent\n", "from convlab2.dialog_agent.agent import PipelineAgent\n",
"from convlab2.dialog_agent.env import Environment\n", "from convlab2.dialog_agent.env import Environment\n",
@ -88,7 +100,7 @@
"\n", "\n",
"logging.disable(logging.DEBUG)\n", "logging.disable(logging.DEBUG)\n",
"\n", "\n",
"# determinizacja oblicze\u0144\n", "# determinizacja obliczeń\n",
"import random\n", "import random\n",
"import torch\n", "import torch\n",
"import numpy as np\n", "import numpy as np\n",
@ -102,8 +114,8 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"\u015arodowisko, z kt\u00f3rym agent b\u0119dzie wchodzi\u0142 w interakcje zawiera\u0107 b\u0119dzie\n", "Środowisko, z którym agent będzie wchodził w interakcje zawierać będzie\n",
"symulator u\u017cytkownika wykorzystuj\u0105cy taktyk\u0119 prowadzenia dialogu zbudowan\u0105 z wykorzystaniem regu\u0142." "symulator użytkownika wykorzystujący taktykę prowadzenia dialogu zbudowaną z wykorzystaniem reguł."
] ]
}, },
{ {
@ -163,12 +175,12 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Jak mo\u017cna zauwa\u017cy\u0107 powy\u017cej akcja, kt\u00f3ra prowadzi do pomy\u015blnego zako\u0144czenia zadania uzyskuje nagrod\u0119 $40$,\n", "Jak można zauważyć powyżej akcja, która prowadzi do pomyślnego zakończenia zadania uzyskuje nagrodę $40$,\n",
"akcja kt\u00f3ra prowadzi do prawid\u0142owego rozpoznania dziedziny uzyskuje nagrod\u0119 $5$,\n", "akcja która prowadzi do prawidłowego rozpoznania dziedziny uzyskuje nagrodę $5$,\n",
"natomiast ka\u017cda inna akcja uzyskuje \"kar\u0119\" $-1$. Taka definicja zwrotu premiuje kr\u00f3tkie dialogi\n", "natomiast każda inna akcja uzyskuje \"karę\" $-1$. Taka definicja zwrotu premiuje krótkie dialogi\n",
"prowadz\u0105ce do pomy\u015blnego wykonania zadania.\n", "prowadzące do pomyślnego wykonania zadania.\n",
"\n", "\n",
"Sie\u0107 neuronowa, kt\u00f3r\u0105 wykorzystamy do aproksymacji funkcji $Q*$ ma nast\u0119puj\u0105c\u0105 architektur\u0119" "Sieć neuronowa, którą wykorzystamy do aproksymacji funkcji $Q*$ ma następującą architekturę"
] ]
}, },
{ {
@ -207,14 +219,14 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Ka\u017cdy krok procedury uczenia sk\u0142ada si\u0119 z dw\u00f3ch etap\u00f3w:\n", "Każdy krok procedury uczenia składa się z dwóch etapów:\n",
"\n", "\n",
" 1. Wygenerowania przy u\u017cyciu taktyki (metoda `policy.predict`) oraz \u015brodowiska (metoda `env.step`) *trajektorii*, tj. sekwencji przej\u015b\u0107 pomi\u0119dzy stanami z\u0142o\u017conych z krotek postaci:\n", " 1. Wygenerowania przy użyciu taktyki (metoda `policy.predict`) oraz środowiska (metoda `env.step`) *trajektorii*, tj. sekwencji przejść pomiędzy stanami złożonych z krotek postaci:\n",
" - stanu \u017ar\u00f3d\u0142owego,\n", " - stanu źródłowego,\n",
" - podj\u0119tej akcji (aktu systemowego),\n", " - podjętej akcji (aktu systemowego),\n",
" - nagrody,\n", " - nagrody,\n",
" - stanu docelowego,\n", " - stanu docelowego,\n",
" - znacznika ko\u0144ca dialogu." " - znacznika końca dialogu."
] ]
}, },
{ {
@ -230,23 +242,23 @@
" max_trajectory_len = 50\n", " max_trajectory_len = 50\n",
"\n", "\n",
" while sampled_num < batch_size:\n", " while sampled_num < batch_size:\n",
" # rozpocz\u0119cie nowego dialogu\n", " # rozpoczęcie nowego dialogu\n",
" s = env.reset()\n", " s = env.reset()\n",
"\n", "\n",
" for t in range(max_trajectory_len):\n", " for t in range(max_trajectory_len):\n",
" try:\n", " try:\n",
" # podj\u0119cie akcji przez agenta dialogowego\n", " # podjęcie akcji przez agenta dialogowego\n",
" a = policy.predict(s, warm_up=warm_up)\n", " a = policy.predict(s, warm_up=warm_up)\n",
"\n", "\n",
" # odpowied\u017a \u015brodowiska na podj\u0119t\u0105 akcje\n", " # odpowiedź środowiska na podjętą akcje\n",
" next_s, r, done = env.step(a)\n", " next_s, r, done = env.step(a)\n",
"\n", "\n",
" # dodanie krotki do zbioru danych\n", " # dodanie krotki do zbioru danych\n",
" buff.push(torch.Tensor(policy.vector.state_vectorize(s)).numpy(), # stan \u017ar\u00f3d\u0142owy\n", " buff.push(torch.Tensor(policy.vector.state_vectorize(s)).numpy(), # stan źródłowy\n",
" policy.vector.action_vectorize(a), # akcja\n", " policy.vector.action_vectorize(a), # akcja\n",
" r, # nagroda\n", " r, # nagroda\n",
" torch.Tensor(policy.vector.state_vectorize(next_s)).numpy(), # stan docelowy\n", " torch.Tensor(policy.vector.state_vectorize(next_s)).numpy(), # stan docelowy\n",
" 0 if done else 1) # znacznik ko\u0144ca\n", " 0 if done else 1) # znacznik końca\n",
"\n", "\n",
" s = next_s\n", " s = next_s\n",
"\n", "\n",
@ -266,7 +278,7 @@
"source": [ "source": [
" 2. Wykorzystania wygenerowanych krotek do aktualizacji taktyki.\n", " 2. Wykorzystania wygenerowanych krotek do aktualizacji taktyki.\n",
"\n", "\n",
"Funkcja `train` realizuj\u0105ca pojedynczy krok uczenia przez wzmacnianie ma nast\u0119puj\u0105c\u0105 posta\u0107" "Funkcja `train` realizująca pojedynczy krok uczenia przez wzmacnianie ma następującą postać"
] ]
}, },
{ {
@ -286,7 +298,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Metoda `update` klasy `DQN` wykorzystywana do aktualizacji wag ma nast\u0119puj\u0105c\u0105 posta\u0107" "Metoda `update` klasy `DQN` wykorzystywana do aktualizacji wag ma następującą postać"
] ]
}, },
{ {
@ -327,7 +339,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Przebieg procesu uczenia zilustrujemy wykonuj\u0105c 100 iteracji. W ka\u017cdej iteracji ograniczymy si\u0119 do 100 przyk\u0142ad\u00f3w." "Przebieg procesu uczenia zilustrujemy wykonując 100 iteracji. W każdej iteracji ograniczymy się do 100 przykładów."
] ]
}, },
{ {
@ -349,7 +361,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Sprawd\u017amy jakie akty systemowe zwraca taktyka `DQN` w odpowiedzi na zmieniaj\u0105cy si\u0119 stan dialogu." "Sprawdźmy jakie akty systemowe zwraca taktyka `DQN` w odpowiedzi na zmieniający się stan dialogu."
] ]
}, },
{ {
@ -411,8 +423,8 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Jako\u015b\u0107 wyuczonego modelu mo\u017cemy oceni\u0107 mierz\u0105c tzw. wska\u017anik sukcesu (ang. *task success rate*),\n", "Jakość wyuczonego modelu możemy ocenić mierząc tzw. wskaźnik sukcesu (ang. *task success rate*),\n",
"tj. stosunek liczby dialog\u00f3w zako\u0144czonych powodzeniem do liczby wszystkich dialog\u00f3w." "tj. stosunek liczby dialogów zakończonych powodzeniem do liczby wszystkich dialogów."
] ]
}, },
{ {
@ -455,10 +467,10 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"**Uwaga**: Chc\u0105c uzyska\u0107 taktyk\u0119 o skuteczno\u015bci por\u00f3wnywalnej z wynikami przedstawionymi na stronie\n", "**Uwaga**: Chcąc uzyskać taktykę o skuteczności porównywalnej z wynikami przedstawionymi na stronie\n",
"[ConvLab-2](https://github.com/thu-coai/ConvLab-2/blob/master/README.md) trzeba odpowiednio\n", "[ConvLab-2](https://github.com/thu-coai/ConvLab-2/blob/master/README.md) trzeba odpowiednio\n",
"zwi\u0119kszy\u0107 zar\u00f3wno liczb\u0119 iteracji jak i liczb\u0119 przyk\u0142ad\u00f3w generowanych w ka\u017cdym przyro\u015bcie.\n", "zwiększyć zarówno liczbę iteracji jak i liczbę przykładów generowanych w każdym przyroście.\n",
"W celu przy\u015bpieszenia procesu uczenia warto zr\u00f3wnolegli\u0107 obliczenia, jak pokazano w\n", "W celu przyśpieszenia procesu uczenia warto zrównoleglić obliczenia, jak pokazano w\n",
"skrypcie [train.py](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/policy/dqn/train.py).\n", "skrypcie [train.py](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/policy/dqn/train.py).\n",
"\n", "\n",
"Literatura\n", "Literatura\n",
@ -472,18 +484,38 @@
} }
], ],
"metadata": { "metadata": {
"author": "Marek Kubis",
"email": "mkubis@amu.edu.pl",
"interpreter": {
"hash": "2f9d6cf1e3d8195079a65c851de355134a77367bcd714b1a5d498c42d3c07114"
},
"jupytext": { "jupytext": {
"cell_metadata_filter": "-all", "cell_metadata_filter": "-all",
"main_language": "python", "main_language": "python",
"notebook_metadata_filter": "-all" "notebook_metadata_filter": "-all"
}, },
"author": "Marek Kubis", "kernelspec": {
"email": "mkubis@amu.edu.pl", "display_name": "Python 3.8.3 64-bit",
"language": "python",
"name": "python3"
},
"lang": "pl", "lang": "pl",
"subtitle": "10.Zarz\u0105dzanie dialogiem z wykorzystaniem technik uczenia maszynowego[laboratoria]", "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.8.3"
},
"subtitle": "10.Zarządzanie dialogiem z wykorzystaniem technik uczenia maszynowego[laboratoria]",
"title": "Systemy Dialogowe", "title": "Systemy Dialogowe",
"year": "2021" "year": "2021"
}, },
"nbformat": 4, "nbformat": 4,
"nbformat_minor": 4 "nbformat_minor": 4
} }

25
lab/utils/state.py Normal file
View File

@ -0,0 +1,25 @@
def default_state():
state = dict(user_action=[],
system_action=[],
belief_state={},
request_state={},
terminated=False,
history=[])
state['belief_state'] = {
"cinema": {
"book": {
"title": "",
"date": "",
"time": "",
"quantity": "",
"seats": "",
"area": "",
"interval": "",
},
"semi": {
"goal": ""
}
},
}
return state

507
lab/utils/value_dict.json Normal file
View File

@ -0,0 +1,507 @@
{
"train": {
"time": [
"05:51",
"07:51",
"09:51",
"11:51",
"13:51",
"15:51",
"17:51",
"19:51",
"21:51",
"23:51",
"06:08",
"08:08",
"10:08",
"12:08",
"14:08",
"16:08",
"18:08",
"20:08",
"22:08",
"24:08",
"07:27",
"09:27",
"11:27",
"13:27",
"15:27",
"17:27",
"19:27",
"21:27",
"23:27",
"01:27",
"07:07",
"09:07",
"11:07",
"13:07",
"15:07",
"17:07",
"19:07",
"21:07",
"23:07",
"01:07",
"05:58",
"06:58",
"07:58",
"08:58",
"09:58",
"10:58",
"11:58",
"12:58",
"13:58",
"14:58",
"15:58",
"16:58",
"17:58",
"18:58",
"19:58",
"20:58",
"21:58",
"22:58",
"23:58",
"06:55",
"07:55",
"08:55",
"09:55",
"10:55",
"11:55",
"12:55",
"13:55",
"14:55",
"15:55",
"16:55",
"17:55",
"18:55",
"19:55",
"20:55",
"21:55",
"22:55",
"23:55",
"24:55",
"06:35",
"07:35",
"08:35",
"09:35",
"10:35",
"11:35",
"12:35",
"13:35",
"14:35",
"15:35",
"16:35",
"17:35",
"18:35",
"19:35",
"20:35",
"21:35",
"22:35",
"23:35",
"24:35",
"05:56",
"06:24",
"06:56",
"07:24",
"07:56",
"08:24",
"08:56",
"09:24",
"09:56",
"10:24",
"10:56",
"11:24",
"11:56",
"12:24",
"12:56",
"13:24",
"13:56",
"14:24",
"14:56",
"15:24",
"15:56",
"16:24",
"16:56",
"17:24",
"17:56",
"18:24",
"18:56",
"19:24",
"19:56",
"20:24",
"20:56",
"21:24",
"21:56",
"22:24",
"22:56",
"23:24",
"23:56",
"24:24",
"06:09",
"06:38",
"07:09",
"07:38",
"08:09",
"08:38",
"09:09",
"09:38",
"10:09",
"10:38",
"11:09",
"11:38",
"12:09",
"12:38",
"13:09",
"13:38",
"14:09",
"14:38",
"15:09",
"15:38",
"16:09",
"16:38",
"17:09",
"17:38",
"18:09",
"18:38",
"19:09",
"19:38",
"20:09",
"20:38",
"21:09",
"21:38",
"22:09",
"22:38",
"23:09",
"23:38",
"24:09",
"24:38",
"06:07",
"08:07",
"10:07",
"12:07",
"14:07",
"16:07",
"18:07",
"20:07",
"22:07",
"24:07",
"05:52",
"07:52",
"09:52",
"11:52",
"13:52",
"15:52",
"17:52",
"19:52",
"21:52",
"23:52",
"07:08",
"09:08",
"11:08",
"13:08",
"15:08",
"17:08",
"19:08",
"21:08",
"23:08",
"06:52",
"08:52",
"10:52",
"12:52",
"14:52",
"16:52",
"18:52",
"20:52",
"22:52",
"07:06",
"08:06",
"09:06",
"10:06",
"11:06",
"12:06",
"13:06",
"14:06",
"15:06",
"16:06",
"17:06",
"18:06",
"19:06",
"20:06",
"21:06",
"22:06",
"23:06",
"24:06",
"01:06",
"06:54",
"07:54",
"08:54",
"09:54",
"10:54",
"11:54",
"12:54",
"13:54",
"14:54",
"15:54",
"16:54",
"17:54",
"18:54",
"19:54",
"20:54",
"21:54",
"22:54",
"23:54",
"24:54",
"07:44",
"08:44",
"09:44",
"10:44",
"11:44",
"12:44",
"13:44",
"14:44",
"15:44",
"16:44",
"17:44",
"18:44",
"19:44",
"20:44",
"21:44",
"22:44",
"23:44",
"24:44",
"01:44",
"08:23",
"09:23",
"10:23",
"11:23",
"12:23",
"13:23",
"14:23",
"15:23",
"16:23",
"17:23",
"18:23",
"19:23",
"20:23",
"21:23",
"22:23",
"23:23",
"24:23",
"01:23",
"02:23",
"06:01",
"07:01",
"08:01",
"09:01",
"10:01",
"11:01",
"12:01",
"13:01",
"14:01",
"15:01",
"16:01",
"17:01",
"18:01",
"19:01",
"20:01",
"21:01",
"22:01",
"23:01",
"24:01",
"06:32",
"07:32",
"08:32",
"09:32",
"10:32",
"11:32",
"12:32",
"13:32",
"14:32",
"15:32",
"16:32",
"17:32",
"18:32",
"19:32",
"20:32",
"21:32",
"22:32",
"23:32",
"24:32",
"06:10",
"08:10",
"10:10",
"12:10",
"14:10",
"16:10",
"18:10",
"20:10",
"22:10",
"24:10",
"06:43",
"08:43",
"10:43",
"12:43",
"14:43",
"16:43",
"18:43",
"20:43",
"22:43",
"24:43",
"pierwszą",
"drugą",
"trzecią",
"piątą",
"szóstą",
"siódmą",
"ósmą",
"dziewiatą",
"dziesiątą",
"jedenastą",
"dwunastą",
"trzynastą",
"czternastą",
"piętnastą",
"szesnastą",
"siedemnastą",
"osiemnastą",
"dziewiętnastą",
"dwudziestą pierwszą",
"dwudziestą drugą",
"dwudziestą trzecią",
"dwudziestą czwartą",
"o północy"
],
"date": [
"w najbliższy poniedziałek",
"w najbliższy wtorek",
"w najbliższą środę",
"w najbliższy czwartek",
"w najbliższy piątek",
"w najbliższą sobotę",
"w najbliższą niedzielę",
"w poniedziałek",
"we wtorek",
"w środę",
"w czwartek",
"w piątek",
"w sobotę",
"w niedzielę",
"na najbliższy poniedziałek",
"na najbliższy wtorek",
"na najbliższą środę",
"na najbliższy czwartek",
"na najbliższy piątek",
"na najbliższą sobotę",
"na najbliższą niedzielę",
"najbliższy poniedziałek",
"najbliższy wtorek",
"najbliższa środa",
"najbliższy czwartek",
"najbliższy piątek",
"najbliższa sobota",
"najbliższa niedziela",
"na jutro",
"jutro",
"w dniu jutrzejszym",
"po jutrze",
"pojutrze",
"za dwa dni",
"za trzy dni",
"za tydzień",
"dzisiaj",
"dziś",
"na dzień 21/09",
"na 21/09",
"dzień 21/09",
"dnia 21/09",
"21/09",
"12/09",
"5/09",
"21/12",
"12/12",
"5/12",
"21/3",
"12/3",
"5/3"
],
"quantities" : [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"20",
"jeden",
"dwa",
"trzy",
"cztery",
"pięć",
"sześć",
"siedem",
"osiem",
"dziewięć",
"dziesięć",
"jedenaście",
"dwanaście",
"trzynaście"
],
"seats" : [
"a1",
"a1 a2",
"a1 a2 a3",
"a1 a2 a3 a4",
"a1 a2 a3 a4 a5",
"h1",
"h1 h2",
"h1 h2 h3",
"h1 h2 h3 h4",
"h1 h2 h3 h4 h5",
"a12",
"a11 a12",
"a11 a12 a13",
"a11 a12 a13 a14",
"a11 a12 a13 a14 a15"
],
"areas" : [
"u góry po prawej",
"u góry po lewej",
"u góry na środku",
"na środku po prawej",
"na środku po lewej",
"na dole po prawej",
"na dole po lewej",
"na dole na środku",
"po lewej",
"po prawej",
"na środku",
"lewo",
"prawo",
"środek",
"blisko od ekranu",
"daleko od ekranu",
"blisko ekranu",
"daleko ekranu"
],
"interval" : [
"rano",
"wieczorem",
"w południe",
"po południu",
"popołudniu",
"w nocy"
]
}
}

View File

@ -1,22 +1,61 @@
# Adrian
class DST: class DST:
def __init__(self, slots):
self.slots = slots
def getDialogueState(self, userActs): def __init__(self):
# iterate over speech acts self.init_session()
if userActs['act'] == 'book': # self.value_dict = json.load(open('utils/value_dict.json'))
if userActs['slots']:
for (k, v) in userActs['slots']:
print(k)
if k in self.slots:
self.slots[k] = v
# returns all slots def update(self, user_act=None):
return self.slots for intent, domain, slot, value in user_act:
domain = domain.lower()
intent = intent.lower()
value = value.lower()
k = slot
#dst = DST() if intent == 'inform':
# userActs = {'inform': {'name': 'edyta', 'age': 18}, 'reqmore': {'date', 'time'}}
#ivona_acts = {'act': 'book', 'slots': [('name', 'ewa'), ('hour', 'dziesiąta'), ('size', 'trzech')]} domain_dic = self.state['belief_state'][domain]
#print(dst.getDialogueState(ivona_acts))
if k in domain_dic['semi']:
self.state['belief_state'][domain]['semi'][k] = value
elif k in domain_dic['book']:
self.state['belief_state'][domain]['book'][k] = value
elif k.lower() in domain_dic['book']:
self.state['belief_state'][domain]['book'][k.lower()] = value
elif intent == 'request':
if domain not in self.state['request_state']:
self.state['request_state'][domain] = {}
if k not in self.state['request_state'][domain]:
self.state['request_state'][domain][k] = 0
return self.state
def init_session(self):
self.state = self.default_state()
def default_state(self):
state = dict(user_action=[],
system_action=[],
belief_state={},
request_state={},
terminated=False,
history=[])
state['belief_state'] = {
"cinema": {
"book": {
"title": "",
"date": "",
"time": "",
"quantity": "",
"seats": "",
"area": "",
"interval": "",
},
"semi": {
"goal": ""
}
},
}
return state

View File

@ -13,7 +13,7 @@ class NLU:
csentence = [{'form': word} for word in sentence] csentence = [{'form': word} for word in sentence]
fsentence = self.conllu2flair([csentence])[0] fsentence = self.conllu2flair([csentence])[0]
self.nluModel.predict(fsentence) self.nluModel.predict(fsentence)
return [(token, ftoken.get_tag('slot').value) for token, ftoken in zip(sentence, fsentence)] return self.toDSTInput([(token, ftoken.get_tag('slot').value) for token, ftoken in zip(sentence, fsentence)])
def conllu2flair(self, sentences, label=None): def conllu2flair(self, sentences, label=None):
fsentences = [] fsentences = []
@ -40,4 +40,34 @@ class NLU:
# new_str = re.sub(' +', ' ', new_str) # new_str = re.sub(' +', ' ', new_str)
for char in punctuation: for char in punctuation:
messageLower = messageLower.replace(char,'') messageLower = messageLower.replace(char,'')
return messageLower.split() return messageLower.split()
def toDSTInput(self, taggedSentence):
result = []
intent = None
slotValue = None
slot = None
for tuple in taggedSentence:
value, tagInt = tuple
if intent is None: intent = tagInt.split("/")[1]
if tagInt.split("/")[0] == "O":
if slotValue is not None:
result.append([intent, 'Cinema', slot, slotValue])
slot = None
slotValue = None
elif tagInt.split("/")[0].split("-")[0] == "B":
slot = tagInt.split("/")[0].split("-")[1]
slotValue = value
elif tagInt.split("/")[0].split("-")[0] == "I":
try:
slotValue += " " + value
except:
slot = tagInt.split("/")[0].split("-")[1]
slotValue = value
if slotValue is not None:
result.append([intent, 'Cinema', slot, slotValue])
return result

View File

@ -2,23 +2,13 @@ from components.NLU import NLU
from components.NLG import NLG from components.NLG import NLG
from components.DST import DST from components.DST import DST
slots = [
("title", None),
("date", None),
("time", None),
("quantity", None),
("seats", None),
("goal", None),
("area", None),
("interval", None),
]
def chatbot(): def chatbot():
isActive = True isActive = True
# NLU # NLU
nlu = NLU() nlu = NLU()
dst = DST()
# hello message # hello message
print("wpisz /exit aby zakończyć") print("wpisz /exit aby zakończyć")
@ -32,5 +22,6 @@ def chatbot():
isActive = False isActive = False
else: else:
nluPred = nlu.predict(sentence=userMessage) nluPred = nlu.predict(sentence=userMessage)
print(nluPred) dst.update(nluPred)
print(dst.state)
chatbot() chatbot()

View File

@ -2941,7 +2941,7 @@
4 moje inform NoLabel 4 moje inform NoLabel
5 miejsca inform NoLabel 5 miejsca inform NoLabel
6 to inform NoLabel 6 to inform NoLabel
7 h1h3h56 inform NoLabel 7 h1h3h56 inform B-seats
# text: wymień seansy jutro # text: wymień seansy jutro
# intent: inform # intent: inform