Files
ModelTrainEval/models/heads/classification.py
T
Shaun ZhouandClaude Opus 5 3a36aad6c3 feat(models): 纯卷积缺陷分类定位模型
面向实时设备部署,全程只用 convolution,不含 attention / transformer。

- backbones: 自研 tiny_conv(深度可分离,默认)与 torchvision 封装(resnet/mobilenet/shufflenet)
- necks: nearest 上采样 + 3x3 卷积,把特征恢复到 stride 4,兼顾小缺陷定位与速度
- heads: anchor-free 中心点定位头(heatmap + wh + offset)与图像级分类头;
  分类头输出维度随 label_mode 切换(多类多热 / 单类互斥含背景位)
- postprocess: 3x3 max-pool 峰值抑制替代 NMS 循环,无循环、可导出 TensorRT / OpenVINO

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 17:54:55 +08:00

28 lines
925 B
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""图像级缺陷分类头。
输出维度由 `label_mode` 决定,见 `models.defect_net.DefectNet`:
multilabel: num_classes —— 每一维独立 sigmoid,全 0 表示 OK 片
multiclass: num_classes + 1 —— softmax 互斥,最后一维为 "无缺陷"
"""
from __future__ import annotations
import torch
from torch import nn
from models.registry import HEADS
@HEADS.register("classification")
class ClassificationHead(nn.Module):
def __init__(self, in_channels: int, num_outputs: int, dropout: float = 0.0) -> None:
super().__init__()
self.pool = nn.AdaptiveAvgPool2d(1)
self.drop = nn.Dropout(dropout) if dropout > 0 else nn.Identity()
self.fc = nn.Linear(in_channels, num_outputs)
self.num_outputs = num_outputs
def forward(self, feat: torch.Tensor) -> torch.Tensor:
x = self.pool(feat).flatten(1)
return self.fc(self.drop(x))