日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

度量学习和pytorch-metric-learning的使用

發布時間:2025/3/8 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 度量学习和pytorch-metric-learning的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??度量學習是學習一種特征空間的映射,把特征映射到具有度量屬性的空間中,所謂度量屬性是指在某種度量距離(可以是歐氏距離、余弦相似性等)下類內距離更小,類間距離更大。有了這種屬性之后,就可以僅根據特征間的距離來判斷樣本是否屬于同一類,常用在少樣本學習任務中,解決由于樣本數量少而無法或不足以建立從特征到類別的參數化映射的問題。有一個開源的度量學習庫pytorch-metric-learning,集成了當前常用的各種度量學習方法,是一個非常好用的工具。
??度量學習作為一個大領域,網上有不少介紹的文章,pytorch-metric-learning庫的官方文檔也有比較詳細的說明和demo,所以本文不打算再對它們做細致嚴謹的入門級介紹,而是記錄我在學習過程中的一些思考和觀點,以及代碼的便捷使用,歡迎討論。

1 度量學習的主要原理

??如前所述,度量學習的目的是把特征約束到具有度量屬性的空間中。
??首先什么是特征?通常我們認為,深度學習網絡中(如ResNet50),前面的卷積部分作用是逐層深入的提取越來越高級的特征,最后的全連接層的作用則是建立特征到具體類別間的規則關系。那么我們度量學習要處理的特征當然應該選擇經卷積層完全處理完畢,輸入給全連接網絡的這層特征,如果這層特征的維度太高而導致運算量太大(如ResNet50的卷積層最后輸出有2048通道),也可以先用全連接層降維。我們把這層特征提取出來,通常稱為嵌入特征embbeding features。
??然后是如何約束?神經網絡通過加入損失函數作為約束條件,以類別標簽作為監督信息,使用監督學習的方法訓練網絡參數,使網絡輸出的嵌入特征逐漸滿足約束條件。所謂約束條件就是指類內距離小、類間距離大,那么損失函數就是要滿足這兩個目標,但具體設計起來仍有很多技術在里面,主要是怎么讓訓練收斂更快、更穩定,收斂的結果更好。

2 幾種損失函數

2.1 Contrastive Loss


??只考慮兩兩之間的類別和距離。注意其中加入margin的思路(即max(0,margin-loss)的方式),我覺得這個思路很有意思,值得學習。我理解加入margin的目的是這樣的:因為我們優化類間距離的目的是越大越好,而通常損失函數在梯度下降算法中是趨向于越來越小的,所以必須讓損失函數也變成一個減函數,如果我們直接取一個負號,則會讓損失函數變成一個負的特別大的數,這通常會導致訓練不穩定。而且我們也不需要類間距離非常大,只要大于一定值能夠和類內距離明顯區分就可以了,所以這里加入一個margin,讓目標函數限定到(0,margin)區間內,避免訓練不穩定。在網絡設計中我們經常也會遇到想讓一個目標函數越來越大的情況,我覺得可以嘗試這種取負號再加margin的方案,當然另一種思路是取倒數,即1/loss,我沒對比過哪個更有效,以后有機會可以試一試。

2.2 Triplet Loss


??考慮三元組,錨樣本、正樣本和負樣本之間的互相距離。由于每次同時考慮了正樣本對和負樣本對的距離都滿足約束關系,訓練效率比Contrastive loss要高。注意Triplet loss的目的是讓類間距離比類內距離更大,對應的也是一個越大越好的目標函數,這里也使用了取負號再加margin并截斷負值的思路把它變成一個區間減函數形式的損失函數。

2.3 更多損失函數

??在Triplet loss之后,又發展出來了各種各樣更多的損失函數,如N-pair Loss, ranklist loss, multisimilarity loss ,cirlce loss等,總的趨勢是考慮更多的對之間的距離關系,并考慮各樣本學習的難易不同,提高難例的權重。circle loss還考慮了類別標簽的使用,也就是綜合了分類損失。

2.4 在pytorch-metric-learning中使用各種損失函數

??使用pip install pytorch-metric-learning安裝該庫,支持的多種損失函數可查閱pytorch-metric-learning的官方文檔。如果對各種損失函數不太了解,直接使用Circle loss就好了。

from pytorch_metric_learning import losses loss_func = losses.CircleLoss() for data, labels in train_loader:embeddings,_ = model(data)loss = loss_func(embeddings, labels)

