源碼解讀與實(shí)戰(zhàn)指南)
torchvision LRASPP 語義分割模型Lite R-ASPP 架構(gòu)源碼解讀與實(shí)戰(zhàn)指南【免費(fèi)下載鏈接】visionDatasets, Transforms and Models specific to Computer Vision項(xiàng)目地址: https://gitcode.com/gh_mirrors/vi/visionLRASPPLite R-ASPP輕量級 Atrous Spatial Pyramid Pooling是 torchvision 提供的一種輕量化語義分割模型以 MobileNetV3-Large 為骨干網(wǎng)絡(luò)源自論文Searching for MobileNetV3arXiv:1905.02244。本文以 docs/source/models/lraspp.rst 為主線結(jié)合 torchvision/models/segmentation/lraspp.py 源碼與 references/segmentation/README.md 訓(xùn)練腳本完整講解該模型的構(gòu)建接口、預(yù)訓(xùn)練權(quán)重、雙分支解碼頭原理、推理用法與復(fù)現(xiàn)命令幫助你直接上手基于 torchvision 的輕量級語義分割任務(wù)。LRASPP 是什么為移動端設(shè)計的輕量語義分割頭LRASPP 全稱為 Lite R-ASPP是 R-ASPPAtrous Spatial Pyramid Pooling的輕量化變體。它與 DeepLabV3 的 ASPP 模塊思路同源——都是通過不同感受野的特征提取來增強(qiáng)語義分割的多尺度表達(dá)能力——但 LRASPP 刻意削減了膨脹卷積分支的數(shù)量與通道開銷使其特別適合搭配輕量骨干網(wǎng)絡(luò)在資源受限場景下運(yùn)行。在 torchvision 中LRASPP 被組織在torchvision.models.segmentation模塊下segmentation/init.py 中通過from .lraspp import *導(dǎo)出并提供唯一的預(yù)置構(gòu)建器lraspp_mobilenet_v3_large。需要特別留意的是該模型屬于 segmentation 模塊的 beta 功能原文檔以betastatus標(biāo)注這意味著其 API 在未來版本中仍可能調(diào)整生產(chǎn)環(huán)境使用時需關(guān)注 torchvision 的版本更新說明。模型內(nèi)部由兩部分組成對應(yīng)源碼中的兩個類LRASPPlraspp.py#L19-L51頂層網(wǎng)絡(luò)容器持有骨干網(wǎng)絡(luò)與分類頭負(fù)責(zé)特征提取、最終上采樣與輸出組織LRASPPHeadlraspp.py#L54-L79輕量解碼頭融合低層細(xì)節(jié)特征與高層語義特征生成分割結(jié)果。模型構(gòu)建器lraspp_mobilenet_v3_large 完整參數(shù)說明構(gòu)建器的完整簽名定義在 lraspp.py#L127-L134def lraspp_mobilenet_v3_large( *, weights: Optional[LRASPP_MobileNet_V3_Large_Weights] None, progress: bool True, num_classes: Optional[int] None, weights_backbone: Optional[MobileNet_V3_Large_Weights] MobileNet_V3_Large_Weights.IMAGENET1K_V1, **kwargs: Any, ) - LRASPP:各參數(shù)含義與行為如下參數(shù)類型默認(rèn)值說明weightsLRASPP_MobileNet_V3_Large_WeightsNone是否加載預(yù)訓(xùn)練權(quán)重。為None時不加載傳入權(quán)重枚舉或.DEFAULT時加載對應(yīng)權(quán)重詳見下文權(quán)重章節(jié)progressboolTrue下載權(quán)重時是否在 stderr 顯示進(jìn)度條num_classesintNone輸出類別數(shù)包含背景類。為None且未指定權(quán)重時默認(rèn)取 21Pascal VOC 語義分割的 20 類 背景weights_backboneMobileNet_V3_Large_WeightsMobileNet_V3_Large_Weights.IMAGENET1K_V1骨干網(wǎng)絡(luò)的預(yù)訓(xùn)練權(quán)重ImageNet-1K 預(yù)訓(xùn)練**kwargs——透傳給LRASPP基類的額外參數(shù)關(guān)于參數(shù)的幾個關(guān)鍵實(shí)現(xiàn)細(xì)節(jié)源自 lraspp.py#L160-L178aux_loss不受支持構(gòu)建器中顯式kwargs.pop(aux_loss, False)若傳入aux_lossTrue會直接拋出NotImplementedError(This model does not use auxiliary loss)。LRASPP 沒有輔助損失分支與 FCN/DeepLabV3 不同。num_classes的自動覆蓋邏輯當(dāng)加載預(yù)訓(xùn)練權(quán)重時若用戶顯式傳入的num_classes與權(quán)重元數(shù)據(jù)中的類別數(shù)不一致會拋出ValueError由_ovewrite_value_param校驗(yàn)見 models/_utils.py#L242-L246否則自動使用權(quán)重定義好的類別數(shù)。而一旦加載整體權(quán)重weights_backbone會被置為None避免重復(fù)加載骨干權(quán)重。新舊接口兼容構(gòu)建器通過handle_legacy_interface裝飾器models/_utils.py#L152-L231兼容舊的pretrained/pretrained_backbone寫法但使用舊參數(shù)會發(fā)出棄用警告建議統(tǒng)一使用新的weights/weights_backbone接口。預(yù)訓(xùn)練權(quán)重基于 COCO 子集的 VOC 標(biāo)簽?zāi)P臀ㄒ豢捎玫臋?quán)重枚舉是LRASPP_MobileNet_V3_Large_Weights.COCO_WITH_VOC_LABELS_V1也是DEFAULT其元數(shù)據(jù)定義在 lraspp.py#L96-L119關(guān)鍵信息如下元數(shù)據(jù)項(xiàng)值參數(shù)量num_params3,221,538約 322 萬推理計算量_ops2.086 GMacs權(quán)重文件大小_file_size12.49 MB輸入尺寸約束min_size(1, 1)輸出類別categoriesPascal VOC 的 20 類 背景共 21 類完整列表見 models/_meta.py#L1128-L1150即_VOC_CATEGORIESCOCO-val2017VOC 標(biāo)簽mIoU57.9COCO-val2017VOC 標(biāo)簽像素精度91.2權(quán)重訓(xùn)練數(shù)據(jù)說明這批權(quán)重并不是在完整 COCO 上訓(xùn)練的而是使用了 COCO 中與 Pascal VOC 重疊的 20 個類別組成的子集進(jìn)行訓(xùn)練因此輸出標(biāo)簽與 Pascal VOC 語義分割完全一致含背景共 21 類。上述 mIoU 與像素精度指標(biāo)也是在帶 VOC 標(biāo)簽的 COCO 驗(yàn)證集上評估得到的。構(gòu)建器內(nèi)部還會為每個輸入圖像套用SemanticSegmentation預(yù)處理預(yù)設(shè)transforms/_presets.py#L147-L188對應(yīng)權(quán)重中登記的resize_size520def __init__( self, *, resize_size: Optional[int], # LRASPP 權(quán)重登記為 520 mean: tuple[float, ...] (0.485, 0.456, 0.406), # ImageNet 均值 std: tuple[float, ...] (0.229, 0.224, 0.225), # ImageNet 標(biāo)準(zhǔn)差 interpolation: InterpolationMode InterpolationMode.BILINEAR, antialias: Optional[bool] True, ) - None其forward依次執(zhí)行雙線性縮放至短邊 520短邊 520 是訓(xùn)練/推理階段的慣例可減少移動端上的特征圖開銷→ 轉(zhuǎn)浮點(diǎn)并歸一化到[0, 1]→ 按 ImageNet 均值/標(biāo)準(zhǔn)差標(biāo)準(zhǔn)化。使用weights.DEFAULT時模型會自動攜帶這一預(yù)設(shè)通過weights.transforms()即可獲取。源碼解剖LRASPPHead 雙分支輕量融合LRASPPHead 的核心設(shè)計是只使用一條高層語義路徑 一條低層細(xì)節(jié)路徑用極少的計算量完成多尺度融合。其結(jié)構(gòu)lraspp.py#L54-L79包含四個子模塊self.cbr nn.Sequential( # 1×1 卷積降維 BN ReLU nn.Conv2d(high_channels, inter_channels, 1, biasFalse), nn.BatchNorm2d(inter_channels), nn.ReLU(inplaceTrue), ) self.scale nn.Sequential( # 全局上下文門控通道注意力 nn.AdaptiveAvgPool2d(1), nn.Conv2d(high_channels, inter_channels, 1, biasFalse), nn.Sigmoid(), ) self.low_classifier nn.Conv2d(low_channels, num_classes, 1) # 低層路徑分類頭 self.high_classifier nn.Conv2d(inter_channels, num_classes, 1) # 高層路徑分類頭forward的融合計算邏輯為low input[low] # 低層特征來自骨干網(wǎng)絡(luò)的 C2stride8 high input[high] # 高層特征來自骨干網(wǎng)絡(luò)的 C5stride16 x self.cbr(high) # 1) 高層特征降維到 inter_channels默認(rèn) 128 s self.scale(high) # 2) 全局池化產(chǎn)生逐通道縮放因子 x x * s # 3) 通道級門控加權(quán) x F.interpolate(x, sizelow.shape[-2:], modebilinear, align_cornersFalse) # 4) 上采樣對齊低層特征尺寸 return self.low_classifier(low) self.high_classifier(x) # 5) 兩路徑逐像素相加可以這樣理解這五步cbr用 1×1 卷積把高層特征從high_channels壓縮到 128 維控制后續(xù)計算量scale通過全局平均池化 Sigmoid 為每個通道計算 0~1 的權(quán)重讓網(wǎng)絡(luò)學(xué)習(xí)哪些高層通道對分割更重要兩路分類頭分別把低層與高層特征投影到類別空間后逐像素相加——低層特征負(fù)責(zé)精細(xì)邊緣與空間細(xì)節(jié)高層特征負(fù)責(zé)語義判別這正是 LRASPP 輕量而有效的關(guān)鍵。頂層網(wǎng)絡(luò)骨干特征抽取與輸出上采樣LRASPP基類lraspp.py#L35-L51的構(gòu)造與前向邏輯如下def __init__(self, backbone, low_channels, high_channels, num_classes, inter_channels128): self.backbone backbone self.classifier LRASPPHead(low_channels, high_channels, num_classes, inter_channels) def forward(self, input): features self.backbone(input) # 返回 OrderedDict鍵為 low / high out self.classifier(features) out F.interpolate(out, sizeinput.shape[-2:], modebilinear, align_cornersFalse) result OrderedDict() result[out] out return result三個要點(diǎn)值得注意骨干輸出協(xié)議LRASPP要求傳入的backbone返回OrderedDict[Tensor]且鍵必須為high高層特征圖與low低層特征圖這由LRASPPHead.forward直接按字典鍵取值。最終的 4 倍上采樣分類頭輸出尺寸約為輸入尺寸的 1/16因骨干 stride16LRASPP.forward用雙線性插值align_cornersFalse將其恢復(fù)到原始輸入分辨率因此模型輸出的分割圖與輸入圖像分辨率一致無需用戶額外對齊。輸出為 OrderedDict返回{out: tensor}的結(jié)構(gòu)與 torchvision 其他分割模型保持一致方便統(tǒng)一的后處理代碼。骨干適配MobileNetV3-Large 空洞卷積 IntermediateLayerGetter_lraspp_mobilenetv3lraspp.py#L82-L93負(fù)責(zé)把 MobileNetV3-Large 適配為 LRASPP 的特征提取器backbone mobilenet_v3_large(weightsweights_backbone, dilatedTrue) # 關(guān)鍵dilatedTrue backbone backbone.features stage_indices [0] [i for i, b in enumerate(backbone) if getattr(b, _is_cn, False)] [len(backbone) - 1] low_pos stage_indices[-4] # 取 C2輸出 stride 8 high_pos stage_indices[-1] # 取 C5輸出 stride 16 backbone IntermediateLayerGetter(backbone, return_layers{str(low_pos): low, str(high_pos): high})其原理分三層空洞卷積保持分辨率構(gòu)建骨干時傳入dilatedTrueMobileNetV3-Large 的最后兩個階段會替換為帶洞卷積詳見 torchvision/models/mobilenetv3.py使整體輸出 stride 從 32 降低到 16避免高層特征因連續(xù)下采樣而丟失過多空間細(xì)節(jié)按_is_cn標(biāo)記定位階段MobileNetV3 中每個 stride 下采樣塊的_is_cn屬性為 True據(jù)此定位 C1~C4 的邊界從而確定 C2stride8與 C5stride16的位置IntermediateLayerGetter抽取中間層models/_utils.py#L13-L73按return_layers配置逐層前向命中時把特征存入輸出字典并重命名為low/high實(shí)現(xiàn)一次前向同時拿到兩路特征。注意_is_cn定位方式依賴于模塊注冊順序即前向執(zhí)行順序這一假設(shè)這也是IntermediateLayerGetter文檔中強(qiáng)調(diào)的約束。實(shí)戰(zhàn)加載預(yù)訓(xùn)練 LRASPP 做語義分割推理下面給出完整的推理示例展示權(quán)重預(yù)設(shè)、預(yù)處理與后處理的正確組合import torch from PIL import Image import torchvision.transforms as T from torchvision.models.segmentation import lraspp_mobilenet_v3_large, LRASPP_MobileNet_V3_Large_Weights # 1. 構(gòu)建模型并加載預(yù)訓(xùn)練權(quán)重weights 會自動攜帶 transforms 預(yù)設(shè) weights LRASPP_MobileNet_V3_Large_Weights.DEFAULT model lraspp_mobilenet_v3_large(weightsweights) model.eval() # 2. 使用權(quán)重自帶的預(yù)處理短邊縮放至 520 歸一化 preprocess weights.transforms() # 3. 讀取并預(yù)處理圖像 img Image.open(demo.jpg).convert(RGB) batch preprocess(img).unsqueeze(0) # 形狀: (1, 3, H, W) # 4. 前向推理輸出與輸入分辨率一致的分割圖 with torch.inference_mode(): out model(batch)[out] # 形狀: (1, 21, H, W) # 5. 后處理argmax 得到逐像素類別索引 pred out.argmax(dim1).squeeze(0) # 形狀: (H, W)若想完全控制預(yù)處理流程也可以手動構(gòu)造SemanticSegmentation預(yù)設(shè)from torchvision.transforms._presets import SemanticSegmentation preprocess SemanticSegmentation(resize_size520)訓(xùn)練復(fù)現(xiàn)官方 reference 腳本references/segmentation/README.md#L40-L42 給出了官方復(fù)現(xiàn)命令在 8×V100 GPU 環(huán)境下訓(xùn)練torchrun --nproc_per_node8 train.py --dataset coco -b 4 \ --model lraspp_mobilenet_v3_large \ --wd 0.000001 \ --weights-backbone MobileNet_V3_Large_Weights.IMAGENET1K_V1使用前需要按 README 說明修改兩個必填參數(shù)--data-path/path/to/dataset指向 COCO 數(shù)據(jù)集路徑與--nproc_per_node實(shí)際可用 GPU 數(shù)。與 FCN/DeepLabV3 的復(fù)現(xiàn)命令相比LRASPP 的命令沒有--aux-loss這與構(gòu)建器不支持輔助損失的實(shí)現(xiàn)保持一致同時其權(quán)重衰減設(shè)置為極小的1e-6這是為了配合 MobileNetV3 骨干的特性。注意該訓(xùn)練命令中的--dataset coco與預(yù)訓(xùn)練權(quán)重一樣實(shí)際使用的是 COCO 中 VOC 類別的子集監(jiān)督。完整的訓(xùn)練入口與參數(shù)解析位于 references/segmentation/train.py可參考其中的數(shù)據(jù)加載、損失與評估邏輯。測試驗(yàn)證模型與權(quán)重枚舉的回歸保障torchvision 的測試套件對 LRASPP 提供了系統(tǒng)性覆蓋test/test_extended_models.py第 27 行將(lraspp_mobilenet_v3_large, models.segmentation.LRASPP)注冊到模型類注冊表驗(yàn)證構(gòu)建器返回類型正確第 42 行注冊構(gòu)建器函數(shù)本身第 57 行注冊LRASPP_MobileNet_V3_Large_Weights權(quán)重枚舉驗(yàn)證權(quán)重枚舉可枚舉、可校驗(yàn)第 73 行將該模型加入需用 CPU 運(yùn)行的回歸測試分組第 93 行加入免下載/格式校驗(yàn)相關(guān)分組test/test_models.py#L271模型期望輸出對照表ModelTester系列測試同樣覆蓋了該模型。如果要在本地跑一個最小冒煙驗(yàn)證可參考測試方式構(gòu)造隨機(jī)輸入斷言輸出形狀import torch from torchvision.models.segmentation import lraspp_mobilenet_v3_large model lraspp_mobilenet_v3_large(weightsNone, num_classes21).eval() x torch.rand(1, 3, 520, 520) with torch.inference_mode(): out model(x)[out] assert out.shape (1, 21, 520, 520) # 輸出與輸入分辨率一致使用限制與注意事項(xiàng)Beta 狀態(tài)segmentation 模塊整體為 beta 功能接口可能隨版本演進(jìn)升級 torchvision 后需回歸驗(yàn)證不支持輔助損失aux_lossTrue會直接拋錯不能照搬 FCN/DeepLabV3 的訓(xùn)練配置類別數(shù)校驗(yàn)嚴(yán)格加載預(yù)訓(xùn)練權(quán)重時若手工傳入不相符的num_classes會報ValueError自定義微調(diào)應(yīng)顯式傳weightsNone并指定num_classes輸入尺寸權(quán)重元數(shù)據(jù)min_size為(1, 1)理論可處理任意尺寸輸入但考慮到整體 stride 為 16建議輸入尺寸為 16 的倍數(shù)以獲得對齊的逐像素結(jié)果推理默認(rèn)按短邊 520 縮放。綜上LRASPP 是 torchvision 語義分割家族中最輕量的成員之一約 322 萬參數(shù)、2.09 GMacs其高層語義門控 低層細(xì)節(jié)融合的解碼頭設(shè)計在精度與算力之間取得了良好平衡特別適合移動端與邊緣設(shè)備上的語義分割部署?!久赓M(fèi)下載鏈接】visionDatasets, Transforms and Models specific to Computer Vision項(xiàng)目地址: https://gitcode.com/gh_mirrors/vi/vision創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考