Skip to content

Commit

Permalink
Initial pass at more flexible training and removing persnickety archi…
Browse files Browse the repository at this point in the history
…tectures.
  • Loading branch information
faustomorales committed May 21, 2022
1 parent 925ce47 commit 5426ae1
Show file tree
Hide file tree
Showing 31 changed files with 288 additions and 2,858 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mira provides tooling for simple object detection projects. The package spans th

- **Core** object detection abstractions for images and annotations
- Access to **datasets** from common formats (e.g., VOC, COCO) and image sets (e.g., VOC 2012)
- A common API to for **well-known models** (e.g., EfficientDet and FasterRCNN)
- A common API to for **well-known models** (e.g., RetinaNet and FasterRCNN)

Check out [the docs](https://mira-python.readthedocs.io/en/latest/).

Expand Down
14 changes: 7 additions & 7 deletions docs/tutorials.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,23 @@ dataset = datasets.load_voc2012(subset='val')
# set up to use COCO labels.
detector_faster = detectors.FasterRCNN(pretrained_top=True)

detector_ed = detectors.EfficientDet(pretrained_top=True)
detector_retina = detectors.RetinaNet(pretrained_top=True)

# Pick an example scene
scene = dataset[5]

# Set up side-by-side plots
fig, (ax_ed, ax_faster) = plt.subplots(ncols=2, figsize=(10, 5))
ax_ed.set_title('EfficientDet')
fig, (ax_retinanet, ax_faster) = plt.subplots(ncols=2, figsize=(10, 5))
ax_retinanet.set_title('EfficientDet')
ax_faster.set_title('FasterRCNN')

# We get predicted scenes from each detector. Detectors return
# lists of annotations for a given image. So we can just replace
# (assign) those new annotations to the scene to get a new scene
# reflecting the detector's prediction.
predicted_ed = scene.assign(
annotations=detector_ed.detect(scene.image),
annotation_config=detector_ed.annotation_config
predicted_retinanet = scene.assign(
annotations=detector_retina.detect(scene.image),
annotation_config=detector_retina.annotation_config
)
predicted_faster = scene.assign(
annotations=detector_faster.detect(scene.image, threshold=0.4),
Expand All @@ -102,7 +102,7 @@ predicted_faster = scene.assign(

# Plot both predictions. The calls to annotation() get us
# an image with the bounding boxes drawn.
_ = predicted_ed.show(ax=ax_ed)
_ = predicted_retinanet.show(ax=ax_retinanet)
_ = predicted_faster.show(ax=ax_faster)
```

Expand Down
11 changes: 7 additions & 4 deletions mira/core/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,20 +200,23 @@ def crop(self, width, height):
)[-2]
]

def resize(self, scale: float) -> "Annotation":
def resize(self, scale: typing.Union[float, np.ndarray]) -> "Annotation":
"""Obtain a revised selection with a given
uniform scaling."""
return (
self.assign(
**{
k: int(getattr(self, k) * scale)
for k in (
k: int(getattr(self, k) * s)
for k, s in zip(
[
"x1",
"y1",
"x2",
"y2",
]
],
[scale[0], scale[1], scale[0], scale[1]]
if isinstance(scale, np.ndarray)
else [scale, scale, scale, scale],
)
}
)
Expand Down
5 changes: 1 addition & 4 deletions mira/core/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ def best_weights(
maximizes it).
key: What name to use for the saved flag.
"""
if torch is None:
raise ValueError("You must install pytorch to use this callback.")

# pylint: disable=unused-argument
def callback(detector, summaries, data_dir):
saved = False
Expand All @@ -58,7 +55,7 @@ def callback(detector, summaries, data_dir):
else summaries_df[metric].idxmin()
)
if best_idx == len(summaries_df) - 1:
torch.save(detector.model.state_dict(), filepath)
detector.save_weights(filepath)
saved = True
return {key: saved}

Expand Down
2 changes: 1 addition & 1 deletion mira/core/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def annotated(
for ann in self.annotations:
x1, y1, _, _ = ann.x1y1x2y2()
ax.annotate(
text=ann.category.name,
ann.category.name,
xy=(x1, y1),
fontsize=fontsize,
backgroundcolor=(1, 1, 1, 0.5),
Expand Down
3 changes: 1 addition & 2 deletions mira/detectors/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from .efficientdet import EfficientDet
from .detector import Detector
from .fasterrcnn import FasterRCNN
from .retinanet import RetinaNet
from .detr import DETR
from .segmentation import SMP
105 changes: 0 additions & 105 deletions mira/detectors/assets/serve/efficientdet.py

This file was deleted.

21 changes: 2 additions & 19 deletions mira/detectors/assets/serve/fasterrcnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,7 @@ def __init__(self, *args, **kwargs):
),
**self.detector_kwargs,
)
self.set_input_shape(width=INPUT_WIDTH, height=INPUT_HEIGHT)

@property
def input_shape(self):
return self._input_shape

def set_input_shape(self, width, height):
self._input_shape = (height, width, 3)
self.model.transform.fixed_size = (height, width) # type: ignore
self.model.transform.min_size = (min(width, height),) # type: ignore
self.model.transform.max_size = max(height, width) # type: ignore
self.model.transform = mdc.convert_rcnn_transform(self.model.transform)

def forward(self, x):
return mdc.torchvision_serve_inference(
self,
x=x,
resize_method=RESIZE_METHOD,
height=INPUT_HEIGHT,
width=INPUT_WIDTH,
base=None,
)
return mdc.torchvision_serve_inference(self, x=x, resize_config=RESIZE_CONFIG)
21 changes: 2 additions & 19 deletions mira/detectors/assets/serve/retinanet.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,7 @@ def __init__(self, *args, **kwargs):
),
**self.detector_kwargs,
)
self.set_input_shape(width=INPUT_WIDTH, height=INPUT_HEIGHT)

@property
def input_shape(self):
return self._input_shape

def set_input_shape(self, width, height):
self._input_shape = (height, width, 3)
self.model.transform.fixed_size = (height, width) # type: ignore
self.model.transform.min_size = (min(width, height),) # type: ignore
self.model.transform.max_size = max(height, width) # type: ignore
self.model.transform = mdc.convert_rcnn_transform(self.model.transform)

def forward(self, x):
return mdc.torchvision_serve_inference(
self,
x=x,
resize_method=RESIZE_METHOD,
height=INPUT_HEIGHT,
width=INPUT_WIDTH,
base=None,
)
return mdc.torchvision_serve_inference(self, x=x, resize_config=RESIZE_CONFIG)

0 comments on commit 5426ae1

Please sign in to comment.