We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
fastai efficientdet fails on learn.validate() with AttributeError: 'NoneType' object has no attribute 'shape'
## 🐛 Bug
when trying to simply validate metrics for an efficientdet model with fastai 
```python
KeyError: 'image_id'
```
```python
AttributeError: 'NoneType' object has no attribute 'shape'
```

it fails when trying to read the batch size automatically: in `accumulate, find_bs`
```python
class AvgLoss(Metric):
    "Average the losses taking into account potential different batch sizes"
    def reset(self):           self.total,self.count = 0.,0
    def accumulate(self, learn):
        bs = find_bs(learn.yb)
        self.total += learn.to_detach(learn.loss.mean())*bs
        self.count += bs
    @property
    def value(self): return self.total/self.count if self.count != 0 else None
    @property
    def name(self):  return "loss"
```
**To Reproduce**
Steps to reproduce the behavior:
1. Go to https://colab.research.google.com/drive/1i4aXYu4wIKA7eLUK86GwTm7lq7zku_oF?usp=sharing



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `icevision/models/torchvision/fastai/learner.py`
Content:
```
1 __all__ = ["RCNNCallback", "rcnn_learner"]
2 
3 from icevision.imports import *
4 from icevision.engines.fastai import *
5 from icevision.models.torchvision.loss_fn import loss_fn
6 from icevision.models.torchvision.fastai.callbacks import *
7 
8 
9 def noop_watch(models, criterion=None, log="gradients", log_freq=1000, idx=None):
10     return []
11 
12 
13 def rcnn_learner(
14     dls: List[Union[DataLoader, fastai.DataLoader]],
15     model: nn.Module,
16     cbs=None,
17     **kwargs,
18 ):
19     learn = adapted_fastai_learner(
20         dls=dls,
21         model=model,
22         cbs=cbs,
23         loss_func=loss_fn,
24         **kwargs,
25     )
26 
27     # HACK: patch AvgLoss (in original, find_bs gives errors)
28     class RCNNAvgLoss(fastai.AvgLoss):
29         def accumulate(self, learn):
30             bs = len(learn.yb)
31             self.total += fastai.to_detach(learn.loss.mean()) * bs
32             self.count += bs
33 
34     recorder = [cb for cb in learn.cbs if isinstance(cb, fastai.Recorder)][0]
35     recorder.loss = RCNNAvgLoss()
36 
37     is_wandb = [cb for cb in learn.cbs if "WandbCallback" in str(type(cb))]
38     if len(is_wandb) == 1:
39         logger.warning("Wandb quickfix implemented, for more info check issue #527")
40         wandb.watch = noop_watch
41     if len(is_wandb) > 1:
42         raise ValueError(
43             f"It seems you are passing {len(is_wandb)} `WandbCallback` instances to the `learner`. Only 1 is allowed."
44         )
45 
46     return learn
47
```

