Spaces:
Sleeping
Sleeping
Initial Commit
Browse files- .gitattributes +3 -35
- .ipynb_checkpoints/ChatBot_Training-checkpoint.ipynb +681 -0
- .ipynb_checkpoints/ChatBot_using_NLP-checkpoint.ipynb +330 -0
- .ipynb_checkpoints/chatbot-training-checkpoint.ipynb +1 -0
- ChatBot_using_NLP.ipynb +322 -0
- Images/Bot Image.jpeg +3 -0
- README.md +2 -14
- Trained Model/bert_chatbot_model.pth +3 -0
- Trained Model/bert_chatbot_tokenizer/special_tokens_map.json +7 -0
- Trained Model/bert_chatbot_tokenizer/tokenizer_config.json +58 -0
- Trained Model/bert_chatbot_tokenizer/vocab.txt +0 -0
- Trained Model/chatbot_model/config.json +576 -0
- Trained Model/chatbot_model/model.safetensors +3 -0
- Trained Model/chatbot_model/special_tokens_map.json +7 -0
- Trained Model/chatbot_model/tokenizer_config.json +58 -0
- Trained Model/chatbot_model/vocab.txt +0 -0
- chat_history.json +1 -0
- chatbot-training.ipynb +659 -0
- chatbot.py +188 -0
- intents.json +0 -0
- requirements.txt +5 -0
.gitattributes
CHANGED
|
@@ -1,35 +1,3 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 1 |
+
Trained[[:space:]]Model/bert_chatbot_model.pth filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
Trained[[:space:]]Model/chatbot_model/model.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
Images/Bot[[:space:]]Image.jpeg filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.ipynb_checkpoints/ChatBot_Training-checkpoint.ipynb
ADDED
|
@@ -0,0 +1,681 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 1,
|
| 6 |
+
"metadata": {
|
| 7 |
+
"execution": {
|
| 8 |
+
"iopub.execute_input": "2025-03-13T10:03:08.356914Z",
|
| 9 |
+
"iopub.status.busy": "2025-03-13T10:03:08.356580Z",
|
| 10 |
+
"iopub.status.idle": "2025-03-13T10:03:08.533121Z",
|
| 11 |
+
"shell.execute_reply": "2025-03-13T10:03:08.532252Z",
|
| 12 |
+
"shell.execute_reply.started": "2025-03-13T10:03:08.356884Z"
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
"outputs": [],
|
| 16 |
+
"source": [
|
| 17 |
+
"from kaggle_secrets import UserSecretsClient\n",
|
| 18 |
+
"user_secrets = UserSecretsClient()\n",
|
| 19 |
+
"secret_value_0 = user_secrets.get_secret(\"HF_Token\")"
|
| 20 |
+
]
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"cell_type": "code",
|
| 24 |
+
"execution_count": 2,
|
| 25 |
+
"metadata": {
|
| 26 |
+
"_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
|
| 27 |
+
"_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
|
| 28 |
+
"execution": {
|
| 29 |
+
"iopub.execute_input": "2025-03-13T10:03:08.534578Z",
|
| 30 |
+
"iopub.status.busy": "2025-03-13T10:03:08.534321Z",
|
| 31 |
+
"iopub.status.idle": "2025-03-13T10:14:01.403519Z",
|
| 32 |
+
"shell.execute_reply": "2025-03-13T10:14:01.402735Z",
|
| 33 |
+
"shell.execute_reply.started": "2025-03-13T10:03:08.534558Z"
|
| 34 |
+
}
|
| 35 |
+
},
|
| 36 |
+
"outputs": [
|
| 37 |
+
{
|
| 38 |
+
"name": "stdout",
|
| 39 |
+
"output_type": "stream",
|
| 40 |
+
"text": [
|
| 41 |
+
"Using device: cuda\n"
|
| 42 |
+
]
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"data": {
|
| 46 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 47 |
+
"model_id": "a9551b71420a46b3ba4ccabf52a6a351",
|
| 48 |
+
"version_major": 2,
|
| 49 |
+
"version_minor": 0
|
| 50 |
+
},
|
| 51 |
+
"text/plain": [
|
| 52 |
+
"tokenizer_config.json: 0%| | 0.00/48.0 [00:00<?, ?B/s]"
|
| 53 |
+
]
|
| 54 |
+
},
|
| 55 |
+
"metadata": {},
|
| 56 |
+
"output_type": "display_data"
|
| 57 |
+
},
|
| 58 |
+
{
|
| 59 |
+
"data": {
|
| 60 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 61 |
+
"model_id": "96393c771e0042a788fc15c2462b3ad7",
|
| 62 |
+
"version_major": 2,
|
| 63 |
+
"version_minor": 0
|
| 64 |
+
},
|
| 65 |
+
"text/plain": [
|
| 66 |
+
"vocab.txt: 0%| | 0.00/232k [00:00<?, ?B/s]"
|
| 67 |
+
]
|
| 68 |
+
},
|
| 69 |
+
"metadata": {},
|
| 70 |
+
"output_type": "display_data"
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"data": {
|
| 74 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 75 |
+
"model_id": "dab3bf2fa5d6417c9a88cdda11a6f120",
|
| 76 |
+
"version_major": 2,
|
| 77 |
+
"version_minor": 0
|
| 78 |
+
},
|
| 79 |
+
"text/plain": [
|
| 80 |
+
"tokenizer.json: 0%| | 0.00/466k [00:00<?, ?B/s]"
|
| 81 |
+
]
|
| 82 |
+
},
|
| 83 |
+
"metadata": {},
|
| 84 |
+
"output_type": "display_data"
|
| 85 |
+
},
|
| 86 |
+
{
|
| 87 |
+
"data": {
|
| 88 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 89 |
+
"model_id": "aaecc1d18c2147f78fa59a05c5c0aa94",
|
| 90 |
+
"version_major": 2,
|
| 91 |
+
"version_minor": 0
|
| 92 |
+
},
|
| 93 |
+
"text/plain": [
|
| 94 |
+
"config.json: 0%| | 0.00/570 [00:00<?, ?B/s]"
|
| 95 |
+
]
|
| 96 |
+
},
|
| 97 |
+
"metadata": {},
|
| 98 |
+
"output_type": "display_data"
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"data": {
|
| 102 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 103 |
+
"model_id": "6e7825fd462a4dffb7aeb8fc78cf76b0",
|
| 104 |
+
"version_major": 2,
|
| 105 |
+
"version_minor": 0
|
| 106 |
+
},
|
| 107 |
+
"text/plain": [
|
| 108 |
+
"model.safetensors: 0%| | 0.00/440M [00:00<?, ?B/s]"
|
| 109 |
+
]
|
| 110 |
+
},
|
| 111 |
+
"metadata": {},
|
| 112 |
+
"output_type": "display_data"
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"name": "stderr",
|
| 116 |
+
"output_type": "stream",
|
| 117 |
+
"text": [
|
| 118 |
+
"Some weights of BertForSequenceClassification were not initialized from the model checkpoint at bert-base-uncased and are newly initialized: ['classifier.bias', 'classifier.weight']\n",
|
| 119 |
+
"You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n"
|
| 120 |
+
]
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"name": "stdout",
|
| 124 |
+
"output_type": "stream",
|
| 125 |
+
"text": [
|
| 126 |
+
"Epoch 1/90 - Average Loss: 5.6619\n",
|
| 127 |
+
"Epoch 2/90 - Average Loss: 5.5883\n",
|
| 128 |
+
"Epoch 3/90 - Average Loss: 5.5470\n",
|
| 129 |
+
"Epoch 4/90 - Average Loss: 5.4290\n",
|
| 130 |
+
"Epoch 5/90 - Average Loss: 5.2496\n",
|
| 131 |
+
"Epoch 6/90 - Average Loss: 5.0645\n",
|
| 132 |
+
"Epoch 7/90 - Average Loss: 4.8741\n",
|
| 133 |
+
"Epoch 8/90 - Average Loss: 4.7122\n",
|
| 134 |
+
"Epoch 9/90 - Average Loss: 4.5314\n",
|
| 135 |
+
"Epoch 10/90 - Average Loss: 4.3852\n",
|
| 136 |
+
"Epoch 11/90 - Average Loss: 4.2249\n",
|
| 137 |
+
"Epoch 12/90 - Average Loss: 4.0838\n",
|
| 138 |
+
"Epoch 13/90 - Average Loss: 3.9303\n",
|
| 139 |
+
"Epoch 14/90 - Average Loss: 3.7829\n",
|
| 140 |
+
"Epoch 15/90 - Average Loss: 3.6581\n",
|
| 141 |
+
"Epoch 16/90 - Average Loss: 3.5259\n",
|
| 142 |
+
"Epoch 17/90 - Average Loss: 3.3789\n",
|
| 143 |
+
"Epoch 18/90 - Average Loss: 3.2480\n",
|
| 144 |
+
"Epoch 19/90 - Average Loss: 3.1250\n",
|
| 145 |
+
"Epoch 20/90 - Average Loss: 2.9910\n",
|
| 146 |
+
"Epoch 21/90 - Average Loss: 2.8648\n",
|
| 147 |
+
"Epoch 22/90 - Average Loss: 2.7338\n",
|
| 148 |
+
"Epoch 23/90 - Average Loss: 2.6204\n",
|
| 149 |
+
"Epoch 24/90 - Average Loss: 2.5009\n",
|
| 150 |
+
"Epoch 25/90 - Average Loss: 2.3891\n",
|
| 151 |
+
"Epoch 26/90 - Average Loss: 2.2775\n",
|
| 152 |
+
"Epoch 27/90 - Average Loss: 2.1512\n",
|
| 153 |
+
"Epoch 28/90 - Average Loss: 2.0413\n",
|
| 154 |
+
"Epoch 29/90 - Average Loss: 1.9370\n",
|
| 155 |
+
"Epoch 30/90 - Average Loss: 1.8393\n",
|
| 156 |
+
"Epoch 31/90 - Average Loss: 1.7441\n",
|
| 157 |
+
"Epoch 32/90 - Average Loss: 1.6401\n",
|
| 158 |
+
"Epoch 33/90 - Average Loss: 1.5407\n",
|
| 159 |
+
"Epoch 34/90 - Average Loss: 1.4577\n",
|
| 160 |
+
"Epoch 35/90 - Average Loss: 1.3693\n",
|
| 161 |
+
"Epoch 36/90 - Average Loss: 1.2951\n",
|
| 162 |
+
"Epoch 37/90 - Average Loss: 1.2153\n",
|
| 163 |
+
"Epoch 38/90 - Average Loss: 1.1336\n",
|
| 164 |
+
"Epoch 39/90 - Average Loss: 1.0695\n",
|
| 165 |
+
"Epoch 40/90 - Average Loss: 1.0081\n",
|
| 166 |
+
"Epoch 41/90 - Average Loss: 0.9498\n",
|
| 167 |
+
"Epoch 42/90 - Average Loss: 0.8879\n",
|
| 168 |
+
"Epoch 43/90 - Average Loss: 0.8284\n",
|
| 169 |
+
"Epoch 44/90 - Average Loss: 0.7808\n",
|
| 170 |
+
"Epoch 45/90 - Average Loss: 0.7360\n",
|
| 171 |
+
"Epoch 46/90 - Average Loss: 0.6892\n",
|
| 172 |
+
"Epoch 47/90 - Average Loss: 0.6492\n",
|
| 173 |
+
"Epoch 48/90 - Average Loss: 0.6026\n",
|
| 174 |
+
"Epoch 49/90 - Average Loss: 0.5694\n",
|
| 175 |
+
"Epoch 50/90 - Average Loss: 0.5378\n",
|
| 176 |
+
"Epoch 51/90 - Average Loss: 0.5075\n",
|
| 177 |
+
"Epoch 52/90 - Average Loss: 0.4727\n",
|
| 178 |
+
"Epoch 53/90 - Average Loss: 0.4481\n",
|
| 179 |
+
"Epoch 54/90 - Average Loss: 0.4278\n",
|
| 180 |
+
"Epoch 55/90 - Average Loss: 0.4013\n",
|
| 181 |
+
"Epoch 56/90 - Average Loss: 0.3765\n",
|
| 182 |
+
"Epoch 57/90 - Average Loss: 0.3588\n",
|
| 183 |
+
"Epoch 58/90 - Average Loss: 0.3379\n",
|
| 184 |
+
"Epoch 59/90 - Average Loss: 0.3237\n",
|
| 185 |
+
"Epoch 60/90 - Average Loss: 0.3053\n",
|
| 186 |
+
"Epoch 61/90 - Average Loss: 0.2887\n",
|
| 187 |
+
"Epoch 62/90 - Average Loss: 0.2751\n",
|
| 188 |
+
"Epoch 63/90 - Average Loss: 0.2624\n",
|
| 189 |
+
"Epoch 64/90 - Average Loss: 0.2491\n",
|
| 190 |
+
"Epoch 65/90 - Average Loss: 0.2376\n",
|
| 191 |
+
"Epoch 66/90 - Average Loss: 0.2225\n",
|
| 192 |
+
"Epoch 67/90 - Average Loss: 0.2182\n",
|
| 193 |
+
"Epoch 68/90 - Average Loss: 0.2059\n",
|
| 194 |
+
"Epoch 69/90 - Average Loss: 0.1965\n",
|
| 195 |
+
"Epoch 70/90 - Average Loss: 0.1880\n",
|
| 196 |
+
"Epoch 71/90 - Average Loss: 0.1791\n",
|
| 197 |
+
"Epoch 72/90 - Average Loss: 0.1692\n",
|
| 198 |
+
"Epoch 73/90 - Average Loss: 0.1649\n",
|
| 199 |
+
"Epoch 74/90 - Average Loss: 0.1574\n",
|
| 200 |
+
"Epoch 75/90 - Average Loss: 0.1575\n",
|
| 201 |
+
"Epoch 76/90 - Average Loss: 0.1470\n",
|
| 202 |
+
"Epoch 77/90 - Average Loss: 0.1394\n",
|
| 203 |
+
"Epoch 78/90 - Average Loss: 0.1344\n",
|
| 204 |
+
"Epoch 79/90 - Average Loss: 0.1296\n",
|
| 205 |
+
"Epoch 80/90 - Average Loss: 0.1253\n",
|
| 206 |
+
"Epoch 81/90 - Average Loss: 0.1209\n",
|
| 207 |
+
"Epoch 82/90 - Average Loss: 0.1161\n",
|
| 208 |
+
"Epoch 83/90 - Average Loss: 0.1113\n",
|
| 209 |
+
"Epoch 84/90 - Average Loss: 0.1074\n",
|
| 210 |
+
"Epoch 85/90 - Average Loss: 0.1038\n",
|
| 211 |
+
"Epoch 86/90 - Average Loss: 0.1011\n",
|
| 212 |
+
"Epoch 87/90 - Average Loss: 0.0969\n",
|
| 213 |
+
"Epoch 88/90 - Average Loss: 0.0925\n",
|
| 214 |
+
"Epoch 89/90 - Average Loss: 0.0914\n",
|
| 215 |
+
"Epoch 90/90 - Average Loss: 0.0881\n",
|
| 216 |
+
"🤖 Chatbot is ready! Type 'exit' to stop.\n"
|
| 217 |
+
]
|
| 218 |
+
},
|
| 219 |
+
{
|
| 220 |
+
"name": "stdin",
|
| 221 |
+
"output_type": "stream",
|
| 222 |
+
"text": [
|
| 223 |
+
"You: exit\n"
|
| 224 |
+
]
|
| 225 |
+
},
|
| 226 |
+
{
|
| 227 |
+
"name": "stdout",
|
| 228 |
+
"output_type": "stream",
|
| 229 |
+
"text": [
|
| 230 |
+
"Bot: Goodbye! 👋\n"
|
| 231 |
+
]
|
| 232 |
+
}
|
| 233 |
+
],
|
| 234 |
+
"source": [
|
| 235 |
+
"import json\n",
|
| 236 |
+
"import torch\n",
|
| 237 |
+
"import os\n",
|
| 238 |
+
"import torch.nn as nn\n",
|
| 239 |
+
"import torch.optim as optim\n",
|
| 240 |
+
"from torch.utils.data import Dataset, DataLoader\n",
|
| 241 |
+
"from transformers import BertTokenizer, BertForSequenceClassification\n",
|
| 242 |
+
"import torch.nn.functional as F\n",
|
| 243 |
+
"from sklearn.utils.class_weight import compute_class_weight\n",
|
| 244 |
+
"import numpy as np\n",
|
| 245 |
+
"import random\n",
|
| 246 |
+
"\n",
|
| 247 |
+
"# Load JSON data\n",
|
| 248 |
+
"with open(\"/kaggle/input/intents/intents.json\", \"r\") as file:\n",
|
| 249 |
+
" intents = json.load(file)\n",
|
| 250 |
+
"\n",
|
| 251 |
+
"# Remove duplicate intent tags\n",
|
| 252 |
+
"unique_intents = []\n",
|
| 253 |
+
"seen_tags = set()\n",
|
| 254 |
+
"for intent in intents:\n",
|
| 255 |
+
" if intent[\"tag\"] not in seen_tags:\n",
|
| 256 |
+
" unique_intents.append(intent)\n",
|
| 257 |
+
" seen_tags.add(intent[\"tag\"])\n",
|
| 258 |
+
"\n",
|
| 259 |
+
"# Ensure unique intent tags\n",
|
| 260 |
+
"intent_tags = [intent[\"tag\"] for intent in unique_intents]\n",
|
| 261 |
+
"num_labels = len(intent_tags)\n",
|
| 262 |
+
"\n",
|
| 263 |
+
"# Create label mapping\n",
|
| 264 |
+
"label_map = {tag: i for i, tag in enumerate(intent_tags)}\n",
|
| 265 |
+
"\n",
|
| 266 |
+
"# Check for GPU availability\n",
|
| 267 |
+
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
|
| 268 |
+
"print(f\"Using device: {device}\")\n",
|
| 269 |
+
"\n",
|
| 270 |
+
"# Load BERT tokenizer & model\n",
|
| 271 |
+
"tokenizer = BertTokenizer.from_pretrained('bert-base-uncased', token=secret_value_0)\n",
|
| 272 |
+
"model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=num_labels, token=secret_value_0)\n",
|
| 273 |
+
"model.to(device)\n",
|
| 274 |
+
"\n",
|
| 275 |
+
"# Define Dataset\n",
|
| 276 |
+
"class IntentDataset(Dataset):\n",
|
| 277 |
+
" def __init__(self, intents, tokenizer):\n",
|
| 278 |
+
" self.texts = []\n",
|
| 279 |
+
" self.labels = []\n",
|
| 280 |
+
" self.label_map = label_map\n",
|
| 281 |
+
"\n",
|
| 282 |
+
" for intent in intents:\n",
|
| 283 |
+
" for pattern in intent[\"patterns\"]:\n",
|
| 284 |
+
" self.texts.append(pattern)\n",
|
| 285 |
+
" self.labels.append(self.label_map[intent[\"tag\"]])\n",
|
| 286 |
+
"\n",
|
| 287 |
+
" def __len__(self):\n",
|
| 288 |
+
" return len(self.labels)\n",
|
| 289 |
+
"\n",
|
| 290 |
+
" def __getitem__(self, idx):\n",
|
| 291 |
+
" text = self.texts[idx]\n",
|
| 292 |
+
" label = torch.tensor(self.labels[idx], dtype=torch.long).to(device)\n",
|
| 293 |
+
"\n",
|
| 294 |
+
" encoding = tokenizer(text, truncation=True, padding=\"max_length\", max_length=32, return_tensors=\"pt\")\n",
|
| 295 |
+
" item = {key: val.squeeze(0).to(device) for key, val in encoding.items()} # Remove batch dim\n",
|
| 296 |
+
"\n",
|
| 297 |
+
" return item, label\n",
|
| 298 |
+
"\n",
|
| 299 |
+
"# Load dataset & dataloader\n",
|
| 300 |
+
"dataset = IntentDataset(unique_intents, tokenizer)\n",
|
| 301 |
+
"dataloader = DataLoader(dataset, batch_size=16, shuffle=True) # Increased batch size\n",
|
| 302 |
+
"\n",
|
| 303 |
+
"# Compute class weights\n",
|
| 304 |
+
"labels = [dataset.label_map[intent[\"tag\"]] for intent in unique_intents for _ in intent[\"patterns\"]]\n",
|
| 305 |
+
"class_weights = compute_class_weight(\"balanced\", classes=np.unique(labels), y=labels)\n",
|
| 306 |
+
"class_weights = torch.tensor(class_weights, dtype=torch.float).to(device)\n",
|
| 307 |
+
"\n",
|
| 308 |
+
"# Define optimizer & loss function\n",
|
| 309 |
+
"optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5) # Lower learning rate\n",
|
| 310 |
+
"loss_fn = torch.nn.CrossEntropyLoss(weight=class_weights) # Use class-weighted loss\n",
|
| 311 |
+
"\n",
|
| 312 |
+
"# Training loop\n",
|
| 313 |
+
"epochs = 90 # Increased from 20 to 50 for better training\n",
|
| 314 |
+
"model.train()\n",
|
| 315 |
+
"\n",
|
| 316 |
+
"for epoch in range(epochs):\n",
|
| 317 |
+
" total_loss = 0\n",
|
| 318 |
+
" for batch in dataloader:\n",
|
| 319 |
+
" inputs, labels = batch\n",
|
| 320 |
+
" optimizer.zero_grad()\n",
|
| 321 |
+
" outputs = model(**inputs)\n",
|
| 322 |
+
" loss = loss_fn(outputs.logits, labels)\n",
|
| 323 |
+
" loss.backward()\n",
|
| 324 |
+
" optimizer.step()\n",
|
| 325 |
+
" total_loss += loss.item()\n",
|
| 326 |
+
" \n",
|
| 327 |
+
" avg_loss = total_loss / len(dataloader)\n",
|
| 328 |
+
" print(f\"Epoch {epoch+1}/{epochs} - Average Loss: {avg_loss:.4f}\")\n",
|
| 329 |
+
"\n",
|
| 330 |
+
"# Function to predict intent\n",
|
| 331 |
+
"def predict_intent(user_input):\n",
|
| 332 |
+
" model.eval()\n",
|
| 333 |
+
" inputs = tokenizer(user_input, return_tensors=\"pt\", truncation=True, padding=True, max_length=32)\n",
|
| 334 |
+
" inputs = {key: val.to(device) for key, val in inputs.items()} # Move input to GPU\n",
|
| 335 |
+
"\n",
|
| 336 |
+
" with torch.no_grad():\n",
|
| 337 |
+
" outputs = model(**inputs)\n",
|
| 338 |
+
"\n",
|
| 339 |
+
" predicted_label = torch.argmax(outputs.logits).item()\n",
|
| 340 |
+
" \n",
|
| 341 |
+
" # Map predicted label to intent\n",
|
| 342 |
+
" intent_tag = list(dataset.label_map.keys())[predicted_label]\n",
|
| 343 |
+
"\n",
|
| 344 |
+
" # Fetch a random response for the predicted intent\n",
|
| 345 |
+
" for intent in unique_intents:\n",
|
| 346 |
+
" if intent[\"tag\"] == intent_tag:\n",
|
| 347 |
+
" return random.choice(intent[\"responses\"])\n",
|
| 348 |
+
"\n",
|
| 349 |
+
"# Run chatbot interaction\n",
|
| 350 |
+
"print(\"🤖 Chatbot is ready! Type 'exit' to stop.\")\n",
|
| 351 |
+
"while True:\n",
|
| 352 |
+
" user_input = input(\"You: \")\n",
|
| 353 |
+
" if user_input.lower() in [\"exit\", \"quit\"]:\n",
|
| 354 |
+
" print(\"Bot: Goodbye! 👋\")\n",
|
| 355 |
+
" break\n",
|
| 356 |
+
" response = predict_intent(user_input)\n",
|
| 357 |
+
" print(\"Bot:\", response)\n"
|
| 358 |
+
]
|
| 359 |
+
},
|
| 360 |
+
{
|
| 361 |
+
"cell_type": "code",
|
| 362 |
+
"execution_count": 3,
|
| 363 |
+
"metadata": {
|
| 364 |
+
"execution": {
|
| 365 |
+
"iopub.execute_input": "2025-03-13T10:14:01.405815Z",
|
| 366 |
+
"iopub.status.busy": "2025-03-13T10:14:01.405308Z",
|
| 367 |
+
"iopub.status.idle": "2025-03-13T10:14:01.867874Z",
|
| 368 |
+
"shell.execute_reply": "2025-03-13T10:14:01.866999Z",
|
| 369 |
+
"shell.execute_reply.started": "2025-03-13T10:14:01.405792Z"
|
| 370 |
+
}
|
| 371 |
+
},
|
| 372 |
+
"outputs": [
|
| 373 |
+
{
|
| 374 |
+
"name": "stdout",
|
| 375 |
+
"output_type": "stream",
|
| 376 |
+
"text": [
|
| 377 |
+
"Test Accuracy: 1.0000\n"
|
| 378 |
+
]
|
| 379 |
+
}
|
| 380 |
+
],
|
| 381 |
+
"source": [
|
| 382 |
+
"import torch\n",
|
| 383 |
+
"from torch.utils.data import random_split\n",
|
| 384 |
+
"from sklearn.metrics import accuracy_score\n",
|
| 385 |
+
"\n",
|
| 386 |
+
"# Split dataset into training (80%) and test (20%) sets\n",
|
| 387 |
+
"train_size = int(0.8 * len(dataset))\n",
|
| 388 |
+
"test_size = len(dataset) - train_size\n",
|
| 389 |
+
"train_dataset, test_dataset = random_split(dataset, [train_size, test_size])\n",
|
| 390 |
+
"\n",
|
| 391 |
+
"# Create test dataloader\n",
|
| 392 |
+
"test_dataloader = DataLoader(test_dataset, batch_size=16, shuffle=False)\n",
|
| 393 |
+
"\n",
|
| 394 |
+
"# Function to evaluate model accuracy\n",
|
| 395 |
+
"def evaluate_model(model, test_dataloader):\n",
|
| 396 |
+
" model.eval()\n",
|
| 397 |
+
" all_preds, all_labels = [], []\n",
|
| 398 |
+
" \n",
|
| 399 |
+
" with torch.no_grad():\n",
|
| 400 |
+
" for batch in test_dataloader:\n",
|
| 401 |
+
" inputs, labels = batch\n",
|
| 402 |
+
" outputs = model(**inputs)\n",
|
| 403 |
+
" preds = torch.argmax(outputs.logits, dim=1)\n",
|
| 404 |
+
"\n",
|
| 405 |
+
" all_preds.extend(preds.cpu().numpy())\n",
|
| 406 |
+
" all_labels.extend(labels.cpu().numpy())\n",
|
| 407 |
+
"\n",
|
| 408 |
+
" accuracy = accuracy_score(all_labels, all_preds)\n",
|
| 409 |
+
" return accuracy\n",
|
| 410 |
+
"\n",
|
| 411 |
+
"# Compute accuracy\n",
|
| 412 |
+
"test_accuracy = evaluate_model(model, test_dataloader)\n",
|
| 413 |
+
"print(f\"Test Accuracy: {test_accuracy:.4f}\")\n"
|
| 414 |
+
]
|
| 415 |
+
},
|
| 416 |
+
{
|
| 417 |
+
"cell_type": "code",
|
| 418 |
+
"execution_count": 4,
|
| 419 |
+
"metadata": {
|
| 420 |
+
"execution": {
|
| 421 |
+
"iopub.execute_input": "2025-03-13T10:14:01.869228Z",
|
| 422 |
+
"iopub.status.busy": "2025-03-13T10:14:01.868962Z",
|
| 423 |
+
"iopub.status.idle": "2025-03-13T10:14:03.262649Z",
|
| 424 |
+
"shell.execute_reply": "2025-03-13T10:14:03.261892Z",
|
| 425 |
+
"shell.execute_reply.started": "2025-03-13T10:14:01.869205Z"
|
| 426 |
+
}
|
| 427 |
+
},
|
| 428 |
+
"outputs": [
|
| 429 |
+
{
|
| 430 |
+
"name": "stdout",
|
| 431 |
+
"output_type": "stream",
|
| 432 |
+
"text": [
|
| 433 |
+
"Training Accuracy: 0.9939\n"
|
| 434 |
+
]
|
| 435 |
+
}
|
| 436 |
+
],
|
| 437 |
+
"source": [
|
| 438 |
+
"def evaluate_train_accuracy(model, train_dataloader):\n",
|
| 439 |
+
" model.eval()\n",
|
| 440 |
+
" all_preds, all_labels = [], []\n",
|
| 441 |
+
" \n",
|
| 442 |
+
" with torch.no_grad():\n",
|
| 443 |
+
" for batch in train_dataloader:\n",
|
| 444 |
+
" inputs, labels = batch\n",
|
| 445 |
+
" outputs = model(**inputs)\n",
|
| 446 |
+
" preds = torch.argmax(outputs.logits, dim=1)\n",
|
| 447 |
+
"\n",
|
| 448 |
+
" all_preds.extend(preds.cpu().numpy())\n",
|
| 449 |
+
" all_labels.extend(labels.cpu().numpy())\n",
|
| 450 |
+
"\n",
|
| 451 |
+
" accuracy = accuracy_score(all_labels, all_preds)\n",
|
| 452 |
+
" return accuracy\n",
|
| 453 |
+
"\n",
|
| 454 |
+
"# Compute Training Accuracy\n",
|
| 455 |
+
"train_dataloader = DataLoader(train_dataset, batch_size=16, shuffle=False)\n",
|
| 456 |
+
"train_accuracy = evaluate_train_accuracy(model, train_dataloader)\n",
|
| 457 |
+
"print(f\"Training Accuracy: {train_accuracy:.4f}\")\n"
|
| 458 |
+
]
|
| 459 |
+
},
|
| 460 |
+
{
|
| 461 |
+
"cell_type": "code",
|
| 462 |
+
"execution_count": 5,
|
| 463 |
+
"metadata": {
|
| 464 |
+
"execution": {
|
| 465 |
+
"iopub.execute_input": "2025-03-13T10:14:03.263629Z",
|
| 466 |
+
"iopub.status.busy": "2025-03-13T10:14:03.263411Z",
|
| 467 |
+
"iopub.status.idle": "2025-03-13T10:22:02.539404Z",
|
| 468 |
+
"shell.execute_reply": "2025-03-13T10:22:02.538512Z",
|
| 469 |
+
"shell.execute_reply.started": "2025-03-13T10:14:03.263611Z"
|
| 470 |
+
}
|
| 471 |
+
},
|
| 472 |
+
"outputs": [
|
| 473 |
+
{
|
| 474 |
+
"data": {
|
| 475 |
+
"image/png": "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ERGRm3W9xztjxoxh7NixN33c9evX53kuvA4dOtC0adMSE6RMnQeoqCrIeYC2H0/C39uNCl7qcyQiUpDS0tI4dOgQ1atXzzE9SlF2eVQz2CYLHj16NHv27LHvK1OmDGXKlAFsw8Kzs7NxciqcexlFJQBd67rezPd3iRoFVtT9Z+FO7vlwFZ+vPmR2KSIiUgQFBATYNx8fHywWi/3n3bt34+XlxS+//EJoaKh9jrsDBw5w//334+/vT5kyZWjZsiVLly7Ncdx/PgKzWCx88skndO/eHQ8PD0JCQliwYEGeav/+++9p0KABrq6uBAcHM2HChByvf/TRR4SEhODm5oa/vz8PPPCA/bXvvvuORo0a4e7uTvny5YmIiCAlJSVP9VyPAlAhalW9HABfrz1CSnqWydWIiJQ+hmGQmpFV6Ft+Pmx58cUXeeutt9i1axeNGzfm4sWL3H333URHR7Np0yY6d+7Mvffey9GjR695nNdee43evXuzdetW7r77bvr168fZs2dvqaYNGzbQu3dvHnzwQbZt28bYsWN59dVXmTFjBgCxsbE8/fTTvP766+zZs4fFixdz++23A7auK3379uXRRx9l165dLF++nB49euTr7yw3pvYBKm0i6vlT3c+TQ6dTmBMbx6C21c0uSUSkVLmUmU390b8W+ufufD0SD5f8+cp9/fXXueuuu+w/lytXjiZNmth/fuONN/jhhx9YsGBBjkFC/zRw4ED69u0LwH//+18++OAD1q1bR+fOnW+6pvfee4+OHTva+9zWrl2bnTt38s477zBw4ECOHj2Kp6cn99xzD15eXlSrVo1mzZoBtgCUlZVFjx49qFatGgCNGjW66Rpulu4AFSIHBwuP3WYLPZ+uOkRWttXkikREpLj557x2Fy9e5F//+hf16tXD19eXMmXKsGvXruveAWrcuLH9z56ennh7e9uXmbhZu3btom3btjn2tW3bln379pGdnc1dd91FtWrVqFGjBo888gjffPMNqampADRp0oSOHTvSqFEjevXqxfTp0zl37twt1XEzdAeokPVsXoUJS/Zy7Nwlftkez71NAs0uSUSk1HB3dmTn65GmfG5++edorn/9619ERUXx7rvvUqtWLdzd3XnggQfIyMi45nGcnZ1z/GyxWLBaC+Yf5l5eXmzcuJHly5ezZMkSRo8ezdixY1m/fj2+vr5ERUWx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9mi+IBGRYu6WAtD999/Pl19+CcD58+cJCwtjwoQJdOvWjSlTpuRrgSJFgcViYfidtfB0cWT78WR+3ZFgdkkiIpIHtxSANm7cyG233QbAd999h7+/P0eOHOHLL7/kgw8+yNcCRYqK8mVcebRddQDei9pDtkaHiYgUW7cUgFJTU/Hy8gJgyZIl9OjRAwcHB1q3bs2RI0fytUCRouSx22rg7ebE3oSLLNx6wuxyRETkFt1SAKpVqxbz588nLi6OX3/9lU6dOgGQmJioTsNSovm4O/PE7TUAmLh0n2aMFhEppm4pAI0ePZp//etfBAcH06pVK8LDwwHb3aBmzZrla4EiRc3AttUp5+nCodMpzNt03OxyRETkFtxSAHrggQc4evQosbGx/Prrr/b9HTt25P3337/p402ePJng4GDc3NwICwtj3bp112w/d+5c6tati5ubG40aNWLRokU5Xh84cCAWiyXHdnmyRlMln4TPOkP8NrMrkTwo4+rEkPY1Afjf0n1kZOkukIhIcXNLAQggICCAZs2aceLECfvK8K1ataJu3bo3dZzZs2czcuRIxowZw8aNG2nSpAmRkZEkJibm2n7NmjX07duXwYMHs2nTJrp160a3bt3Yvn17jnadO3fm5MmT9u3bb7+9tRPNT1GvwtEYmN4R1n8KGkpdbD3cuhoVvVw5fv4Sc2LjzC5HRERu0i0FIKvVyuuvv46Pjw/VqlWjWrVq+Pr68sYbb2C13ty/ht977z0ef/xxBg0aRP369Zk6dSoeHh722aX/6X//+x+dO3fm+eefp169erzxxhs0b96cSZMm5Wjn6upKQECAffv7hI2m6TIeaneG7HT4eSR8NwjSks2uSm6Bu4sjw+6sBcCHv+0j8UKayRWJiMjNuKUA9PLLLzNp0iTeeustNm3axKZNm/jvf//Lhx9+yKuvvnrDx8nIyGDDhg1ERET8VZCDAxEREcTExOT6npiYmBztASIjI69ov3z5cipWrEidOnUYMmQIZ86cuWod6enpJCcn59gKhEc56DsLOr0JDk6w4wf4+HY4salgPk8KVJ+WQVQt50FCcjq9psYQdzY113ZnUzJ48qsNdJywnGPncm8jIiKF65YC0BdffMEnn3zCkCFDaNy4MY0bN+app55i+vTpzJgx44aPc/r0abKzs/H398+x39/fn/j4+FzfEx8ff932nTt3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PPGE4evra8THx5tdWqkwZMgQw8fHx1i+fLlx8uRJ+5aammpv8+STTxpVq1Y1fvvtNyM2NtYIDw83wsPDTay69Pn7KDDD0DUxw7p16wwnJyfjzTffNPbt22d88803hoeHh/H111/b27z11luGr6+v8eOPPxpbt2417r//fqN69erGpUuXTKy85BowYIBRuXJlY+HChcahQ4eMefPmGX5+fsYLL7xgb6Nrkj8UgArIhx9+aFStWtVwcXExWrVqZaxdu9bskkoNINft888/t7e5dOmS8dRTTxlly5Y1PDw8jO7duxsnT540r+hS6J8BSNfEHD/99JPRsGFDw9XV1ahbt64xbdq0HK9brVbj1VdfNfz9/Q1XV1ejY8eOxp49e0yqtuRLTk42RowYYVStWtVwc3MzatSoYbz88stGenq6vY2uSf6wGMbfppcUERERKQXUB0hERERKHQUgERERKXUUgERERKTUUQASERGRUkcBSEREREodBSAREREpdRSAREREpNRRABIRuQqLxcL8+fPNLkNECoACkIgUSQMHDsRisVyxde7c2ezSRKQEcDK7ABGRq+ncuTOff/55jn2urq4mVSMiJYnuAIlIkeXq6kpAQECOrWzZsoDt8dSUKVPo0qUL7u7u1KhRg++++y7H+7dt28add96Ju7s75cuX54knnuDixYs52nz22Wc0aNAAV1dXKlWqxLBhw3K8fvr0abp3746HhwchISEsWLDA/tq5c+fo168fFSpUwN3dnZCQkCsCm4gUTQpAIlJsvfrqq/Ts2ZMtW7bQr18/HnzwQXbt2gVASkoKkZGRlC1blvXr1zN37lyWLl2aI+BMmTKFoUOH8sQTT7Bt2zYWLFhArVq1cnzGa6+9Ru/evdm6dSt33303/fr14+zZs/bP37lzJ7/88gu7du1iypQp+Pn5Fd4vQERundmrsYqI5GbAgAGGo6Oj4enpmWN78803DcMwDMB48sknc7wnLCzMGDJkiGEYhjFt2jSjbNmyxsWLF+2v//zzz4aDg4MRHx9vGIZhBAYGGi+//PJVawCMV155xf7zxYsXDcD45ZdfDMMwjHvvvdcYNGhQ/pywiBQq9QESkSLrjjvuYMqUKTn2lStXzv7n8PDwHK+Fh4ezefNmAHbt2kWTJk3w9PS0v962bVusVit79uzBYrFw4sQJOnbseM0aGjdubP+zp6cn3t7eJCYmAjBkyBB69uzJxo0b6dSpE926daNNmza3dK4iUrgUgESkyPL09LzikVR+cXd3v6F2zs7OOX62WCxYrVYAunTpwpEjR1i0aBFRUVF07NiRoUOH8u677+Z7vSKSv9QHSESKrbVr117xc7169QCoV68eW7ZsISUlxf766tWrcXBwoE6dOnh5eREcHEx0dHSeaqhQoQIDBgzg66+/ZuLEiUybNi1PxxORwqE7QCJSZKWnpxMfH59jn5OTk72j8dy5c2nRogXt2rXjm2++Yd26dXz66acA9OvXjzFjxjBgwADGjh3LqVOnGD58OI888gj+/v4AjB07lieffJKKFSvSpUsXLly4wOrVqxk+fPgN1Td69GhCQ0Np0KAB6enpLFy40B7ARKRoUwASkSJr8eLFVKpUKce+OnXqsHv3bsA2QmvWrFk89dRTVKpUiW+//Zb69esD4OHhwa+//sqIESNo2bIlHh4e9OzZk/fee89+rAEDBpCWlsb777/Pv/71L/z8/HjggQduuD4XFxdGjRrF4cOHcXd357bbbmPWrFn5cOYiUtAshmEYZhchInKzLBYLP/zwA926dTO7FBEphtQHSEREREodBSAREREpddQHSESKJT29F5G80B0gERERKXUUgERERKTUUQASERGRUkcBSEREREodBSAREREpdRSAREREpNRRABIREZFSRwFIRERESh0FIBERESl1/h/U6g1xFq/opQAAAABJRU5ErkJggg==\n",
|
| 476 |
+
"text/plain": [
|
| 477 |
+
"<Figure size 640x480 with 1 Axes>"
|
| 478 |
+
]
|
| 479 |
+
},
|
| 480 |
+
"metadata": {},
|
| 481 |
+
"output_type": "display_data"
|
| 482 |
+
}
|
| 483 |
+
],
|
| 484 |
+
"source": [
|
| 485 |
+
"import matplotlib.pyplot as plt\n",
|
| 486 |
+
"\n",
|
| 487 |
+
"# Assuming you store losses during training like this:\n",
|
| 488 |
+
"train_losses = []\n",
|
| 489 |
+
"test_losses = []\n",
|
| 490 |
+
"\n",
|
| 491 |
+
"for epoch in range(epochs):\n",
|
| 492 |
+
" total_train_loss = 0\n",
|
| 493 |
+
" total_test_loss = 0\n",
|
| 494 |
+
"\n",
|
| 495 |
+
" model.train()\n",
|
| 496 |
+
" for batch in train_dataloader:\n",
|
| 497 |
+
" inputs, labels = batch\n",
|
| 498 |
+
" optimizer.zero_grad()\n",
|
| 499 |
+
" outputs = model(**inputs)\n",
|
| 500 |
+
" loss = loss_fn(outputs.logits, labels)\n",
|
| 501 |
+
" loss.backward()\n",
|
| 502 |
+
" optimizer.step()\n",
|
| 503 |
+
" total_train_loss += loss.item()\n",
|
| 504 |
+
" \n",
|
| 505 |
+
" model.eval()\n",
|
| 506 |
+
" with torch.no_grad():\n",
|
| 507 |
+
" for batch in test_dataloader:\n",
|
| 508 |
+
" inputs, labels = batch\n",
|
| 509 |
+
" outputs = model(**inputs)\n",
|
| 510 |
+
" loss = loss_fn(outputs.logits, labels)\n",
|
| 511 |
+
" total_test_loss += loss.item()\n",
|
| 512 |
+
"\n",
|
| 513 |
+
" train_losses.append(total_train_loss / len(train_dataloader))\n",
|
| 514 |
+
" test_losses.append(total_test_loss / len(test_dataloader))\n",
|
| 515 |
+
"\n",
|
| 516 |
+
"# Plot the loss curves\n",
|
| 517 |
+
"plt.plot(range(1, epochs+1), train_losses, label=\"Train Loss\")\n",
|
| 518 |
+
"plt.plot(range(1, epochs+1), test_losses, label=\"Test Loss\")\n",
|
| 519 |
+
"plt.xlabel(\"Epochs\")\n",
|
| 520 |
+
"plt.ylabel(\"Loss\")\n",
|
| 521 |
+
"plt.legend()\n",
|
| 522 |
+
"plt.title(\"Training vs. Test Loss\")\n",
|
| 523 |
+
"plt.show()\n"
|
| 524 |
+
]
|
| 525 |
+
},
|
| 526 |
+
{
|
| 527 |
+
"cell_type": "code",
|
| 528 |
+
"execution_count": 6,
|
| 529 |
+
"metadata": {
|
| 530 |
+
"execution": {
|
| 531 |
+
"iopub.execute_input": "2025-03-13T10:22:02.540339Z",
|
| 532 |
+
"iopub.status.busy": "2025-03-13T10:22:02.540114Z",
|
| 533 |
+
"iopub.status.idle": "2025-03-13T10:22:02.642619Z",
|
| 534 |
+
"shell.execute_reply": "2025-03-13T10:22:02.642022Z",
|
| 535 |
+
"shell.execute_reply.started": "2025-03-13T10:22:02.540320Z"
|
| 536 |
+
}
|
| 537 |
+
},
|
| 538 |
+
"outputs": [
|
| 539 |
+
{
|
| 540 |
+
"name": "stdout",
|
| 541 |
+
"output_type": "stream",
|
| 542 |
+
"text": [
|
| 543 |
+
"User: Tell me a joke\n",
|
| 544 |
+
"Bot: Why don't skeletons fight each other? They don't have the guts!\n",
|
| 545 |
+
"\n",
|
| 546 |
+
"User: Recommend a good book\n",
|
| 547 |
+
"Bot: Reading books can broaden your knowledge, enhance creativity, and provide a great way to relax.\n",
|
| 548 |
+
"\n",
|
| 549 |
+
"User: What's the weather like today?\n",
|
| 550 |
+
"Bot: You can check the weather on a weather app or website.\n",
|
| 551 |
+
"\n",
|
| 552 |
+
"User: How can I save money?\n",
|
| 553 |
+
"Bot: Investing in stocks, mutual funds, or real estate can help grow your wealth over time.\n",
|
| 554 |
+
"\n",
|
| 555 |
+
"User: How do I meditate?\n",
|
| 556 |
+
"Bot: Meditation can reduce stress, improve focus, and promote emotional well-being.\n",
|
| 557 |
+
"\n"
|
| 558 |
+
]
|
| 559 |
+
}
|
| 560 |
+
],
|
| 561 |
+
"source": [
|
| 562 |
+
"test_inputs = [\n",
|
| 563 |
+
" \"Tell me a joke\", \n",
|
| 564 |
+
" \"Recommend a good book\", \n",
|
| 565 |
+
" \"What's the weather like today?\", \n",
|
| 566 |
+
" \"How can I save money?\", \n",
|
| 567 |
+
" \"How do I meditate?\"\n",
|
| 568 |
+
"]\n",
|
| 569 |
+
"\n",
|
| 570 |
+
"for input_text in test_inputs:\n",
|
| 571 |
+
" response = predict_intent(input_text)\n",
|
| 572 |
+
" print(f\"User: {input_text}\\nBot: {response}\\n\")\n"
|
| 573 |
+
]
|
| 574 |
+
},
|
| 575 |
+
{
|
| 576 |
+
"cell_type": "code",
|
| 577 |
+
"execution_count": 7,
|
| 578 |
+
"metadata": {
|
| 579 |
+
"execution": {
|
| 580 |
+
"iopub.execute_input": "2025-03-13T10:33:46.308702Z",
|
| 581 |
+
"iopub.status.busy": "2025-03-13T10:33:46.308278Z",
|
| 582 |
+
"iopub.status.idle": "2025-03-13T10:33:46.964362Z",
|
| 583 |
+
"shell.execute_reply": "2025-03-13T10:33:46.963545Z",
|
| 584 |
+
"shell.execute_reply.started": "2025-03-13T10:33:46.308678Z"
|
| 585 |
+
}
|
| 586 |
+
},
|
| 587 |
+
"outputs": [
|
| 588 |
+
{
|
| 589 |
+
"name": "stdout",
|
| 590 |
+
"output_type": "stream",
|
| 591 |
+
"text": [
|
| 592 |
+
"Model saved to bert_chatbot_model.pth\n",
|
| 593 |
+
"Tokenizer saved to bert_chatbot_tokenizer\n"
|
| 594 |
+
]
|
| 595 |
+
}
|
| 596 |
+
],
|
| 597 |
+
"source": [
|
| 598 |
+
"# Define save paths\n",
|
| 599 |
+
"model_path = \"bert_chatbot_model.pth\"\n",
|
| 600 |
+
"tokenizer_path = \"bert_chatbot_tokenizer\"\n",
|
| 601 |
+
"\n",
|
| 602 |
+
"# Save model state dictionary\n",
|
| 603 |
+
"torch.save(model.state_dict(), model_path)\n",
|
| 604 |
+
"\n",
|
| 605 |
+
"# Save tokenizer\n",
|
| 606 |
+
"tokenizer.save_pretrained(tokenizer_path)\n",
|
| 607 |
+
"\n",
|
| 608 |
+
"print(f\"Model saved to {model_path}\")\n",
|
| 609 |
+
"print(f\"Tokenizer saved to {tokenizer_path}\")"
|
| 610 |
+
]
|
| 611 |
+
},
|
| 612 |
+
{
|
| 613 |
+
"cell_type": "code",
|
| 614 |
+
"execution_count": 8,
|
| 615 |
+
"metadata": {
|
| 616 |
+
"execution": {
|
| 617 |
+
"iopub.execute_input": "2025-03-13T10:38:56.933623Z",
|
| 618 |
+
"iopub.status.busy": "2025-03-13T10:38:56.933265Z",
|
| 619 |
+
"iopub.status.idle": "2025-03-13T10:38:57.968705Z",
|
| 620 |
+
"shell.execute_reply": "2025-03-13T10:38:57.967785Z",
|
| 621 |
+
"shell.execute_reply.started": "2025-03-13T10:38:56.933591Z"
|
| 622 |
+
}
|
| 623 |
+
},
|
| 624 |
+
"outputs": [
|
| 625 |
+
{
|
| 626 |
+
"data": {
|
| 627 |
+
"text/plain": [
|
| 628 |
+
"('chatbot_model/tokenizer_config.json',\n",
|
| 629 |
+
" 'chatbot_model/special_tokens_map.json',\n",
|
| 630 |
+
" 'chatbot_model/vocab.txt',\n",
|
| 631 |
+
" 'chatbot_model/added_tokens.json')"
|
| 632 |
+
]
|
| 633 |
+
},
|
| 634 |
+
"execution_count": 8,
|
| 635 |
+
"metadata": {},
|
| 636 |
+
"output_type": "execute_result"
|
| 637 |
+
}
|
| 638 |
+
],
|
| 639 |
+
"source": [
|
| 640 |
+
"model.save_pretrained(\"chatbot_model\")\n",
|
| 641 |
+
"tokenizer.save_pretrained(\"chatbot_model\")"
|
| 642 |
+
]
|
| 643 |
+
}
|
| 644 |
+
],
|
| 645 |
+
"metadata": {
|
| 646 |
+
"kaggle": {
|
| 647 |
+
"accelerator": "nvidiaTeslaT4",
|
| 648 |
+
"dataSources": [
|
| 649 |
+
{
|
| 650 |
+
"datasetId": 6859551,
|
| 651 |
+
"sourceId": 11016856,
|
| 652 |
+
"sourceType": "datasetVersion"
|
| 653 |
+
}
|
| 654 |
+
],
|
| 655 |
+
"dockerImageVersionId": 30919,
|
| 656 |
+
"isGpuEnabled": true,
|
| 657 |
+
"isInternetEnabled": true,
|
| 658 |
+
"language": "python",
|
| 659 |
+
"sourceType": "notebook"
|
| 660 |
+
},
|
| 661 |
+
"kernelspec": {
|
| 662 |
+
"display_name": "Python 3 (ipykernel)",
|
| 663 |
+
"language": "python",
|
| 664 |
+
"name": "python3"
|
| 665 |
+
},
|
| 666 |
+
"language_info": {
|
| 667 |
+
"codemirror_mode": {
|
| 668 |
+
"name": "ipython",
|
| 669 |
+
"version": 3
|
| 670 |
+
},
|
| 671 |
+
"file_extension": ".py",
|
| 672 |
+
"mimetype": "text/x-python",
|
| 673 |
+
"name": "python",
|
| 674 |
+
"nbconvert_exporter": "python",
|
| 675 |
+
"pygments_lexer": "ipython3",
|
| 676 |
+
"version": "3.8.20"
|
| 677 |
+
}
|
| 678 |
+
},
|
| 679 |
+
"nbformat": 4,
|
| 680 |
+
"nbformat_minor": 4
|
| 681 |
+
}
|
.ipynb_checkpoints/ChatBot_using_NLP-checkpoint.ipynb
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"id": "f0ce57f4-5984-43e6-b3bb-60f2d9251d75",
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"source": [
|
| 8 |
+
"# Implementation of Chatbot using Natural Language Processing(NLP)"
|
| 9 |
+
]
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"cell_type": "markdown",
|
| 13 |
+
"id": "3c062c6e-0773-4af8-bcb9-aa33f7afeb25",
|
| 14 |
+
"metadata": {},
|
| 15 |
+
"source": [
|
| 16 |
+
"### Importing necessary libraries"
|
| 17 |
+
]
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"cell_type": "code",
|
| 21 |
+
"execution_count": 1,
|
| 22 |
+
"id": "23417a10-2691-4887-b02e-2448f6200cd1",
|
| 23 |
+
"metadata": {},
|
| 24 |
+
"outputs": [],
|
| 25 |
+
"source": [
|
| 26 |
+
"import nltk\n",
|
| 27 |
+
"import random\n",
|
| 28 |
+
"import os\n",
|
| 29 |
+
"import ssl\n",
|
| 30 |
+
"import streamlit as st\n",
|
| 31 |
+
"from sklearn.svm import SVC\n",
|
| 32 |
+
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
|
| 33 |
+
"from sklearn.linear_model import LogisticRegression"
|
| 34 |
+
]
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"cell_type": "markdown",
|
| 38 |
+
"id": "1dc3d789-6567-4266-bd33-005aed1d4e93",
|
| 39 |
+
"metadata": {},
|
| 40 |
+
"source": [
|
| 41 |
+
"### Bypass SSL verification for NLTK downloads"
|
| 42 |
+
]
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"cell_type": "code",
|
| 46 |
+
"execution_count": 2,
|
| 47 |
+
"id": "298e3201-b127-4c68-b041-2a22ace29340",
|
| 48 |
+
"metadata": {},
|
| 49 |
+
"outputs": [
|
| 50 |
+
{
|
| 51 |
+
"name": "stderr",
|
| 52 |
+
"output_type": "stream",
|
| 53 |
+
"text": [
|
| 54 |
+
"[nltk_data] Downloading package punkt to\n",
|
| 55 |
+
"[nltk_data] C:\\Users\\LENOVO\\AppData\\Roaming\\nltk_data...\n",
|
| 56 |
+
"[nltk_data] Package punkt is already up-to-date!\n"
|
| 57 |
+
]
|
| 58 |
+
},
|
| 59 |
+
{
|
| 60 |
+
"data": {
|
| 61 |
+
"text/plain": [
|
| 62 |
+
"True"
|
| 63 |
+
]
|
| 64 |
+
},
|
| 65 |
+
"execution_count": 2,
|
| 66 |
+
"metadata": {},
|
| 67 |
+
"output_type": "execute_result"
|
| 68 |
+
}
|
| 69 |
+
],
|
| 70 |
+
"source": [
|
| 71 |
+
"ssl._create_default_https_context = ssl._create_unverified_context\n",
|
| 72 |
+
"nltk.data.path.append(os.path.abspath('nltk_data'))\n",
|
| 73 |
+
"nltk.download('punkt')"
|
| 74 |
+
]
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"cell_type": "markdown",
|
| 78 |
+
"id": "62d1be3d-37b1-4ab3-a527-9185e183ac98",
|
| 79 |
+
"metadata": {},
|
| 80 |
+
"source": [
|
| 81 |
+
"### Intent dataset"
|
| 82 |
+
]
|
| 83 |
+
},
|
| 84 |
+
{
|
| 85 |
+
"cell_type": "code",
|
| 86 |
+
"execution_count": 3,
|
| 87 |
+
"id": "a4c238c5-fe25-4802-9328-70ec7b064044",
|
| 88 |
+
"metadata": {},
|
| 89 |
+
"outputs": [],
|
| 90 |
+
"source": [
|
| 91 |
+
"intents = [\n",
|
| 92 |
+
" {\n",
|
| 93 |
+
" \"tag\": \"greeting\", \"patterns\": [\"Hi\", \"Hello\", \"Hey\", \"What's up\", \"How are you\"],\n",
|
| 94 |
+
" \"responses\": [\"Hi there!\", \"Hello!\", \"Hey!\", \"Nothing much.\", \"I'm fine, thank you.\"]\n",
|
| 95 |
+
" },\n",
|
| 96 |
+
" {\n",
|
| 97 |
+
" \"tag\": \"goodbye\", \"patterns\": [\"Bye\", \"See you later\", \"Goodbye\", \"Take care\"],\n",
|
| 98 |
+
" \"responses\": [\"Goodbye!\", \"See you later!\", \"Take care!\"]\n",
|
| 99 |
+
" },\n",
|
| 100 |
+
" {\n",
|
| 101 |
+
" \"tag\": \"thanks\", \"patterns\": [\"Thank you\", \"Thanks\", \"Thanks a lot\", \"I appreciate it\"],\n",
|
| 102 |
+
" \"responses\": [\"You're welcome!\", \"No problem!\", \"Glad I could help!\"]\n",
|
| 103 |
+
" },\n",
|
| 104 |
+
" {\n",
|
| 105 |
+
" \"tag\": \"about\", \"patterns\": [\"What can you do\", \"Who are you\", \"What are you\", \"What is your purpose\"],\n",
|
| 106 |
+
" \"responses\": [\"I am a chatbot.\", \"My purpose is to assist you.\", \"I can answer questions and provide assistance.\"]\n",
|
| 107 |
+
" },\n",
|
| 108 |
+
" {\n",
|
| 109 |
+
" \"tag\": \"help\", \"patterns\": [\"Help\", \"I need help\", \"Can you help me\", \"What should I do\"],\n",
|
| 110 |
+
" \"responses\": [\"Sure, what do you need help with?\", \"I'm here to help. What's the problem?\", \"How can I assist you?\"]\n",
|
| 111 |
+
" },\n",
|
| 112 |
+
" {\n",
|
| 113 |
+
" \"tag\": \"age\", \"patterns\": [\"How old are you\", \"What's your age\"],\n",
|
| 114 |
+
" \"responses\": [\"I don't have an age. I'm a chatbot.\", \"I was just born in the digital world.\", \"Age is just a number for me.\"]\n",
|
| 115 |
+
" },\n",
|
| 116 |
+
" {\n",
|
| 117 |
+
" \"tag\": \"weather\", \"patterns\": [\"What's the weather like\", \"How's the weather today\"],\n",
|
| 118 |
+
" \"responses\": [\"I'm sorry, I cannot provide real-time weather information.\", \"You can check the weather on a weather app or website.\"]\n",
|
| 119 |
+
" },\n",
|
| 120 |
+
" {\n",
|
| 121 |
+
" \"tag\": \"budget\", \"patterns\": [\"How can I make a budget\", \"What's a good budgeting strategy\", \"How do I create a budget\"],\n",
|
| 122 |
+
" \"responses\": [\"Start by tracking your income and expenses. Allocate money for essentials, savings, and discretionary spending.\",\n",
|
| 123 |
+
" \"A good strategy is the 50/30/20 rule: 50% for needs, 30% for wants, and 20% for savings and debt.\",\n",
|
| 124 |
+
" \"Set financial goals, monitor expenses, and adjust your budget as needed.\"]\n",
|
| 125 |
+
" },\n",
|
| 126 |
+
" {\n",
|
| 127 |
+
" \"tag\": \"credit_score\", \"patterns\": [\"What is a credit score\", \"How do I check my credit score\", \"How can I improve my credit score\"],\n",
|
| 128 |
+
" \"responses\": [\"A credit score reflects your creditworthiness and is used by lenders to assess loans.\",\n",
|
| 129 |
+
" \"Check your credit score on platforms like Credit Karma or Credit Sesame.\",\n",
|
| 130 |
+
" \"Improve your credit score by paying bills on time, reducing debt, and maintaining good credit utilization.\"]\n",
|
| 131 |
+
" },\n",
|
| 132 |
+
" {\n",
|
| 133 |
+
" \"tag\": \"food\", \"patterns\": [\"What should I eat\", \"Suggest me some food\", \"I am hungry\"],\n",
|
| 134 |
+
" \"responses\": [\"You could try a healthy salad, a sandwich, or some pasta!\", \"How about some homemade pizza?\", \"A nice bowl of soup and bread would be great!\"]\n",
|
| 135 |
+
" },\n",
|
| 136 |
+
" {\n",
|
| 137 |
+
" \"tag\": \"exercise\", \"patterns\": [\"What exercises should I do\", \"How to stay fit\", \"Suggest a workout\"],\n",
|
| 138 |
+
" \"responses\": [\"Try a mix of cardio and strength training!\", \"A daily walk and some stretching would help.\", \"Yoga is great for both mind and body!\"]\n",
|
| 139 |
+
" },\n",
|
| 140 |
+
" {\n",
|
| 141 |
+
" \"tag\": \"movies\", \"patterns\": [\"Suggest me a movie\", \"What are some good movies\", \"I want to watch a film\"],\n",
|
| 142 |
+
" \"responses\": [\"How about an action thriller?\", \"A comedy might lift your mood!\", \"Sci-fi movies are always exciting!\"]\n",
|
| 143 |
+
" },\n",
|
| 144 |
+
" {\n",
|
| 145 |
+
" \"tag\": \"music\", \"patterns\": [\"Suggest me some music\", \"What should I listen to\", \"Recommend a song\"],\n",
|
| 146 |
+
" \"responses\": [\"Try some relaxing jazz or lo-fi music!\", \"Pop songs are always fun!\", \"How about some classic rock?\"]\n",
|
| 147 |
+
" }\n",
|
| 148 |
+
"]"
|
| 149 |
+
]
|
| 150 |
+
},
|
| 151 |
+
{
|
| 152 |
+
"cell_type": "markdown",
|
| 153 |
+
"id": "3ece2689-d741-48ea-9659-be9cf20e3033",
|
| 154 |
+
"metadata": {},
|
| 155 |
+
"source": [
|
| 156 |
+
"### Create the vectorizer and classifier"
|
| 157 |
+
]
|
| 158 |
+
},
|
| 159 |
+
{
|
| 160 |
+
"cell_type": "code",
|
| 161 |
+
"execution_count": 4,
|
| 162 |
+
"id": "18d6ccb9-639c-4053-981a-69e2fa7cccca",
|
| 163 |
+
"metadata": {},
|
| 164 |
+
"outputs": [],
|
| 165 |
+
"source": [
|
| 166 |
+
"vectorizer = TfidfVectorizer()\n",
|
| 167 |
+
"clf = SVC(kernel='linear', random_state=0)\n",
|
| 168 |
+
"#clf = LogisticRegression(random_state=0, max_iter=10000)"
|
| 169 |
+
]
|
| 170 |
+
},
|
| 171 |
+
{
|
| 172 |
+
"cell_type": "markdown",
|
| 173 |
+
"id": "09e70e89-e826-432a-9c22-b4097b5ac07f",
|
| 174 |
+
"metadata": {},
|
| 175 |
+
"source": [
|
| 176 |
+
"### Preprocess the data"
|
| 177 |
+
]
|
| 178 |
+
},
|
| 179 |
+
{
|
| 180 |
+
"cell_type": "code",
|
| 181 |
+
"execution_count": 5,
|
| 182 |
+
"id": "aca02fbf-201b-47a6-b46c-ca9e0d4e9334",
|
| 183 |
+
"metadata": {},
|
| 184 |
+
"outputs": [],
|
| 185 |
+
"source": [
|
| 186 |
+
"tags = []\n",
|
| 187 |
+
"patterns = []\n",
|
| 188 |
+
"for intent in intents:\n",
|
| 189 |
+
" for pattern in intent['patterns']:\n",
|
| 190 |
+
" tags.append(intent['tag'])\n",
|
| 191 |
+
" patterns.append(pattern)"
|
| 192 |
+
]
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"cell_type": "markdown",
|
| 196 |
+
"id": "e33f4599-2a6b-4b9b-805a-7875b1840eb4",
|
| 197 |
+
"metadata": {},
|
| 198 |
+
"source": [
|
| 199 |
+
"### Training the model"
|
| 200 |
+
]
|
| 201 |
+
},
|
| 202 |
+
{
|
| 203 |
+
"cell_type": "code",
|
| 204 |
+
"execution_count": 6,
|
| 205 |
+
"id": "6d11f50c-7062-46e3-89d2-f6e252e5cf12",
|
| 206 |
+
"metadata": {},
|
| 207 |
+
"outputs": [
|
| 208 |
+
{
|
| 209 |
+
"data": {
|
| 210 |
+
"text/html": [
|
| 211 |
+
"<style>#sk-container-id-1 {color: black;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>SVC(kernel='linear', random_state=0)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">SVC</label><div class=\"sk-toggleable__content\"><pre>SVC(kernel='linear', random_state=0)</pre></div></div></div></div></div>"
|
| 212 |
+
],
|
| 213 |
+
"text/plain": [
|
| 214 |
+
"SVC(kernel='linear', random_state=0)"
|
| 215 |
+
]
|
| 216 |
+
},
|
| 217 |
+
"execution_count": 6,
|
| 218 |
+
"metadata": {},
|
| 219 |
+
"output_type": "execute_result"
|
| 220 |
+
}
|
| 221 |
+
],
|
| 222 |
+
"source": [
|
| 223 |
+
"x = vectorizer.fit_transform(patterns)\n",
|
| 224 |
+
"y = tags\n",
|
| 225 |
+
"clf.fit(x, y)"
|
| 226 |
+
]
|
| 227 |
+
},
|
| 228 |
+
{
|
| 229 |
+
"cell_type": "markdown",
|
| 230 |
+
"id": "a75b5c8f-cc42-4afc-b261-bfdbe6c79913",
|
| 231 |
+
"metadata": {},
|
| 232 |
+
"source": [
|
| 233 |
+
"### Python function to chat with the chatbot"
|
| 234 |
+
]
|
| 235 |
+
},
|
| 236 |
+
{
|
| 237 |
+
"cell_type": "code",
|
| 238 |
+
"execution_count": 7,
|
| 239 |
+
"id": "12ac8a47-eac5-440f-ab0e-93686944b34b",
|
| 240 |
+
"metadata": {},
|
| 241 |
+
"outputs": [],
|
| 242 |
+
"source": [
|
| 243 |
+
"def chatbot(input_text):\n",
|
| 244 |
+
" input_text = vectorizer.transform([input_text])\n",
|
| 245 |
+
" tag = clf.predict(input_text)[0]\n",
|
| 246 |
+
" for intent in intents:\n",
|
| 247 |
+
" if intent['tag'] == tag:\n",
|
| 248 |
+
" response = random.choice(intent['responses'])\n",
|
| 249 |
+
" return response"
|
| 250 |
+
]
|
| 251 |
+
},
|
| 252 |
+
{
|
| 253 |
+
"cell_type": "markdown",
|
| 254 |
+
"id": "cf1ff963-ebbe-4fac-af82-26d3e3336c33",
|
| 255 |
+
"metadata": {},
|
| 256 |
+
"source": [
|
| 257 |
+
"### Checking our chatbot"
|
| 258 |
+
]
|
| 259 |
+
},
|
| 260 |
+
{
|
| 261 |
+
"cell_type": "code",
|
| 262 |
+
"execution_count": 8,
|
| 263 |
+
"id": "8f469e8a-c8a0-4683-9be0-0aefa67c8cea",
|
| 264 |
+
"metadata": {},
|
| 265 |
+
"outputs": [
|
| 266 |
+
{
|
| 267 |
+
"name": "stdout",
|
| 268 |
+
"output_type": "stream",
|
| 269 |
+
"text": [
|
| 270 |
+
"Hey!\n"
|
| 271 |
+
]
|
| 272 |
+
}
|
| 273 |
+
],
|
| 274 |
+
"source": [
|
| 275 |
+
"user_input = \"Hello\"\n",
|
| 276 |
+
"response = chatbot(user_input)\n",
|
| 277 |
+
"print(response)"
|
| 278 |
+
]
|
| 279 |
+
},
|
| 280 |
+
{
|
| 281 |
+
"cell_type": "code",
|
| 282 |
+
"execution_count": 9,
|
| 283 |
+
"id": "f49306db-d7da-4e79-860e-cd6e2985ca58",
|
| 284 |
+
"metadata": {},
|
| 285 |
+
"outputs": [
|
| 286 |
+
{
|
| 287 |
+
"name": "stdout",
|
| 288 |
+
"output_type": "stream",
|
| 289 |
+
"text": [
|
| 290 |
+
"Try a mix of cardio and strength training!\n"
|
| 291 |
+
]
|
| 292 |
+
}
|
| 293 |
+
],
|
| 294 |
+
"source": [
|
| 295 |
+
"user_input = \"What exercises should I do\"\n",
|
| 296 |
+
"response = chatbot(user_input)\n",
|
| 297 |
+
"print(response)"
|
| 298 |
+
]
|
| 299 |
+
},
|
| 300 |
+
{
|
| 301 |
+
"cell_type": "code",
|
| 302 |
+
"execution_count": null,
|
| 303 |
+
"id": "edcde051-3bbe-444f-9318-77fb7dc161bf",
|
| 304 |
+
"metadata": {},
|
| 305 |
+
"outputs": [],
|
| 306 |
+
"source": []
|
| 307 |
+
}
|
| 308 |
+
],
|
| 309 |
+
"metadata": {
|
| 310 |
+
"kernelspec": {
|
| 311 |
+
"display_name": "GPU(sam)",
|
| 312 |
+
"language": "python",
|
| 313 |
+
"name": "sam"
|
| 314 |
+
},
|
| 315 |
+
"language_info": {
|
| 316 |
+
"codemirror_mode": {
|
| 317 |
+
"name": "ipython",
|
| 318 |
+
"version": 3
|
| 319 |
+
},
|
| 320 |
+
"file_extension": ".py",
|
| 321 |
+
"mimetype": "text/x-python",
|
| 322 |
+
"name": "python",
|
| 323 |
+
"nbconvert_exporter": "python",
|
| 324 |
+
"pygments_lexer": "ipython3",
|
| 325 |
+
"version": "3.8.20"
|
| 326 |
+
}
|
| 327 |
+
},
|
| 328 |
+
"nbformat": 4,
|
| 329 |
+
"nbformat_minor": 5
|
| 330 |
+
}
|
.ipynb_checkpoints/chatbot-training-checkpoint.ipynb
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":11018742,"sourceType":"datasetVersion","datasetId":6860959}],"dockerImageVersionId":30919,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Importing HuggingFace Token\nfrom kaggle_secrets import UserSecretsClient\nuser_secrets = UserSecretsClient()\nsecret_value_0 = user_secrets.get_secret(\"HF_Token\")","metadata":{"execution":{"iopub.status.busy":"2025-03-14T06:02:34.158188Z","iopub.execute_input":"2025-03-14T06:02:34.158602Z","iopub.status.idle":"2025-03-14T06:02:34.361502Z","shell.execute_reply.started":"2025-03-14T06:02:34.158571Z","shell.execute_reply":"2025-03-14T06:02:34.360367Z"},"trusted":true},"outputs":[],"execution_count":1},{"cell_type":"code","source":"# Importing Libraries\nimport json\nimport torch\nimport os\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom transformers import BertTokenizer, BertForSequenceClassification\nimport torch.nn.functional as F\nfrom sklearn.utils.class_weight import compute_class_weight\nimport numpy as np\nimport random\n\n# Load JSON data\nwith open(\"/kaggle/input/intents1/intents.json\", \"r\") as file:\n intents = json.load(file)\n\n# Remove duplicate intent tags\nunique_intents = []\nseen_tags = set()\nfor intent in intents:\n if intent[\"tag\"] not in seen_tags:\n unique_intents.append(intent)\n seen_tags.add(intent[\"tag\"])\n\n# Ensure unique intent tags\nintent_tags = [intent[\"tag\"] for intent in unique_intents]\nnum_labels = len(intent_tags)\n\n# Create label mapping\nlabel_map = {tag: i for i, tag in enumerate(intent_tags)}\n\n# Check for GPU availability\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Using device: {device}\")\n\n# Load BERT tokenizer & model\ntokenizer = BertTokenizer.from_pretrained('bert-base-uncased', token=secret_value_0)\nmodel = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=num_labels, token=secret_value_0)\nmodel.to(device)\n\n# Define Dataset\nclass IntentDataset(Dataset):\n def __init__(self, intents, tokenizer):\n self.texts = []\n self.labels = []\n self.label_map = label_map\n\n for intent in intents:\n for pattern in intent[\"patterns\"]:\n self.texts.append(pattern)\n self.labels.append(self.label_map[intent[\"tag\"]])\n\n def __len__(self):\n return len(self.labels)\n\n def __getitem__(self, idx):\n text = self.texts[idx]\n label = torch.tensor(self.labels[idx], dtype=torch.long).to(device)\n\n encoding = tokenizer(text, truncation=True, padding=\"max_length\", max_length=32, return_tensors=\"pt\")\n item = {key: val.squeeze(0).to(device) for key, val in encoding.items()} # Remove batch dim\n\n return item, label\n\n# Load dataset & dataloader\ndataset = IntentDataset(unique_intents, tokenizer)\ndataloader = DataLoader(dataset, batch_size=16, shuffle=True) # Increased batch size\n\n# Compute class weights\nlabels = [dataset.label_map[intent[\"tag\"]] for intent in unique_intents for _ in intent[\"patterns\"]]\nclass_weights = compute_class_weight(\"balanced\", classes=np.unique(labels), y=labels)\nclass_weights = torch.tensor(class_weights, dtype=torch.float).to(device)\n\n# Define optimizer & loss function\noptimizer = torch.optim.AdamW(model.parameters(), lr=2e-5) # Lower learning rate\nloss_fn = torch.nn.CrossEntropyLoss(weight=class_weights) # Use class-weighted loss\n\n# Training loop\nepochs = 90 # Increased from 20 to 50 for better training\nmodel.train()\n\nfor epoch in range(epochs):\n total_loss = 0\n for batch in dataloader:\n inputs, labels = batch\n optimizer.zero_grad()\n outputs = model(**inputs)\n loss = loss_fn(outputs.logits, labels)\n loss.backward()\n optimizer.step()\n total_loss += loss.item()\n \n avg_loss = total_loss / len(dataloader)\n print(f\"Epoch {epoch+1}/{epochs} - Average Loss: {avg_loss:.4f}\")\n\n# Function to predict intent\ndef predict_intent(user_input):\n model.eval()\n inputs = tokenizer(user_input, return_tensors=\"pt\", truncation=True, padding=True, max_length=32)\n inputs = {key: val.to(device) for key, val in inputs.items()} # Move input to GPU\n\n with torch.no_grad():\n outputs = model(**inputs)\n\n predicted_label = torch.argmax(outputs.logits).item()\n \n # Map predicted label to intent\n intent_tag = list(dataset.label_map.keys())[predicted_label]\n\n # Fetch a random response for the predicted intent\n for intent in unique_intents:\n if intent[\"tag\"] == intent_tag:\n return random.choice(intent[\"responses\"])","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.status.busy":"2025-03-14T06:02:34.362718Z","iopub.execute_input":"2025-03-14T06:02:34.363000Z","iopub.status.idle":"2025-03-14T06:12:26.502668Z","shell.execute_reply.started":"2025-03-14T06:02:34.362977Z","shell.execute_reply":"2025-03-14T06:12:26.501655Z"},"trusted":true},"outputs":[{"name":"stdout","text":"Using device: cuda\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"tokenizer_config.json: 0%| | 0.00/48.0 [00:00<?, ?B/s]","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"7824a999787d4bd1b195d7d91c77b73d"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"vocab.txt: 0%| | 0.00/232k [00:00<?, ?B/s]","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"d429c8c5a09d44acabf466ce018c6bcd"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"tokenizer.json: 0%| | 0.00/466k [00:00<?, ?B/s]","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"0a455715281a4842b2b84fb392994a9a"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"config.json: 0%| | 0.00/570 [00:00<?, ?B/s]","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"cb3a2c53b638478c9aebbcb91ba50d1a"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"model.safetensors: 0%| | 0.00/440M [00:00<?, ?B/s]","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"e7ab9075f9a542439774f2c2fba440a1"}},"metadata":{}},{"name":"stderr","text":"Some weights of BertForSequenceClassification were not initialized from the model checkpoint at bert-base-uncased and are newly initialized: ['classifier.bias', 'classifier.weight']\nYou should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n","output_type":"stream"},{"name":"stdout","text":"Epoch 1/90 - Average Loss: 5.6662\nEpoch 2/90 - Average Loss: 5.6118\nEpoch 3/90 - Average Loss: 5.5608\nEpoch 4/90 - Average Loss: 5.4642\nEpoch 5/90 - Average Loss: 5.3513\nEpoch 6/90 - Average Loss: 5.1811\nEpoch 7/90 - Average Loss: 5.0176\nEpoch 8/90 - Average Loss: 4.8236\nEpoch 9/90 - Average Loss: 4.6535\nEpoch 10/90 - Average Loss: 4.4724\nEpoch 11/90 - Average Loss: 4.3279\nEpoch 12/90 - Average Loss: 4.1504\nEpoch 13/90 - Average Loss: 4.0176\nEpoch 14/90 - Average Loss: 3.8612\nEpoch 15/90 - Average Loss: 3.7189\nEpoch 16/90 - Average Loss: 3.5748\nEpoch 17/90 - Average Loss: 3.4296\nEpoch 18/90 - Average Loss: 3.3193\nEpoch 19/90 - Average Loss: 3.1704\nEpoch 20/90 - Average Loss: 3.0567\nEpoch 21/90 - Average Loss: 2.9273\nEpoch 22/90 - Average Loss: 2.7933\nEpoch 23/90 - Average Loss: 2.6832\nEpoch 24/90 - Average Loss: 2.5414\nEpoch 25/90 - Average Loss: 2.4337\nEpoch 26/90 - Average Loss: 2.3230\nEpoch 27/90 - Average Loss: 2.2094\nEpoch 28/90 - Average Loss: 2.0913\nEpoch 29/90 - Average Loss: 1.9798\nEpoch 30/90 - Average Loss: 1.8935\nEpoch 31/90 - Average Loss: 1.7755\nEpoch 32/90 - Average Loss: 1.6802\nEpoch 33/90 - Average Loss: 1.5814\nEpoch 34/90 - Average Loss: 1.5013\nEpoch 35/90 - Average Loss: 1.4134\nEpoch 36/90 - Average Loss: 1.3328\nEpoch 37/90 - Average Loss: 1.2458\nEpoch 38/90 - Average Loss: 1.1845\nEpoch 39/90 - Average Loss: 1.1036\nEpoch 40/90 - Average Loss: 1.0327\nEpoch 41/90 - Average Loss: 0.9679\nEpoch 42/90 - Average Loss: 0.9215\nEpoch 43/90 - Average Loss: 0.8682\nEpoch 44/90 - Average Loss: 0.8089\nEpoch 45/90 - Average Loss: 0.7654\nEpoch 46/90 - Average Loss: 0.7181\nEpoch 47/90 - Average Loss: 0.6696\nEpoch 48/90 - Average Loss: 0.6318\nEpoch 49/90 - Average Loss: 0.5918\nEpoch 50/90 - Average Loss: 0.5542\nEpoch 51/90 - Average Loss: 0.5274\nEpoch 52/90 - Average Loss: 0.4944\nEpoch 53/90 - Average Loss: 0.4631\nEpoch 54/90 - Average Loss: 0.4428\nEpoch 55/90 - Average Loss: 0.4125\nEpoch 56/90 - Average Loss: 0.3950\nEpoch 57/90 - Average Loss: 0.3698\nEpoch 58/90 - Average Loss: 0.3491\nEpoch 59/90 - Average Loss: 0.3309\nEpoch 60/90 - Average Loss: 0.3142\nEpoch 61/90 - Average Loss: 0.2992\nEpoch 62/90 - Average Loss: 0.2829\nEpoch 63/90 - Average Loss: 0.2706\nEpoch 64/90 - Average Loss: 0.2552\nEpoch 65/90 - Average Loss: 0.2451\nEpoch 66/90 - Average Loss: 0.2355\nEpoch 67/90 - Average Loss: 0.2219\nEpoch 68/90 - Average Loss: 0.2122\nEpoch 69/90 - Average Loss: 0.2063\nEpoch 70/90 - Average Loss: 0.1950\nEpoch 71/90 - Average Loss: 0.1860\nEpoch 72/90 - Average Loss: 0.1758\nEpoch 73/90 - Average Loss: 0.1675\nEpoch 74/90 - Average Loss: 0.1630\nEpoch 75/90 - Average Loss: 0.1607\nEpoch 76/90 - Average Loss: 0.1525\nEpoch 77/90 - Average Loss: 0.1441\nEpoch 78/90 - Average Loss: 0.1364\nEpoch 79/90 - Average Loss: 0.1326\nEpoch 80/90 - Average Loss: 0.1293\nEpoch 81/90 - Average Loss: 0.1269\nEpoch 82/90 - Average Loss: 0.1199\nEpoch 83/90 - Average Loss: 0.1129\nEpoch 84/90 - Average Loss: 0.1095\nEpoch 85/90 - Average Loss: 0.1076\nEpoch 86/90 - Average Loss: 0.1030\nEpoch 87/90 - Average Loss: 0.0984\nEpoch 88/90 - Average Loss: 0.0944\nEpoch 89/90 - Average Loss: 0.0919\nEpoch 90/90 - Average Loss: 0.0880\n","output_type":"stream"}],"execution_count":2},{"cell_type":"code","source":"import torch\nfrom torch.utils.data import random_split\nfrom sklearn.metrics import accuracy_score\n\n# Split dataset into training (80%) and test (20%) sets\ntrain_size = int(0.8 * len(dataset))\ntest_size = len(dataset) - train_size\ntrain_dataset, test_dataset = random_split(dataset, [train_size, test_size])\n\n# Create test dataloader\ntest_dataloader = DataLoader(test_dataset, batch_size=16, shuffle=False)\n\n# Function to evaluate model accuracy\ndef evaluate_model(model, test_dataloader):\n model.eval()\n all_preds, all_labels = [], []\n \n with torch.no_grad():\n for batch in test_dataloader:\n inputs, labels = batch\n outputs = model(**inputs)\n preds = torch.argmax(outputs.logits, dim=1)\n\n all_preds.extend(preds.cpu().numpy())\n all_labels.extend(labels.cpu().numpy())\n\n accuracy = accuracy_score(all_labels, all_preds)\n return accuracy\n\n# Compute accuracy\ntest_accuracy = evaluate_model(model, test_dataloader)\nprint(f\"Test Accuracy: {test_accuracy:.4f}\")\n","metadata":{"execution":{"iopub.status.busy":"2025-03-14T06:12:26.504747Z","iopub.execute_input":"2025-03-14T06:12:26.505510Z","iopub.status.idle":"2025-03-14T06:12:26.934471Z","shell.execute_reply.started":"2025-03-14T06:12:26.505474Z","shell.execute_reply":"2025-03-14T06:12:26.933341Z"},"trusted":true},"outputs":[{"name":"stdout","text":"Test Accuracy: 1.0000\n","output_type":"stream"}],"execution_count":3},{"cell_type":"code","source":"def evaluate_train_accuracy(model, train_dataloader):\n model.eval()\n all_preds, all_labels = [], []\n \n with torch.no_grad():\n for batch in train_dataloader:\n inputs, labels = batch\n outputs = model(**inputs)\n preds = torch.argmax(outputs.logits, dim=1)\n\n all_preds.extend(preds.cpu().numpy())\n all_labels.extend(labels.cpu().numpy())\n\n accuracy = accuracy_score(all_labels, all_preds)\n return accuracy\n\n# Compute Training Accuracy\ntrain_dataloader = DataLoader(train_dataset, batch_size=16, shuffle=False)\ntrain_accuracy = evaluate_train_accuracy(model, train_dataloader)\nprint(f\"Training Accuracy: {train_accuracy:.4f}\")\n","metadata":{"execution":{"iopub.status.busy":"2025-03-14T06:12:26.936431Z","iopub.execute_input":"2025-03-14T06:12:26.936897Z","iopub.status.idle":"2025-03-14T06:12:28.400809Z","shell.execute_reply.started":"2025-03-14T06:12:26.936850Z","shell.execute_reply":"2025-03-14T06:12:28.399868Z"},"trusted":true},"outputs":[{"name":"stdout","text":"Training Accuracy: 0.9939\n","output_type":"stream"}],"execution_count":4},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Assuming you store losses during training like this:\ntrain_losses = []\ntest_losses = []\n\nfor epoch in range(epochs):\n total_train_loss = 0\n total_test_loss = 0\n\n model.train()\n for batch in train_dataloader:\n inputs, labels = batch\n optimizer.zero_grad()\n outputs = model(**inputs)\n loss = loss_fn(outputs.logits, labels)\n loss.backward()\n optimizer.step()\n total_train_loss += loss.item()\n \n model.eval()\n with torch.no_grad():\n for batch in test_dataloader:\n inputs, labels = batch\n outputs = model(**inputs)\n loss = loss_fn(outputs.logits, labels)\n total_test_loss += loss.item()\n\n train_losses.append(total_train_loss / len(train_dataloader))\n test_losses.append(total_test_loss / len(test_dataloader))\n\n# Plot the loss curves\nplt.plot(range(1, epochs+1), train_losses, label=\"Train Loss\")\nplt.plot(range(1, epochs+1), test_losses, label=\"Test Loss\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Loss\")\nplt.legend()\nplt.title(\"Training vs. Test Loss\")\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2025-03-14T06:12:28.401654Z","iopub.execute_input":"2025-03-14T06:12:28.401902Z","iopub.status.idle":"2025-03-14T06:20:24.794528Z","shell.execute_reply.started":"2025-03-14T06:12:28.401882Z","shell.execute_reply":"2025-03-14T06:20:24.793362Z"},"trusted":true},"outputs":[{"output_type":"display_data","data":{"text/plain":"<Figure size 640x480 with 1 Axes>","image/png":"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bUbPnj2NmjVrGhkZGSZWXnYNGDDAqFq1qrFw4ULj8OHDxvfff28EBAQYL7zwgr2NvpPCoQBURN577z2jevXqhouLi9GmTRtj7dq1ZpdUbgD5Pj777DN7m4yMDOOZZ54xKlSoYHh4eBi9e/c2Tp06ZV7R5dD/BiB9J+b48ccfjUaNGhmurq5GeHi4MX369DyvW61W45VXXjECAwMNV1dXo1OnTsbevXtNqrbsS01NNYYNG2ZUr17dcHNzM2rVqmW89NJLRlZWlr2NvpPCYTGMvy0vKSIiIlIOaAyQiIiIlDsKQCIiIlLuKACJiIhIuaMAJCIiIuWOApCIiIiUOwpAIiIiUu4oAImIiEi5owAkInIFFouF+fPnm12GiBQBBSARKZEGDhyIxWK57NGlSxezSxORMsDJ7AJERK6kS5cufPbZZ3mOubq6mlSNiJQl6gESkRLL1dWVoKCgPI8KFSoAtttTH3zwAV27dsXd3Z1atWoxd+7cPOdv376dO+64A3d3d/z9/XniiSc4f/58njaffvopDRs2xNXVlSpVqjB48OA8ryclJdG7d288PDwICwtjwYIF9tfOnTvHgw8+SKVKlXB3dycsLOyywCYiJZMCkIiUWq+88gp9+/bljz/+4MEHH+SBBx5g9+7dAKSnp9O5c2cqVKjAhg0bmDNnDsuWLcsTcD744AOeffZZnnjiCbZv386CBQuoU6dOnvcYO3Ys999/P9u2bePuu+/mwQcf5OzZs/b337VrF4sXL2b37t188MEHBAQEFN8PQERuntm7sYqI5GfAgAGGo6Oj4enpmefx2muvGYZhGIDx1FNP5TknIiLCePrppw3DMIzp06cbFSpUMM6fP29//aeffjIcHByM+Ph4wzAMIzg42HjppZeuWANgvPzyy/bn58+fNwBj8eLFhmEYxj333GMMGjSocD6wiBQrjQESkRLr9ttv54MPPshzrGLFiva/R0ZG5nktMjKSrVu3ArB7926aNm2Kp6en/fX27dtjtVrZu3cvFouFkydP0qlTp6vW0KRJE/vfPT098fHxITExEYCnn36avn37snnzZu666y569epFu3btbuqzikjxUgASkRLL09PzsltShcXd3f262jk7O+d5brFYsFqtAHTt2pWjR4+yaNEili5dSqdOnXj22Wd56623Cr1eESlcGgMkIqXW2rVrL3tev359AOrXr88ff/xBenq6/fXVq1fj4OBAvXr18Pb2JjQ0lJiYmALVUKlSJQYMGMDXX3/N5MmTmT59eoGuJyLFQz1AIlJiZWVlER8fn+eYk5OTfaDxnDlzaNWqFR06dOCbb75h/fr1fPLJJwA8+OCDjB49mgEDBjBmzBhOnz7NkCFDePjhhwkMDARgzJgxPPXUU1SuXJmuXbuSlpbG6tWrGTJkyHXVN2rUKFq2bEnDhg3Jyspi4cKF9gAmIiWbApCIlFhLliyhSpUqeY7Vq1ePPXv2ALYZWjNnzuSZZ56hSpUqfPvttzRo0AAADw8Pfv75Z4YNG0br1q3x8PCgb9++vP322/ZrDRgwgMzMTN555x3+/e9/ExAQwL333nvd9bm4uDBy5EiOHDmCu7s7t9xyCzNnziyETy4iRc1iGIZhdhEiIjfKYrEwb948evXqZXYpIlIKaQyQiIiIlDsKQCIiIlLuaAyQiJRKunsvIgWhHiAREREpdxSAREREpNxRABIREZFyRwFIREREyh0FIBERESl3FIBERESk3FEAEhERkXJHAUhERETKHQUgERERKXf+H7ZokyJnjmeEAAAAAElFTkSuQmCC\n"},"metadata":{}}],"execution_count":5},{"cell_type":"code","source":"# Testing on New Data to test model generalization\ntest_inputs = [\n \"Tell me a joke\", \n \"Recommend a good book\", \n \"What's the weather like today?\", \n \"How can I save money?\", \n \"How do I meditate?\"\n]\n\nfor input_text in test_inputs:\n response = predict_intent(input_text)\n print(f\"User: {input_text}\\nBot: {response}\\n\")\n","metadata":{"execution":{"iopub.status.busy":"2025-03-14T06:20:24.795687Z","iopub.execute_input":"2025-03-14T06:20:24.796070Z","iopub.status.idle":"2025-03-14T06:20:24.907652Z","shell.execute_reply.started":"2025-03-14T06:20:24.796036Z","shell.execute_reply":"2025-03-14T06:20:24.906513Z"},"trusted":true},"outputs":[{"name":"stdout","text":"User: Tell me a joke\nBot: Did you hear about the mathematician who’s afraid of negative numbers? He’ll stop at nothing to avoid them!\n\nUser: Recommend a good book\nBot: As an AI, I don't have personal preferences, but there are countless amazing books in various genres. Some popular ones include Harry Potter, To Kill a Mockingbird, and 1984.\n\nUser: What's the weather like today?\nBot: I'm sorry, I cannot provide real-time weather information.\n\nUser: How can I save money?\nBot: Investing in stocks, mutual funds, or real estate can help grow your wealth over time.\n\nUser: How do I meditate?\nBot: Meditation can reduce stress, improve focus, and promote emotional well-being.\n\n","output_type":"stream"}],"execution_count":6},{"cell_type":"code","source":"# Define save paths\nmodel_path = \"bert_chatbot_model.pth\"\ntokenizer_path = \"bert_chatbot_tokenizer\"\n\n# Save model state dictionary\ntorch.save(model.state_dict(), model_path)\n\n# Save tokenizer\ntokenizer.save_pretrained(tokenizer_path)\n\nprint(f\"Model saved to {model_path}\")\nprint(f\"Tokenizer saved to {tokenizer_path}\")","metadata":{"execution":{"iopub.status.busy":"2025-03-14T06:20:24.908862Z","iopub.execute_input":"2025-03-14T06:20:24.909244Z","iopub.status.idle":"2025-03-14T06:20:25.664937Z","shell.execute_reply.started":"2025-03-14T06:20:24.909206Z","shell.execute_reply":"2025-03-14T06:20:25.664169Z"},"trusted":true},"outputs":[{"name":"stdout","text":"Model saved to bert_chatbot_model.pth\nTokenizer saved to bert_chatbot_tokenizer\n","output_type":"stream"}],"execution_count":7},{"cell_type":"code","source":"model.save_pretrained(\"chatbot_model\")\ntokenizer.save_pretrained(\"chatbot_model\")","metadata":{"execution":{"iopub.status.busy":"2025-03-14T06:20:25.666633Z","iopub.execute_input":"2025-03-14T06:20:25.666894Z","iopub.status.idle":"2025-03-14T06:20:26.840930Z","shell.execute_reply.started":"2025-03-14T06:20:25.666873Z","shell.execute_reply":"2025-03-14T06:20:26.839944Z"},"trusted":true},"outputs":[{"execution_count":8,"output_type":"execute_result","data":{"text/plain":"('chatbot_model/tokenizer_config.json',\n 'chatbot_model/special_tokens_map.json',\n 'chatbot_model/vocab.txt',\n 'chatbot_model/added_tokens.json')"},"metadata":{}}],"execution_count":8}]}
|
ChatBot_using_NLP.ipynb
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"id": "f0ce57f4-5984-43e6-b3bb-60f2d9251d75",
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"source": [
|
| 8 |
+
"# Implementation of Chatbot using Natural Language Processing(NLP)"
|
| 9 |
+
]
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"cell_type": "markdown",
|
| 13 |
+
"id": "3c062c6e-0773-4af8-bcb9-aa33f7afeb25",
|
| 14 |
+
"metadata": {},
|
| 15 |
+
"source": [
|
| 16 |
+
"### Importing necessary libraries"
|
| 17 |
+
]
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"cell_type": "code",
|
| 21 |
+
"execution_count": 1,
|
| 22 |
+
"id": "23417a10-2691-4887-b02e-2448f6200cd1",
|
| 23 |
+
"metadata": {},
|
| 24 |
+
"outputs": [],
|
| 25 |
+
"source": [
|
| 26 |
+
"import nltk\n",
|
| 27 |
+
"import random\n",
|
| 28 |
+
"import os\n",
|
| 29 |
+
"import ssl\n",
|
| 30 |
+
"import streamlit as st\n",
|
| 31 |
+
"from sklearn.svm import SVC\n",
|
| 32 |
+
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
|
| 33 |
+
"from sklearn.linear_model import LogisticRegression"
|
| 34 |
+
]
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"cell_type": "markdown",
|
| 38 |
+
"id": "1dc3d789-6567-4266-bd33-005aed1d4e93",
|
| 39 |
+
"metadata": {},
|
| 40 |
+
"source": [
|
| 41 |
+
"### Bypass SSL verification for NLTK downloads"
|
| 42 |
+
]
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"cell_type": "code",
|
| 46 |
+
"execution_count": 2,
|
| 47 |
+
"id": "298e3201-b127-4c68-b041-2a22ace29340",
|
| 48 |
+
"metadata": {},
|
| 49 |
+
"outputs": [
|
| 50 |
+
{
|
| 51 |
+
"name": "stderr",
|
| 52 |
+
"output_type": "stream",
|
| 53 |
+
"text": [
|
| 54 |
+
"[nltk_data] Downloading package punkt to\n",
|
| 55 |
+
"[nltk_data] C:\\Users\\LENOVO\\AppData\\Roaming\\nltk_data...\n",
|
| 56 |
+
"[nltk_data] Package punkt is already up-to-date!\n"
|
| 57 |
+
]
|
| 58 |
+
},
|
| 59 |
+
{
|
| 60 |
+
"data": {
|
| 61 |
+
"text/plain": [
|
| 62 |
+
"True"
|
| 63 |
+
]
|
| 64 |
+
},
|
| 65 |
+
"execution_count": 2,
|
| 66 |
+
"metadata": {},
|
| 67 |
+
"output_type": "execute_result"
|
| 68 |
+
}
|
| 69 |
+
],
|
| 70 |
+
"source": [
|
| 71 |
+
"ssl._create_default_https_context = ssl._create_unverified_context\n",
|
| 72 |
+
"nltk.data.path.append(os.path.abspath('nltk_data'))\n",
|
| 73 |
+
"nltk.download('punkt')"
|
| 74 |
+
]
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"cell_type": "markdown",
|
| 78 |
+
"id": "62d1be3d-37b1-4ab3-a527-9185e183ac98",
|
| 79 |
+
"metadata": {},
|
| 80 |
+
"source": [
|
| 81 |
+
"### Intent dataset"
|
| 82 |
+
]
|
| 83 |
+
},
|
| 84 |
+
{
|
| 85 |
+
"cell_type": "code",
|
| 86 |
+
"execution_count": 3,
|
| 87 |
+
"id": "a4c238c5-fe25-4802-9328-70ec7b064044",
|
| 88 |
+
"metadata": {},
|
| 89 |
+
"outputs": [],
|
| 90 |
+
"source": [
|
| 91 |
+
"intents = [\n",
|
| 92 |
+
" {\n",
|
| 93 |
+
" \"atag\": \"greeting\", \"patterns\": [\"Hi\", \"Hello\", \"Hey\", \"What's up\", \"How are you\"],\n",
|
| 94 |
+
" \"responses\": [\"Hi there!\", \"Hello!\", \"Hey!\", \"Nothing much.\", \"I'm fine, thank you.\"]\n",
|
| 95 |
+
" },\n",
|
| 96 |
+
" {\n",
|
| 97 |
+
" \"tag\": \"goodbye\", \"patterns\": [\"Bye\", \"See you later\", \"Goodbye\", \"Take care\"],\n",
|
| 98 |
+
" \"responses\": [\"Goodbye!\", \"See you later!\", \"Take care!\"]\n",
|
| 99 |
+
" },\n",
|
| 100 |
+
" {\n",
|
| 101 |
+
" \"tag\": \"thanks\", \"patterns\": [\"Thank you\", \"Thanks\", \"Thanks a lot\", \"I appreciate it\"],\n",
|
| 102 |
+
" \"responses\": [\"You're welcome!\", \"No problem!\", \"Glad I could help!\"]\n",
|
| 103 |
+
" },\n",
|
| 104 |
+
" {\n",
|
| 105 |
+
" \"tag\": \"about\", \"patterns\": [\"What can you do\", \"Who are you\", \"What are you\", \"What is your purpose\"],\n",
|
| 106 |
+
" \"responses\": [\"I am a chatbot.\", \"My purpose is to assist you.\", \"I can answer questions and provide assistance.\"]\n",
|
| 107 |
+
" },\n",
|
| 108 |
+
" {\n",
|
| 109 |
+
" \"tag\": \"help\", \"patterns\": [\"Help\", \"I need help\", \"Can you help me\", \"What should I do\"],\n",
|
| 110 |
+
" \"responses\": [\"Sure, what do you need help with?\", \"I'm here to help. What's the problem?\", \"How can I assist you?\"]\n",
|
| 111 |
+
" },\n",
|
| 112 |
+
" {\n",
|
| 113 |
+
" \"tag\": \"age\", \"patterns\": [\"How old are you\", \"What's your age\"],\n",
|
| 114 |
+
" \"responses\": [\"I don't have an age. I'm a chatbot.\", \"I was just born in the digital world.\", \"Age is just a number for me.\"]\n",
|
| 115 |
+
" },\n",
|
| 116 |
+
" {\n",
|
| 117 |
+
" \"tag\": \"weather\", \"patterns\": [\"What's the weather like\", \"How's the weather today\"],\n",
|
| 118 |
+
" \"responses\": [\"I'm sorry, I cannot provide real-time weather information.\", \"You can check the weather on a weather app or website.\"]\n",
|
| 119 |
+
" },\n",
|
| 120 |
+
" {\n",
|
| 121 |
+
" \"tag\": \"budget\", \"patterns\": [\"How can I make a budget\", \"What's a good budgeting strategy\", \"How do I create a budget\"],\n",
|
| 122 |
+
" \"responses\": [\"Start by tracking your income and expenses. Allocate money for essentials, savings, and discretionary spending.\",\n",
|
| 123 |
+
" \"A good strategy is the 50/30/20 rule: 50% for needs, 30% for wants, and 20% for savings and debt.\",\n",
|
| 124 |
+
" \"Set financial goals, monitor expenses, and adjust your budget as needed.\"]\n",
|
| 125 |
+
" },\n",
|
| 126 |
+
" {\n",
|
| 127 |
+
" \"tag\": \"credit_score\", \"patterns\": [\"What is a credit score\", \"How do I check my credit score\", \"How can I improve my credit score\"],\n",
|
| 128 |
+
" \"responses\": [\"A credit score reflects your creditworthiness and is used by lenders to assess loans.\",\n",
|
| 129 |
+
" \"Check your credit score on platforms like Credit Karma or Credit Sesame.\",\n",
|
| 130 |
+
" \"Improve your credit score by paying bills on time, reducing debt, and maintaining good credit utilization.\"]\n",
|
| 131 |
+
" },\n",
|
| 132 |
+
" {\n",
|
| 133 |
+
" \"tag\": \"food\", \"patterns\": [\"What should I eat\", \"Suggest me some food\", \"I am hungry\"],\n",
|
| 134 |
+
" \"responses\": [\"You could try a healthy salad, a sandwich, or some pasta!\", \"How about some homemade pizza?\", \"A nice bowl of soup and bread would be great!\"]\n",
|
| 135 |
+
" },\n",
|
| 136 |
+
" {\n",
|
| 137 |
+
" \"tag\": \"exercise\", \"patterns\": [\"What exercises should I do\", \"How to stay fit\", \"Suggest a workout\"],\n",
|
| 138 |
+
" \"responses\": [\"Try a mix of cardio and strength training!\", \"A daily walk and some stretching would help.\", \"Yoga is great for both mind and body!\"]\n",
|
| 139 |
+
" },\n",
|
| 140 |
+
" {\n",
|
| 141 |
+
" \"tag\": \"movies\", \"patterns\": [\"Suggest me a movie\", \"What are some good movies\", \"I want to watch a film\"],\n",
|
| 142 |
+
" \"responses\": [\"How about an action thriller?\", \"A comedy might lift your mood!\", \"Sci-fi movies are always exciting!\"]\n",
|
| 143 |
+
" },\n",
|
| 144 |
+
" {\n",
|
| 145 |
+
" \"tag\": \"music\", \"patterns\": [\"Suggest me some music\", \"What should I listen to\", \"Recommend a song\"],\n",
|
| 146 |
+
" \"responses\": [\"Try some relaxing jazz or lo-fi music!\", \"Pop songs are always fun!\", \"How about some classic rock?\"]\n",
|
| 147 |
+
" }\n",
|
| 148 |
+
"]"
|
| 149 |
+
]
|
| 150 |
+
},
|
| 151 |
+
{
|
| 152 |
+
"cell_type": "markdown",
|
| 153 |
+
"id": "3ece2689-d741-48ea-9659-be9cf20e3033",
|
| 154 |
+
"metadata": {},
|
| 155 |
+
"source": [
|
| 156 |
+
"### Create the vectorizer and classifier"
|
| 157 |
+
]
|
| 158 |
+
},
|
| 159 |
+
{
|
| 160 |
+
"cell_type": "code",
|
| 161 |
+
"execution_count": 4,
|
| 162 |
+
"id": "18d6ccb9-639c-4053-981a-69e2fa7cccca",
|
| 163 |
+
"metadata": {},
|
| 164 |
+
"outputs": [],
|
| 165 |
+
"source": [
|
| 166 |
+
"vectorizer = TfidfVectorizer()\n",
|
| 167 |
+
"clf = SVC(kernel='linear', random_state=0)\n",
|
| 168 |
+
"#clf = LogisticRegression(random_state=0, max_iter=10000)"
|
| 169 |
+
]
|
| 170 |
+
},
|
| 171 |
+
{
|
| 172 |
+
"cell_type": "markdown",
|
| 173 |
+
"id": "09e70e89-e826-432a-9c22-b4097b5ac07f",
|
| 174 |
+
"metadata": {},
|
| 175 |
+
"source": [
|
| 176 |
+
"### Preprocess the data"
|
| 177 |
+
]
|
| 178 |
+
},
|
| 179 |
+
{
|
| 180 |
+
"cell_type": "code",
|
| 181 |
+
"execution_count": 5,
|
| 182 |
+
"id": "aca02fbf-201b-47a6-b46c-ca9e0d4e9334",
|
| 183 |
+
"metadata": {},
|
| 184 |
+
"outputs": [],
|
| 185 |
+
"source": [
|
| 186 |
+
"tags = []\n",
|
| 187 |
+
"patterns = []\n",
|
| 188 |
+
"for intent in intents:\n",
|
| 189 |
+
" for pattern in intent['patterns']:\n",
|
| 190 |
+
" tags.append(intent['tag'])\n",
|
| 191 |
+
" patterns.append(pattern)"
|
| 192 |
+
]
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"cell_type": "markdown",
|
| 196 |
+
"id": "e33f4599-2a6b-4b9b-805a-7875b1840eb4",
|
| 197 |
+
"metadata": {},
|
| 198 |
+
"source": [
|
| 199 |
+
"### Training the model"
|
| 200 |
+
]
|
| 201 |
+
},
|
| 202 |
+
{
|
| 203 |
+
"cell_type": "code",
|
| 204 |
+
"execution_count": 6,
|
| 205 |
+
"id": "6d11f50c-7062-46e3-89d2-f6e252e5cf12",
|
| 206 |
+
"metadata": {},
|
| 207 |
+
"outputs": [
|
| 208 |
+
{
|
| 209 |
+
"data": {
|
| 210 |
+
"text/html": [
|
| 211 |
+
"<style>#sk-container-id-1 {color: black;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>SVC(kernel='linear', random_state=0)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">SVC</label><div class=\"sk-toggleable__content\"><pre>SVC(kernel='linear', random_state=0)</pre></div></div></div></div></div>"
|
| 212 |
+
],
|
| 213 |
+
"text/plain": [
|
| 214 |
+
"SVC(kernel='linear', random_state=0)"
|
| 215 |
+
]
|
| 216 |
+
},
|
| 217 |
+
"execution_count": 6,
|
| 218 |
+
"metadata": {},
|
| 219 |
+
"output_type": "execute_result"
|
| 220 |
+
}
|
| 221 |
+
],
|
| 222 |
+
"source": [
|
| 223 |
+
"x = vectorizer.fit_transform(patterns)\n",
|
| 224 |
+
"y = tags\n",
|
| 225 |
+
"clf.fit(x, y)"
|
| 226 |
+
]
|
| 227 |
+
},
|
| 228 |
+
{
|
| 229 |
+
"cell_type": "markdown",
|
| 230 |
+
"id": "a75b5c8f-cc42-4afc-b261-bfdbe6c79913",
|
| 231 |
+
"metadata": {},
|
| 232 |
+
"source": [
|
| 233 |
+
"### Python function to chat with the chatbot"
|
| 234 |
+
]
|
| 235 |
+
},
|
| 236 |
+
{
|
| 237 |
+
"cell_type": "code",
|
| 238 |
+
"execution_count": 7,
|
| 239 |
+
"id": "12ac8a47-eac5-440f-ab0e-93686944b34b",
|
| 240 |
+
"metadata": {},
|
| 241 |
+
"outputs": [],
|
| 242 |
+
"source": [
|
| 243 |
+
"def chatbot(input_text):\n",
|
| 244 |
+
" input_text = vectorizer.transform([input_text])\n",
|
| 245 |
+
" tag = clf.predict(input_text)[0]\n",
|
| 246 |
+
" for intent in intents:\n",
|
| 247 |
+
" if intent['tag'] == tag:\n",
|
| 248 |
+
" response = random.choice(intent['responses'])\n",
|
| 249 |
+
" return response"
|
| 250 |
+
]
|
| 251 |
+
},
|
| 252 |
+
{
|
| 253 |
+
"cell_type": "markdown",
|
| 254 |
+
"id": "cf1ff963-ebbe-4fac-af82-26d3e3336c33",
|
| 255 |
+
"metadata": {},
|
| 256 |
+
"source": [
|
| 257 |
+
"### Checking our chatbot"
|
| 258 |
+
]
|
| 259 |
+
},
|
| 260 |
+
{
|
| 261 |
+
"cell_type": "code",
|
| 262 |
+
"execution_count": 8,
|
| 263 |
+
"id": "8f469e8a-c8a0-4683-9be0-0aefa67c8cea",
|
| 264 |
+
"metadata": {},
|
| 265 |
+
"outputs": [
|
| 266 |
+
{
|
| 267 |
+
"name": "stdout",
|
| 268 |
+
"output_type": "stream",
|
| 269 |
+
"text": [
|
| 270 |
+
"Hey!\n"
|
| 271 |
+
]
|
| 272 |
+
}
|
| 273 |
+
],
|
| 274 |
+
"source": [
|
| 275 |
+
"user_input = \"Hello\"\n",
|
| 276 |
+
"response = chatbot(user_input)\n",
|
| 277 |
+
"print(response)"
|
| 278 |
+
]
|
| 279 |
+
},
|
| 280 |
+
{
|
| 281 |
+
"cell_type": "code",
|
| 282 |
+
"execution_count": 9,
|
| 283 |
+
"id": "f49306db-d7da-4e79-860e-cd6e2985ca58",
|
| 284 |
+
"metadata": {},
|
| 285 |
+
"outputs": [
|
| 286 |
+
{
|
| 287 |
+
"name": "stdout",
|
| 288 |
+
"output_type": "stream",
|
| 289 |
+
"text": [
|
| 290 |
+
"Try a mix of cardio and strength training!\n"
|
| 291 |
+
]
|
| 292 |
+
}
|
| 293 |
+
],
|
| 294 |
+
"source": [
|
| 295 |
+
"user_input = \"What exercises should I do\"\n",
|
| 296 |
+
"response = chatbot(user_input)\n",
|
| 297 |
+
"print(response)"
|
| 298 |
+
]
|
| 299 |
+
}
|
| 300 |
+
],
|
| 301 |
+
"metadata": {
|
| 302 |
+
"kernelspec": {
|
| 303 |
+
"display_name": "GPU(sam)",
|
| 304 |
+
"language": "python",
|
| 305 |
+
"name": "sam"
|
| 306 |
+
},
|
| 307 |
+
"language_info": {
|
| 308 |
+
"codemirror_mode": {
|
| 309 |
+
"name": "ipython",
|
| 310 |
+
"version": 3
|
| 311 |
+
},
|
| 312 |
+
"file_extension": ".py",
|
| 313 |
+
"mimetype": "text/x-python",
|
| 314 |
+
"name": "python",
|
| 315 |
+
"nbconvert_exporter": "python",
|
| 316 |
+
"pygments_lexer": "ipython3",
|
| 317 |
+
"version": "3.8.20"
|
| 318 |
+
}
|
| 319 |
+
},
|
| 320 |
+
"nbformat": 4,
|
| 321 |
+
"nbformat_minor": 5
|
| 322 |
+
}
|
Images/Bot Image.jpeg
ADDED
|
Git LFS Details
|
README.md
CHANGED
|
@@ -1,14 +1,2 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
emoji: 📚
|
| 4 |
-
colorFrom: pink
|
| 5 |
-
colorTo: yellow
|
| 6 |
-
sdk: streamlit
|
| 7 |
-
sdk_version: 1.43.2
|
| 8 |
-
app_file: app.py
|
| 9 |
-
pinned: false
|
| 10 |
-
license: apache-2.0
|
| 11 |
-
short_description: The System on Real Time Intent Recognition and Conversations
|
| 12 |
-
---
|
| 13 |
-
|
| 14 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 1 |
+
# Implementation of Chatbot using Natural Language Processing (NLP)
|
| 2 |
+
Welcome!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Trained Model/bert_chatbot_model.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:cfae148072dd42387f8b37e25dd6145fba9fbb1f4d85598dc0d57af6f42d0537
|
| 3 |
+
size 438852591
|
Trained Model/bert_chatbot_tokenizer/special_tokens_map.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cls_token": "[CLS]",
|
| 3 |
+
"mask_token": "[MASK]",
|
| 4 |
+
"pad_token": "[PAD]",
|
| 5 |
+
"sep_token": "[SEP]",
|
| 6 |
+
"unk_token": "[UNK]"
|
| 7 |
+
}
|
Trained Model/bert_chatbot_tokenizer/tokenizer_config.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"added_tokens_decoder": {
|
| 3 |
+
"0": {
|
| 4 |
+
"content": "[PAD]",
|
| 5 |
+
"lstrip": false,
|
| 6 |
+
"normalized": false,
|
| 7 |
+
"rstrip": false,
|
| 8 |
+
"single_word": false,
|
| 9 |
+
"special": true
|
| 10 |
+
},
|
| 11 |
+
"100": {
|
| 12 |
+
"content": "[UNK]",
|
| 13 |
+
"lstrip": false,
|
| 14 |
+
"normalized": false,
|
| 15 |
+
"rstrip": false,
|
| 16 |
+
"single_word": false,
|
| 17 |
+
"special": true
|
| 18 |
+
},
|
| 19 |
+
"101": {
|
| 20 |
+
"content": "[CLS]",
|
| 21 |
+
"lstrip": false,
|
| 22 |
+
"normalized": false,
|
| 23 |
+
"rstrip": false,
|
| 24 |
+
"single_word": false,
|
| 25 |
+
"special": true
|
| 26 |
+
},
|
| 27 |
+
"102": {
|
| 28 |
+
"content": "[SEP]",
|
| 29 |
+
"lstrip": false,
|
| 30 |
+
"normalized": false,
|
| 31 |
+
"rstrip": false,
|
| 32 |
+
"single_word": false,
|
| 33 |
+
"special": true
|
| 34 |
+
},
|
| 35 |
+
"103": {
|
| 36 |
+
"content": "[MASK]",
|
| 37 |
+
"lstrip": false,
|
| 38 |
+
"normalized": false,
|
| 39 |
+
"rstrip": false,
|
| 40 |
+
"single_word": false,
|
| 41 |
+
"special": true
|
| 42 |
+
}
|
| 43 |
+
},
|
| 44 |
+
"clean_up_tokenization_spaces": true,
|
| 45 |
+
"cls_token": "[CLS]",
|
| 46 |
+
"do_basic_tokenize": true,
|
| 47 |
+
"do_lower_case": true,
|
| 48 |
+
"extra_special_tokens": {},
|
| 49 |
+
"mask_token": "[MASK]",
|
| 50 |
+
"model_max_length": 512,
|
| 51 |
+
"never_split": null,
|
| 52 |
+
"pad_token": "[PAD]",
|
| 53 |
+
"sep_token": "[SEP]",
|
| 54 |
+
"strip_accents": null,
|
| 55 |
+
"tokenize_chinese_chars": true,
|
| 56 |
+
"tokenizer_class": "BertTokenizer",
|
| 57 |
+
"unk_token": "[UNK]"
|
| 58 |
+
}
|
Trained Model/bert_chatbot_tokenizer/vocab.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Trained Model/chatbot_model/config.json
ADDED
|
@@ -0,0 +1,576 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_name_or_path": "bert-base-uncased",
|
| 3 |
+
"architectures": [
|
| 4 |
+
"BertForSequenceClassification"
|
| 5 |
+
],
|
| 6 |
+
"attention_probs_dropout_prob": 0.1,
|
| 7 |
+
"classifier_dropout": null,
|
| 8 |
+
"gradient_checkpointing": false,
|
| 9 |
+
"hidden_act": "gelu",
|
| 10 |
+
"hidden_dropout_prob": 0.1,
|
| 11 |
+
"hidden_size": 768,
|
| 12 |
+
"id2label": {
|
| 13 |
+
"0": "LABEL_0",
|
| 14 |
+
"1": "LABEL_1",
|
| 15 |
+
"2": "LABEL_2",
|
| 16 |
+
"3": "LABEL_3",
|
| 17 |
+
"4": "LABEL_4",
|
| 18 |
+
"5": "LABEL_5",
|
| 19 |
+
"6": "LABEL_6",
|
| 20 |
+
"7": "LABEL_7",
|
| 21 |
+
"8": "LABEL_8",
|
| 22 |
+
"9": "LABEL_9",
|
| 23 |
+
"10": "LABEL_10",
|
| 24 |
+
"11": "LABEL_11",
|
| 25 |
+
"12": "LABEL_12",
|
| 26 |
+
"13": "LABEL_13",
|
| 27 |
+
"14": "LABEL_14",
|
| 28 |
+
"15": "LABEL_15",
|
| 29 |
+
"16": "LABEL_16",
|
| 30 |
+
"17": "LABEL_17",
|
| 31 |
+
"18": "LABEL_18",
|
| 32 |
+
"19": "LABEL_19",
|
| 33 |
+
"20": "LABEL_20",
|
| 34 |
+
"21": "LABEL_21",
|
| 35 |
+
"22": "LABEL_22",
|
| 36 |
+
"23": "LABEL_23",
|
| 37 |
+
"24": "LABEL_24",
|
| 38 |
+
"25": "LABEL_25",
|
| 39 |
+
"26": "LABEL_26",
|
| 40 |
+
"27": "LABEL_27",
|
| 41 |
+
"28": "LABEL_28",
|
| 42 |
+
"29": "LABEL_29",
|
| 43 |
+
"30": "LABEL_30",
|
| 44 |
+
"31": "LABEL_31",
|
| 45 |
+
"32": "LABEL_32",
|
| 46 |
+
"33": "LABEL_33",
|
| 47 |
+
"34": "LABEL_34",
|
| 48 |
+
"35": "LABEL_35",
|
| 49 |
+
"36": "LABEL_36",
|
| 50 |
+
"37": "LABEL_37",
|
| 51 |
+
"38": "LABEL_38",
|
| 52 |
+
"39": "LABEL_39",
|
| 53 |
+
"40": "LABEL_40",
|
| 54 |
+
"41": "LABEL_41",
|
| 55 |
+
"42": "LABEL_42",
|
| 56 |
+
"43": "LABEL_43",
|
| 57 |
+
"44": "LABEL_44",
|
| 58 |
+
"45": "LABEL_45",
|
| 59 |
+
"46": "LABEL_46",
|
| 60 |
+
"47": "LABEL_47",
|
| 61 |
+
"48": "LABEL_48",
|
| 62 |
+
"49": "LABEL_49",
|
| 63 |
+
"50": "LABEL_50",
|
| 64 |
+
"51": "LABEL_51",
|
| 65 |
+
"52": "LABEL_52",
|
| 66 |
+
"53": "LABEL_53",
|
| 67 |
+
"54": "LABEL_54",
|
| 68 |
+
"55": "LABEL_55",
|
| 69 |
+
"56": "LABEL_56",
|
| 70 |
+
"57": "LABEL_57",
|
| 71 |
+
"58": "LABEL_58",
|
| 72 |
+
"59": "LABEL_59",
|
| 73 |
+
"60": "LABEL_60",
|
| 74 |
+
"61": "LABEL_61",
|
| 75 |
+
"62": "LABEL_62",
|
| 76 |
+
"63": "LABEL_63",
|
| 77 |
+
"64": "LABEL_64",
|
| 78 |
+
"65": "LABEL_65",
|
| 79 |
+
"66": "LABEL_66",
|
| 80 |
+
"67": "LABEL_67",
|
| 81 |
+
"68": "LABEL_68",
|
| 82 |
+
"69": "LABEL_69",
|
| 83 |
+
"70": "LABEL_70",
|
| 84 |
+
"71": "LABEL_71",
|
| 85 |
+
"72": "LABEL_72",
|
| 86 |
+
"73": "LABEL_73",
|
| 87 |
+
"74": "LABEL_74",
|
| 88 |
+
"75": "LABEL_75",
|
| 89 |
+
"76": "LABEL_76",
|
| 90 |
+
"77": "LABEL_77",
|
| 91 |
+
"78": "LABEL_78",
|
| 92 |
+
"79": "LABEL_79",
|
| 93 |
+
"80": "LABEL_80",
|
| 94 |
+
"81": "LABEL_81",
|
| 95 |
+
"82": "LABEL_82",
|
| 96 |
+
"83": "LABEL_83",
|
| 97 |
+
"84": "LABEL_84",
|
| 98 |
+
"85": "LABEL_85",
|
| 99 |
+
"86": "LABEL_86",
|
| 100 |
+
"87": "LABEL_87",
|
| 101 |
+
"88": "LABEL_88",
|
| 102 |
+
"89": "LABEL_89",
|
| 103 |
+
"90": "LABEL_90",
|
| 104 |
+
"91": "LABEL_91",
|
| 105 |
+
"92": "LABEL_92",
|
| 106 |
+
"93": "LABEL_93",
|
| 107 |
+
"94": "LABEL_94",
|
| 108 |
+
"95": "LABEL_95",
|
| 109 |
+
"96": "LABEL_96",
|
| 110 |
+
"97": "LABEL_97",
|
| 111 |
+
"98": "LABEL_98",
|
| 112 |
+
"99": "LABEL_99",
|
| 113 |
+
"100": "LABEL_100",
|
| 114 |
+
"101": "LABEL_101",
|
| 115 |
+
"102": "LABEL_102",
|
| 116 |
+
"103": "LABEL_103",
|
| 117 |
+
"104": "LABEL_104",
|
| 118 |
+
"105": "LABEL_105",
|
| 119 |
+
"106": "LABEL_106",
|
| 120 |
+
"107": "LABEL_107",
|
| 121 |
+
"108": "LABEL_108",
|
| 122 |
+
"109": "LABEL_109",
|
| 123 |
+
"110": "LABEL_110",
|
| 124 |
+
"111": "LABEL_111",
|
| 125 |
+
"112": "LABEL_112",
|
| 126 |
+
"113": "LABEL_113",
|
| 127 |
+
"114": "LABEL_114",
|
| 128 |
+
"115": "LABEL_115",
|
| 129 |
+
"116": "LABEL_116",
|
| 130 |
+
"117": "LABEL_117",
|
| 131 |
+
"118": "LABEL_118",
|
| 132 |
+
"119": "LABEL_119",
|
| 133 |
+
"120": "LABEL_120",
|
| 134 |
+
"121": "LABEL_121",
|
| 135 |
+
"122": "LABEL_122",
|
| 136 |
+
"123": "LABEL_123",
|
| 137 |
+
"124": "LABEL_124",
|
| 138 |
+
"125": "LABEL_125",
|
| 139 |
+
"126": "LABEL_126",
|
| 140 |
+
"127": "LABEL_127",
|
| 141 |
+
"128": "LABEL_128",
|
| 142 |
+
"129": "LABEL_129",
|
| 143 |
+
"130": "LABEL_130",
|
| 144 |
+
"131": "LABEL_131",
|
| 145 |
+
"132": "LABEL_132",
|
| 146 |
+
"133": "LABEL_133",
|
| 147 |
+
"134": "LABEL_134",
|
| 148 |
+
"135": "LABEL_135",
|
| 149 |
+
"136": "LABEL_136",
|
| 150 |
+
"137": "LABEL_137",
|
| 151 |
+
"138": "LABEL_138",
|
| 152 |
+
"139": "LABEL_139",
|
| 153 |
+
"140": "LABEL_140",
|
| 154 |
+
"141": "LABEL_141",
|
| 155 |
+
"142": "LABEL_142",
|
| 156 |
+
"143": "LABEL_143",
|
| 157 |
+
"144": "LABEL_144",
|
| 158 |
+
"145": "LABEL_145",
|
| 159 |
+
"146": "LABEL_146",
|
| 160 |
+
"147": "LABEL_147",
|
| 161 |
+
"148": "LABEL_148",
|
| 162 |
+
"149": "LABEL_149",
|
| 163 |
+
"150": "LABEL_150",
|
| 164 |
+
"151": "LABEL_151",
|
| 165 |
+
"152": "LABEL_152",
|
| 166 |
+
"153": "LABEL_153",
|
| 167 |
+
"154": "LABEL_154",
|
| 168 |
+
"155": "LABEL_155",
|
| 169 |
+
"156": "LABEL_156",
|
| 170 |
+
"157": "LABEL_157",
|
| 171 |
+
"158": "LABEL_158",
|
| 172 |
+
"159": "LABEL_159",
|
| 173 |
+
"160": "LABEL_160",
|
| 174 |
+
"161": "LABEL_161",
|
| 175 |
+
"162": "LABEL_162",
|
| 176 |
+
"163": "LABEL_163",
|
| 177 |
+
"164": "LABEL_164",
|
| 178 |
+
"165": "LABEL_165",
|
| 179 |
+
"166": "LABEL_166",
|
| 180 |
+
"167": "LABEL_167",
|
| 181 |
+
"168": "LABEL_168",
|
| 182 |
+
"169": "LABEL_169",
|
| 183 |
+
"170": "LABEL_170",
|
| 184 |
+
"171": "LABEL_171",
|
| 185 |
+
"172": "LABEL_172",
|
| 186 |
+
"173": "LABEL_173",
|
| 187 |
+
"174": "LABEL_174",
|
| 188 |
+
"175": "LABEL_175",
|
| 189 |
+
"176": "LABEL_176",
|
| 190 |
+
"177": "LABEL_177",
|
| 191 |
+
"178": "LABEL_178",
|
| 192 |
+
"179": "LABEL_179",
|
| 193 |
+
"180": "LABEL_180",
|
| 194 |
+
"181": "LABEL_181",
|
| 195 |
+
"182": "LABEL_182",
|
| 196 |
+
"183": "LABEL_183",
|
| 197 |
+
"184": "LABEL_184",
|
| 198 |
+
"185": "LABEL_185",
|
| 199 |
+
"186": "LABEL_186",
|
| 200 |
+
"187": "LABEL_187",
|
| 201 |
+
"188": "LABEL_188",
|
| 202 |
+
"189": "LABEL_189",
|
| 203 |
+
"190": "LABEL_190",
|
| 204 |
+
"191": "LABEL_191",
|
| 205 |
+
"192": "LABEL_192",
|
| 206 |
+
"193": "LABEL_193",
|
| 207 |
+
"194": "LABEL_194",
|
| 208 |
+
"195": "LABEL_195",
|
| 209 |
+
"196": "LABEL_196",
|
| 210 |
+
"197": "LABEL_197",
|
| 211 |
+
"198": "LABEL_198",
|
| 212 |
+
"199": "LABEL_199",
|
| 213 |
+
"200": "LABEL_200",
|
| 214 |
+
"201": "LABEL_201",
|
| 215 |
+
"202": "LABEL_202",
|
| 216 |
+
"203": "LABEL_203",
|
| 217 |
+
"204": "LABEL_204",
|
| 218 |
+
"205": "LABEL_205",
|
| 219 |
+
"206": "LABEL_206",
|
| 220 |
+
"207": "LABEL_207",
|
| 221 |
+
"208": "LABEL_208",
|
| 222 |
+
"209": "LABEL_209",
|
| 223 |
+
"210": "LABEL_210",
|
| 224 |
+
"211": "LABEL_211",
|
| 225 |
+
"212": "LABEL_212",
|
| 226 |
+
"213": "LABEL_213",
|
| 227 |
+
"214": "LABEL_214",
|
| 228 |
+
"215": "LABEL_215",
|
| 229 |
+
"216": "LABEL_216",
|
| 230 |
+
"217": "LABEL_217",
|
| 231 |
+
"218": "LABEL_218",
|
| 232 |
+
"219": "LABEL_219",
|
| 233 |
+
"220": "LABEL_220",
|
| 234 |
+
"221": "LABEL_221",
|
| 235 |
+
"222": "LABEL_222",
|
| 236 |
+
"223": "LABEL_223",
|
| 237 |
+
"224": "LABEL_224",
|
| 238 |
+
"225": "LABEL_225",
|
| 239 |
+
"226": "LABEL_226",
|
| 240 |
+
"227": "LABEL_227",
|
| 241 |
+
"228": "LABEL_228",
|
| 242 |
+
"229": "LABEL_229",
|
| 243 |
+
"230": "LABEL_230",
|
| 244 |
+
"231": "LABEL_231",
|
| 245 |
+
"232": "LABEL_232",
|
| 246 |
+
"233": "LABEL_233",
|
| 247 |
+
"234": "LABEL_234",
|
| 248 |
+
"235": "LABEL_235",
|
| 249 |
+
"236": "LABEL_236",
|
| 250 |
+
"237": "LABEL_237",
|
| 251 |
+
"238": "LABEL_238",
|
| 252 |
+
"239": "LABEL_239",
|
| 253 |
+
"240": "LABEL_240",
|
| 254 |
+
"241": "LABEL_241",
|
| 255 |
+
"242": "LABEL_242",
|
| 256 |
+
"243": "LABEL_243",
|
| 257 |
+
"244": "LABEL_244",
|
| 258 |
+
"245": "LABEL_245",
|
| 259 |
+
"246": "LABEL_246",
|
| 260 |
+
"247": "LABEL_247",
|
| 261 |
+
"248": "LABEL_248",
|
| 262 |
+
"249": "LABEL_249",
|
| 263 |
+
"250": "LABEL_250",
|
| 264 |
+
"251": "LABEL_251",
|
| 265 |
+
"252": "LABEL_252",
|
| 266 |
+
"253": "LABEL_253",
|
| 267 |
+
"254": "LABEL_254",
|
| 268 |
+
"255": "LABEL_255",
|
| 269 |
+
"256": "LABEL_256",
|
| 270 |
+
"257": "LABEL_257",
|
| 271 |
+
"258": "LABEL_258",
|
| 272 |
+
"259": "LABEL_259",
|
| 273 |
+
"260": "LABEL_260",
|
| 274 |
+
"261": "LABEL_261",
|
| 275 |
+
"262": "LABEL_262",
|
| 276 |
+
"263": "LABEL_263",
|
| 277 |
+
"264": "LABEL_264",
|
| 278 |
+
"265": "LABEL_265",
|
| 279 |
+
"266": "LABEL_266",
|
| 280 |
+
"267": "LABEL_267",
|
| 281 |
+
"268": "LABEL_268",
|
| 282 |
+
"269": "LABEL_269",
|
| 283 |
+
"270": "LABEL_270",
|
| 284 |
+
"271": "LABEL_271",
|
| 285 |
+
"272": "LABEL_272"
|
| 286 |
+
},
|
| 287 |
+
"initializer_range": 0.02,
|
| 288 |
+
"intermediate_size": 3072,
|
| 289 |
+
"label2id": {
|
| 290 |
+
"LABEL_0": 0,
|
| 291 |
+
"LABEL_1": 1,
|
| 292 |
+
"LABEL_10": 10,
|
| 293 |
+
"LABEL_100": 100,
|
| 294 |
+
"LABEL_101": 101,
|
| 295 |
+
"LABEL_102": 102,
|
| 296 |
+
"LABEL_103": 103,
|
| 297 |
+
"LABEL_104": 104,
|
| 298 |
+
"LABEL_105": 105,
|
| 299 |
+
"LABEL_106": 106,
|
| 300 |
+
"LABEL_107": 107,
|
| 301 |
+
"LABEL_108": 108,
|
| 302 |
+
"LABEL_109": 109,
|
| 303 |
+
"LABEL_11": 11,
|
| 304 |
+
"LABEL_110": 110,
|
| 305 |
+
"LABEL_111": 111,
|
| 306 |
+
"LABEL_112": 112,
|
| 307 |
+
"LABEL_113": 113,
|
| 308 |
+
"LABEL_114": 114,
|
| 309 |
+
"LABEL_115": 115,
|
| 310 |
+
"LABEL_116": 116,
|
| 311 |
+
"LABEL_117": 117,
|
| 312 |
+
"LABEL_118": 118,
|
| 313 |
+
"LABEL_119": 119,
|
| 314 |
+
"LABEL_12": 12,
|
| 315 |
+
"LABEL_120": 120,
|
| 316 |
+
"LABEL_121": 121,
|
| 317 |
+
"LABEL_122": 122,
|
| 318 |
+
"LABEL_123": 123,
|
| 319 |
+
"LABEL_124": 124,
|
| 320 |
+
"LABEL_125": 125,
|
| 321 |
+
"LABEL_126": 126,
|
| 322 |
+
"LABEL_127": 127,
|
| 323 |
+
"LABEL_128": 128,
|
| 324 |
+
"LABEL_129": 129,
|
| 325 |
+
"LABEL_13": 13,
|
| 326 |
+
"LABEL_130": 130,
|
| 327 |
+
"LABEL_131": 131,
|
| 328 |
+
"LABEL_132": 132,
|
| 329 |
+
"LABEL_133": 133,
|
| 330 |
+
"LABEL_134": 134,
|
| 331 |
+
"LABEL_135": 135,
|
| 332 |
+
"LABEL_136": 136,
|
| 333 |
+
"LABEL_137": 137,
|
| 334 |
+
"LABEL_138": 138,
|
| 335 |
+
"LABEL_139": 139,
|
| 336 |
+
"LABEL_14": 14,
|
| 337 |
+
"LABEL_140": 140,
|
| 338 |
+
"LABEL_141": 141,
|
| 339 |
+
"LABEL_142": 142,
|
| 340 |
+
"LABEL_143": 143,
|
| 341 |
+
"LABEL_144": 144,
|
| 342 |
+
"LABEL_145": 145,
|
| 343 |
+
"LABEL_146": 146,
|
| 344 |
+
"LABEL_147": 147,
|
| 345 |
+
"LABEL_148": 148,
|
| 346 |
+
"LABEL_149": 149,
|
| 347 |
+
"LABEL_15": 15,
|
| 348 |
+
"LABEL_150": 150,
|
| 349 |
+
"LABEL_151": 151,
|
| 350 |
+
"LABEL_152": 152,
|
| 351 |
+
"LABEL_153": 153,
|
| 352 |
+
"LABEL_154": 154,
|
| 353 |
+
"LABEL_155": 155,
|
| 354 |
+
"LABEL_156": 156,
|
| 355 |
+
"LABEL_157": 157,
|
| 356 |
+
"LABEL_158": 158,
|
| 357 |
+
"LABEL_159": 159,
|
| 358 |
+
"LABEL_16": 16,
|
| 359 |
+
"LABEL_160": 160,
|
| 360 |
+
"LABEL_161": 161,
|
| 361 |
+
"LABEL_162": 162,
|
| 362 |
+
"LABEL_163": 163,
|
| 363 |
+
"LABEL_164": 164,
|
| 364 |
+
"LABEL_165": 165,
|
| 365 |
+
"LABEL_166": 166,
|
| 366 |
+
"LABEL_167": 167,
|
| 367 |
+
"LABEL_168": 168,
|
| 368 |
+
"LABEL_169": 169,
|
| 369 |
+
"LABEL_17": 17,
|
| 370 |
+
"LABEL_170": 170,
|
| 371 |
+
"LABEL_171": 171,
|
| 372 |
+
"LABEL_172": 172,
|
| 373 |
+
"LABEL_173": 173,
|
| 374 |
+
"LABEL_174": 174,
|
| 375 |
+
"LABEL_175": 175,
|
| 376 |
+
"LABEL_176": 176,
|
| 377 |
+
"LABEL_177": 177,
|
| 378 |
+
"LABEL_178": 178,
|
| 379 |
+
"LABEL_179": 179,
|
| 380 |
+
"LABEL_18": 18,
|
| 381 |
+
"LABEL_180": 180,
|
| 382 |
+
"LABEL_181": 181,
|
| 383 |
+
"LABEL_182": 182,
|
| 384 |
+
"LABEL_183": 183,
|
| 385 |
+
"LABEL_184": 184,
|
| 386 |
+
"LABEL_185": 185,
|
| 387 |
+
"LABEL_186": 186,
|
| 388 |
+
"LABEL_187": 187,
|
| 389 |
+
"LABEL_188": 188,
|
| 390 |
+
"LABEL_189": 189,
|
| 391 |
+
"LABEL_19": 19,
|
| 392 |
+
"LABEL_190": 190,
|
| 393 |
+
"LABEL_191": 191,
|
| 394 |
+
"LABEL_192": 192,
|
| 395 |
+
"LABEL_193": 193,
|
| 396 |
+
"LABEL_194": 194,
|
| 397 |
+
"LABEL_195": 195,
|
| 398 |
+
"LABEL_196": 196,
|
| 399 |
+
"LABEL_197": 197,
|
| 400 |
+
"LABEL_198": 198,
|
| 401 |
+
"LABEL_199": 199,
|
| 402 |
+
"LABEL_2": 2,
|
| 403 |
+
"LABEL_20": 20,
|
| 404 |
+
"LABEL_200": 200,
|
| 405 |
+
"LABEL_201": 201,
|
| 406 |
+
"LABEL_202": 202,
|
| 407 |
+
"LABEL_203": 203,
|
| 408 |
+
"LABEL_204": 204,
|
| 409 |
+
"LABEL_205": 205,
|
| 410 |
+
"LABEL_206": 206,
|
| 411 |
+
"LABEL_207": 207,
|
| 412 |
+
"LABEL_208": 208,
|
| 413 |
+
"LABEL_209": 209,
|
| 414 |
+
"LABEL_21": 21,
|
| 415 |
+
"LABEL_210": 210,
|
| 416 |
+
"LABEL_211": 211,
|
| 417 |
+
"LABEL_212": 212,
|
| 418 |
+
"LABEL_213": 213,
|
| 419 |
+
"LABEL_214": 214,
|
| 420 |
+
"LABEL_215": 215,
|
| 421 |
+
"LABEL_216": 216,
|
| 422 |
+
"LABEL_217": 217,
|
| 423 |
+
"LABEL_218": 218,
|
| 424 |
+
"LABEL_219": 219,
|
| 425 |
+
"LABEL_22": 22,
|
| 426 |
+
"LABEL_220": 220,
|
| 427 |
+
"LABEL_221": 221,
|
| 428 |
+
"LABEL_222": 222,
|
| 429 |
+
"LABEL_223": 223,
|
| 430 |
+
"LABEL_224": 224,
|
| 431 |
+
"LABEL_225": 225,
|
| 432 |
+
"LABEL_226": 226,
|
| 433 |
+
"LABEL_227": 227,
|
| 434 |
+
"LABEL_228": 228,
|
| 435 |
+
"LABEL_229": 229,
|
| 436 |
+
"LABEL_23": 23,
|
| 437 |
+
"LABEL_230": 230,
|
| 438 |
+
"LABEL_231": 231,
|
| 439 |
+
"LABEL_232": 232,
|
| 440 |
+
"LABEL_233": 233,
|
| 441 |
+
"LABEL_234": 234,
|
| 442 |
+
"LABEL_235": 235,
|
| 443 |
+
"LABEL_236": 236,
|
| 444 |
+
"LABEL_237": 237,
|
| 445 |
+
"LABEL_238": 238,
|
| 446 |
+
"LABEL_239": 239,
|
| 447 |
+
"LABEL_24": 24,
|
| 448 |
+
"LABEL_240": 240,
|
| 449 |
+
"LABEL_241": 241,
|
| 450 |
+
"LABEL_242": 242,
|
| 451 |
+
"LABEL_243": 243,
|
| 452 |
+
"LABEL_244": 244,
|
| 453 |
+
"LABEL_245": 245,
|
| 454 |
+
"LABEL_246": 246,
|
| 455 |
+
"LABEL_247": 247,
|
| 456 |
+
"LABEL_248": 248,
|
| 457 |
+
"LABEL_249": 249,
|
| 458 |
+
"LABEL_25": 25,
|
| 459 |
+
"LABEL_250": 250,
|
| 460 |
+
"LABEL_251": 251,
|
| 461 |
+
"LABEL_252": 252,
|
| 462 |
+
"LABEL_253": 253,
|
| 463 |
+
"LABEL_254": 254,
|
| 464 |
+
"LABEL_255": 255,
|
| 465 |
+
"LABEL_256": 256,
|
| 466 |
+
"LABEL_257": 257,
|
| 467 |
+
"LABEL_258": 258,
|
| 468 |
+
"LABEL_259": 259,
|
| 469 |
+
"LABEL_26": 26,
|
| 470 |
+
"LABEL_260": 260,
|
| 471 |
+
"LABEL_261": 261,
|
| 472 |
+
"LABEL_262": 262,
|
| 473 |
+
"LABEL_263": 263,
|
| 474 |
+
"LABEL_264": 264,
|
| 475 |
+
"LABEL_265": 265,
|
| 476 |
+
"LABEL_266": 266,
|
| 477 |
+
"LABEL_267": 267,
|
| 478 |
+
"LABEL_268": 268,
|
| 479 |
+
"LABEL_269": 269,
|
| 480 |
+
"LABEL_27": 27,
|
| 481 |
+
"LABEL_270": 270,
|
| 482 |
+
"LABEL_271": 271,
|
| 483 |
+
"LABEL_272": 272,
|
| 484 |
+
"LABEL_28": 28,
|
| 485 |
+
"LABEL_29": 29,
|
| 486 |
+
"LABEL_3": 3,
|
| 487 |
+
"LABEL_30": 30,
|
| 488 |
+
"LABEL_31": 31,
|
| 489 |
+
"LABEL_32": 32,
|
| 490 |
+
"LABEL_33": 33,
|
| 491 |
+
"LABEL_34": 34,
|
| 492 |
+
"LABEL_35": 35,
|
| 493 |
+
"LABEL_36": 36,
|
| 494 |
+
"LABEL_37": 37,
|
| 495 |
+
"LABEL_38": 38,
|
| 496 |
+
"LABEL_39": 39,
|
| 497 |
+
"LABEL_4": 4,
|
| 498 |
+
"LABEL_40": 40,
|
| 499 |
+
"LABEL_41": 41,
|
| 500 |
+
"LABEL_42": 42,
|
| 501 |
+
"LABEL_43": 43,
|
| 502 |
+
"LABEL_44": 44,
|
| 503 |
+
"LABEL_45": 45,
|
| 504 |
+
"LABEL_46": 46,
|
| 505 |
+
"LABEL_47": 47,
|
| 506 |
+
"LABEL_48": 48,
|
| 507 |
+
"LABEL_49": 49,
|
| 508 |
+
"LABEL_5": 5,
|
| 509 |
+
"LABEL_50": 50,
|
| 510 |
+
"LABEL_51": 51,
|
| 511 |
+
"LABEL_52": 52,
|
| 512 |
+
"LABEL_53": 53,
|
| 513 |
+
"LABEL_54": 54,
|
| 514 |
+
"LABEL_55": 55,
|
| 515 |
+
"LABEL_56": 56,
|
| 516 |
+
"LABEL_57": 57,
|
| 517 |
+
"LABEL_58": 58,
|
| 518 |
+
"LABEL_59": 59,
|
| 519 |
+
"LABEL_6": 6,
|
| 520 |
+
"LABEL_60": 60,
|
| 521 |
+
"LABEL_61": 61,
|
| 522 |
+
"LABEL_62": 62,
|
| 523 |
+
"LABEL_63": 63,
|
| 524 |
+
"LABEL_64": 64,
|
| 525 |
+
"LABEL_65": 65,
|
| 526 |
+
"LABEL_66": 66,
|
| 527 |
+
"LABEL_67": 67,
|
| 528 |
+
"LABEL_68": 68,
|
| 529 |
+
"LABEL_69": 69,
|
| 530 |
+
"LABEL_7": 7,
|
| 531 |
+
"LABEL_70": 70,
|
| 532 |
+
"LABEL_71": 71,
|
| 533 |
+
"LABEL_72": 72,
|
| 534 |
+
"LABEL_73": 73,
|
| 535 |
+
"LABEL_74": 74,
|
| 536 |
+
"LABEL_75": 75,
|
| 537 |
+
"LABEL_76": 76,
|
| 538 |
+
"LABEL_77": 77,
|
| 539 |
+
"LABEL_78": 78,
|
| 540 |
+
"LABEL_79": 79,
|
| 541 |
+
"LABEL_8": 8,
|
| 542 |
+
"LABEL_80": 80,
|
| 543 |
+
"LABEL_81": 81,
|
| 544 |
+
"LABEL_82": 82,
|
| 545 |
+
"LABEL_83": 83,
|
| 546 |
+
"LABEL_84": 84,
|
| 547 |
+
"LABEL_85": 85,
|
| 548 |
+
"LABEL_86": 86,
|
| 549 |
+
"LABEL_87": 87,
|
| 550 |
+
"LABEL_88": 88,
|
| 551 |
+
"LABEL_89": 89,
|
| 552 |
+
"LABEL_9": 9,
|
| 553 |
+
"LABEL_90": 90,
|
| 554 |
+
"LABEL_91": 91,
|
| 555 |
+
"LABEL_92": 92,
|
| 556 |
+
"LABEL_93": 93,
|
| 557 |
+
"LABEL_94": 94,
|
| 558 |
+
"LABEL_95": 95,
|
| 559 |
+
"LABEL_96": 96,
|
| 560 |
+
"LABEL_97": 97,
|
| 561 |
+
"LABEL_98": 98,
|
| 562 |
+
"LABEL_99": 99
|
| 563 |
+
},
|
| 564 |
+
"layer_norm_eps": 1e-12,
|
| 565 |
+
"max_position_embeddings": 512,
|
| 566 |
+
"model_type": "bert",
|
| 567 |
+
"num_attention_heads": 12,
|
| 568 |
+
"num_hidden_layers": 12,
|
| 569 |
+
"pad_token_id": 0,
|
| 570 |
+
"position_embedding_type": "absolute",
|
| 571 |
+
"torch_dtype": "float32",
|
| 572 |
+
"transformers_version": "4.47.0",
|
| 573 |
+
"type_vocab_size": 2,
|
| 574 |
+
"use_cache": true,
|
| 575 |
+
"vocab_size": 30522
|
| 576 |
+
}
|
Trained Model/chatbot_model/model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:da4b23741fbf40b8ee8f054fb977dabf7ec19fbf607330b1778949d53c6d2315
|
| 3 |
+
size 438792244
|
Trained Model/chatbot_model/special_tokens_map.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cls_token": "[CLS]",
|
| 3 |
+
"mask_token": "[MASK]",
|
| 4 |
+
"pad_token": "[PAD]",
|
| 5 |
+
"sep_token": "[SEP]",
|
| 6 |
+
"unk_token": "[UNK]"
|
| 7 |
+
}
|
Trained Model/chatbot_model/tokenizer_config.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"added_tokens_decoder": {
|
| 3 |
+
"0": {
|
| 4 |
+
"content": "[PAD]",
|
| 5 |
+
"lstrip": false,
|
| 6 |
+
"normalized": false,
|
| 7 |
+
"rstrip": false,
|
| 8 |
+
"single_word": false,
|
| 9 |
+
"special": true
|
| 10 |
+
},
|
| 11 |
+
"100": {
|
| 12 |
+
"content": "[UNK]",
|
| 13 |
+
"lstrip": false,
|
| 14 |
+
"normalized": false,
|
| 15 |
+
"rstrip": false,
|
| 16 |
+
"single_word": false,
|
| 17 |
+
"special": true
|
| 18 |
+
},
|
| 19 |
+
"101": {
|
| 20 |
+
"content": "[CLS]",
|
| 21 |
+
"lstrip": false,
|
| 22 |
+
"normalized": false,
|
| 23 |
+
"rstrip": false,
|
| 24 |
+
"single_word": false,
|
| 25 |
+
"special": true
|
| 26 |
+
},
|
| 27 |
+
"102": {
|
| 28 |
+
"content": "[SEP]",
|
| 29 |
+
"lstrip": false,
|
| 30 |
+
"normalized": false,
|
| 31 |
+
"rstrip": false,
|
| 32 |
+
"single_word": false,
|
| 33 |
+
"special": true
|
| 34 |
+
},
|
| 35 |
+
"103": {
|
| 36 |
+
"content": "[MASK]",
|
| 37 |
+
"lstrip": false,
|
| 38 |
+
"normalized": false,
|
| 39 |
+
"rstrip": false,
|
| 40 |
+
"single_word": false,
|
| 41 |
+
"special": true
|
| 42 |
+
}
|
| 43 |
+
},
|
| 44 |
+
"clean_up_tokenization_spaces": true,
|
| 45 |
+
"cls_token": "[CLS]",
|
| 46 |
+
"do_basic_tokenize": true,
|
| 47 |
+
"do_lower_case": true,
|
| 48 |
+
"extra_special_tokens": {},
|
| 49 |
+
"mask_token": "[MASK]",
|
| 50 |
+
"model_max_length": 512,
|
| 51 |
+
"never_split": null,
|
| 52 |
+
"pad_token": "[PAD]",
|
| 53 |
+
"sep_token": "[SEP]",
|
| 54 |
+
"strip_accents": null,
|
| 55 |
+
"tokenize_chinese_chars": true,
|
| 56 |
+
"tokenizer_class": "BertTokenizer",
|
| 57 |
+
"unk_token": "[UNK]"
|
| 58 |
+
}
|
Trained Model/chatbot_model/vocab.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
chat_history.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
["[2025-03-15 12:02:53] You: Hi", "[2025-03-15 12:02:53] Bot: Hi there"]
|
chatbot-training.ipynb
ADDED
|
@@ -0,0 +1,659 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 1,
|
| 6 |
+
"metadata": {
|
| 7 |
+
"execution": {
|
| 8 |
+
"iopub.execute_input": "2025-03-14T06:02:34.158602Z",
|
| 9 |
+
"iopub.status.busy": "2025-03-14T06:02:34.158188Z",
|
| 10 |
+
"iopub.status.idle": "2025-03-14T06:02:34.361502Z",
|
| 11 |
+
"shell.execute_reply": "2025-03-14T06:02:34.360367Z",
|
| 12 |
+
"shell.execute_reply.started": "2025-03-14T06:02:34.158571Z"
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
"outputs": [],
|
| 16 |
+
"source": [
|
| 17 |
+
"# Importing HuggingFace Token\n",
|
| 18 |
+
"from kaggle_secrets import UserSecretsClient\n",
|
| 19 |
+
"user_secrets = UserSecretsClient()\n",
|
| 20 |
+
"secret_value_0 = user_secrets.get_secret(\"HF_Token\")"
|
| 21 |
+
]
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"cell_type": "code",
|
| 25 |
+
"execution_count": 2,
|
| 26 |
+
"metadata": {
|
| 27 |
+
"_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
|
| 28 |
+
"_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
|
| 29 |
+
"execution": {
|
| 30 |
+
"iopub.execute_input": "2025-03-14T06:02:34.363000Z",
|
| 31 |
+
"iopub.status.busy": "2025-03-14T06:02:34.362718Z",
|
| 32 |
+
"iopub.status.idle": "2025-03-14T06:12:26.502668Z",
|
| 33 |
+
"shell.execute_reply": "2025-03-14T06:12:26.501655Z",
|
| 34 |
+
"shell.execute_reply.started": "2025-03-14T06:02:34.362977Z"
|
| 35 |
+
}
|
| 36 |
+
},
|
| 37 |
+
"outputs": [
|
| 38 |
+
{
|
| 39 |
+
"name": "stdout",
|
| 40 |
+
"output_type": "stream",
|
| 41 |
+
"text": [
|
| 42 |
+
"Using device: cuda\n"
|
| 43 |
+
]
|
| 44 |
+
},
|
| 45 |
+
{
|
| 46 |
+
"data": {
|
| 47 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 48 |
+
"model_id": "7824a999787d4bd1b195d7d91c77b73d",
|
| 49 |
+
"version_major": 2,
|
| 50 |
+
"version_minor": 0
|
| 51 |
+
},
|
| 52 |
+
"text/plain": [
|
| 53 |
+
"tokenizer_config.json: 0%| | 0.00/48.0 [00:00<?, ?B/s]"
|
| 54 |
+
]
|
| 55 |
+
},
|
| 56 |
+
"metadata": {},
|
| 57 |
+
"output_type": "display_data"
|
| 58 |
+
},
|
| 59 |
+
{
|
| 60 |
+
"data": {
|
| 61 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 62 |
+
"model_id": "d429c8c5a09d44acabf466ce018c6bcd",
|
| 63 |
+
"version_major": 2,
|
| 64 |
+
"version_minor": 0
|
| 65 |
+
},
|
| 66 |
+
"text/plain": [
|
| 67 |
+
"vocab.txt: 0%| | 0.00/232k [00:00<?, ?B/s]"
|
| 68 |
+
]
|
| 69 |
+
},
|
| 70 |
+
"metadata": {},
|
| 71 |
+
"output_type": "display_data"
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"data": {
|
| 75 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 76 |
+
"model_id": "0a455715281a4842b2b84fb392994a9a",
|
| 77 |
+
"version_major": 2,
|
| 78 |
+
"version_minor": 0
|
| 79 |
+
},
|
| 80 |
+
"text/plain": [
|
| 81 |
+
"tokenizer.json: 0%| | 0.00/466k [00:00<?, ?B/s]"
|
| 82 |
+
]
|
| 83 |
+
},
|
| 84 |
+
"metadata": {},
|
| 85 |
+
"output_type": "display_data"
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"data": {
|
| 89 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 90 |
+
"model_id": "cb3a2c53b638478c9aebbcb91ba50d1a",
|
| 91 |
+
"version_major": 2,
|
| 92 |
+
"version_minor": 0
|
| 93 |
+
},
|
| 94 |
+
"text/plain": [
|
| 95 |
+
"config.json: 0%| | 0.00/570 [00:00<?, ?B/s]"
|
| 96 |
+
]
|
| 97 |
+
},
|
| 98 |
+
"metadata": {},
|
| 99 |
+
"output_type": "display_data"
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"data": {
|
| 103 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 104 |
+
"model_id": "e7ab9075f9a542439774f2c2fba440a1",
|
| 105 |
+
"version_major": 2,
|
| 106 |
+
"version_minor": 0
|
| 107 |
+
},
|
| 108 |
+
"text/plain": [
|
| 109 |
+
"model.safetensors: 0%| | 0.00/440M [00:00<?, ?B/s]"
|
| 110 |
+
]
|
| 111 |
+
},
|
| 112 |
+
"metadata": {},
|
| 113 |
+
"output_type": "display_data"
|
| 114 |
+
},
|
| 115 |
+
{
|
| 116 |
+
"name": "stderr",
|
| 117 |
+
"output_type": "stream",
|
| 118 |
+
"text": [
|
| 119 |
+
"Some weights of BertForSequenceClassification were not initialized from the model checkpoint at bert-base-uncased and are newly initialized: ['classifier.bias', 'classifier.weight']\n",
|
| 120 |
+
"You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n"
|
| 121 |
+
]
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"name": "stdout",
|
| 125 |
+
"output_type": "stream",
|
| 126 |
+
"text": [
|
| 127 |
+
"Epoch 1/90 - Average Loss: 5.6662\n",
|
| 128 |
+
"Epoch 2/90 - Average Loss: 5.6118\n",
|
| 129 |
+
"Epoch 3/90 - Average Loss: 5.5608\n",
|
| 130 |
+
"Epoch 4/90 - Average Loss: 5.4642\n",
|
| 131 |
+
"Epoch 5/90 - Average Loss: 5.3513\n",
|
| 132 |
+
"Epoch 6/90 - Average Loss: 5.1811\n",
|
| 133 |
+
"Epoch 7/90 - Average Loss: 5.0176\n",
|
| 134 |
+
"Epoch 8/90 - Average Loss: 4.8236\n",
|
| 135 |
+
"Epoch 9/90 - Average Loss: 4.6535\n",
|
| 136 |
+
"Epoch 10/90 - Average Loss: 4.4724\n",
|
| 137 |
+
"Epoch 11/90 - Average Loss: 4.3279\n",
|
| 138 |
+
"Epoch 12/90 - Average Loss: 4.1504\n",
|
| 139 |
+
"Epoch 13/90 - Average Loss: 4.0176\n",
|
| 140 |
+
"Epoch 14/90 - Average Loss: 3.8612\n",
|
| 141 |
+
"Epoch 15/90 - Average Loss: 3.7189\n",
|
| 142 |
+
"Epoch 16/90 - Average Loss: 3.5748\n",
|
| 143 |
+
"Epoch 17/90 - Average Loss: 3.4296\n",
|
| 144 |
+
"Epoch 18/90 - Average Loss: 3.3193\n",
|
| 145 |
+
"Epoch 19/90 - Average Loss: 3.1704\n",
|
| 146 |
+
"Epoch 20/90 - Average Loss: 3.0567\n",
|
| 147 |
+
"Epoch 21/90 - Average Loss: 2.9273\n",
|
| 148 |
+
"Epoch 22/90 - Average Loss: 2.7933\n",
|
| 149 |
+
"Epoch 23/90 - Average Loss: 2.6832\n",
|
| 150 |
+
"Epoch 24/90 - Average Loss: 2.5414\n",
|
| 151 |
+
"Epoch 25/90 - Average Loss: 2.4337\n",
|
| 152 |
+
"Epoch 26/90 - Average Loss: 2.3230\n",
|
| 153 |
+
"Epoch 27/90 - Average Loss: 2.2094\n",
|
| 154 |
+
"Epoch 28/90 - Average Loss: 2.0913\n",
|
| 155 |
+
"Epoch 29/90 - Average Loss: 1.9798\n",
|
| 156 |
+
"Epoch 30/90 - Average Loss: 1.8935\n",
|
| 157 |
+
"Epoch 31/90 - Average Loss: 1.7755\n",
|
| 158 |
+
"Epoch 32/90 - Average Loss: 1.6802\n",
|
| 159 |
+
"Epoch 33/90 - Average Loss: 1.5814\n",
|
| 160 |
+
"Epoch 34/90 - Average Loss: 1.5013\n",
|
| 161 |
+
"Epoch 35/90 - Average Loss: 1.4134\n",
|
| 162 |
+
"Epoch 36/90 - Average Loss: 1.3328\n",
|
| 163 |
+
"Epoch 37/90 - Average Loss: 1.2458\n",
|
| 164 |
+
"Epoch 38/90 - Average Loss: 1.1845\n",
|
| 165 |
+
"Epoch 39/90 - Average Loss: 1.1036\n",
|
| 166 |
+
"Epoch 40/90 - Average Loss: 1.0327\n",
|
| 167 |
+
"Epoch 41/90 - Average Loss: 0.9679\n",
|
| 168 |
+
"Epoch 42/90 - Average Loss: 0.9215\n",
|
| 169 |
+
"Epoch 43/90 - Average Loss: 0.8682\n",
|
| 170 |
+
"Epoch 44/90 - Average Loss: 0.8089\n",
|
| 171 |
+
"Epoch 45/90 - Average Loss: 0.7654\n",
|
| 172 |
+
"Epoch 46/90 - Average Loss: 0.7181\n",
|
| 173 |
+
"Epoch 47/90 - Average Loss: 0.6696\n",
|
| 174 |
+
"Epoch 48/90 - Average Loss: 0.6318\n",
|
| 175 |
+
"Epoch 49/90 - Average Loss: 0.5918\n",
|
| 176 |
+
"Epoch 50/90 - Average Loss: 0.5542\n",
|
| 177 |
+
"Epoch 51/90 - Average Loss: 0.5274\n",
|
| 178 |
+
"Epoch 52/90 - Average Loss: 0.4944\n",
|
| 179 |
+
"Epoch 53/90 - Average Loss: 0.4631\n",
|
| 180 |
+
"Epoch 54/90 - Average Loss: 0.4428\n",
|
| 181 |
+
"Epoch 55/90 - Average Loss: 0.4125\n",
|
| 182 |
+
"Epoch 56/90 - Average Loss: 0.3950\n",
|
| 183 |
+
"Epoch 57/90 - Average Loss: 0.3698\n",
|
| 184 |
+
"Epoch 58/90 - Average Loss: 0.3491\n",
|
| 185 |
+
"Epoch 59/90 - Average Loss: 0.3309\n",
|
| 186 |
+
"Epoch 60/90 - Average Loss: 0.3142\n",
|
| 187 |
+
"Epoch 61/90 - Average Loss: 0.2992\n",
|
| 188 |
+
"Epoch 62/90 - Average Loss: 0.2829\n",
|
| 189 |
+
"Epoch 63/90 - Average Loss: 0.2706\n",
|
| 190 |
+
"Epoch 64/90 - Average Loss: 0.2552\n",
|
| 191 |
+
"Epoch 65/90 - Average Loss: 0.2451\n",
|
| 192 |
+
"Epoch 66/90 - Average Loss: 0.2355\n",
|
| 193 |
+
"Epoch 67/90 - Average Loss: 0.2219\n",
|
| 194 |
+
"Epoch 68/90 - Average Loss: 0.2122\n",
|
| 195 |
+
"Epoch 69/90 - Average Loss: 0.2063\n",
|
| 196 |
+
"Epoch 70/90 - Average Loss: 0.1950\n",
|
| 197 |
+
"Epoch 71/90 - Average Loss: 0.1860\n",
|
| 198 |
+
"Epoch 72/90 - Average Loss: 0.1758\n",
|
| 199 |
+
"Epoch 73/90 - Average Loss: 0.1675\n",
|
| 200 |
+
"Epoch 74/90 - Average Loss: 0.1630\n",
|
| 201 |
+
"Epoch 75/90 - Average Loss: 0.1607\n",
|
| 202 |
+
"Epoch 76/90 - Average Loss: 0.1525\n",
|
| 203 |
+
"Epoch 77/90 - Average Loss: 0.1441\n",
|
| 204 |
+
"Epoch 78/90 - Average Loss: 0.1364\n",
|
| 205 |
+
"Epoch 79/90 - Average Loss: 0.1326\n",
|
| 206 |
+
"Epoch 80/90 - Average Loss: 0.1293\n",
|
| 207 |
+
"Epoch 81/90 - Average Loss: 0.1269\n",
|
| 208 |
+
"Epoch 82/90 - Average Loss: 0.1199\n",
|
| 209 |
+
"Epoch 83/90 - Average Loss: 0.1129\n",
|
| 210 |
+
"Epoch 84/90 - Average Loss: 0.1095\n",
|
| 211 |
+
"Epoch 85/90 - Average Loss: 0.1076\n",
|
| 212 |
+
"Epoch 86/90 - Average Loss: 0.1030\n",
|
| 213 |
+
"Epoch 87/90 - Average Loss: 0.0984\n",
|
| 214 |
+
"Epoch 88/90 - Average Loss: 0.0944\n",
|
| 215 |
+
"Epoch 89/90 - Average Loss: 0.0919\n",
|
| 216 |
+
"Epoch 90/90 - Average Loss: 0.0880\n"
|
| 217 |
+
]
|
| 218 |
+
}
|
| 219 |
+
],
|
| 220 |
+
"source": [
|
| 221 |
+
"# Importing Libraries\n",
|
| 222 |
+
"import json\n",
|
| 223 |
+
"import torch\n",
|
| 224 |
+
"import os\n",
|
| 225 |
+
"import torch.nn as nn\n",
|
| 226 |
+
"import torch.optim as optim\n",
|
| 227 |
+
"from torch.utils.data import Dataset, DataLoader\n",
|
| 228 |
+
"from transformers import BertTokenizer, BertForSequenceClassification\n",
|
| 229 |
+
"import torch.nn.functional as F\n",
|
| 230 |
+
"from sklearn.utils.class_weight import compute_class_weight\n",
|
| 231 |
+
"import numpy as np\n",
|
| 232 |
+
"import random\n",
|
| 233 |
+
"\n",
|
| 234 |
+
"# Load JSON data\n",
|
| 235 |
+
"with open(\"/kaggle/input/intents1/intents.json\", \"r\") as file:\n",
|
| 236 |
+
" intents = json.load(file)\n",
|
| 237 |
+
"\n",
|
| 238 |
+
"# Remove duplicate intent tags\n",
|
| 239 |
+
"unique_intents = []\n",
|
| 240 |
+
"seen_tags = set()\n",
|
| 241 |
+
"for intent in intents:\n",
|
| 242 |
+
" if intent[\"tag\"] not in seen_tags:\n",
|
| 243 |
+
" unique_intents.append(intent)\n",
|
| 244 |
+
" seen_tags.add(intent[\"tag\"])\n",
|
| 245 |
+
"\n",
|
| 246 |
+
"# Ensure unique intent tags\n",
|
| 247 |
+
"intent_tags = [intent[\"tag\"] for intent in unique_intents]\n",
|
| 248 |
+
"num_labels = len(intent_tags)\n",
|
| 249 |
+
"\n",
|
| 250 |
+
"# Create label mapping\n",
|
| 251 |
+
"label_map = {tag: i for i, tag in enumerate(intent_tags)}\n",
|
| 252 |
+
"\n",
|
| 253 |
+
"# Check for GPU availability\n",
|
| 254 |
+
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
|
| 255 |
+
"print(f\"Using device: {device}\")\n",
|
| 256 |
+
"\n",
|
| 257 |
+
"# Load BERT tokenizer & model\n",
|
| 258 |
+
"tokenizer = BertTokenizer.from_pretrained('bert-base-uncased', token=secret_value_0)\n",
|
| 259 |
+
"model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=num_labels, token=secret_value_0)\n",
|
| 260 |
+
"model.to(device)\n",
|
| 261 |
+
"\n",
|
| 262 |
+
"# Define Dataset\n",
|
| 263 |
+
"class IntentDataset(Dataset):\n",
|
| 264 |
+
" def __init__(self, intents, tokenizer):\n",
|
| 265 |
+
" self.texts = []\n",
|
| 266 |
+
" self.labels = []\n",
|
| 267 |
+
" self.label_map = label_map\n",
|
| 268 |
+
"\n",
|
| 269 |
+
" for intent in intents:\n",
|
| 270 |
+
" for pattern in intent[\"patterns\"]:\n",
|
| 271 |
+
" self.texts.append(pattern)\n",
|
| 272 |
+
" self.labels.append(self.label_map[intent[\"tag\"]])\n",
|
| 273 |
+
"\n",
|
| 274 |
+
" def __len__(self):\n",
|
| 275 |
+
" return len(self.labels)\n",
|
| 276 |
+
"\n",
|
| 277 |
+
" def __getitem__(self, idx):\n",
|
| 278 |
+
" text = self.texts[idx]\n",
|
| 279 |
+
" label = torch.tensor(self.labels[idx], dtype=torch.long).to(device)\n",
|
| 280 |
+
"\n",
|
| 281 |
+
" encoding = tokenizer(text, truncation=True, padding=\"max_length\", max_length=32, return_tensors=\"pt\")\n",
|
| 282 |
+
" item = {key: val.squeeze(0).to(device) for key, val in encoding.items()} # Remove batch dim\n",
|
| 283 |
+
"\n",
|
| 284 |
+
" return item, label\n",
|
| 285 |
+
"\n",
|
| 286 |
+
"# Load dataset & dataloader\n",
|
| 287 |
+
"dataset = IntentDataset(unique_intents, tokenizer)\n",
|
| 288 |
+
"dataloader = DataLoader(dataset, batch_size=16, shuffle=True) # Increased batch size\n",
|
| 289 |
+
"\n",
|
| 290 |
+
"# Compute class weights\n",
|
| 291 |
+
"labels = [dataset.label_map[intent[\"tag\"]] for intent in unique_intents for _ in intent[\"patterns\"]]\n",
|
| 292 |
+
"class_weights = compute_class_weight(\"balanced\", classes=np.unique(labels), y=labels)\n",
|
| 293 |
+
"class_weights = torch.tensor(class_weights, dtype=torch.float).to(device)\n",
|
| 294 |
+
"\n",
|
| 295 |
+
"# Define optimizer & loss function\n",
|
| 296 |
+
"optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5) # Lower learning rate\n",
|
| 297 |
+
"loss_fn = torch.nn.CrossEntropyLoss(weight=class_weights) # Use class-weighted loss\n",
|
| 298 |
+
"\n",
|
| 299 |
+
"# Training loop\n",
|
| 300 |
+
"epochs = 90 # Increased from 20 to 50 for better training\n",
|
| 301 |
+
"model.train()\n",
|
| 302 |
+
"\n",
|
| 303 |
+
"for epoch in range(epochs):\n",
|
| 304 |
+
" total_loss = 0\n",
|
| 305 |
+
" for batch in dataloader:\n",
|
| 306 |
+
" inputs, labels = batch\n",
|
| 307 |
+
" optimizer.zero_grad()\n",
|
| 308 |
+
" outputs = model(**inputs)\n",
|
| 309 |
+
" loss = loss_fn(outputs.logits, labels)\n",
|
| 310 |
+
" loss.backward()\n",
|
| 311 |
+
" optimizer.step()\n",
|
| 312 |
+
" total_loss += loss.item()\n",
|
| 313 |
+
" \n",
|
| 314 |
+
" avg_loss = total_loss / len(dataloader)\n",
|
| 315 |
+
" print(f\"Epoch {epoch+1}/{epochs} - Average Loss: {avg_loss:.4f}\")\n",
|
| 316 |
+
"\n",
|
| 317 |
+
"# Function to predict intent\n",
|
| 318 |
+
"def predict_intent(user_input):\n",
|
| 319 |
+
" model.eval()\n",
|
| 320 |
+
" inputs = tokenizer(user_input, return_tensors=\"pt\", truncation=True, padding=True, max_length=32)\n",
|
| 321 |
+
" inputs = {key: val.to(device) for key, val in inputs.items()} # Move input to GPU\n",
|
| 322 |
+
"\n",
|
| 323 |
+
" with torch.no_grad():\n",
|
| 324 |
+
" outputs = model(**inputs)\n",
|
| 325 |
+
"\n",
|
| 326 |
+
" predicted_label = torch.argmax(outputs.logits).item()\n",
|
| 327 |
+
" \n",
|
| 328 |
+
" # Map predicted label to intent\n",
|
| 329 |
+
" intent_tag = list(dataset.label_map.keys())[predicted_label]\n",
|
| 330 |
+
"\n",
|
| 331 |
+
" # Fetch a random response for the predicted intent\n",
|
| 332 |
+
" for intent in unique_intents:\n",
|
| 333 |
+
" if intent[\"tag\"] == intent_tag:\n",
|
| 334 |
+
" return random.choice(intent[\"responses\"])"
|
| 335 |
+
]
|
| 336 |
+
},
|
| 337 |
+
{
|
| 338 |
+
"cell_type": "code",
|
| 339 |
+
"execution_count": 3,
|
| 340 |
+
"metadata": {
|
| 341 |
+
"execution": {
|
| 342 |
+
"iopub.execute_input": "2025-03-14T06:12:26.505510Z",
|
| 343 |
+
"iopub.status.busy": "2025-03-14T06:12:26.504747Z",
|
| 344 |
+
"iopub.status.idle": "2025-03-14T06:12:26.934471Z",
|
| 345 |
+
"shell.execute_reply": "2025-03-14T06:12:26.933341Z",
|
| 346 |
+
"shell.execute_reply.started": "2025-03-14T06:12:26.505474Z"
|
| 347 |
+
}
|
| 348 |
+
},
|
| 349 |
+
"outputs": [
|
| 350 |
+
{
|
| 351 |
+
"name": "stdout",
|
| 352 |
+
"output_type": "stream",
|
| 353 |
+
"text": [
|
| 354 |
+
"Test Accuracy: 1.0000\n"
|
| 355 |
+
]
|
| 356 |
+
}
|
| 357 |
+
],
|
| 358 |
+
"source": [
|
| 359 |
+
"import torch\n",
|
| 360 |
+
"from torch.utils.data import random_split\n",
|
| 361 |
+
"from sklearn.metrics import accuracy_score\n",
|
| 362 |
+
"\n",
|
| 363 |
+
"# Split dataset into training (80%) and test (20%) sets\n",
|
| 364 |
+
"train_size = int(0.8 * len(dataset))\n",
|
| 365 |
+
"test_size = len(dataset) - train_size\n",
|
| 366 |
+
"train_dataset, test_dataset = random_split(dataset, [train_size, test_size])\n",
|
| 367 |
+
"\n",
|
| 368 |
+
"# Create test dataloader\n",
|
| 369 |
+
"test_dataloader = DataLoader(test_dataset, batch_size=16, shuffle=False)\n",
|
| 370 |
+
"\n",
|
| 371 |
+
"# Function to evaluate model accuracy\n",
|
| 372 |
+
"def evaluate_model(model, test_dataloader):\n",
|
| 373 |
+
" model.eval()\n",
|
| 374 |
+
" all_preds, all_labels = [], []\n",
|
| 375 |
+
" \n",
|
| 376 |
+
" with torch.no_grad():\n",
|
| 377 |
+
" for batch in test_dataloader:\n",
|
| 378 |
+
" inputs, labels = batch\n",
|
| 379 |
+
" outputs = model(**inputs)\n",
|
| 380 |
+
" preds = torch.argmax(outputs.logits, dim=1)\n",
|
| 381 |
+
"\n",
|
| 382 |
+
" all_preds.extend(preds.cpu().numpy())\n",
|
| 383 |
+
" all_labels.extend(labels.cpu().numpy())\n",
|
| 384 |
+
"\n",
|
| 385 |
+
" accuracy = accuracy_score(all_labels, all_preds)\n",
|
| 386 |
+
" return accuracy\n",
|
| 387 |
+
"\n",
|
| 388 |
+
"# Compute accuracy\n",
|
| 389 |
+
"test_accuracy = evaluate_model(model, test_dataloader)\n",
|
| 390 |
+
"print(f\"Test Accuracy: {test_accuracy:.4f}\")\n"
|
| 391 |
+
]
|
| 392 |
+
},
|
| 393 |
+
{
|
| 394 |
+
"cell_type": "code",
|
| 395 |
+
"execution_count": 4,
|
| 396 |
+
"metadata": {
|
| 397 |
+
"execution": {
|
| 398 |
+
"iopub.execute_input": "2025-03-14T06:12:26.936897Z",
|
| 399 |
+
"iopub.status.busy": "2025-03-14T06:12:26.936431Z",
|
| 400 |
+
"iopub.status.idle": "2025-03-14T06:12:28.400809Z",
|
| 401 |
+
"shell.execute_reply": "2025-03-14T06:12:28.399868Z",
|
| 402 |
+
"shell.execute_reply.started": "2025-03-14T06:12:26.936850Z"
|
| 403 |
+
}
|
| 404 |
+
},
|
| 405 |
+
"outputs": [
|
| 406 |
+
{
|
| 407 |
+
"name": "stdout",
|
| 408 |
+
"output_type": "stream",
|
| 409 |
+
"text": [
|
| 410 |
+
"Training Accuracy: 0.9939\n"
|
| 411 |
+
]
|
| 412 |
+
}
|
| 413 |
+
],
|
| 414 |
+
"source": [
|
| 415 |
+
"def evaluate_train_accuracy(model, train_dataloader):\n",
|
| 416 |
+
" model.eval()\n",
|
| 417 |
+
" all_preds, all_labels = [], []\n",
|
| 418 |
+
" \n",
|
| 419 |
+
" with torch.no_grad():\n",
|
| 420 |
+
" for batch in train_dataloader:\n",
|
| 421 |
+
" inputs, labels = batch\n",
|
| 422 |
+
" outputs = model(**inputs)\n",
|
| 423 |
+
" preds = torch.argmax(outputs.logits, dim=1)\n",
|
| 424 |
+
"\n",
|
| 425 |
+
" all_preds.extend(preds.cpu().numpy())\n",
|
| 426 |
+
" all_labels.extend(labels.cpu().numpy())\n",
|
| 427 |
+
"\n",
|
| 428 |
+
" accuracy = accuracy_score(all_labels, all_preds)\n",
|
| 429 |
+
" return accuracy\n",
|
| 430 |
+
"\n",
|
| 431 |
+
"# Compute Training Accuracy\n",
|
| 432 |
+
"train_dataloader = DataLoader(train_dataset, batch_size=16, shuffle=False)\n",
|
| 433 |
+
"train_accuracy = evaluate_train_accuracy(model, train_dataloader)\n",
|
| 434 |
+
"print(f\"Training Accuracy: {train_accuracy:.4f}\")\n"
|
| 435 |
+
]
|
| 436 |
+
},
|
| 437 |
+
{
|
| 438 |
+
"cell_type": "code",
|
| 439 |
+
"execution_count": 5,
|
| 440 |
+
"metadata": {
|
| 441 |
+
"execution": {
|
| 442 |
+
"iopub.execute_input": "2025-03-14T06:12:28.401902Z",
|
| 443 |
+
"iopub.status.busy": "2025-03-14T06:12:28.401654Z",
|
| 444 |
+
"iopub.status.idle": "2025-03-14T06:20:24.794528Z",
|
| 445 |
+
"shell.execute_reply": "2025-03-14T06:20:24.793362Z",
|
| 446 |
+
"shell.execute_reply.started": "2025-03-14T06:12:28.401882Z"
|
| 447 |
+
}
|
| 448 |
+
},
|
| 449 |
+
"outputs": [
|
| 450 |
+
{
|
| 451 |
+
"data": {
|
| 452 |
+
"image/png": "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bUbPnj2NmjVrGhkZGSZWXnYNGDDAqFq1qrFw4ULj8OHDxvfff28EBAQYL7zwgr2NvpPCoQBURN577z2jevXqhouLi9GmTRtj7dq1ZpdUbgD5Pj777DN7m4yMDOOZZ54xKlSoYHh4eBi9e/c2Tp06ZV7R5dD/BiB9J+b48ccfjUaNGhmurq5GeHi4MX369DyvW61W45VXXjECAwMNV1dXo1OnTsbevXtNqrbsS01NNYYNG2ZUr17dcHNzM2rVqmW89NJLRlZWlr2NvpPCYTGMvy0vKSIiIlIOaAyQiIiIlDsKQCIiIlLuKACJiIhIuaMAJCIiIuWOApCIiIiUOwpAIiIiUu4oAImIiEi5owAkInIFFouF+fPnm12GiBQBBSARKZEGDhyIxWK57NGlSxezSxORMsDJ7AJERK6kS5cufPbZZ3mOubq6mlSNiJQl6gESkRLL1dWVoKCgPI8KFSoAtttTH3zwAV27dsXd3Z1atWoxd+7cPOdv376dO+64A3d3d/z9/XniiSc4f/58njaffvopDRs2xNXVlSpVqjB48OA8ryclJdG7d288PDwICwtjwYIF9tfOnTvHgw8+SKVKlXB3dycsLOyywCYiJZMCkIiUWq+88gp9+/bljz/+4MEHH+SBBx5g9+7dAKSnp9O5c2cqVKjAhg0bmDNnDsuWLcsTcD744AOeffZZnnjiCbZv386CBQuoU6dOnvcYO3Ys999/P9u2bePuu+/mwQcf5OzZs/b337VrF4sXL2b37t188MEHBAQEFN8PQERuntm7sYqI5GfAgAGGo6Oj4enpmefx2muvGYZhGIDx1FNP5TknIiLCePrppw3DMIzp06cbFSpUMM6fP29//aeffjIcHByM+Ph4wzAMIzg42HjppZeuWANgvPzyy/bn58+fNwBj8eLFhmEYxj333GMMGjSocD6wiBQrjQESkRLr9ttv54MPPshzrGLFiva/R0ZG5nktMjKSrVu3ArB7926aNm2Kp6en/fX27dtjtVrZu3cvFouFkydP0qlTp6vW0KRJE/vfPT098fHxITExEYCnn36avn37snnzZu666y569epFu3btbuqzikjxUgASkRLL09PzsltShcXd3f262jk7O+d5brFYsFqtAHTt2pWjR4+yaNEili5dSqdOnXj22Wd56623Cr1eESlcGgMkIqXW2rVrL3tev359AOrXr88ff/xBenq6/fXVq1fj4OBAvXr18Pb2JjQ0lJiYmALVUKlSJQYMGMDXX3/N5MmTmT59eoGuJyLFQz1AIlJiZWVlER8fn+eYk5OTfaDxnDlzaNWqFR06dOCbb75h/fr1fPLJJwA8+OCDjB49mgEDBjBmzBhOnz7NkCFDePjhhwkMDARgzJgxPPXUU1SuXJmuXbuSlpbG6tWrGTJkyHXVN2rUKFq2bEnDhg3Jyspi4cKF9gAmIiWbApCIlFhLliyhSpUqeY7Vq1ePPXv2ALYZWjNnzuSZZ56hSpUqfPvttzRo0AAADw8Pfv75Z4YNG0br1q3x8PCgb9++vP322/ZrDRgwgMzMTN555x3+/e9/ExAQwL333nvd9bm4uDBy5EiOHDmCu7s7t9xyCzNnziyETy4iRc1iGIZhdhEiIjfKYrEwb948evXqZXYpIlIKaQyQiIiIlDsKQCIiIlLuaAyQiJRKunsvIgWhHiAREREpdxSAREREpNxRABIREZFyRwFIREREyh0FIBERESl3FIBERESk3FEAEhERkXJHAUhERETKHQUgERERKXf+H7ZokyJnjmeEAAAAAElFTkSuQmCC\n",
|
| 453 |
+
"text/plain": [
|
| 454 |
+
"<Figure size 640x480 with 1 Axes>"
|
| 455 |
+
]
|
| 456 |
+
},
|
| 457 |
+
"metadata": {},
|
| 458 |
+
"output_type": "display_data"
|
| 459 |
+
}
|
| 460 |
+
],
|
| 461 |
+
"source": [
|
| 462 |
+
"import matplotlib.pyplot as plt\n",
|
| 463 |
+
"\n",
|
| 464 |
+
"# Assuming you store losses during training like this:\n",
|
| 465 |
+
"train_losses = []\n",
|
| 466 |
+
"test_losses = []\n",
|
| 467 |
+
"\n",
|
| 468 |
+
"for epoch in range(epochs):\n",
|
| 469 |
+
" total_train_loss = 0\n",
|
| 470 |
+
" total_test_loss = 0\n",
|
| 471 |
+
"\n",
|
| 472 |
+
" model.train()\n",
|
| 473 |
+
" for batch in train_dataloader:\n",
|
| 474 |
+
" inputs, labels = batch\n",
|
| 475 |
+
" optimizer.zero_grad()\n",
|
| 476 |
+
" outputs = model(**inputs)\n",
|
| 477 |
+
" loss = loss_fn(outputs.logits, labels)\n",
|
| 478 |
+
" loss.backward()\n",
|
| 479 |
+
" optimizer.step()\n",
|
| 480 |
+
" total_train_loss += loss.item()\n",
|
| 481 |
+
" \n",
|
| 482 |
+
" model.eval()\n",
|
| 483 |
+
" with torch.no_grad():\n",
|
| 484 |
+
" for batch in test_dataloader:\n",
|
| 485 |
+
" inputs, labels = batch\n",
|
| 486 |
+
" outputs = model(**inputs)\n",
|
| 487 |
+
" loss = loss_fn(outputs.logits, labels)\n",
|
| 488 |
+
" total_test_loss += loss.item()\n",
|
| 489 |
+
"\n",
|
| 490 |
+
" train_losses.append(total_train_loss / len(train_dataloader))\n",
|
| 491 |
+
" test_losses.append(total_test_loss / len(test_dataloader))\n",
|
| 492 |
+
"\n",
|
| 493 |
+
"# Plot the loss curves\n",
|
| 494 |
+
"plt.plot(range(1, epochs+1), train_losses, label=\"Train Loss\")\n",
|
| 495 |
+
"plt.plot(range(1, epochs+1), test_losses, label=\"Test Loss\")\n",
|
| 496 |
+
"plt.xlabel(\"Epochs\")\n",
|
| 497 |
+
"plt.ylabel(\"Loss\")\n",
|
| 498 |
+
"plt.legend()\n",
|
| 499 |
+
"plt.title(\"Training vs. Test Loss\")\n",
|
| 500 |
+
"plt.show()\n"
|
| 501 |
+
]
|
| 502 |
+
},
|
| 503 |
+
{
|
| 504 |
+
"cell_type": "code",
|
| 505 |
+
"execution_count": 6,
|
| 506 |
+
"metadata": {
|
| 507 |
+
"execution": {
|
| 508 |
+
"iopub.execute_input": "2025-03-14T06:20:24.796070Z",
|
| 509 |
+
"iopub.status.busy": "2025-03-14T06:20:24.795687Z",
|
| 510 |
+
"iopub.status.idle": "2025-03-14T06:20:24.907652Z",
|
| 511 |
+
"shell.execute_reply": "2025-03-14T06:20:24.906513Z",
|
| 512 |
+
"shell.execute_reply.started": "2025-03-14T06:20:24.796036Z"
|
| 513 |
+
}
|
| 514 |
+
},
|
| 515 |
+
"outputs": [
|
| 516 |
+
{
|
| 517 |
+
"name": "stdout",
|
| 518 |
+
"output_type": "stream",
|
| 519 |
+
"text": [
|
| 520 |
+
"User: Tell me a joke\n",
|
| 521 |
+
"Bot: Did you hear about the mathematician who’s afraid of negative numbers? He’ll stop at nothing to avoid them!\n",
|
| 522 |
+
"\n",
|
| 523 |
+
"User: Recommend a good book\n",
|
| 524 |
+
"Bot: As an AI, I don't have personal preferences, but there are countless amazing books in various genres. Some popular ones include Harry Potter, To Kill a Mockingbird, and 1984.\n",
|
| 525 |
+
"\n",
|
| 526 |
+
"User: What's the weather like today?\n",
|
| 527 |
+
"Bot: I'm sorry, I cannot provide real-time weather information.\n",
|
| 528 |
+
"\n",
|
| 529 |
+
"User: How can I save money?\n",
|
| 530 |
+
"Bot: Investing in stocks, mutual funds, or real estate can help grow your wealth over time.\n",
|
| 531 |
+
"\n",
|
| 532 |
+
"User: How do I meditate?\n",
|
| 533 |
+
"Bot: Meditation can reduce stress, improve focus, and promote emotional well-being.\n",
|
| 534 |
+
"\n"
|
| 535 |
+
]
|
| 536 |
+
}
|
| 537 |
+
],
|
| 538 |
+
"source": [
|
| 539 |
+
"# Testing on New Data to test model generalization\n",
|
| 540 |
+
"test_inputs = [\n",
|
| 541 |
+
" \"Tell me a joke\", \n",
|
| 542 |
+
" \"Recommend a good book\", \n",
|
| 543 |
+
" \"What's the weather like today?\", \n",
|
| 544 |
+
" \"How can I save money?\", \n",
|
| 545 |
+
" \"How do I meditate?\"\n",
|
| 546 |
+
"]\n",
|
| 547 |
+
"\n",
|
| 548 |
+
"for input_text in test_inputs:\n",
|
| 549 |
+
" response = predict_intent(input_text)\n",
|
| 550 |
+
" print(f\"User: {input_text}\\nBot: {response}\\n\")\n"
|
| 551 |
+
]
|
| 552 |
+
},
|
| 553 |
+
{
|
| 554 |
+
"cell_type": "code",
|
| 555 |
+
"execution_count": 7,
|
| 556 |
+
"metadata": {
|
| 557 |
+
"execution": {
|
| 558 |
+
"iopub.execute_input": "2025-03-14T06:20:24.909244Z",
|
| 559 |
+
"iopub.status.busy": "2025-03-14T06:20:24.908862Z",
|
| 560 |
+
"iopub.status.idle": "2025-03-14T06:20:25.664937Z",
|
| 561 |
+
"shell.execute_reply": "2025-03-14T06:20:25.664169Z",
|
| 562 |
+
"shell.execute_reply.started": "2025-03-14T06:20:24.909206Z"
|
| 563 |
+
}
|
| 564 |
+
},
|
| 565 |
+
"outputs": [
|
| 566 |
+
{
|
| 567 |
+
"name": "stdout",
|
| 568 |
+
"output_type": "stream",
|
| 569 |
+
"text": [
|
| 570 |
+
"Model saved to bert_chatbot_model.pth\n",
|
| 571 |
+
"Tokenizer saved to bert_chatbot_tokenizer\n"
|
| 572 |
+
]
|
| 573 |
+
}
|
| 574 |
+
],
|
| 575 |
+
"source": [
|
| 576 |
+
"# Define save paths\n",
|
| 577 |
+
"model_path = \"bert_chatbot_model.pth\"\n",
|
| 578 |
+
"tokenizer_path = \"bert_chatbot_tokenizer\"\n",
|
| 579 |
+
"\n",
|
| 580 |
+
"# Save model state dictionary\n",
|
| 581 |
+
"torch.save(model.state_dict(), model_path)\n",
|
| 582 |
+
"\n",
|
| 583 |
+
"# Save tokenizer\n",
|
| 584 |
+
"tokenizer.save_pretrained(tokenizer_path)\n",
|
| 585 |
+
"\n",
|
| 586 |
+
"print(f\"Model saved to {model_path}\")\n",
|
| 587 |
+
"print(f\"Tokenizer saved to {tokenizer_path}\")"
|
| 588 |
+
]
|
| 589 |
+
},
|
| 590 |
+
{
|
| 591 |
+
"cell_type": "code",
|
| 592 |
+
"execution_count": 8,
|
| 593 |
+
"metadata": {
|
| 594 |
+
"execution": {
|
| 595 |
+
"iopub.execute_input": "2025-03-14T06:20:25.666894Z",
|
| 596 |
+
"iopub.status.busy": "2025-03-14T06:20:25.666633Z",
|
| 597 |
+
"iopub.status.idle": "2025-03-14T06:20:26.840930Z",
|
| 598 |
+
"shell.execute_reply": "2025-03-14T06:20:26.839944Z",
|
| 599 |
+
"shell.execute_reply.started": "2025-03-14T06:20:25.666873Z"
|
| 600 |
+
}
|
| 601 |
+
},
|
| 602 |
+
"outputs": [
|
| 603 |
+
{
|
| 604 |
+
"data": {
|
| 605 |
+
"text/plain": [
|
| 606 |
+
"('chatbot_model/tokenizer_config.json',\n",
|
| 607 |
+
" 'chatbot_model/special_tokens_map.json',\n",
|
| 608 |
+
" 'chatbot_model/vocab.txt',\n",
|
| 609 |
+
" 'chatbot_model/added_tokens.json')"
|
| 610 |
+
]
|
| 611 |
+
},
|
| 612 |
+
"execution_count": 8,
|
| 613 |
+
"metadata": {},
|
| 614 |
+
"output_type": "execute_result"
|
| 615 |
+
}
|
| 616 |
+
],
|
| 617 |
+
"source": [
|
| 618 |
+
"model.save_pretrained(\"chatbot_model\")\n",
|
| 619 |
+
"tokenizer.save_pretrained(\"chatbot_model\")"
|
| 620 |
+
]
|
| 621 |
+
}
|
| 622 |
+
],
|
| 623 |
+
"metadata": {
|
| 624 |
+
"kaggle": {
|
| 625 |
+
"accelerator": "nvidiaTeslaT4",
|
| 626 |
+
"dataSources": [
|
| 627 |
+
{
|
| 628 |
+
"datasetId": 6860959,
|
| 629 |
+
"sourceId": 11018742,
|
| 630 |
+
"sourceType": "datasetVersion"
|
| 631 |
+
}
|
| 632 |
+
],
|
| 633 |
+
"dockerImageVersionId": 30919,
|
| 634 |
+
"isGpuEnabled": true,
|
| 635 |
+
"isInternetEnabled": true,
|
| 636 |
+
"language": "python",
|
| 637 |
+
"sourceType": "notebook"
|
| 638 |
+
},
|
| 639 |
+
"kernelspec": {
|
| 640 |
+
"display_name": "Python 3 (ipykernel)",
|
| 641 |
+
"language": "python",
|
| 642 |
+
"name": "python3"
|
| 643 |
+
},
|
| 644 |
+
"language_info": {
|
| 645 |
+
"codemirror_mode": {
|
| 646 |
+
"name": "ipython",
|
| 647 |
+
"version": 3
|
| 648 |
+
},
|
| 649 |
+
"file_extension": ".py",
|
| 650 |
+
"mimetype": "text/x-python",
|
| 651 |
+
"name": "python",
|
| 652 |
+
"nbconvert_exporter": "python",
|
| 653 |
+
"pygments_lexer": "ipython3",
|
| 654 |
+
"version": "3.8.20"
|
| 655 |
+
}
|
| 656 |
+
},
|
| 657 |
+
"nbformat": 4,
|
| 658 |
+
"nbformat_minor": 4
|
| 659 |
+
}
|
chatbot.py
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import torch
|
| 3 |
+
from transformers import BertTokenizer, BertForSequenceClassification
|
| 4 |
+
import json
|
| 5 |
+
import os
|
| 6 |
+
import time
|
| 7 |
+
import datetime
|
| 8 |
+
import random
|
| 9 |
+
from streamlit_extras.add_vertical_space import add_vertical_space
|
| 10 |
+
from streamlit_extras.let_it_rain import rain
|
| 11 |
+
from streamlit_modal import Modal
|
| 12 |
+
|
| 13 |
+
# Streamlit UI
|
| 14 |
+
st.set_page_config(page_title="ChatBot", layout="wide")
|
| 15 |
+
|
| 16 |
+
# Load BERT Model & Tokenizer
|
| 17 |
+
MODEL_PATH = "Trained Model/chatbot_model" # Path where your model & tokenizer are saved
|
| 18 |
+
|
| 19 |
+
# Set device
|
| 20 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 21 |
+
|
| 22 |
+
# Load model & tokenizer
|
| 23 |
+
tokenizer = BertTokenizer.from_pretrained(MODEL_PATH)
|
| 24 |
+
model = BertForSequenceClassification.from_pretrained(MODEL_PATH)
|
| 25 |
+
model.to(device)
|
| 26 |
+
model.eval()
|
| 27 |
+
|
| 28 |
+
# Load intents
|
| 29 |
+
with open("intents.json", "r") as file:
|
| 30 |
+
intents = json.load(file)
|
| 31 |
+
|
| 32 |
+
intent_mapping = {i: intent['tag'] for i, intent in enumerate(intents)}
|
| 33 |
+
|
| 34 |
+
# Chat history file
|
| 35 |
+
CHAT_HISTORY_FILE = "chat_history.json"
|
| 36 |
+
|
| 37 |
+
# Load Chat History (Ensuring Persistence)
|
| 38 |
+
def load_chat_history():
|
| 39 |
+
if os.path.exists(CHAT_HISTORY_FILE):
|
| 40 |
+
with open(CHAT_HISTORY_FILE, "r") as file:
|
| 41 |
+
return json.load(file)
|
| 42 |
+
return []
|
| 43 |
+
|
| 44 |
+
# Save Chat History
|
| 45 |
+
def save_chat_history():
|
| 46 |
+
with open(CHAT_HISTORY_FILE, "w") as file:
|
| 47 |
+
json.dump(st.session_state.chat_history, file)
|
| 48 |
+
|
| 49 |
+
# Initialize session state variables
|
| 50 |
+
if "chat_history" not in st.session_state:
|
| 51 |
+
st.session_state.chat_history = load_chat_history()
|
| 52 |
+
if "show_history" not in st.session_state:
|
| 53 |
+
st.session_state.show_history = False
|
| 54 |
+
if "show_about" not in st.session_state:
|
| 55 |
+
st.session_state.show_about = False
|
| 56 |
+
if "chat_input" not in st.session_state:
|
| 57 |
+
st.session_state.chat_input = ""
|
| 58 |
+
|
| 59 |
+
def predict_intent(text):
|
| 60 |
+
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True).to(device)
|
| 61 |
+
with torch.no_grad():
|
| 62 |
+
outputs = model(**inputs)
|
| 63 |
+
|
| 64 |
+
predicted_index = torch.argmax(outputs.logits, dim=1).item()
|
| 65 |
+
return intent_mapping.get(predicted_index, "unknown")
|
| 66 |
+
|
| 67 |
+
def get_response(intent_label):
|
| 68 |
+
for intent in intents:
|
| 69 |
+
if intent_label == intent['tag']:
|
| 70 |
+
return random.choice(intent['responses'])
|
| 71 |
+
return "I'm not sure how to respond to that."
|
| 72 |
+
|
| 73 |
+
# Sidebar menu
|
| 74 |
+
with st.sidebar:
|
| 75 |
+
st.image("Images/Bot Image.jpeg", use_container_width=True)
|
| 76 |
+
st.title("💬 Chatbot Menu")
|
| 77 |
+
add_vertical_space(1)
|
| 78 |
+
|
| 79 |
+
if st.button("🆕 New Chat"):
|
| 80 |
+
st.session_state.chat_input = ""
|
| 81 |
+
save_chat_history()
|
| 82 |
+
|
| 83 |
+
if st.button("📜 Chat History"):
|
| 84 |
+
st.session_state.show_history = True
|
| 85 |
+
|
| 86 |
+
if st.button("ℹ️ About"):
|
| 87 |
+
st.session_state.show_about = True
|
| 88 |
+
st.caption("🚀 Built with ❤️ by AI Enthusiast")
|
| 89 |
+
|
| 90 |
+
# Modal Windows (Chat History & About)
|
| 91 |
+
history_modal = Modal("📜Chat History", key="history_modal")
|
| 92 |
+
about_modal = Modal("ℹ️About", key="about_modal")
|
| 93 |
+
|
| 94 |
+
# Display chat history without affecting the chat window
|
| 95 |
+
if st.session_state.show_history:
|
| 96 |
+
with history_modal.container():
|
| 97 |
+
if st.session_state.chat_history:
|
| 98 |
+
for chat in st.session_state.chat_history[-10:]: # Show last 10 messages
|
| 99 |
+
st.write(chat)
|
| 100 |
+
else:
|
| 101 |
+
st.info("No chat history available.")
|
| 102 |
+
|
| 103 |
+
# Clear History Button
|
| 104 |
+
if st.button("🗑 Clear History", key="clear_history"):
|
| 105 |
+
st.session_state.chat_history = [] # Clear session history
|
| 106 |
+
if os.path.exists(CHAT_HISTORY_FILE):
|
| 107 |
+
os.remove(CHAT_HISTORY_FILE) # Delete saved file
|
| 108 |
+
st.rerun() # Refresh UI to reflect changes
|
| 109 |
+
|
| 110 |
+
# Close Modal Button
|
| 111 |
+
if st.button("Close", key="close_history"):
|
| 112 |
+
st.session_state.show_history = False
|
| 113 |
+
st.rerun()
|
| 114 |
+
|
| 115 |
+
if st.session_state.show_about:
|
| 116 |
+
with about_modal.container():
|
| 117 |
+
st.info("""This chatbot is powered by a deep learning approach using Hugging Face Transformers and a BERT model for intent recognition.
|
| 118 |
+
It understands user queries by predicting intent and responding with predefined answers based on a trained dataset.
|
| 119 |
+
|
| 120 |
+
✅ Natural Language Processing (NLP)
|
| 121 |
+
|
| 122 |
+
🔹 Transformers (Hugging Face) 🤖 – BERT-based intent classification
|
| 123 |
+
|
| 124 |
+
✅ Deep Learning
|
| 125 |
+
|
| 126 |
+
🔹 PyTorch 🔥 – Model training & fine-tuning
|
| 127 |
+
""")
|
| 128 |
+
|
| 129 |
+
if st.button("Close", key="close_about"):
|
| 130 |
+
st.session_state.show_about = False # Close modal without resetting UI
|
| 131 |
+
st.rerun()
|
| 132 |
+
|
| 133 |
+
# Chat UI
|
| 134 |
+
st.title("🤖 AI Chatbot")
|
| 135 |
+
st.markdown("### Talk to me, I'm listening...")
|
| 136 |
+
|
| 137 |
+
rain(emoji="💬", font_size=10, falling_speed=5, animation_length="infinite")
|
| 138 |
+
rain(emoji="❄️", font_size=10, falling_speed=5, animation_length="infinite")
|
| 139 |
+
|
| 140 |
+
# Chat Input with Enter Button
|
| 141 |
+
with st.form("chat_form", clear_on_submit=True):
|
| 142 |
+
chat_input = st.text_input("You:", key="chat_input")
|
| 143 |
+
submit_button = st.form_submit_button("Enter")
|
| 144 |
+
|
| 145 |
+
if submit_button and chat_input:
|
| 146 |
+
intent_label = predict_intent(chat_input)
|
| 147 |
+
response = get_response(intent_label)
|
| 148 |
+
chat_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
| 149 |
+
|
| 150 |
+
# Append messages to chat history (User & Bot)
|
| 151 |
+
st.session_state.chat_history.append(f"[{chat_time}] You: {chat_input}")
|
| 152 |
+
st.session_state.chat_history.append(f"[{chat_time}] Bot: {response}")
|
| 153 |
+
|
| 154 |
+
# Save chat history persistently
|
| 155 |
+
save_chat_history()
|
| 156 |
+
|
| 157 |
+
# Display conversation immediately
|
| 158 |
+
with st.chat_message("user"):
|
| 159 |
+
st.markdown(f"**You:** {chat_input}")
|
| 160 |
+
time.sleep(0.5)
|
| 161 |
+
with st.chat_message("assistant"):
|
| 162 |
+
st.markdown(f"**Bot:** {response}")
|
| 163 |
+
|
| 164 |
+
# Style customization
|
| 165 |
+
st.markdown("""
|
| 166 |
+
<style>
|
| 167 |
+
|
| 168 |
+
/* Fix Modal Height & Enable Scroll */
|
| 169 |
+
div[data-modal-container="true"] {
|
| 170 |
+
position: fixed !important;
|
| 171 |
+
top: 5% !important; /* Adjust this value to position it higher */
|
| 172 |
+
color: #000000;
|
| 173 |
+
max-height: 1000px !important; /* Set max height */
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
/* Ensure the close button stays visible */
|
| 177 |
+
div[data-modal-container="true"] button {
|
| 178 |
+
position: sticky;
|
| 179 |
+
bottom: 10px;
|
| 180 |
+
background-color: #000000;
|
| 181 |
+
color: white;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
.stChatMessage {padding: 10px; border-radius: 10px; background-color: #900C3F;}
|
| 185 |
+
.stChatMessageUser {background-color: #900C3F;}
|
| 186 |
+
.stChatMessageAssistant {background-color: #900C3F;}
|
| 187 |
+
</style>
|
| 188 |
+
""", unsafe_allow_html=True)
|
intents.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
requirements.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
streamlit
|
| 2 |
+
torch
|
| 3 |
+
transformers
|
| 4 |
+
streamlit_extras
|
| 5 |
+
streamlit_modal
|