PatBall1 / detectree2

Python package for automatic tree crown delineation based on the Detectron2 implementation of Mask R-CNN
https://patball1.github.io/detectree2/
MIT License
148 stars 35 forks source link

TypeError: 'float' object is not subscriptable during training #94

Open zeppehpt1 opened 1 year ago

zeppehpt1 commented 1 year ago

Hello,

I would like to include four locations for training my model.

Error

Here is the error code:

Traceback (most recent call last):
  File "driver.py", line 75, in <module>
    trainer = MyTrainer(cfg, patience=4)
  File "/home/nieding/detectree2/detectree2/models/train.py", line 182, in __init__
    super().__init__(cfg)
  File "/home/nieding/mambaforge/envs/detectree2/lib/python3.8/site-packages/detectron2/engine/defaults.py", line 378, in __init__
    data_loader = self.build_train_loader(cfg)
  File "/home/nieding/mambaforge/envs/detectree2/lib/python3.8/site-packages/detectron2/engine/defaults.py", line 547, in build_train_loader
    return build_detection_train_loader(cfg)
  File "/home/nieding/mambaforge/envs/detectree2/lib/python3.8/site-packages/detectron2/config/config.py", line 207, in wrapped
    explicit_args = _get_args_from_config(from_config, *args, **kwargs)
  File "/home/nieding/mambaforge/envs/detectree2/lib/python3.8/site-packages/detectron2/config/config.py", line 245, in _get_args_from_config
    ret = from_config_func(*args, **kwargs)
  File "/home/nieding/mambaforge/envs/detectree2/lib/python3.8/site-packages/detectron2/data/build.py", line 344, in _train_loader_from_config
    dataset = get_detection_dataset_dicts(
  File "/home/nieding/mambaforge/envs/detectree2/lib/python3.8/site-packages/detectron2/data/build.py", line 241, in get_detection_dataset_dicts
    dataset_dicts = [DatasetCatalog.get(dataset_name) for dataset_name in names]
  File "/home/nieding/mambaforge/envs/detectree2/lib/python3.8/site-packages/detectron2/data/build.py", line 241, in <listcomp>
    dataset_dicts = [DatasetCatalog.get(dataset_name) for dataset_name in names]
  File "/home/nieding/mambaforge/envs/detectree2/lib/python3.8/site-packages/detectron2/data/catalog.py", line 59, in get
    return f()
  File "/home/nieding/detectree2/detectree2/models/train.py", line 489, in <lambda>
    DatasetCatalog.register(name + "_" + d, lambda d=d: combine_dicts(train_location,
  File "/home/nieding/detectree2/detectree2/models/train.py", line 443, in combine_dicts
    tree_dicts += get_tree_dicts(d, classes=classes, classes_at=classes_at)
  File "/home/nieding/detectree2/detectree2/models/train.py", line 388, in get_tree_dicts
    px = [a[0] for a in anno["coordinates"][0]]
  File "/home/nieding/detectree2/detectree2/models/train.py", line 388, in <listcomp>
    px = [a[0] for a in anno["coordinates"][0]]
TypeError: 'float' object is not subscriptable

Code snippet

The following code describes how I register the datasets:

# register hain
train_location = '../data/Bamberg_Hain/training/training_tiles/train/'
register_train_data(train_location, 'Bamberg_Hain', 1) # registers train and val sets
print("Hain datasets registered")

# register stadtwald
train_location = '../data/Bamberg_Stadtwald/training/training_tiles/train/'
register_train_data(train_location, 'Bamberg_Stadtwald', 1) # registers train and val sets
print("Stadtwald datasets registered")

[...]

# set models
base_model = "COCO-InstanceSegmentation/mask_rcnn_R_101_FPN_3x.yaml" #with api
pre_trained_model = site_folder + 'models/220723_withParacouUAV.pth'

# registered sets
# registered sets
trains = ("Bamberg_Hain_train", "Bamberg_Stadtwald_train" "Tretzendorf_train", "Schiefer_train")
tests = ("Bamberg_Hain_val", "Bamberg_Stadtwald_val" "Tretzendorf_val", "Schiefer_val")

Update:

Ok with a fresh mind, I found that the error message was not misleading and that a sudden float object was the reason for the failure.

PatBall1 commented 1 year ago

Hi @zeppehpt1 I am glad you could solve your issue. Would you mind sharing some more details about the problem/solution to help other users and possibly allow me to implement a fix that would make the code more robust? Thanks for using the package and feel free to get in touch if you have any more issues/comments.

zeppehpt1 commented 1 year ago

Oh yeah for sure, just had to do some additional investigations. So the problem was that the created .geojson files from the data preparation step (tiling) contained not only 'Polygon' as a geometry type, but also the type 'LineString'. In this particular case, the first index (a[0]) is a float and not a list - so the error occurred. I checked the ground truth file for possible 'LineString' geometries, but there were none. I temporarily fixed this by checking for the geometry type 'LineString' in the get_tree_dicts() function. Though, I don't know why this 'LineString' type occured and why it was created in the first place. Strangely this only appeared in the two datasets that I didn't annotated by myself. Perhaps it ultimately depends on having high-quality annotated data.

My temp fix:

for features in img_anns["features"]:
            anno = features["geometry"]
            if anno['type'] != 'LineString':
PatBall1 commented 1 year ago

Interesting, thanks. I'll aim to get that fixed in the next update.