1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
| import torch import torch.nn as nn
class SwinFatigueDetector(nn.Module): """ Swin Transformer疲劳检测 Nature 2025 论文对比模型 准确率:99.03% 优势: 1. 层级特征提取(金字塔结构) 2. 移位窗口注意力(减少计算量) 3. 更适合处理局部特征(眼睛、嘴巴) """ def __init__(self, image_size: int = 224, patch_size: int = 4, num_classes: int = 2, embed_dim: int = 96, depths: list = [2, 2, 6, 2], num_heads: list = [3, 6, 12, 24], window_size: int = 7): super().__init__() self.patch_embed = nn.Conv2d(3, embed_dim, kernel_size=patch_size, stride=patch_size) self.stages = nn.ModuleList() for i, (depth, num_head) in enumerate(zip(depths, num_heads)): stage = SwinStage( dim=embed_dim * (2 ** i), depth=depth, num_heads=num_head, window_size=window_size ) self.stages.append(stage) if i < len(depths) - 1: self.stages.append(PatchMerging(embed_dim * (2 ** i))) self.norm = nn.LayerNorm(embed_dim * (2 ** (len(depths) - 1))) self.head = nn.Linear(embed_dim * (2 ** (len(depths) - 1)), num_classes) def forward(self, x: torch.Tensor) -> torch.Tensor: x = self.patch_embed(x) x = x.flatten(2).permute(0, 2, 1) for stage in self.stages: x = stage(x) x = self.norm(x) x = x.mean(dim=1) logits = self.head(x) return logits
class SwinStage(nn.Module): """Swin Transformer Stage""" def __init__(self, dim: int, depth: int, num_heads: int, window_size: int): super().__init__() self.blocks = nn.ModuleList([ SwinTransformerBlock(dim, num_heads, window_size, shift_size=0 if i % 2 == 0 else window_size // 2) for i in range(depth) ]) def forward(self, x: torch.Tensor) -> torch.Tensor: for block in self.blocks: x = block(x) return x
class SwinTransformerBlock(nn.Module): """Swin Transformer Block""" def __init__(self, dim: int, num_heads: int, window_size: int, shift_size: int): super().__init__() self.norm1 = nn.LayerNorm(dim) self.attn = WindowAttention(dim, num_heads, window_size) self.norm2 = nn.LayerNorm(dim) self.mlp = nn.Sequential( nn.Linear(dim, dim * 4), nn.GELU(), nn.Linear(dim * 4, dim) ) self.window_size = window_size self.shift_size = shift_size def forward(self, x: torch.Tensor) -> torch.Tensor: shortcut = x x = self.norm1(x) x = self.attn(x, self.window_size, self.shift_size) x = shortcut + x x = x + self.mlp(self.norm2(x)) return x
class WindowAttention(nn.Module): """Window-based Multi-head Attention""" def __init__(self, dim: int, num_heads: int, window_size: int): super().__init__() self.attn = nn.MultiheadAttention(dim, num_heads, batch_first=True) def forward(self, x: torch.Tensor, window_size: int, shift_size: int) -> torch.Tensor: attn_out, _ = self.attn(x, x, x) return attn_out
class PatchMerging(nn.Module): """Patch Merging(下采样)""" def __init__(self, dim: int): super().__init__() self.norm = nn.LayerNorm(dim * 4) self.reduction = nn.Linear(dim * 4, dim * 2) def forward(self, x: torch.Tensor) -> torch.Tensor: return x
if __name__ == "__main__": model = SwinFatigueDetector() x = torch.randn(2, 3, 224, 224) output = model(x) print(f"Swin输出形状: {output.shape}")
|