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