feat: 未分类样本的无监督聚类(多 stage 特征 + KMeans,可选 SimCLR)
把 data/film 下所有图片拉平做聚类,不使用任何目录名,簇数由 num_clusters 决定。 预处理针对该批数据的实际情况(14.5k 张已裁好的缺陷小图,中位 152x113, 宽高比 0.24~39.9):尺寸与亮度都是 ROI 裁剪和光照的产物、不是缺陷属性, 因此拉伸到 128x128(不用 letterbox,其填充比例等价于编码了宽高比)并逐图 z-score。 - cluster: torch 实现的 kmeans++/Lloyd(含空簇处理与 n_init)、PCA、轮廓系数、 NMI 稳定性、多 stage 特征提取;不引 scikit-learn - 白化默认关闭:CNN 特征谱极陡(λ1/λ32≈165x),白化会把噪声方向抬到与信号同权, 实测最大簇一度吃掉 96% 的样本 - simclr: NT-Xent 自监督预训练,用项目自己的卷积骨架,权重可直接初始化 DefectNet; 属于训练,走 require_cuda() 守卫 - 产出 assignments.csv、summary.json、按簇的软链目录与代表样本拼图,供人工核对 全量 14,579 张:轮廓系数 0.326、换种子稳定性 0.964,CPU 约 100 秒。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4b1147ed8f
commit
f433e5cf59
@@ -0,0 +1,30 @@
|
||||
"""SimCLR 的投影头。
|
||||
|
||||
对比损失只作用在投影后的空间;聚类时**丢掉投影头、用骨架特征**——
|
||||
这是 SimCLR 的既有结论:投影头会丢掉对下游任务有用但对比任务用不上的信息。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import torch
|
||||
from torch import nn
|
||||
|
||||
from models.registry import HEADS
|
||||
|
||||
|
||||
@HEADS.register("projection")
|
||||
class ProjectionHead(nn.Module):
|
||||
def __init__(self, in_channels: int, hidden_channels: int = 256, out_channels: int = 128) -> None:
|
||||
super().__init__()
|
||||
self.pool = nn.AdaptiveAvgPool2d(1)
|
||||
self.mlp = nn.Sequential(
|
||||
nn.Linear(in_channels, hidden_channels),
|
||||
nn.BatchNorm1d(hidden_channels),
|
||||
nn.ReLU(inplace=True),
|
||||
nn.Linear(hidden_channels, out_channels),
|
||||
)
|
||||
|
||||
def forward(self, feat: torch.Tensor) -> torch.Tensor:
|
||||
if feat.dim() == 4:
|
||||
feat = self.pool(feat).flatten(1)
|
||||
return self.mlp(feat)
|
||||
Reference in New Issue
Block a user