Advertisement
jckuri

SmallNeuralNetwork.py

Nov 7th, 2016
1,681
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.04 KB | None | 0 0
  1. import numpy as np
  2. import math as m
  3. import random as r
  4. import time as t
  5.  
  6. def sigmoid(x):
  7.  return 1.0/(1.0+m.exp(-x))
  8.  
  9. vectorizedSigmoid=np.vectorize(sigmoid)
  10.  
  11. def sigmoidDerivative(y):
  12.  return y*(1-y)  
  13.  
  14. vectorizedSigmoidDerivative=np.vectorize(sigmoidDerivative)
  15.  
  16. class NeuralNetwork:
  17.    
  18.  def __init__(self,hiddenLayers,samples):
  19.   self.hiddenLayers=hiddenLayers
  20.   self.samples=listsToNumPyMatrixes(samples)
  21.   self.l2Lambda=0.001
  22.   self.alpha=1
  23.   #self.precision=1e-8
  24.   self.convergence=1e-6
  25.   self.converged=False
  26.   self.setLayerSizes()
  27.   self.cost=self.costFunction()
  28.  
  29.  def setLayerSizes(self):
  30.   nInput=len(self.samples[0][0])
  31.   nOutput=len(self.samples[0][1])
  32.   self.nLayers=[nInput]+self.hiddenLayers+[nOutput]
  33.   self.layerSizes=[(self.nLayers[i+1],self.nLayers[i]) for i in range(len(self.nLayers)-1)]
  34.   print('Layer sizes: {}'.format(self.layerSizes))
  35.   self.setInitialWeights()
  36.  
  37.  def setInitialWeights(self):
  38.   self.weights=[]
  39.   for (nRows,nColumns) in self.layerSizes:
  40.    self.weights.append(getRandomMatrix((nRows,nColumns+1)))
  41.    
  42.  def feedForward(self,input):
  43.   activation=input
  44.   for matrix in self.weights:
  45.    activation=addRowToNumPyMatrix(activation,[1])
  46.    activation=vectorizedSigmoid(matrix*activation)
  47.   return activation
  48.    
  49.  def costFunctionPerSample(self,sample):
  50.   (input,output)=sample
  51.   lastA=self.feedForward(input)
  52.   return np.sum(vectorizedLogisticCost(output,lastA))
  53.  
  54.  def costFunction(self):
  55.   costsSum=0
  56.   n=len(self.samples)
  57.   for sample in self.samples:
  58.    costsSum+=self.costFunctionPerSample(sample)
  59.   sss=0
  60.   for matrix in self.weights:
  61.    sss+=np.sum(vectorizedSquare(matrix))
  62.   return -costsSum/n+self.l2Lambda*sss/(2*n)
  63.            
  64.  def costDerivative(self, output_activations, y):
  65.   return (output_activations-y)      
  66.  
  67.  def backpropagation(self,x,y):
  68.   nablaW=[np.zeros(w.shape) for w in self.weights]
  69.   activation=addRowToNumPyMatrix(x,[1])
  70.   activations=[activation]
  71.   zs=[]
  72.   deltas=[]
  73.   for w in self.weights:
  74.    z=w*activation
  75.    zs.append(z)
  76.    activation=addRowToNumPyMatrix(vectorizedSigmoid(z),[1])
  77.    activations.append(activation)
  78.   delta=activations[-1]-addRowToNumPyMatrix(y,[1])
  79.   nablaW[-1]=removeLastRowOfNumPyMatrix(delta*activations[-2].transpose())
  80.   numberOfLayers=len(self.nLayers)
  81.   for l in range(2,numberOfLayers):
  82.    wt=self.weights[-l+1].transpose()
  83.    sd=vectorizedSigmoidDerivative(activations[-l])
  84.    lastDeltaWithoutBias=removeLastRowOfNumPyMatrix(delta)
  85.    delta=np.multiply(wt*lastDeltaWithoutBias,sd)
  86.    nablaW[-l]=removeLastRowOfNumPyMatrix(delta*activations[-l-1].transpose())
  87.   return nablaW
  88.  
  89.  def backpropagateAllSamples(self):
  90.   nablaWSum=[np.zeros(w.shape) for w in self.weights]
  91.   nMatrix=len(nablaWSum)
  92.   nSamples=len(self.samples)
  93.   for sample in self.samples:
  94.    (x,y)=sample
  95.    nablaW=self.backpropagation(x,y)
  96.    for matrixIndex in range(nMatrix):
  97.     nablaWSum[matrixIndex]+=nablaW[matrixIndex]
  98.   for matrixIndex in range(nMatrix):
  99.    nablaWSum[matrixIndex]=(nablaWSum[matrixIndex]+self.l2Lambda*self.weights[matrixIndex])/nSamples
  100.   return nablaWSum
  101.  
  102.  def iterate(self):
  103.   g=self.backpropagateAllSamples()
  104.   nMatrix=len(self.weights)
  105.   for matrixIndex in range(nMatrix):
  106.    self.weights[matrixIndex]-=self.alpha*g[matrixIndex]
  107.   totalCost=self.costFunction()
  108.   if(abs(totalCost-self.cost)<self.convergence): self.converged=True
  109.   self.cost=totalCost
  110.  
  111.  def printIteration(self):
  112.   print('Iteration '+str(self.iteration)+'. Error: '+str(self.cost))
  113.  
  114.  def iterateUntilConvergence(self):
  115.   t0=t.time()
  116.   self.iteration=0
  117.   self.printIteration()
  118.   while not self.converged:
  119.    self.iteration+=1
  120.    if self.iteration%100==0:
  121.     self.printIteration()
  122.    self.iterate()
  123.   self.printIteration()
  124.   t1=t.time()
  125.   self.deltaTime=t1-t0
  126.   print('Neural network has converged in {:0.2f} seconds.'.format(self.deltaTime))
  127.  
  128. def logisticCost(y,y2):
  129.  return y*m.log(y2)+(1-y)*m.log(1-y2)
  130.  
  131. vectorizedLogisticCost=np.vectorize(logisticCost)
  132.  
  133. def square(x):
  134.  return x*x
  135.  
  136. vectorizedSquare=np.vectorize(square)
  137.  
  138. def addRowToNumPyMatrix(m,row):
  139.  return np.vstack([m,row])
  140.  
  141. def removeLastRowOfNumPyMatrix(m):
  142.  return m[:m.shape[0]-1]
  143.  
  144. def listToNumPyMatrix(l):
  145.  return np.matrix(l).transpose()
  146.  
  147. def columnVectorToList(m):
  148.  return [m[i,0] for i in range(m.shape[0])]
  149.  
  150. def listsToNumPyMatrixes(samples):
  151.  npArrays=[]
  152.  for (x,y) in samples:
  153.   npArrays.append((listToNumPyMatrix(x),listToNumPyMatrix(y)))
  154.  return npArrays
  155.  
  156. def getRandomWeight(maximum):
  157.  return r.random()*2*maximum-maximum
  158.  
  159. def getRandomMatrix(size):
  160.  s=''
  161.  (nRows,nColumns)=size
  162.  for row in range(nRows):
  163.   for column in range(nColumns):
  164.    s+=str(getRandomWeight(1))+' '
  165.   if row<nRows-1: s+=';'
  166.  return np.mat(s)
  167.  
  168. def main():
  169.  samplesXOR=[([0,0],[0]),([0,1],[1]),([1,0],[1]),([1,1],[0])]
  170.  nn=NeuralNetwork([2],samplesXOR)
  171.  nn.iterateUntilConvergence()
  172.  for sample in nn.samples:
  173.   (input,output)=sample
  174.   print('input',input,'output',output,'approximate output',nn.feedForward(input))
  175.  
  176. if __name__ == "__main__":
  177.  main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement