Neural Network in python only learning for 1 in-/output pair per dataset? -


i wrote code generating , training artifiacial neural networks in python (with backpropagation). works well, 1 problem bugs me days , can't seem find why:

the network generate decreases error on datasets if sets contain 1 in-/output pair. e.g. input [[1,1]] 2 input neurons , simplicity [[1,1]] output. works well, error decreases. if choose [[1,1],[0,0]] input, error alternates or somestimes goes against 2, no matter how long let work. here code:

import numpy np graphics import * import math  class neuron():      def __init__(self,input=0,output=0,activation_func_key="logistic",bias=false,inp=false):         self.b = bias         self.input = input + self.b         self.output = output         self.key = activation_func_key         self.inp = inp      def add_to_input(self,input_=0):         self.input += input_      def add_to_input(self,input_=0):         self.input += float(input_)      def get_output(self):         if self.b:             return 1         if self.inp:             return self.input         if self.key "relu":             return np.maximum((self.input),0)         if self.key "tanh":             return np.tanh(self.input)         if self.key "softplus":             return np.log(1+np.e**(self.input))         if self.key "logistic":             return 1/(1+np.e**-(self.input))      def reset(self):         self.input = 0         self.ouput = 0  class network():      def __init__(self,weight_matrix,input_neuron_num,hidden_neuron_nums,ouput_neuron_num,activation_f="relu"):         self.weight_matrix = weight_matrix         self.neurons = [neuron(activation_func_key=activation_f) _ in range(weight_matrix[0].__len__())]          back_layers = 0         val = input_neuron_num         counter = 0          in range(weight_matrix[0].__len__()):             bias = false             inp = false              if val:                 bias = true                 if counter < hidden_neuron_nums.__len__():                     val += hidden_neuron_nums[counter]+1                 counter += 1              if < input_neuron_num:                 inp = true              self.neurons[i] = neuron(activation_func_key=activation_f,inp=inp,bias=bias)          self.input_neuron_num = input_neuron_num         self.hidden_neuron_nums = hidden_neuron_nums         self.output_neuron_num = ouput_neuron_num      def propagate_forward(self,inputv,output_len):         in range(self.neurons.__len__()):             if < self.input_neuron_num:                 self.neurons[i].add_to_input(inputv[i])             else:                 spalte = self.weight_matrix[:][i]                  j in range(spalte.__len__()):                     #if > j: #nur obere dreiecksmatrix                     self.neurons[i].add_to_input(self.weight_matrix[j][i] * self.neurons[j].get_output())         output = []         in range(output_len):             output.append(self.neurons[self.weight_matrix[0].__len__()-i-1].get_output())          output.reverse()          return output      def reset(self):         n in self.neurons:             n.reset()  def make_net(inp,hidden,out,activation_f="logistic"):      hsum = 0     in range(hidden.__len__()):         hsum += hidden[i]+1      sum = inp + 1 + hsum + out      weights = [[0 _ in range(sum)] _ in range(sum)]      neurons_till_this_layer = 0      in range(inp+1):         j in range(hidden[0]):             weights[i][inp+j+1] = np.random.uniform(-1,1)      neurons_till_this_layer += inp+1      in range(hidden.__len__()-1):         n in range(hidden[i]+1):             m in range(hidden[i+1]):                 weights[n+neurons_till_this_layer][m+neurons_till_this_layer+hidden[i]+1] = np.random.uniform(-1,1)         neurons_till_this_layer += hidden[i]+1      in range(hidden[hidden.__len__()-1]+1):         j in range(out):             weights[i+neurons_till_this_layer][j+neurons_till_this_layer+hidden[hidden.__len__()-1]+1] = np.random.uniform(-1,1)      net = network(weights,inp,hidden,out,activation_f=activation_f)      return net  def backpropagation(net,inputs,outputs,learning_rate=0.001,epsilon=0.1,draw=false,win=0):      if draw:         win = 0         if win not 0:             win = win         else:             win = draw_window(net)      if inputs[0][:].__len__() not net.input_neuron_num:         print("error: input length not match! no learning done!")         return net     if outputs[0][:].__len__() not net.output_neuron_num:         print("error: output length not match! no learning done!")         return net      hsum = 0     in range(net.hidden_neuron_nums.__len__()):         hsum += net.hidden_neuron_nums[i]+1      outer_delta_w_matrix = [[0 _ in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num)] _ in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num)]      n in range(inputs.__len__()):          net_output = net.propagate_forward(inputs[n],outputs[0].__len__())          delta_w_matrix = [[0 _ in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num)] _ in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num)]         delta_j_list = [float(0) _ in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num)]          in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num):             j = net.input_neuron_num + 1 + hsum + net.output_neuron_num - - 1             derivate = "error"             if net.neurons[j].key "relu":                 derivate = 0 if net.neurons[j].input <= 0 else 1             if net.neurons[j].key "tanh":                 derivate = (1 / (np.cosh(net.neurons[j].input) * np.cosh(net.neurons[j].input)))             if net.neurons[j].key "softplus":                 derivate = 1 / (1 + np.e ** -net.neurons[j].input)             if net.neurons[j].key "logistic":                 #print(" input: %f" % net.neurons[j].input)                 derivate = (np.exp(net.neurons[j].input)) / (((np.exp(net.neurons[j].input)) + 1) ** 2)                 #derivate = net.neurons[j].output * (1 - net.neurons[i].get_output())             if < net.output_neuron_num:                 delta_j_list[j] = derivate * (net.neurons[j].get_output() - float(outputs[n][net.output_neuron_num-i-1]))             else:                 prev_delta_sum = 0                 x in range(net.weight_matrix[j][:].__len__()):                     prev_delta_sum += (delta_j_list[j-x] * net.weight_matrix[j][x])                 #print(net.neurons[j].input)                 delta_j_list[j] = derivate * prev_delta_sum          in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num):             j in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num):                 if net.weight_matrix[i][j]:                     delta_w_matrix[i][j] = -learning_rate * delta_j_list[j] * net.neurons[i].get_output()          in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num):             j in range(net.input_neuron_num + 1 + hsum + net.output_neuron_num):                 outer_delta_w_matrix[i][j] += (delta_w_matrix[i][j] / (inputs.__len__()))          #print_matrix(net.weight_matrix)         #print()          #print("completed cycle")          net.reset()      in range(net.input_neuron_num + hsum + net.output_neuron_num):         j in range(net.input_neuron_num + hsum + net.output_neuron_num):             if net.weight_matrix[i][j]:                 net.weight_matrix[i][j] = net.weight_matrix[i][j] + outer_delta_w_matrix[i][j]      if draw:         draw_net(net, win)      return net  def print_matrix(matrix):      = matrix[0][:]     b = matrix[:][0]      in range(a.__len__()):         print()         j in range(b.__len__()):             sys.stdout.write("% 1.7f " % matrix[i][j])      print()  def get_dataset_binary(dataset_length=1000,max=4):      rdm_nums = [np.random.randint(0,2**max) _ in range(dataset_length)]      bin_nums = [0 _ in range(rdm_nums.__len__())]      length = max      in range(rdm_nums.__len__()):         bin_nums[i] = "{0:b}".format(rdm_nums[i])         while bin_nums[i].__len__() < length:             bin_nums[i] = "0" + bin_nums[i]      r_value = [0 _ in range(dataset_length)]      in range(dataset_length):         r_value[i] = list(bin_nums[i])      return r_value  def draw_window(net,autoflush=false):     width = 0     in range(net.hidden_neuron_nums.__len__()):         if net.hidden_neuron_nums[i] > width:             width = net.hidden_neuron_nums[i]      if net.input_neuron_num > width:         width = net.input_neuron_num     if net.output_neuron_num > width:         width = net.output_neuron_num      scale_factor = 0.7      counter = 0     r = 50*scale_factor     v_buf = 100*scale_factor     h_buf = 50*scale_factor     d1 = 20*scale_factor     d2 = 12*scale_factor      return graphwin("netzwerk", (2*h_buf)+(width*2*r)+(width*h_buf)-h_buf, 2 * v_buf + 2*r+v_buf + net.hidden_neuron_nums.__len__()*2*r + net.hidden_neuron_nums.__len__()*v_buf-v_buf + 2*r+v_buf, autoflush=autoflush)  def draw_net(net,win=0):      width = 0     in range(net.hidden_neuron_nums.__len__()):         if net.hidden_neuron_nums[i] > width:             width = net.hidden_neuron_nums[i]+1      if net.input_neuron_num > width:         width = net.input_neuron_num+1     if net.output_neuron_num > width:         width = net.output_neuron_num      scale_factor = 0.7      counter = 0     r = 50*scale_factor     v_buf = 100*scale_factor     h_buf = 50*scale_factor     d1 = 20*scale_factor     d2 = 12*scale_factor      if win 0:         win = graphwin("netzwerk", (2*h_buf)+(width*2*r)+(width*h_buf)-h_buf, 2 * v_buf + 2*r+v_buf + net.hidden_neuron_nums.__len__()*2*r + net.hidden_neuron_nums.__len__()*v_buf-v_buf + 2*r+v_buf)      in range(net.weight_matrix.__len__()):         j in range(net.weight_matrix.__len__()):             if net.weight_matrix[i][j] not 0:                 from_pos = get_neuron_pos(net,i,r,v_buf,h_buf,width)                 to_pos = get_neuron_pos(net,j,r,v_buf,h_buf,width)                  thickness = np.abs(net.weight_matrix[i][j]) * 10                  weight = polygon([point(from_pos.x-thickness,from_pos.y), point(from_pos.x+thickness,from_pos.y),point(to_pos.x+thickness,to_pos.y), point(to_pos.x-thickness,to_pos.y)])                 if net.weight_matrix[i][j] > 0:                     weight.setfill("firebrick4")                 else:                     weight.setfill("lightskyblue")                  label = text(point((from_pos.x+to_pos.x)/2, (from_pos.y+to_pos.y)/2), "%0.5f" % net.weight_matrix[i][j])                 label.setsize(np.maximum(int(10*scale_factor),5))                  weight.draw(win)                 label.draw(win)      hidden_neuron_num = 0      in range(net.hidden_neuron_nums.__len__()):         hidden_neuron_num += net.hidden_neuron_nums[i]+1      in range(net.input_neuron_num+1):         inp_neuron = circle(point( (win.width - ((net.input_neuron_num+1) * 2 * r + (net.input_neuron_num+1) * h_buf - h_buf))/2 + i*(2*r+h_buf) + r, v_buf+r),r)         inp_neuron.setfill("springgreen3")         if net.input_neuron_num:             inp_neuron.setfill("snow")         name = text(point((win.width - ((net.input_neuron_num+1) * 2 * r + (net.input_neuron_num+1) * h_buf - h_buf))/2 + i*(2*r+h_buf) + r, v_buf+r-d1), "%s" % ("neuron(in) " + str(counter+1)))         if net.input_neuron_num:             name.settext("%s" % ("neuron(bias) " + str(counter+1)))         label = text(point((win.width - ((net.input_neuron_num+1) * 2 * r + (net.input_neuron_num+1) * h_buf - h_buf))/2 + i*(2*r+h_buf) + r, v_buf+r+d2), "output:\n%1.6f" % float(net.neurons[counter].get_output()))          name.setsize(np.maximum(int(10*scale_factor),5))         label.setsize(np.maximum(int(10*scale_factor),5))          inp_neuron.draw(win)         name.draw(win)         label.draw(win)         counter +=1      in range(net.hidden_neuron_nums.__len__()):         j in range(net.hidden_neuron_nums[i]+1):             hidden_neuron = circle(point((win.width-((net.hidden_neuron_nums[i]+1)*2*r+(net.hidden_neuron_nums[i]+1)*h_buf-h_buf))/2+j*(2*r+h_buf)+r,(3*r+2*v_buf)+i*(2*r+v_buf)),r)             hidden_neuron.setfill("lavender")             if j net.hidden_neuron_nums[i]:                 hidden_neuron.setfill("snow")             name = text(point((win.width-((net.hidden_neuron_nums[i]+1)*2*r+(net.hidden_neuron_nums[i]+1)*h_buf-h_buf))/2+j*(2*r+h_buf)+r, (3*r+2*v_buf)+i*(2*r+v_buf)-d1), "%s" % ("neuron " + str(counter+1)))             if j net.hidden_neuron_nums[i]:                 name.settext("%s" % ("neuron(bias) " + str(counter+1)))             label = text(point((win.width-((net.hidden_neuron_nums[i]+1)*2*r+(net.hidden_neuron_nums[i]+1)*h_buf-h_buf))/2+j*(2*r+h_buf)+r, (3*r+2*v_buf)+i*(2*r+v_buf)+d2), "output:\n%1.6f" % net.neurons[counter].get_output())              name.setsize(np.maximum(int(10*scale_factor),5))             label.setsize(np.maximum(int(10*scale_factor),5))              hidden_neuron.draw(win)             name.draw(win)             label.draw(win)             counter += 1      in range(net.output_neuron_num):         out_neuron = circle(point((win.width-(net.output_neuron_num*2*r+net.output_neuron_num*h_buf-h_buf))/2+i*(2*r+h_buf)+r, net.hidden_neuron_nums.__len__()*2*r + 2*r + net.hidden_neuron_nums.__len__()*v_buf + 2* v_buf + r),r)         out_neuron.setfill("darkgoldenrod3")         name = text(point((win.width-(net.output_neuron_num*2*r+net.output_neuron_num*h_buf-h_buf))/2+i*(2*r+h_buf)+r, net.hidden_neuron_nums.__len__()*2*r + 2*r + net.hidden_neuron_nums.__len__()*v_buf + 2* v_buf + r - d1), "%s" % ("neuron(out) " + str(counter+1)))         label = text(point((win.width-(net.output_neuron_num*2*r+net.output_neuron_num*h_buf-h_buf))/2+i*(2*r+h_buf)+r, net.hidden_neuron_nums.__len__()*2*r + 2*r + net.hidden_neuron_nums.__len__()*v_buf + 2* v_buf + r + d2), "output:\n%1.6f" % net.neurons[counter].get_output())          name.setsize(np.maximum(int(10*scale_factor),5))         label.setsize(np.maximum(int(10*scale_factor),5))          out_neuron.draw(win)         name.draw(win)         label.draw(win)         counter += 1      win.update()      win.wait_window()  def get_neuron_pos(net, n, r, v_buf, h_buf, width):      if n < net.input_neuron_num+1:          return point(((2*h_buf)+(width*2*r)+(width*h_buf)-h_buf - ((net.input_neuron_num+1) * 2 * r + (net.input_neuron_num+1) * h_buf - h_buf)) / 2 + n * (2 * r + h_buf) + r, v_buf + r)      current = net.input_neuron_num+1      h in range(net.hidden_neuron_nums.__len__()):         current += (net.hidden_neuron_nums[h]+1)         if n < current:             return point(((2*h_buf)+(width*2*r)+(width*h_buf)-h_buf-((net.hidden_neuron_nums[h]+1)*2*r+(net.hidden_neuron_nums[h]+1)*h_buf-h_buf))/2+(n-(current-net.hidden_neuron_nums[h]-1))*(2*r+h_buf)+r,(3*r+2*v_buf)+h*(2*r+v_buf))      if n - current  < net.output_neuron_num:         return point(((2*h_buf)+(width*2*r)+(width*h_buf)-h_buf-((net.output_neuron_num)*2*r+(net.output_neuron_num)*h_buf-h_buf))/2+(n-current)*(2*r+h_buf)+r, net.hidden_neuron_nums.__len__()*2*r + 2*r + net.hidden_neuron_nums.__len__()*v_buf + 2* v_buf + r)      return -1  def backpropagation_(net,inputs,outputs,learning_rate=0.01,epsilon=0.1):      endlich_fertig = false      while not endlich_fertig:          net = backpropagation(net,inputs,outputs,learning_rate,epsilon)          endlich_fertig = true          error = 0          in range(inputs.__len__()):              output = net.propagate_forward(inputs[i], outputs[0][:].__len__())              j in range(output.__len__()):                 error += np.abs(output[j] - float(outputs[i][j]))              if error > epsilon:                 endlich_fertig = false          print("error: %f" % error)      return net  net = make_net(2,[3,2],2)  print_matrix(net.weight_matrix)  inputs = [[1,1],[0,0]] outputs = inputs  draw_net(net)  trained_net = backpropagation_(net,inputs,outputs)  draw_net(trained_net) 

edit: put in full code can reproduce behaviour locally


Comments

Popular posts from this blog

What is happening when Matlab is starting a "parallel pool"? -

angular - DownloadURL return null in below code -

php - Cannot override Laravel Spark authentication with own implementation -