import torchimport torch.nn.functional as Fimport matplotlib.pyplot as plt # for making figures%matplotlib inline
# read in all the wordswords = open('names.txt', 'r').read().splitlines()# build the vocabulary of characters and mappings to/from integerschars = sorted(list(set(''.join(words))))stoi = {s:i+1 for i,s in enumerate(chars)}stoi['.'] = 0itos = {i:s for s,i in stoi.items()}# build the datasetblock_size = 3 # context length: how many characters do we take to predict the next one?X, Y = [], []for w in words: #print(w) context = [0] * block_size for ch in w + '.': ix = stoi[ch] X.append(context) Y.append(ix) #print(''.join(itos[i] for i in context), '--->', itos[ix]) context = context[1:] + [ix] # crop and appendX = torch.tensor(X)Y = torch.tensor(Y)
for p in parameters: p.requires_grad = True #Coz we know PyTorch asks for this parameter, as it is set to false by default
for _ in range(10): #forward pass emb = C[X] h = torch.tanh(emb.view(-1,6) @ W1 + b1) logits = h @ W2 + b2 loss = F.cross_entropy(logits, Y) print(loss) #backward pass for p in parameters: p.grad = None loss.backward() #update for p in parameters: p.data += -0.1 * p.grad# print(loss.item())
for _ in range(1000): #Minibatch xi = torch.randint(0, X.shape[0], (32,)) #forward pass emb = C[X[xi]] #added for X h = torch.tanh(emb.view(-1,6) @ W1 + b1) logits = h @ W2 + b2 loss = F.cross_entropy(logits, Y[xi]) #added for Y #print(loss.item()) #backward pass for p in parameters: p.grad = None loss.backward() #update for p in parameters: p.data += -0.1 * p.gradprint(loss.item())
#Everytime you wanna restart just run this to reset the parametersg = torch.Generator().manual_seed(2147483647)C = torch.randn((27,2), generator=g)W1 = torch.rand((6, 100), generator=g)b1 = torch.rand(100, generator=g)W2 = torch.rand((100, 27), generator=g)b2 = torch.rand(27, generator=g)parameters = [C, W1, b1, W2, b2]
for p in parameters: p.requires_grad = True
lre = torch.linspace(-3, 0, 1000)lrs = 10**lre
lri = []lossi = []for i in range(1000): #Minibatch xi = torch.randint(0, X.shape[0], (32,)) #forward pass emb = C[X[xi]] h = torch.tanh(emb.view(-1,6) @ W1 + b1) logits = h @ W2 + b2 loss = F.cross_entropy(logits, Y[xi]) #print(loss.item()) #backward pass for p in parameters: p.grad = None loss.backward() #update lr = lrs[i] for p in parameters: p.data += -0.1 * p.grad #keeping track lri.append(lr) lossi.append(loss.item())print(loss.item())
Output
2.419145107269287
plt.plot(lri, lossi)
Output
[<matplotlib.lines.Line2D at 0x225085e9b40>]
But we would like to see which exponent value is recommended to use, so we'll update the x-axis
#Remember to reset the parameters and only then run thislri = []lossi = []for i in range(1000): #Minibatch xi = torch.randint(0, X.shape[0], (32,)) #forward pass emb = C[X[xi]] h = torch.tanh(emb.view(-1,6) @ W1 + b1) logits = h @ W2 + b2 loss = F.cross_entropy(logits, Y[xi]) #print(loss.item()) #backward pass for p in parameters: p.grad = None loss.backward() #update lr = lrs[i] for p in parameters: p.data += -0.1 * p.grad #keeping track lri.append(lre[i]) #We are taking the exponent of the learning rate for the x-axis lossi.append(loss.item())print(loss.item())
Output
2.705171585083008
plt.plot(lri, lossi)
Output
[<matplotlib.lines.Line2D at 0x22507dc3850>]
^Here exp of -1 is the closest to where the loss is less, so exponent of -1 is 0.1, which was the actual value we had considered anyway
Just to cross-check we'll directly plot that value and see
#Remember to reset the parameters and only then run thislri = []lossi = []for i in range(1000): #Minibatch xi = torch.randint(0, X.shape[0], (32,)) #forward pass emb = C[X[xi]] h = torch.tanh(emb.view(-1,6) @ W1 + b1) logits = h @ W2 + b2 loss = F.cross_entropy(logits, Y[xi]) #print(loss.item()) #backward pass for p in parameters: p.grad = None loss.backward() #update lr = lrs[i] for p in parameters: p.data += -0.1 * p.grad #keeping track lri.append(lrs[i]) #We are taking the exponent of the learning rate for the x-axis lossi.append(loss.item())print(loss.item())