Jeremiah_

EEG-LSTM-01.py

Oct 8th, 2019
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.42 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. Created on Mon Sep 30 14:42:30 2019
  5.  
  6. @author: jeremiah
  7. """
  8. #%% inportings
  9. import codecs
  10. import arff as af
  11. import torch
  12. import numpy as np
  13. from torch import nn, optim
  14. import matplotlib.pyplot as plt
  15. %matplotlib inline
  16.  
  17.  
  18. #%% loading data
  19.  
  20. path = '/home/jeremiah/data_analysis/datasets/EEG Eye State.arff'
  21.  
  22. file = codecs.open(path, 'rb', 'utf-8')
  23. file = af.load(file)
  24.  
  25. #print(af.dumps(file))
  26.  
  27. #%% returns training, validation and testing datasets along with training, validation and testing labels
  28.  
  29. def get_labels(data, test_len_per, val_len_per):
  30.    
  31.     total_len = len(data)
  32.     train_len = int((1-val_len_per)*total_len)
  33.     train_labels, val_labels = data[:train_len], data[train_len:]
  34.    
  35.     #divide train_data between train_data and test_data
  36.     total_len = len(train_labels)
  37.     train_len = int(0.7*total_len)
  38.     train_labels, test_labels = train_labels[:train_len], train_labels[train_len:]
  39.    
  40.     return train_labels, test_labels, val_labels
  41.  
  42.  
  43. def divide_dataset(data, test_len_per, val_len_per):
  44.     #divide data between train_data and val_data
  45.    
  46.     labels = []
  47.  
  48.     for lista in data:
  49.         labels.append(lista[-1])
  50.         lista.pop()
  51.        
  52.    
  53.     total_len = len(data)
  54.     train_len = int((1-val_len_per)*total_len)
  55.     train_data, val_data = data[:train_len], data[train_len:]
  56.    
  57.     #divide train_data between train_data and test_data
  58.     total_len = len(train_data)
  59.     train_len = int(0.7*total_len)
  60.     train_data, test_data = train_data[:train_len], train_data[train_len:]
  61.    
  62.    
  63.     train_labels, test_labels, val_labels = get_labels(labels, test_len_per, val_len_per)
  64.    
  65.     return train_data, train_labels, test_data, test_labels, val_data, val_labels
  66.  
  67. #%% dividing data between training, validation and testing sets
  68.  
  69.  
  70. train_data, train_labels, test_data, test_labels, val_data, val_labels = divide_dataset(file['data'], 0.3, 0.1)
  71.  
  72. train_data =  np.asarray(train_data, dtype='float32')
  73. train_labels =  np.asarray(train_labels, dtype='float32')
  74.  
  75. test_data =  np.asarray(test_data, dtype='float32')
  76. test_labels =  np.asarray(test_labels, dtype='float32')
  77.  
  78. val_data =  np.asarray(val_data, dtype='float32')
  79. val_labels =  np.asarray(val_labels, dtype='float32')
  80.  
  81. #%%
  82. print(f'training set length: {len(train_data)}')
  83. print(f'testing set length: {len(test_data)}')
  84. print(f'validation set length: {len(val_data)}')
  85.  
  86. #%%
  87.  
  88. def get_batches(inputs, labels, batch_size, seq_len):
  89.    
  90.     batch_total_size = batch_size * seq_len
  91.     n_batches = len(inputs)//batch_total_size
  92.    
  93.     inputs = inputs[:n_batches * batch_total_size]
  94.     inputs = inputs.reshape((batch_size, -1, 14))
  95.    
  96.     labels = labels[:n_batches * batch_total_size]
  97.     labels = labels.reshape((batch_size, -1))
  98.    
  99.     for i in range(0, inputs.shape[1], seq_len):
  100.        
  101.         x = inputs[:, i : i+seq_len]
  102.         y = labels[:, i : i+seq_len]
  103.        
  104.         yield x, y
  105.  
  106. #%% defining our model
  107.  
  108. class LSTM_Net(nn.Module):
  109.     def __init__(self, in_size, out_size, h_size, n_layers, drop_p = 0.5, batch_first = True):
  110.         super().__init__()
  111.        
  112.         self.in_size = in_size
  113.         self.out_size = out_size
  114.         self.hidden_size = h_size
  115.         self.n_layers = n_layers
  116.        
  117.         self.lstm = nn.LSTM(in_size, h_size, n_layers, dropout = drop_p, batch_first = batch_first)
  118.        
  119.         self.dropout = nn.Dropout(drop_p)
  120.        
  121.         self.fc = nn.Linear(h_size, out_size)
  122.     def forward(self, x, h):
  123.         out, h = self.lstm(x, h)
  124.        
  125.         out = self.dropout(out)
  126.        
  127.         out = out.reshape(-1, self.hidden_size)
  128.        
  129.         out = self.fc(out)
  130.         return out, h
  131.    
  132.     def init_hidden(self, batch_size):
  133.         weight = next(self.parameters()).data
  134.        
  135.         hidden = (weight.new(self.n_layers, batch_size, self.hidden_size).zero_(),
  136.                   weight.new(self.n_layers, batch_size, self.hidden_size).zero_())
  137.        
  138.         return hidden
  139.  
  140.  
  141. #%% training the model
  142.        
  143. def train(net, inputs, labels, test_inputs, test_labels, epochs, batch_size, seq_len, print_every, clip = 5, lr=0.001):
  144.    
  145.     net.train()
  146.    
  147.     criterion = nn.MSELoss()
  148.     op = optim.Adam(net.parameters(), lr=lr)
  149.    
  150.     steps = 0
  151.     last_test_loss = np.Inf
  152.     train_losses = []
  153.     test_losses = []
  154.     model_name = ''
  155.    
  156.     for e in range(epochs):
  157.        
  158.         hidden = net.init_hidden(batch_size)
  159.         test_loss = []
  160.         train_loss = []
  161.         for x, y in get_batches(inputs, labels, batch_size, seq_len):
  162.            
  163.             steps += 1
  164.            
  165.             x, y = torch.from_numpy(x), torch.from_numpy(y)
  166.            
  167.             hidden = tuple([each.data for each in hidden])
  168.            
  169.             net.zero_grad()
  170.             out, hidden = net(x, hidden)
  171.             #print(out.shape)
  172.            
  173.             loss = criterion(out, y.reshape(batch_size*seq_len, 1))
  174.             train_loss.append(loss.item())
  175.            
  176.             loss.backward()
  177.             nn.utils.clip_grad_norm_(net.parameters(), clip)
  178.             op.step()
  179.            
  180.         else:
  181.            
  182.             net.eval()
  183.              
  184.             test_loss = []
  185.             test_h = net.init_hidden(batch_size)
  186.              
  187.             for x, y in get_batches(test_inputs, test_labels, batch_size, seq_len):
  188.                
  189.                 x, y = torch.from_numpy(x), torch.from_numpy(y)
  190.                  
  191.                 test_h = tuple([each.data for each in test_h])
  192.                  
  193.                 out, test_h = net(x, test_h)
  194.                  
  195.                 test_loss.append(criterion(out, y.reshape(batch_size*seq_len, 1)).item())
  196.                  
  197.                  
  198.             net.train()
  199.             train_losses.append(np.mean(train_loss))
  200.             test_losses.append(np.mean(test_loss))
  201.              
  202.             print('Epoch: {}/{}'.format(e+1, epochs),
  203.                   'Step: {}'.format(steps),
  204.                   'Train_Loss: {}'.format(train_losses[-1]),
  205.                   'Test_Loss: {}'.format(test_losses[-1]))
  206.              
  207.             if test_losses[-1] < last_test_loss:
  208.                
  209.                 print('Saving model...')
  210.                 last_test_loss = test_losses[-1]
  211.                 model_name = '/home/jeremiah/trained_models/LSTM-EGG-01-' + str(epochs) + '-epochs-' + str(net.hidden_size) + '-h_layers-bs' + str(batch_size) +'-sl' + str(seq_len) + '.net'
  212.                  
  213.                 checkpoint = {'input_size' : net.in_size,
  214.                               'output_size' : net.out_size,
  215.                               'hidden_size' : net.hidden_size,
  216.                               'n_layers' : net.n_layers,
  217.                               'state_dict' : net.state_dict()}
  218.                 with open(model_name, 'wb') as f:
  219.                     torch.save(checkpoint, f)
  220.                  
  221.                 model_name = '/home/jeremiah/trained_models/LSTM-EGG-01-' + str(epochs) + '-epochs-' + str(net.hidden_size) + '-h_layers-bs' + str(batch_size) +'-sl' + str(seq_len) + '.txt'
  222.                 net_info = 'Model name: ' + model_name[:-4] + '\n'
  223.                 net_info += 'Steps: ' + str(steps) + '\n'
  224.                 net_info += 'Epochs: ' + str(epochs) + '\n'
  225.                 net_info += 'Batch size: ' + str(batch_size) + '\n'
  226.                 net_info += 'Sequence length: ' + str(seq_len) + '\n'
  227.                 net_info += 'Learning rate: ' + str(learn_rate) + '\n\n'
  228.                 net_info += 'Hidden size: ' + str(net.hidden_size) + '\n'
  229.                 net_info += 'Number of layers: ' + str(net.n_layers) + '\n\n'
  230.                 net_info += 'Training loss: ' + str(train_losses[-1]) + '\n'
  231.                 net_info += 'Testing loss: ' + str(test_losses[-1])+'\n'
  232.                 net_info += 'Model saved in epoch: ' + str(e) + '\n\n'
  233.                 net_info += 'Training set length: ' + str(len(train_data)) + '\n'
  234.                 net_info += 'Testing set length: ' + str(len(test_data)) + '\n'
  235.                 net_info += 'Validation set lengt: ' + str(len(val_data)) + '\n\n'
  236.                 net_info += 'Loss function: MSELoss() - Mean Squared Error Loss Function\n'
  237.                      
  238.                 with open(model_name, 'w+') as f:
  239.                     f.write(net_info)
  240.                  
  241.     plt.plot(train_losses, 'r', label='train_loss')
  242.     plt.plot(test_losses, 'b', label='test_loss')
  243.     plt.legend(loc='best')
  244.     plt.savefig('/home/jeremiah/trained_models/LSTM-EEG-01-'+str(epochs)+'-epochs-'+str(hidden_size)+'-h_layers-bs' + str(batch_size) +'-sl' + str(seq_len) + '.png')
  245.      
  246.                
  247.                
  248. #%%
  249. input_size = 14
  250. output_size = 1
  251. hidden_size = 32
  252. n_layers = 2
  253. dropout = 0.5
  254.  
  255.  
  256. net = LSTM_Net(input_size, output_size, hidden_size, n_layers, dropout, batch_first=True)
  257. print(net)
  258.  
  259. #%%
  260.  
  261. epochs = 100
  262. batch_size = 16
  263. seq_length = 8
  264. print_every = 100
  265. clip = 5
  266. learn_rate = 0.002
  267.  
  268. train(net, train_data, train_labels, test_data, test_labels, epochs, batch_size, seq_length, print_every, clip, learn_rate)              
  269.                
  270. #%% load a trained model
  271. with open('/home/jeremiah/trained_models/LSTM-EGG-01-70-epochs-16-h_layers-bs4-sl1.net', 'rb') as f:
  272.     cpt = torch.load(f)
  273.  
  274. net = LSTM_Net(cpt['input_size'], cpt['output_size'], cpt['hidden_size'], cpt['n_layers'])
  275.  
  276. net.load_state_dict(cpt['state_dict'])
  277. print(net)
  278.  
  279. #%% test a trained model
Advertisement
Add Comment
Please, Sign In to add comment