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

Add support for custom classes #71

Merged
merged 16 commits into from
Sep 16, 2020

Conversation

igonro
Copy link
Contributor

@igonro igonro commented Aug 18, 2020

Please, read open-mmlab/mmdetection#2408 for understanding the changes and the justification.

I didn't add the boolean parameter custom_classes (as it is currently in mmdetection), because I didn't know if it would fit or if it would be necessary to do it. Everything else has been done with the intention of following the logic as it is in mmdetection.

@CLAassistant
Copy link

CLAassistant commented Aug 18, 2020

CLA assistant check
All committers have signed the CLA.

@codecov
Copy link

codecov bot commented Aug 18, 2020

Codecov Report

Merging #71 into master will increase coverage by 0.07%.
The diff coverage is 71.79%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #71      +/-   ##
==========================================
+ Coverage   82.20%   82.28%   +0.07%     
==========================================
  Files          84       84              
  Lines        3974     4013      +39     
  Branches      614      629      +15     
==========================================
+ Hits         3267     3302      +35     
- Misses        576      577       +1     
- Partials      131      134       +3     
Flag Coverage Δ
#unittests 82.28% <71.79%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
mmseg/datasets/custom.py 86.79% <69.44%> (-5.08%) ⬇️
mmseg/datasets/pipelines/loading.py 97.05% <100.00%> (+0.13%) ⬆️
mmseg/datasets/cityscapes.py 21.83% <0.00%> (+1.14%) ⬆️
mmseg/datasets/pipelines/transforms.py 97.52% <0.00%> (+1.23%) ⬆️
mmseg/datasets/ade.py 100.00% <0.00%> (+12.50%) ⬆️
mmseg/datasets/voc.py 100.00% <0.00%> (+20.00%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c3e4dbc...5d0fda4. Read the comment docs.

@hellock hellock requested a review from xvjiarui August 18, 2020 15:33
@xvjiarui
Copy link
Collaborator

Hi @igonro
Thanks for your contribution.
But in this PR, training on the only subclass is still not supported since the annotation is the same.
We need to modify data pipeline to make it work.

@igonro
Copy link
Contributor Author

igonro commented Aug 19, 2020

Is that functionality already being implemented? If not, I could try to implement it. @xvjiarui

@xvjiarui
Copy link
Collaborator

Hi @igonro
It not implemented yet. PRs are welcome!

@igonro
Copy link
Contributor Author

igonro commented Aug 19, 2020

Have you identified any problem or any way to proceed to implement it? I'm still a newbie to mmsegmentation, so it would be great to get some hint (if you have thought about it). @xvjiarui

@xvjiarui
Copy link
Collaborator

Hi @igonro
Sorry for the late reply.
Since the pixel label is determined by the annotation file, we may need to modify the loading annotation pipeline here.
Very naive way to achieve this is to filter and re-assign the gt_semantic_seg. But it is not very neat. Any idea?

@igonro
Copy link
Contributor Author

igonro commented Aug 25, 2020

Hi @xvjiarui, can you check out the last changes I have made?

mmseg/datasets/custom.py Outdated Show resolved Hide resolved
mmseg/datasets/custom.py Outdated Show resolved Hide resolved
@@ -160,6 +187,8 @@ def get_ann_info(self, idx):
def pre_pipeline(self, results):
"""Prepare results dict for pipeline."""
results['seg_fields'] = []
if self.custom_classes:
results['old_id_to_new_id'] = self.old_id_to_new_id
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use something like label_map and add some comments about it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what you mean by label_map. Do you mean changing the key name?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the ambiguity.
Yes, 'old_id_to_new_id' is a bit too long. But 'label_map' may not be straight forward enough. Any idea?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe class_transform, class_id_transform or label_transform?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or label_map could be good with a comment explaining it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then label_map it is. We may add comments about key and value of this dict.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may also add comments about what's the purpose of adding this dict.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So shall we rename it to label_map?

mmseg/datasets/custom.py Outdated Show resolved Hide resolved
Comment on lines 111 to 112
if matched_classes < len(classes):
raise ValueError('classes is not a subset of CLASSES.')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may check this by python builtin issubset.

self.old_id_to_new_id = {}
matched_classes = 0
for i, c in enumerate(self.CLASSES):
if c not in classes:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may remove this condition by checking issubset first.

@igonro igonro marked this pull request as draft August 28, 2020 09:45
Comment on lines 279 to 299
def get_palette_for_custom_classes(self, palette=None):

if palette:
if isinstance(palette, str):
# take it as a file path
palette_values = mmcv.list_from_file(palette)
elif isinstance(palette, (tuple, list)):
palette_values = palette
else:
raise ValueError(
f'Unsupported type {type(palette)} of palette.')

else:
palette_values = []
for x in sorted(self.old_id_to_new_id.items(), key=lambda x: x[1]):
if x[1] != -1:
palette_values.append(self.PALETTE[x[0]])

palette_values = type(self.PALETTE)(palette_values)

return palette_values
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Custom palette from user input may not be necessary for CustomDataset. We may directly set palette by indices from subclasses.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sorry. I was still fixing some things... You can now take a look if you can.

classes=None,
test_mode=True)

