haesleinhuepf / napari-accelerated-pixel-and-object-classification

GPU-accelerated, OpenCL-based Random Forest Classifiers for pixel and labeled object classification in napari.
BSD 3-Clause "New" or "Revised" License
43 stars 7 forks source link

`EmitLoopError` when trying to run the GUI #25

Closed alisterburt closed 2 years ago

alisterburt commented 2 years ago

Hi Robert,

Is this one you've seen before? I tried to train a classifier from the GUI

output from napari --info

napari: 0.4.16
Platform: macOS-12.5.1-arm64-arm-64bit
System: MacOS 12.5.1
Python: 3.10.6 | packaged by conda-forge | (main, Aug 22 2022, 20:41:22) [Clang 13.0.1 ]
Qt: 5.15.4
PyQt5: 5.15.7
NumPy: 1.23.3
SciPy: 1.9.1
Dask: 2022.9.2
VisPy: 0.10.0

OpenGL:
  - GL version:  2.1 Metal - 76.3
  - MAX_TEXTURE_SIZE: 16384

Screens:
  - screen 1: resolution 1512x982, scale 2.0

Plugins:
  - console: 0.0.6
  - mrcfile-reader: 0.1.3
  - napari-accelerated-pixel-and-object-classification: 0.10.2
  - napari-svg: 0.1.6
  - napari-time-slicer: 0.4.9
  - napari-tools-menu: 0.1.17
  - scikit-image: 0.4.16
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File src/psygnal/_signal.py:912, in psygnal._signal.SignalInstance._run_emit_loop()

File ~/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/magicgui/widgets/_function_gui.py:207, in FunctionGui.__init__.<locals>._disable_button_and_call()
    206 try:
--> 207     self.__call__()
        self = <FunctionGui Train_object_segmentation(image: napari.types.ImageData = <class 'numpy.ndarray'> (3838, 3710) float32, annotation: napari.types.LabelsData = <class 'numpy.ndarray'> (3838, 3710) int64, model_filename: str = 'ObjectSegmenter.cl', featureset: apoc._feature_sets.PredefinedFeatureSet = <PredefinedFeatureSet.small_quick: 'original gaussian_blur=1 sobel_of_gaussian_blur=1'>, custom_features: str = 'original gaussian_blur=1 sobel_of_gaussian_blur=1', max_depth: int = 2, num_ensembles: int = 100, annotated_object_intensity: int = 2) -> napari.types.LabelsData>
    208 finally:

File ~/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/magicgui/widgets/_function_gui.py:318, in FunctionGui.__call__(self=<FunctionGui Train_object_segmentation(image: na...t_intensity: int = 2) -> napari.types.LabelsData>, update_widget=False, *args=(), **kwargs={})
    317 with _function_name_pointing_to_widget(self):
--> 318     value = self._function(*bound.args, **bound.kwargs)
        self = <FunctionGui Train_object_segmentation(image: napari.types.ImageData = <class 'numpy.ndarray'> (3838, 3710) float32, annotation: napari.types.LabelsData = <class 'numpy.ndarray'> (3838, 3710) int64, model_filename: str = 'ObjectSegmenter.cl', featureset: apoc._feature_sets.PredefinedFeatureSet = <PredefinedFeatureSet.small_quick: 'original gaussian_blur=1 sobel_of_gaussian_blur=1'>, custom_features: str = 'original gaussian_blur=1 sobel_of_gaussian_blur=1', max_depth: int = 2, num_ensembles: int = 100, annotated_object_intensity: int = 2) -> napari.types.LabelsData>
        bound = <BoundArguments (image=<class 'numpy.ndarray'> (3838, 3710) float32, annotation=<class 'numpy.ndarray'> (3838, 3710) int64, model_filename='ObjectSegmenter.cl', featureset=<PredefinedFeatureSet.small_quick: 'original gaussian_blur=1 sobel_of_gaussian_blur=1'>, custom_features='original gaussian_blur=1 sobel_of_gaussian_blur=1', max_depth=2, num_ensembles=100, annotated_object_intensity=2)>
        self._function = <function Train_object_segmentation at 0x28e8c6830>
    320 self._call_count += 1

File ~/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/napari_accelerated_pixel_and_object_classification/_function.py:127, in Train_object_segmentation(image=<class 'numpy.ndarray'> (3838, 3710) float32, annotation=<class 'numpy.ndarray'> (3838, 3710) int64, model_filename='ObjectSegmenter.cl', featureset=<PredefinedFeatureSet.small_quick: 'original gaussian_blur=1 sobel_of_gaussian_blur=1'>, custom_features='original gaussian_blur=1 sobel_of_gaussian_blur=1', max_depth=2, num_ensembles=100, annotated_object_intensity=2)
    125 clf.train(feature_stack, annotation, [image])
