phanerozoic commited on
Commit
d5bbf99
·
verified ·
1 Parent(s): 3a6f6a2

dim20: 3.9 mAP from 22K params. 768->20->80 bottleneck, SVD-initialized from pruned prototypes.

Browse files
heads/__init__.py CHANGED
@@ -26,6 +26,7 @@ from .optimal_transport.head import OptimalTransport
26
  from .tropical.head import TropicalDetection
27
  from .compression.head import CompressionDetection
28
  from .curvature.head import CurvatureDetection
 
29
 
30
  REGISTRY = {
31
  "baseline_fcos": BaselineFCOS,
@@ -54,6 +55,7 @@ REGISTRY = {
54
  "compression": CompressionDetection,
55
  "curvature": CurvatureDetection,
56
  "cofiber_threshold_box32": CofiberThresholdV2,
 
57
  }
58
 
59
  ALL_NAMES = list(REGISTRY.keys())
 
26
  from .tropical.head import TropicalDetection
27
  from .compression.head import CompressionDetection
28
  from .curvature.head import CurvatureDetection
29
+ from .cofiber_threshold.dim20_20k.head import CofiberThresholdDim20
30
 
31
  REGISTRY = {
32
  "baseline_fcos": BaselineFCOS,
 
55
  "compression": CompressionDetection,
56
  "curvature": CurvatureDetection,
57
  "cofiber_threshold_box32": CofiberThresholdV2,
58
+ "cofiber_threshold_dim20": CofiberThresholdDim20,
59
  }
60
 
61
  ALL_NAMES = list(REGISTRY.keys())
heads/cofiber_threshold/dim10_13k/head.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Cofiber Threshold Dim10: 768->10->80 classification. 13,426 params."""
2
+
3
+ import math
4
+ import torch
5
+ import torch.nn as nn
6
+ import torch.nn.functional as F
7
+
8
+
9
+ def cofiber_decompose(f, n_scales):
10
+ cofibers = []
11
+ residual = f
12
+ for _ in range(n_scales - 1):
13
+ omega = F.avg_pool2d(residual, 2)
14
+ sigma_omega = F.interpolate(omega, size=residual.shape[2:], mode="bilinear", align_corners=False)
15
+ cofibers.append(residual - sigma_omega)
16
+ residual = omega
17
+ cofibers.append(residual)
18
+ return cofibers
19
+
20
+
21
+ class CofiberThresholdDim10(nn.Module):
22
+ name = "cofiber_threshold_dim10"
23
+ needs_intermediates = False
24
+
25
+ def __init__(self, feat_dim=768, bottleneck_dim=10, num_classes=80, n_scales=3, reg_hidden=16):
26
+ super().__init__()
27
+ self.n_scales = n_scales
28
+ self.scale_norms = nn.ModuleList([nn.LayerNorm(feat_dim) for _ in range(n_scales)])
29
+ self.project = nn.Linear(feat_dim, bottleneck_dim, bias=False)
30
+ self.cls_weight = nn.Parameter(torch.randn(num_classes, bottleneck_dim) * 0.01)
31
+ self.cls_bias = nn.Parameter(torch.zeros(num_classes))
32
+ self.reg_hidden = nn.Linear(bottleneck_dim, reg_hidden)
33
+ self.reg_act = nn.GELU()
34
+ self.reg_out = nn.Linear(reg_hidden, 4)
35
+ self.ctr_weight = nn.Parameter(torch.randn(1, bottleneck_dim) * 0.01)
36
+ self.ctr_bias = nn.Parameter(torch.zeros(1))
37
+ self.scale_params = nn.Parameter(torch.ones(n_scales))
38
+
39
+ def forward(self, spatial, inter=None):
40
+ cofibers = cofiber_decompose(spatial, self.n_scales)
41
+ cls_l, reg_l, ctr_l = [], [], []
42
+ for i, cof in enumerate(cofibers):
43
+ B, C, H, W = cof.shape
44
+ f = self.scale_norms[i](cof.permute(0, 2, 3, 1).reshape(-1, C))
45
+ z = self.project(f)
46
+ cls = (z @ self.cls_weight.T + self.cls_bias).reshape(B, H, W, -1).permute(0, 3, 1, 2)
47
+ reg_raw = (self.reg_out(self.reg_act(self.reg_hidden(z))) * self.scale_params[i]).clamp(-10, 10)
48
+ reg = torch.exp(reg_raw).reshape(B, H, W, 4).permute(0, 3, 1, 2)
49
+ ctr = (z @ self.ctr_weight.T + self.ctr_bias).reshape(B, H, W, 1).permute(0, 3, 1, 2)
50
+ cls_l.append(cls); reg_l.append(reg); ctr_l.append(ctr)
51
+ return cls_l, reg_l, ctr_l
52
+
53
+ def loss(self, preds, locs, boxes_b, labels_b):
54
+ from losses.fcos import fcos_loss
55
+ return fcos_loss(*preds, locs, boxes_b, labels_b)
56
+
57
+ def decode(self, preds, locs, **kw):
58
+ from utils.decode import decode_fcos
59
+ return decode_fcos(*preds, locs, **kw)
60
+
61
+ def get_locs(self, spatial):
62
+ from utils.decode import make_locations
63
+ dummy = cofiber_decompose(spatial[:1], self.n_scales)
64
+ sizes = [(c.shape[2], c.shape[3]) for c in dummy]
65
+ strides = [16 * (2 ** i) for i in range(self.n_scales)]
66
+ return make_locations(sizes, strides, spatial.device)
heads/cofiber_threshold/dim10_13k/svd_init.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bfc10537d889491f549b872928d240d9756d18c30ae595d8e3a8b94f5b9c45ff
3
+ size 35821
heads/cofiber_threshold/dim15_17k/head.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Cofiber Threshold Dim15: 768->15->80 classification. 17,751 params."""
2
+
3
+ import math
4
+ import torch
5
+ import torch.nn as nn
6
+ import torch.nn.functional as F
7
+
8
+
9
+ def cofiber_decompose(f, n_scales):
10
+ cofibers = []
11
+ residual = f
12
+ for _ in range(n_scales - 1):
13
+ omega = F.avg_pool2d(residual, 2)
14
+ sigma_omega = F.interpolate(omega, size=residual.shape[2:], mode="bilinear", align_corners=False)
15
+ cofibers.append(residual - sigma_omega)
16
+ residual = omega
17
+ cofibers.append(residual)
18
+ return cofibers
19
+
20
+
21
+ class CofiberThresholdDim15(nn.Module):
22
+ name = "cofiber_threshold_dim15"
23
+ needs_intermediates = False
24
+
25
+ def __init__(self, feat_dim=768, bottleneck_dim=15, num_classes=80, n_scales=3, reg_hidden=16):
26
+ super().__init__()
27
+ self.n_scales = n_scales
28
+ self.scale_norms = nn.ModuleList([nn.LayerNorm(feat_dim) for _ in range(n_scales)])
29
+ self.project = nn.Linear(feat_dim, bottleneck_dim, bias=False)
30
+ self.cls_weight = nn.Parameter(torch.randn(num_classes, bottleneck_dim) * 0.01)
31
+ self.cls_bias = nn.Parameter(torch.zeros(num_classes))
32
+ self.reg_hidden = nn.Linear(bottleneck_dim, reg_hidden)
33
+ self.reg_act = nn.GELU()
34
+ self.reg_out = nn.Linear(reg_hidden, 4)
35
+ self.ctr_weight = nn.Parameter(torch.randn(1, bottleneck_dim) * 0.01)
36
+ self.ctr_bias = nn.Parameter(torch.zeros(1))
37
+ self.scale_params = nn.Parameter(torch.ones(n_scales))
38
+
39
+ def forward(self, spatial, inter=None):
40
+ cofibers = cofiber_decompose(spatial, self.n_scales)
41
+ cls_l, reg_l, ctr_l = [], [], []
42
+ for i, cof in enumerate(cofibers):
43
+ B, C, H, W = cof.shape
44
+ f = self.scale_norms[i](cof.permute(0, 2, 3, 1).reshape(-1, C))
45
+ z = self.project(f)
46
+ cls = (z @ self.cls_weight.T + self.cls_bias).reshape(B, H, W, -1).permute(0, 3, 1, 2)
47
+ reg_raw = (self.reg_out(self.reg_act(self.reg_hidden(z))) * self.scale_params[i]).clamp(-10, 10)
48
+ reg = torch.exp(reg_raw).reshape(B, H, W, 4).permute(0, 3, 1, 2)
49
+ ctr = (z @ self.ctr_weight.T + self.ctr_bias).reshape(B, H, W, 1).permute(0, 3, 1, 2)
50
+ cls_l.append(cls); reg_l.append(reg); ctr_l.append(ctr)
51
+ return cls_l, reg_l, ctr_l
52
+
53
+ def loss(self, preds, locs, boxes_b, labels_b):
54
+ from losses.fcos import fcos_loss
55
+ return fcos_loss(*preds, locs, boxes_b, labels_b)
56
+
57
+ def decode(self, preds, locs, **kw):
58
+ from utils.decode import decode_fcos
59
+ return decode_fcos(*preds, locs, **kw)
60
+
61
+ def get_locs(self, spatial):
62
+ from utils.decode import make_locations
63
+ dummy = cofiber_decompose(spatial[:1], self.n_scales)
64
+ sizes = [(c.shape[2], c.shape[3]) for c in dummy]
65
+ strides = [16 * (2 ** i) for i in range(self.n_scales)]
66
+ return make_locations(sizes, strides, spatial.device)
heads/cofiber_threshold/dim15_17k/svd_init.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1843641c84fb1a44e8b9e2e308b22e38ebc42f63e105464511946f8aa826ce1d
3
+ size 52781
heads/cofiber_threshold/dim20_20k/checkpoint.pth CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:acd116819d27c1b4c8cfeece6195d6d22abe31b3382394c2af44ec509b7bf7ef
3
  size 94325
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4da888b1bf8d9713177831259be1dceb5cdc79e21f13ed4621927ed3bd786101
3
  size 94325
heads/cofiber_threshold/dim20_20k/cofiber_threshold_dim20_coco_8ep_22k.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8a5f897f169c0ee7370f74a58766f4b717d32835c8278ad2e09d9d024801b9bc
3
+ size 94513
heads/cofiber_threshold/dim20_20k/cofiber_threshold_dim20_coco_8ep_22k_coco_summary.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "head": "cofiber_threshold_dim20",
3
+ "params": 22076,
4
+ "checkpoint": "heads/cofiber_threshold/dim20_20k/cofiber_threshold_dim20_coco_8ep_22k.pth",
5
+ "n_images": 5000,
6
+ "n_detections": 499821,
7
+ "mAP_0.5_0.95": 0.03944936745927407,
8
+ "mAP_0.50": 0.1479595923539579,
9
+ "mAP_0.75": 0.009029135490091572,
10
+ "mAP_small": 0.015860738490560772,
11
+ "mAP_medium": 0.039767698217524725,
12
+ "mAP_large": 0.058431098084337586
13
+ }
heads/cofiber_threshold/dim20_20k/head.py CHANGED
@@ -64,3 +64,18 @@ class CofiberThresholdDim20(nn.Module):
64
  reg_l.append(reg)
