0

I want to rescale a 4D array of MNIST data by a factor of 0.5. I get an error using skimage.transform.rescale:

LinAlgError: SVD did not converge

I have a feeling it might be related to image dimensions but the documentation doesn't mention image dimensions.

from skimage import transform
...
...
data = load_mnist() #Contains mnist data in format (50000, 1, 28, 28)
data_rescaled = transform.rescale(data, 0.5)
ali_m
  • 71,714
  • 23
  • 223
  • 298
user3711518
  • 253
  • 1
  • 3
  • 14

1 Answers1

1

From the documentation:

skimage.transform.rescale(image, scale, order=1, mode='constant', cval=0, clip=True, preserve_range=False)[source]

Scale image by a certain factor.

Performs interpolation to upscale or down-scale images. For down-sampling N-dimensional images with integer factors by applying the arithmetic sum or mean, see skimage.measure.local_sum and skimage.transform.downscale_local_mean, respectively. ...

scale : {float, tuple of floats}

Scale factors. Separate scale factors can be defined as (row_scale, col_scale).

My interpretation is that skimage.measure.rescale only supports 2D images. A quick attempt at passing separate scaling factors for each dimension seems to confirm this:

In [1]: data = np.random.randn(500, 1, 28, 28)

In [2]: rescaled = transform.rescale(data, (0.5, 0.5, 0.5, 0.5))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-638fc58c2154> in <module>()
----> 1 rescaled = transform.rescale(data, (0.5, 0.5, 0.5, 0.5))

/home/alistair/.venvs/rfmap/lib/python2.7/site-packages/skimage/transform/_warps.pyc in rescale(image, scale, order, mode, cval, clip, preserve_range)
    164 
    165     try:
--> 166         row_scale, col_scale = scale
    167     except TypeError:
    168         row_scale = col_scale = scale

ValueError: too many values to unpack

As the documentation says, you could use skimage.transform.local_sum or skimage.downscale_local_mean instead, provided that you only need to downsample by an integer factor (in your case, 2).

Another alternative that supports using interpolation for non-integer zoom factors is scipy.ndimage.zoom:

In [3]: from scipy import ndimage

In [4]: rescaled = ndimage.zoom(data, 0.5)

In [5]: rescaled.shape
Out[5]: (250, 1, 14, 14)
ali_m
  • 71,714
  • 23
  • 223
  • 298