dim20: 3.9 mAP from 22K params. 768->20->80 bottleneck, SVD-initialized from pruned prototypes.
Browse files- heads/__init__.py +2 -0
- heads/cofiber_threshold/dim10_13k/head.py +66 -0
- heads/cofiber_threshold/dim10_13k/svd_init.pt +3 -0
- heads/cofiber_threshold/dim15_17k/head.py +66 -0
- heads/cofiber_threshold/dim15_17k/svd_init.pt +3 -0
- heads/cofiber_threshold/dim20_20k/checkpoint.pth +1 -1
- heads/cofiber_threshold/dim20_20k/cofiber_threshold_dim20_coco_8ep_22k.pth +3 -0
- heads/cofiber_threshold/dim20_20k/cofiber_threshold_dim20_coco_8ep_22k_coco_summary.json +13 -0
- heads/cofiber_threshold/dim20_20k/head.py +15 -0
- heads/cofiber_threshold/dim20_22k/svd_init.pt +3 -0
- heads/cofiber_threshold/dim30_30k/head.py +66 -0
- heads/cofiber_threshold/dim30_30k/svd_init.pt +3 -0
- heads/cofiber_threshold/dim5_9k/head.py +66 -0
- heads/cofiber_threshold/dim5_9k/svd_init.pt +3 -0
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:
|
| 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
|