def test_resizer(axes): rng = np.random.RandomState(42) resizer = PadAndCropResizer() checker = NoResizer() for _ in range(50): imdims = list(rng.randint(20,40,size=len(axes))) div_by = list(rng.randint(1,20,size=len(axes))) u = np.empty(imdims,np.float32) if any(s%div_n!=0 for s, div_n in zip(imdims, div_by)): with pytest.raises(ValueError): checker.before(u, axes, div_by) v = resizer.before(u, axes, div_by) assert all ( s_v >= s_u and s_v%div_n==0 for s_u, s_v, div_n in zip(u.shape, v.shape, div_by) ) w = resizer.after(v, axes) assert u.shape == w.shape d = rng.choice(len(axes)) _axes = axes.replace(axes[d],'') _u = np.take(u,0,axis=d) _v = np.take(v,0,axis=d) _w = resizer.after(_v, _axes) assert _u.shape == _w.shape
def predict(self, img, resizer=PadAndCropResizer(), **predict_kwargs): """Predict. Parameters ---------- img : :class:`numpy.ndarray` Input image resizer : :class:`csbdeep.data.Resizer` or None If necessary, input image is resized to enable neural network prediction and result is (possibly) resized to yield original image size. Returns ------- (:class:`numpy.ndarray`,:class:`numpy.ndarray`) Returns the tuple (`prob`, `dist`) of per-pixel object probabilities and star-convex polygon distances. """ if resizer is None: resizer = NoResizer() isinstance(resizer, Resizer) or _raise(ValueError()) img.ndim in (2, 3) or _raise(ValueError()) x = img if x.ndim == 2: x = np.expand_dims(x, (-1 if backend_channels_last() else 0)) channel = x.ndim - 1 if backend_channels_last() else 0 axes = 'YXC' if backend_channels_last() else 'CYX' self.config.n_channel_in == x.shape[channel] or _raise(ValueError()) # resize: make divisible by power of 2 to allow downsampling steps in unet axes_div_by = tuple(2**self.config.unet_n_depth if a != 'C' else 1 for a in axes) x = resizer.before(x, axes, axes_div_by) if backend_channels_last(): sh = x.shape[:-1] + (1, ) else: sh = (1, ) + x.shape[1:] dummy = np.empty((1, ) + sh, np.float32) prob, dist = self.keras_model.predict([np.expand_dims(x, 0), dummy], **predict_kwargs) prob, dist = prob[0], dist[0] prob = resizer.after(prob, axes) dist = resizer.after(dist, axes) prob = np.take(prob, 0, axis=channel) dist = np.moveaxis(dist, channel, -1) return prob, dist
def test_model_predict_tiled(tmpdir,config): """ Test that tiled prediction yields the same or similar result as compared to predicting the whole image at once. """ rng = np.random.RandomState(42) normalizer, resizer = NoNormalizer(), NoResizer() K.clear_session() model = CARE(config,basedir=str(tmpdir)) def _predict(imdims,axes,n_tiles): img = rng.uniform(size=imdims) # print(img.shape, axes) mean, scale = model._predict_mean_and_scale(img, axes, normalizer, resizer, n_tiles=None) mean_tiled, scale_tiled = model._predict_mean_and_scale(img, axes, normalizer, resizer, n_tiles=n_tiles) assert mean.shape == mean_tiled.shape if config.probabilistic: assert scale.shape == scale_tiled.shape error_max = np.max(np.abs(mean-mean_tiled)) # print('n, k, err = {0}, {1}x{1}, {2}'.format(model.config.unet_n_depth, model.config.unet_kern_size, error_max)) assert error_max < 1e-3 return mean, mean_tiled imdims = list(rng.randint(50,70,size=config.n_dim)) if config.n_dim == 3: imdims[0] = 16 # make one dim small, otherwise test takes too long div_n = 2**config.unet_n_depth imdims = [(d//div_n)*div_n for d in imdims] imdims.insert(0,config.n_channel_in) axes = 'C'+config.axes.replace('C','') for n_tiles in ( -1, 1.2, [1]+[1.2]*config.n_dim, [1]*config.n_dim, # missing value for channel axis [2]+[1]*config.n_dim, # >1 tiles for channel axis ): with pytest.raises(ValueError): _predict(imdims,axes,n_tiles) for n_tiles in [list(rng.randint(1,5,size=config.n_dim)) for _ in range(3)]: # print(imdims,axes,[1]+n_tiles) if config.n_channel_in == 1: _predict(imdims[1:],axes[1:],n_tiles) _predict(imdims,axes,[1]+n_tiles) # legacy api: tile only largest dimension n_blocks = np.max(imdims) // div_n for n_tiles in (2,5,n_blocks+1): with pytest.warns(UserWarning): if config.n_channel_in == 1: _predict(imdims[1:],axes[1:],n_tiles) _predict(imdims,axes,n_tiles)
def test_model_predict(): rng = np.random.RandomState(42) configs = config_generator( axes=['YX', 'ZYX'], n_channel_in=[1, 2], n_channel_out=[1, 2], probabilistic=[False, True], # unet_residual = [False,True], unet_n_depth=[2], unet_kern_size=[3], unet_n_first=[4], unet_last_activation=['linear'], # unet_input_shape = [(None, None, 1)], ) with tempfile.TemporaryDirectory() as tmpdir: normalizer, resizer = NoNormalizer(), NoResizer() for config in filter(lambda c: c.is_valid(), configs): K.clear_session() model = CARE(config, basedir=tmpdir) axes = config.axes def _predict(imdims, axes): img = rng.uniform(size=imdims) # print(img.shape, axes, config.n_channel_out) mean, scale = model._predict_mean_and_scale( img, axes, normalizer, resizer) if config.probabilistic: assert mean.shape == scale.shape else: assert scale is None if 'C' not in axes: if config.n_channel_out == 1: assert mean.shape == img.shape else: assert mean.shape == img.shape + ( config.n_channel_out, ) else: channel = axes_dict(axes)['C'] imdims[channel] = config.n_channel_out assert mean.shape == tuple(imdims) imdims = list(rng.randint(20, 40, size=config.n_dim)) div_n = 2**config.unet_n_depth imdims = [(d // div_n) * div_n for d in imdims] if config.n_channel_in == 1: _predict(imdims, axes=axes.replace('C', '')) channel = rng.randint(0, config.n_dim) imdims.insert(channel, config.n_channel_in) _axes = axes.replace('C', '') _axes = _axes[:channel] + 'C' + _axes[channel:] _predict(imdims, axes=_axes)
def test_model_predict(tmpdir,config): rng = np.random.RandomState(42) normalizer, resizer = NoNormalizer(), NoResizer() K.clear_session() model = CARE(config,basedir=str(tmpdir)) axes = config.axes def _predict(imdims,axes): img = rng.uniform(size=imdims) # print(img.shape, axes, config.n_channel_out) if config.probabilistic: prob = model.predict_probabilistic(img, axes, normalizer, resizer) mean, scale = prob.mean(), prob.scale() assert mean.shape == scale.shape else: mean = model.predict(img, axes, normalizer, resizer) if 'C' not in axes: if config.n_channel_out == 1: assert mean.shape == img.shape else: assert mean.shape == img.shape + (config.n_channel_out,) else: channel = axes_dict(axes)['C'] imdims[channel] = config.n_channel_out assert mean.shape == tuple(imdims) imdims = list(rng.randint(20,40,size=config.n_dim)) div_n = 2**config.unet_n_depth imdims = [(d//div_n)*div_n for d in imdims] if config.n_channel_in == 1: _predict(imdims,axes=axes.replace('C','')) channel = rng.randint(0,config.n_dim) imdims.insert(channel,config.n_channel_in) _axes = axes.replace('C','') _axes = _axes[:channel]+'C'+_axes[channel:] _predict(imdims,axes=_axes)
def test_model_predict_tiled(): """ Test that tiled prediction yields the same or similar result as compared to predicting the whole image at once. """ rng = np.random.RandomState(42) configs = config_generator( axes=['YX', 'ZYX'], n_channel_in=[1], n_channel_out=[1], probabilistic=[False], # unet_residual = [False,True], unet_n_depth=[1, 2, 3], unet_kern_size=[3, 5], unet_n_first=[4], unet_last_activation=['linear'], # unet_input_shape = [(None, None, 1)], ) with tempfile.TemporaryDirectory() as tmpdir: normalizer, resizer = NoNormalizer(), NoResizer() for config in filter(lambda c: c.is_valid(), configs): K.clear_session() model = CARE(config, basedir=tmpdir) def _predict(imdims, axes, n_tiles): img = rng.uniform(size=imdims) # print(img.shape, axes) mean, scale = model._predict_mean_and_scale(img, axes, normalizer, resizer, n_tiles=1) mean_tiled, scale_tiled = model._predict_mean_and_scale( img, axes, normalizer, resizer, n_tiles=n_tiles) assert mean.shape == mean_tiled.shape if config.probabilistic: assert scale.shape == scale_tiled.shape error_max = np.max(np.abs(mean - mean_tiled)) # print('n, k, err = {0}, {1}x{1}, {2}'.format(model.config.unet_n_depth, model.config.unet_kern_size, error_max)) assert error_max < 1e-3 return mean, mean_tiled imdims = list(rng.randint(100, 130, size=config.n_dim)) if config.n_dim == 3: imdims[ 0] = 32 # make one dim small, otherwise test takes too long div_n = 2**config.unet_n_depth imdims = [(d // div_n) * div_n for d in imdims] n_blocks = np.max(imdims) // div_n def _predict_wrapped(imdims, axes, n_tiles): if 0 < n_tiles <= n_blocks: _predict(imdims, axes, n_tiles=n_tiles) else: with pytest.warns(UserWarning): _predict(imdims, axes, n_tiles=n_tiles) imdims.insert(0, config.n_channel_in) axes = config.axes.replace('C', '') # return _predict(imdims,'C'+axes,n_tiles=(3,4)) # tile one dimension for n_tiles in (0, 2, 3, 6, n_blocks + 1): if config.n_channel_in == 1: _predict_wrapped(imdims[1:], axes, n_tiles) _predict_wrapped(imdims, 'C' + axes, n_tiles) # tile two dimensions for n_tiles in product((2, 4), (3, 5)): _predict(imdims, 'C' + axes, n_tiles) # tile three dimensions if config.n_dim == 3: _predict(imdims, 'C' + axes, (2, 3, 4))