--> 127 result = clf.predict(feature_stack, [image])
        feature_stack = 'original gaussian_blur=1 sobel_of_gaussian_blur=1'
        clf = Classifier type: ObjectSegmenter
--- Random forest info ---
Used features for training: original gaussian_blur=1 sobel_of_gaussian_blur=1
Ground truth dimensions: 2
Maximum depth: 2
Number of ensembles: 100
Number of classes: 2
Number of features: 3
Number of channels: 1Positive class identifier: 2
        [image] = [<class 'numpy.ndarray'> (3838, 3710) float32]
        image = <class 'numpy.ndarray'> (3838, 3710) float32
    128 return result

File ~/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/apoc/_object_segmenter.py:61, in ObjectSegmenter.predict(self=Classifier type: ObjectSegmenter
--- Random fore...Number of channels: 1Positive class identifier: 2, image='original gaussian_blur=1 sobel_of_gaussian_blur=1', features=[<class 'numpy.ndarray'> (3838, 3710) float32])
     60 self.positive_class_identifier = self.positive_class_identifier_from_file
---> 61 result = super().predict(features=features, image=image)
        features = [<class 'numpy.ndarray'> (3838, 3710) float32]
        image = 'original gaussian_blur=1 sobel_of_gaussian_blur=1'
     63 import pyclesperanto_prototype as cle

File ~/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/apoc/_pixel_classifier.py:157, in PixelClassifier.predict(self=Classifier type: ObjectSegmenter
--- Random fore...Number of channels: 1Positive class identifier: 2, image='original gaussian_blur=1 sobel_of_gaussian_blur=1', features=[<class 'numpy.ndarray'> (3838, 3710) float32])
    155 parameters['out'] = output
--> 157 cle.execute(None, self.opencl_file, "predict", features[0].shape, parameters)
        features = [<class 'numpy.ndarray'> (3838, 3710) float32]
        parameters = {'in0': <class 'numpy.ndarray'> (3838, 3710) float32, 'out': <class 'numpy.ndarray'> (3710, 3838) uint32}
        self.opencl_file = 'ObjectSegmenter.cl'
        self = Classifier type: ObjectSegmenter
--- Random forest info ---
Used features for training: original gaussian_blur=1 sobel_of_gaussian_blur=1
Ground truth dimensions: 2
Maximum depth: 2
Number of ensembles: 100
Number of classes: 2
Number of features: 3
Number of channels: 1Positive class identifier: 2
        features[0] = <class 'numpy.ndarray'> (3838, 3710) float32
        cle = <module 'pyclesperanto_prototype' from '/Users/alisterburt/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/pyclesperanto_prototype/__init__.py'>
    159 return output

File ~/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/pyclesperanto_prototype/_tier0/_execute.py:3, in execute(anchor=None, opencl_kernel_filename='ObjectSegmenter.cl', kernel_name='predict', global_size=(3838, 3710), parameters={'in0': <class 'numpy.ndarray'> (3838, 3710) float32, 'out': <class 'numpy.ndarray'> (3710, 3838) uint32}, prog=None, constants=None, image_size_independent_kernel_compilation=None, device=None)
      2 def execute(anchor, opencl_kernel_filename, kernel_name, global_size, parameters, prog = None, constants = None, image_size_independent_kernel_compilation : bool = None, device = None):
----> 3     return Backend.get_instance().get().execute(anchor, opencl_kernel_filename, kernel_name, global_size, parameters, prog, constants, image_size_independent_kernel_compilation, device)
        anchor = None
        opencl_kernel_filename = 'ObjectSegmenter.cl'
        kernel_name = 'predict'
        global_size = (3838, 3710)
        parameters = {'in0': <class 'numpy.ndarray'> (3838, 3710) float32, 'out': <class 'numpy.ndarray'> (3710, 3838) uint32}
        prog = None
        constants = None
        image_size_independent_kernel_compilation = None
        device = None

