Advertisement
Guest User

Untitled

a guest
Jul 6th, 2015
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.37 KB | None | 0 0
  1. import scipy.io
  2. import lasagne
  3. import theano
  4. import theano.tensor as T
  5. import numpy as np
  6. import time
  7.  
  8. import logging
  9.  
  10. logger = logging.getLogger('')
  11. logger.setLevel(logging.DEBUG)
  12. fh = logging.FileHandler('experiment.log')
  13. fh.setLevel(logging.DEBUG)
  14. ch = logging.StreamHandler()
  15. ch.setLevel(logging.DEBUG)
  16. formatter = logging.Formatter('%(message)s')
  17. ch.setFormatter(formatter)
  18. fh.setFormatter(formatter)
  19. logger.addHandler(ch)
  20. logger.addHandler(fh)
  21.  
  22. TRAIN_NC = '../data/train_1_speaker.nc'
  23. VAL_NC = '../data/val_1_speaker.nc'
  24. BATCH_SIZE = 50
  25.  
  26.  
  27. def one_hot(labels, n_classes):
  28. '''
  29. Converts an array of label integers to a one-hot matrix encoding
  30.  
  31. :parameters:
  32. - labels : np.ndarray, dtype=int
  33. Array of integer labels, in {0, n_classes - 1}
  34. - n_classes : int
  35. Total number of classes
  36.  
  37. :returns:
  38. - one_hot : np.ndarray, dtype=bool, shape=(labels.shape[0], n_classes)
  39. One-hot matrix of the input
  40. '''
  41. one_hot = np.zeros((labels.shape[0], n_classes)).astype(bool)
  42. one_hot[range(labels.shape[0]), labels] = True
  43. return one_hot
  44.  
  45.  
  46. def load_netcdf(filename):
  47. '''
  48. Loads in data from a netcdf file in rnnlib format
  49.  
  50. :parameters:
  51. - filename : str
  52. Path to a netcdf file
  53.  
  54. :returns:
  55. - X : list of np.ndarray
  56. List of time series matrices
  57. - y : list of np.ndarray
  58. List of label arrays in one-hot form (see one_hot)
  59. '''
  60. with open(filename, 'r') as f:
  61. netcdf_data = scipy.io.netcdf_file(f).variables
  62.  
  63. X = []
  64. y = []
  65. n = 0
  66. for length in netcdf_data['seqLengths'].data:
  67. X_n = netcdf_data['inputs'].data[n:n + length]
  68. X.append(X_n.astype(theano.config.floatX))
  69. y_n = one_hot(netcdf_data['targetClasses'].data[n:n + length],
  70. netcdf_data['numTargetClasses'].data)
  71. y.append(y_n.astype(theano.config.floatX))
  72. n += length
  73. return X, y
  74.  
  75.  
  76. def make_batches(X, length, batch_size=BATCH_SIZE):
  77. '''
  78. Convert a list of matrices into batches of uniform length
  79.  
  80. :parameters:
  81. - X : list of np.ndarray
  82. List of matrices
  83. - length : int
  84. Desired sequence length. Smaller sequences will be padded with 0s,
  85. longer will be truncated.
  86. - batch_size : int
  87. Mini-batch size
  88.  
  89. :returns:
  90. - X_batch : np.ndarray
  91. Tensor of time series matrix batches,
  92. shape=(n_batches, batch_size, length, n_features)
  93. - X_mask : np.ndarray
  94. Mask denoting whether to include each time step of each time series
  95. matrix
  96. '''
  97. n_batches = len(X)//batch_size
  98. X_batch = np.zeros((n_batches, batch_size, length, X[0].shape[1]),
  99. dtype=theano.config.floatX)
  100. X_mask = np.zeros(X_batch.shape, dtype=np.bool)
  101. for b in range(n_batches):
  102. for n in range(batch_size):
  103. X_m = X[b*batch_size + n]
  104. X_batch[b, n, :X_m.shape[0]] = X_m[:length]
  105. X_mask[b, n, :X_m.shape[0]] = 1
  106. return X_batch, X_mask
  107.  
  108.  
  109. logger.info('Loading data...')
  110. X_train, y_train = load_netcdf(TRAIN_NC)
  111. X_train = X_train
  112. y_train = y_train
  113. X_val, y_val = load_netcdf(VAL_NC)
  114. X_val = X_val
  115. y_val = y_val
  116.  
  117. print X_train[0].shape
  118.  
  119. # Find the longest sequence
  120. length = max(max([X.shape[0] for X in X_train]),
  121. max([X.shape[0] for X in X_val]))
  122. # Convert to batches of time series of uniform length
  123. X_train, _ = make_batches(X_train, length)
  124. y_train, train_mask = make_batches(y_train, length)
  125. X_val, _ = make_batches(X_val, length)
  126. y_val, val_mask = make_batches(y_val, length)
  127.  
  128. n_epochs = 500
  129. learning_rate = 10
  130. momentum = .9
  131. precompute = False
  132. l_in = lasagne.layers.InputLayer(shape=(BATCH_SIZE, length, X_val.shape[-1]))
  133. l_noise = lasagne.layers.GaussianNoiseLayer(l_in, sigma=0.6)
  134.  
  135. l_forward_1 = lasagne.layers.LSTMLayer(l_noise, num_units=156, backwards=False, precompute_input=precompute)
  136. l_backward_1 = lasagne.layers.LSTMLayer(l_noise, num_units=156, backwards=True, precompute_input=precompute)
  137. l_recurrent_1 = lasagne.layers.ElemwiseSumLayer(
  138. [l_forward_1, l_backward_1])
  139.  
  140. l_forward_2 = lasagne.layers.LSTMLayer(
  141. l_recurrent_1, num_units=300, backwards=False, precompute_input=precompute)
  142. l_backward_2 = lasagne.layers.LSTMLayer(
  143. l_recurrent_1, num_units=300, backwards=True, precompute_input=precompute)
  144. l_recurrent_2 = lasagne.layers.ElemwiseSumLayer(
  145. [l_forward_2, l_backward_2])
  146.  
  147. l_forward_3 = lasagne.layers.LSTMLayer(
  148. l_recurrent_2, num_units=102, backwards=False, precompute_input=precompute)
  149. l_backward_3 = lasagne.layers.LSTMLayer(
  150. l_recurrent_2, num_units=102, backwards=False, precompute_input=precompute)
  151. l_recurrent_3 = lasagne.layers.ElemwiseSumLayer(
  152. [l_forward_3, l_backward_3])
  153.  
  154. l_reshape = lasagne.layers.ReshapeLayer(l_recurrent_3, (-1, 102))
  155. nonlinearity = lasagne.nonlinearities.softmax
  156. l_rec_out = lasagne.layers.DenseLayer(l_reshape, num_units=y_val.shape[-1],
  157. nonlinearity=nonlinearity)
  158. l_out = lasagne.layers.ReshapeLayer(l_rec_out,
  159. (BATCH_SIZE, length, y_val.shape[-1]))
  160.  
  161. # Cost function is mean squared error
  162. input = T.tensor3('input')
  163. target_output = T.tensor3('target_output')
  164. mask = T.tensor3('mask')
  165.  
  166.  
  167. def cost(output):
  168. return -T.sum(mask*target_output*T.log(output))/T.sum(mask)
  169.  
  170. cost_train = cost(lasagne.layers.get_output(l_out, input, deterministic=False))
  171. cost_eval = cost(lasagne.layers.get_output(l_out, input, deterministic=True))
  172.  
  173.  
  174. # Use SGD for training
  175. all_params = lasagne.layers.get_all_params(l_out, trainable=True)
  176. logger.info('Computing updates...')
  177. updates = lasagne.updates.momentum(cost_train, all_params,
  178. learning_rate, momentum)
  179. logger.info('Compiling functions...')
  180. # Theano functions for training, getting output, and computing cost
  181. train = theano.function([input, target_output, mask], cost_train,
  182. updates=updates)
  183. y_pred = theano.function([input], lasagne.layers.get_output(l_out, input, deterministic=True))
  184. compute_cost = theano.function([input, target_output, mask], cost_eval)
  185.  
  186. logger.info('Training...')
  187. # Train the net
  188. for epoch in range(n_epochs):
  189.  
  190. batch_shuffle = np.random.choice(X_train.shape[0], X_train.shape[0], False)
  191. for sequences, labels, sequence_mask in zip(X_train[batch_shuffle],
  192. y_train[batch_shuffle],
  193. train_mask[batch_shuffle]):
  194.  
  195. start_time = time.time()
  196. sequence_shuffle = np.random.choice(sequences.shape[0],
  197. sequences.shape[0], False)
  198. train(sequences[sequence_shuffle], labels[sequence_shuffle],
  199. sequence_mask[sequence_shuffle])
  200. end_time = time.time()
  201.  
  202. print end_time - start_time
  203. cost_val = sum([compute_cost(X_val_n, y_val_n, mask_n)
  204. for X_val_n, y_val_n, mask_n,
  205. in zip(X_val, y_val, val_mask)])
  206. y_val_pred = np.array([y_pred(X_val_n) for X_val_n in X_val])
  207. y_val_labels = np.argmax(y_val*val_mask, axis=-1).flatten()
  208. y_val_pred_labels = np.argmax(y_val_pred*val_mask, axis=-1).flatten()
  209. n_time_steps = np.sum(val_mask)/val_mask.shape[-1]
  210. error = np.sum(y_val_labels != y_val_pred_labels)/float(n_time_steps)
  211. logger.info("Epoch {} took {}, cost = {}, error = {}".format(
  212. epoch, end_time - start_time, cost_val, error))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement