title: How to fix 'TypeError: Object arrays are not currently supported' error in numpy python 3 (matrix multiplication)
body: <p>I'm trying to make my own neural network "library" (if you can call it that) for myself to use, since I am hobby-learning about them.</p>
  
  <p>I wrote this code that makes a propagatable neural network by feeding it a structure of the desired network, and it worked pretty well.</p>
  
  <p><strong>But</strong> then when I tried giving the model a different amount of nodes, the code <strong><em>BUGGED</em></strong></p>
  
  <p>I've already tried to edit the amount of nodes in each layer and see where that takes me, and I've found out that I only get this error when the first and the second layer have the same amount of nodes in them, but the output layer has a different amount. I've also tried to do the matrix multiplication of the structure that outputs the bug on paper, and it gave me an actual result (which I've double-checked for legitness a lot of times). So now I know that it has something to do with the practical and not theoretical.
  There's clearly something wrong with the matrix multiplication, I think.</p>
  
  <h1>The script's functions</h1>
  
  <blockquote>
    <p>I had to include these functions in the question, so you can have a better inside on how this code works.  </p>
  </blockquote>
  
  <h2>is_iterable()</h2>
  
  <p>This function returns a boolean value that describes if the input is iterable</p>
  
  <pre><code>    def is_iterable(x):
          try:
              x[0]
              return True
          except:
              return False
  </code></pre>
  
  <h2>blueprint()</h2>
  
  <p>This function returns a copy of the input array but changes the elements that aren't iterable to 0's</p>
  
  <pre><code>    def blueprint(x):
          return [blueprint(e) if is_iterable(e) else 0 for e in x]
  </code></pre>
  
  <h2>build()</h2>
  
  <p>This function takes a model of your desired neural network structure as input, and outputs suited randomized biases and weights seperated in two different arrays
  The 'randomize()' function returns a copy of the input array but changes the elements that aren't iterable to random floats between -1's and 1's.
  The 'build-weights()' function returns randomized weights based on a model of a neural network.</p>
  
  <pre><code>    def build(x):
  
          def randomize(x):
              return np.array([randomize(n) if type(n) is list else random.uniform(-1, 1) for n in x])
  
          def build_weighs(x):
              y = []
              for i, l in enumerate(x):
                  if i == len(x) - 1:
                      break
                  y.append([randomize(x[i + 1]) for n in l])
              return np.array(y)
  
          return (randomize(x), build_weighs(x))
  </code></pre>
  
  <h2>apply_funcs()</h2>
  
  <p>This function applies a list of functions to another list of functions and then returns them. If the function list contains a 0, an element from the other list positioned in the same place will not be applied to any function.</p>
  
  <pre><code>    def apply_funcs(x, f):
          y = x
          i = 0
          for xj, fj in zip(x, f):
              if fj == 0:
                  y[i] = xj
              else:
                  y[i] = fj(xj)
              i += 1
          return y
  </code></pre>
  
  <h2>nn()</h2>
  
  <p>This is the class for making a neural network.
  You can see that it has a function named, 'prop' for the forward propagation of the network.</p>
  
  <pre><code>    class nn:
          def __init__(self, structure, a_funcs=None):
              self.structure = structure
              self.b = np.array(structure[0])
              self.w = np.array(structure[1])
              if a_funcs == None:
                  a_funcs = blueprint(self.b)
              self.a_funcs = np.array(a_funcs).
  
          def prop(self, x):
              y = np.array(x)
              if y.shape != self.b[0].shape:
                  raise ValueError("The input needs to be intact with the Input Nodes\nInput: {} != Input Nodes: {}".format(blueprint(y), blueprint(self.b[0])))
              wi = 0
              # A loop through the layers of the neural network
              for i in range(len(self.b)):
                  # This if statement is here so that the weights get applied in the right order
                  if i != 0:
                      y = np.matmul(y, self.w[wi])
                      wi += 1
                  # Applying the biases of layer i to the current information
                  y = np.add(y, self.b[i])
                  # Applying the activation functions to the current information
                  y = apply_funcs(y, self.a_funcs[i])
  
              return y
  </code></pre>
  
  <h1>Defining a neural network structure and propagating it</h1>
  
  <p><strong>n</strong> is containing the structure which is a 3 layer network containing respectively <em>2 nodes, 2 nodes and 3 nodes.</em></p>
  
  <pre><code>    n = [[0] * 2, [0] * 2, [0] * 3]
      bot = nn(build(n))
      print(bot.prop([1] * 2))
  </code></pre>
  
  <p>When I do this I expect the code to output an array of three semi-random numbers like this: </p>
  
  <pre><code>    [-0.55889818  0.62762604  0.59222784]
  </code></pre>
  
  <p>but instead I get an error from numpy saying this:</p>
  
  <pre><code>    File "C:\Users\Black\git\Changbot\oper.py.py", line 78, in prop
          y = np.matmul(y, self.w[wi])
      TypeError: Object arrays are not currently supported
  </code></pre>
  
  <p>And the weirdest thing about this is that (as I said earlier) I only get this error when the first and the second layer have the same amount of nodes in them, but the output layer has a different amount. All the other times I get the expected output...</p>
  
  <p>I have now again checked the values that are causing this error and I don't see any objects other than a list. It's the same when it's not bugging...
  So I added this try-except statement:</p>
  
  <pre><code>    try:
          y = np.matmul(np.array(y), self.w[wi])
      except TypeError:
          print("y:{}\nself.w[wi]:{}".format(y, self.w[wi]))
  </code></pre>
  
  <p>It then outputs this:</p>
  
  <pre><code>    y:[1.6888437]
      self.w[wi]:[array([-0.19013173])]
  </code></pre>
  
  <p>Which should have the ability to be multiplied with each other
  I have even tried copy pasting the values into an interpreter and multiplying them there, and it works there...</p>
  
  <blockquote>
    <p>NOTE: THIS IS A VERY BAD TEST AS THE COPY PASTE ARRAYS DOESN'T HAVE THE SAME DTYPES AS THE ACTUAL ARRAYS</p>
  </blockquote>
  
  <pre><code>    np.matmul([1.6888437], [np.array([-0.19013173])])
  </code></pre>
  
  <p>Output for the above:</p>
  
  <pre><code>    [-0.32110277]
  </code></pre>
  
  <h1>After looking at the answers</h1>
  
  <p>Okay. I have now found out that the object dtype arrays lies in the structure of the neural network by doing this at the end of the script:</p>
  
  <pre><code>    print("STRUCTURE:{}".format(n))
  </code></pre>
  
  <p>It then outputs this:</p>
  
  <pre><code>    STRUCTURE:(array([array([0.6888437]), array([ 0.51590881, -0.15885684]),
     array([-0.4821665 ,  0.02254944, -0.19013173])], dtype=object), array([list([array([ 0.56759718, -0.39337455])]),
     list([array([-0.04680609,  0.16676408,  0.81622577]), array([ 0.00937371, -0.43632431,  0.51160841])])],
    dtype=object))
  </code></pre>
  
  <p><strong>Solving the bug</strong></p>
  
  <p>I can understand from one of the answer to this post that <em>np.array() tries to create as high a dimensional array as it can, and failing that falls back on object dtype (or for some combinations of inputs raises an error).</em></p>
  
  <p>The object dtype gets created in the <em>build()</em> function so I tried to remove all <em>np.array()</em> functions in that. Actually i removed all of such from the whole script. <em>And guess what?</em> <strong>It worked! Thanks a 1000 times to you contributers!</strong></p>
  
  <p>Btw <strong><em>Happy New Year</em></strong> </p>