For those looking to add a touch of Artificial Intelligence to their applications, chatbot with PyTorch is a great place to start. They can be utilized to enhance Customer Service experience, answer Frequently Asked Questions (FAQs), or even just to chat with you when you are feeling lonely. In this tutorial, we will teach you how to build a Chatbot using Python3 and PyTorch. Before we jump into writing code, let us first get an understanding of PyTorch.
Chatbot with PyTorch
PyTorch is a library that is based on the Torch library. It is a scientific computing package that is used to develop Deep Learning algorithms. It has a ton of features that makes it easier to work with, fewer dependencies, and is designed to be more python-friendly to users who are passionate about machine learning. PyTorch brings an ease of use by providing a smooth and straightforward experience of coding.
Let us move forward and build our Chatbot!
Chatbot with PyTorch Step 1: Environment setup
Firstly, let us create a virtual environment for our Chatbot. Open up the command prompt or terminal and enter the following command:
python3 -m venv pytorch-env
This command creates a virtual environment named ‘pytorch-env’ in the current directory. Activate the environment using the following command:
source pytorch-env/bin/activate
Chatbot with PyTorch Step 2: Installing PyTorch
Now that we have our environment set up, we need to install PyTorch. Use the following command to perform the installation:
pip3 install torch torchvision
Chatbot with PyTorch Step 3: Installing NLTK
We need the Natural Language Toolkit (NLTK) for our Chatbot. It is a python package that helps in building human-like language understanding. Use the following command to install NLTK:
pip3 install nltk
Chatbot with PyTorch Step 4: Creating the Chatbot
1. Importing the necessary libraries:
We will be using PyTorch and NLTK for our Chatbot. Import the following libraries:
import torch import torch.nn as nn from torch.utils.data import Dataset, DataLoader from nltk.tokenize import word_tokenize from nltk.stem import WordNetLemmatizer
2. Preprocessing the data:
Before we begin with the Chatbot, we need to preprocess our data. We will invert our dictionary using a lemmatizer to convert all the words into their simple or root form:
lemmatizer = WordNetLemmatizer() def preprocess(sentence): sentence_words = word_tokenize(sentence) sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words] return sentence_words
3. Loading and splitting the data:
We’ll use a JSON data file with our information for the Chatbot. In this file, we will have two fields, ‘intents’ and ‘responses’. The ‘intents’ field will contain all possible user inputs that we want our Chatbot to recognize and respond to. Each ‘intent’ object will have the ‘tag’ (the name of the intent) and the ‘patterns’ (the ways the user can communicate the intent). The ‘responses’ field will contain the responses our Chatbot will use for each intent. Use the following code to load and split the data:
import json with open('intents.json', 'r') as f: intents = json.load(f) all_words = [] tags = [] patterns = [] responses = [] for intent in intents['intents']: tag = intent['tag'] tags.append(tag) for pattern in intent['patterns']: pattern_words = preprocess(pattern) all_words.extend(pattern_words) patterns.append(pattern_words) responses.append(intent['responses'])
4. Creating a training dataset and data loader:
We need a full vocabulary of words from all the patterns, combined with each response so that when a user input is entered, the output response is pulled from it. Convert our data into a format that we can feed into our neural network model:
from sklearn.preprocessing import OneHotEncoder import numpy as np all_words = sorted(set(all_words)) tags = sorted(set(tags)) X_train = [] y_train = [] for i, pattern in enumerate(patterns): bag = [] pattern_words = {lemmatizer.lemmatize(word.lower()) for word in pattern} for word in all_words: bag.append(1 if word.lower() in pattern_words else 0) X_train.append(bag) y_train.append(tags.index(tags[i])) enc = OneHotEncoder() y_train = enc.fit_transform(np.array(y_train).reshape(-1,1)).toarray() class ChatDataset(Dataset): def __init__(self): self.n_samples = len(X_train) self.x_data = torch.Tensor(X_train) self.y_data = torch.Tensor(y_train) # Get the length of the dataset def __len__(self): return self.n_samples # Get features and labels of the dataset def __getitem__(self, index): return self.x_data[index], self.y_data[index] # Create a data loader batch_size = 8 dataset = ChatDataset() train_loader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=True, num_workers=2)
5. Creating the neural network model:
We will use PyTorch to build our neural network model for our Chatbot. Before we proceed, the following code will set the seeds for PyTorch:
# Set the seeds for PyTorch torch.manual_seed(1)
We will have an input layer that has the size of our bag of words, a hidden layer, and an output layer that has the size of our number of tags. We are using PyTorch’s Sequential module to stack our layers.
class ChatNet(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(ChatNet,self).__init__() self.i2h = nn.Linear(input_size, hidden_size) self.h2o = nn.Linear(hidden_size, output_size) self.relu = nn.ReLU() def forward(self, x): x = self.i2h(x) x = self.relu(x) x = self.h2o(x) return x input_size = len(X_train[0]) hidden_size = 8 output_size = len(tags) chat_net = ChatNet(input_size, hidden_size, output_size)
6. Training the model:
Now that we have our neural network, we will proceed to train it. We will use the Negative Log Likelihood Loss in the PyTorch optimizer to train our model:
# Initialize Loss and Optimizer Function loss_fn = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(chat_net.parameters(), lr=0.001) # Train the model num_epochs = 1000 for epoch in range(num_epochs): for (patterns, labels) in train_loader: outputs = chat_net(patterns) loss = loss_fn(outputs, torch.max(labels, 1)[1]) optimizer.zero_grad() loss.backward() optimizer.step() if epoch % 100 == 0: print(f"Loss: {loss.item()} Epoch: {epoch}")
Step 5: Testing the model
Now that we have trained our model, we can test the Chatbot. We have to write a code to take a user input, preprocess it, get the predicted label and extract the correct response:
# Test the Model def chat(): print("Start talking with the bot (type quit to exit):") chatbot_running = True while chatbot_running: sentence = input('You: ') if sentence == 'quit': chatbot_running = False break # Preprocess the user input sentence_words = preprocess(sentence) X_test = [] for word in all_words: X_test.append(1 if word in sentence_words else 0) # Predict the tag of the input X_test = np.array(X_test).reshape(1, -1) X_test = torch.from_numpy(X_test).float() output = chat_net(X_test) _, predicted = torch.max(output, dim = 1) tag = tags[predicted.item()] # Get a random response for the predicted tag responses_list = responses[tags.index(tag)] print("Bot:", np.random.choice(responses_list)) chat()
Congratulations, we have successfully created a chatbot using PyTorch in Python. We have learned some very fundamental techniques used in Machine Learning and Artificial Intelligence, this technique can be applied to problems in any domain to make informed decisions. While this model is not a perfect chatbot, we can improve the model to improve its accuracy, learn more patterns to expand its vocabulary. With that being said, we have come a long way and learned a lot.
Want to learn more about Python, checkout the Python Official Documentation for detail.