def flatten(m, im_shape):
    """Flatten matrix in shape of (batches, channels, rows, cols)
    to (batches, -1).

    This function has no side effect, that is, it doesn't modify
    argument "m" directly.

    Arguments
    ---------
    m : np.array
        4D matrix in shape of (batches, channels, rows, cols).
    im_shape : tuple
        Shape of image, which is supposed to be (channels, rows, cols).

    Returns
    -------
    np.array
        Flattened matrix in 2d array.
    """
    batches = m.shape[0]
    chs, rows, cols = im_shape
    return m.reshape(batches, chs*rows*cols)