facebookresearch / ClassyVision

An end-to-end PyTorch framework for image and video classification
https://classyvision.ai
MIT License
1.59k stars 278 forks source link

ValueError: Cannot register duplicate param scheduler (step) - Video classification #762

Closed jpainam closed 2 years ago

jpainam commented 3 years ago

šŸ› Bug

I'm reproducing the video classification. In the 4 step, Building the task. i get this error

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-49f45384e2d7> in <module>
----> 1 from classy_vision.tasks import ClassificationTask
      2 from classy_vision.optim import build_optimizer
      3 from classy_vision.losses import build_loss
      4 
      5 loss = build_loss({"name": "CrossEntropyLoss"})

~/env/lib/python3.6/site-packages/classy_vision/tasks/__init__.py in <module>
     70 
     71 
---> 72 from .classification_task import ClassificationTask  # isort:skip
     73 from .fine_tuning_task import FineTuningTask  # isort:skip
     74 

~/env/lib/python3.6/site-packages/classy_vision/tasks/classification_task.py in <module>
     37 from classy_vision.meters import ClassyMeter, build_meters
     38 from classy_vision.models import ClassyModel, build_model
---> 39 from classy_vision.optim import (
     40     ClassyOptimizer,
     41     build_optimizer,

~/env/lib/python3.6/site-packages/classy_vision/optim/__init__.py in <module>
     10 from classy_vision.generic.registry_utils import import_all_modules
     11 
---> 12 from .classy_optimizer import ClassyOptimizer
     13 from .param_scheduler import build_param_scheduler
     14 

~/env/lib/python3.6/site-packages/classy_vision/optim/classy_optimizer.py in <module>
     10 import torch
     11 
---> 12 from .param_scheduler import (
     13     ClassyParamScheduler,
     14     ConstantParamScheduler,

~/env/lib/python3.6/site-packages/classy_vision/optim/param_scheduler/__init__.py in <module>
     68 
     69 # automatically import any Python files in the optim/param_scheduler/ directory
---> 70 import_all_modules(FILE_ROOT, "classy_vision.optim.param_scheduler")
     71 
     72 from .composite_scheduler import CompositeParamScheduler, IntervalScaling  # isort:skip

~/env/lib/python3.6/site-packages/classy_vision/generic/registry_utils.py in import_all_modules(root, base_module)
     18             if module not in sys.modules:
     19                 module_name = ".".join([base_module, module])
---> 20                 importlib.import_module(module_name)
     21 
     22 

~/env/lib/python3.6/importlib/__init__.py in import_module(name, package)
    124                 break
    125             level += 1
--> 126     return _bootstrap._gcd_import(name[level:], package, level)
    127 
    128 

~/env/lib/python3.6/site-packages/classy_vision/optim/param_scheduler/fvcore_schedulers.py in <module>
     92     param_scheduler.StepParamScheduler,
     93     "step",
---> 94     default_update_interval=UpdateInterval.EPOCH,
     95 )
     96 

~/env/lib/python3.6/site-packages/classy_vision/optim/param_scheduler/fvcore_schedulers.py in _create_classy_scheduler_class(base_class, register_name, default_update_interval)
     55     if hasattr(base_class, "__doc__"):
     56         cls.__doc__ = base_class.__doc__.replace("num_updates", "num_epochs")
---> 57     register_param_scheduler(register_name)(cls)
     58     return cls
     59 

~/env/lib/python3.6/site-packages/classy_vision/optim/param_scheduler/__init__.py in register_param_scheduler_cls(cls)
     53         if name in PARAM_SCHEDULER_REGISTRY:
     54             raise ValueError(
---> 55                 "Cannot register duplicate param scheduler ({})".format(name)
     56             )
     57         if not issubclass(cls, ClassyParamScheduler):

ValueError: Cannot register duplicate param scheduler (step)
mannatsingh commented 3 years ago

@jpainam this seems like it might be expected behavior - if you try to register any component a second time, we raise an error.

If you think you are not re-registering a parameter scheduler, can you share details about your environment and the code you ran?

jpainam commented 3 years ago

I donā€™t think itā€™s necessary to raise an error when someone tries to register a component for a second. A simple warning might be enough. I only register my custom dataset once. And the error seems to occur during the optimizer and scheduler build. I'm using Jupyter notebook and all the cells run except the cell where i defined my scheduler and optimizer.

mannatsingh commented 3 years ago

I agree that the error raising isn't great for most use cases - it was written to prevent a different set of scenarios. It's especially frustrating when working on Jupyter notebooks. I'm sorry for the inconvenience, we'll keep this in mind for future fixes.

I'm hoping you are able to make progress on the tutorial though after restarting your kernel?

jpainam commented 3 years ago

I executed this code using a .py file and a Jupyter notebook with a fresh kernel. Restarted it many times. same error,

from classy_vision.tasks import ClassificationTask
from classy_vision.optim import build_optimizer
from classy_vision.losses import build_loss
from classy_vision.meters import build_meters, AccuracyMeter, VideoAccuracyMeter
from classy_vision.heads import build_head
from collections import defaultdict
from classy_vision.models import build_model

loss = build_loss({"name": "CrossEntropyLoss"})

optimizer = build_optimizer({
    "name": "sgd",
    "param_schedulers": {
        "lr": {
            "name": "multistep",
            "values": [0.005, 0.0005],
            "milestones": [1]
        }
    },
    "num_epochs": 25,
    "weight_decay": 0.0001,
    "momentum": 0.9
})

meters = build_meters({
    "accuracy": {
        "topk": [1, 5]
    },
    "video_accuracy": {
        "topk": [1, 5],
        "clips_per_video_train": 1,
        "clips_per_video_test": 10
    }
})
unique_id = "default_head"
head = build_head({
    "name": "fully_convolutional_linear",
    "unique_id": unique_id,
    "pool_size": [1, 7, 7],
    "num_classes": 2,
    "in_plane": 512    
})

model = build_model({
    "name": "resnext3d",
    "frames_per_clip": 8,        # The number of frames we have in each video clip
    "input_planes": 3,           # We use RGB video frames. So the input planes is 3
    "clip_crop_size": 112,       # We take croppings of size 112 x 112 from the video frames 
    "skip_transformation_type": "postactivated_shortcut",    # The type of skip connection in residual unit
    "residual_transformation_type": "basic_transformation",  # The type of residual connection in residual unit
    "num_blocks": [2, 2, 2, 2],  # The number of residual blocks in each of the 4 stages 
    "input_key": "video",        # The key used to index into the model input of dict type 
    "stage_planes": 64,    
    "num_classes": 2           # the number of classes
})

# In Classy Vision, the head can be attached to any residual block in the trunk. 
# Here we attach the head to the last block as in the standard ResNet model
fork_block = "pathway0-stage4-block1"
heads = {fork_block: [head]}
model.set_heads(heads)

num_epochs = 25
task = (
    ClassificationTask()
    .set_num_epochs(num_epochs)
    .set_loss(loss)
    .set_model(model)
    .set_optimizer(optimizer)
    .set_meters(meters)
) 
#for phase in ["train", "test"]:
#    task.set_dataset(datasets[phase], phase)

Hope the code is self-contained and can be executed. This is my environment

python 3.6
classy_vision 0.5.0
torch 1.8
torchvision 0.9.0
mannatsingh commented 3 years ago

I was not able to repro the error - upon copying the code with the same environment as you mentioned @jpainam I was able to run the code without any issues. Maybe try creating a new environment from scratch and trying this out?

These are the steps I followed -


conda create --name classy_762 python=3.6
conda activate classy_762
conda install pytorch==1.8.0 torchvision==0.9.0 torchaudio==0.8.0 cudatoolkit=10.2 -c pytorch
pip install classy_vision==0.5.0
vim test_classy_762.py
python test_classy_762.py