Repository: Lightning-Universe/lightning-flash

Issue:
Cannot use ReduceLROnPlateau in ObjectDetector
## 🐛 Bug

```python
Using 'efficientdet' provided by airctic/IceVision (https://github.com/airctic/icevision) and rwightman/efficientdet-pytorch (https://github.com/rwightman/efficientdet-pytorch).
GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
Uncaught exception
Traceback (most recent call last):
  File "/mnt/data/buduanban_detection/test.py", line 27, in <module>
    trainer.finetune(model, datamodule=datamodule, strategy="freeze")
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/flash/core/trainer.py", line 161, in finetune
    return super().fit(model, train_dataloader, val_dataloaders, datamodule)
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/trainer/trainer.py", line 740, in fit
    self._call_and_handle_interrupt(
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/trainer/trainer.py", line 685, in _call_and_handle_interrupt
    return trainer_fn(*args, **kwargs)
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/trainer/trainer.py", line 777, in _fit_impl
    self._run(model, ckpt_path=ckpt_path)
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/trainer/trainer.py", line 1145, in _run
    self.accelerator.setup(self)
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/accelerators/gpu.py", line 46, in setup
    return super().setup(trainer)
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/accelerators/accelerator.py", line 93, in setup
    self.setup_optimizers(trainer)
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/accelerators/accelerator.py", line 354, in setup_optimizers
    optimizers, lr_schedulers, optimizer_frequencies = self.training_type_plugin.init_optimizers(
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/plugins/training_type/training_type_plugin.py", line 245, in init_optimizers
    return trainer.init_optimizers(model)
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/trainer/optimizers.py", line 35, in init_optimizers
    optim_conf = self.call_hook("configure_optimizers", pl_module=pl_module)
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/pytorch_lightning/trainer/trainer.py", line 1501, in call_hook
    output = model_fx(*args, **kwargs)
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/flash/core/model.py", line 500, in configure_optimizers
    return [optimizer], [self._instantiate_lr_scheduler(optimizer)]
  File "/data/miniconda3/envs/torch/lib/python3.9/site-packages/flash/core/model.py", line 759, in _instantiate_lr_scheduler
    raise MisconfigurationException(
pytorch_lightning.utilities.exceptions.MisconfigurationException: Please make sure that your custom configuration outputs either an LR Scheduler or a scheduler configuration with keys belonging to ['scheduler', 'name', 'interval', 'frequency', 'reduce_on_plateau', 'monitor', 'strict', 'opt_idx'].
```

### To Reproduce
#### Code sample

```python
import flash
from flash.core.data.utils import download_data
from flash.image import ObjectDetectionData, ObjectDetector

# 1. Create the DataModule
# Dataset Credit: https://www.kaggle.com/ultralytics/coco128
download_data("https://github.com/zhiqwang/yolov5-rt-stack/releases/download/v0.3.0/coco128.zip", "data/")

datamodule = ObjectDetectionData.from_coco(
    train_folder="data/coco128/images/train2017/",
    train_ann_file="data/coco128/annotations/instances_train2017.json",
    val_split=0.1,
    transform_kwargs={"image_size": 128},
    batch_size=4,
)

# 2. Build the task
model = ObjectDetector(head="efficientdet", 
                       backbone="d0", 
                       num_classes=datamodule.num_classes, 
                       image_size=128,
                       lr_scheduler=("reducelronplateau", {"mode": "min"}, {"monitor": "val_loss"}),    # <------------------ use  ReduceLROnPlateau, following the method in https://lightning-flash.readthedocs.io/en/latest/general/optimization.html?highlight=ReduceLROnPlateau#setting-a-learning-rate-scheduler
                       )

# 3. Create the trainer and finetune the model
trainer = flash.Trainer(max_epochs=1, gpus=1)                                 
trainer.finetune(model, datamodule=datamodule, strategy="freeze")

# 4. Detect objects in a few images!
datamodule = ObjectDetectionData.from_files(
    predict_files=[
        "data/coco128/images/train2017/000000000625.jpg",
        "data/coco128/images/train2017/000000000626.jpg",
        "data/coco128/images/train2017/000000000629.jpg",
    ],
    transform_kwargs={"image_size": 128},
    batch_size=4,
)
predictions = trainer.predict(model, datamodule=datamodule)
print(predictions)

# 5. Save the model!
trainer.save_checkpoint("object_detection_model.pt")
```

### Expected behavior

<!-- A clear and concise description of what you expected to happen. -->

### Environment

 - OS (e.g., Linux):  Linux
 - Python version:  3.9.10
 - PyTorch/Lightning/Flash Version (e.g., 1.10/1.5/0.7):   0.7.1
 - GPU models and configuration:
 - Any other relevant information:

### Additional context

<!-- Add any other context about the problem here. -->



Discussion:

Resolving patch:
diff --git a/flash/core/model.py b/flash/core/model.py
--- a/flash/core/model.py
+++ b/flash/core/model.py
@@ -774,12 +774,6 @@ def _instantiate_lr_scheduler(self, optimizer: Optimizer) -> Dict[str, Any]:
         # 2) If return value is a dictionary, check for the lr_scheduler_config `only keys` and return the config.
         lr_scheduler: Union[_LRScheduler, Dict[str, Any]] = lr_scheduler_fn(optimizer, **lr_scheduler_kwargs)
 
-        if not isinstance(lr_scheduler, (_LRScheduler, Dict)):
-            raise MisconfigurationException(
-                f"Please make sure that your custom configuration outputs either an LR Scheduler or a scheduler"
-                f" configuration with keys belonging to {list(default_scheduler_config.keys())}."
-            )
-
         if isinstance(lr_scheduler, Dict):
             dummy_config = default_scheduler_config
             if not all(config_key in dummy_config.keys() for config_key in lr_scheduler.keys()):


Test patch:
diff --git a/tests/core/test_model.py b/tests/core/test_model.py
--- a/tests/core/test_model.py
+++ b/tests/core/test_model.py
@@ -24,7 +24,6 @@
 import pytorch_lightning as pl
 import torch
 from pytorch_lightning.callbacks import Callback
-from pytorch_lightning.utilities.exceptions import MisconfigurationException
 from torch import nn, Tensor
 from torch.nn import functional as F
 from torch.utils.data import DataLoader
@@ -443,18 +442,6 @@ def test_errors_and_exceptions_optimizers_and_schedulers():
         task = ClassificationTask(model, optimizer="Adam", lr_scheduler="not_a_valid_key")
         task.configure_optimizers()
 
-    @ClassificationTask.lr_schedulers
-    def i_will_create_a_misconfiguration_exception(optimizer):
-        return "Done. Created."
-
-    with pytest.raises(MisconfigurationException):
-        task = ClassificationTask(model, optimizer="Adam", lr_scheduler="i_will_create_a_misconfiguration_exception")
-        task.configure_optimizers()
-
-    with pytest.raises(MisconfigurationException):
-        task = ClassificationTask(model, optimizer="Adam", lr_scheduler=i_will_create_a_misconfiguration_exception)
-        task.configure_optimizers()
-
     with pytest.raises(TypeError):
         task = ClassificationTask(model, optimizer="Adam", lr_scheduler=["not", "a", "valid", "type"])
         task.configure_optimizers()
@@ -465,8 +452,6 @@ def i_will_create_a_misconfiguration_exception(optimizer):
         )
         task.configure_optimizers()
 
-    pass
-
 
 def test_classification_task_metrics():
     train_dataset = FixedDataset([0, 1])