File ~/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/pyclesperanto_prototype/_tier0/_opencl_backend.py:41, in OpenCLBackend.execute(self=<pyclesperanto_prototype._tier0._opencl_backend.OpenCLBackend object>, anchor=None, opencl_kernel_filename='ObjectSegmenter.cl', kernel_name='predict', global_size=(3838, 3710), parameters={'in0': <class 'numpy.ndarray'> (3838, 3710) float32, 'out': <class 'numpy.ndarray'> (3710, 3838) uint32}, prog=None, constants=None, image_size_independent_kernel_compilation=None, device=None)
     40 def execute(self, anchor, opencl_kernel_filename, kernel_name, global_size, parameters, prog = None, constants = None, image_size_independent_kernel_compilation : bool = None, device = None):
---> 41     return execute(anchor, opencl_kernel_filename, kernel_name, global_size, parameters, prog, constants, image_size_independent_kernel_compilation, device)
        anchor = None
        opencl_kernel_filename = 'ObjectSegmenter.cl'
        kernel_name = 'predict'
        global_size = (3838, 3710)
        parameters = {'in0': <class 'numpy.ndarray'> (3838, 3710) float32, 'out': <class 'numpy.ndarray'> (3710, 3838) uint32}
        prog = None
        constants = None
        image_size_independent_kernel_compilation = None
        device = None

File ~/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/pyclesperanto_prototype/_tier0/_opencl_execute.py:290, in execute(anchor=None, opencl_kernel_filename='ObjectSegmenter.cl', kernel_name='predict', global_size=(3838, 3710), parameters={'in0': <class 'numpy.ndarray'> (3838, 3710) float32, 'out': <class 'numpy.ndarray'> (3710, 3838) uint32}, prog=None, constants=None, image_size_independent_kernel_compilation=True, device=None)
    289         var_type = str(type(value))
--> 290         raise TypeError(
    291             f"other types than float and int aren`t supported yet for parameters {key} : {value} . \n"
    292             f"function {kernel_name}"
    293             f"type {var_type}"
    294         )
    296 # print("Assembling " + opencl_kernel_filename + " took " + str((time.time() - time_stamp) * 1000) + " ms")

TypeError: other types than float and int aren`t supported yet for parameters in0 : [[ 2.5605469   6.1796875   1.9042969  ...  1.8066406   3.4765625
   5.6835938 ]
 [ 2.8203125   1.9326172   3.4355469  ...  3.3144531  -0.06213379
   3.5136719 ]
 [ 5.28125     1.2695312   3.5820312  ...  4.2773438   2.0292969
   2.3027344 ]
 ...
 [ 2.6875      1.1953125   2.9394531  ...  4.703125    1.1337891
   4.203125  ]
 [ 2.4375      8.1953125   6.3398438  ...  3.9394531   4.6953125
   1.2128906 ]
 [ 9.171875    5.0273438   0.35424805 ...  4.3476562   2.8203125
   3.3339844 ]] . 
function predicttype <class 'numpy.ndarray'>

The above exception was the direct cause of the following exception:

EmitLoopError                             Traceback (most recent call last)
File ~/mambaforge/envs/teamtomo-unets/lib/python3.10/site-packages/magicgui/widgets/_bases/value_widget.py:57, in ValueWidget._on_value_change(self=PushButton(value=False, annotation=None, name='call_button'), value=False)
     55 if value is self.null_value and not self._nullable:
     56     return
---> 57 self.changed.emit(value)
        value = False
        self.changed = <SignalInstance 'changed' on PushButton(value=False, annotation=None, name='call_button')>
        self = PushButton(value=False, annotation=None, name='call_button')

File src/psygnal/_signal.py:849, in psygnal._signal.SignalInstance.emit()

File src/psygnal/_signal.py:891, in psygnal._signal.SignalInstance._run_emit_loop()

File src/psygnal/_signal.py:892, in psygnal._signal.SignalInstance._run_emit_loop()

File src/psygnal/_signal.py:914, in psygnal._signal.SignalInstance._run_emit_loop()

EmitLoopError: calling <function FunctionGui.__init__.<locals>._disable_button_and_call at 0x2ac1e7d90> with args=() caused TypeError in emit loop.
haesleinhuepf commented 2 years ago

Hey @alisterburt ,

thanks for reporting! This one looks suspicious, because:

tried to train a classifier from the GUI

Train_object_segmentation

It looks like you're training a segmenter...

Can you give some more details? I'd like to know what data/shape/layer-type you're working with. Also, which menu did you click? A screenshot of your config / scene might also help.

Thanks again!

Best, Robert

alisterburt commented 2 years ago

thanks for the fast response! This is my bad, I wanted to train a pixel classifier and clicked through the menu without really thinking, I was indeed trying to train an object classifier - training a pixel classifier works exactly as expected, sorry for the noise! :)