糖尿病视网膜病变检测 (Diabetic Retinopathy Detection)


前言

我们今年是一个实践就是 糖尿病视网膜病变检测
这个题目是kaggle的一个竞赛原题,Diabetic Retinopathy Detection。
只不过kaggle上是五分类,而我们是四分类。


一、任务目标

这次任务的数据集是1000的糖网的4个等级的眼底图像,我们需要利用深度学习框架pytorch 来根据眼底图像预测其分类。
在这里插入图片描述
在这里插入图片描述

二、数据处理

1.数据分析

通过对数据统计可以得到(已经划分的训练集):
在这里插入图片描述
图片种类的分布是有一点不均匀的,同时图片数量也有一点少,所以我们先简单的对图片数据进行一下扩充,这里我们使用最简单的图片反转作为数据增强的方式。我们对一类的图片进行的左右翻转和上下翻转,扩充为原来的三倍。对二类和三类的图片我们做了上下翻转,扩充到原来的二倍。对零类图片不做任何处理。
在这里插入图片描述
这是处理后的训练集分布。
我是7:3分割的训练集和验证集

2.模型训练


2.1模型准备

使用的模型是torchvision.model里的经典模型和预训练好的参数。

from torchvision import models as models
# inception_v3,ResNet50
model = models.resnet50(pretrained=True)
#将pretrained置为true,意思是使用已经预训练好的参数。
model.fc#打印模型全连接层的输入和输出参数
#Linear(in_features=2048, out_features=1000, bias=True)

因为我们是四分类所以调整模型输出为:

model.fc = torch.nn.Linear(in_features=2048, out_features=4, bias=True)
model.aux_logits = False #这个设置是InceptionV3这个模型需要设置的,
#不知道什么意思,但不设置会报错。

2.2参数设置

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device=device)
learning_rate = 1e-4
num_epochs = 10
batch_size = 32
optimizer = torch.optim.Adam(model.parameters(), lr = learning_rate)
loss_criterion = torch.nn.CrossEntropyLoss()

2.3读取数据并转换为tensor类型

这一部分我是定义了一个类mydataset继承父类Dataset来获取可迭代的数据对象,同时对图片的处理和transform转换也在这里面实现。这里就不多说,对dataset不懂得可以看我之前写的dataset类。直接贴代码。

my_transform = transforms.Compose([
    transforms.Resize((299,299)),
    transforms.ToTensor(),
#     transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
#这里进行transform是因为inception_v3模型的输入是(299*299)
#resnet就不需要是(299*299)了
class retinaDataset(Dataset):
    def __init__(self, imagepath=r"D:\course\junior_2\deep_learning\third\train", csv_path=" ",transform=my_transform):
        self.df = pd.read_csv(csv_path)
        
        # if (total is not None):
        #     self.df = self.df[:total]
        self.transform = transform
        self.imagepath = imagepath
        
    def __len__(self):
        return len(self.df)
    
    def __getitem__(self, index):
        img_path = os.path.join(self.imagepath, self.df.iloc[index].image +".png")
        img = Image.open(img_path)
        if(self.transform):
            img = self.transform(img)
        return img, torch.tensor(self.df.iloc[index].Retinopathy_grade)
train_dataset = retinaDataset(csv_path=r"D:\course\junior_2\deep_learning\mythird\train.csv")

train_dataloader = DataLoader(dataset=train_dataset, 
batch_size=batch_size, shuffle=True)
#这里调用Dataloder函数对数据进行分组并打乱顺序。

2.4开始训练

for epoch in range(num_epochs):
    for data, target in tqdm(train_dataloader):
        data = data.to(device=device)
        target = target.to(device=device)
        
        score = model(data)
        optimizer.zero_grad()
        
        
        loss = loss_criterion(score, target)
        loss.backward()
        
        optimizer.step()
    
    print(f"for epoch {epoch}, loss : {loss}")

2.5测试模型准确率

def f_check_accuracy(model_i,model_r, loader):
    model_i.eval() #模型inception_v3
    model_r.eval() #模型resnet50
    num0=0
    num1=0
    num2=0
    num3=0
    total0=0
    total1=0
    total2=0
    total3=0
    correct_output = 0
    total_output = 0
    
    with torch.no_grad(): #反向传播时不再自动求导,节省显存。
        for x, y in tqdm(loader):
            x = x.to(device=device)
            y = y.to(device=device)
            
            score_i = model_i(x)
            score_r = model_r(x)
            _,predictions_i = score_i.max(1)
            _,predictions_r = score_r.max(1)
            for i in range (len(y)):
                if(y[i]==0):
                    total0=total0+1
                    if(predictions_i[i]==0):
                        num0=num0+1
                elif(y[i]==1):
                    total1=total1+1
                    if(predictions_r[i]==1):
                        num1=num1+1
                elif(y[i]==2):
                    total2=total2+1
                    if(predictions_r[i]==2):
                        num2=num2+1   
                elif(y[i]==3):
                    total3=total3+1
                    if(predictions_i[i]==3):
                        num3=num3+1 
            correct_output =num0+num1+num2+num3
            total_output =total0+total1+total2+total3
            
    # model.train()
    print("0类准确率",num0/total0,"correct:",num0,"total:",total0)
    print("1类准确率",num1/total1,"correct:",num1,"total:",total1)
    print("2类准确率",num2/total2,"correct:",num2,"total:",total2)
    print("3类准确率",num3/total3,"correct:",num3,"total:",total3)
    print(f"out of {total_output} , total correct: {correct_output} with an accuracy of {float(correct_output/total_output)*100}")

解释一下我为什么要把inception_v3和resnet50结合到一起。
在这里插入图片描述
我们可以看到v3和resnet50再不同种类的准确率不同。所以可以把这两个模型结合在一起来提高准确率。
在这里插入图片描述
可以看到准确率提升的效果很好,大约20个点左右。
我们还可以从kaggle中下载一些数据来补充训练集,因为1000图片在划分之后对于四分类的任务来说是不够的。

三、未完成的问题

这行代码的作用。

model.aux_logits = False
  • 7
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Brandy_Whisky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值