65
  ctr_l.append(ctr)
66
  return cls_l, reg_l, ctr_l
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  reg_l.append(reg)
65
  ctr_l.append(ctr)
66
  return cls_l, reg_l, ctr_l
67
+
68
+ def loss(self, preds, locs, boxes_b, labels_b):
69
+ from losses.fcos import fcos_loss
70
+ return fcos_loss(*preds, locs, boxes_b, labels_b)
71
+
72
+ def decode(self, preds, locs, **kw):
73
+ from utils.decode import decode_fcos
74
+ return decode_fcos(*preds, locs, **kw)
75
+
76
+ def get_locs(self, spatial):
77
+ from utils.decode import make_locations
78
+ dummy = cofiber_decompose(spatial[:1], self.n_scales)
79
+ sizes = [(c.shape[2], c.shape[3]) for c in dummy]
80
+ strides = [16 * (2 ** i) for i in range(self.n_scales)]
81
+ return make_locations(sizes, strides, spatial.device)
heads/cofiber_threshold/dim20_22k/svd_init.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6ec7e85396c35b2e0678220d2471286a7df583d4635b2553717fd107dd80a4b5
3
+ size 69741
heads/cofiber_threshold/dim30_30k/head.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Cofiber Threshold Dim30: 768->30->80 classification. 30,726 params."""
2
+
3
+ import math
4
+ import torch
5
+ import torch.nn as nn
6
+ import torch.nn.functional as F
7
+
8
+
9
+ def cofiber_decompose(f, n_scales):
10
+ cofibers = []
11
+ residual = f
12
+ for _ in range(n_scales - 1):
13
+ omega = F.avg_pool2d(residual, 2)
14
+ sigma_omega = F.interpolate(omega, size=residual.shape[2:], mode="bilinear", align_corners=False)
15
+ cofibers.append(residual - sigma_omega)
16
+ residual = omega
17
+ cofibers.append(residual)
18
+ return cofibers
19
+
20
+
21
+ class CofiberThresholdDim30(nn.Module):
22
+ name = "cofiber_threshold_dim30"
23
+ needs_intermediates = False
24
+
25
+ def __init__(self, feat_dim=768, bottleneck_dim=30, num_classes=80, n_scales=3, reg_hidden=16):
26
+ super().__init__()
27
+ self.n_scales = n_scales
28
+ self.scale_norms = nn.ModuleList([nn.LayerNorm(feat_dim) for _ in range(n_scales)])
29
+ self.project = nn.Linear(feat_dim, bottleneck_dim, bias=False)
30
+ self.cls_weight = nn.Parameter(torch.randn(num_classes, bottleneck_dim) * 0.01)
31
+ self.cls_bias = nn.Parameter(torch.zeros(num_classes))
32
+ self.reg_hidden = nn.Linear(bottleneck_dim, reg_hidden)
33
+ self.reg_act = nn.GELU()
34
+ self.reg_out = nn.Linear(reg_hidden, 4)
35
+ self.ctr_weight = nn.Parameter(torch.randn(1, bottleneck_dim) * 0.01)
36
+ self.ctr_bias = nn.Parameter(torch.zeros(1))
37
+ self.scale_params = nn.Parameter(torch.ones(n_scales))
38
+
39
+ def forward(self, spatial, inter=None):
40
+ cofibers = cofiber_decompose(spatial, self.n_scales)
41
+ cls_l, reg_l, ctr_l = [], [], []
42
+ for i, cof in enumerate(cofibers):
43
+ B, C, H, W = cof.shape
44
+ f = self.scale_norms[i](cof.permute(0, 2, 3, 1).reshape(-1, C))
45
+ z = self.project(f)
46
+ cls = (z @ self.cls_weight.T + self.cls_bias).reshape(B, H, W, -1).permute(0, 3, 1, 2)
47
+ reg_raw = (self.reg_out(self.reg_act(self.reg_hidden(z))) * self.scale_params[i]).clamp(-10, 10)
48
+ reg = torch.exp(reg_raw).reshape(B, H, W, 4).permute(0, 3, 1, 2)
49
+ ctr = (z @ self.ctr_weight.T + self.ctr_bias).reshape(B, H, W, 1).permute(0, 3, 1, 2)
50
+ cls_l.append(cls); reg_l.append(reg); ctr_l.append(ctr)
51
+ return cls_l, reg_l, ctr_l
52
+
53
+ def loss(self, preds, locs, boxes_b, labels_b):
54
+ from losses.fcos import fcos_loss
55
+ return fcos_loss(*preds, locs, boxes_b, labels_b)
56
+
57
+ def decode(self, preds, locs, **kw):
58
+ from utils.decode import decode_fcos
59
+ return decode_fcos(*preds, locs, **kw)
60
+
61
+ def get_locs(self, spatial):
62
+ from utils.decode import make_locations
63
+ dummy = cofiber_decompose(spatial[:1], self.n_scales)
64
+ sizes = [(c.shape[2], c.shape[3]) for c in dummy]
65
+ strides = [16 * (2 ** i) for i in range(self.n_scales)]
66
+ return make_locations(sizes, strides, spatial.device)
heads/cofiber_threshold/dim30_30k/svd_init.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2de5b79f34fac5fd500ab3180733435ebc27bb3836b3c62f129ba6022812867a
3
+ size 103661
heads/cofiber_threshold/dim5_9k/head.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Cofiber Threshold Dim5: 768->5->80 classification. 9,101 params."""
2
+
3
+ import math
4
+ import torch
5
+ import torch.nn as nn
6
+ import torch.nn.functional as F
7
+
8
+
9
+ def cofiber_decompose(f, n_scales):
10
+ cofibers = []
11
+ residual = f
12
+ for _ in range(n_scales - 1):
13
+ omega = F.avg_pool2d(residual, 2)
14
+ sigma_omega = F.interpolate(omega, size=residual.shape[2:], mode="bilinear", align_corners=False)
15
+ cofibers.append(residual - sigma_omega)
16
+ residual = omega
17
+ cofibers.append(residual)
18
+ return cofibers
19
+
20
+
21
+ class CofiberThresholdDim5(nn.Module):
22
+ name = "cofiber_threshold_dim5"
23
+ needs_intermediates = False
24
+
25
+ def __init__(self, feat_dim=768, bottleneck_dim=5, num_classes=80, n_scales=3, reg_hidden=16):
26
+ super().__init__()
27
+ self.n_scales = n_scales
28
+ self.scale_norms = nn.ModuleList([nn.LayerNorm(feat_dim) for _ in range(n_scales)])
29
+ self.project = nn.Linear(feat_dim, bottleneck_dim, bias=False)
30
+ self.cls_weight = nn.Parameter(torch.randn(num_classes, bottleneck_dim) * 0.01)
31
+ self.cls_bias = nn.Parameter(torch.zeros(num_classes))
32
+ self.reg_hidden = nn.Linear(bottleneck_dim, reg_hidden)
33
+ self.reg_act = nn.GELU()
34
+ self.reg_out = nn.Linear(reg_hidden, 4)
35
+ self.ctr_weight = nn.Parameter(torch.randn(1, bottleneck_dim) * 0.01)
36
+ self.ctr_bias = nn.Parameter(torch.zeros(1))
37
+ self.scale_params = nn.Parameter(torch.ones(n_scales))
38
+
39
+ def forward(self, spatial, inter=None):
40
+ cofibers = cofiber_decompose(spatial, self.n_scales)
41
+ cls_l, reg_l, ctr_l = [], [], []
42
+ for i, cof in enumerate(cofibers):
43
+ B, C, H, W = cof.shape
44
+ f = self.scale_norms[i](cof.permute(0, 2, 3, 1).reshape(-1, C))
45
+ z = self.project(f)
46
+ cls = (z @ self.cls_weight.T + self.cls_bias).reshape(B, H, W, -1).permute(0, 3, 1, 2)
47
+ reg_raw = (self.reg_out(self.reg_act(self.reg_hidden(z))) * self.scale_params[i]).clamp(-10, 10)
48
+ reg = torch.exp(reg_raw).reshape(B, H, W, 4).permute(0, 3, 1, 2)
49
+ ctr = (z @ self.ctr_weight.T + self.ctr_bias).reshape(B, H, W, 1).permute(0, 3, 1, 2)
50
+ cls_l.append(cls); reg_l.append(reg); ctr_l.append(ctr)
51
+ return cls_l, reg_l, ctr_l
52
+
53
+ def loss(self, preds, locs, boxes_b, labels_b):
54
+ from losses.fcos import fcos_loss
55
+ return fcos_loss(*preds, locs, boxes_b, labels_b)
56
+
57
+ def decode(self, preds, locs, **kw):
58
+ from utils.decode import decode_fcos
59
+ return decode_fcos(*preds, locs, **kw)
60
+
61
+ def get_locs(self, spatial):
62
+ from utils.decode import make_locations
63
+ dummy = cofiber_decompose(spatial[:1], self.n_scales)
64
+ sizes = [(c.shape[2], c.shape[3]) for c in dummy]
65
+ strides = [16 * (2 ** i) for i in range(self.n_scales)]
66
+ return make_locations(sizes, strides, spatial.device)
heads/cofiber_threshold/dim5_9k/svd_init.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b54e557b30c91fed9365db41c9920f1a9cd69cbb047313e26e882058bffc57dc
3
+ size 18861