bluemellophone commited on
Commit
6fe328f
·
unverified ·
1 Parent(s): 79b792e

Added changelog, documentation on model outputs, new envars, and label mapping

Browse files
CHANGELOG.rst ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ =========
2
+ Changelog
3
+ =========
4
+
5
+ Version 0.1.17
6
+ --------------
7
+
8
+ - Added detection label mapping for the ``phase1`` output to rename ``elephant_savanna`` to ``elephant``
9
+ to be consistent with the ``mvp`` output labels.
10
+ - Added rounding to the WIC predicted confidence to 4 decimal points in the print and JSON outputs.
11
+ - Added to the documentation the list of supported class labels for each model configuration.
12
+ - Added platform detection code to detect macOS and reduce the batch size of WIC models with the
13
+ MVP model to 1 (added to Known Issues).
14
+ - Added three new environment variables to allow specifying the model configuration for the ``WIC``,
15
+ ``LOC``, and ``AGG``, respectively: ``WIC_CONFIG``, ``LOC_CONFIG``, ``AGG_CONFIG``. If unset, it
16
+ uses the global config and behavior as specified by the ``CONFIG`` environment variable. The TILE
17
+ module does not have different settings dependent on the model configuration.
18
+ - Added a new environment variable to allow for faster but less accurate results: ``FAST``. If unset, it
19
+ uses the standard tile extraction behavior for grid1 and grid2. Turning this flag on will dramatically
20
+ speed up inference by processing approximately half of the number of tiles per image.
21
+ - Added ``CHANGELOG.rst`` and ``ISSUES.rst``.
22
+ - Modified documentation strings in a few places for clarity and correctness.
23
+
24
+ Version 0.1.16
25
+ --------------
26
+
27
+ *Alpha version of Scoutbot, with all Phase 1 and MVP functionality and pre-trained models included*
ISSUES.rst ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ ============
2
+ Known Issues
3
+ ============
4
+
5
+ - Non-determinism and ONNX Runtime prediction failure on macOS when using MVP WIC
6
+ model and a batch size greater than 1. The code will automatically recude the
7
+ batch size to 1 for this configuration and applicable environments.
docs/cli.rst CHANGED
@@ -7,7 +7,6 @@ models that have been pretrained for inference in a production environment.
7
 
8
  .. toctree::
9
  :maxdepth: 3
10
- :caption: Contents:
11
 
12
  .. click:: scoutbot.scoutbot:cli
13
  :prog: scoutbot
 
7
 
8
  .. toctree::
9
  :maxdepth: 3
 
10
 
11
  .. click:: scoutbot.scoutbot:cli
12
  :prog: scoutbot
docs/environment.rst CHANGED
@@ -7,12 +7,30 @@ and configurations.
7
  - ``CONFIG`` (default: mvp)
8
  The configuration setting for which machine lerning models to use.
9
  Must be one of ``phase1`` or ``mvp``, or their respective aliases as ``old`` or ``new``.
 
 
 
 
 
 
 
 
 
 
 
 
10
  - ``WIC_BATCH_SIZE`` (default: 256)
11
  The configuration setting for how many tiles to send to the GPU in a single batch during the WIC
12
  prediction (forward inference). The LOC model has a fixed batch size (16 for ``phase1`` and
13
  32 for ``mvp``) and cannot be adjusted. This setting can be used to control how fast the pipeline
14
  runs, as a trade-off of faster compute for more memory usage. It is highly suggested to set this
15
  value as high as possible to fit into the GPU.
 
 
 
 
 
16
  - ``VERBOSE`` (default: not set)
17
  A verbosity flag that can be set to turn on debug logging. Defaults to "not set", which translates
18
- to no debug logging.
 
 
7
  - ``CONFIG`` (default: mvp)
8
  The configuration setting for which machine lerning models to use.
9
  Must be one of ``phase1`` or ``mvp``, or their respective aliases as ``old`` or ``new``.
10
+ - ``WIC_CONFIG`` (default: not set)
11
+ The configuration setting for which machine lerning models to use with the WIC.
12
+ Must be one of ``phase1`` or ``mvp``, or their respective aliases as ``old`` or ``new``.
13
+ Defaults to the value of the ``CONFIG`` environment variable.
14
+ - ``LOC_CONFIG`` (default: not set)
15
+ The configuration setting for which machine lerning models to use with the LOC.
16
+ Must be one of ``phase1`` or ``mvp``, or their respective aliases as ``old`` or ``new``.
17
+ Defaults to the value of the ``CONFIG`` environment variable.
18
+ - ``AGG_CONFIG`` (default: not set)
19
+ The configuration setting for which machine lerning models to use with the AGG.
20
+ Must be one of ``phase1`` or ``mvp``, or their respective aliases as ``old`` or ``new``.
21
+ Defaults to the value of the ``CONFIG`` environment variable.
22
  - ``WIC_BATCH_SIZE`` (default: 256)
23
  The configuration setting for how many tiles to send to the GPU in a single batch during the WIC
24
  prediction (forward inference). The LOC model has a fixed batch size (16 for ``phase1`` and
25
  32 for ``mvp``) and cannot be adjusted. This setting can be used to control how fast the pipeline
26
  runs, as a trade-off of faster compute for more memory usage. It is highly suggested to set this
27
  value as high as possible to fit into the GPU.
28
+ - ``FAST`` (default: not set)
29
+ A flag that can be set to turn off extracting the second grid of tiles. Defaults to "not set", which
30
+ translates to the standard process of extracting all tiles for grid1 and grid2. Setting this
31
+ value to anything will turn off grid2 and results in faster (but less accurate) detections
32
+ (e.g., ``FAST=1``).
33
  - ``VERBOSE`` (default: not set)
34
  A verbosity flag that can be set to turn on debug logging. Defaults to "not set", which translates
35
+ to no debug logging. Setting this value to anything will turn on debug logging
36
+ (e.g., ``VERBOSE=1``).
docs/index.rst CHANGED
@@ -1,6 +1,15 @@
1
  .. include:: ../README.rst
2
 
 
 
 
 
 
 
 
 
3
  .. toctree::
 
4
 
5
  Home <self>
6
  scoutbot
 
1
  .. include:: ../README.rst
2
 
3
+ .. include:: ../CHANGELOG.rst
4
+
5
+ .. include:: ../ISSUES.rst
6
+
7
+ ========
8
+ Contents
9
+ ========
10
+
11
  .. toctree::
12
+ :maxdepth: 3
13
 
14
  Home <self>
15
  scoutbot
docs/onnx.rst CHANGED
@@ -27,3 +27,63 @@ cache folder:
27
  SHA256 checksum: ``3ff3a192803e53758af5e112526ba9622f1dedc55e2fa88850db6f32af160f32``
28
  - LOC: ``https://wildbookiarepository.azureedge.net/models/scout.loc.mvp.0.onnx`` (194M)
29
  SHA256 checksum: ``f5bd22fbacc91ba4cf5abaef5197d1645ae5bc4e63e88839e6848c48b3710c58``
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  SHA256 checksum: ``3ff3a192803e53758af5e112526ba9622f1dedc55e2fa88850db6f32af160f32``
28
  - LOC: ``https://wildbookiarepository.azureedge.net/models/scout.loc.mvp.0.onnx`` (194M)
29
  SHA256 checksum: ``f5bd22fbacc91ba4cf5abaef5197d1645ae5bc4e63e88839e6848c48b3710c58``
30
+
31
+ Supported Objects of Interest
32
+ -----------------------------
33
+
34
+ The ONNX models are pre-configured to support a specific batch size and will predict specific species in
35
+ the final detection results. The input sizes are defined explicitly when they cannot be changed, but the
36
+ ``WIC`` model's inputs can be balanced using the environment variable ``WIC_BATCH_SIZE``. The outputs of
37
+ the pipeline is a collection of bounding boxes, confidence values, and class labels. Some of the labels
38
+ are not clean and are mapped, for convience, when the final detection labels are created. Below are the
39
+ supported species for each model:
40
+
41
+ - Phase 1: ``phase1``
42
+ - `elephant_savanna`
43
+ - - mapped to: `elephant`
44
+
45
+ - MVP: ``mvp``
46
+ - `buffalo`
47
+ - `camel`
48
+ - `canoe`
49
+ - `car`
50
+ - `cow`
51
+ - `crocodile`
52
+ - `dead_animalwhite_bones`
53
+ - - mapped to: `white_bones`
54
+ - `deadbones`
55
+ - - mapped to: `white_bones`
56
+ - `eland`
57
+ - `elecarcass_old`
58
+ - - mapped to: `white_bones`
59
+ - `elephant`
60
+ - `gazelle_gr`
61
+ - - mapped to: `gazelle_grants`
62
+ - `gazelle_grants`
63
+ - `gazelle_th`
64
+ - - mapped to: `gazelle_thomsons`
65
+ - `gazelle_thomsons`
66
+ - `gerenuk`
67
+ - `giant_forest_hog`
68
+ - `giraffe`
69
+ - `goat`
70
+ - `hartebeest`
71
+ - `hippo`
72
+ - `impala`
73
+ - `kob`
74
+ - `kudu`
75
+ - `motorcycle`
76
+ - `oribi`
77
+ - `oryx`
78
+ - `ostrich`
79
+ - `roof_grass`
80
+ - `roof_mabati`
81
+ - `sheep`
82
+ - `test`
83
+ - `topi`
84
+ - `vehicle`
85
+ - `warthog`
86
+ - `waterbuck`
87
+ - `white_bones`
88
+ - `wildebeest`
89
+ - `zebra`
docs/scoutbot.rst CHANGED
@@ -7,7 +7,6 @@ pretrained for inference in a production environment.
7
 
