Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem when running 3D model on 2-channel stack #182

Open
lcferme opened this issue Feb 7, 2022 · 6 comments
Open

Problem when running 3D model on 2-channel stack #182

lcferme opened this issue Feb 7, 2022 · 6 comments

Comments

@lcferme
Copy link

lcferme commented Feb 7, 2022

Hello,

I have trained a 3D model on 2-channel images, but I have problems when I try to run it on a new dataset having similar shape zyxc, (50, 233, 257, 2).
Here is the code I am using:

import os
import sys
import numpy as np
from tqdm import tqdm
from glob import glob
from csbdeep.utils import Path, normalize
from stardist.models import StarDist3D
from tifffile import imread, imsave

Z = sorted(glob(pathname+"/*.tif"))
Z = list(map(imread,Z))

n_channel = 1 if Z[0].ndim == 3 else Z[0].shape[1]
axis_norm = (0,1,2)   # normalize channels independently
if n_channel >1:
      if Z[0].shape[:-1]!=n_channel:
        Z = [np.moveaxis(z, 1, -1) for z in Z]
        n_tiles = (n_tiles_Z, n_tiles_Y, n_tiles_X, n_channel)

model = StarDist3D(None, name=model_name, basedir=model_dir)

#Normalization
Z = [normalize(z, 1,99.8) for z in Z]


# run prediction
n_tiles_Z =  1
n_tiles_Y =  4
n_tiles_X =  4
n_tiles = (n_tiles_Z, n_tiles_Y, n_tiles_X)

for i in range(len(Z)):
    labels, polygons = model.predict_instances(Z[i], axes="ZYXC", n_tiles = n_tiles)

And here is where I get the error messages:

Traceback (most recent call last):
  File "C:\Users\Lucrezia\stardist\stardist_venv\lib\site-packages\stardist\models\base.py", line 674, in _axes_tile_overlap
    self._tile_overlap
AttributeError: 'StarDist3D' object has no attribute '_tile_overlap'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C_prediction_2C.py", line 136, in <module>
    labels, polygons = model.predict_instances(Z[i], axes="ZYXC", n_tiles = n_tiles)
  File "C:\Users\Lucrezia\stardist\stardist_venv\lib\site-packages\stardist\models\base.py", line 419, in predict_instances
    prob, dist = self.predict(img, axes=axes, normalizer=normalizer, n_tiles=n_tiles, show_tile_progress=show_tile_progress, **predict_kwargs)
  File "C:\Users\Lucrezia\stardist\stardist_venv\lib\site-packages\stardist\models\base.py", line 322, in predict
    axes_net_tile_overlaps = self._axes_tile_overlap(axes_net)
  File "C:\Users\Lucrezia\stardist\stardist_venv\lib\site-packages\stardist\models\base.py", line 676, in _axes_tile_overlap
    self._tile_overlap = self._compute_receptive_field()
  File "C:\Users\Lucrezia\stardist\stardist_venv\lib\site-packages\stardist\models\base.py", line 668, in _compute_receptive_field
    return [(m-np.min(i), np.max(i)-m) for (m,i) in zip(mid,ind)]
  File "C:\Users\Lucrezia\stardist\stardist_venv\lib\site-packages\stardist\models\base.py", line 668, in <listcomp>
    return [(m-np.min(i), np.max(i)-m) for (m,i) in zip(mid,ind)]
  File "<__array_function__ internals>", line 6, in amin
  File "C:\Users\Lucrezia\stardist\stardist_venv\lib\site-packages\numpy\core\fromnumeric.py", line 2793, in amin
    keepdims=keepdims, initial=initial, where=where)
  File "C:\Users\Lucrezia\stardist\stardist_venv\lib\site-packages\numpy\core\fromnumeric.py", line 90, in _wrapreduction
    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
ValueError: zero-size array to reduction operation minimum which has no identity

I am not sure what I am doing wrong... by chance do you have a clue of what I should modify/correct?

Thank you a lot!!
Lucrezia

@maweigert
Copy link
Member

Hi @lcferme ,

Might related to #121 . Could you try the following:

  1. Close all running notebooks and restart the prediction notebook
  2. print the shape of the input
print(Z[0].shape)
  1. Increase the number of tiles to e.g. (2,8,8) and try predicting

@lcferme
Copy link
Author

lcferme commented Feb 8, 2022

Hi @maweigert !

I am not running a notebook, just a script from the terminal. Everything works as long as I have one channel, but then if I try with two I get that error.
In this specific case, the shape of the image is (50, 233, 257, 2). As you see, it is quite small and I actually did not get any error once I give n_tiles = None in model.predict_instances()
For bigger files, what is the correct way to set up the tiles? Should I specify the number of channels , like n_tiles = (2, 8, 8, 2) for ZYXC or I only define ZYX?

Thank you for your help!!

@uschmidt83
Copy link
Member

n_channel = 1 if Z[0].ndim == 3 else Z[0].shape[1]
if n_channel >1:
      if Z[0].shape[:-1]!=n_channel:
        Z = [np.moveaxis(z, 1, -1) for z in Z]

Note that Z[0].shape[:-1]!=n_channel is always True, since Z[0].shape[:-1] is a tuple and n_channel is an integer.

For bigger files, what is the correct way to set up the tiles? Should I specify the number of channels , like n_tiles = (2, 8, 8, 2) for ZYXC or I only define ZYX?

n_tiles must have an entry for each of the axes, but channels cannot be tiled, i.e. the entry for channels must be 1. E.g.:

model.predict_instances(Z[i], axes="ZYXC", n_tiles=(2,8,8,1))

@uschmidt83
Copy link
Member

This works for me:

from stardist.models import StarDist3D, Config3D

config = Config3D(n_channel_in=2)
model = StarDist3D(config, 'my_model', basedir=None)

x = np.zeros((12,133,157,2), dtype=np.float32)
out = model.predict_instances(x, axes='ZYXC', n_tiles=(1,4,4,1))

@lcferme
Copy link
Author

lcferme commented Feb 10, 2022

@uschmidt83 thanks, I corrected the mistake with the tuple :)
But I still have problems running the prediction on bigger files, for instance for a file of shape (193, 1699, 1938, 2) I get the same error.

@uschmidt83
Copy link
Member

uschmidt83 commented Feb 11, 2022

Just tried it with this shape, and it works on my GPU (8GB RAM):

from stardist.models import StarDist3D, Config3D

config = Config3D(n_channel_in=2)
model = StarDist3D(config, 'my_model', basedir=None)

x = np.zeros((193, 1699, 1938, 2), dtype=np.float32)
out = model.predict_instances(x, axes='ZYXC', n_tiles=(2,16,16,1))

Does this not run for you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants