Advertisement
Guest User

nn_lib.py

a guest
Mar 19th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.89 KB | None | 0 0
  1. import numpy as np
  2.  
  3.  
  4. def _define_minibatches(X, Y, mb_size, seed):
  5.     cl = Y.shape[0]
  6.     m = X.shape[1]
  7.     mini_batches = []
  8.     permutation = list(np.random.permutation(m))
  9.     shuffled_X = X[:, permutation]
  10.     shuffled_Y = Y[:, permutation]
  11.     mb_floor = np.floor(m/mb_size).astype(int) #1!!
  12.     for k in range(0, mb_floor):
  13.         mini_batch_X = shuffled_X[:, mb_size*k:mb_size*(k+1)]
  14.         mini_batch_Y = shuffled_Y[:, mb_size*k:mb_size*(k+1)]
  15.         mini_batch = (mini_batch_X, mini_batch_Y)
  16.         mini_batches.append(mini_batch)
  17.     if m % mb_size != 0:
  18.         mini_batch_X = shuffled_X[:,(m-m%mb_size):]
  19.         mini_batch_Y = shuffled_Y[:,(m-m%mb_size):]
  20.         mini_batch = (mini_batch_X, mini_batch_Y)
  21.         mini_batches.append(mini_batch)
  22.     return mini_batches
  23.  
  24.  
  25. def init_parameters(shape, method, bias = True):
  26.     if method == 'he':
  27.         w = np.random.randn(shape[0], shape[1])*np.sqrt(2/shape[1])
  28.     if method == 'rand':
  29.         w = np.random.randn(shape[0], shape[1])
  30.     b = np.zeros((shape[0], 1)) if bias == True else None
  31.     return (w, b)
  32.  
  33. class relu:
  34.     @staticmethod
  35.     def activate(Z):
  36.         s = np.maximum(0,Z)
  37.         return s
  38.     @staticmethod
  39.     def backprop(dA, Z):
  40.         dZ = np.multiply(dA, np.int64(Z > 0))
  41.         return dZ
  42.  
  43. class softmax:
  44.     @staticmethod
  45.     def activate(Z):
  46.         exp_scores = np.exp(Z - np.max(Z))
  47.         s = exp_scores / np.sum(exp_scores, axis=0, keepdims=True)
  48.         return s
  49.     @staticmethod
  50.     def backprop(dA, Z):
  51.         dZ = dA
  52.         return dZ
  53.  
  54.  
  55. class layer():
  56.    
  57.     def __init__(self, hidden_units, activation_func, init_method = 'he'):
  58.         self.hidden_units = hidden_units
  59.         self.activation_func = activation_func
  60.         self.init_method = init_method
  61.    
  62.     @classmethod
  63.     def check(cls):
  64.         return 'layer'
  65.    
  66.     def initialize(self, shape):
  67.         hidden_units_prev = shape[0]
  68.         self.W, self.b = init_parameters((self.hidden_units, hidden_units_prev),
  69.                                           method = self.init_method)
  70.         return (self.hidden_units, hidden_units_prev)
  71.    
  72.     def forward(self, Ap):
  73.         Z = np.dot(self.W, Ap)+self.b
  74.         A = self.activation_func.activate(Z)
  75.         return A, ((Z, self.W), Ap)
  76.    
  77.     def backward_and_update(self, dA, cache, lr):
  78.         ((Z,w), ap) = cache
  79.         dZ = self.activation_func.backprop(dA, Z)
  80.         m = ap.shape[1]
  81.         d_w = np.dot(dZ, ap.T)*(1/m)
  82.         d_b = np.sum(dZ, axis=1, keepdims=True)*(1/m)
  83.         d_a_prev = w.T.dot(dZ)
  84.         assert (d_a_prev.shape == ap.shape)
  85.         assert (d_w.shape == self.W.shape)
  86.         assert (d_b.shape == self.b.shape)
  87.         self.W = self.W - (lr*d_w)
  88.         self.b = self.b - (lr*d_b)
  89.         return d_a_prev
  90.    
  91. class rnn_layer(layer):
  92.    
  93.     def initialize(self, shape):
  94.         n_x, m, T_x = shape
  95.         hidden_units_prev = n_x
  96.         self.Wx, self.b = init_parameters((self.hidden_units, hidden_units_prev),
  97.                                            method = self.init_method)
  98.         self.Wa = init_parameters((self.hidden_units, self.hidden_units),
  99.                                    method = self.init_method,
  100.                                    bias = False)
  101.         self.Aa = np.zeros((self.hidden_units, m, T_x))
  102.         self.A0 = init_parameters((self.hidden_units, m),
  103.                                    method = self.init_method,
  104.                                    bias = False)
  105.        
  106.         return (self.hidden_units, m, T_x)
  107.    
  108.     def forward(self, Ax, Aa):
  109.        
  110.         assert len(Ax.shape)==3
  111.         Tx = Ax.shape[2]
  112.        
  113.        
  114.         for t in range(Tx):
  115.        
  116.             Z = np.dot(self.Wx, Ax[:,:,t]) + np.dot(self.Wa, Aa[:,:,t]) + b
  117.             A = self.activation_func.activate(Z)
  118.             Aa[:,:t] = A
  119.        
  120.        
  121.        
  122.  
  123. class nnet():
  124.  
  125.     def __init__(self):
  126.         self._layers = []
  127.         self.parameters = []
  128.        
  129.     def add(self, layer):
  130.         if layer.check() == 'layer':
  131.             self._layers.append(layer)
  132.         else:
  133.             raise Exception('Unacceptable object')
  134.            
  135.     def train(self, X, Y, lr=0.01, num_epoch = 10000):
  136.        
  137.         self.costs = []
  138.        
  139.         if len(self._layers)==0:
  140.             raise Exception('Layers were not added')
  141.        
  142.        
  143.          #!!!!!!!!!!!!!!!!!!!!!!!
  144.        
  145.         prev_shape = X.shape #for columns as features
  146.        
  147.         #initialize parameters
  148.         for n, l in enumerate(self._layers):
  149.             h = l.initialize(prev_shape)
  150.             prev_shape = h
  151.            
  152.         print('Parameters are initialized\n')
  153.        
  154.         seed = 10
  155.         ###################
  156.         for i in range(num_epoch):
  157.             seed = seed + 1
  158.             epoch_cost = 0
  159.             minibatches = _define_minibatches(X, Y, 64, seed)
  160.             for minibatch in minibatches:
  161.                 (minibatch_X, minibatch_Y) = minibatch
  162.                 caches = []
  163.                 A_prev = minibatch_X
  164.                 #forward propagation
  165.                 for n, l in enumerate(self._layers):
  166.                     A, cache = l.forward(A_prev)
  167.                     A_prev = A
  168.                     caches.append(cache)
  169.  
  170.                 #find current cost and dAL for softmax
  171.                 epoch_cost += - np.mean(np.sum(minibatch_Y*np.log(A), axis=0))
  172.                 dA = A-minibatch_Y
  173.  
  174.                 #backward propagation and parameters update
  175.                 for n,l in reversed(list(enumerate(self._layers))):
  176.                     dA_prev = l.backward_and_update(dA, caches[n], lr)
  177.                     dA = dA_prev
  178.            
  179.             if i % 1000 == 0:
  180.                 print("Cost after epoch %i: %f" %(i, epoch_cost))
  181.             if i % 100 == 0:
  182.                 self.costs.append(epoch_cost)
  183.  
  184.            
  185.         plt.plot(self.costs)
  186.         plt.ylabel('cost')
  187.         plt.xlabel('iterations (per hundreds)')
  188.         plt.title("Learning rate =" + str(lr))
  189.         plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement