- 中篇:PYTORCH 案例應用
第八章 圖像專案案例
第八章簡介
本章介紹圖像領域的相關案例,包括圖像分類、圖像分割、目標檢測、目標跟蹤、GAN、擴散模型等相關任務,這裡將以一個完整的項目為一節,代碼也將是獨立的,希望通過一個個完整的案例,梳理在實際任務中所涉及的各個知識點、環節。
8.1 圖像分類案例——胸部X光肺炎分類
前言
前言:時隔7個月,終於能有時間繼續撰寫本書,在這期間,生活發生了重大變化、工作內容與崗位也有不小調整,整體而言還是未來可期,接下來一段時間將開始撰寫中篇,案例應用。
本案例以胸部X光片二分類任務為案例,完整的介紹圖像分類任務的訓練過程。其中,涉及的知識點有:
- 圖片的讀取與dataset的編寫
- 資料增強策略消融實驗:手動設置資料增強,AutoAug實驗
- 基於torchvision的預訓練模型使用與替換:調用resnet、convnext模型
- 完整的訓練日誌分析
- 模型推理代碼及推理速度、輸送量計算對比
案例的講解不再拘泥於代碼細節,而是從任務分解出發,將該案例任務劃分為多個模組,並對每個模組涉及的知識點及核心代碼進行講解。
圖像分類的主代碼採用第七章第四節中的訓練腳本實現。
資料模組
首先來看資料部分,資料通過mendeley下載,得到的是ChestXRay2017.zip壓縮包,圖片已經劃分好訓練集與驗證集。
獲取資料後,需要對資料基礎情況進行瞭解,首先看目錄組織形式,便於dataset的編寫,目錄組織形式如下:
├─test
│ ├─NORMAL
│ └─PNEUMONIA
└─train
├─NORMAL
└─PNEUMONIA
資料為jpeg格式,類型為灰度圖像,長寬在600-1000圖元左右。
接下來即可編寫dataset,這裡仍舊需要dataset的基礎知識,可以快速回顧第三章 PyTorch 資料模組。
dataset配套代碼。
資料載入完成後,需要做資料增強,這裡可以手動根據任務背景知識進行手動設計,或者使用AutoAug中的資料增強策略。
手動設計
對於手動設計,這裡給出了基於torchvision的案例與albumentations的案例,分別位於train_main.py與train_aug.py
這裡要重點介紹的是albumentations的使用,需要注意的是資料normalize與totensor的地方有些不同,詳情看
A.Normalize(normMean, normStd, max_pixel_value=255.), # mean, std, 基於0-1,圖元值要求0-255,並通過max_pixel_value=255,來實現整體資料變換為0-1
ToTensorV2(), # 僅資料轉換,不會除以255
Copy
對於pytorch,totensor是會除以255的,而albumentations是在normalize中實現除以255的操作。
AutoAug
一些任務可以套用AutoAug的策略,關於自動資料增強可以回顧第三章,在代碼實現時候也需要注意將變換後的資料進行銜接,這裡主要是把資料的size變換到模型接收的大小。從代碼上看,autoaug可以理解為一個打包好的transform.compose,插入自訂的compose中即可。
auto_aug_list = torchvision.transforms.AutoAugment(transforms.AutoAugmentPolicy.IMAGENET)
train_transform = transforms.Compose([
auto_aug_list,
transforms.Resize(256),
transforms.RandomCrop(input_size, padding=4),
transforms.ToTensor(),
transforms.Normalize(normMean, normStd),
])
Copy
模型模組
關於模型的創建就很簡單了,基於CNN的模型,可以通過torchvision直接創建,並且載入imagenet的預訓練參數。
主要注意如何修改模型最後的FC層,來適應自訂任務的分類類別數。
對於提供的模型(如resnet, convnext),需要載入進來之後,debug形式的去觀察模型的結構,看看最後一個FC層的定義是什麼,然後針對性的修改。
例如:resnet50的是model.fc, convnext的是model.classifier[2],這裡就需要大家對第四章module的概念有較深入的理解。
訓練指令
resnet50
nohup python train_aug.py --data-path ./data/chest_xray --batch-size 64 --workers 16 --lr 0.01 --lr-step-size 20 --epochs 50 --model resnet50 > ./log.log 2>&1 &
nohup python train_main.py --data-path ./data/chest_xray --batch-size 64--workers 16 --lr 0.01 --lr-step-size 20 --epochs 50 --model resnet50 > ./log.log 2>&1 &
nohup python train_aug.py --data-path ./data/chest_xray --batch-size 64 --workers 16 --lr 0.01 --lr-step-size 20 --epochs 50 --model resnet50 --autoaug > ./log.log 2>&1 &
convnext
nohup python train_aug.py --data-path ./data/chest_xray --batch-size 32 --workers 16 --lr 0.01 --lr-step-size 20 --epochs 50 --print-freq 20 --model convnext > ./log.log 2>&1 &
nohup python train_main.py --data-path ./data/chest_xray --batch-size 32 --workers 16 --lr 0.01 --lr-step-size 20 --epochs 50 --print-freq 20 --model convnext > ./log.log 2>&1 &
convnext-tiny
nohup python train_aug.py --data-path ./data/chest_xray --batch-size 32 --workers 16 --lr 0.01 --lr-step-size 20 --epochs 50 --print-freq 20 --model convnext-tiny > ./log.log 2>&1 &
nohup python train_main.py --data-path ./data/chest_xray --batch-size 64 --workers 16 --lr 0.01 --lr-step-size 20 --epochs 50 --print-freq 20 --model convnext-tiny > ./log.log 2>&1 &
Copy
訓練實驗記錄
其它模組代碼都是先前腳本中有的,就不再贅述,在本案例中,做了一些對比實驗。
對比實驗一:resnet50與convnext-base/tiny的比較
對比實驗二:手動設計資料增強與AutoAug資料增強的比較
結論一:簡單場景下,resnet50適用性更好;convnext-base與convnext-tiny在本任務差別不大;
結論二:AutoAug資料增強方法稍差些,非自然圖像場景,手動設計資料增強策略效果更好;
模型名稱 |
日誌資料夾 |
acc |
---|---|---|
convnext-tiny |
2023-02-09_09-50-07 |
92.5 |
convnext-base |
2023-02-08_20-28-44 |
92.3 |
resnet50 |
2023-02-08_16-37-24 |
93.8 |
resnet50 + albumentation |
2023-02-08_17-45-29 |
94.87 |
resnet50 + autoaug |
2023-02-09_13-45-08 |
93.3 |
模型推理與時間測試
模型訓練好之後是以將模型的權重參數存儲為字典形式,放在了pt檔中,在未來使用時候需要創建模型(nn.module),然後把參數載入進去,同時需要注意在推理階段的資料前處理。
在配套代碼中,實現了一張圖片的推理,同時對resnet50的推理速度進行了評估,推理速度效率如下:
設備 |
推理速度(bs=128) |
輸送量(bs=128) |
---|---|---|
GTX 1080 Ti |
5.23 ms/例0.67s ÷ 128 = 5.23 ms |
191 幀 / 秒 1 ÷ 5.23 * 1000 = 191 |
RTX 3060 Laptop |
2.18 ms/例0.28s ÷ 128 = 2.18 ms |
459 幀 / 秒 1 ÷ 2.18 * 1000 = 459 |
Inte i7-11800H @ 2.30GHz 八核 |
41.2 ms/例 5.27s ÷ 128 = 41.2 ms |
24.3 幀 / 秒1 ÷ 41.2 * 1000 = 24.3 |
i7-7700 @ 3.60GHz |
101.8 ms/例 13.03s ÷ 128 = 101.8 ms |
9.8 幀 / 秒1 ÷ 101.8 * 1000 = 9.8 |
綜合來看,一般的cpu可以實現即時推理,gpu推理速度是cpu的10-50倍。
PS:本次推理時間測試並不充分,不可代表實際生產下的推理效率,因此需要額外注意幾個點:
- 時間測算需考慮資料前處理、後處理時間;
- 資料組batch後,可充分利用gpu資源,單位時間內推理的圖片數更多,但也需要考慮組batch的時間消耗
小結
本小節通過胸部X光片的二分類場景,詳細描述了從資料集讀取、資料增強策略、模型finetune修改、實驗對比、模型推理的各個步驟,包含代碼與理論介紹。
通過本小節,應能獨立實現圖像分類任務。