??注意默認的度量距離使用余弦相似性,如不特殊指定的話,也應在推理階段使用余弦相似性對生成的嵌入特征進行處理。

3 難例挖掘方法

??我們可以看到,在當前度量學習的損失函數設計中都是含有margin的,那么網絡在學習的時候對于易例,損失函數已經能夠達到margin的程度,梯度會變成0,就不會再對網絡有任何訓練的作用了,只有那些難例,梯度較大,才會對網絡起到較大的訓練作用,所以為了提高訓練效率,需要只把難例加入訓練。pytorch-metric-learning庫提供的挖掘方法在miners文件中,有很多,具體可以查看官方文檔。我在未經充分試驗的情況下發現MultiSimilarityMiner效果不錯,如果對各種挖掘方法不是很了解,可以先用這個。加入之后的訓練方法如下:

from pytorch_metric_learning import losses, miners loss_func = losses.CircleLoss() mining_func = miners.MultiSimilarityMiner() for data, labels in train_loader:embeddings,_ = model(data)hard_tuples = mining_func(embeddings, labels)loss = loss_func(embeddings, labels, hard_tuples)

4 采樣器設計

??如果訓練樣本的類別較多的時候,隨機采樣的話可能在一個mini batch內遇不到幾個正樣本對,例如有100類,而batch size只有64。而損失函數設計都是考慮到正樣本對的,這會導致訓練效果受很大影響,所以要調整采樣器,保證一個mini batch內有一定比例的正樣本對,比如可以指定每一類都固定采樣m個樣本,通常m=4效果較好,這樣batch size = 64時,每次能夠采樣16類,每類4個樣本。pytorch-metric-learning庫中集成了一個采樣器MPerClassSampler,它對torch.utils.data.sampler修改而來,調用方法如下:

from pytorch_metric_learning import samplers sampler = samplers.MPerClassSampler(labels, m=4,length_before_new_iter=len(train_dataset)) train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size,sampler=sampler, **kwargs)

??還有其他一些采樣器可參考官方文檔,如果還需要給采樣器加入更多的功能,比如在MPerClassSampler的基礎上還想保證訓練的時候各類別平衡采樣以解決長尾問題,可以再魔改一下官方MPerClassSampler代碼文件,也不難。

5 度量-分類聯合訓練

??度量學習只考慮一對數據是否是同類或異類,并不考慮每個數據具體是哪一類,顯然它沒有充分利用標簽提供的信息。所以如果只用度量學習的損失函數進行訓練,網絡提取的特征不充分,如果同時加入全連接層構成的分類器,并使用交叉熵損失接受標簽的分類監督信息,可以提高網絡的特征提取能力。(circle loss可以部分彌補這一點,但仍沒有加入分類聯合訓練效果好)

from pytorch import nn from pytorch_metric_learning import losses, miners loss_func = losses.CircleLoss() mining_func = miners.MultiSimilarityMiner() criterion = nn.CrossEntropyLoss() for data, labels in train_loader:embeddings,out = model(data)hard_tuples = mining_func(embeddings, labels)loss1 = loss_func(embeddings, labels, hard_tuples)loss2 = criterion(out,labels)loss = 0.1*loss1 + loss2

??代碼中的embeddings指嵌入層特征,out指網絡最后和類別數同維度的輸出。

6 度量學習的思考

1,為什么度量學習能夠泛化?它有多強的泛化能力?
??度量學習常被用在少樣本學習領域,因為它在已知類別上訓練完成的度量空間映射能力同樣可以在未知類別上使用。這是因為度量學習通過同類和異類的對比,把數據集中共性特征放大,個性特征抑制,而分類學習更關注對每類的個性特征,所以相比度量學習有更好的泛化能力。而如果測試集和訓練集不僅存在類別差異,還存在特征分布差異(域偏差)的時候,度量學習也不能夠泛化。
2,度量學習在推理階段僅使用樣本間的距離進行判斷,顯然浪費了特征中蘊含的很多信息量,并不是一種最優方案。
??更理想的方案應該是并不對特征壓縮轉換為單維度的標量(如距離),仍使用特征豐富的全維度信息進行推理。比如可以使用一個fc層或多fc層的MLP網絡來實現對特征到某個單類的規則映射,這個fc層的參數不使用梯度下降訓練法得到(只有少樣本也很難訓練),而是解方程得到一個最小二乘解,這個方法也許會有更好的效果,先放到這里,有待后續研究。

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的度量学习和pytorch-metric-learning的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。