PyTorch Tutorial RNN 1
- date:
19 oct 2019
from io import open;import glob;import os
import unicodedata;import string
import torch;import torch.nn as nn
import random;import matplotlib.pyplot as plt
allLetters=string.ascii_letters+" .,;'"
def findFiles(path): return glob.glob(path)
def unicodeToAscii(s):
return ''.join(
c for c in unicodedata.normalize('NFD',s)
if unicodedata.category(c)!='Mn' and c in allLetters)
def readLines(filename):
lines=open(filename,encoding='utf-8').read().strip().split('\n')
return [unicodeToAscii(line) for line in lines]
def lineToTensor(line):
tensor=torch.zeros([len(line),1,len(allLetters)])
for i,letter in enumerate(line):
#print(i,letter)
index=allLetters.find(letter)
tensor[i][0][index]=1
return tensor
def categoryFromOutput(output,allCategories):
values,indices=output.topk(1)
index=indices[0].item()
return allCategories[index],index
def randomTrainingExample(allCategories,categoryLines):
category=random.choice(allCategories)
line=random.choice(categoryLines[category])
categoryTensor=torch.tensor([allCategories.index(category)],dtype=torch.long)
return category,line,categoryTensor,lineToTensor(line)
class GetData:
def __init__(self):
self.categoryLines={};self.allCategories=[]
for filename in findFiles('*.txt'):
category=os.path.splitext(os.path.basename(filename))[0]
self.allCategories.append(category)
self.categoryLines[category]=readLines(filename)
#print(self.categoryLines['Chinese'])
#print(lineToTensor('abc'))
class RNN(nn.Module):
def __init__(self,inputSize,hiddenSize,outputSize):
super(RNN,self).__init__()
self.hiddenSize=hiddenSize
self.i2h=nn.Linear(inputSize+hiddenSize,hiddenSize)
self.i2o=nn.Linear(inputSize+hiddenSize,outputSize)
self.softmax=nn.LogSoftmax(dim=1)
def forward(self,input,hidden):
combined=torch.cat((input,hidden),1)
hidden=self.i2h(combined)
output=self.softmax(self.i2o(combined))
return output,hidden
def initHidden(self):
return torch.zeros([1,self.hiddenSize])
class Agent:
def __init__(self,learnRate):
self.learnRate=learnRate
self.getData=GetData()
self.rnn=RNN(len(allLetters),128,len(getData.allCategories))
self.criterion=nn.NLLLoss()
def trainOne(self,categoryTensor,lineTensor):
hidden=self.rnn.initHidden()
self.rnn.zero_grad()
for i in range(lineTensor.shape[0]):
output,hidden=self.rnn(lineTensor[i],hidden)
loss=self.criterion(output,categoryTensor)
loss.backward()
for p in self.rnn.parameters():
p.data.add_(-self.learnRate,p.grad.data)
return output,loss.item()
def train(self,numIterations):
currentLoss=0;losses=[]
for iter in range(1,numIterations+1):
category,line,categoryTensor,lineTensor=randomTrainingExample(
self.getData.allCategories,self.getData.categoryLines)
output,loss=self.trainOne(categoryTensor,lineTensor)
currentLoss+=loss
if(iter%1000==0):
losses.append(currentLoss);currentLoss=0
print("loss",loss)
plt.plot(losses);plt.show()
agent=Agent(learnRate=0.005)
agent.train(100000)
image.webp