In [1]:
import numpy as np
#We are defining the NN here which will take only the length of nodes in each of the 3 layers as
class NN:
def __init__(self,i,h,o):
self.i=i;
self.o=o;
self.h=h;
self.w1=np.random.normal(0,1,(i+1,h));
self.w2=np.random.normal(0,1,(h+1,o));
self.I=np.zeros((i+1));
self.H=np.zeros((h+1));
self.O=np.zeros((o));
def sigmoid(self,x):
return(1/(1+np.exp(-(x))))
def dsigmoid(self,y):
return(np.multiply(y,(1-y)))
def feedforward(self,inputs):
self.I=np.append(inputs,[1])
#print(self.I.shape)
self.H=np.append(self.sigmoid(np.dot(self.I,self.w1)),[1])
self.O=self.sigmoid(np.dot(self.H,self.w2))
return([self.H,self.O])
def backpropagate(self,inputs,targets,lr=0.001,lossfunc="logloss"):
if(lossfunc=="squareloss"):
outputs=self.feedforward(inputs)
hiddens=outputs[0];
outputs=outputs[1];
errorterm2=outputs-targets #actually it is (-error)
w2gradient=np.dot((self.H).reshape(((self.h+1),1)),(errorterm2*self.dsigmoid(outputs)).reshape((1,self.o)))
xgrad=np.multiply(self.w2,(errorterm2*self.dsigmoid(outputs)))
errorterm1=np.sum(xgrad[:-1],axis=1)
w1gradient=np.dot((self.I).reshape(((self.i+1),1)),(errorterm1*self.dsigmoid(hiddens[:-1])).reshape((1,self.h)))
elif(lossfunc=="logloss"):
outputs=self.feedforward(inputs)
hiddens=outputs[0];
outputs=outputs[1];
errorterm2=0-targets/(0.0001+outputs)+(1-targets)/(1.0001-outputs) #actually it is (-error)... 0.0001 is added to avoid hitting infinity
w2gradient=np.dot((self.H).reshape(((self.h+1),1)),(errorterm2*self.dsigmoid(outputs)).reshape((1,self.o)))
xgrad=np.multiply(self.w2,(errorterm2*self.dsigmoid(outputs)))
errorterm1=np.sum(xgrad[:-1],axis=1)
w1gradient=np.dot((self.I).reshape(((self.i+1),1)),(errorterm1*self.dsigmoid(hiddens[:-1])).reshape((1,self.h)))
#update step
self.w1=self.w1-w1gradient*lr;
self.w2=self.w2-w2gradient*lr;
def train(self,inputs,targets,lr=0.001,niter=1000,lossfunc="logloss"):
for u in range(niter):
for row in range(len(inputs)):
self.backpropagate(inputs[row],targets[row],lr,lossfunc)
self.evaluate(inputs,targets,lossfunc)
def evaluate(self,inputs,targets,lossfunc="logloss"):
if(lossfunc=="squareloss"):
print(np.mean(([np.square(self.feedforward(inputs[ii])[1]-targets[ii]) for ii in range(len(inputs))])))
print(" *****error printed***** ")
elif(lossfunc=="logloss"):
print(np.mean(([np.square(self.feedforward(inputs[ii])[1]-targets[ii]) for ii in range(len(inputs))])))
print(" *****error printed***** ")
In [2]:
model=NN(2,5,2)
In [3]:
ins=np.random.randint(0,2,(4000,2))
outs=np.array([[g[0]*g[1],(g[0]+g[1]>0)*1] for g in ins])
In [4]:
model.train(ins,outs,0.5,20,"squareloss")
In [5]:
model2=NN(2,5,2)
model2.train(ins,outs,0.5,20,"logloss")
In [ ]: