Equimo 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {equimo-0.1.0 → equimo-0.1.2}/Equimo.egg-info/PKG-INFO +1 -1
  2. {equimo-0.1.0 → equimo-0.1.2}/PKG-INFO +1 -1
  3. {equimo-0.1.0 → equimo-0.1.2}/equimo/models/emamodel.py +16 -0
  4. {equimo-0.1.0 → equimo-0.1.2}/equimo/models/fastervit.py +7 -2
  5. {equimo-0.1.0 → equimo-0.1.2}/equimo/models/mlla.py +19 -12
  6. {equimo-0.1.0 → equimo-0.1.2}/equimo/models/partialformer.py +10 -3
  7. {equimo-0.1.0 → equimo-0.1.2}/equimo/models/shvit.py +18 -13
  8. {equimo-0.1.0 → equimo-0.1.2}/equimo/models/vit.py +5 -1
  9. {equimo-0.1.0 → equimo-0.1.2}/equimo/models/vssd.py +19 -12
  10. {equimo-0.1.0 → equimo-0.1.2}/pyproject.toml +1 -1
  11. {equimo-0.1.0 → equimo-0.1.2}/Equimo.egg-info/SOURCES.txt +0 -0
  12. {equimo-0.1.0 → equimo-0.1.2}/Equimo.egg-info/dependency_links.txt +0 -0
  13. {equimo-0.1.0 → equimo-0.1.2}/Equimo.egg-info/requires.txt +0 -0
  14. {equimo-0.1.0 → equimo-0.1.2}/Equimo.egg-info/top_level.txt +0 -0
  15. {equimo-0.1.0 → equimo-0.1.2}/LICENSE.md +0 -0
  16. {equimo-0.1.0 → equimo-0.1.2}/README.md +0 -0
  17. {equimo-0.1.0 → equimo-0.1.2}/equimo/__init__.py +0 -0
  18. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/__init__.py +0 -0
  19. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/attention.py +0 -0
  20. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/convolution.py +0 -0
  21. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/downsample.py +0 -0
  22. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/dropout.py +0 -0
  23. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/ffn.py +0 -0
  24. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/generic.py +0 -0
  25. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/mamba.py +0 -0
  26. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/norm.py +0 -0
  27. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/patch.py +0 -0
  28. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/posemb.py +0 -0
  29. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/sharing.py +0 -0
  30. {equimo-0.1.0 → equimo-0.1.2}/equimo/layers/squeeze_excite.py +0 -0
  31. {equimo-0.1.0 → equimo-0.1.2}/equimo/models/__init__.py +0 -0
  32. {equimo-0.1.0 → equimo-0.1.2}/equimo/ops/scan.py +0 -0
  33. {equimo-0.1.0 → equimo-0.1.2}/equimo/utils.py +0 -0
  34. {equimo-0.1.0 → equimo-0.1.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Equimo
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Implementation of popular vision models in Jax
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Equimo
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Implementation of popular vision models in Jax
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -32,6 +32,22 @@ class EmaModel:
32
32
  self.decay = decay
33
33
  self.ema_params = None
34
34
 
35
+ def features(self, *args, **kwargs):
36
+ """
37
+ Get the underlying model's features.
38
+
39
+ This method relies on the implementation of the `features()` function
40
+ of the underlying model.
41
+
42
+ Args:
43
+ *args: Positional arguments to pass to the underlying model.
44
+ **kwargs: Keyword arguments to pass to the underlying model.
45
+
46
+ Returns:
47
+ The output of the underlying model.
48
+ """
49
+ return self.model.features(*args, **kwargs)
50
+
35
51
  def __call__(self, *args, **kwargs):
36
52
  """
37
53
  Call the underlying model.
@@ -431,7 +431,11 @@ class FasterViT(eqx.Module):
431
431
 
432
432
  num_features = int(dim * 2 ** (len(depths) - 1))
433
433
  self.norm = norm_layer(num_features)
434
- self.head = eqx.nn.Linear(num_features, num_classes, key=key_head)
434
+ self.head = (
435
+ eqx.nn.Linear(num_features, num_classes, key=key_head)
436
+ if num_classes > 0
437
+ else eqx.nn.Identity()
438
+ )
435
439
 
436
440
  def features(
437
441
  self,
@@ -455,6 +459,8 @@ class FasterViT(eqx.Module):
455
459
  for blk, key_block in zip(self.blocks, block_subkeys):
456
460
  x = blk(x, enable_dropout=enable_dropout, key=key_block)
457
461
 
462
+ x = rearrange(x, "c h w -> (h w) c")
463
+
458
464
  return x
459
465
 
460
466
  def __call__(
@@ -474,7 +480,6 @@ class FasterViT(eqx.Module):
474
480
  Classification logits for each class
475
481
  """
476
482
  x = self.features(x, enable_dropout, key)
477
- x = rearrange(x, "c h w -> (h w) c")
478
483
  x = jax.vmap(self.norm)(x)
479
484
  x = pool_sd(
480
485
  x,
@@ -126,17 +126,28 @@ class Mlla(eqx.Module):
126
126
  for i, depth in enumerate(depths)
127
127
  ]
128
128
 
129
+ self.norm = eqx.nn.LayerNorm(self.num_features)
129
130
  self.head = (
130
- eqx.nn.Sequential(
131
- [
132
- eqx.nn.LayerNorm(self.num_features),
133
- eqx.nn.Linear(self.num_features, num_classes, key=key_head),
134
- ]
135
- )
131
+ eqx.nn.Linear(self.num_features, num_classes, key=key_head)
136
132
  if num_classes > 0
137
133
  else eqx.nn.Identity()
138
134
  )
139
135
 
136
+ def features(
137
+ self,
138
+ x: Float[Array, "..."],
139
+ enable_dropout: bool,
140
+ key: PRNGKeyArray,
141
+ ) -> Float[Array, "..."]:
142
+ key_pd, *keys = jr.split(key, 1 + len(self.blocks))
143
+
144
+ x = self.patch_embed(x)
145
+ x = self.pos_drop(x, inference=not enable_dropout, key=key_pd)
146
+ for i, blk in enumerate(self.blocks):
147
+ x = blk(x, enable_dropout=enable_dropout, key=keys[i])
148
+
149
+ return x
150
+
140
151
  def __call__(
141
152
  self,
142
153
  x: Float[Array, "..."],
@@ -154,12 +165,8 @@ class Mlla(eqx.Module):
154
165
  Output tensor (class logits if num_classes > 0,
155
166
  otherwise feature representations)
156
167
  """
157
- key_pd, *keys = jr.split(key, 1 + len(self.blocks))
158
-
159
- x = self.patch_embed(x)
160
- x = self.pos_drop(x, inference=not enable_dropout, key=key_pd)
161
- for i, blk in enumerate(self.blocks):
162
- x = blk(x, enable_dropout=enable_dropout, key=keys[i])
168
+ x = self.features(x, enable_dropout=enable_dropout, key=key)
169
+ x = jax.vmap(self.norm)(x)
163
170
  x = reduce(x, "s d -> d", "mean")
164
171
  x = self.head(x)
165
172
 
@@ -349,13 +349,18 @@ class PartialFormer(eqx.Module):
349
349
  ]
350
350
 
351
351
  self.norm = norm_layer(self.num_features)
352
- self.head = eqx.nn.Linear(self.num_features, num_classes, key=key_head)
352
+ self.head = (
353
+ eqx.nn.Linear(self.num_features, num_classes, key=key_head)
354
+ if num_classes > 0
355
+ else eqx.nn.Identity()
356
+ )
353
357
 
354
358
  def features(
355
359
  self,
356
360
  x: Float[Array, "channels height width"],
357
361
  enable_dropout: bool,
358
362
  key: PRNGKeyArray,
363
+ return_qa: bool = False,
359
364
  ) -> Float[Array, "seqlen dim"]:
360
365
  """Extract features from input image using partial attention.
361
366
 
@@ -380,7 +385,9 @@ class PartialFormer(eqx.Module):
380
385
  key=key_block,
381
386
  )
382
387
 
383
- return x, qa
388
+ if return_qa:
389
+ return x, qa
390
+ return x
384
391
 
385
392
  def __call__(
386
393
  self,
@@ -398,7 +405,7 @@ class PartialFormer(eqx.Module):
398
405
  Returns:
399
406
  Classification logits for each class
400
407
  """
401
- x, qa = self.features(x, enable_dropout, key)
408
+ x = self.features(x, enable_dropout, key)
402
409
  x = jax.vmap(self.norm)(x)
403
410
  x = reduce(x, "n c -> c", "mean")
404
411
 
@@ -336,17 +336,27 @@ class SHViT(eqx.Module):
336
336
  for i, depth in enumerate(depths)
337
337
  ]
338
338
 
339
+ self.norm = eqx.nn.LayerNorm(dims[-1])
339
340
  self.head = (
340
- eqx.nn.Sequential(
341
- [
342
- eqx.nn.LayerNorm(dims[-1]),
343
- eqx.nn.Linear(dims[-1], num_classes, key=key_head),
344
- ]
345
- )
341
+ eqx.nn.Linear(dims[-1], num_classes, key=key_head)
346
342
  if num_classes > 0
347
343
  else eqx.nn.Identity()
348
344
  )
349
345
 
346
+ def features(
347
+ self,
348
+ x: Float[Array, "..."],
349
+ enable_dropout: bool,
350
+ key: PRNGKeyArray,
351
+ ) -> Float[Array, "..."]:
352
+ keys = jr.split(key, len(self.blocks))
353
+
354
+ x = self.patch_embed(x)
355
+ for i, blk in enumerate(self.blocks):
356
+ x = blk(x, enable_dropout=enable_dropout, key=keys[i])
357
+
358
+ return x
359
+
350
360
  def __call__(
351
361
  self,
352
362
  x: Float[Array, "..."],
@@ -363,14 +373,9 @@ class SHViT(eqx.Module):
363
373
  Returns:
364
374
  Classification logits for each class
365
375
  """
366
- keys = jr.split(key, len(self.blocks))
367
-
368
- x = self.patch_embed(x)
369
- for i, blk in enumerate(self.blocks):
370
- x = blk(x, enable_dropout=enable_dropout, key=keys[i])
371
-
376
+ x = self.features(x, enable_dropout=enable_dropout, key=key)
377
+ x = jax.vmap(self.norm)(x)
372
378
  x = reduce(x, "c h w -> c", "mean")
373
-
374
379
  x = self.head(x)
375
380
 
376
381
  return x
@@ -279,7 +279,11 @@ class VisionTransformer(eqx.Module):
279
279
  ]
280
280
 
281
281
  self.norm = norm_layer(dim)
282
- self.head = eqx.nn.Linear(dim, num_classes, key=key_head)
282
+ self.head = (
283
+ eqx.nn.Linear(dim, num_classes, key=key_head)
284
+ if num_classes > 0
285
+ else eqx.nn.Identity()
286
+ )
283
287
 
284
288
  def resample_pos_embed(
285
289
  self,
@@ -144,17 +144,28 @@ class Vssd(eqx.Module):
144
144
  for i, depth in enumerate(depths)
145
145
  ]
146
146
 
147
+ self.norm = eqx.nn.LayerNorm(self.num_features)
147
148
  self.head = (
148
- eqx.nn.Sequential(
149
- [
150
- eqx.nn.LayerNorm(self.num_features),
151
- eqx.nn.Linear(self.num_features, num_classes, key=key_head),
152
- ]
153
- )
149
+ eqx.nn.Linear(self.num_features, num_classes, key=key_head)
154
150
  if num_classes > 0
155
151
  else eqx.nn.Identity()
156
152
  )
157
153
 
154
+ def features(
155
+ self,
156
+ x: Float[Array, "..."],
157
+ enable_dropout: bool,
158
+ key: PRNGKeyArray,
159
+ ) -> Float[Array, "..."]:
160
+ key_pd, *keys = jr.split(key, 1 + len(self.blocks))
161
+
162
+ x = self.patch_embed(x)
163
+ x = self.pos_drop(x, inference=not enable_dropout, key=key_pd)
164
+ for i, blk in enumerate(self.blocks):
165
+ x = blk(x, enable_dropout=enable_dropout, key=keys[i])
166
+
167
+ return x
168
+
158
169
  def __call__(
159
170
  self,
160
171
  x: Float[Array, "..."],
@@ -177,12 +188,8 @@ class Vssd(eqx.Module):
177
188
  3. Global average pooling
178
189
  4. Classification head
179
190
  """
180
- key_pd, *keys = jr.split(key, 1 + len(self.blocks))
181
-
182
- x = self.patch_embed(x)
183
- x = self.pos_drop(x, inference=not enable_dropout, key=key_pd)
184
- for i, blk in enumerate(self.blocks):
185
- x = blk(x, enable_dropout=enable_dropout, key=keys[i])
191
+ x = self.features(x, enable_dropout=enable_dropout, key=key)
192
+ x = jax.vmap(self.norm)(x)
186
193
  x = reduce(x, "s d -> d", "mean")
187
194
  x = self.head(x)
188
195
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "Equimo"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "Implementation of popular vision models in Jax"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes