beaunix commited on
Commit
a269f8c
·
verified ·
1 Parent(s): 65c0ad1

set Fall Detector Model

Browse files
Files changed (1) hide show
  1. model.py +91 -0
model.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import timm
3
+ import torch
4
+ import torch.nn as nn
5
+
6
+ EFFICIENTNET_DIM = 1280
7
+
8
+
9
+ class TemporalAttention(nn.Module):
10
+ """
11
+ Input : (B, N_FRAMES, EFFICIENTNET_DIM)
12
+ Output : (pooled (B, EFFICIENTNET_DIM), attn_weights (B, N_FRAMES))
13
+ """
14
+
15
+ def __init__(self, input_dim: int = EFFICIENTNET_DIM):
16
+ super().__init__()
17
+ self.attention = nn.Sequential(
18
+ nn.Linear(input_dim, 128),
19
+ nn.Tanh(),
20
+ nn.Linear(128, 1),
21
+ )
22
+
23
+ def forward(self, x: torch.Tensor):
24
+ scores = self.attention(x) # (B, 16, 1)
25
+ weights = torch.softmax(scores, dim=1) # (B, 16, 1)
26
+ pooled = (weights * x).sum(dim=1) # (B, 1280)
27
+
28
+ return pooled, weights.squeeze(-1) # (B, 1280), (B, 16)
29
+
30
+
31
+
32
+
33
+ class FallDetector(nn.Module):
34
+ """
35
+ EfficientNet-Lite0 + Temporal Attention + MLP classifier.
36
+
37
+ Forward:
38
+ (B, 16, 3, 224, 224)
39
+ -> per-frame EfficientNet-Lite0 -> (B, 16, 1280)
40
+ -> TemporalAttention -> (B, 1280), (B, 16)
41
+ -> MLP classifier -> (B, 1) logit
42
+ Sigmoid is applied explicitly at inference, not inside the module.
43
+ """
44
+
45
+ def __init__(self, pretrained_backbone: bool = False):
46
+ super().__init__()
47
+ backbone = timm.create_model("efficientnet_lite0", pretrained=pretrained_backbone)
48
+
49
+ self.conv_stem = backbone.conv_stem
50
+ self.bn1 = backbone.bn1
51
+ self.blocks = backbone.blocks
52
+ self.conv_head = backbone.conv_head
53
+ self.bn2 = backbone.bn2
54
+ self.global_pool = backbone.global_pool
55
+
56
+ self.temporal_attention = TemporalAttention(EFFICIENTNET_DIM)
57
+
58
+ self.classifier = nn.Sequential(
59
+ nn.Linear(EFFICIENTNET_DIM, 512),
60
+ nn.ReLU(inplace=True),
61
+ nn.Dropout(0.2),
62
+ nn.Linear(512, 128),
63
+ nn.ReLU(inplace=True),
64
+ nn.Dropout(0.2),
65
+ nn.Linear(128, 1),
66
+ )
67
+
68
+ def forward(self, x: torch.Tensor):
69
+ B, T, C, H, W = x.shape
70
+ x_flat = x.view(B * T, C, H, W)
71
+
72
+ f = self.conv_stem(x_flat)
73
+ f = self.bn1(f)
74
+ f = self.blocks(f)
75
+ f = self.conv_head(f)
76
+ f = self.bn2(f)
77
+ f = self.global_pool(f) # (B*16, 1280)
78
+ f = f.view(B, T, EFFICIENTNET_DIM) # (B, 16, 1280)
79
+
80
+ pooled, attn_weights = self.temporal_attention(f)
81
+ logit = self.classifier(pooled) # (B, 1)
82
+
83
+ return logit, attn_weights
84
+
85
+
86
+ def count_parameters(self):
87
+ total = sum(p.numel() for p in self.parameters())
88
+ trainable = sum(p.numel() for p in self.parameters() if p.requires_grad)
89
+
90
+ return total, trainable
91
+