pythonarraysnumpyneural-networkparticle-swarm

Reshaping numpy arrays of differing dimensions inside an array


So the task is to optimise a Neural Network with a PSO. The PSO needs a one-dimensional list of all the weights and biases, like so [0.1 0.244 ... 0.214]. The NN needs an array of arrays with different dimensions, like so [[x,y], [m,n], ...(all the hidden layer matrices)... ,[p,q]] X and y are the dimensions for the input layer, then all the hidden layers and finally p and q - the dimensions of the output layer.

I can easily flatten the array to pass it to the PSO, but I need a method that takes the modified array and reshapes it back into the same array of arrays with the same dimensions as the starting one from the NN.

The dimensions depend on the amount of neurons in a layer, we have that information from the start.

I have tried to keep track of the shapes array and create an indices array to know when to stop but it doesn't seem to work. I am trying something with slicing now but no cigar yet. A modification to the NN is also possible but how to create it so it takes a predefined list of weights? There might be a very nice and efficient way to do it but I just haven't thought of it yet... Any suggestions?

Example:

a = np.array([1,2,3])
b = np.array([7,8,9,10])
c = np.array([12,13,14,15,16])
b.reshape(2,2)
arr = []
arr.append(a)
arr.append(b)
arr.append(c)

This is a very simple example of what the list of weights is as the NN works with it - a list of multi-dimensional array. Arr can be converted into a numpy array of objects if necessary with np.asarray(arr).

Flattening is easy, here is how I do it (there might be a better that doesn't need a loop, if you know, I'd be thankful if you shared).

Flattening:

new_arr = np.array([])
for i in range(len(arr)):
    new_arr = np.append(arr, arr[i].flatten())

My question is how to take new_arr and put it back together to look like arr and is there a beautiful and fast way to do it.


Solution

  • new_arr = np.array([])
    shapes=[]
    for i in range(len(arr)):
        new_arr = np.append(new_arr, arr[i].flatten())
        shapes.append(arr[i].shape)
    
    #do whatever
    
    restoredArray =[]
    offset=0
    for i in range(len(shapes)):
        s = shapes[i]
        n = np.prod(s)
        restoredArray.append(new_arr[offset:(offset+n)].reshape(s))
        offset+=n