自監督學習:SimCLR 與 DINO - 讓無標註的監視器畫面自己當老師

自監督學習:SimCLR 與 DINO - 讓無標註的監視器畫面自己當老師

標一張畫面要錢,監視器每天卻吐上萬張沒人標。自監督學習讓資料自己出考題:SimCLR 逼「同一畫面的兩個視角要相似」,DINO 用師生自蒸餾連負樣本都省了。本篇在筆電 CPU 上完整重現,實測驚喜與打臉並存:每類只給 1 張標籤時 SimCLR 海放原始像素 12 個百分點;但數字太簡單,標籤一多 raw pixels 就追平;精簡版 DINO 學得動卻明顯落後——一場關於「省標籤到底能省多少」的誠實實驗。


核心貢獻者

Ting Chen 與 Geoffrey Hinton 領銜的 Google Brain 團隊於 2020 年發表 SimCLR《A Simple Framework for Contrastive Learning of Visual Representations》,核心精神就藏在標題的 Simple:丟掉所有花俏設計,只要「強力資料增強 + 大批次對比」,自監督學到的特徵就能逼近監督式。一年後,Mathilde Caron 等 Meta (FAIR) 團隊在 2021 年發表 DINO《Emerging Properties in Self-Supervised ViT》——名字是 self-DIstillation with NO labels 的縮寫:師生自蒸餾、完全不用負樣本,還意外長出了能分割物件輪廓的注意力。兩篇論文共同宣告:視覺特徵,不一定要靠人類標註才能學會


為什麼要讓資料自己當老師?

Day 045 的門禁模型 ,是用「有標籤的人臉配對」訓練出來的——我們得先知道哪兩張是同一人,才能拉近推遠。但現實更殘酷:廠區監視器 24 小時運轉,每天錄下數萬張畫面,沒有任何一張有標籤

問題卡在標註成本。要標「這格畫面有沒有人違規」,得請老師傅一張張看;幾萬張根本標不完。於是有了一個大膽的提問:能不能不靠人給答案,讓資料自己出題、自己改?

這就是自監督學習 (Self-Supervised Learning):從資料本身「無中生有」造出監督訊號。它的核心假設樸素得驚人——一張圖經過不同的裁切、旋轉、加噪之後,它還是同一張圖。模型只要學會「認出這件事」,就被迫理解了影像的內容。標註費太貴,就讓資料自己當老師。


1. 資料集來源

資料集:Digits (scikit-learn)

備註:sklearn.datasets.load_digits 一行載入,1797 張 8×8 灰階手寫數字、10 類。為了讓整套 SimCLR/DINO 在筆電 CPU 上完整可重現,這裡用它當「監視器畫面」的代理資料集 (proxy)。真實監視器是幾十萬張 224×224 的畫面,道理一模一樣,只是算力差三個數量級

實驗設計:關鍵是「假裝沒有標籤」

  • 無標註影片庫:把訓練集 1257 張全部當成「錄下來但沒人標」的畫面,做自監督預訓練——過程完全不看 y
  • 評估方式 (線性探測 Linear Probe):凍結學好的特徵,只用每類 K 張標籤訓練一個邏輯回歸,在 540 張測試集上驗收。K 從 1 掃到 50,看「省標籤」的極限在哪。
  • 對照組:原始像素、隨機權重 encoder (沒訓練過的同款網路)、以及從頭訓練 CNN (拿少量標籤直接端到端硬 train)。

2. 原理

2.1 沒有人給答案,就讓資料自己出題

自監督的招式叫前置任務 (Pretext Task):設計一個「答案藏在資料裡」的假任務,逼模型在解題過程中學到有用的特徵。對比學習的前置任務是——判斷這兩個視角是不是來自同一張圖

2.2 SimCLR:同一畫面的兩個視角要相似

增強視角

如上圖,同一張數字經過旋轉、縮放、加噪、遮擋,產生多個視角 (view)。SimCLR 的規則簡單粗暴:

  • 正樣本對:同一張圖的兩個增強視角,要在嵌入空間拉近
  • 負樣本:同批次裡其他所有圖的視角,一律推遠

用的損失是 NT-Xent (溫度縮放的交叉熵),對一個正樣本對 (i,j)(i,j):

i,j=logexp(sim(zi,zj)/τ)kiexp(sim(zi,zk)/τ)\ell_{i,j} = -\log \frac{\exp(\text{sim}(z_i, z_j)/\tau)}{\sum_{k \neq i}\exp(\text{sim}(z_i, z_k)/\tau)}

  • 增強是靈魂:增強太弱,模型靠背景就能配對,學不到內容;增強夠強,它才被逼著理解「這是個數字」。
  • 大批次是本錢:批次越大,負樣本越多,對比訊號越銳利——這也是 SimCLR 出了名吃資源的原因。

SimCLR 架構:同一張無標籤圖產生兩個增強視角,各自通過權重共用的編碼器 與投影頭 g,得到 z1z2;NT-Xent 把這對正樣本拉近、把批次內其他圖推遠。

Loading Diagram...

2.3 DINO:師生自蒸餾,連負樣本都不要

SimCLR 需要一堆負樣本撐開空間,DINO 反其道而行:只有正向訊號,沒有負樣本。它擺兩個同款網路——學生 (student)老師 (teacher):

LDINO=cpt(c)logps(c),pt=softmax ⁣(gt(v2)centerτt), ps=softmax ⁣(gs(v1)τs)\mathcal{L}_{\text{DINO}} = -\sum_{c} p_t(c)\,\log p_s(c),\quad p_t=\text{softmax}\!\Big(\tfrac{g_t(v_2)-\text{center}}{\tau_t}\Big),\ p_s=\text{softmax}\!\Big(\tfrac{g_s(v_1)}{\tau_s}\Big)

  • 學生看視角 v1v_1、老師看視角 v2v_2,學生要去預測老師輸出的機率分布——跨視角的自我一致。
  • 老師不做反向傳播,而是學生的 EMA (指數移動平均):老師是學生的「慢速穩定版分身」。

DINO 架構:學生與老師看不同視角,學生去追老師輸出的機率分布(交叉熵);老師不回傳梯度、是學生的 EMA 慢速分身,再靠「扣 center + 低溫銳化」防止塌縮。

Loading Diagram...

2.4 SimCLR vs DINO:兩種省標籤哲學

面向SimCLRDINO
監督訊號對比 (正 vs 負)自蒸餾 (師生一致)
需要負樣本需要,且越多越好完全不需要
抗塌縮機制負樣本自然撐開centering + sharpening
對批次大小敏感 (大批次才強)相對不敏感
代表骨幹ResNetViT (Day 44 的主角)

2.5 共同的頭號敵人:表徵塌縮

兩派方法看似南轅北轍,對抗的卻是同一個惡魔——塌縮 (Collapse):網路偷懶把所有圖都映射到同一個點,損失照樣很低,但特徵全廢 (這正是 Day 45 那個「損失卡在 margin」的老朋友)。SimCLR 靠負樣本硬撐開空間;DINO 沒有負樣本,改用兩招:centering (老師輸出扣掉移動平均,避免退化成單一類) 加上 sharpening (老師溫度 τt\tau_t 比學生低,讓分布更尖銳)。三招缺一,DINO 立刻塌給你看


3. 實戰

Python 程式碼實作

# 增強:同一張圖呼叫兩次 = 兩個「視角」,這是自監督的燃料
def augment(x):
    x = rand_affine(x)                          # 旋轉 ±15°、縮放、平移
    x = x * (0.7 + 0.6 * torch.rand_like(x[:, :1, :1, :1]))  # 強度抖動
    x = x + 0.10 * torch.randn_like(x)          # 高斯雜訊
    return cutout(x).clamp(0, 1)                # 隨機遮擋一小塊

