forked from Chakravartinsamrat/SmileScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrain.py
More file actions
131 lines (102 loc) · 5 KB
/
Copy pathtrain.py
File metadata and controls
131 lines (102 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import json
import numpy as np
from nltk_utils import tokenize, stem, bag_of_words
import torch
import torch.nn as nn
from chat_dataset import ChatDataset
from torch.utils.data import Dataset, DataLoader
from model import NeuralNet
if __name__ == '__main__':
with open('intents.json', 'r') as f:
intents = json.load(f)
all_words = [] #all stemmed words are collected to this array
tags = [] #all unique tags are collected to tags
xy = [] #xy is the pairing array
conversationa_history=[]
#for eg: if an intent has patterttns "what are you? what can you do? and the tag is greeting the xy list would contains like
#[{what}{are}{you}, {greeting}]
for intent in intents['intents']:
tag = intent['tag'] #extracts the tag associated with it, this tag as label for intent category
tags.append(tag) #appends the extracted tag to the tags list
for pattern in intent['patterns']: #this loop iterates over each patters associated with the current intent
w = tokenize(pattern) #sentence to words
all_words.extend(w) #all words list is extended with the tokens extracted from current pattern
xy.append((w, tag)) #appends like this [{what}{are}{you}, {greeting}]
all_words = [stem(w) for w in all_words]
#filters out any words that are present in the ignore letters list, reducing size and generalizing model
all_words = sorted(set(all_words))
#removes duplication and sorts alphabetically
tags = sorted(set(tags))
# Train model
X_train = []
Y_train = []
#initialized 2 empty list
for (pattern_sentence, tag) in xy:
#iterates over patterns and tag eg: [{what}{are}{you}, {greeting}]
bag = bag_of_words(pattern_sentence, all_words)
#bag words function is called
X_train.append(bag)
#appends bag to xtrain
label = tags.index(tag)
#appends tags to y train
Y_train.append(label)
X_train = np.array(X_train)
Y_train = np.array(Y_train)
#covert to numpy array
# Hyperparameters
batch_size = 8 #number of samples per batch duriong trianing
hidden_size = 16 #numbe rof units in hidden layer
#batch size 8 and Hidden 16 is giving the most accurate outputs
output_size = len(tags) #number of outputs, detrmined by tags
input_size = len(X_train[0]) #size of input, determined by bag of words
learning_rate = 0.001 #learning rate for optimization algorithm
num_epochs = 1000 #number of times the entire dataset is passed forward and backward through the neural network
#epochs= one complete pass through the entire training dataset,
dataset = ChatDataset(X_train, Y_train) #load dataset
train_loader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=True)
#creates a dataloader object to handle batching of the training data , shuffles the data for better generalization
#defines devices used for
device = torch.device('cpu')
model = NeuralNet(input_size, hidden_size, output_size).to(device)
#initializes NN with the given parameters
# Define loss and optimizer
criterion = nn.CrossEntropyLoss()
#defines loss function, it calculates the difference between predicted porbabbility distribution and actual probability distribution
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
#adaptive moment distribution
for epoch in range(num_epochs):
for (words, labels) in train_loader:
#within each epoch, code iterates over batches of data obtained from trainloader
words = words.to(device)
labels = labels.to(device)
labels = labels.type(torch.LongTensor)
#datatype to longtensor??????
#moving data to device
# Forward pass
outputs = model(words)
#passes words through THE NN
loss = criterion(outputs, labels)
#calculates loss between predicted "outputs " and actual "Labels"
# Backward and optimize
optimizer.zero_grad()
#cleaars gradient of all optimized parameters before backpass, to ensure prev gradients dont get collected
loss.backward()
#computes gradient loss
optimizer.step()
#updates amodel parameters using computed gradients and optimization algo
#logging progress
if (epoch + 1) % 100 == 0: #to check if epoch is a multiple of 100
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
print(f'Final Loss: {loss.item():.4f}')
#Now the trainning data is saved to Data.pth, IT IS ALSO CALLED A DICTIONARY
data={
"model_state":model.state_dict(),
"input_size":input_size,
"output_size": output_size,
"hidden_size":hidden_size,
"all_words":all_words,
"tags":tags,
}
FILE ="data.pth"
torch.save(data,FILE)
print(f'training Complete. File Saved to {FILE}')