Search code examples
pythonarraysreshape

Why (X.shape[0], -1) is used as parameters while using reshape function on a matrix X?


While doing the deeplearning.ai course, on an instant I needed to use numpy.reshape(). However while doing so I was instructed in the course notebook to do it in a specific way. The purpose was to convert a 4 dimensional vector to a 2 dimensional vector.

// Instructions:

For convenience, you should now reshape images of shape (num_px, num_px, 3) in a numpy-array of shape (num_px ∗∗ num_px ∗∗ 3, 1). After this, our training (and test) dataset is a numpy-array where each column represents a flattened image. There should be m_train (respectively m_test) columns.

Exercise: Reshape the training and test data sets so that images of size (num_px, num_px, 3) are flattened into single vectors of shape (num_px ∗∗ num_px ∗∗ 3, 1).

A trick when you want to flatten a matrix X of shape (a,b,c,d) to a matrix X_flatten of shape (b∗∗c∗∗d, a) is to use:

X_flatten = X.reshape(X.shape[0], -1).T  


(X.T is the transpose of X)

I am unable to understand why the parameters are given in such a way? Also, while playing with the code, changing '-1' to any any negative integer, didn't change the output.


Solution

  • I am assuming you are working with the MNIST dataset, so you have n images of size mm3 lets assume n to be 100 and m to be 8. So you have 100 RGB-images(3 channels) of size 8*8, thus making your datashape 100,8,8,3. Now you would like to flatten each of the 100 images, so you could either loop through the dataset, and flatten it image by image, or you could reshape it.

    You decide to reshape it via:

    X.reshape(X.shape[0], -1).T
    

    lets unpack this a bit more, X.shape[0] gives you 100. The shape attribute will return you a tuple of (100,8,8,3) since that is the shape of your dataset and you access its 0th element, that's 100, so you get

    X.reshape(100, -1).T
    

    So what this does it that it reshapes the array but makes sure that you still have 100 images, and what -1 states is that you do not care about what shape the result will be reshaped into, so it automatically infers the shape from the original shape. Previously you had a 4-D array of shape 100,8,8,3 but now you want to reshape it into a 2-D array, you specify that 100 should be dimension 0 of the shape, so numpy infers that to reshape it into such a 2-D shape it will have to flatten it, and thus 100,883 is the output shape.

    After that you just transpose it

    Also, this is what numpy documentation states

    The new shape should be compatible with the original shape. If an integer, then the result will be a 1-D array of that length. One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.