max pool layer in scratch neural network

Viewed 43

I added my own max pool layer to the independent's code project neural network from scratch code(Here is the link to the his vid: https://www.youtube.com/watch?v=Lakz2MoHy6o&t=570s).I checked parts of my code and it looks like it should work, but I get an error when I try to train the model that says can't reshape array of size 1 into shape(845,1). I can't seem to find where the array of size 1 is coming from and can't find where in my code something would cause this.

Here is the code for my max pool layer(rest is from Independent code project video):

class MaxPool2d(Layer):
  
  def __init__(self, input_shape, block_size):

      input_depth, input_height, input_width = input_shape
      self.block_size = block_size
      self.height = input_height
      self.width = input_width
      self.input_shape = input_shape
      self.input_depth = input_depth
      self.output_shape = (input_depth, (input_height / block_size), (input_width / block_size))




  def forward_prop(self, input):
    self.input = input
    self.output = np.zeros(self.output_shape)
    self.block_input_array = np.zeros(self.input_shape)

    for i in range(self.input_depth):
      #gets max matrix
      self.output[i] = block_reduce(self.input[i], block_size=(self.block_size, self.block_size), func=np.max)
      #need this block array for the back prop
      block_array = view_as_blocks(self.input[i], (self.block_size, self.block_size))
      self.block_input_array[i] = block_array.reshape(self.width, self.height)

    return self.output

def backward_prop(self, output_gradient, learning_rate):

  self.input_gradient = np.zeros(self.input_shape)


  for i in range(self.input_depth):

    #find all indicies of the maxes in each block
    max_indices = np.argmax(self.block_input_array[i], axis=1)
    max_indices = np.expand_dims(max_indices,axis=1)
    grad_arr = np.zeros_like(self.block_input_array[i])
    #places a 1 on every index that had a max value
    np.put_along_axis(grad_arr, max_indices, 1, axis=1)
    grad_arr = grad_arr.reshape(-1, self.block_size, self.block_size)
    #chain rule
    self.input_gradient[i] = np.multiply(undo_blocks(grad_arr, self.width, self.height, self.block_size), output_gradient[i])

  return self.input_gradient

#puts the array into same order as it was in the input
def undo_blocks(array, width, height, block_size):

  ordered_blocks = array.reshape(-1,block_size,block_size)
  split_blocks = np.array(np.hsplit(ordered_blocks,block_size))
  split_blocks = np.array(np.hsplit(split_blocks, (width / block_size)))
  reshaped_arr = split_blocks.flatten().reshape(width,height)
  return reshaped_arr

Here is the code for building the network:

network = [
    Convolutional((1, 28, 28), 3, 5),
    Sigmoid(),
    MaxPool2d((5,26,26), 2),
    Reshape((5, 13, 13), (5 * 13 * 13, 1)),
    Dense(5 * 13 * 13, 100),
    Sigmoid(),
    Dense(100, 2),
    Softmax()
]

epochs = 10
learning_rate = 0.1
x_axis = []
y_axis = []

# train
for e in range(epochs):

    error = 0
    for x, y in zip(x_train, y_train):
        # forward
        output = x
        for layer in network:
            output = layer.forward(output)

        # error
        error += binary_cross_entropy(y, output)

        # backward
        grad = binary_cross_entropy_prime(y, output)
        for layer in reversed(network):
            grad = layer.backward(grad, learning_rate)

    x_axis.append(e)
    y_axis.append(error)
    error /= len(x_train)
    print(f"{e + 1}/{epochs}, error={error}")

# test
for x, y in zip(x_test, y_test):
    output = x
    for layer in network:
        output = layer.forward(output)
    print(f"pred: {np.argmax(output)}, true: {np.argmax(y)}")

The error I'm getting is happening during the forward propagation of the MaxPool layer I think and here is what it says: ValueError: cannot reshape array of size 1 into shape (845,1)

When I took out the max pool layer and changed the input shapes to match the code works fine. I don't know why but its like somewhere its changing the data to only contain one value since the error said that it can't reshape array of size 1 to (845,1).

0 Answers
Related