Advertisement
philRG

NN demystified (Lessons 1 - 5) only - Lesson 6 missing

Oct 7th, 2021
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.01 KB | None | 0 0
  1. import sys
  2. import math
  3.  
  4. from matplotlib.pyplot import *
  5. import numpy as np
  6. from scipy import optimize
  7. from math import *
  8.  
  9. def idebug(*args):
  10.     # return
  11.     print(*args, file=sys.stderr, flush=True)
  12.  
  13.  
  14. def debug(*args):
  15.     # return
  16.     print(*args, file=sys.stderr, flush=True)
  17.  
  18.  
  19. """Neural Networks Demystified [Part 6: Training]"""
  20.  
  21.  
  22. class Trainer(object):
  23.     def __init__(self, N):
  24.         # Make local reference to Neural Network:
  25.         self.N = N
  26.  
  27.     def costFunctionWrapper(self, params, X, y):
  28.         self.N.setParams(params)
  29.         cost = self.N.costFunction(X, y)
  30.         grad = self.N.computeGradients(X, y)
  31.         return cost, grad
  32.  
  33.     def callbackF(self, params):
  34.         self.N.setParams(params)
  35.         self.J.append(self.N.costFunction(self.X, self.y))
  36.  
  37.     def train(self, X, y, max_iterations):
  38.         # Make internal variable for callback function:
  39.         self.X = X
  40.         self.y = y
  41.  
  42.         # Make empty list to store costs:
  43.         self.J = []
  44.  
  45.         params0 = self.N.getParams()
  46.  
  47.         options = {'maxiter': max_iterations, 'disp': True}
  48.         _res = optimize.minimize(self.costFunctionWrapper, params0, jac=True, method='BFGS', args=(X, y), options=options, callback=self.callbackF)
  49.  
  50.         self.N.setParams(_res.x)
  51.         self.optimizationResults = _res
  52.  
  53.  
  54. class Neural_Network(object):
  55.     def __init__(self, inputs, outputs, hidden_layers):
  56.         # Define Hyperparameters
  57.         self.inputLayerSize = inputs
  58.         self.outputLayerSize = outputs
  59.         self.hiddenLayerSize = hidden_layers
  60.  
  61.         # Weights (Parameters)
  62.         self.W1 = np.random.randn(self.inputLayerSize, self.hiddenLayerSize)
  63.         self.W2 = np.random.randn(self.hiddenLayerSize, self.outputLayerSize)
  64.  
  65.     def forward(self, X):
  66.         # Propagate inputs through network
  67.         self.z2 = np.dot(X, self.W1)
  68.         self.a2 = self.sigmoid(self.z2)
  69.         self.z3 = np.dot(self.a2, self.W2)
  70.         yHat = self.sigmoid(self.z3)
  71.         return yHat
  72.  
  73.     def sigmoid(self, z):
  74.         """Apply sigmoid activation function to scalar, vector, or matrix"""
  75.         return 1 / (1 + np.exp(-z))
  76.  
  77.     def sigmoidPrime(self, z):
  78.         """Derivative of Sigmoid function"""
  79.         return np.exp(-z) / ((1 + np.exp(-z))**2)
  80.  
  81.     def costFunction(self, X, y):
  82.         """Compute cost for given X, y, used weights already stored in class."""
  83.         self.yHat = self.forward(X)
  84.         J = 0.5 * sum((y - self.yHat) ** 2)
  85.         return J
  86.  
  87.     def costFunctionPrime(self, X, y):
  88.         """Compute derivative with respect to W1 and W2"""
  89.         self.yHat = self.forward(X)
  90.  
  91.         delta3 = np.multiply(-(y - self.yHat), self.sigmoidPrime(self.z3))
  92.         dJdW2 = np.dot(self.a2.T, delta3)
  93.  
  94.         delta2 = np.dot(delta3, self.W2.T) * self.sigmoidPrime(self.z2)
  95.         dJdW1 = np.dot(X.T, delta2)
  96.  
  97.         return dJdW1, dJdW2
  98.  
  99.     """Neural Networks Demystified [Part 5: Numerical Gradient Checking]"""
  100.  
  101.     # Helper functions for interacting with other methods/classes
  102.     def getParams(self):
  103.         """Get W1 and W2 Rolled into vector:"""
  104.         params = np.concatenate((self.W1.ravel(), self.W2.ravel()))
  105.         return params
  106.  
  107.     def setParams(self, params):
  108.         """Set W1 and W2 usint single parameter vector:"""
  109.         W1_start = 0
  110.         W1_end = self.hiddenLayerSize * self.inputLayerSize
  111.         self.W1 = np.reshape(params[W1_start: W1_end], (self.inputLayerSize, self.hiddenLayerSize))
  112.         W2_end = W1_end + self.hiddenLayerSize * self.outputLayerSize
  113.         self.W2 = np.reshape(params[W1_end: W2_end], (self.hiddenLayerSize, self.outputLayerSize))
  114.  
  115.     def computeGradients(self, X, y):
  116.         dJdW1, dJdW2 = self.costFunctionPrime(X, y)
  117.         return np.concatenate((dJdW1.ravel(), dJdW2.ravel()))
  118.  
  119.     def computeNumericalGradient(self, N, X, y):
  120.         paramsInitial = N.getParams()
  121.         numgrad = np.zeros(paramsInitial.shape)
  122.         perturb = np.zeros(paramsInitial.shape)
  123.         e = 1e-4
  124.         for p in range(len(paramsInitial)):
  125.             # Set perturbation vector
  126.             perturb[p] = e
  127.             N.setParams(paramsInitial + perturb)
  128.             loss2 = N.costFunction(X, y)
  129.  
  130.             N.setParams(paramsInitial - perturb)
  131.             loss1 = N.costFunction(X, y)
  132.  
  133.             # Compute Numerical Gradient:
  134.             numgrad[p] = (loss2 - loss1) / (2 * e)
  135.  
  136.             # Return the value we changed back to zero:
  137.             perturb[p] = 0
  138.  
  139.         # Return Params to original value:
  140.         N.setParams(paramsInitial)
  141.  
  142.         return numgrad
  143.  
  144.  
  145. # Auto-generated code below aims at helping you parse
  146. # the standard input according to the problem statement.
  147.  
  148. line = input()
  149. idebug(line)
  150. inputs, outputs, hidden_layers, test_inputs, training_examples, training_iterations = [int(i) for i in line.split()]
  151.  
  152. tic = time.time()
  153.  
  154. line = input()
  155. idebug(line)
  156. nodes = [int(i) for i in line.split()]
  157.  
  158. test_data = []
  159. for i in range(test_inputs):
  160.     test_input = input()
  161.     idebug(test_input)
  162.     test_data.append(list(test_input))
  163.  
  164. X_test = np.array(test_data, dtype=int)
  165.  
  166. training_data = set()
  167. X = np.array([], dtype=int)
  168. y = np.array([], dtype=int)
  169. training_inputs_list = []
  170. training_data_list = []
  171. for i in range(training_examples):
  172.     line = input()
  173.     idebug(line)
  174.     training_inputs, expected_outputs = line.split()
  175.     training_data.add((training_inputs, expected_outputs))
  176.     training_inputs_list.append(list(training_inputs))
  177.     training_data_list.append(list(expected_outputs))
  178.  
  179. X = np.array(training_inputs_list, dtype=int)
  180. y = np.array(training_data_list, dtype=int)
  181.  
  182. NN = Neural_Network(inputs, outputs, hidden_layers)
  183. T = Trainer(NN)
  184. T.train(X, y, training_iterations)
  185. plot(T.J)
  186. grid(1)
  187. ylabel('Cost')
  188. xlabel('Iterations')
  189.  
  190. yHat = NN.forward(X_test)
  191. for i in range(test_inputs):
  192.     # Write an answer using print
  193.     # To debug: print("Debug messages...", file=sys.stderr, flush=True)
  194.  
  195.     print(yHat[i])
  196.  
  197. debug(f'elapsed time = {round((time.time() - tic) * 1000, 2)} ms')
  198.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement