Advertisement

PyTorch框架——医学图像之基于深度学习MobileNetV2神经网络新冠肺炎识别分类系统

阅读量:

第一步:准备数据

4种肺部数据,新冠肺炎阳性病例,正常、肺部不透明(非COVID肺部感染)和病毒性肺炎图像:

复制代码

,总共有21161张图片,每个文件夹单独放一种

第二步:搭建模型

本文选择MobileNetV2,其网络结构如下:

第三步:训练代码

1)损失函数为:交叉熵损失函数

2)MobileNetV2代码:

复制代码
 from torch import nn

    
 import torch
    
  
    
  
    
 def _make_divisible(ch, divisor=8, min_ch=None):
    
     """
    
     This function is taken from the original tf repo.
    
     It ensures that all layers have a channel number that is divisible by 8
    
     It can be seen here:
    
     https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py
    
     """
    
     if min_ch is None:
    
     min_ch = divisor
    
     new_ch = max(min_ch, int(ch + divisor / 2) // divisor * divisor)
    
     # Make sure that round down does not go down by more than 10%.
    
     if new_ch < 0.9 * ch:
    
     new_ch += divisor
    
     return new_ch
    
  
    
  
    
 class ConvBNReLU(nn.Sequential):
    
     def __init__(self, in_channel, out_channel, kernel_size=3, stride=1, groups=1):
    
     padding = (kernel_size - 1) // 2
    
     super(ConvBNReLU, self).__init__(
    
         nn.Conv2d(in_channel, out_channel, kernel_size, stride, padding, groups=groups, bias=False),
    
         nn.BatchNorm2d(out_channel),
    
         nn.ReLU6(inplace=True)
    
     )
    
  
    
  
    
 class InvertedResidual(nn.Module):
    
     def __init__(self, in_channel, out_channel, stride, expand_ratio):
    
     super(InvertedResidual, self).__init__()
    
     hidden_channel = in_channel * expand_ratio
    
     self.use_shortcut = stride == 1 and in_channel == out_channel
    
  
    
     layers = []
    
     if expand_ratio != 1:
    
         # 1x1 pointwise conv
    
         layers.append(ConvBNReLU(in_channel, hidden_channel, kernel_size=1))
    
     layers.extend([
    
         # 3x3 depthwise conv
    
         ConvBNReLU(hidden_channel, hidden_channel, stride=stride, groups=hidden_channel),
    
         # 1x1 pointwise conv(linear)
    
         nn.Conv2d(hidden_channel, out_channel, kernel_size=1, bias=False),
    
         nn.BatchNorm2d(out_channel),
    
     ])
    
  
    
     self.conv = nn.Sequential(*layers)
    
  
    
     def forward(self, x):
    
     if self.use_shortcut:
    
         return x + self.conv(x)
    
     else:
    
         return self.conv(x)
    
  
    
  
    
 class MobileNetV2(nn.Module):
    
     def __init__(self, num_classes=1000, alpha=1.0, round_nearest=8):
    
     super(MobileNetV2, self).__init__()
    
     block = InvertedResidual
    
     input_channel = _make_divisible(32 * alpha, round_nearest)
    
     last_channel = _make_divisible(1280 * alpha, round_nearest)
    
  
    
     inverted_residual_setting = [
    
         # t, c, n, s
    
         [1, 16, 1, 1],
    
         [6, 24, 2, 2],
    
         [6, 32, 3, 2],
    
         [6, 64, 4, 2],
    
         [6, 96, 3, 1],
    
         [6, 160, 3, 2],
    
         [6, 320, 1, 1],
    
     ]
    
  
    
     features = []
    
     # conv1 layer
    
     features.append(ConvBNReLU(3, input_channel, stride=2))
    
     # building inverted residual residual blockes
    
     for t, c, n, s in inverted_residual_setting:
    
         output_channel = _make_divisible(c * alpha, round_nearest)
    
         for i in range(n):
    
             stride = s if i == 0 else 1
    
             features.append(block(input_channel, output_channel, stride, expand_ratio=t))
    
             input_channel = output_channel
    
     # building last several layers
    
     features.append(ConvBNReLU(input_channel, last_channel, 1))
    
     # combine feature layers
    
     self.features = nn.Sequential(*features)
    
  
    
     # building classifier
    
     self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
    
     self.classifier = nn.Sequential(
    
         nn.Dropout(0.2),
    
         nn.Linear(last_channel, num_classes)
    
     )
    
  
    
     # weight initialization
    
     for m in self.modules():
    
         if isinstance(m, nn.Conv2d):
    
             nn.init.kaiming_normal_(m.weight, mode='fan_out')
    
             if m.bias is not None:
    
                 nn.init.zeros_(m.bias)
    
         elif isinstance(m, nn.BatchNorm2d):
    
             nn.init.ones_(m.weight)
    
             nn.init.zeros_(m.bias)
    
         elif isinstance(m, nn.Linear):
    
             nn.init.normal_(m.weight, 0, 0.01)
    
             nn.init.zeros_(m.bias)
    
  
    
     def forward(self, x):
    
     x = self.features(x)
    
     x = self.avgpool(x)
    
     x = torch.flatten(x, 1)
    
     x = self.classifier(x)
    
     return x
    
    
    
    

第四步:统计训练过程中验证集准确率和loss变化

正确率高达93%

第五步:搭建GUI界面

第六步:整个工程的内容

有训练代码和训练好的模型以及训练过程,提供数据,提供GUI界面代码

【源码下载】GitCode,关键词【Pytorch新冠肺炎识别

整套项目源码内容包含

全部评论 (0)

还没有任何评论哟~