戰(zhàn):從數(shù)據(jù)到調(diào)參的完整指南)
簡(jiǎn)介本資源面向醫(yī)學(xué)圖像分割方向的初學(xué)者與算法實(shí)踐者提供一套基于U-Net的眼底血管二分類(lèi)分割完整方案解決從數(shù)據(jù)準(zhǔn)備到模型推理的全流程落地問(wèn)題。壓縮包共216個(gè)文件以182張png切片圖像、8個(gè)py腳本、1個(gè)pth權(quán)重文件及若干txt日志與xml配置為主整體約153.92MB數(shù)據(jù)集、代碼與訓(xùn)練結(jié)果一并打包。訓(xùn)練腳本支持0.5至1.5倍隨機(jī)縮放的多尺度訓(xùn)練utils中的compute_gray函數(shù)可將mask灰度值寫(xiě)入txt并自動(dòng)定義U-Net輸出通道便于擴(kuò)展多分割任務(wù)學(xué)習(xí)率采用cos衰減損失與IoU曲線(xiàn)、各類(lèi)別IoU、recall、precision及全局像素準(zhǔn)確率均保存在run_results與訓(xùn)練日志中。僅訓(xùn)練10個(gè)epochs全局像素準(zhǔn)確度已達(dá)0.95miou為0.67加大epoch性能可進(jìn)一步提升。推理時(shí)只需將待測(cè)圖像放入inference目錄并運(yùn)行predict腳本無(wú)需額外參數(shù)。目前已有269人學(xué)習(xí)適合快速?gòu)?fù)現(xiàn)與二次開(kāi)發(fā)。1. 眼底血管分割這套 Unet 資源拿到手先別急著訓(xùn)練眼底血管分割是醫(yī)學(xué)圖像分割里最經(jīng)典的入門(mén)任務(wù)之一也是很多人從分類(lèi)模型轉(zhuǎn)向像素級(jí)預(yù)測(cè)的第一站。你拿到的這份資源核心是一個(gè)基于 Unet 的眼底血管二分類(lèi)分割項(xiàng)目附帶已經(jīng)切片好的數(shù)據(jù)集、完整可運(yùn)行的訓(xùn)練與推理代碼以及作者跑完 10 個(gè) epoch 后的結(jié)果文件。作者給出的指標(biāo)是全局像素準(zhǔn)確率 0.95、miou 0.67這個(gè)數(shù)字在只訓(xùn)練 10 輪的前提下算是相當(dāng)能打——血管本身是細(xì)長(zhǎng)結(jié)構(gòu)前景像素占比極低miou 能到 0.67 說(shuō)明模型確實(shí)學(xué)到了血管的拓?fù)渥呦蚨皇强坎卤尘八?zhǔn)確率。這份資源適合三類(lèi)人剛接觸醫(yī)學(xué)圖像分割、想找一個(gè)能直接跑通全流程的練手項(xiàng)目的人手里有自己的眼底數(shù)據(jù)、想拿這套代碼當(dāng)訓(xùn)練框架改的人以及需要一份帶訓(xùn)練日志和權(quán)重文件、方便做對(duì)比實(shí)驗(yàn)的從業(yè)者。代碼里已經(jīng)內(nèi)置了多尺度訓(xùn)練、cos 學(xué)習(xí)率衰減、按 mask 灰度值自動(dòng)定義輸出通道這些工程細(xì)節(jié)不是那種只貼一個(gè) model.py 就號(hào)稱(chēng)完整的半成品。下面按「資源是什么 → 怎么跑起來(lái) → 參數(shù)怎么調(diào) → 坑在哪」的順序拆開(kāi)講。2. 拆開(kāi)資源包目錄結(jié)構(gòu)、數(shù)據(jù)格式與 Unet 輸出通道的自動(dòng)推導(dǎo)2.1 目錄里到底有什么資源包解壓后根目錄下能看到.gitignore、u-net-me.iml這類(lèi)工程配置文件以及一批以數(shù)字命名的 png 圖片84.png、65.png、63.png 等。這些數(shù)字命名的圖不是隨便放的通常是數(shù)據(jù)集里的樣本切片或者訓(xùn)練過(guò)程中保存的中間可視化結(jié)果。真正干活的部分在代碼目錄里按功能拆成訓(xùn)練、推理、工具函數(shù)三塊。你拿到手第一件事不是運(yùn)行 train而是先把目錄結(jié)構(gòu)和數(shù)據(jù)流理清楚否則后面改路徑會(huì)改到懷疑人生。常見(jiàn)做法是保持作者原有的目錄層級(jí)不動(dòng)只替換數(shù)據(jù)。因?yàn)?train 腳本里讀數(shù)據(jù)的路徑、run_results 的寫(xiě)入路徑、inference 的讀取路徑都是相對(duì)路徑寫(xiě)死的你一旦挪動(dòng)文件位置就得同步改三處代碼容易漏。我一般會(huì)先跑一遍tree或者find . -maxdepth 2 -type d把結(jié)構(gòu)打印出來(lái)確認(rèn)數(shù)據(jù)目錄、結(jié)果目錄、權(quán)重目錄各自在哪再動(dòng)手。2.2 數(shù)據(jù)格式與 mask 灰度值的約定眼底血管分割的數(shù)據(jù)對(duì)是「原圖 mask」的形式。原圖是彩色眼底照mask 是單通道灰度圖血管區(qū)域?yàn)榘咨叶戎?255背景為黑色0。這份資源的關(guān)鍵設(shè)計(jì)在于 utils 里的compute_gray函數(shù)它會(huì)掃描 mask 目錄下所有灰度圖把出現(xiàn)過(guò)的灰度值收集起來(lái)寫(xiě)進(jìn)一個(gè) txt 文本然后根據(jù)這個(gè)灰度值列表自動(dòng)決定 Unet 最后一層輸出多少個(gè) channel。這個(gè)設(shè)計(jì)的好處是你換一個(gè)多類(lèi)分割任務(wù)時(shí)不用手動(dòng)去改網(wǎng)絡(luò)輸出維度。比如你以后做視盤(pán)、視杯、血管三分類(lèi)mask 里有 0、1、2 三種灰度值compute_gray掃完自動(dòng)把輸出通道設(shè)成 3省掉一處最容易寫(xiě)錯(cuò)的硬編碼。代價(jià)是每次換數(shù)據(jù)集都要重新跑一次這個(gè)函數(shù)生成 txt不能直接復(fù)用舊的。# utils 中 compute_gray 的核心邏輯示意 import os import numpy as np from PIL import Image def compute_gray(mask_dir, save_txtgray_values.txt): gray_set set() for name in os.listdir(mask_dir): if not name.lower().endswith((.png, .jpg, .bmp)): continue mask np.array(Image.open(os.path.join(mask_dir, name)).convert(L)) gray_set.update(np.unique(mask).tolist()) gray_values sorted(gray_set) with open(save_txt, w) as f: f.write(,.join(str(g) for g in gray_values)) # 輸出通道數(shù) 灰度類(lèi)別數(shù)二分類(lèi)時(shí)通常為 2 return len(gray_values), gray_values邏輯說(shuō)明函數(shù)遍歷 mask 目錄用convert(L)強(qiáng)制轉(zhuǎn)單通道避免有些 png 帶 alpha 通道導(dǎo)致np.unique多出無(wú)意義的值。gray_set去重后排序?qū)懳募祷刂道锏念?lèi)別數(shù)直接喂給 Unet 的輸出層。參數(shù)上mask_dir指向你的 mask 文件夾save_txt建議放在工程根目錄方便 train 腳本讀取。注意二分類(lèi)任務(wù)里 mask 只有 0 和 255 兩個(gè)值但如果你用交叉熵?fù)p失輸出通道要設(shè)成 2背景 血管別設(shè)成 1否則 softmax 維度對(duì)不上。2.3 多尺度訓(xùn)練是怎么實(shí)現(xiàn)的train 腳本在送數(shù)據(jù)進(jìn)網(wǎng)絡(luò)前會(huì)把圖像隨機(jī)縮放為設(shè)定尺寸的 0.5 到 1.5 倍之間。這是醫(yī)學(xué)圖像分割里很實(shí)用的一招血管粗細(xì)在不同放大倍率下差異明顯模型見(jiàn)過(guò)多種尺度后對(duì)小血管的召回會(huì)更好。實(shí)現(xiàn)上一般是在 Dataset 的__getitem__里生成一個(gè)隨機(jī)縮放因子用cv2.resize或torch.nn.functional.interpolate對(duì)圖像和 mask 同步縮放mask 必須用最近鄰插值否則灰度值會(huì)被插值成中間值破壞類(lèi)別標(biāo)簽。import random import cv2 import numpy as np def random_scale(img, mask, base_size512, scale_range(0.5, 1.5)): scale random.uniform(*scale_range) new_size int(base_size * scale) img cv2.resize(img, (new_size, new_size), interpolationcv2.INTER_LINEAR) # mask 必須用最近鄰保住 0/255 的類(lèi)別邊界 mask cv2.resize(mask, (new_size, new_size), interpolationcv2.INTER_NEAREST) return img, mask邏輯說(shuō)明scale_range控制縮放幅度0.5 到 1.5 是作者給的默認(rèn)區(qū)間你數(shù)據(jù)里血管特別細(xì)的話(huà)可以收窄到 0.8 到 1.2避免縮太小把血管縮沒(méi)了。base_size是基準(zhǔn)尺寸縮放后再統(tǒng)一 crop 或 pad 到網(wǎng)絡(luò)輸入尺寸。這里最容易翻車(chē)的是 mask 用了雙線(xiàn)性插值訓(xùn)練時(shí) loss 看著在降但 miou 上不去因?yàn)闃?biāo)簽被污染了。3. 從零跑通訓(xùn)練cos 衰減、日志解讀與結(jié)果文件3.1 訓(xùn)練腳本的執(zhí)行流程train 腳本是自動(dòng)化的你只要把數(shù)據(jù)按約定擺好直接運(yùn)行就行。它會(huì)依次做這幾件事調(diào)用compute_gray生成灰度值 txt 并確定輸出通道、構(gòu)建 Dataset 和 DataLoader、初始化 Unet、設(shè)置 cos 學(xué)習(xí)率衰減、開(kāi)始 epoch 循環(huán)、每個(gè) epoch 結(jié)束后在測(cè)試集上算 loss 和 iou、把曲線(xiàn)用 matplotlib 畫(huà)出來(lái)存進(jìn) run_results、保存最優(yōu)權(quán)重和訓(xùn)練日志。# 訓(xùn)練啟動(dòng)示意具體入口以 README 為準(zhǔn) python train.py \ --data_root ./data \ --epochs 10 \ --batch_size 4 \ --lr 1e-3 \ --base_size 512參數(shù)說(shuō)明data_root是數(shù)據(jù)根目錄里面要有原圖和 mask 兩個(gè)子文件夾epochs作者只跑了 10你機(jī)器允許的話(huà)加到 50 到 100miou 通常還能往上走batch_size受顯存限制512 尺寸下 4 是保守值8G 顯存可以試 8lr初始學(xué)習(xí)率配合 cos 衰減1e-3 是常見(jiàn)起點(diǎn)。運(yùn)行后終端會(huì)打印每個(gè) epoch 的 lossrun_results 里會(huì)多出曲線(xiàn)圖和日志文件。3.2 cos 學(xué)習(xí)率衰減為什么適合這個(gè)任務(wù)學(xué)習(xí)率采用余弦退火公式是 lr 隨 epoch 按余弦曲線(xiàn)從初始值平滑降到接近 0。相比階梯衰減cos 衰減前期降得慢、后期降得快訓(xùn)練初期能充分探索后期在小學(xué)習(xí)率下精細(xì)收斂。對(duì)血管分割這種前景稀疏的任務(wù)后期學(xué)習(xí)率太大容易把已經(jīng)學(xué)好的細(xì)血管權(quán)重沖掉cos 衰減正好壓住這個(gè)抖動(dòng)。import math def cosine_lr(optimizer, base_lr, epoch, total_epochs, warmup0): if epoch warmup: lr base_lr * (epoch 1) / warmup else: progress (epoch - warmup) / max(1, total_epochs - warmup) lr 0.5 * base_lr * (1 math.cos(math.pi * progress)) for pg in optimizer.param_groups: pg[lr] lr return lr邏輯說(shuō)明base_lr是初始學(xué)習(xí)率total_epochs要和訓(xùn)練總輪數(shù)一致否則余弦曲線(xiàn)走不完。warmup是可選的預(yù)熱輪數(shù)數(shù)據(jù)量小的時(shí)候加上能防止第一個(gè) epoch 梯度爆炸。注意這個(gè)函數(shù)每個(gè) epoch 調(diào)用一次別放進(jìn) batch 循環(huán)里否則學(xué)習(xí)率會(huì)降得過(guò)快。3.3 訓(xùn)練日志里該看哪些指標(biāo)訓(xùn)練日志里記錄了每個(gè)類(lèi)別的 iou、recall、precision以及全局像素準(zhǔn)確率。這里有個(gè)血淚經(jīng)驗(yàn)全局像素準(zhǔn)確率在血管分割里參考價(jià)值有限因?yàn)楸尘罢季懦梢陨夏P腿A(yù)測(cè)背景也能有 0.9 的準(zhǔn)確率。真正要看的是血管這一類(lèi)的前景 iou 和 recall。作者給的 miou 0.67 是兩類(lèi) iou 的平均如果背景 iou 接近 0.99、血管 iou 只有 0.35平均下來(lái)也能到 0.67所以你得把日志里每個(gè)類(lèi)別的數(shù)字單獨(dú)拎出來(lái)看。指標(biāo)含義該關(guān)注什么全局像素準(zhǔn)確率所有像素預(yù)測(cè)正確的比例參考即可背景主導(dǎo)時(shí)虛高前景 iou血管區(qū)域的交并比核心指標(biāo)低于 0.3 說(shuō)明沒(méi)學(xué)到recall血管被召回的比例低說(shuō)明漏檢多細(xì)血管斷precision預(yù)測(cè)為血管中正確的比例低說(shuō)明誤檢多背景被誤判miou各類(lèi) iou 平均看趨勢(shì)別只看絕對(duì)值3.4 結(jié)果文件與最優(yōu)權(quán)重的保存run_results 目錄里會(huì)有 loss 曲線(xiàn)、iou 曲線(xiàn)、訓(xùn)練日志和最優(yōu)權(quán)重。曲線(xiàn)圖由 matplotlib 繪制橫軸 epoch、縱軸指標(biāo)方便你判斷有沒(méi)有過(guò)擬合。最優(yōu)權(quán)重一般按驗(yàn)證集 miou 或 loss 來(lái)存代碼里通常是「當(dāng)前指標(biāo)優(yōu)于歷史最優(yōu)就覆蓋保存」。你復(fù)現(xiàn)時(shí)如果發(fā)現(xiàn)權(quán)重文件沒(méi)更新先檢查驗(yàn)證集路徑是不是空的空驗(yàn)證集算不出指標(biāo)自然不會(huì)觸發(fā)保存。4. 推理與換自己的數(shù)據(jù)predict 腳本和「擺好數(shù)據(jù)就能訓(xùn)」的邊界4.1 推理腳本怎么用推理部分設(shè)計(jì)得很省事把待推理的眼底圖放進(jìn) inference 目錄直接運(yùn)行 predict 腳本不需要設(shè)任何參數(shù)。腳本會(huì)自動(dòng)加載最優(yōu)權(quán)重、遍歷 inference 里的圖、輸出分割結(jié)果。這對(duì)新手很友好但也意味著權(quán)重路徑和輸入尺寸是寫(xiě)死的你換權(quán)重文件或者換輸入分辨率時(shí)得去代碼里改。# 推理示意 python predict.py # 輸出默認(rèn)落在 inference/result 或類(lèi)似目錄邏輯說(shuō)明predict 腳本內(nèi)部一般做三件事——加載權(quán)重、對(duì)每張圖做和訓(xùn)練一致的預(yù)處理縮放、歸一化、前向推理后把輸出 argmax 成 mask 保存。注意預(yù)處理必須和訓(xùn)練時(shí)一致訓(xùn)練用了 0.5 到 1.5 隨機(jī)縮放推理時(shí)要用固定尺寸通常是 base_size不能也隨機(jī)否則同一張圖每次結(jié)果都不一樣。4.2 換成自己的數(shù)據(jù)要?jiǎng)幽睦镒髡哒f(shuō)「訓(xùn)練自己數(shù)據(jù)的話(huà)直接擺好數(shù)據(jù)即可」這話(huà)對(duì)了一半。擺好數(shù)據(jù)是前提但還有幾個(gè)隱含約定要滿(mǎn)足原圖和 mask 文件名要能一一對(duì)應(yīng)mask 必須是單通道灰度圖灰度值要能代表類(lèi)別。如果你的 mask 是 RGB 三通道的彩色標(biāo)注圖直接扔進(jìn)去compute_gray會(huì)掃出一堆無(wú)意義的灰度值輸出通道數(shù)就錯(cuò)了。# 把 RGB 標(biāo)注 mask 轉(zhuǎn)成單通道類(lèi)別 mask示意 import numpy as np from PIL import Image def rgb_mask_to_label(mask_path, color_map): rgb np.array(Image.open(mask_path).convert(RGB)) label np.zeros(rgb.shape[:2], dtypenp.uint8) for idx, color in enumerate(color_map): match np.all(rgb color, axis-1) label[match] idx return label邏輯說(shuō)明color_map是你標(biāo)注時(shí)用的顏色列表順序?qū)?yīng)類(lèi)別編號(hào)。轉(zhuǎn)換后保存成 png再放進(jìn) mask 目錄。這一步不做后面訓(xùn)練 loss 會(huì)異常因?yàn)榫W(wǎng)絡(luò)以為有幾十個(gè)類(lèi)別。另外數(shù)據(jù)量小的時(shí)候建議做在線(xiàn)增強(qiáng)旋轉(zhuǎn)、翻轉(zhuǎn)、彈性形變血管分割對(duì)旋轉(zhuǎn)很敏感增強(qiáng)能明顯提 miou。4.3 顯存和輸入尺寸的取舍512 尺寸、batch_size 4 是作者驗(yàn)證過(guò)的配置。你想提 batch_size 但顯存不夠常見(jiàn)做法是降到 256 尺寸再翻倍 batch但血管在 256 下會(huì)變細(xì)小血管容易丟。另一個(gè)辦法是用梯度累積攢幾個(gè) batch 再更新一次等效大 batch 但不吃顯存。我一般會(huì)先跑 256 確認(rèn)流程通再上 512 看顯存余量別一上來(lái)就拉滿(mǎn)導(dǎo)致 OOM 中斷。5. 避坑與排查訓(xùn)練不收斂、miou 虛高、推理結(jié)果全黑的常見(jiàn)原因5.1 現(xiàn)象loss 一直不降miou 卡在 0.1 附近原因最常見(jiàn)的是 mask 灰度值和輸出通道對(duì)不上。比如 mask 是 0/255但代碼按 0/1 處理或者compute_gray生成的 txt 沒(méi)被 train 腳本讀到輸出通道用了默認(rèn)值。另一個(gè)原因是圖像和 mask 沒(méi)對(duì)齊縮放時(shí)一個(gè)用了線(xiàn)性插值一個(gè)用了最近鄰標(biāo)簽錯(cuò)位。解決先打印compute_gray的返回值和 txt 內(nèi)容確認(rèn)類(lèi)別數(shù)再可視化一個(gè) batch 的原圖和 mask 疊加看血管位置是否重合。對(duì)齊問(wèn)題就統(tǒng)一 mask 用最近鄰插值。5.2 現(xiàn)象全局準(zhǔn)確率 0.95 但血管幾乎沒(méi)分出來(lái)原因這是血管分割最典型的坑。背景像素占比極高模型退化成「全預(yù)測(cè)背景」也能拿高準(zhǔn)確率。作者給的 0.95 準(zhǔn)確率必須配合 miou 0.67 一起看單看準(zhǔn)確率會(huì)被誤導(dǎo)。解決把評(píng)估指標(biāo)換成前景 iou 和 dice或者在 loss 里加類(lèi)別權(quán)重給血管類(lèi)更高權(quán)重。常見(jiàn)做法是用 dice loss 或帶權(quán)交叉熵壓住背景的主導(dǎo)地位。5.3 現(xiàn)象推理結(jié)果全黑或全白原因預(yù)處理不一致。訓(xùn)練時(shí)圖像做了歸一化比如除以 255 或減均值推理時(shí)忘了做輸入分布偏移網(wǎng)絡(luò)輸出全偏向一類(lèi)?;蛘邫?quán)重沒(méi)加載成功用了隨機(jī)初始化的網(wǎng)絡(luò)。解決把推理的預(yù)處理函數(shù)和訓(xùn)練的__getitem__對(duì)齊逐行比對(duì)。加載權(quán)重后打印幾個(gè)參數(shù)值確認(rèn)不是隨機(jī)初始化。推理前先拿一張訓(xùn)練集里的圖測(cè)訓(xùn)練集都分不對(duì)說(shuō)明權(quán)重或預(yù)處理有問(wèn)題。5.4 現(xiàn)象換自己數(shù)據(jù)后報(bào)通道數(shù)不匹配原因compute_gray生成的 txt 還是舊數(shù)據(jù)集的新數(shù)據(jù)的類(lèi)別數(shù)變了但 txt 沒(méi)重新生成網(wǎng)絡(luò)輸出通道和標(biāo)簽對(duì)不上。解決每次換數(shù)據(jù)集都刪掉舊 txt 重新跑compute_gray別偷懶復(fù)用。這一步花不了幾秒但能省掉半小時(shí)的報(bào)錯(cuò)排查。5.5 現(xiàn)象訓(xùn)練到后面 miou 突然掉下去原因?qū)W習(xí)率沒(méi)降下來(lái)或者 cos 衰減的total_epochs設(shè)錯(cuò)了導(dǎo)致后期學(xué)習(xí)率還很大把學(xué)好的權(quán)重沖亂。也可能是過(guò)擬合驗(yàn)證集 miou 掉但訓(xùn)練集還在漲。解決檢查 cos 衰減的total_epochs是否等于實(shí)際訓(xùn)練輪數(shù)過(guò)擬合的話(huà)加數(shù)據(jù)增強(qiáng)、加 dropout 或早停。血管分割數(shù)據(jù)量通常不大過(guò)擬合很常見(jiàn)早停是最省事的后悔藥。6. 把 10 個(gè) epoch 推到更高 miou幾個(gè)我反復(fù)驗(yàn)證過(guò)的調(diào)參習(xí)慣作者只跑了 10 個(gè) epoch 就到 miou 0.67這個(gè)起點(diǎn)不錯(cuò)但離可用還有距離。想把指標(biāo)往上推我一般按這個(gè)順序調(diào)先把 epoch 加到 50 到 100cos 衰減的total_epochs同步改這一步通常能漲 3 到 5 個(gè)點(diǎn)然后加數(shù)據(jù)增強(qiáng)旋轉(zhuǎn)、水平垂直翻轉(zhuǎn)、彈性形變?nèi)籽軐?duì)旋轉(zhuǎn)敏感增強(qiáng)收益明顯再考慮換 lossdice loss 和交叉熵按比例混合對(duì)細(xì)血管召回幫助大。驗(yàn)證方法上別只看最后一個(gè) epoch 的權(quán)重把驗(yàn)證集 miou 最高的那個(gè)權(quán)重單獨(dú)存一份訓(xùn)練完拿它做推理。日志里的曲線(xiàn)如果驗(yàn)證 miou 在某個(gè) epoch 后不再漲后面都是過(guò)擬合早停能省時(shí)間。我踩過(guò)的一個(gè)坑是只存了最后一個(gè) epoch 的權(quán)重結(jié)果最后幾輪過(guò)擬合指標(biāo)反而不如中間輪次只能重訓(xùn)。調(diào)整項(xiàng)建議值預(yù)期收益epoch50 到 100miou 3 到 5數(shù)據(jù)增強(qiáng)旋轉(zhuǎn) 翻轉(zhuǎn) 彈性形變小血管召回提升lossdice 交叉熵混合前景 iou 提升輸入尺寸512 起步顯存夠上 768細(xì)血管更清晰權(quán)重保存按驗(yàn)證 miou 存最優(yōu)避免過(guò)擬合權(quán)重還有一個(gè)容易忽略的點(diǎn)推理時(shí)的后處理。血管是連通的細(xì)長(zhǎng)結(jié)構(gòu)模型輸出可能有小孔洞或孤立噪點(diǎn)用形態(tài)學(xué)閉運(yùn)算填孔、去掉小于閾值的連通域miou 能再漲一點(diǎn)。但后處理參數(shù)別調(diào)太狠閉運(yùn)算核太大會(huì)把相鄰血管粘在一起反而降指標(biāo)。我一般用 3x3 核做一次閉運(yùn)算連通域面積閾值設(shè)成 50 像素左右具體看你的分辨率。從那以后我每次跑分割任務(wù)都強(qiáng)制先可視化一個(gè) batch 的原圖、mask 和預(yù)測(cè)疊加圖確認(rèn)數(shù)據(jù)對(duì)齊、標(biāo)簽正確、預(yù)處理一致再去看指標(biāo)。這一步花兩分鐘能擋掉八成玄學(xué)問(wèn)題。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取