8
  .. toctree::
9
  :maxdepth: 3
10
- :caption: Contents:
11
 
12
  .. include:: overview.rst
13
 
 
7
 
8
  .. toctree::
9
  :maxdepth: 3
 
10
 
11
  .. include:: overview.rst
12
 
scoutbot/__init__.py CHANGED
@@ -62,7 +62,7 @@ QUIET = not utils.VERBOSE
62
 
63
  from scoutbot import agg, loc, tile, wic # NOQA
64
 
65
- VERSION = '0.1.16'
66
  version = VERSION
67
  __version__ = VERSION
68
 
@@ -148,6 +148,8 @@ def pipeline(
148
 
149
  # Threshold for WIC
150
  wic_ = max(wic_output.get('positive') for wic_output in wic_outputs)
 
 
151
  flags = [wic_output.get('positive') >= wic_thresh for wic_output in wic_outputs]
152
  loc_tile_grids = ut.compress(tile_grids, flags)
153
  loc_tile_filepaths = ut.compress(tile_filepaths, flags)
@@ -298,6 +300,7 @@ def batch(
298
  for filepath in filepaths:
299
  data = batch[filepath]
300
  wic_ = wic_dict.get(filepath, None)
 
301
 
302
  img_shape = data['shape']
303
  loc_tile_grids = data['loc']['grids']
@@ -326,7 +329,7 @@ def batch(
326
 
327
  def example():
328
  """
329
- Run the pipeline on an example image with the Phase 1 models
330
  """
331
  TEST_IMAGE = 'scout.example.jpg'
332
  TEST_IMAGE_HASH = (
 
62
 
63
  from scoutbot import agg, loc, tile, wic # NOQA
64
 
65
+ VERSION = '0.1.17'
66
  version = VERSION
67
  __version__ = VERSION
68
 
 
148
 
149
  # Threshold for WIC
150
  wic_ = max(wic_output.get('positive') for wic_output in wic_outputs)
151
+ wic_ = round(wic_, 4)
152
+
153
  flags = [wic_output.get('positive') >= wic_thresh for wic_output in wic_outputs]
154
  loc_tile_grids = ut.compress(tile_grids, flags)
155
  loc_tile_filepaths = ut.compress(tile_filepaths, flags)
 
300
  for filepath in filepaths:
301
  data = batch[filepath]
302
  wic_ = wic_dict.get(filepath, None)
303
+ wic_ = round(wic_, 4)
304
 
305
  img_shape = data['shape']
306
  loc_tile_grids = data['loc']['grids']
 
329
 
330
  def example():
331
  """
332
+ Run the pipeline on an example image with the default configuration
333
  """
334
  TEST_IMAGE = 'scout.example.jpg'
335
  TEST_IMAGE_HASH = (
scoutbot/agg/__init__.py CHANGED
@@ -15,7 +15,7 @@ from scoutbot import log
15
 
16
  MARGIN = 32.0
17
 
18
- DEFAULT_CONFIG = os.getenv('CONFIG', 'mvp').strip().lower()
19
  CONFIGS = {
20
  'phase1': {
21
  'thresh': 0.4,
@@ -214,6 +214,8 @@ def compute(
214
 
215
  assert len(tile_grids) == len(loc_outputs)
216
 
 
 
217
  if agg_thresh is None:
218
  agg_thresh = CONFIGS[config]['thresh']
219
  if nms_thresh is None:
 
15
 
16
  MARGIN = 32.0
17
 
18
+ DEFAULT_CONFIG = os.getenv('AGG_CONFIG', os.getenv('CONFIG', 'mvp')).strip().lower()
19
  CONFIGS = {
20
  'phase1': {
21
  'thresh': 0.4,
 
214
 
215
  assert len(tile_grids) == len(loc_outputs)
216
 
217
+ if config is None:
218
+ config = DEFAULT_CONFIG
219
  if agg_thresh is None:
220
  agg_thresh = CONFIGS[config]['thresh']
221
  if nms_thresh is None:
scoutbot/loc/__init__.py CHANGED
@@ -37,7 +37,7 @@ INPUT_SIZE = (416, 416)
37
  INPUT_SIZE_H, INPUT_SIZE_W = INPUT_SIZE
38
  NETWORK_SIZE = (INPUT_SIZE_H, INPUT_SIZE_W, 3)
39
 
40
- DEFAULT_CONFIG = os.getenv('CONFIG', 'mvp').strip().lower()
41
  CONFIGS = {
42
  'phase1': {
43
  'batch': 16,
@@ -137,6 +137,9 @@ def fetch(pull=False, config=DEFAULT_CONFIG):
137
  Raises:
138
  AssertionError: If the model cannot be fetched.
139
  """
 
 
 
140
  model_name = CONFIGS[config]['name']
141
  model_path = CONFIGS[config]['path']
142
  model_hash = CONFIGS[config]['hash']
@@ -178,6 +181,9 @@ def pre(inputs, config=DEFAULT_CONFIG):
178
  - - trim index
179
  - - model configuration
180
  """
 
 
 
181
  if len(inputs) == 0:
182
  return [], config
183
 
@@ -229,6 +235,9 @@ def predict(gen):
229
  ort_sessions = {}
230
 
231
  for chunk, sizes, trim, config in tqdm.tqdm(gen, disable=QUIET):
 
 
 
232
  assert len(chunk) == len(sizes)
233
 
234
  if len(chunk) == 0:
@@ -308,6 +317,9 @@ def post(gen, loc_thresh=None, nms_thresh=None):
308
  if len(preds) == 0:
309
  continue
310
 
 
 
 
311
  anchors = CONFIGS[config]['anchors']
312
  classes = CONFIGS[config]['classes']
313
  if loc_thresh is None:
@@ -325,18 +337,14 @@ def post(gen, loc_thresh=None, nms_thresh=None):
325
 
326
  preds = postprocess(torch.tensor(preds))
327
 
328
- if config in ['phase1']:
329
- class_map = {}
330
- elif config in [None, 'mvp']:
331
- class_map = {
332
- 'dead_animalwhite_bones': 'white_bones',
333
- 'deadbones': 'white_bones',
334
- 'elecarcass_old': 'white_bones',
335
- 'gazelle_gr': 'gazelle_grants',
336
- 'gazelle_th': 'gazelle_thomsons',
337
- }
338
- else:
339
- raise ValueError()
340
 
341
  for pred, size in zip(preds, sizes):
342
  output = ReverseLetterbox.apply([pred], INPUT_SIZE, size)
 
37
  INPUT_SIZE_H, INPUT_SIZE_W = INPUT_SIZE
38
  NETWORK_SIZE = (INPUT_SIZE_H, INPUT_SIZE_W, 3)
39
 
40
+ DEFAULT_CONFIG = os.getenv('LOC_CONFIG', os.getenv('CONFIG', 'mvp')).strip().lower()
41
  CONFIGS = {
42
  'phase1': {
43
  'batch': 16,
 
137
  Raises:
138
  AssertionError: If the model cannot be fetched.
139
  """
140
+ if config is None:
141
+ config = DEFAULT_CONFIG
142
+
143
  model_name = CONFIGS[config]['name']
144
  model_path = CONFIGS[config]['path']
145
  model_hash = CONFIGS[config]['hash']
 
181
  - - trim index
182
  - - model configuration
183
  """
184
+ if config is None:
185
+ config = DEFAULT_CONFIG
186
+
187
  if len(inputs) == 0:
188
  return [], config
189
 
 
235
  ort_sessions = {}
236
 
237
  for chunk, sizes, trim, config in tqdm.tqdm(gen, disable=QUIET):
238
+ if config is None:
239
+ config = DEFAULT_CONFIG
240
+
241
  assert len(chunk) == len(sizes)
242
 
243
  if len(chunk) == 0:
 
317
  if len(preds) == 0:
318
  continue
319
 
320
+ if config is None:
321
+ config = DEFAULT_CONFIG
322
+
323
  anchors = CONFIGS[config]['anchors']
324
  classes = CONFIGS[config]['classes']
325
  if loc_thresh is None:
 
337
 
338
  preds = postprocess(torch.tensor(preds))
339
 
340
+ class_map = {
341
+ 'elephant_savanna': 'elephant',
342
+ 'dead_animalwhite_bones': 'white_bones',
343
+ 'deadbones': 'white_bones',
344
+ 'elecarcass_old': 'white_bones',
345
+ 'gazelle_gr': 'gazelle_grants',
346
+ 'gazelle_th': 'gazelle_thomsons',
347
+ }
 
 
 
 
348
 
349
  for pred, size in zip(preds, sizes):
350
  output = ReverseLetterbox.apply([pred], INPUT_SIZE, size)
scoutbot/scoutbot.py CHANGED
@@ -282,7 +282,7 @@ def batch(
282
  @click.command('example')
283
  def example():
284
  """
285
- Run a test of the pipeline on an example image with the Phase 1 models
286
  """
287
  scoutbot.example()
288
 
 
282
  @click.command('example')
283
  def example():
284
  """
285
+ Run a test of the pipeline on an example image with the default configuration.
286
  """
287
  scoutbot.example()
288
 
scoutbot/tile/__init__.py CHANGED
@@ -2,6 +2,7 @@
2
  '''
3
 
4
  '''
 
5
  from os.path import abspath, exists, join, split, splitext
6
 
7
  import cv2
@@ -17,7 +18,10 @@ TILE_OFFSET = 0
17
  TILE_BORDERS = True
18
 
19
 
20
- def compute(img_filepath, grid1=True, grid2=True, ext=None, **kwargs):
 
 
 
21
  """
22
  Compute the tiles for a given input image and saves them to disk.
23
 
@@ -28,7 +32,8 @@ def compute(img_filepath, grid1=True, grid2=True, ext=None, **kwargs):
28
  grid1 (bool, optional): If :obj:`True`, create a dense grid of tiles on the image.
29
  Defaults to :obj:`True`.
30
  grid2 (bool, optional): If :obj:`True`, create a secondary dense grid of tiles
31
- on the image with a 50% offset. Defaults to :obj:`False`.
 
32
  ext (str, optional): The file extension of the resulting tile files. If this value is
33
  not specified, it will use the same extension as `img_filepath`. Passed as input
34
  to :meth:`scoutbot.tile.tile_filepath`. Defaults to :obj:`None`.
 
2
  '''
3
 
4
  '''
5
+ import os
6
  from os.path import abspath, exists, join, split, splitext
7
 
8
  import cv2
 
18
  TILE_BORDERS = True
19
 
20
 
21
+ FAST = os.getenv('FAST', None) is not None
22
+
23
+
24
+ def compute(img_filepath, grid1=True, grid2=not FAST, ext=None, **kwargs):
25
  """
26
  Compute the tiles for a given input image and saves them to disk.
27
 
 
32
  grid1 (bool, optional): If :obj:`True`, create a dense grid of tiles on the image.
33
  Defaults to :obj:`True`.
34
  grid2 (bool, optional): If :obj:`True`, create a secondary dense grid of tiles
35
+ on the image with a 50% offset. Defaults to :obj:`False`. Can be disabled by
36
+ setting the environment variable ``FAST=1``.
37
  ext (str, optional): The file extension of the resulting tile files. If this value is
38
  not specified, it will use the same extension as `img_filepath`. Passed as input
39
  to :meth:`scoutbot.tile.tile_filepath`. Defaults to :obj:`None`.
scoutbot/wic/__init__.py CHANGED
@@ -10,6 +10,7 @@ import os
10
  import warnings
11
  from os.path import exists, join
12
  from pathlib import Path
 
13
 
14
  import numpy as np
15
  import onnxruntime as ort
@@ -28,7 +29,7 @@ from scoutbot.wic.dataloader import ( # NOQA
28
  PWD = Path(__file__).absolute().parent
29
 
30
 
31
- DEFAULT_CONFIG = os.getenv('CONFIG', 'mvp').strip().lower()
32
  CONFIGS = {
33
  'phase1': {
34
  'name': 'scout.wic.5fbfff26.3.0.onnx',
@@ -70,6 +71,9 @@ def fetch(pull=False, config=DEFAULT_CONFIG):
70
  Raises:
71
  AssertionError: If the model cannot be fetched.
72
  """
 
 
 
73
  model_name = CONFIGS[config]['name']
74
  model_path = CONFIGS[config]['path']
75
  model_hash = CONFIGS[config]['hash']
@@ -111,11 +115,20 @@ def pre(inputs, batch_size=BATCH_SIZE, config=DEFAULT_CONFIG):
111
  - - list of transformed image data with shape ``(b, c, w, h)``
112
  - - model configuration
113
  """
 
 
 
114
  if len(inputs) == 0:
115
  return [], config
116
 
117
  log.debug(f'Preprocessing {len(inputs)} WIC inputs in batches of {batch_size}')
118
 
 
 
 
 
 
 
119
  transform = _init_transforms()
120
  dataset = ImageFilePathList(inputs, transform=transform)
121
  dataloader = torch.utils.data.DataLoader(
@@ -145,6 +158,8 @@ def predict(gen):
145
  ort_sessions = {}
146
 
147
  for chunk, config in tqdm.tqdm(gen, disable=QUIET):
 
 
148
 
149
  ort_session = ort_sessions.get(config)
150
  if ort_session is None:
@@ -189,6 +204,9 @@ def post(gen):
189
 
190
  outputs = []
191
  for preds, config in gen:
 
 
 
192
  classes = CONFIGS[config]['classes']
193
  for pred in preds:
194
  output = dict(zip(classes, pred.tolist()))
 
10
  import warnings
11
  from os.path import exists, join
12
  from pathlib import Path
13
+ from sys import platform
14
 
15
  import numpy as np
16
  import onnxruntime as ort
 
29
  PWD = Path(__file__).absolute().parent
30
 
31
 
32
+ DEFAULT_CONFIG = os.getenv('WIC_CONFIG', os.getenv('CONFIG', 'mvp')).strip().lower()
33
  CONFIGS = {
34
  'phase1': {
35
  'name': 'scout.wic.5fbfff26.3.0.onnx',
 
71
  Raises:
72
  AssertionError: If the model cannot be fetched.
73
  """
74
+ if config is None:
75
+ config = DEFAULT_CONFIG
76
+
77
  model_name = CONFIGS[config]['name']
78
  model_path = CONFIGS[config]['path']
79
  model_hash = CONFIGS[config]['hash']
 
115
  - - list of transformed image data with shape ``(b, c, w, h)``
116
  - - model configuration
117
  """
118
+ if config is None:
119
+ config = DEFAULT_CONFIG
120
+
121
  if len(inputs) == 0:
122
  return [], config
123
 
124
  log.debug(f'Preprocessing {len(inputs)} WIC inputs in batches of {batch_size}')
125
 
126
+ # @TODO: Non-determinism and ONNX Runtime prediction failure on macOS
127
+ # when using MVP WIC model and a batch size greater than 1
128
+ if config in ['mvp'] and platform in ['darwin']:
129
+ log.debug(f'Overriding default WIC batch size of {len(inputs)} with 1 on macOS')
130
+ batch_size = 1
131
+
132
  transform = _init_transforms()
133
  dataset = ImageFilePathList(inputs, transform=transform)
134
  dataloader = torch.utils.data.DataLoader(
 
158
  ort_sessions = {}
159
 
160
  for chunk, config in tqdm.tqdm(gen, disable=QUIET):
161
+ if config is None:
162
+ config = DEFAULT_CONFIG
163
 
164
  ort_session = ort_sessions.get(config)
165
  if ort_session is None:
 
204
 
205
  outputs = []
206
  for preds, config in gen:
207
+ if config is None:
208
+ config = DEFAULT_CONFIG
209
+
210
  classes = CONFIGS[config]['classes']
211
  for pred in preds:
212
  output = dict(zip(classes, pred.tolist()))
tests/test_agg.py CHANGED
@@ -33,12 +33,13 @@ def test_agg_compute_phase1():
33
  # Aggregate
34
  detects = agg.compute(img_shape, loc_tile_grids, loc_outputs, config='phase1')
35
 
36
- assert len(detects) == 3
37
 
38
  targets = [
39
- {'l': 'elephant_savanna', 'c': 0.9299, 'x': 4597, 'y': 2322, 'w': 72, 'h': 149},
40
- {'l': 'elephant_savanna', 'c': 0.8739, 'x': 4865, 'y': 2422, 'w': 97, 'h': 109},
41
- {'l': 'elephant_savanna', 'c': 0.7115, 'x': 4806, 'y': 2476, 'w': 66, 'h': 119},
 
42
  ]
43
 
44
  for output, target in zip(detects, targets):
@@ -69,7 +70,7 @@ def test_agg_compute_mvp():
69
  ]
70
  loc_tile_grids = ut.compress(tile_grids, flags)
71
  loc_tile_filepaths = ut.compress(tile_filepaths, flags)
72
- assert sum(flags) == 125
73
 
74
  # Run localizer
75
  loc_outputs = loc.post(loc.predict(loc.pre(loc_tile_filepaths, config='mvp')))
@@ -78,7 +79,7 @@ def test_agg_compute_mvp():
78
  # Aggregate
79
  detects = agg.compute(img_shape, loc_tile_grids, loc_outputs, config='mvp')
80
 
81
- assert len(detects) == 8
82
 
83
  # fmt: off
84
  targets = [
 
33
  # Aggregate
34
  detects = agg.compute(img_shape, loc_tile_grids, loc_outputs, config='phase1')
35
 
36
+ assert len(detects) in [3, 4]
37
 
38
  targets = [
39
+ {'l': 'elephant', 'c': 0.9299, 'x': 4597, 'y': 2322, 'w': 72, 'h': 149},
40
+ {'l': 'elephant', 'c': 0.8739, 'x': 4865, 'y': 2422, 'w': 97, 'h': 109},
41
+ {'l': 'elephant', 'c': 0.7115, 'x': 4806, 'y': 2476, 'w': 66, 'h': 119},
42
+ {'l': 'elephant', 'c': 0.5236, 'x': 3511, 'y': 1228, 'w': 47, 'h': 78},
43
  ]
44
 
45
  for output, target in zip(detects, targets):
 
70
  ]
71
  loc_tile_grids = ut.compress(tile_grids, flags)
72
  loc_tile_filepaths = ut.compress(tile_filepaths, flags)
73
+ assert sum(flags) in [123, 125]
74
 
75
  # Run localizer
76
  loc_outputs = loc.post(loc.predict(loc.pre(loc_tile_filepaths, config='mvp')))
 
79
  # Aggregate
80
  detects = agg.compute(img_shape, loc_tile_grids, loc_outputs, config='mvp')
81
 
82
+ assert len(detects) in [7, 8]
83
 
84
  # fmt: off
85
  targets = [
tests/test_loc.py CHANGED
@@ -69,7 +69,7 @@ def test_loc_onnx_pipeline_phase1():
69
  # fmt: off
70
  targets = [
71
  {
72
- 'l': 'elephant_savanna',
73
  'c': 0.77065581,
74
  'x': 206.00893930,
75
  'y': 189.09138371,
@@ -77,7 +77,7 @@ def test_loc_onnx_pipeline_phase1():
77
  'h': 66.46106896,
78
  },
79
  {
80
- 'l': 'elephant_savanna',
81
  'c': 0.61152166,
82
  'x': 216.61065204,
83
  'y': 193.30525090,
@@ -85,7 +85,7 @@ def test_loc_onnx_pipeline_phase1():
85
  'h': 62.44728440,
86
  },
87
  {
88
- 'l': 'elephant_savanna',
89
  'c': 0.50862342,
90
  'x': 51.61210749,
91
  'y': 235.37819260,
@@ -93,7 +93,7 @@ def test_loc_onnx_pipeline_phase1():
93
  'h': 17.41258826,
94
  },
95
  {
96
- 'l': 'elephant_savanna',
97
  'c': 0.44841822,
98
  'x': 57.47630427,
99
  'y': 236.92587515,
@@ -101,7 +101,7 @@ def test_loc_onnx_pipeline_phase1():
101
  'h': 16.03246718,
102
  },
103
  {
104
- 'l': 'elephant_savanna',
105
  'c': 0.44012001,
106
  'x': 37.07233605,
107
  'y': 230.39122596,
@@ -109,7 +109,7 @@ def test_loc_onnx_pipeline_phase1():
109
  'h': 24.81017362,
110
  },
111
  # {
112
- # 'l': 'elephant_savanna',
113
  # 'c': 0.38498798,
114
  # 'x': 56.43274395,
115
  # 'y': 232.00978440,
@@ -117,7 +117,7 @@ def test_loc_onnx_pipeline_phase1():
117
  # 'h': 22.50272075,
118
  # },
119
  # {
120
- # 'l': 'elephant_savanna',
121
  # 'c': 0.37786528,
122
  # 'x': 202.67217548,
123
  # 'y': 178.77696814,
 
69
  # fmt: off
70
  targets = [
71
  {
72
+ 'l': 'elephant',
73
  'c': 0.77065581,
74
  'x': 206.00893930,
75
  'y': 189.09138371,
 
77
  'h': 66.46106896,
78
  },
79
  {
80
+ 'l': 'elephant',
81
  'c': 0.61152166,
82
  'x': 216.61065204,
83
  'y': 193.30525090,
 
85
  'h': 62.44728440,
86
  },
87
  {
88
+ 'l': 'elephant',
89
  'c': 0.50862342,
90
  'x': 51.61210749,
91
  'y': 235.37819260,
 
93
  'h': 17.41258826,
94
  },
95
  {
96
+ 'l': 'elephant',
97
  'c': 0.44841822,
98
  'x': 57.47630427,
99
  'y': 236.92587515,
 
101
  'h': 16.03246718,
102
  },
103
  {
104
+ 'l': 'elephant',
105
  'c': 0.44012001,
106
  'x': 37.07233605,
107
  'y': 230.39122596,
 
109
  'h': 24.81017362,
110
  },
111
  # {
112
+ # 'l': 'elephant',
113
  # 'c': 0.38498798,
114
  # 'x': 56.43274395,
115
  # 'y': 232.00978440,
 
117
  # 'h': 22.50272075,
118
  # },
119
  # {
120
+ # 'l': 'elephant',
121
  # 'c': 0.37786528,
122
  # 'x': 202.67217548,
123
  # 'y': 178.77696814,
tests/test_scoutbot.py CHANGED
@@ -21,13 +21,13 @@ def test_pipeline_phase1():
21
  wic_, detects = scoutbot.pipeline(img_filepath, config='phase1')
22
 
23
  assert abs(wic_ - 1.0) < 1e-2
24
- assert len(detects) == 4
25
 
26
  targets = [
27
- {'l': 'elephant_savanna', 'c': 0.9299, 'x': 4597, 'y': 2322, 'w': 72, 'h': 149},
28
- {'l': 'elephant_savanna', 'c': 0.8739, 'x': 4865, 'y': 2422, 'w': 97, 'h': 109},
29
- {'l': 'elephant_savanna', 'c': 0.7115, 'x': 4806, 'y': 2476, 'w': 66, 'h': 119},
30
- {'l': 'elephant_savanna', 'c': 0.5236, 'x': 3511, 'y': 1228, 'w': 47, 'h': 78},
31
  ]
32
 
33
  for output, target in zip(detects, targets):
@@ -52,13 +52,13 @@ def test_batch_phase1():
52
  detects = detects_list[0]
53
 
54
  assert abs(wic_ - 1.0) < 1e-2
55
- assert len(detects) == 4
56
 
57
  targets = [
58
- {'l': 'elephant_savanna', 'c': 0.9299, 'x': 4597, 'y': 2322, 'w': 72, 'h': 149},
59
- {'l': 'elephant_savanna', 'c': 0.8739, 'x': 4865, 'y': 2422, 'w': 97, 'h': 109},
60
- {'l': 'elephant_savanna', 'c': 0.7115, 'x': 4806, 'y': 2476, 'w': 66, 'h': 119},
61
- {'l': 'elephant_savanna', 'c': 0.5236, 'x': 3511, 'y': 1228, 'w': 47, 'h': 78},
62
  ]
63
 
64
  for output, target in zip(detects, targets):
@@ -77,7 +77,7 @@ def test_pipeline_mvp():
77
  wic_, detects = scoutbot.pipeline(img_filepath, config='mvp')
78
 
79
  assert abs(wic_ - 1.0) < 1e-2
80
- assert len(detects) == 8
81
 
82
  # fmt: off
83
  targets = [
@@ -114,7 +114,7 @@ def test_batch_mvp():
114
  detects = detects_list[0]
115
 
116
  assert abs(wic_ - 1.0) < 1e-2
117
- assert len(detects) == 8
118
 
119
  # fmt: off
120
  targets = [
 
21
  wic_, detects = scoutbot.pipeline(img_filepath, config='phase1')
22
 
23
  assert abs(wic_ - 1.0) < 1e-2
24
+ assert len(detects) in [3, 4]
25
 
26
  targets = [
27
+ {'l': 'elephant', 'c': 0.9299, 'x': 4597, 'y': 2322, 'w': 72, 'h': 149},
28
+ {'l': 'elephant', 'c': 0.8739, 'x': 4865, 'y': 2422, 'w': 97, 'h': 109},
29
+ {'l': 'elephant', 'c': 0.7115, 'x': 4806, 'y': 2476, 'w': 66, 'h': 119},
30
+ {'l': 'elephant', 'c': 0.5236, 'x': 3511, 'y': 1228, 'w': 47, 'h': 78},
31
  ]
32
 
33
  for output, target in zip(detects, targets):
 
52
  detects = detects_list[0]
53
 
54
  assert abs(wic_ - 1.0) < 1e-2
55
+ assert len(detects) in [3, 4]
56
 
57
  targets = [
58
+ {'l': 'elephant', 'c': 0.9299, 'x': 4597, 'y': 2322, 'w': 72, 'h': 149},
59
+ {'l': 'elephant', 'c': 0.8739, 'x': 4865, 'y': 2422, 'w': 97, 'h': 109},
60
+ {'l': 'elephant', 'c': 0.7115, 'x': 4806, 'y': 2476, 'w': 66, 'h': 119},
61
+ {'l': 'elephant', 'c': 0.5236, 'x': 3511, 'y': 1228, 'w': 47, 'h': 78},
62
  ]
63
 
64
  for output, target in zip(detects, targets):
 
77
  wic_, detects = scoutbot.pipeline(img_filepath, config='mvp')
78
 
79
  assert abs(wic_ - 1.0) < 1e-2
80
+ assert len(detects) in [7, 8]
81
 
82
  # fmt: off
83
  targets = [
 
114
  detects = detects_list[0]
115
 
116
  assert abs(wic_ - 1.0) < 1e-2
117
+ assert len(detects) in [7, 8]
118
 
119
  # fmt: off
120
  targets = [