0

0

飞桨常规赛:PALM病理性近视病灶检测与分割 - 5月第六名方案

P粉084495128

P粉084495128

发布时间:2025-07-31 15:05:59

|

569人浏览过

|

来源于php中文网

原创

该内容围绕PALM病理性近视病灶检测与分割赛题展开,介绍了利用PaddleSeg和patta工具的实现过程。包括克隆相关库、解压数据集、生成数据列表、构建数据集,选用SFNet模型,混合多种损失函数训练,最后进行模型预测并展示结果,以完成病灶分割任务。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

飞桨常规赛:palm病理性近视病灶检测与分割 - 5月第六名方案 - php中文网

0. 赛题介绍

常规赛:PALM病理性近视病灶检测与分割由ISBI2019 PALM眼科挑战赛赛题再现,其中病理性近视病灶检测与分割的任务旨在对眼科图像进行判断,获取两种疾病的分割结果。

数据集由中山大学中山眼科中心提供800张带萎缩和脱离病变分割标注的眼底彩照供选手训练模型,另提供400张带标注数据供平台进行模型测试。图像分辨率为1444×1444,或2124124×2056。标注金标准存储为BMP图像。分割图像大小与对应的眼底图像大小相同,标签如下:

  1. 萎缩病变分割金标准:萎缩区域:0;背景:255;
  2. 脱离病变分割金标准:脱离区域:0;背景:255。

评价指标为:0.5 X F1分数 + 0.5 X Dice

飞桨常规赛:PALM病理性近视病灶检测与分割 - 5月第六名方案 - php中文网        

比赛链接: 常规赛:PALM病理性近视病灶检测与分割

1. 包准备

既然是分割任务,首先想到的是PaddleSeg。那就直接搞起来就对了。这里想到之前遥感分割中用到patta还挺不错的,这里也弄进来一起搅。

In [1]
! git clone https://gitee.com/paddlepaddle/PaddleSeg.git
! pip -q install pattaimport sys

sys.path.append('PaddleSeg')
   

2. 数据准备

2.1解压数据集

这个没啥好写的。

In [2]
! unzip -oq /home/aistudio/data/data85135/常规赛:PALM病理性近视病灶检测与分割.zip! rm -rf __MACOSX
! mv 常规赛:PALM病理性近视病灶检测与分割 dataset
   

2.2 生成数据列表

老套路了,这里按0.9进行划分的,0.9的训练数据,0.1的验证数据。只是这里将两个数据分开进行处理,分别生成数据列表。这里我做点改变就是针对有一个任务标签很少的情况,每当读到它有标签的图像,就写50次进来,希望正负样本可以更加均衡。

UP简历
UP简历

基于AI技术的免费在线简历制作工具

下载
In [4]
import osimport randomdef create_list(lab_class='Detachment', s_rate=9, ex_num=50):
    file_path = 'dataset/Train/fundus_image'
    imgs_name = os.listdir(file_path)
    random.shuffle(imgs_name)    with open('dataset/Train/' + lab_class + '_train.txt', 'w') as tf:        with open('dataset/Train/' + lab_class + '_val.txt', 'w') as ef:            for idx, img_name in enumerate(imgs_name):
                img_path = os.path.join('fundus_image', img_name)
                lab_path = img_exist('dataset/Train', \
                					 img_path.replace('fundus_image', ('Lesion_Masks/' + \
                                     lab_class)).replace('jpg', 'bmp'))                if (idx % 10 + 1) < s_rate:                    if lab_class == 'Detachment' and lab_path != 'None':                        for _ in range(ex_num):
                            tf.write(img_path + ' ' + lab_path + '\n')                    else:
                    	tf.write(img_path + ' ' + lab_path + '\n')                else:
                    ef.write(img_path + ' ' + lab_path + '\n')def img_exist(path, name):
    p = os.path.join(path, name)    if os.path.exists(p):        return name    else:        return 'None'def shuffle_txt(path, save_path):
    out = open(save_path,'w')
    lines = []    with open(path, 'r') as infile:        for line in infile:
            lines.append(line)
        random.shuffle(lines)        for line in lines:
            out.write(line)
    out.close()