Path: `icevision/models/ross/efficientdet/fastai/learner.py`
Content:
```
1 __all__ = ["learner"]
2 
3 from icevision.imports import *
4 from icevision.engines.fastai import *
5 from icevision.models.ross.efficientdet.loss_fn import loss_fn
6 from icevision.models.ross.efficientdet.fastai.callbacks import EfficientDetCallback
7 
8 
9 def learner(
10     dls: List[Union[DataLoader, fastai.DataLoader]],
11     model: nn.Module,
12     cbs=None,
13     **learner_kwargs,
14 ):
15     """Fastai `Learner` adapted for EfficientDet.
16 
17     # Arguments
18         dls: `Sequence` of `DataLoaders` passed to the `Learner`.
19         The first one will be used for training and the second for validation.
20         model: The model to train.
21         cbs: Optional `Sequence` of callbacks.
22         **learner_kwargs: Keyword arguments that will be internally passed to `Learner`.
23 
24     # Returns
25         A fastai `Learner`.
26     """
27     cbs = [EfficientDetCallback()] + L(cbs)
28 
29     learn = adapted_fastai_learner(
30         dls=dls,
31         model=model,
32         cbs=cbs,
33         loss_func=loss_fn,
34         **learner_kwargs,
35     )
36 
37     # HACK: patch AvgLoss (in original, find_bs gives errors)
38     class PatchedAvgLoss(fastai.AvgLoss):
39         def accumulate(self, learn):
40             bs = len(learn.yb)
41             self.total += fastai.to_detach(learn.loss.mean()) * bs
42             self.count += bs
43 
44     recorder = [cb for cb in learn.cbs if isinstance(cb, fastai.Recorder)][0]
45     recorder.loss = PatchedAvgLoss()
46 
47     return learn
48
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/icevision/models/ross/efficientdet/fastai/learner.py b/icevision/models/ross/efficientdet/fastai/learner.py
--- a/icevision/models/ross/efficientdet/fastai/learner.py
+++ b/icevision/models/ross/efficientdet/fastai/learner.py
@@ -34,14 +34,14 @@
         **learner_kwargs,
     )
 
-    # HACK: patch AvgLoss (in original, find_bs gives errors)
-    class PatchedAvgLoss(fastai.AvgLoss):
+    # HACK: patch AvgLoss (in original, find_bs looks at the first element in dictionary and gives errors)
+    class EffDetAvgLoss(fastai.AvgLoss):
         def accumulate(self, learn):
-            bs = len(learn.yb)
-            self.total += fastai.to_detach(learn.loss.mean()) * bs
+            bs = len(first(learn.yb)["cls"])
+            self.total += learn.to_detach(learn.loss.mean()) * bs
             self.count += bs
 
     recorder = [cb for cb in learn.cbs if isinstance(cb, fastai.Recorder)][0]
-    recorder.loss = PatchedAvgLoss()
+    recorder.loss = EffDetAvgLoss()
 
     return learn
diff --git a/icevision/models/torchvision/fastai/learner.py b/icevision/models/torchvision/fastai/learner.py
--- a/icevision/models/torchvision/fastai/learner.py
+++ b/icevision/models/torchvision/fastai/learner.py
@@ -27,7 +27,7 @@
     # HACK: patch AvgLoss (in original, find_bs gives errors)
     class RCNNAvgLoss(fastai.AvgLoss):
         def accumulate(self, learn):
-            bs = len(learn.yb)
+            bs = len(first(learn.yb))
             self.total += fastai.to_detach(learn.loss.mean()) * bs
             self.count += bs

{"golden_diff": "diff --git a/icevision/models/ross/efficientdet/fastai/learner.py b/icevision/models/ross/efficientdet/fastai/learner.py\n--- a/icevision/models/ross/efficientdet/fastai/learner.py\n+++ b/icevision/models/ross/efficientdet/fastai/learner.py\n@@ -34,14 +34,14 @@\n         **learner_kwargs,\n     )\n \n-    # HACK: patch AvgLoss (in original, find_bs gives errors)\n-    class PatchedAvgLoss(fastai.AvgLoss):\n+    # HACK: patch AvgLoss (in original, find_bs looks at the first element in dictionary and gives errors)\n+    class EffDetAvgLoss(fastai.AvgLoss):\n         def accumulate(self, learn):\n-            bs = len(learn.yb)\n-            self.total += fastai.to_detach(learn.loss.mean()) * bs\n+            bs = len(first(learn.yb)[\"cls\"])\n+            self.total += learn.to_detach(learn.loss.mean()) * bs\n             self.count += bs\n \n     recorder = [cb for cb in learn.cbs if isinstance(cb, fastai.Recorder)][0]\n-    recorder.loss = PatchedAvgLoss()\n+    recorder.loss = EffDetAvgLoss()\n \n     return learn\ndiff --git a/icevision/models/torchvision/fastai/learner.py b/icevision/models/torchvision/fastai/learner.py\n--- a/icevision/models/torchvision/fastai/learner.py\n+++ b/icevision/models/torchvision/fastai/learner.py\n@@ -27,7 +27,7 @@\n     # HACK: patch AvgLoss (in original, find_bs gives errors)\n     class RCNNAvgLoss(fastai.AvgLoss):\n         def accumulate(self, learn):\n-            bs = len(learn.yb)\n+            bs = len(first(learn.yb))\n             self.total += fastai.to_detach(learn.loss.mean()) * bs\n             self.count += bs\n", "issue": "fastai efficientdet fails on learn.validate() with AttributeError: 'NoneType' object has no attribute 'shape'\n## \ud83d\udc1b Bug\r\nwhen trying to simply validate metrics for an efficientdet model with fastai \r\n```python\r\nKeyError: 'image_id'\r\n```\r\n```python\r\nAttributeError: 'NoneType' object has no attribute 'shape'\r\n```\r\n\r\nit fails when trying to read the batch size automatically: in `accumulate, find_bs`\r\n```python\r\nclass AvgLoss(Metric):\r\n    \"Average the losses taking into account potential different batch sizes\"\r\n    def reset(self):           self.total,self.count = 0.,0\r\n    def accumulate(self, learn):\r\n        bs = find_bs(learn.yb)\r\n        self.total += learn.to_detach(learn.loss.mean())*bs\r\n        self.count += bs\r\n    @property\r\n    def value(self): return self.total/self.count if self.count != 0 else None\r\n    @property\r\n    def name(self):  return \"loss\"\r\n```\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Go to https://colab.research.google.com/drive/1i4aXYu4wIKA7eLUK86GwTm7lq7zku_oF?usp=sharing\r\n\r\n\n", "before_files": [{"content": "__all__ = [\"RCNNCallback\", \"rcnn_learner\"]\n\nfrom icevision.imports import *\nfrom icevision.engines.fastai import *\nfrom icevision.models.torchvision.loss_fn import loss_fn\nfrom icevision.models.torchvision.fastai.callbacks import *\n\n\ndef noop_watch(models, criterion=None, log=\"gradients\", log_freq=1000, idx=None):\n    return []\n\n\ndef rcnn_learner(\n    dls: List[Union[DataLoader, fastai.DataLoader]],\n    model: nn.Module,\n    cbs=None,\n    **kwargs,\n):\n    learn = adapted_fastai_learner(\n        dls=dls,\n        model=model,\n        cbs=cbs,\n        loss_func=loss_fn,\n        **kwargs,\n    )\n\n    # HACK: patch AvgLoss (in original, find_bs gives errors)\n    class RCNNAvgLoss(fastai.AvgLoss):\n        def accumulate(self, learn):\n            bs = len(learn.yb)\n            self.total += fastai.to_detach(learn.loss.mean()) * bs\n            self.count += bs\n\n    recorder = [cb for cb in learn.cbs if isinstance(cb, fastai.Recorder)][0]\n    recorder.loss = RCNNAvgLoss()\n\n    is_wandb = [cb for cb in learn.cbs if \"WandbCallback\" in str(type(cb))]\n    if len(is_wandb) == 1:\n        logger.warning(\"Wandb quickfix implemented, for more info check issue #527\")\n        wandb.watch = noop_watch\n    if len(is_wandb) > 1:\n        raise ValueError(\n            f\"It seems you are passing {len(is_wandb)} `WandbCallback` instances to the `learner`. Only 1 is allowed.\"\n        )\n\n    return learn\n", "path": "icevision/models/torchvision/fastai/learner.py"}, {"content": "__all__ = [\"learner\"]\n\nfrom icevision.imports import *\nfrom icevision.engines.fastai import *\nfrom icevision.models.ross.efficientdet.loss_fn import loss_fn\nfrom icevision.models.ross.efficientdet.fastai.callbacks import EfficientDetCallback\n\n\ndef learner(\n    dls: List[Union[DataLoader, fastai.DataLoader]],\n    model: nn.Module,\n    cbs=None,\n    **learner_kwargs,\n):\n    \"\"\"Fastai `Learner` adapted for EfficientDet.\n\n    # Arguments\n        dls: `Sequence` of `DataLoaders` passed to the `Learner`.\n        The first one will be used for training and the second for validation.\n        model: The model to train.\n        cbs: Optional `Sequence` of callbacks.\n        **learner_kwargs: Keyword arguments that will be internally passed to `Learner`.\n\n    # Returns\n        A fastai `Learner`.\n    \"\"\"\n    cbs = [EfficientDetCallback()] + L(cbs)\n\n    learn = adapted_fastai_learner(\n        dls=dls,\n        model=model,\n        cbs=cbs,\n        loss_func=loss_fn,\n        **learner_kwargs,\n    )\n\n    # HACK: patch AvgLoss (in original, find_bs gives errors)\n    class PatchedAvgLoss(fastai.AvgLoss):\n        def accumulate(self, learn):\n            bs = len(learn.yb)\n            self.total += fastai.to_detach(learn.loss.mean()) * bs\n            self.count += bs\n\n    recorder = [cb for cb in learn.cbs if isinstance(cb, fastai.Recorder)][0]\n    recorder.loss = PatchedAvgLoss()\n\n    return learn\n", "path": "icevision/models/ross/efficientdet/fastai/learner.py"}], "after_files": [{"content": "__all__ = [\"RCNNCallback\", \"rcnn_learner\"]\n\nfrom icevision.imports import *\nfrom icevision.engines.fastai import *\nfrom icevision.models.torchvision.loss_fn import loss_fn\nfrom icevision.models.torchvision.fastai.callbacks import *\n\n\ndef noop_watch(models, criterion=None, log=\"gradients\", log_freq=1000, idx=None):\n    return []\n\n\ndef rcnn_learner(\n    dls: List[Union[DataLoader, fastai.DataLoader]],\n    model: nn.Module,\n    cbs=None,\n    **kwargs,\n):\n    learn = adapted_fastai_learner(\n        dls=dls,\n        model=model,\n        cbs=cbs,\n        loss_func=loss_fn,\n        **kwargs,\n    )\n\n    # HACK: patch AvgLoss (in original, find_bs gives errors)\n    class RCNNAvgLoss(fastai.AvgLoss):\n        def accumulate(self, learn):\n            bs = len(first(learn.yb))\n            self.total += fastai.to_detach(learn.loss.mean()) * bs\n            self.count += bs\n\n    recorder = [cb for cb in learn.cbs if isinstance(cb, fastai.Recorder)][0]\n    recorder.loss = RCNNAvgLoss()\n\n    is_wandb = [cb for cb in learn.cbs if \"WandbCallback\" in str(type(cb))]\n    if len(is_wandb) == 1:\n        logger.warning(\"Wandb quickfix implemented, for more info check issue #527\")\n        wandb.watch = noop_watch\n    if len(is_wandb) > 1:\n        raise ValueError(\n            f\"It seems you are passing {len(is_wandb)} `WandbCallback` instances to the `learner`. Only 1 is allowed.\"\n        )\n\n    return learn\n", "path": "icevision/models/torchvision/fastai/learner.py"}, {"content": "__all__ = [\"learner\"]\n\nfrom icevision.imports import *\nfrom icevision.engines.fastai import *\nfrom icevision.models.ross.efficientdet.loss_fn import loss_fn\nfrom icevision.models.ross.efficientdet.fastai.callbacks import EfficientDetCallback\n\n\ndef learner(\n    dls: List[Union[DataLoader, fastai.DataLoader]],\n    model: nn.Module,\n    cbs=None,\n    **learner_kwargs,\n):\n    \"\"\"Fastai `Learner` adapted for EfficientDet.\n\n    # Arguments\n        dls: `Sequence` of `DataLoaders` passed to the `Learner`.\n        The first one will be used for training and the second for validation.\n        model: The model to train.\n        cbs: Optional `Sequence` of callbacks.\n        **learner_kwargs: Keyword arguments that will be internally passed to `Learner`.\n\n    # Returns\n        A fastai `Learner`.\n    \"\"\"\n    cbs = [EfficientDetCallback()] + L(cbs)\n\n    learn = adapted_fastai_learner(\n        dls=dls,\n        model=model,\n        cbs=cbs,\n        loss_func=loss_fn,\n        **learner_kwargs,\n    )\n\n    # HACK: patch AvgLoss (in original, find_bs looks at the first element in dictionary and gives errors)\n    class EffDetAvgLoss(fastai.AvgLoss):\n        def accumulate(self, learn):\n            bs = len(first(learn.yb)[\"cls\"])\n            self.total += learn.to_detach(learn.loss.mean()) * bs\n            self.count += bs\n\n    recorder = [cb for cb in learn.cbs if isinstance(cb, fastai.Recorder)][0]\n    recorder.loss = EffDetAvgLoss()\n\n    return learn\n", "path": "icevision/models/ross/efficientdet/fastai/learner.py"}]}