背景介绍部分参考这一篇博文:【01】有丝分裂检测—病理领域适应问题—论文解析1_TianleiShi的博客-CSDN博客
原文Github链接:https://github.com/scjjb/MIDOG_Domain_Adaptation
修改后的代码链接:
一. MIDOG预处理
- 解析MIDOG的标注文件.json → df = get_bbox_df()
- 训练集和测试集划分 → train_test_split(df)
- 图像块生成:不重叠裁剪成512*512尺寸的patch → mask_segmentor()
from PatchSeg_functions import mask_segmentor
from Data_functions import get_bbox_df, train_test_split
############ Preparation ################
## Get dataset and generate 512x512 crops from the original WSIs
df = get_bbox_df()
df_train, df_test = train_test_split(df)
image_ids=list(df['file_name'].unique())
mask_segmentor(image_ids,df,512,512,categories=['mitotic figure'],
image_folder="I:/Pathology/Dataset/MIDOG2021/image_crops/")
1. json文件解析
- 主要是两个列表元素:images和annotations
- images列表中包含200张图像信息:file_name,id,width和height
- annotation中包含了4435个标注信息:bbox坐标,category_id,image_id,id(第几个标注)
- 最终得到df,shape = {tuple: 2}(4435, 8),如下图所示
2. 训练集和测试集划分
- A、B、C三个中心分别有50张图片,每个中心以8:2的比例划分训练集和测试集【前40个为训练集,后10个为测试集】
- 分别训练三个模型,并在另外1个中心进行外部测试。eg:A+B训练,C外部测试
- 只对外部测试集进行校正,参与模型训练的数据集不进行颜色校正
二. 颜色校正
三. 细胞检测
1. U-Net分割网络实现过程
-
step1:依赖库导入,模型设置
💡 segmentation_models_pytorch 高级API:①集成了9种分割模型架构:Unet、Unet++、MAnet、Linknet、FPN、PSPNet、PAN、DeepLabV3、DeepLabV3+;②每种架构有113种可用的编码器;③所有编码器均具有预训练的权重,可更快收敛。
## Import required packages and functions
import torch
import numpy as np
import matplotlib.pyplot as plt
import gc
from torchvision import transforms
import segmentation_models_pytorch ### 一个基于PyTorch的图像分割神经网络
from segmentation_processing import preprocess_crops, get_model_predictions, add_bbox_to_map
from segmentation_modelling import create_data_loaders, train_one_epoch, metric, evaluate, F1_score_centered
from pneumothorax_segmentation.unet_pipeline.Losses import ComboLoss
## Model selection can be changed
model = segmentation_models_pytorch.Unet(
encoder_name='resnet152', # 选择解码器,例如mobilenet_v2 或 efficientnet-b7
encoder_weights='imagenet', # 使用预先训练的权重imagenet进行解码器初始化
classes=1, # 模型输出通道(数据集所分的类别总数)
activation=None, )
-
step2:数据加载
- 定义data_transforms函数,注意train和valid数据集变换不同
- preprocess_crops函数的功能如下:输入train、valid、test的patch数量,以及train scanner和test scanner;输出对应的patch索引
- create_data_loaders:数据transform以及dataloader
## train_transforms will only be used in training, not evaluation
## image_transforms will be used in training and evaluation
train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomVerticalFlip(p=0.5),
transforms.RandomAffine(degrees=90, translate=(0.1, 0.1), scale=(0.9, 1.1), shear=0.1)])
image_transforms = transforms.Compose([
transforms.ToTensor(),])
## Prepare data loaders with image crops
train_ids, valid_ids, test_ids = preprocess_crops(5000, 1000, 2000,
train_scanners=train_scanners,valid_scanners=valid_scanners)
train_loader, valid_loader, test_loader = create_data_loaders(train_ids, valid_ids,
test_ids=test_ids,image_transform=image_transforms,train_transform=train_transforms)
-
step3:训练前设置
- 损失权重:criterion = ComboLoss(**{'weights': {'bce': 2, 'dice': 1, 'focal': 10}})
-
优化器定义:optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=0.001)
-
学习率控制器:scheduler = torch.optim.lr_scheduler.MultiStepLR( optimizer, milestones=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], gamma=gamma)
💡MultiStepLR多步长衰减:固定步长衰减虽然能够按照固定的区间长度进行学习率更新,但是有时我们希望不同的区间采用不同的更新频率,或者是有的区间更新学习率,有的区间不更新学习率。动态区间长度控制。
—— 其中milestones参数为表示学习率更新的起止区间,在区间[0. 1]内学习率不更新,而在[1, 2]、[2, 3].....[9, 10]的右侧值都进行一次更新;gamma参数表示学习率衰减为上次的gamma分之一
-
step4:训练过程
- 训练一个epoch后,计算train_loss
- valid_loader前向传播,evaluate函数计算val_loss,以及f1_score
- get_model_predictions计算边界框预测结果valid_preds(每个像素点的分类概率)
- add_bbox_to_map函数将边界框参数转为图像bboxs(01掩码)
- 最后利用混淆矩阵计算f1_score得分
- 保存得分最高的模型,并绘制损失曲线和F1得分曲线
- 绘制训练集和测试集的F1得分曲线