在前面的章節(jié)中,我們討論了如何在只有 60000 張圖像的 Fashion-MNIST 訓(xùn)練數(shù)據(jù)集上訓(xùn)練模型。我們還描述了 ImageNet,這是學(xué)術(shù)界使用最廣泛的大規(guī)模圖像數(shù)據(jù)集,它有超過(guò) 1000 萬(wàn)張圖像和 1000 個(gè)對(duì)象。然而,我們通常遇到的數(shù)據(jù)集的大小介于這兩個(gè)數(shù)據(jù)集之間。
假設(shè)我們要從圖片中識(shí)別出不同類(lèi)型的椅子,然后向用戶(hù)推薦購(gòu)買(mǎi)鏈接。一種可能的方法是首先識(shí)別 100 把普通椅子,為每把椅子拍攝 1000 張不同角度的圖像,然后在收集的圖像數(shù)據(jù)集上訓(xùn)練分類(lèi)模型。雖然這個(gè)椅子數(shù)據(jù)集可能比 Fashion-MNIST 數(shù)據(jù)集大,但示例數(shù)量仍然不到 ImageNet 中的十分之一。這可能會(huì)導(dǎo)致適用于 ImageNet 的復(fù)雜模型在此椅子數(shù)據(jù)集上過(guò)度擬合。此外,由于訓(xùn)練示例數(shù)量有限,訓(xùn)練模型的準(zhǔn)確性可能無(wú)法滿(mǎn)足實(shí)際要求。
為了解決上述問(wèn)題,一個(gè)顯而易見(jiàn)的解決方案是收集更多的數(shù)據(jù)。然而,收集和標(biāo)記數(shù)據(jù)可能會(huì)花費(fèi)大量時(shí)間和金錢(qián)。例如,為了收集 ImageNet 數(shù)據(jù)集,研究人員花費(fèi)了數(shù)百萬(wàn)美元的研究經(jīng)費(fèi)。雖然目前的數(shù)據(jù)采集成本已經(jīng)大幅降低,但這一成本仍然不容忽視。
另一種解決方案是應(yīng)用遷移學(xué)習(xí),將從源數(shù)據(jù)集中學(xué)到的知識(shí)遷移到目標(biāo)數(shù)據(jù)集中。例如,盡管 ImageNet 數(shù)據(jù)集中的大部分圖像與椅子無(wú)關(guān),但在此數(shù)據(jù)集上訓(xùn)練的模型可能會(huì)提取出更一般的圖像特征,這有助于識(shí)別邊緣、紋理、形狀和物體組成。這些相似的特征也可能對(duì)識(shí)別椅子有效。
14.2.1。腳步
在本節(jié)中,我們將介紹遷移學(xué)習(xí)中的一種常用技術(shù):微調(diào)。如圖 14.2.1所示,微調(diào)包括以下四個(gè)步驟:
-
在源數(shù)據(jù)集(例如,ImageNet 數(shù)據(jù)集)上預(yù)訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型,即源模型。
-
創(chuàng)建一個(gè)新的神經(jīng)網(wǎng)絡(luò)模型,即目標(biāo)模型。這將復(fù)制源模型上除輸出層之外的所有模型設(shè)計(jì)及其參數(shù)。我們假設(shè)這些模型參數(shù)包含從源數(shù)據(jù)集中學(xué)到的知識(shí),并且這些知識(shí)也適用于目標(biāo)數(shù)據(jù)集。我們還假設(shè)源模型的輸出層與源數(shù)據(jù)集的標(biāo)簽密切相關(guān);因此它不在目標(biāo)模型中使用。
-
向目標(biāo)模型添加一個(gè)輸出層,其輸出數(shù)量為目標(biāo)數(shù)據(jù)集中的類(lèi)別數(shù)量。然后隨機(jī)初始化該層的模型參數(shù)。
-
在目標(biāo)數(shù)據(jù)集(例如椅子數(shù)據(jù)集)上訓(xùn)練目標(biāo)模型。輸出層將從頭開(kāi)始訓(xùn)練,而所有其他層的參數(shù)將根據(jù)源模型的參數(shù)進(jìn)行微調(diào)。
當(dāng)目標(biāo)數(shù)據(jù)集遠(yuǎn)小于源數(shù)據(jù)集時(shí),微調(diào)有助于提高模型的泛化能力。
14.2.2。熱狗識(shí)別
讓我們通過(guò)一個(gè)具體案例來(lái)演示微調(diào):熱狗識(shí)別。我們將在一個(gè)小型數(shù)據(jù)集上微調(diào) ResNet 模型,該數(shù)據(jù)集是在 ImageNet 數(shù)據(jù)集上預(yù)訓(xùn)練的。這個(gè)小數(shù)據(jù)集包含數(shù)千張有熱狗和沒(méi)有熱狗的圖像。我們將使用微調(diào)模型從圖像中識(shí)別熱狗。
14.2.2.1。讀取數(shù)據(jù)集
我們使用的熱狗數(shù)據(jù)集取自在線圖像。該數(shù)據(jù)集包含 1400 張包含熱狗的正類(lèi)圖像,以及包含其他食物的大量負(fù)類(lèi)圖像。兩個(gè)類(lèi)別的 1000 張圖像用于訓(xùn)練,其余用于測(cè)試。
解壓下載的數(shù)據(jù)集后,我們得到兩個(gè)文件夾 hotdog/train
和hotdog/test
. 這兩個(gè)文件夾都有hotdog
和 not-hotdog
子文件夾,其中任何一個(gè)都包含相應(yīng)類(lèi)別的圖像。
Downloading ../data/hotdog.zip from http://d2l-data.s3-accelerate.amazonaws.com/hotdog.zip...
我們創(chuàng)建兩個(gè)實(shí)例來(lái)分別讀取訓(xùn)練和測(cè)試數(shù)據(jù)集中的所有圖像文件。
前 8 個(gè)正面示例和最后 8 個(gè)負(fù)面圖像如下所示。如您所見(jiàn),圖像的大小和縱橫比各不相同。
hotdogs = [train_imgs[i][0] for i in range(8)]
not_hotdogs = [train_imgs[-i - 1][0] for i in range(8)]
d2l.show_images(hotdogs + not_hotdogs, 2, 8, scale=1.4);
在訓(xùn)練過(guò)程中,我們首先從圖像中裁剪出一個(gè)隨機(jī)大小和隨機(jī)縱橫比的隨機(jī)區(qū)域,然后將這個(gè)區(qū)域縮放到 224×224輸入圖像。在測(cè)試過(guò)程中,我們將圖像的高度和寬度都縮放到 256 像素,然后裁剪一個(gè)中心 224×224區(qū)域作為輸入。此外,對(duì)于三個(gè) RGB(紅色、綠色和藍(lán)色)顏色通道,我們逐通道標(biāo)準(zhǔn)化它們的值。具體來(lái)說(shuō),就是用該通道的每個(gè)值減去該通道的平均值,然后除以該通道的標(biāo)準(zhǔn)差。
# Specify the means and standard deviations of the three RGB channels to
# standardize each channel
normalize = torchvision.transforms.Normalize(
[0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
train_augs = torchvision.transforms.Compose([
torchvision.transforms.RandomResizedCrop(224),
torchvision.transforms.RandomHorizontalFlip(),
torchvision.transforms.ToTensor(),
normalize])
test_augs = torchvision.transforms.Compose([
torchvision.transforms.Resize([256, 256]),
torchvision.transforms.CenterCrop(224),
torchvision.transforms.ToTensor(),
normalize])
# Specify the means and standard deviations of the three RGB channels to
# standardize each channel
normalize = gluon.data.vision.transforms.Normalize(
[0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
train_augs = gluon.data.vision.transforms.Compose([
gluon.data.vision.transforms.RandomResizedCrop(224),
gluon.data.vision.transforms.RandomFlipLeftRight(),
gluon.data.vision.transforms.ToTensor(),
normalize])
test_augs = gluon.data.vision.transforms.Compose([
gluon.data.vision.transforms.Resize(256),
gluon.data.vision.transforms.CenterCrop(224),
gluon.data.vision.transforms.ToTensor(),
normalize])
14.2.2.2。定義和初始化模型
我們使用在 ImageNet 數(shù)據(jù)集上預(yù)訓(xùn)練的 ResNet-18 作為源模型。在這里,我們指定pretrained=True
自動(dòng)下載預(yù)訓(xùn)練模型參數(shù)。如果是第一次使用這個(gè)模型,需要連接互聯(lián)網(wǎng)才能下載。
預(yù)訓(xùn)練源模型實(shí)例包含多個(gè)特征層和一個(gè)輸出層fc
。這種劃分的主要目的是為了便于微調(diào)除輸出層之外的所有層的模型參數(shù)。fc
下面給出源模型的成員變量。
Linear(in_features=512, out_features=1000, bias=True)
The pretrained source model instance contains two member variables: features
and output
. The former contains all layers of the model except the output layer, and the latter is the output layer of the model. The main purpose of this division is to facilitate the fine-tuning of model parameters of all layers but the output layer. The member variable output
of source model is shown below.
Dense(512 -> 1000, linear)
作為全連接層,它將 ResNet 最終的全局平均池化輸出轉(zhuǎn)化為 ImageNet 數(shù)據(jù)集的 1000 類(lèi)輸出。然后我們構(gòu)建一個(gè)新的神經(jīng)網(wǎng)絡(luò)作為目標(biāo)模型。它的定義方式與預(yù)訓(xùn)練源模型相同,不同之處在于它在最后一層的輸出數(shù)量設(shè)置為目標(biāo)數(shù)據(jù)集中的類(lèi)數(shù)(而不是 1000)。
在下面的代碼中,目標(biāo)模型實(shí)例的輸出層之前的模型參數(shù)finetune_net
被初始化為源模型中相應(yīng)層的模型參數(shù)。由于這些模型參數(shù)是通過(guò)在 ImageNet 上進(jìn)行預(yù)訓(xùn)練獲得的,因此它們是有效的。因此,我們只能使用較小的學(xué)習(xí)率來(lái) 微調(diào)此類(lèi)預(yù)訓(xùn)練參數(shù)。相比之下,輸出層中的模型參數(shù)是隨機(jī)初始化的,通常需要更大的學(xué)習(xí)率才能從頭開(kāi)始學(xué)習(xí)。讓基礎(chǔ)學(xué)習(xí)率成為η, 學(xué)習(xí)率10η將用于迭代輸出層中的模型參數(shù)。
評(píng)論
查看更多