習(xí)實(shí)戰(zhàn))
1. 項(xiàng)目概述為什么VGG16依然是理解CNN的“必修課”如果你剛開(kāi)始接觸計(jì)算機(jī)視覺(jué)或者深度學(xué)習(xí)在學(xué)完卷積神經(jīng)網(wǎng)絡(luò)CNN的基礎(chǔ)概念后第一個(gè)讓你感到“震撼”的經(jīng)典網(wǎng)絡(luò)很可能就是VGG16。這個(gè)名字在2014年ImageNet競(jìng)賽中橫空出世雖然冠軍被GoogLeNetInception v1摘得但VGGNet憑借其極致的簡(jiǎn)潔性和強(qiáng)大的性能成為了后續(xù)無(wú)數(shù)研究和工程項(xiàng)目的基石模型。今天我們不談那些花里胡哨的最新變體就扎扎實(shí)實(shí)地把VGG16拆開(kāi)揉碎了講清楚。你會(huì)發(fā)現(xiàn)這個(gè)看似“古老”的網(wǎng)絡(luò)其設(shè)計(jì)思想至今仍在發(fā)光發(fā)熱是理解現(xiàn)代深度卷積網(wǎng)絡(luò)不可或缺的一環(huán)。它就像編程里的“Hello World”或者算法里的“快速排序”基礎(chǔ)、經(jīng)典且蘊(yùn)含著最核心的設(shè)計(jì)哲學(xué)。VGG16到底解決了什么問(wèn)題在它之前AlexNet證明了深度卷積網(wǎng)絡(luò)的有效性但網(wǎng)絡(luò)結(jié)構(gòu)還比較隨意和復(fù)雜。VGG16的核心貢獻(xiàn)在于它通過(guò)一系列嚴(yán)謹(jǐn)?shù)摹⒖蓮?fù)現(xiàn)的實(shí)驗(yàn)向業(yè)界證明了網(wǎng)絡(luò)的深度Depth對(duì)于提升模型性能至關(guān)重要。更關(guān)鍵的是它提出了一種極其簡(jiǎn)單、優(yōu)雅的構(gòu)建塊連續(xù)使用多個(gè)3x3的小卷積核來(lái)替代大卷積核如5x5 7x7。這個(gè)設(shè)計(jì)不僅減少了參數(shù)數(shù)量還增加了網(wǎng)絡(luò)的非線(xiàn)性能力使得構(gòu)建非常深的網(wǎng)絡(luò)成為可能。對(duì)于學(xué)習(xí)者而言VGG16結(jié)構(gòu)規(guī)整、層次清晰是學(xué)習(xí)CNN前向傳播、反向傳播、特征圖尺寸計(jì)算、參數(shù)統(tǒng)計(jì)的絕佳樣板。對(duì)于實(shí)踐者其預(yù)訓(xùn)練模型至今仍是許多視覺(jué)任務(wù)如圖像分類(lèi)、目標(biāo)檢測(cè)、風(fēng)格遷移優(yōu)秀的特征提取器起點(diǎn)。2. VGG16核心設(shè)計(jì)思想深度拆解2.1 “小卷積核堆疊”的魔力為何3x3是黃金尺寸VGG16最標(biāo)志性的設(shè)計(jì)就是通篇使用3x3的卷積核。這背后有深刻的數(shù)學(xué)和工程考量絕不是隨意選擇。首先從感受野Receptive Field的角度看。兩個(gè)串聯(lián)的3x3卷積層其有效感受野是5x5。因?yàn)榈谝粚?x3卷積的輸出特征圖上每個(gè)點(diǎn)對(duì)應(yīng)了輸入圖像上3x3的區(qū)域第二層3x3卷積再對(duì)這個(gè)特征圖操作其每個(gè)點(diǎn)又“看到”了第一層特征圖上的3x3區(qū)域這相當(dāng)于看到了原始輸入圖像上5x5的區(qū)域。同理三個(gè)3x3卷積堆疊感受野等價(jià)于一個(gè)7x7的卷積。這樣做的好處是什么參數(shù)更少這是最直觀的優(yōu)勢(shì)。一個(gè)7x7卷積核的參數(shù)數(shù)量是 C × C‘ × 7 × 7假設(shè)輸入輸出通道數(shù)分別為C和C‘。而三個(gè)3x3卷積核的參數(shù)總數(shù)是 C × C1 × 3 × 3 C1 × C2 × 3 × 3 C2 × C‘ × 3 × 3。通常中間通道數(shù)C1, C2會(huì)小于或等于C‘在VGG中它們經(jīng)常翻倍。即使中間通道數(shù)翻倍計(jì)算后也會(huì)發(fā)現(xiàn)三個(gè)3x3的參數(shù)總量仍然顯著少于一個(gè)7x7。更少的參數(shù)意味著更低的模型復(fù)雜度更不容易過(guò)擬合也減少了計(jì)算量。非線(xiàn)性更強(qiáng)每個(gè)卷積層后面都緊跟著一個(gè)ReLU激活函數(shù)。一個(gè)7x7卷積層只經(jīng)過(guò)一次非線(xiàn)性變換ReLU。而三個(gè)3x3卷積層堆疊經(jīng)歷了三次ReLU激活引入了更多的非線(xiàn)性變換使得模型的判別能力更強(qiáng)能夠?qū)W習(xí)更復(fù)雜的特征模式。特征提取更精細(xì)小卷積核可以捕捉更局部、更精細(xì)的特征如邊緣、角點(diǎn)通過(guò)多層堆疊這些局部特征被逐步組合成更高級(jí)的、全局性的語(yǔ)義特征如眼睛、輪子。這種由細(xì)到粗的層次化特征學(xué)習(xí)是深度學(xué)習(xí)成功的關(guān)鍵。注意在實(shí)際計(jì)算感受野時(shí)還需要考慮步長(zhǎng)Stride和填充Padding。VGG中卷積步長(zhǎng)固定為1并使用了1像素的填充padding1這保證了卷積操作不改變特征圖的空間尺寸高和寬只有池化層才會(huì)下采樣。這個(gè)設(shè)計(jì)使得網(wǎng)絡(luò)前向傳播時(shí)尺寸變化非常規(guī)律易于理解和調(diào)試。2.2 規(guī)整的模塊化設(shè)計(jì)像搭積木一樣構(gòu)建深度網(wǎng)絡(luò)VGG16的另一個(gè)偉大之處在于其模塊化。整個(gè)網(wǎng)絡(luò)可以被清晰地劃分為幾個(gè)“階段”Stage每個(gè)階段由若干連續(xù)的卷積層和一個(gè)最大池化層構(gòu)成。階段一二專(zhuān)注于提取低級(jí)特征如邊緣、紋理、顏色。使用2個(gè)卷積層后接池化。階段三開(kāi)始組合低級(jí)特征形成更復(fù)雜的紋理和圖案。使用3個(gè)卷積層后接池化。階段四五致力于提取高級(jí)語(yǔ)義特征如物體的部件或整體。分別使用3個(gè)卷積層后接池化。每個(gè)階段內(nèi)部卷積層的通道數(shù)即濾波器數(shù)量是固定的并且在進(jìn)入下一個(gè)階段時(shí)通道數(shù)通常會(huì)翻倍從64到128再到256最后到512。這種設(shè)計(jì)非常符合直覺(jué)隨著網(wǎng)絡(luò)加深、特征圖空間尺寸減小池化導(dǎo)致我們?cè)黾油ǖ罃?shù)來(lái)保留和編碼更多的信息。這種“空間信息減少通道信息增加”的模式后來(lái)成為了深度CNN設(shè)計(jì)的標(biāo)準(zhǔn)范式。這種規(guī)整的結(jié)構(gòu)帶來(lái)了巨大的好處代碼實(shí)現(xiàn)極其簡(jiǎn)潔。你幾乎可以用一個(gè)循環(huán)來(lái)構(gòu)建整個(gè)卷積部分。這也使得VGG16非常易于修改和擴(kuò)展例如你可以輕松地嘗試VGG19在最后三個(gè)卷積塊各多加一個(gè)卷積層或者創(chuàng)建自己的變體。2.3 全連接層與分類(lèi)頭從特征到?jīng)Q策經(jīng)過(guò)五個(gè)階段的卷積和池化后原始224x224x3的輸入圖像被轉(zhuǎn)換為7x7x512的特征圖。此時(shí)空間信息已經(jīng)被高度抽象和壓縮每個(gè)7x7的網(wǎng)格都包含了原圖某一區(qū)域的高級(jí)語(yǔ)義信息。接下來(lái)是三個(gè)全連接層。第一個(gè)全連接層將7x7x51225088個(gè)元素“展平”為一個(gè)一維向量然后連接到4096個(gè)神經(jīng)元。這一步是信息的高度壓縮和整合將空間維度的特征全部融合。第二個(gè)全連接層也是4096維。最后一個(gè)全連接層輸出1000維對(duì)應(yīng)ImageNet數(shù)據(jù)集的1000個(gè)類(lèi)別并通過(guò)Softmax函數(shù)轉(zhuǎn)換為概率分布。這里有一個(gè)非常重要的實(shí)操細(xì)節(jié)VGG16的全連接層參數(shù)占據(jù)了整個(gè)網(wǎng)絡(luò)參數(shù)的絕大部分約90%。這也是它被詬病“參數(shù)冗余”的主要原因。后來(lái)的網(wǎng)絡(luò)如GoogLeNet、ResNet紛紛采用全局平均池化Global Average Pooling來(lái)替代全連接層極大地減少了參數(shù)數(shù)量。但在當(dāng)時(shí)全連接層被認(rèn)為是實(shí)現(xiàn)高性能分類(lèi)所必需的。實(shí)操心得當(dāng)你使用預(yù)訓(xùn)練的VGG16作為其他任務(wù)如目標(biāo)檢測(cè)的特征提取器時(shí)通常會(huì)“砍掉”最后的全連接層分類(lèi)頭只保留卷積部分常稱(chēng)為“骨干網(wǎng)絡(luò)”或“Backbone”。卷積部分提取的通用特征具有很強(qiáng)的遷移能力。3. VGG16網(wǎng)絡(luò)結(jié)構(gòu)逐層解析與參數(shù)計(jì)算讓我們以PyTorch為例親手“搭建”一個(gè)VGG16并詳細(xì)計(jì)算每一層的輸出尺寸和參數(shù)量。這是徹底理解它的最佳方式。3.1 輸入與預(yù)處理VGG16的官方輸入尺寸是224x224像素的RGB三通道圖像。在輸入網(wǎng)絡(luò)前通常需要進(jìn)行標(biāo)準(zhǔn)化處理即減去均值ImageNet數(shù)據(jù)集的平均像素值例如[0.485, 0.456, 0.406]并除以標(biāo)準(zhǔn)差[0.229, 0.224, 0.225]。這一步在PyTorch的torchvision.models.vgg16預(yù)訓(xùn)練模型中已經(jīng)內(nèi)置。import torch import torch.nn as nn # 假設(shè)我們有一個(gè)批處理大小為4的輸入 batch_size 4 input_tensor torch.randn(batch_size, 3, 224, 224) # (N, C, H, W) print(f輸入尺寸: {input_tensor.shape})3.2 卷積與池化層詳解我們按照VGG16的配置表來(lái)構(gòu)建網(wǎng)絡(luò)。記住關(guān)鍵規(guī)則所有卷積層kernel_size3, stride1, padding1所有池化層kernel_size2, stride2。第一階段 (通道數(shù): 64)Conv2d(3, 64, kernel_size3, padding1) - ReLU輸入:(4, 3, 224, 224)輸出:(4, 64, 224, 224)(padding1 保持尺寸)參數(shù)量:(3 * 64 * 3 * 3) 64(1728) 641792(權(quán)重 偏置)Conv2d(64, 64, kernel_size3, padding1) - ReLU輸入/輸出:(4, 64, 224, 224)參數(shù)量:(64 * 64 * 3 * 3) 64(36864) 6436928MaxPool2d(kernel_size2, stride2)輸入:(4, 64, 224, 224)輸出:(4, 64, 112, 112)(尺寸減半)第二階段 (通道數(shù): 128)4. Conv2d(64, 128, 3, padding1) - ReLU - 輸入:(4, 64, 112, 112)- 輸出:(4, 128, 112, 112)- 參數(shù)量:(64 * 128 * 3 * 3) 128(73728) 128738565. Conv2d(128, 128, 3, padding1) - ReLU - 輸入/輸出:(4, 128, 112, 112)- 參數(shù)量:(128 * 128 * 3 * 3) 128(147456) 1281475846. MaxPool2d(2,2) - 輸出:(4, 128, 56, 56)第三階段 (通道數(shù): 256)7. Conv2d(128, 256, 3, padding1) - ReLU - 參數(shù)量:(128 * 256 * 3 * 3) 256(294912) 2562951688. Conv2d(256, 256, 3, padding1) - ReLU - 參數(shù)量:(256 * 256 * 3 * 3) 256(589824) 2565900809. Conv2d(256, 256, 3, padding1) - ReLU - 參數(shù)量: 同上59008010. MaxPool2d(2,2) - 輸出:(4, 256, 28, 28)第四階段 (通道數(shù): 512)11. Conv2d(256, 512, 3, padding1) - ReLU - 參數(shù)量:(256 * 512 * 3 * 3) 512(1179648) 512118016012. Conv2d(512, 512, 3, padding1) - ReLU - 參數(shù)量:(512 * 512 * 3 * 3) 512(2359296) 512235980813. Conv2d(512, 512, 3, padding1) - ReLU - 參數(shù)量: 同上235980814. MaxPool2d(2,2) - 輸出:(4, 512, 14, 14)第五階段 (通道數(shù): 512)15. Conv2d(512, 512, 3, padding1) - ReLU - 參數(shù)量:235980816. Conv2d(512, 512, 3, padding1) - ReLU - 參數(shù)量:235980817. Conv2d(512, 512, 3, padding1) - ReLU - 參數(shù)量:235980818. MaxPool2d(2,2) -最終卷積部分輸出:(4, 512, 7, 7)至此我們得到了一個(gè)7x7x512的特征圖。你可以手動(dòng)驗(yàn)證一下224 - 112 - 56 - 28 - 14 - 7正好經(jīng)過(guò)5次池化每次/2。3.3 全連接層參數(shù)爆炸與展平操作接下來(lái)進(jìn)入全連接層。首先需要將(4, 512, 7, 7)的特征圖“展平”成一維向量。# 展平操作 flatten_features 512 * 7 * 7 # 25088 # 假設(shè)我們有一個(gè)樣本展平后形狀為 (25088,)第一全連接層 (FC1)nn.Linear(25088, 4096)參數(shù)量:25088 * 4096 4096102,764,544 4096102,768,640輸出:(4, 4096)第二全連接層 (FC2)nn.Linear(4096, 4096)參數(shù)量:4096 * 4096 409616,781,312 409616,785,408輸出:(4, 4096)第三全連接層 (FC3 / 分類(lèi)頭)nn.Linear(4096, 1000)(ImageNet 1000類(lèi))參數(shù)量:4096 * 1000 10004,096,000 10004,097,000輸出:(4, 1000)總參數(shù)量估算卷積層參數(shù)約 1千4百萬(wàn) (14M)全連接層參數(shù)約 1億2千萬(wàn) (120M)總計(jì): 約 1億3千8百萬(wàn) (138M) 參數(shù)。可以看到三個(gè)全連接層占據(jù)了絕大部分參數(shù)約90%。這也是為什么后來(lái)的網(wǎng)絡(luò)架構(gòu)迫切需要進(jìn)行“全連接層革命”。4. VGG16的實(shí)戰(zhàn)應(yīng)用與遷移學(xué)習(xí)理解了結(jié)構(gòu)我們來(lái)看看VGG16在今天還能怎么用。直接從頭訓(xùn)練一個(gè)VGG16在ImageNet上達(dá)到SOTAState-of-the-Art已經(jīng)不現(xiàn)實(shí)了但它預(yù)訓(xùn)練的權(quán)重依然是寶貴的財(cái)富。4.1 使用預(yù)訓(xùn)練模型進(jìn)行圖像分類(lèi)在PyTorch中使用預(yù)訓(xùn)練的VGG16進(jìn)行圖像分類(lèi)只需幾行代碼import torch from torchvision import models, transforms from PIL import Image # 1. 加載預(yù)訓(xùn)練模型 (權(quán)重在首次下載時(shí)會(huì)自動(dòng)緩存) model models.vgg16(pretrainedTrue) model.eval() # 設(shè)置為評(píng)估模式 # 2. 定義圖像預(yù)處理流程 (必須與訓(xùn)練時(shí)一致) preprocess 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]), ]) # 3. 加載并預(yù)處理圖像 img Image.open(your_image.jpg) img_t preprocess(img) batch_t torch.unsqueeze(img_t, 0) # 增加一個(gè)批次維度 - (1, 3, 224, 224) # 4. 前向傳播 with torch.no_grad(): # 禁用梯度計(jì)算節(jié)省內(nèi)存和計(jì)算 output model(batch_t) # 5. 解讀結(jié)果 # 輸出是1000個(gè)類(lèi)別的logits需要取概率最高的 _, index torch.max(output, 1) percentage torch.nn.functional.softmax(output, dim1)[0] * 100 # 加載ImageNet標(biāo)簽 (需要額外下載) # ... 此處可以加載標(biāo)簽文件將index轉(zhuǎn)換為類(lèi)別名 print(f預(yù)測(cè)類(lèi)別索引: {index.item()}, 置信度: {percentage[index].item():.2f}%)4.2 作為特征提取器遷移學(xué)習(xí)的核心這是VGG16目前最廣泛的應(yīng)用。我們凍結(jié)其卷積層的權(quán)重只訓(xùn)練自己新添加的分類(lèi)層。import torch.nn as nn # 加載預(yù)訓(xùn)練模型 model models.vgg16(pretrainedTrue) # 凍結(jié)所有卷積層的參數(shù)使其在訓(xùn)練中不更新 for param in model.features.parameters(): param.requires_grad False # 替換最后的分類(lèi)器 (全連接層部分) # 假設(shè)我們的新任務(wù)只有10個(gè)類(lèi)別 num_ftrs model.classifier[6].in_features # 獲取原最后一層輸入特征數(shù) (4096) # 方式一只替換最后一層 model.classifier[6] nn.Linear(num_ftrs, 10) # 方式二更常見(jiàn)重新定義整個(gè)分類(lèi)器有時(shí)會(huì)保留一部分原全連接層 # model.classifier nn.Sequential( # nn.Linear(512 * 7 * 7, 4096), # nn.ReLU(True), # nn.Dropout(p0.5), # nn.Linear(4096, 4096), # nn.ReLU(True), # nn.Dropout(p0.5), # nn.Linear(4096, 10), # 新類(lèi)別數(shù) # ) # 現(xiàn)在只有 model.classifier[6] (或我們新定義的層) 的參數(shù) requires_gradTrue # 接下來(lái)可以用自己的數(shù)據(jù)集進(jìn)行訓(xùn)練學(xué)習(xí)率可以設(shè)得比從頭訓(xùn)練大一些注意事項(xiàng)使用預(yù)訓(xùn)練模型時(shí)數(shù)據(jù)預(yù)處理尤其是歸一化的均值和標(biāo)準(zhǔn)差必須與模型訓(xùn)練時(shí)保持一致通常是ImageNet的統(tǒng)計(jì)值。不一致的預(yù)處理會(huì)導(dǎo)致特征分布差異嚴(yán)重降低模型性能。4.3 在其他視覺(jué)任務(wù)中的應(yīng)用VGG16的卷積部分作為一個(gè)強(qiáng)大的“通用視覺(jué)特征提取器”被嵌入到更復(fù)雜的架構(gòu)中目標(biāo)檢測(cè)Faster R-CNN、SSD等經(jīng)典檢測(cè)器的早期版本常使用VGG16作為骨干網(wǎng)絡(luò)從輸入圖像中提取特征圖供后續(xù)的區(qū)域提議網(wǎng)絡(luò)RPN和檢測(cè)頭使用。語(yǔ)義分割FCN全卷積網(wǎng)絡(luò)將VGG16的全連接層轉(zhuǎn)換為卷積層使其可以接受任意尺寸的輸入并對(duì)每個(gè)像素進(jìn)行分類(lèi)。風(fēng)格遷移著名的Neural Style Transfer算法利用VGG16中間層的特征來(lái)分別表征內(nèi)容圖像的內(nèi)容和風(fēng)格圖像的風(fēng)格通過(guò)優(yōu)化使生成圖像在內(nèi)容上接近內(nèi)容圖在風(fēng)格上接近風(fēng)格圖。5. VGG16的局限性、常見(jiàn)問(wèn)題與優(yōu)化策略盡管經(jīng)典VGG16也有其明顯的時(shí)代局限性。了解這些能幫助我們?cè)诤线m的場(chǎng)景使用它并理解后續(xù)網(wǎng)絡(luò)改進(jìn)的動(dòng)機(jī)。5.1 主要局限性分析參數(shù)量巨大計(jì)算成本高1.38億參數(shù)其中全連接層占了絕大部分。這導(dǎo)致模型文件大超過(guò)500MB推理速度慢內(nèi)存占用高不適合移動(dòng)端或?qū)崟r(shí)應(yīng)用。訓(xùn)練較困難由于深度和參數(shù)量VGG16需要大量的數(shù)據(jù)和較長(zhǎng)的訓(xùn)練時(shí)間才能收斂。雖然現(xiàn)在有預(yù)訓(xùn)練模型但在大數(shù)據(jù)集上從頭訓(xùn)練依然不經(jīng)濟(jì)。梯度消失/爆炸風(fēng)險(xiǎn)雖然使用了ReLU緩解了梯度消失問(wèn)題但16層的深度加上激活函數(shù)和池化在訓(xùn)練初期仍可能面臨梯度不穩(wěn)定問(wèn)題。這也是后續(xù)ResNet引入殘差連接的主要原因。全連接層導(dǎo)致的輸入尺寸固定網(wǎng)絡(luò)開(kāi)頭的全連接層要求輸入必須是固定尺寸224x224這限制了其處理可變尺寸圖像的能力。后來(lái)的網(wǎng)絡(luò)多用全局平均池化或全卷積結(jié)構(gòu)解決。5.2 訓(xùn)練與使用中的常見(jiàn)問(wèn)題問(wèn)題1內(nèi)存不足OOM現(xiàn)象在訓(xùn)練或前向傳播時(shí)出現(xiàn)CUDA out of memory錯(cuò)誤。排查與解決減小批次大小Batch Size這是最直接有效的方法。將batch size從32降到16或8。使用梯度累積Gradient Accumulation如果受限于顯存只能使用很小的batch size可以通過(guò)多次前向傳播累積梯度再一次性更新參數(shù)模擬大batch size的效果。檢查輸入尺寸確保輸入圖片確實(shí)是224x224沒(méi)有因?yàn)閿?shù)據(jù)加載錯(cuò)誤而變大。使用混合精度訓(xùn)練AMP利用PyTorch的自動(dòng)混合精度工具可以顯著減少顯存占用并加速訓(xùn)練。釋放緩存在PyTorch中可以使用torch.cuda.empty_cache()嘗試釋放未使用的顯存。問(wèn)題2過(guò)擬合Overfitting現(xiàn)象訓(xùn)練集損失持續(xù)下降但驗(yàn)證集損失早早就停止下降甚至開(kāi)始上升。排查與解決利用預(yù)訓(xùn)練權(quán)重對(duì)于大多數(shù)任務(wù)請(qǐng)務(wù)必使用在ImageNet上預(yù)訓(xùn)練的權(quán)重進(jìn)行微調(diào)而不是從頭訓(xùn)練。數(shù)據(jù)增強(qiáng)Data Augmentation對(duì)訓(xùn)練圖像進(jìn)行隨機(jī)裁剪、翻轉(zhuǎn)、旋轉(zhuǎn)、顏色抖動(dòng)等增加數(shù)據(jù)多樣性。這是防止過(guò)擬合最強(qiáng)大的工具之一。正則化技術(shù)DropoutVGG16原論文就在全連接層后使用了Dropoutp0.5。在微調(diào)時(shí)可以適當(dāng)保留或調(diào)整Dropout率。權(quán)重衰減Weight Decay/L2正則化在優(yōu)化器如AdamW中設(shè)置一個(gè)較小的權(quán)重衰減系數(shù)如1e-4。早停Early Stopping監(jiān)控驗(yàn)證集性能當(dāng)其在連續(xù)多個(gè)epoch不再提升時(shí)停止訓(xùn)練。問(wèn)題3微調(diào)時(shí)模型不收斂或性能差現(xiàn)象損失值震蕩不降或準(zhǔn)確率遠(yuǎn)低于預(yù)期。排查與解決學(xué)習(xí)率設(shè)置不當(dāng)這是最常見(jiàn)的原因。對(duì)于微調(diào)初始學(xué)習(xí)率不宜過(guò)大。通常的做法是分類(lèi)頭新加層使用較大的學(xué)習(xí)率如1e-3骨干網(wǎng)絡(luò)預(yù)訓(xùn)練部分使用較小的學(xué)習(xí)率如1e-4或1e-5。可以使用torch.optim中的param_groups為不同部分設(shè)置不同的學(xué)習(xí)率。數(shù)據(jù)預(yù)處理錯(cuò)誤反復(fù)檢查確保你的預(yù)處理 resize, crop, normalize 的均值和標(biāo)準(zhǔn)差與預(yù)訓(xùn)練模型完全一致。標(biāo)簽錯(cuò)誤檢查你的數(shù)據(jù)集標(biāo)簽是否正確特別是類(lèi)別編號(hào)是否從0開(kāi)始連續(xù)。凍結(jié)了不該凍結(jié)的層對(duì)于與ImageNet差異較大的新數(shù)據(jù)集如醫(yī)學(xué)圖像、衛(wèi)星圖像可以考慮只凍結(jié)淺層卷積如前10層讓深層卷積也參與微調(diào)以適應(yīng)新的特征分布。5.3 針對(duì)局限性的現(xiàn)代優(yōu)化策略雖然我們不會(huì)去改動(dòng)VGG16本身但在使用它時(shí)可以采用一些現(xiàn)代技巧來(lái)?yè)P(yáng)長(zhǎng)避短模型剪枝Pruning與量化Quantization為了部署可以對(duì)訓(xùn)練好的VGG16進(jìn)行剪枝移除不重要的權(quán)重連接和量化將FP32權(quán)重轉(zhuǎn)換為INT8大幅減少模型體積和提升推理速度。TensorRT、PyTorch Mobile等工具支持此類(lèi)操作。知識(shí)蒸餾Knowledge Distillation用一個(gè)龐大但性能好的VGG16作為“教師模型”去訓(xùn)練一個(gè)更小、更快的“學(xué)生模型”如MobileNet讓學(xué)生模型模仿教師模型的輸出從而在保持性能的同時(shí)獲得效率提升。作為特征提取器的替代對(duì)于需要輕量級(jí)骨干網(wǎng)絡(luò)的任務(wù)可以考慮使用MobileNet、ShuffleNet或EfficientNet等更現(xiàn)代的架構(gòu)。但在某些對(duì)特征質(zhì)量要求極高、且計(jì)算資源不是首要瓶頸的研究或特定應(yīng)用中VGG16提取的特征依然有其優(yōu)勢(shì)。VGG16更像是一個(gè)里程碑和一本教科書(shū)。它可能不是你現(xiàn)在新項(xiàng)目的首選架構(gòu)但深入理解它能為你打通CNN的任督二脈讓你在面對(duì)更復(fù)雜的網(wǎng)絡(luò)時(shí)能清晰地看到它們是如何在VGG16奠定的基礎(chǔ)上進(jìn)行演化和創(chuàng)新的。下次當(dāng)你看到某個(gè)網(wǎng)絡(luò)里又堆了一串3x3卷積時(shí)你會(huì)會(huì)心一笑知道這經(jīng)典的智慧仍在延續(xù)。