作者:Amit Chaudhary
編譯:ronghuaiyang
導(dǎo)讀
視覺(jué)上的自監(jiān)督學(xué)習(xí)方法,結(jié)合聚類(lèi),將無(wú)監(jiān)督轉(zhuǎn)變?yōu)橛斜O(jiān)督。
許多自監(jiān)督方法使用[pretext tasks](https://amitness.com/2020/02/illustrated-selfsupervision -learning/)來(lái)生成代理標(biāo)簽,并將無(wú)監(jiān)督學(xué)習(xí)問(wèn)題轉(zhuǎn)化為有監(jiān)督學(xué)習(xí)的問(wèn)題。一些例子包括旋轉(zhuǎn)預(yù)測(cè),圖像著色,拼圖等。然而,這樣的pretext任務(wù)是依賴(lài)于領(lǐng)域的,需要專(zhuān)業(yè)知識(shí)來(lái)設(shè)計(jì)它們。
DeepCluster是Facebook AI研究的Caron等人提出的一種自監(jiān)督方法,帶來(lái)了一種不同的方法。這種方法不需要特定于領(lǐng)域的知識(shí),可以用于學(xué)習(xí)缺乏注釋數(shù)據(jù)的場(chǎng)景的深層表示。
DeepCluster
DeepCluster結(jié)合了兩部分:無(wú)監(jiān)督聚類(lèi)和深度神經(jīng)網(wǎng)絡(luò)。提出了一種端到端聯(lián)合學(xué)習(xí)深度神經(jīng)網(wǎng)絡(luò)參數(shù)及其表示的聚類(lèi)分配的方法。這些特征被迭代地生成和聚合,最后得到一個(gè)訓(xùn)練過(guò)的模型和標(biāo)簽作為輸出結(jié)果。
Deep Cluster Pipeline
現(xiàn)在讓我們了解一下深度聚類(lèi)的pipleline是如何工作的。
End to End Pipeline of DeepCluster Paper
簡(jiǎn)介:
如上圖所示,將拍攝未標(biāo)記的圖像并對(duì)其應(yīng)用圖像增強(qiáng)。然后,使用AlexNet或vgg16等ConvNet架構(gòu)作為特征提取器。首先,對(duì)ConvNet進(jìn)行隨機(jī)權(quán)值初始化,并在最終的分類(lèi)頭之前從層中取特征向量。然后使用PCA對(duì)特征向量進(jìn)行降維,同時(shí)進(jìn)行白化和L2歸一化。最后,將處理后的特征傳遞到K-means,對(duì)每幅圖像進(jìn)行聚類(lèi)分配。
這些聚類(lèi)分配被用作偽標(biāo)簽,并訓(xùn)練ConvNet來(lái)預(yù)測(cè)這些聚類(lèi)。用交叉熵?fù)p失來(lái)衡量模型的性能。模型訓(xùn)練了100個(gè)epoch,每個(gè)epoch進(jìn)行一次聚類(lèi)的操作。最后,我們可以將學(xué)到的表示用于下游任務(wù)。
手把手的例子
讓我們通過(guò)一個(gè)從輸入數(shù)據(jù)到輸出標(biāo)簽的整個(gè)pipeline的一步步例子來(lái)看看DeepCluster是如何實(shí)際應(yīng)用的:
1. 訓(xùn)練數(shù)據(jù)
我們從ImageNet數(shù)據(jù)集中提取未標(biāo)記的圖像,該數(shù)據(jù)集包括130萬(wàn)張圖像,均勻分布在1000個(gè)類(lèi)中。這些圖像的minibatch為256。
Example of ImageNet datasets for DeepCluster
N幅圖像的訓(xùn)練集在數(shù)學(xué)上可以表示為:
2. 圖像增強(qiáng)
將各種變換應(yīng)用于圖像,以便學(xué)習(xí)到的不受增強(qiáng)的影響的特征。分別在訓(xùn)練模型學(xué)習(xí)表示和將圖像表示發(fā)送到聚類(lèi)算法時(shí)進(jìn)行了兩種不同的增強(qiáng):
Case 1: 聚類(lèi)時(shí)使用的變換
當(dāng)要把模型表示送去進(jìn)行聚類(lèi)時(shí),不使用隨機(jī)增強(qiáng)。圖像簡(jiǎn)單地調(diào)整為256×256,并使用中心剪裁得到224×224的圖像。然后應(yīng)用歸一化。
Augmentations done during clustering in DeepCluster
在PyTorch中,可以這樣實(shí)現(xiàn):
from PIL import Image
import torchvision.transforms as transforms
im = Image.open('dog.png')
t = transforms.Compose([transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])])
aug_im = t(im)
Case 2: 訓(xùn)練模型時(shí)候的變換
當(dāng)模型在圖像和標(biāo)簽上進(jìn)行訓(xùn)練時(shí),我們使用隨機(jī)增強(qiáng)。圖像裁剪為隨機(jī)大小和高寬比,然后調(diào)整為224*224。然后,圖像水平翻轉(zhuǎn)的概率為50%。最后,利用ImageNet均值和方差對(duì)圖像進(jìn)行歸一化。
Sequence of Image Augmentations Used before passing to model
在PyTorch中,可以這樣實(shí)現(xiàn):
from PIL import Image
import torchvision.transforms as transforms
im = Image.open('dog.png')
t = transforms.Compose([transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])])
aug_im = t(im)
Sobel變換
一旦我們得到了歸一化的圖像,我們就把它轉(zhuǎn)換成灰度。然后,我們使用Sobel濾波器增加圖像的局部對(duì)比度。
Sobel Transformation in DeepCluster
下面是改編自作者實(shí)現(xiàn)的簡(jiǎn)化代碼片段,我們可以將它應(yīng)用到上面得到的增強(qiáng)圖像aug_im上。
import torch
import torch.nn as nn
# Fill kernel of Conv2d layer with grayscale kernel
grayscale = nn.Conv2d(3, 1, kernel_size=1, stride=1, padding=0)
grayscale.weight.data.fill_(1.0 / 3.0)
grayscale.bias.data.zero_()
# Fill kernel of Conv2d layer with sobel kernels
sobel = nn.Conv2d(1, 2, kernel_size=3, stride=1, padding=1)
sobel.weight.data[0, 0].copy_(
torch.FloatTensor([[1, 0, -1],
[2, 0, -2],
[1, 0, -1]])
)
sobel.weight.data[1, 0].copy_(
torch.FloatTensor([[1, 2, 1],
[0, 0, 0],
[-1, -2, -1]])
)
sobel.bias.data.zero_()
# Combine the two
combined = nn.Sequential(grayscale, sobel)
# Apply
batch_image = aug_im.unsqueeze(dim=0)
sobel_im = combined(batch_image)
3. 確定聚類(lèi)的數(shù)量(類(lèi)別數(shù))
要進(jìn)行聚類(lèi),我們需要決定聚類(lèi)的數(shù)量。這將是模型將要訓(xùn)練的類(lèi)的數(shù)量。
Impact of number of clusters on DeepCluster model
默認(rèn)情況下,ImageNet有1000個(gè)類(lèi),但是本文使用了10,000個(gè)聚類(lèi),因?yàn)檫@樣可以對(duì)未標(biāo)記的圖像進(jìn)行更細(xì)粒度的分組。例如,如果你以前有一組貓和狗,你增加聚類(lèi),然后可以創(chuàng)建貓和狗品種的分組。
4. 模型結(jié)構(gòu)
本文主要采用AlexNet架構(gòu),由5個(gè)卷積層和3個(gè)全連接層組成。刪除LRN層,使用Batch Normalization。也添加了Dropout。使用的卷積尺寸為2012年比賽所用的:96, 256, 384, 384, 256。
AlexNet Architecture Used in DeepCluster
另外,本文還嘗試用帶batch normalization的vgg16替換AlexNet,以查看對(duì)性能的影響。
5. 生成初始的標(biāo)簽
為了生成用于訓(xùn)練的模型的初始標(biāo)簽,我們使用隨機(jī)權(quán)重初始化AlexNet,并去除最后一個(gè)完全連接的層FC3。我們?cè)趫D像上對(duì)模型進(jìn)行前向傳遞,并在圖像上取來(lái)自模型的第二個(gè)全連接層FC2的特征向量。該特征向量的維數(shù)為4096。
How Feature Vectors are taken from AlexNet for Clustering
對(duì)整個(gè)數(shù)據(jù)集的batch中的所有圖像重復(fù)此過(guò)程。因此,如果我們有N幅圖像,我們將得到一個(gè)圖像特征矩陣[N, 4096]。
The Image-Feature Matrix Generated in DeepCluster
6. 聚類(lèi)
在聚類(lèi)之前,對(duì)圖像特征矩陣進(jìn)行降維處理。
Preprocessing for clustering in DeepCluster
在降維方面,采用主成分分析(PCA)方法,將特征從4096維降至256維,然后進(jìn)行白化。本文使用faiss庫(kù)來(lái)進(jìn)行大規(guī)模操作。Faiss提供了一種有效的PCA實(shí)現(xiàn)方法,可以應(yīng)用于圖像特征矩陣x:
import faiss
# Apply PCA with whitening
mat = faiss.PCAMatrix(d_in=4096, d_out=256, eigen_power=-0.5)
mat.train(x)
x_pca = mat.apply_py(x)
然后,對(duì)PCA后得到的值進(jìn)行L2歸一化處理。
import numpy as np
norm = np.linalg.norm(x_pca, axis=1)
x_l2 = x_pca / norm[:, np.newaxis]
這樣,我們最終得到了N幅圖像的矩陣(N, 256)。現(xiàn)在對(duì)預(yù)處理后的特征進(jìn)行K-means聚類(lèi),得到圖像及其對(duì)應(yīng)的聚類(lèi)。這些聚類(lèi)將充當(dāng)偽標(biāo)簽,模型將在其上進(jìn)行訓(xùn)練。
Complete Pipeline from Image to Clustering in DeepCluster
本文使用Johnson的K-means實(shí)現(xiàn),faiss庫(kù)里有。因?yàn)榫垲?lèi)必須在所有圖像上運(yùn)行,所以它需要花費(fèi)總訓(xùn)練時(shí)間的三分之一。
聚類(lèi)完成后,將創(chuàng)建新的圖像batch,這樣來(lái)自每個(gè)聚類(lèi)的圖像都有相同的被包含的機(jī)會(huì)。對(duì)這些圖像進(jìn)行隨機(jī)增強(qiáng)。
7. 表示學(xué)習(xí)
一旦我們有了圖像和聚類(lèi),我們就像訓(xùn)練常規(guī)的監(jiān)督學(xué)習(xí)一樣訓(xùn)練我們的ConvNet模型。我們使用256的batch size,并使用交叉熵?fù)p失來(lái)比較模型預(yù)測(cè)和ground truth聚類(lèi)標(biāo)簽。模型可以學(xué)習(xí)到有用的表示。
Representation Learning Part of the DeepCluster Pipeline
8. 在模型訓(xùn)練和聚類(lèi)之間切換
這個(gè)模型訓(xùn)練了500個(gè)epochs。聚類(lèi)步驟在每個(gè)epoch開(kāi)始時(shí)運(yùn)行一次,為整個(gè)數(shù)據(jù)集生成偽標(biāo)簽。然后,對(duì)所有batch繼續(xù)使用交叉熵?fù)p失對(duì)卷積神經(jīng)網(wǎng)絡(luò)進(jìn)行常規(guī)訓(xùn)練。本文采用動(dòng)量為0.9、學(xué)習(xí)率為0.05、權(quán)值衰減為10^-5^的SGD優(yōu)化器。使用用Pascal P100 GPU進(jìn)行訓(xùn)練。
DeepCluster的代碼實(shí)現(xiàn)
官方實(shí)現(xiàn):https://github.com/facebookresearch/deepcluster,還有AlexNet和Resnet-50的預(yù)訓(xùn)練權(quán)重:https://github.com/facebookresearch/deepcluster#pre-trained-models。
英文原文:https://amitness.com/2020/04/deepcluster/






