Jeremiah_

LSTM-char-wise.py

Sep 26th, 2019
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.59 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. Created on Mon Sep 23 19:06:26 2019
  5.  
  6. @author: jeremiah
  7. """
  8. #%%
  9. import numpy as np
  10. import torch
  11. from torch import nn, optim
  12. import torch.nn.functional as F
  13.  
  14. #%%
  15. #opening the text file e reading it
  16. with open('/home/jeremiah/PyTorch/RNN/ainda-e-cedo.txt', 'r') as f:
  17.     text = f.read()
  18. print(text[:100])
  19.  
  20. #%%tokenizing
  21. chars = tuple(set(text))
  22. int2char = dict(enumerate(chars))
  23. char2int = {ch: i for i, ch in int2char.items()}
  24.  
  25. encoded = np.array([char2int[ch] for ch in text])
  26. print(text[:100])
  27. print(encoded[:100])
  28.  
  29. #%% one-hot encoding
  30. def one_hot_encode(arr, n_labels):
  31.     one_hot = np.zeros((arr.size, n_labels), dtype=np.float32)
  32.     one_hot[np.arange(one_hot.shape[0]), arr.flatten()] = 1
  33.     one_hot = one_hot.reshape((*arr.shape, n_labels))
  34.    
  35.     return one_hot
  36.  
  37. #%%creating batches
  38.    
  39. def get_batches(arr, batch_size, seq_len):
  40.    
  41.     batch_total_size = batch_size*seq_len
  42.     n_batches = len(arr)//batch_total_size
  43.    
  44.     arr = arr[:batch_total_size*n_batches]
  45.     arr = arr.reshape((batch_size, -1))
  46.    
  47.     for i in range(0, arr.shape[1], seq_len):
  48.        
  49.         x = arr[:, i:i+seq_len]
  50.         y = np.zeros_like(x)
  51.        
  52.         try:
  53.             y[:, :-1], y[:, -1] = x[:, 1:], arr[:, i+seq_len]
  54.         except IndexError:
  55.             y[:, :-1], y[:, -1] = x[:, 1:], arr[:, 0]
  56.        
  57.         yield x, y
  58.  
  59.  
  60.  
  61. #%% testing get_batches function
  62.  
  63. batches = get_batches(encoded, 17, 20)
  64. x, y = next(batches)
  65.  
  66. print('x\n', x[:10,:10])
  67. print('')
  68. print('y\n', y[:10,:10])
  69.  
  70. #%% veriying if there is a available GPU
  71. train_on_GPU = torch.cuda.is_available()
  72.  
  73. if train_on_GPU:
  74.     print('Training on GPU...')
  75. else:
  76.     print('Training on CPU')
  77. #%% defining our model
  78.  
  79. class CharRNN(nn.Module):
  80.     def __init__(self, tokens, h_size, n_layers = 2, drop_p = 0.5, lr=0.001, batch_first = True):
  81.         super().__init__()
  82.         self.hidden_size = h_size
  83.         self.n_layers = n_layers
  84.         self.drop_p = drop_p
  85.         self.lr = lr
  86.         self.batch_first = batch_first
  87.        
  88.         self.chars = tokens
  89.         self.int2char = dict(enumerate(self.chars))
  90.         self.char2int = {ch:i for i, ch in self.int2char.items()}
  91.        
  92.         #our model layers
  93.        
  94.         self.lstm = nn.LSTM(len(self.chars), self.hidden_size, self.n_layers,
  95.                             dropout = self.drop_p, batch_first = self.batch_first)
  96.        
  97.         self.fc = nn.Linear(self.hidden_size, len(self.chars))
  98.        
  99.         self.dropout = nn.Dropout(self.drop_p)
  100.        
  101.     def forward(self, x, hidden):
  102.        
  103.         r_output, hidden = self.lstm(x, hidden)
  104.        
  105.         out = self.dropout(r_output)
  106.        
  107.         out = out.contiguous().view(-1, self.hidden_size)
  108.        
  109.         out = self.fc(out)
  110.        
  111.         return out, hidden
  112.    
  113.     def init_hidden(self, batch_size):
  114.         weight = next(self.parameters()).data
  115.        
  116.         if train_on_GPU:
  117.             hidden = (weight.new(self.n_layers, batch_size, self.hidden_size).zero_().cuda(),
  118.                       weight.new(self.n_layers, batch_size, self.hidden_size).zero_().cuda())
  119.         else:
  120.             hidden = (weight.new(self.n_layers, batch_size, self.hidden_size).zero_(),
  121.                       weight.new(self.n_layers, batch_size, self.hidden_size).zero_())
  122.        
  123.         return hidden
  124.  
  125. #%% train fuction
  126.  
  127. def train(net, data, epochs=5, batch_size=16, seq_len=20, lr=0.005, clip=5, val_frac=0.2, print_every=10):
  128.     net.train()
  129.  
  130.     opt = optim.Adam(net.parameters(), lr=lr)
  131.     criterion = nn.CrossEntropyLoss()
  132.    
  133.     val_idx = int(len(data)*(1-val_frac))
  134.     data, val_data = data[:val_idx], data[val_idx:]
  135.    
  136.     if train_on_GPU:
  137.         net.cuda()
  138.        
  139.     steps = 0
  140.     n_chars = len(net.chars)
  141.    
  142.     for e in range(epochs):
  143.         h = net.init_hidden(batch_size)
  144.         for x, y in get_batches(data, batch_size, seq_len):
  145.             steps += 1
  146.            
  147.             x = one_hot_encode(x, n_chars)
  148.            
  149.             inputs, targets = torch.from_numpy(x), torch.from_numpy(y)
  150.            
  151.             if(train_on_GPU):
  152.                 inputs, targets = inputs.cuda(), targets.cuda()
  153.            
  154.             h = tuple([each.data for each in h])
  155.            
  156.             net.zero_grad()
  157.                
  158.            
  159.             output, h = net(inputs, h)
  160.            
  161.             loss = criterion(output, targets.view(batch_size*seq_len).long())
  162.             loss.backward()
  163.            
  164.             nn.utils.clip_grad_norm_(net.parameters(), clip)
  165.             opt.step()
  166.            
  167.             if steps % print_every == 0:
  168.                 val_h = net.init_hidden(batch_size)
  169.                 val_losses = []
  170.                 net.eval()
  171.                 for x, y in get_batches(val_data, batch_size, seq_len):
  172.                     x = one_hot_encode(x, n_chars)
  173.                    
  174.                     inputs, targets = torch.from_numpy(x), torch.from_numpy(y)
  175.                    
  176.                     val_h = tuple([each.data for each in val_h])
  177.                    
  178.                     if train_on_GPU:
  179.                         inputs, targets = inputs.cuda(), targets.cuda()
  180.                    
  181.                     output, val_h = net(inputs, val_h)
  182.                    
  183.                     val_loss = criterion(output, targets.view(batch_size*seq_len).long())
  184.                    
  185.                     val_losses.append(val_loss.item())
  186.                
  187.                 net.train()
  188.                
  189.                 print("Epoch: {}/{}...".format(e+1, epochs),
  190.                       "Step: {}...".format(steps),
  191.                       "Loss: {:.4f}...".format(loss.item()),
  192.                       "Val Loss: {}".format(np.mean(val_losses)))
  193.                
  194. #%% instantianting out model
  195.  
  196. """
  197. with open('/home/jeremiah/PyTorch/RNN/rnn_20_epoch.net', 'rb') as f:
  198.    checkp = torch.load(f)
  199.    
  200. state = checkp['state_dict']
  201. net = CharRNN(checkp['tokens'], checkp['n_hidden'], checkp['n_layers'])
  202. net.load_state_dict(checkp['state_dict'])
  203.  
  204. """
  205.  
  206. n_hidden = 512
  207. n_layers = 2
  208.  
  209. net = CharRNN(chars, n_hidden, n_layers)
  210. print(net)
  211.  
  212. batch_size = 16
  213. seq_len = 50
  214. n_epochs = 20
  215.  
  216. train(net, encoded, n_epochs, batch_size, seq_len)
  217.  
  218. model_name = '/home/jeremiah/PyTorch/RNN/rnn_' + str(n_epochs) +'_epoch.net'
  219.  
  220. checkpoint = {'n_hidden' : net.hidden_size,
  221.               'n_layers' : net.n_layers,
  222.               'state_dict' : net.state_dict(),
  223.               'tokens' : net.chars}
  224.  
  225. with open(model_name, 'wb') as f:
  226.     torch.save(checkpoint, f)
Advertisement
Add Comment
Please, Sign In to add comment