create_list('Detachment', s_rate=8)
create_list('Atrophy')
shuffle_txt('dataset/Train/Detachment_train.txt', \		   'dataset/Train/Detachment_train_shuffle.txt')
   

2.3 构建数据集

构建数据集也是套路的seg的方案,只是也是分别进行了处理。

In [2]
from paddleseg.datasets import Datasetimport paddleseg.transforms as T# 构建训练集train_transforms = [
    T.RandomHorizontalFlip(),  # 水平翻转
    T.RandomRotation(),  # detachment
    T.Resize(target_size=(1024, 1024)),  # 修改大小
    T.Normalize()  # 归一化]

d_train_dataset = Dataset(
    transforms=train_transforms,
    dataset_root='dataset/Train',
    num_classes=2,
    mode='train',
    train_path='dataset/Train/Detachment_train_shuffle.txt',
    separator=' ',
)

a_train_dataset = Dataset(
    transforms=train_transforms,
    dataset_root='dataset/Train',
    num_classes=2,
    mode='train',
    train_path='dataset/Train/Atrophy_train.txt',
    separator=' ',
)# 构建验证集val_transforms = [
    T.Resize(target_size=(1024, 1024)),
    T.Normalize()
]

d_val_dataset = Dataset(
    transforms=val_transforms,
    dataset_root='dataset/Train',
    num_classes=2,
    mode='val',
    val_path='dataset/Train/Detachment_val.txt',
    separator=' ',
)

a_val_dataset = Dataset(
    transforms=val_transforms,
    dataset_root='dataset/Train',
    num_classes=2,
    mode='val',
    val_path='dataset/Train/Atrophy_val.txt',
    separator=' ',
)
   

这里也是输出测试一下,看看数据读取有没有什么问题。避免后面报一堆错不知道哪儿去找问题。还可以看看图像是否正确。

In [6]
# import numpy as np# import matplotlib# import matplotlib.pyplot as plt# %matplotlib inline# for img, lab in d_train_dataset:#     print(img.shape, lab.shape)#     plt.subplot(121);plt.imshow(img.transpose((1, 2, 0)))#     plt.subplot(122);plt.imshow(lab)#     plt.show()#     break
   

3. 模型训练

3.1 训练准备

这里选了一个我从来没用过的网路SFNet,不过有一次就会有下一次,所以就尝试下没用过的。损失混合了三种损失,两个任务需要分别进行训练。

In [7]
import paddlefrom paddleseg.models import SFNetfrom paddleseg.models.backbones import ResNet50_vdfrom paddleseg.models.losses import BCELoss, DiceLoss, LovaszHingeLoss, MixedLoss# 模型url = 'a_save_output/best_model/model.pdparams'model = SFNet(num_classes=2, backbone=ResNet50_vd(output_stride=8), \
			  backbone_indices=[0, 1, 2, 3], pretrained=url)# 训练参数epochs = 10batch_size = 4iters = epochs * len(d_train_dataset) // batch_size# 损失函数mix_losses = [BCELoss(), DiceLoss(), LovaszHingeLoss()]
mix_coef = [1, 1, 1]
mixloss = MixedLoss(mix_losses, mix_coef)
losses = {}
losses['types'] = [mixloss]
losses['coef'] = [1]# 学习率及优化器base_lr = 3e-4# lr = paddle.optimizer.lr.CosineAnnealingDecay(base_lr, T_max=(iters // 5))lr = paddle.optimizer.lr.PolynomialDecay(base_lr, 4277 // 2, end_lr=3e-8)
optimizer = paddle.optimizer.Adam(lr, parameters=model.parameters(), weight_decay=paddle.regularizer.L2Decay(1e-9))
       
2021-05-24 18:50:46 [INFO]	No pretrained model to load, ResNet_vd will be trained from scratch.
2021-05-24 18:50:46 [INFO]	Loading pretrained model from a_save_output/best_model/model.pdparams
2021-05-24 18:50:47 [INFO]	There are 354/354 variables loaded into SFNet.
       

3.2 模型训练

分别调用train即可。

In [8]
from paddleseg.core import train

