ipvikas commited on
Commit
f2b1250
β€’
1 Parent(s): 73d7c69

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +353 -0
app.py ADDED
@@ -0,0 +1,353 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """app.ipynb
3
+
4
+ Automatically generated by Colaboratory.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1Z_cMyllUfHf2lYtUtdS1ggVMpLCLg0-j
8
+ """
9
+
10
+ ########### 5 ###########
11
+
12
+ ########### 1 ###########
13
+
14
+ #https://www.youtube.com/watch?v=RpWeNzfSUHw&list=PLqnslRFeH2UrFW4AUgn-eY37qOAWQpJyg
15
+ #intents.json --> nltk_utils.py --> model.py --> train.ipynb --> chat.ipynb
16
+ import numpy as np
17
+ import nltk
18
+ nltk.download('punkt')
19
+ from nltk.stem.porter import PorterStemmer
20
+ stemmer = PorterStemmer()
21
+
22
+ def tokenize(sentence):
23
+ """
24
+ split sentence into array of words/tokens
25
+ a token can be a word or punctuation character, or number
26
+ """
27
+ return nltk.word_tokenize(sentence)
28
+
29
+ # print(tokenize('Hello how are you'))
30
+
31
+ def stem(word):
32
+ """
33
+ stemming = find the root form of the word
34
+ examples:
35
+ words = ["organize", "organizes", "organizing"]
36
+ words = [stem(w) for w in words]
37
+ -> ["organ", "organ", "organ"]
38
+ """
39
+ return stemmer.stem(word.lower())
40
+
41
+ # print(stem('organize'))
42
+
43
+ def bag_of_words(tokenized_sentence, words):
44
+ """
45
+ return bag of words array:
46
+ 1 for each known word that exists in the sentence, 0 otherwise
47
+ example:
48
+ sentence = ["hello", "how", "are", "you"]
49
+ words = ["hi", "hello", "I", "you", "bye", "thank", "cool"]
50
+ bog = [ 0 , 1 , 0 , 1 , 0 , 0 , 0]
51
+ """
52
+ # stem each word
53
+ sentence_words = [stem(word) for word in tokenized_sentence]
54
+ # initialize bag with 0 for each word
55
+ bag = np.zeros(len(words), dtype=np.float32)
56
+ for idx, w in enumerate(words):
57
+ if w in sentence_words:
58
+ bag[idx] = 1
59
+
60
+ return bag
61
+
62
+ # print(bag_of_words('Hello how are you', 'hi'))
63
+
64
+ ########### 2 ###########
65
+
66
+ import torch
67
+ import torch.nn as nn
68
+
69
+
70
+ class NeuralNet(nn.Module):
71
+ def __init__(self, input_size, hidden_size, num_classes):
72
+ super(NeuralNet, self).__init__()
73
+ self.l1 = nn.Linear(input_size, hidden_size)
74
+ self.l2 = nn.Linear(hidden_size, hidden_size)
75
+ self.l3 = nn.Linear(hidden_size, num_classes)
76
+ self.relu = nn.ReLU()
77
+
78
+ def forward(self, x):
79
+ out = self.l1(x)
80
+ out = self.relu(out)
81
+ out = self.l2(out)
82
+ out = self.relu(out)
83
+ out = self.l3(out)
84
+ # no activation and no softmax at the end
85
+ return out
86
+
87
+ ########### 3 ###########
88
+ import numpy as np
89
+ import random
90
+ import json
91
+
92
+ import torch
93
+ import torch.nn as nn
94
+ from torch.utils.data import Dataset, DataLoader
95
+
96
+ #2. Loading our JSON Data
97
+ from google.colab import drive
98
+ drive.mount('/content/drive')
99
+
100
+ # Commented out IPython magic to ensure Python compatibility.
101
+ # %cd '/content/drive/My Drive/Colab Notebooks/NLP/ChatBot/'
102
+
103
+ path = '/content/drive/My Drive/Colab Notebooks/NLP/ChatBot/intents.json'
104
+
105
+ !pwd
106
+
107
+ import json
108
+ with open(path, 'r') as f:
109
+ intents = json.load(f)
110
+
111
+ # print(intents)
112
+
113
+ # Commented out IPython magic to ensure Python compatibility.
114
+ # %cd '/content/drive/My Drive/Colab Notebooks/NLP/ChatBot/intents.json'
115
+
116
+ # Commented out IPython magic to ensure Python compatibility.
117
+ # %pwd
118
+
119
+ !ls
120
+
121
+ import nltk
122
+ nltk.download('punkt')
123
+
124
+ from nltk_utils import bag_of_words, tokenize, stem
125
+
126
+ all_words = []
127
+ tags = []
128
+ xy = []
129
+ # loop through each sentence in our intents patterns
130
+ for intent in intents['intents']:
131
+ tag = intent['tag']
132
+ # add to tag list
133
+ tags.append(tag)
134
+ for pattern in intent['patterns']:
135
+ # tokenize each word in the sentence
136
+ w = tokenize(pattern)
137
+ # add to our words list
138
+ all_words.extend(w)
139
+ # add to xy pair
140
+ xy.append((w, tag))
141
+
142
+ # stem and lower each word
143
+ # ignore_words = ['?', '.', '!']
144
+ ignore_words = ['(',')','-',':',',',"'s",'!',':',"'","''",'--','.',':','?',';''[',']','``','o','’','β€œ','”','”','[',';']
145
+ all_words = [stem(w) for w in all_words if w not in ignore_words]
146
+ # remove duplicates and sort
147
+ all_words = sorted(set(all_words))
148
+ tags = sorted(set(tags))
149
+
150
+ print(len(xy), "patterns")
151
+ print(len(tags), "tags:", tags)
152
+ print(len(all_words), "unique stemmed words:", all_words)
153
+
154
+ # create training data
155
+ X_train = []
156
+ y_train = []
157
+ for (pattern_sentence, tag) in xy:
158
+ # X: bag of words for each pattern_sentence
159
+ bag = bag_of_words(pattern_sentence, all_words)
160
+ X_train.append(bag)
161
+ # y: PyTorch CrossEntropyLoss needs only class labels, not one-hot
162
+ label = tags.index(tag)
163
+ y_train.append(label)
164
+
165
+ X_train = np.array(X_train)
166
+ y_train = np.array(y_train)
167
+
168
+ # Hyper-parameters
169
+ num_epochs = 1000
170
+ batch_size = 8
171
+ learning_rate = 0.001
172
+ input_size = len(X_train[0])
173
+ hidden_size = 8
174
+ output_size = len(tags)
175
+ print(input_size, output_size)
176
+
177
+ class ChatDataset(Dataset):
178
+
179
+ def __init__(self):
180
+ self.n_samples = len(X_train)
181
+ self.x_data = X_train
182
+ self.y_data = y_train
183
+
184
+ # support indexing such that dataset[i] can be used to get i-th sample
185
+ def __getitem__(self, index):
186
+ return self.x_data[index], self.y_data[index]
187
+
188
+ # we can call len(dataset) to return the size
189
+ def __len__(self):
190
+ return self.n_samples
191
+
192
+ import torch
193
+ import torch.nn as nn
194
+
195
+ from model import NeuralNet
196
+
197
+ dataset = ChatDataset()
198
+ train_loader = DataLoader(dataset=dataset,batch_size=batch_size,shuffle=True,num_workers=2)
199
+
200
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
201
+
202
+ model = NeuralNet(input_size, hidden_size, output_size).to(device)
203
+ # Loss and optimizer
204
+ criterion = nn.CrossEntropyLoss()
205
+ optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
206
+
207
+ # Train the model
208
+ for epoch in range(num_epochs):
209
+ for (words, labels) in train_loader:
210
+ words = words.to(device)
211
+ labels = labels.to(dtype=torch.long).to(device)
212
+
213
+ # Forward pass
214
+ outputs = model(words)
215
+ # if y would be one-hot, we must apply
216
+ # labels = torch.max(labels, 1)[1]
217
+ loss = criterion(outputs, labels)
218
+
219
+ # Backward and optimize
220
+ optimizer.zero_grad()
221
+ loss.backward()
222
+ optimizer.step()
223
+
224
+ if (epoch+1) % 100 == 0:
225
+ print (f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
226
+
227
+
228
+ print(f'final loss: {loss.item():.4f}')
229
+
230
+ data = {
231
+ "model_state": model.state_dict(),
232
+ "input_size": input_size,
233
+ "hidden_size": hidden_size,
234
+ "output_size": output_size,
235
+ "all_words": all_words,
236
+ "tags": tags
237
+ }
238
+
239
+ FILE = "data.pth"
240
+ torch.save(data, FILE)
241
+
242
+ print(f'training complete. file saved to {FILE}')
243
+
244
+ # !nvidia-smi
245
+ #https://github.com/python-engineer/pytorch-chatbot
246
+
247
+ import random
248
+ import string # to process standard python strings
249
+
250
+ import warnings # Hide the warnings
251
+ warnings.filterwarnings('ignore')
252
+
253
+ import torch
254
+
255
+ import nltk
256
+ nltk.download('punkt')
257
+
258
+ from google.colab import drive
259
+ drive.mount("/content/drive")
260
+
261
+ # Commented out IPython magic to ensure Python compatibility.
262
+ # %cd "/content/drive/My Drive/Colab Notebooks/NLP/ChatBot/"
263
+ # !ls
264
+
265
+ import random
266
+ import json
267
+
268
+ import torch
269
+
270
+ from model import NeuralNet
271
+ from nltk_utils import bag_of_words, tokenize
272
+
273
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
274
+
275
+ with open('intents.json', 'r') as json_data:
276
+ intents = json.load(json_data)
277
+
278
+ FILE = "data.pth"
279
+ data = torch.load(FILE, map_location=torch.device('cpu'))
280
+
281
+ input_size = data["input_size"]
282
+ hidden_size = data["hidden_size"]
283
+ output_size = data["output_size"]
284
+ all_words = data['all_words']
285
+ tags = data['tags']
286
+ model_state = data["model_state"]
287
+
288
+ model = NeuralNet(input_size, hidden_size, output_size).to(device)
289
+ model.load_state_dict(model_state)
290
+ model.eval()
291
+
292
+ bot_name = "Sam"
293
+
294
+
295
+
296
+ def get_response(msg):
297
+ sentence = tokenize(msg)
298
+ X = bag_of_words(sentence, all_words)
299
+ X = X.reshape(1, X.shape[0])
300
+ X = torch.from_numpy(X).to(device)
301
+
302
+ output = model(X)
303
+ _, predicted = torch.max(output, dim=1)
304
+
305
+ tag = tags[predicted.item()]
306
+
307
+ probs = torch.softmax(output, dim=1)
308
+ prob = probs[0][predicted.item()]
309
+ if prob.item() > 0.75:
310
+ for intent in intents['intents']:
311
+ if tag == intent["tag"]:
312
+ return random.choice(intent['responses'])
313
+
314
+ return "I do not understand..."
315
+
316
+ print("Let's chat! (type 'quit' to exit)")
317
+ while True:
318
+ # sentence = "do you use credit cards?"
319
+ sentence = input("You: ")
320
+ if sentence == "quit":
321
+ break
322
+
323
+ sentence = tokenize(sentence)
324
+ X = bag_of_words(sentence, all_words)
325
+ X = X.reshape(1, X.shape[0])
326
+ X = torch.from_numpy(X).to(device)
327
+
328
+ output = model(X)
329
+ _, predicted = torch.max(output, dim=1)
330
+
331
+ tag = tags[predicted.item()]
332
+
333
+ probs = torch.softmax(output, dim=1)
334
+ prob = probs[0][predicted.item()]
335
+ if prob.item() > 0.75:
336
+ for intent in intents['intents']:
337
+ if tag == intent["tag"]:
338
+ print(f"{bot_name}: {random.choice(intent['responses'])}")
339
+ else:
340
+ print(f"{bot_name}: I do not understand...")
341
+
342
+
343
+
344
+
345
+
346
+
347
+
348
+
349
+
350
+
351
+
352
+
353
+