From d20dfc0c0f176c51a362118c64c596c82a08edff Mon Sep 17 00:00:00 2001 From: Jeevan-bhandari-git <60292222+Jeevan-bhandari-git@users.noreply.github.com> Date: Fri, 8 Oct 2021 12:55:48 +0530 Subject: [PATCH] Create train_chatbot.py --- train_chatbot.py | 129 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 train_chatbot.py diff --git a/train_chatbot.py b/train_chatbot.py new file mode 100644 index 0000000..0202f6f --- /dev/null +++ b/train_chatbot.py @@ -0,0 +1,129 @@ +import numpy as np +import random +import json +import torch +import torch.nn as nn +from torch.utils.data import Dataset, DataLoader +from nltk_utils import bag_of_words, tokenize, stem +from model import NeuralNet +#from tkinter import messagebox + +with open('intents.json', 'r') as f: + intents = json.load(f) + +all_words = [] +tags = [] +xy = [] +# loop through each sentence in our intents patterns +for intent in intents['intents']: + tag = intent['tag'] + # add to tag list + tags.append(tag) + for pattern in intent['patterns']: + # tokenize each word in the sentence + w = tokenize(pattern) + # add to our words list + all_words.extend(w) + # add to xy pair + xy.append((w, tag)) + +# stem and lower each word +ignore_words = ['?', '.', '!'] +all_words = [stem(w) for w in all_words if w not in ignore_words] +# remove duplicates and sort +all_words = sorted(set(all_words)) +tags = sorted(set(tags)) + +print(len(xy), "patterns") +print(len(tags), "tags:", tags) +print(len(all_words), "unique stemmed words:", all_words) + +# create training data +X_train = [] +y_train = [] +for (pattern_sentence, tag) in xy: + # X: bag of words for each pattern_sentence + bag = bag_of_words(pattern_sentence, all_words) + #messagebox.showinfo("Words Bag", pattern_sentence) + X_train.append(bag) + # y: PyTorch CrossEntropyLoss needs only class labels, not one-hot + label = tags.index(tag) + y_train.append(label) +#X_train:: All postions of all words of patterns# QUESTION: in word bag +#y_train:: Allot Position number of 'patterns' as in 'tags', and repeat as count of question in patters in 'intents.txt' + +X_train = np.array(X_train) +y_train = np.array(y_train) +#print("X_train",X_train[9]) + +# Hyper-parameters +num_epochs = 1000 +batch_size = 8 +learning_rate = 0.001 +input_size = len(X_train[0]) +hidden_size = 8 +output_size = len(tags) +print(input_size, output_size) + +class ChatDataset(Dataset): + + def __init__(self): + self.n_samples = len(X_train) + self.x_data = X_train + self.y_data = y_train + + # support indexing such that dataset[i] can be used to get i-th sample + def __getitem__(self, index): + return self.x_data[index], self.y_data[index] + + # we can call len(dataset) to return the size + def __len__(self): + return self.n_samples + +dataset = ChatDataset() +train_loader = DataLoader(dataset=dataset, + batch_size=batch_size, + shuffle=True, + num_workers=0) + +device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') +model = NeuralNet(input_size, hidden_size, output_size).to(device) + +# Loss and optimizer +criterion = nn.CrossEntropyLoss() +optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) + +# Train the model +for epoch in range(num_epochs): + for (words, labels) in train_loader: + words = words.to(device) + labels = labels.to(dtype=torch.long).to(device) + + # Forward pass + outputs = model(words) + # if y would be one-hot, we must apply + # labels = torch.max(labels, 1)[1] + loss = criterion(outputs, labels) + + # Backward and optimize + optimizer.zero_grad() + loss.backward() + optimizer.step() + + if (epoch+1) % 100 == 0: + print (f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') + +print(f'final loss: {loss.item():.4f}') + +data = { +"model_state": model.state_dict(), +"input_size": input_size, +"hidden_size": hidden_size, +"output_size": output_size, +"all_words": all_words, +"tags": tags +} + +FILE = "data.pth" +torch.save(data, FILE) +print(f'training complete. file saved to {FILE}')