train(
    model=model,
    train_dataset=d_train_dataset,
    val_dataset=d_val_dataset,
    optimizer=optimizer,
    save_dir='d_save_output',
    iters=iters,
    batch_size=batch_size,
    save_interval=int(iters / 10),
    log_iters=10,
    num_workers=0,
    losses=losses,
    use_vdl=True)
   

4. 模型预测

预测这里主要是两个问题。

  1. 由于图像缩小到了1120,所以预测得到的结果需要resize到原大小才行。
  2. 不知道是不是图像太大的问题,一使用patta就GPU炸了,所以这里的结果是没用TTA的结果。
In [1]
import paddlefrom paddleseg.models import SFNetfrom paddleseg.models.backbones import ResNet50_vdimport paddleseg.transforms as Tfrom paddleseg.core import inferimport osimport cv2from tqdm import tqdmfrom PIL import Imageimport numpy as npimport patta as ttadef nn_infer(model, model_path, imgs_path, class_name='Atrophy', is_tta=True):
    params = paddle.load(model_path)
    model.set_dict(params)
    model.eval()    if not os.path.exists('Lesion_Segmentation'):
        os.mkdir('Lesion_Segmentation')    if not os.path.exists(os.path.join('Lesion_Segmentation', class_name)):
        os.mkdir(os.path.join('Lesion_Segmentation', class_name))    # 预测结果
    transforms = T.Compose([
        T.Resize(target_size=(1024, 1024)),
        T.Normalize()
    ])    # 循环预测和保存
    for img_path in tqdm(imgs_path):
        H, W, _ = np.asarray(Image.open(img_path)).shape
        img, _ = transforms(img_path)  # 进行数据预处理
        img = paddle.to_tensor(img[np.newaxis, :])  # C,H,W -> 1,C,H,W
        # TTA
        if is_tta == True:
            tta_pres = paddle.zeros([1, 2, 1024, 1024])            for tta_transform in tta.aliases.flip_transform():
                tta_img = tta_transform.augment_image(img)  # TTA_transforms
                tta_pre = infer.inference(model, tta_img)  # 预测
                deaug_pre = tta_transform.deaugment_mask(tta_pre)
                tta_pres += deaug_pre
            pre = tta_pres / 2.
        else:
            pre = infer.inference(model, img)  # 预测
        pred = paddle.argmax(pre, axis=1).numpy().reshape((1024, 1024)).astype('uint8') * 255
        pred = cv2.resize(pred, (W, H), interpolation=cv2.INTER_NEAREST)
        pil_img = Image.fromarray(pred)
        pil_img.save(os.path.join(('Lesion_Segmentation/' + class_name), img_path.split('/')[-1].replace('jpg', 'png')), 'png')# 网络准备a_model_path='a_save_output/best_model/model.pdparams'd_model_path='d_save_output/best_model/model.pdparams'model = SFNet(num_classes=2, backbone=ResNet50_vd(output_stride=8), \
			  backbone_indices=[0, 1, 2, 3], pretrained=None)# 预测文件set_path = 'dataset/PALM-Testing400-Images'names = os.listdir(set_path)
imgs_path = []for name in names:
    imgs_path.append(os.path.join(set_path, name))# 预测nn_infer(model, a_model_path, imgs_path, class_name='Atrophy', is_tta=False)
nn_infer(model, d_model_path, imgs_path, class_name='Detachment', is_tta=False)
   

5. 结果展示

可以用matplotlib显示一下分割的结果看看。

In [6]
import numpy as npfrom PIL import Imageimport matplotlib.pyplot as plt

%matplotlib inline

img_path = 'dataset/PALM-Testing400-Images/T0225.jpg'inf_a_path = 'Lesion_Segmentation/Atrophy/T0225.png'inf_d_path = 'Lesion_Segmentation/Detachment/T0225.png'img = Image.open(img_path)
inf_a = Image.open(inf_a_path)
inf_d = Image.open(inf_d_path)
plt.figure(figsize=(15, 5))
plt.subplot(131);plt.imshow(img);plt.title('img')
plt.subplot(132);plt.imshow(inf_a);plt.title('inf_a')
plt.subplot(133);plt.imshow(inf_d);plt.title('inf_d')
plt.show()
       
               

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

387

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

571

2023.08.10

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

34

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

14

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

33

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

18

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

12

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.7万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号