# SimCLR:NT-Xent —— 正樣本是「另一個視角」,負樣本是批次裡其他所有圖
def nt_xent(z, temp=0.5):
    z = F.normalize(z, dim=1)                   # 2N 個視角,住在單位球面
    sim = z @ z.t() / temp
    sim.fill_diagonal_(-1e9)                    # 挖掉「和自己比」
    targets = (torch.arange(len(z)) + len(z) // 2) % len(z)
    return F.cross_entropy(sim, targets)        # 一行搞定對比損失

# DINO:student 追 teacher,靠三招防塌縮
s = F.log_softmax(head_s(enc_s(v1)) / 0.1, dim=1)               # student 溫度高
with torch.no_grad():                                          # ③ teacher stop-grad
    t = F.softmax((head_t(enc_t(v2)) - center) / 0.04, dim=1)  # 低溫 sharpening + 扣 center
loss = -(t * s).sum(1).mean()
center = 0.9 * center + 0.1 * teacher_out.mean(0)              # ① centering
for ps, pt in zip(enc_s.parameters(), enc_t.parameters()):
    pt.mul_(0.996).add_(ps, alpha=0.004)                      # ② teacher = student 的 EMA

程式碼重點:

  • 增強是自監督的燃料:仿射 + 強度抖動 + 雜訊 + cutout,同一張圖呼叫兩次就是兩個視角——沒有增強,對比學習無事可學。
  • NT-Xent 一行交叉熵搞定:把對角線挖掉 (不跟自己比),正確答案標在「另一個視角」的位置。
  • DINO 的防塌縮三開關:teacher 用 EMA 不回傳梯度、center 扣掉移動平均、teacher 溫度 (0.04) 比 student (0.1) 低。三招缺一,特徵全部塌成一坨。

4. 模型評估

標籤效率總成績 (每類 K 張標籤,測試集 540 張)

方法每類1張每類2張每類5張每類10張每類20張每類50張
SimCLR (自監督)0.7650.7780.8980.9200.9460.957
DINO (自監督)0.6330.6350.7350.7830.8670.894
原始像素 (基準)0.6430.6940.9070.9150.9310.950
隨機權重 (對照)0.3020.3720.4560.4650.5390.546

從頭訓練 CNN (端到端):每類 5 張 → 0.817;每類 50 張 → 0.770 (過擬合甚至倒退)。

少量標籤時,自監督海放

標籤效率曲線
  • 最左端是自監督的主場:每類只有 1~2 張標籤時,SimCLR (0.765) 大勝原始像素 (0.643) 整整 12 個百分點——特徵先學好,標籤稀缺時直接發威。
  • 隨機權重只有 0.30:同款網路沒訓練過就這分數,證明 SimCLR 的能力是訓練學來的,不是網路結構撿到的。
  • 從頭訓練 CNN 雙雙落敗:紅星每類 5 張 (0.817)、50 張 (0.770,過擬合倒退) 全輸給 SimCLR 線性探測。少標籤時,與其硬 train 一個 CNN,不如拿凍結的自監督特徵配一個邏輯回歸

沒看過標籤,類別自己分開

嵌入空間

把 SimCLR 的測試集特徵投影到 2D——全程沒餵過任何一個標籤,數字 0、1、4、7 卻自己聚成了清楚的團 (中央 3/5/8/9 有些重疊,是 2D 投影與數字本身相似所致)。這就是自監督的本質:它學到的不是「這是幾」,而是影像相似性這個概念本身

誠實的打臉:數字太簡單

這篇的結果不全是漂亮話,兩個必須講清楚的地方:

  • 標籤一多,原始像素就追平:每類 5 張以上時,raw pixels (0.907) 甚至小勝 SimCLR (0.898)。因為 8×8 數字太簡單、像素本身就近乎線性可分。自監督的紅利會隨「資料變難、標籤變少」而放大;在這種玩具級任務上,它的優勢集中在最左端。
  • 精簡版 DINO 明顯落後:我們的 DINO 損失有在降 (11 → 9,確實學得動),但全程輸給 SimCLR。DINO 原論文的驚艷靠的是 ViT + multi-crop + 長訓練排程;剝到最精簡,它比 SimCLR 更難調——方法真正的威力,常常藏在工程細節裡

工安視角的解讀

  • 喚醒沉睡的監視器資料:廠區攝影機錄了幾年,幾乎全是無標註畫面。自監督能先把這些資料變成一座「特徵庫」,日後任何下游任務 (誰沒戴安全帽、誰闖入禁區) 只要少量標籤就能微調上線。
  • 標註成本的算術:標一張工安違規畫面要老師傅逐格判讀,幾萬張標不完。自監督把「非標不可的量」砍到零頭——這是它最務實的價值。
  • 個資友善:同 Day 45,資料庫存的是特徵向量而非原始畫面,對隱私更友善。
  • 誠實提醒:玩具級 0.9 不等於產線級。真實場景 (SimCLR/DINO 跑在 ResNet/ViT、百萬張畫面) 才是紅利真正爆發之處;但省標籤的核心數學,和這篇一模一樣。

5. 總結

我們學習了自監督與對比學習:

  • 換一個老師:不靠人標答案,讓資料自己出題——「同一張圖的兩個視角要相似」就是免費的監督訊號。
  • 兩種哲學:SimCLR 用正負樣本對比 (大批次是本錢);DINO 用師生自蒸餾 (centering + sharpening 防塌縮,連負樣本都省)。共同敵人都是表徵塌縮
  • 實驗結論:每類 1 張標籤時 SimCLR 海放像素 12 個百分點、也輾壓從頭訓練;但數字太簡單,標籤一多優勢就收斂——自監督的紅利屬於「資料多、標籤少、任務難」的真實世界。
  • 工安啟示:監視器畫面天生無標註,自監督把它們變成可用的特徵庫,讓下游工安任務用最少的標註成本落地。

下一篇把「不用標籤」再推一步:如果連「同類」都不必自己定義,直接拿網路上的圖片與文字配對來學呢?CLIP 多模態對齊——讓模型看懂文字與影像的共同語義,直接打字「沒戴安全帽的人」,就能在監視器畫面裡把人一個個撈出來。