assert custom_dataset.CLASSES == original_classes
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may add a test case for LoadAnnotation pipeline when there is custom classes.
To achieve this, we may generate a random ground truth segmentation map.

Copy link
Contributor Author

@igonro igonro Sep 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I add it in test_loading.py or in this same file? Also I'm not very sure what type of test I should add.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may add it in test_loading.py.
We should check if the loaded annotation is of custom classes as desired.

@xvjiarui
Copy link
Collaborator

You may change the draft status when this PR is ready.

@igonro igonro marked this pull request as ready for review September 4, 2020 14:08
if palette:
if isinstance(palette, str):
# take it as a file path
palette = mmcv.list_from_file(palette)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The palette is a list of list. It is not trivial to load palette from path.
I suggest removing this function. We just need to select the right palette if there is.

test_gt[6:8, 2:4] = 3
test_gt[6:8, 6:8] = 4

img_path = osp.join(osp.dirname(__file__), 'img.jpg')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried using tmpdir and tmp_path for doing this, but it raises an error when calling imwrite (not sure why), so I've had to make this workaround.

@igonro
Copy link
Contributor Author

igonro commented Sep 14, 2020

Hey @xvjiarui, could you review this when you have the time? Thanks!

@xvjiarui
Copy link
Collaborator

xvjiarui commented Sep 14, 2020

Hi @igonro
Sorry for the late reply.
This comment has not be resolved yet.
Could you resolve it first? I will look into tmpdir issue today.

Update:
tmpdir looks fine.

@igonro
Copy link
Contributor Author

igonro commented Sep 14, 2020

Hi @igonro
Sorry for the late reply.
This comment has not be resolved yet.
Could you resolve it first? I will look into tmpdir issue today.

Fixed. I've missunderstood your comment.

reduce_zero_label=False):
reduce_zero_label=False,
classes=None,
palette=None):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

palette arg is not needed.

@@ -230,6 +244,49 @@ def get_gt_seg_maps(self):

return gt_seg_maps

def get_classes_and_palette(self, classes=None, palette=None):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

palette arg is not needed.

else:
self.label_map[i] = classes.index(c)

return class_names, palette
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to return the subset of PALETTE since we are using a subset of CLASSES.

@xvjiarui
Copy link
Collaborator

Hi @igonro
Sorry for the late reply.
This comment has not be resolved yet.
Could you resolve it first? I will look into tmpdir issue today.

Fixed. I've missunderstood your comment.

Hi @igonro
There are still some uncleaned snippets about palette. Please refer to the comment for detail.

@igonro
Copy link
Contributor Author

igonro commented Sep 16, 2020

Hi @xvjiarui
I made those changes. I hope that now everything is fine.

@xvjiarui xvjiarui merged commit b8c2f91 into open-mmlab:master Sep 16, 2020
bowenroom pushed a commit to bowenroom/mmsegmentation that referenced this pull request Feb 25, 2022
* Support for custom classes

* Fix test

* Fix pre-commit

* Add pipeline logic for custom classes

* Fix minor issues, fix test

* Fix issues from PR review

* Fix tests

* Remove palette as str

* Rename old_to_new_ids to label_map

* Test for load_anns

* Remove get_palette function

* fixed temp

* Add subset of palette, remove palette as arg

* minor update

Co-authored-by: Jiarui XU <xvjiarui0826@gmail.com>
aravind-h-v pushed a commit to aravind-h-v/mmsegmentation that referenced this pull request Mar 27, 2023
* refactor fir up/down sample

* remove variance scaling

* remove variance scaling from unet sde

* refactor Linear

* style

* actually remove variance scaling

* add back upsample_2d, downsample_2d

* style

* fix FirUpsample2D
sibozhang pushed a commit to sibozhang/mmsegmentation that referenced this pull request Mar 22, 2024
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

Successfully merging this pull request may close these issues.

3 participants