現(xiàn)像素級圖像分類(Segmentation 實(shí)戰(zhàn)指南))
教程人工智能機(jī)器學(xué)習(xí)深度學(xué)習(xí)【免費(fèi)下載鏈接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!項(xiàng)目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners點(diǎn)擊查看免費(fèi)下載本指南基于 AI For Beginners 課程第 12 課「分割Segmentierung」展開完整講解語義分割與實(shí)例分割的概念區(qū)別、編碼器-解碼器網(wǎng)絡(luò)架構(gòu)、分割任務(wù)特有的損失函數(shù)設(shè)計(jì)并帶領(lǐng)讀者基于 PH2 皮膚鏡圖像數(shù)據(jù)集訓(xùn)練真實(shí)的分割網(wǎng)絡(luò)PyTorch 與 TensorFlow 雙版本最后延伸到人體分割實(shí)戰(zhàn)練習(xí)。讀完本文你將理解分割網(wǎng)絡(luò)輸入圖像 → 輸出逐像素掩碼的工作原理并能直接運(yùn)行倉庫中的 Notebook 復(fù)現(xiàn)訓(xùn)練流程。從目標(biāo)檢測到像素級分類為什么需要分割在 目標(biāo)檢測 任務(wù)中我們通過預(yù)測邊界框bounding box來定位圖像中的物體。但許多場景需要遠(yuǎn)比邊界框精確得多的定位醫(yī)學(xué)影像中需要標(biāo)出病灶的精確輪廓自動駕駛需要區(qū)分道路與行人的每個(gè)像素。這種對圖像中每個(gè)像素賦予語義標(biāo)簽的任務(wù)就是分割Segmentation。分割可以看作一種像素級分類Pixel Classification對于圖像的每一個(gè)像素都要預(yù)測它的類別背景本身就是其中一類。根據(jù)輸出粒度的不同分割算法分為兩大類類別說明語義分割Semantic Segmentation只給出每個(gè)像素的類別不區(qū)分同一類中的不同個(gè)體。例如圖片里有 10 只羊語義分割把所有羊都標(biāo)成羊這一類。實(shí)例分割I(lǐng)nstance Segmentation在像素分類的基礎(chǔ)上把同一類別進(jìn)一步拆分為不同實(shí)例。同樣 10 只羊?qū)嵗指顣^(qū)分出 10 個(gè)不同的對象。分割網(wǎng)絡(luò)的統(tǒng)一結(jié)構(gòu)Encoder-Decoder雖然存在多種分割神經(jīng)網(wǎng)絡(luò)架構(gòu)但它們都遵循同一種結(jié)構(gòu)。從某種意義上說這與你在自編碼器課程中學(xué)到的結(jié)構(gòu)非常相似——區(qū)別在于自編碼器的目標(biāo)是重構(gòu)原始圖像而分割網(wǎng)絡(luò)的目標(biāo)是重構(gòu)一張掩碼Mask圖像。一個(gè)分割網(wǎng)絡(luò)由兩個(gè)部分組成編碼器Encoder從輸入圖像中提取特征。通常由一系列卷積層與池化層構(gòu)成逐級壓縮空間尺寸、加深通道數(shù)。解碼器Decoder將編碼器提取的特征逐步上采樣還原為與輸入同尺寸的掩碼圖像其通道數(shù)等于類別數(shù)多類分割輸出 one-hot 編碼的多通道圖二值分割輸出單通道圖。分割專用的損失函數(shù)交叉熵與 BCE在經(jīng)典自編碼器中我們用均方誤差MSE衡量兩張圖像像素之間的相似度但在分割任務(wù)中目標(biāo)掩碼圖像的每個(gè)像素代表的是類別編號沿第三維進(jìn)行 one-hot 編碼因此需要采用專門面向分類問題的損失函數(shù)——交叉熵?fù)p失Cross-Entropy Loss并對所有像素取平均。當(dāng)掩碼是二值的例如我們的痣分割案例只有病灶/背景兩類則使用二值交叉熵?fù)p失BCEBinary Cross-Entropy Loss。? 補(bǔ)充知識one-hot 編碼是一種把類別標(biāo)簽編碼成長度等于類別數(shù)的向量的方法其中只有對應(yīng)類別的位置為 1其余為 0。在分割任務(wù)中每個(gè)像素的類別標(biāo)簽都會被編碼成這樣的向量網(wǎng)絡(luò)輸出因此也自然地采用多通道表示。實(shí)戰(zhàn)醫(yī)學(xué)影像中的痣分割本課將訓(xùn)練一個(gè)網(wǎng)絡(luò)從醫(yī)學(xué)圖像中識別人類色素痣N?vi即俗話說的痣。我們使用PH2 皮膚鏡圖像數(shù)據(jù)庫PH2 Database of dermoscopy images作為數(shù)據(jù)源共200 張圖像分屬三類典型痣typical nevus、非典型痣atypical nevus與黑色素瘤melanoma每張圖像都配有對應(yīng)的掩碼精確勾勒出痣的輪廓我們要訓(xùn)練模型把任意一顆痣從背景中分割出來。這類技術(shù)尤其適合醫(yī)學(xué)影像場景。除了皮膚病變分割你還能聯(lián)想到哪些現(xiàn)實(shí)世界的應(yīng)用例如遙感圖像中的地物分割、自動駕駛場景解析、衛(wèi)星云圖分析等。動手實(shí)驗(yàn)兩種主流分割架構(gòu)倉庫中提供了兩個(gè)可直接運(yùn)行的 Jupyter Notebook分別使用 PyTorch 與 TensorFlow 實(shí)現(xiàn)用于學(xué)習(xí)不同語義分割架構(gòu)并觀察它們的實(shí)際效果Semantic Segmentation PytorchSemantic Segmentation TensorFlow源碼級解析一SegNet——最樸素的編碼器-解碼器SegNet是最簡單的編碼器-解碼器架構(gòu)編碼器使用帶卷積與池化的標(biāo)準(zhǔn) CNN 逐級提取特征解碼器使用帶卷積與上采樣的反卷積 CNN逐步還原分辨率同時(shí)依靠批歸一化Batch Normalization來保證多層網(wǎng)絡(luò)可以成功訓(xùn)練。從 PyTorch 實(shí)現(xiàn) 的代碼可以看到它的完整結(jié)構(gòu)class SegNet(nn.Module): def __init__(self): super().__init__() # Encoder: 3→16→32→64→128每級 ConvReLUBNMaxPool(2x2) self.enc_conv0 nn.Conv2d(in_channels3, out_channels16, kernel_size(3,3), padding1) ... self.pool0 nn.MaxPool2d(kernel_size(2,2)) # ... enc_conv1(16→32)、enc_conv2(32→64)、enc_conv3(64→128) # 瓶頸層128→256 self.bottleneck_conv nn.Conv2d(in_channels128, out_channels256, kernel_size(3,3), padding1) # Decoder: 雙線性上采樣 卷積256→128→64→32→1 self.upsample0 nn.UpsamplingBilinear2d(scale_factor2) ... self.dec_conv3 nn.Conv2d(in_channels32, out_channels1, kernel_size(1,1)) self.sigmoid nn.Sigmoid()PyTorch 版本的訓(xùn)練配置來自 Notebook 代碼為device cuda:0 if torch.cuda.is_available() else cpu train_size 0.9 # 90% 用于訓(xùn)練 lr 1e-3 # Adam 學(xué)習(xí)率 weight_decay 1e-6 # 權(quán)重衰減 batch_size 32 epochs 30 model SegNet().to(device) optimizer optim.Adam(model.parameters(), lrlr, weight_decayweight_decay) loss_fn nn.BCEWithLogitsLoss()由于是二值掩碼病灶/背景損失函數(shù)使用nn.BCEWithLogitsLoss()。訓(xùn)練循環(huán)按常規(guī)方式定義每個(gè) epoch 中把圖像與標(biāo)簽送入device計(jì)算損失后zero_grad → backward → step再用測試集在torch.no_grad()下評估 loss。Notebook 中 30 個(gè) epoch 訓(xùn)練完成后train loss 約為 0.593、test loss 約為 0.577隨后用(model(img) 0.5)的閾值化方式將網(wǎng)絡(luò)輸出轉(zhuǎn)成二值掩碼并可視化。TensorFlow 版本SemanticSegmentationTF.ipynb的 SegNet 是同樣的思路用 Keras API 表達(dá)編碼器為Conv2D BatchNormalization Activation(relu) MaxPool2D解碼器為UpSampling2D(interpolationbilinear) Conv2D最終輸出 1 通道超參數(shù)略有不同train_size 0.8 lr 3e-4 weight_decay 8e-9 batch_size 64 epochs 100 loss_fn losses.BinaryCrossentropy(from_logitsTrue) model.compile(lossloss_fn, optimizeroptimizer)訓(xùn)練日志顯示 SegNet 的 val_loss 從第 1 個(gè) epoch 的 0.696 逐步下降到第 100 個(gè) epoch 的 0.445。源碼級解析二U-Net——跳連帶來的精度提升SegNet 結(jié)構(gòu)很自然但它不是最精確的金字塔式 CNN 在壓縮特征空間分辨率的同時(shí)丟失了空間精度導(dǎo)致重建時(shí)難以準(zhǔn)確還原像素位置。這引出了在編碼器與解碼器卷積層之間建立跳連Skip Connections的思想即著名的U-Net架構(gòu)。跳連在每個(gè)卷積層級把編碼器提取的特征直接拼接到對應(yīng)層級的解碼器上幫助網(wǎng)絡(luò)不丟失該層級來自原始輸入的細(xì)節(jié)信息。倉庫中的 U-Net 實(shí)現(xiàn)印證了這一點(diǎn)——解碼器的輸入通道數(shù)包含了拼接torch.cat進(jìn)來的編碼器特征# U-Net 解碼器384 256(上采樣后) 128(編碼器第4層特征 cat3) self.dec_conv0 nn.Conv2d(in_channels384, out_channels128, kernel_size(3,3), padding1) ... # 前向傳播中把上采樣結(jié)果與同層級編碼器輸出拼接 d0 self.dec_bn0(self.dec_act0(self.dec_conv0(torch.cat((self.upsample0(b), cat3), dim1)))) d1 self.dec_bn1(self.dec_act1(self.dec_conv1(torch.cat((self.upsample1(d0), cat2), dim1))))在 PyTorch 版本中U-Net 與 SegNet 共用同一訓(xùn)練函數(shù)和 BCE 損失30 個(gè) epoch 后 train loss ≈ 0.595、test loss ≈ 0.572。而在 TensorFlow 版本中100 個(gè) epoch 后 U-Net 的 val_loss 降至0.1525遠(yuǎn)低于 SegNet 的 0.445直觀體現(xiàn)了跳連對分割精度的提升。提示本課為了教學(xué)清晰使用了較簡單的 CNN 編碼器實(shí)際應(yīng)用中 U-Net 的編碼器也可以替換為更強(qiáng)的特征提取骨干例如 ResNet-50。更正式的評估指標(biāo)Pixel Accuracy除了可視化對比目標(biāo)掩碼與預(yù)測掩碼分割模型還有正式的量化評估指標(biāo)。其中最容易理解的是像素準(zhǔn)確率Pixel Accuracy——被正確分類的像素所占的百分比即預(yù)測掩碼與真實(shí)掩碼逐像素比對后的正確率。作業(yè)挑戰(zhàn)人體分割實(shí)戰(zhàn)分割在視頻制作中有典型應(yīng)用例如天氣預(yù)報(bào)節(jié)目經(jīng)常需要把人像從攝像頭畫面中摳出來疊加到其他背景素材上。傳統(tǒng)做法使用色度鍵chroma key技術(shù)——讓被攝者站在純色背景前拍攝再移除背景色。而在本課程的 lab 作業(yè) 中我們將改用神經(jīng)網(wǎng)絡(luò)模型直接切出人體剪影從 Kaggle 手動下載并解壓Segmentation Full Body MADS Dataset包含 1192 張圖像及其掩碼打開啟動 Notebook BodySegmentation.ipynb其代碼展示了數(shù)據(jù)組織方式數(shù)據(jù)集目錄下images/與masks/兩個(gè)子目錄存放同名文件plt.imread同時(shí)讀取圖像與掩碼進(jìn)行可視化示例輸出為 512×384 的圖像-掩碼對復(fù)用本課學(xué)到的分割網(wǎng)絡(luò)SegNet / U-Net完成訓(xùn)練與推理。人體分割只是面向人像圖像的常見任務(wù)之一。另一類重要任務(wù)是骨架檢測skeleton detection與姿態(tài)識別pose detection你可以嘗試使用 OpenPose 庫來觀察姿態(tài)識別是如何實(shí)現(xiàn)的??偨Y(jié)分割是一種非常強(qiáng)大的圖像分類技術(shù)它超越了邊界框?qū)崿F(xiàn)了像素級分類在醫(yī)學(xué)影像等領(lǐng)域有著廣泛應(yīng)用。本課的核心要點(diǎn)可歸納為分割 逐像素分類語義分割不區(qū)分同類實(shí)例實(shí)例分割進(jìn)一步拆分實(shí)例主流分割網(wǎng)絡(luò) 編碼器提特征 解碼器生成掩碼分割的損失函數(shù)是逐像素平均的交叉熵二值場景用 BCE而非 MSESegNet 是最簡基線U-Net 通過跳連顯著提升分割精度使用 PH2 數(shù)據(jù)集可完整復(fù)現(xiàn)皮膚病變分割訓(xùn)練流程并使用像素準(zhǔn)確率評估效果。如需進(jìn)一步探索可查看本課架構(gòu)參考圖 segnet.png 與 unet.png以及課程目錄 4-ComputerVision 下的其他視覺任務(wù)章節(jié)。更完整的課件與練習(xí)題可參閱倉庫根目錄 README.md。贊分享教程人工智能機(jī)器學(xué)習(xí)深度學(xué)習(xí)【免費(fèi)下載鏈接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!項(xiàng)目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners點(diǎn)擊查看免費(fèi)下載相關(guān)推薦AI-For-Beginners 語義分割實(shí)戰(zhàn)指南從像素級分類到醫(yī)學(xué)圖像分割SegNet 與 U-Net 完整實(shí)現(xiàn)AI For Beginners 語義分割實(shí)戰(zhàn)指南從像素級分類到醫(yī)學(xué)圖像分割SegNet 與 U Net 完整實(shí)現(xiàn) 本篇技術(shù)指南基于 AI For Beg教程人工智能機(jī)器學(xué)習(xí)深度學(xué)習(xí)語義分割實(shí)戰(zhàn)指南用PyTorch實(shí)現(xiàn)像素級圖像分類語義分割實(shí)戰(zhàn)指南用PyTorch實(shí)現(xiàn)像素級圖像分類 語義分割是計(jì)算機(jī)視覺中一種重要的像素級圖像分類技術(shù)它能將圖像中的每個(gè)像素分配到特定的類別。在深度學(xué)習(xí)領(lǐng)域示例工程教程AI-For-Beginners 圖像分割實(shí)戰(zhàn)指南從像素級分類到醫(yī)學(xué)影像病變分割A(yù)I For Beginners 圖像分割實(shí)戰(zhàn)指南從像素級分類到醫(yī)學(xué)影像病變分割 圖像分割Segmentation是計(jì)算機(jī)視覺中比目標(biāo)檢測更進(jìn)一步的任務(wù)教程人工智能機(jī)器學(xué)習(xí)深度學(xué)習(xí)上一篇終極指南5步使用Warp框架構(gòu)建高性能社交媒體API下一篇Python 定時(shí)任務(wù)一行代碼搞定schedule 庫 repeat 裝飾器完整教程創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考