I have a very simple RNN model which I can execute on Jupyter notebook without any problem, now I want to embed this model in my Django project, so I downloaded the .ipynb file then saved it as .py file, then I just put it in my Django project.
However, the first problem is VSCode says I have unresolved import 'MLutils, the MLutils is my utility file in the same folder.
The second problem is if I just run this file, I'll get this error RuntimeError: cannot perform reduction function argmax on a tensor with no elements because the operation does not have an identity but if I use the Run Cell Above button of the VSCode, I'll get the correct result. The code I want to run is this, called MLTrain.py
import torch import torch.nn as nn import matplotlib.pyplot as plt from MLutils import ALL_LETTERS, N_LETTERS from MLutils import load_data, letter_to_tensor, line_to_tensor, random_training_example class RNN(nn.Module): # implement RNN from scratch rather than using nn.RNN # # number of possible letters, hidden size, categories number def __init__(self, input_size, hidden_size, output_size): super(RNN, self).__init__() self.hidden_size = hidden_size #Define 2 different liner layers self.i2h = nn.Linear(input_size + hidden_size, hidden_size) self.i2o = nn.Linear(input_size + hidden_size, output_size) self.softmax = nn.LogSoftmax(dim=1) def forward(self, input_tensor, hidden_tensor): # combine input and hidden tensor combined = torch.cat((input_tensor, hidden_tensor), 1) # apply the Linear layers and the softmax hidden = self.i2h(combined) output = self.i2o(combined) output = self.softmax(output) # return 2 different tensors return output, hidden # need some initial hidden states in the begining. def init_hidden(self): return torch.zeros(1, self.hidden_size) # dictionary with the country as the key and names as values category_lines, all_categories = load_data() # number of categories n_categories = len(all_categories) # a Hyperparameter n_hidden = 128 # number of possible letters, hidden size, output size rnn = RNN(N_LETTERS, n_hidden, n_categories) # one step input_tensor = letter_to_tensor('A') hidden_tensor = rnn.init_hidden() output, next_hidden = rnn(input_tensor, hidden_tensor) #print(output.size()) #>>> size: [1,18] #print(next_hidden.size()) #>>> size: [1,128] # whole sequence/name input_tensor = line_to_tensor('if') hidden_tensor = rnn.init_hidden() output, next_hidden = rnn(input_tensor[0], hidden_tensor) print(output.size()) print(next_hidden.size()) # In[17]: # In[2]: # apply softmax in the end. # this is the likelyhood of each character of each category def category_from_output(output): # return index of the greatest value category_idx = torch.argmax(output).item() return all_categories[category_idx] print(category_from_output(output)) # In[3]: criterion = nn.NLLLoss() # hyperparameter learning_rate = 0.005 optimizer = torch.optim.SGD(rnn.parameters(), lr=learning_rate) # whole name as tensor, def train(line_tensor, category_tensor): hidden = rnn.init_hidden() #line_tensor.size()[0]: the length of the name for i in range(line_tensor.size()[0]): # apply the current character and the previous hidden state. output, hidden = rnn(line_tensor[i], hidden) loss = criterion(output, category_tensor) optimizer.zero_grad() loss.backward() optimizer.step() return output, loss.item() current_loss = 0 all_losses = [] plot_steps, print_steps = 100, 500 n_iters = 2000 for i in range(n_iters): category, line, category_tensor, line_tensor = random_training_example(category_lines, all_categories) output, loss = train(line_tensor, category_tensor) current_loss += loss if (i+1) % plot_steps == 0: all_losses.append(current_loss / plot_steps) current_loss = 0 if (i+1) % print_steps == 0: guess = category_from_output(output) correct = "CORRECT" if guess == category else f"WRONG ({category})" print(f"{i+1} {(i+1)/n_iters*100} {loss:.4f} {line} / {guess} {correct}") plt.figure() plt.plot(all_losses) plt.show() # model can be saved def predict(input_line): print(f"\n> {input_line}") with torch.no_grad(): line_tensor = line_to_tensor(input_line) hidden = rnn.init_hidden() for i in range(line_tensor.size()[0]): output, hidden = rnn(line_tensor[i], hidden) guess = category_from_output(output) print(guess) while True: sentence = input("Input:") if sentence == "quit": break predict(sentence) if __name__ == "__main__": predict("abcde 1 ifelse" The MLutils.py is this
import io import os import unicodedata import string import glob import torch import random # alphabet small + capital letters + " .,;'" ALL_LETTERS = string.ascii_letters + " .,;'" N_LETTERS = len(ALL_LETTERS) # Turn a Unicode string to plain ASCII, thanks to https://stackoverflow.com/a/518232/2809427 def unicode_to_ascii(s): return ''.join( c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn' and c in ALL_LETTERS ) def load_data(): # Build the category_lines dictionary, a list of names per language category_lines = {} all_categories = [] def find_files(path): return glob.glob(path) # Read a file and split into lines def read_lines(filename): lines = io.open(filename, encoding='utf-8').read().strip().split('\n') return [unicode_to_ascii(line) for line in lines] for filename in find_files('data/categories/*.txt'): category = os.path.splitext(os.path.basename(filename))[0] all_categories.append(category) lines = read_lines(filename) category_lines[category] = lines return category_lines, all_categories # Find letter index from all_letters, e.g. "a" = 0 def letter_to_index(letter): return ALL_LETTERS.find(letter) # Just for demonstration, turn a letter into a <1 x n_letters> Tensor def letter_to_tensor(letter): tensor = torch.zeros(1, N_LETTERS) tensor[0][letter_to_index(letter)] = 1 return tensor # Turn a line into a <line_length x 1 x n_letters>, # or an array of one-hot letter vectors def line_to_tensor(line): tensor = torch.zeros(len(line), 1, N_LETTERS) for i, letter in enumerate(line): tensor[i][0][letter_to_index(letter)] = 1 return tensor def random_training_example(category_lines, all_categories): def random_choice(a): random_idx = random.randint(0, len(a) - 1) return a[random_idx] category = random_choice(all_categories) line = random_choice(category_lines[category]) category_tensor = torch.tensor([all_categories.index(category)], dtype=torch.long) line_tensor = line_to_tensor(line) return category, line, category_tensor, line_tensor if __name__ == '__main__': print(ALL_LETTERS) print(unicode_to_ascii('Ślusàrski')) # category_lines, all_categories = load_data() # print(category_lines['Flow'][:5]) # print(letter_to_tensor('J')) # [1, 57] # print(line_to_tensor('Jones').size()) # [5, 1, 57] That's really wired or I am really stupid on somewhere. Someone please help me! Many thanks.
https://stackoverflow.com/questions/65963949/python-re-write-jupyter-notebook-to-python-script-problem January 30, 2021 at 10:05AM
没有评论:
发表评论