DL00642-基于卷积神经网络U-Net实现生物医学影像分割pytorch框架实现 由于数据集标注的困难并且无法使用之前标注了部分的Mask R-CNN 实例分割数据集本次仅使用30张语义分割图像数据增强到100张进行训练得到的效果较好。在生物医学影像分析领域图像分割一直是个关键任务能帮助医生更好地理解图像结构辅助疾病诊断。这次我们就来聊聊如何基于卷积神经网络U-Net在PyTorch框架下实现生物医学影像分割。数据集的挑战与应对在这个项目中我们遭遇了数据集标注的难题。本来想用之前标注了部分的Mask R-CNN实例分割数据集却发现无法使用。无奈之下我们仅拿到了30张语义分割图像。为了满足训练需求数据增强成了我们的“救星”。通过数据增强技术把这30张图像扩充到了100张没想到最终训练得到的效果还挺不错。PyTorch实现U-Net代码解析导入必要库import torch import torch.nn as nn import torch.optim as optim from torchvision import transforms, datasets在PyTorch中这些库是基础。torch是核心库提供张量操作、自动求导等功能nn模块用于构建神经网络层optim则包含各种优化器torchvision方便处理图像数据像这里的transforms用于数据变换datasets提供了常见数据集的接口。构建U-Net网络class DoubleConv(nn.Module): def __init__(self, in_channels, out_channels): super(DoubleConv, self).__init__() self.conv nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue), nn.Conv2d(out_channels, out_channels, kernel_size3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue) ) def forward(self, x): return self.conv(x) class Down(nn.Module): def __init__(self, in_channels, out_channels): super(Down, self).__init__() self.maxpool_conv nn.Sequential( nn.MaxPool2d(kernel_size2, stride2), DoubleConv(in_channels, out_channels) ) def forward(self, x): return self.maxpool_conv(x) class Up(nn.Module): def __init__(self, in_channels, out_channels): super(Up, self).__init__() self.up nn.ConvTranspose2d(in_channels, in_channels // 2, kernel_size2, stride2) self.conv DoubleConv(in_channels, out_channels) def forward(self, x1, x2): x1 self.up(x1) diffY x2.size()[2] - x1.size()[2] diffX x2.size()[3] - x1.size()[3] x1 nn.functional.pad(x1, [diffX // 2, diffX - diffX // 2, diffY // 2, diffY - diffY // 2]) x torch.cat([x2, x1], dim1) return self.conv(x) class OutConv(nn.Module): def __init__(self, in_channels, out_channels): super(OutConv, self).__init__() self.conv nn.Conv2d(in_channels, out_channels, kernel_size1) def forward(self, x): return self.conv(x) class UNet(nn.Module): def __init__(self, n_channels, n_classes): super(UNet, self).__init__() self.n_channels n_channels self.n_classes n_classes self.inc DoubleConv(n_channels, 64) self.down1 Down(64, 128) self.down2 Down(128, 256) self.down3 Down(256, 512) self.down4 Down(512, 512) self.up1 Up(1024, 256) self.up2 Up(512, 128) self.up3 Up(256, 64) self.up4 Up(128, 64) self.outc OutConv(64, n_classes) def forward(self, x): x1 self.inc(x) x2 self.down1(x1) x3 self.down2(x2) x4 self.down3(x3) x5 self.down4(x4) x self.up1(x5, x4) x self.up2(x, x3) x self.up3(x, x2) x self.up4(x, x1) logits self.outc(x) return logitsU-Net网络结构比较独特很适合生物医学影像分割。DoubleConv类定义了两次卷积操作中间加上批归一化和ReLU激活函数能有效提取特征。Down类先进行最大池化下采样再用DoubleConv进一步提取特征逐渐缩小图像尺寸并增加通道数。Up类则相反通过转置卷积上采样然后与下采样过程中对应的特征图拼接再经过DoubleConv处理。OutConv用于输出最终的分割结果。整个UNet类把这些模块按顺序组合起来完成从输入图像到分割结果的映射。数据加载与预处理transform transforms.Compose([ transforms.Resize((256, 256)), transforms.ToTensor() ]) train_dataset datasets.ImageFolder(roottrain_data_path, transformtransform) train_loader torch.utils.data.DataLoader(train_dataset, batch_size4, shuffleTrue)这里我们定义了数据变换先把图像尺寸调整到256x256再转换成张量。然后用ImageFolder加载训练数据通过DataLoader按批次加载数据每个批次大小设为4并打乱顺序这样训练时模型能看到更丰富的数据组合提升泛化能力。训练过程device torch.device(cuda if torch.cuda.is_available() else cpu) model UNet(n_channels3, n_classes2).to(device) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr1e-4) for epoch in range(10): running_loss 0.0 for i, data in enumerate(train_loader, 0): inputs, labels data[0].to(device), data[1].to(device) optimizer.zero_grad() outputs model(inputs) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() print(fEpoch {epoch 1}, Loss: {running_loss / len(train_loader)})首先确定使用GPU还是CPU进行训练。初始化U-Net模型设置损失函数为交叉熵损失优化器选用Adam学习率设为1e-4。在训练循环中每个epoch遍历所有批次数据。每次迭代先把输入和标签数据移到指定设备上然后清空优化器梯度前向传播得到模型输出计算损失反向传播更新梯度最后记录并打印每个epoch的平均损失。DL00642-基于卷积神经网络U-Net实现生物医学影像分割pytorch框架实现 由于数据集标注的困难并且无法使用之前标注了部分的Mask R-CNN 实例分割数据集本次仅使用30张语义分割图像数据增强到100张进行训练得到的效果较好。尽管数据集一开始很有限但通过合理的数据增强结合U-Net在PyTorch中的高效实现我们还是取得了不错的生物医学影像分割效果。希望这篇博文能给同样在这个领域探索的朋友们一些启发。
基于卷积神经网络U-Net实现生物医学影像分割(PyTorch框架)
DL00642-基于卷积神经网络U-Net实现生物医学影像分割pytorch框架实现 由于数据集标注的困难并且无法使用之前标注了部分的Mask R-CNN 实例分割数据集本次仅使用30张语义分割图像数据增强到100张进行训练得到的效果较好。在生物医学影像分析领域图像分割一直是个关键任务能帮助医生更好地理解图像结构辅助疾病诊断。这次我们就来聊聊如何基于卷积神经网络U-Net在PyTorch框架下实现生物医学影像分割。数据集的挑战与应对在这个项目中我们遭遇了数据集标注的难题。本来想用之前标注了部分的Mask R-CNN实例分割数据集却发现无法使用。无奈之下我们仅拿到了30张语义分割图像。为了满足训练需求数据增强成了我们的“救星”。通过数据增强技术把这30张图像扩充到了100张没想到最终训练得到的效果还挺不错。PyTorch实现U-Net代码解析导入必要库import torch import torch.nn as nn import torch.optim as optim from torchvision import transforms, datasets在PyTorch中这些库是基础。torch是核心库提供张量操作、自动求导等功能nn模块用于构建神经网络层optim则包含各种优化器torchvision方便处理图像数据像这里的transforms用于数据变换datasets提供了常见数据集的接口。构建U-Net网络class DoubleConv(nn.Module): def __init__(self, in_channels, out_channels): super(DoubleConv, self).__init__() self.conv nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue), nn.Conv2d(out_channels, out_channels, kernel_size3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue) ) def forward(self, x): return self.conv(x) class Down(nn.Module): def __init__(self, in_channels, out_channels): super(Down, self).__init__() self.maxpool_conv nn.Sequential( nn.MaxPool2d(kernel_size2, stride2), DoubleConv(in_channels, out_channels) ) def forward(self, x): return self.maxpool_conv(x) class Up(nn.Module): def __init__(self, in_channels, out_channels): super(Up, self).__init__() self.up nn.ConvTranspose2d(in_channels, in_channels // 2, kernel_size2, stride2) self.conv DoubleConv(in_channels, out_channels) def forward(self, x1, x2): x1 self.up(x1) diffY x2.size()[2] - x1.size()[2] diffX x2.size()[3] - x1.size()[3] x1 nn.functional.pad(x1, [diffX // 2, diffX - diffX // 2, diffY // 2, diffY - diffY // 2]) x torch.cat([x2, x1], dim1) return self.conv(x) class OutConv(nn.Module): def __init__(self, in_channels, out_channels): super(OutConv, self).__init__() self.conv nn.Conv2d(in_channels, out_channels, kernel_size1) def forward(self, x): return self.conv(x) class UNet(nn.Module): def __init__(self, n_channels, n_classes): super(UNet, self).__init__() self.n_channels n_channels self.n_classes n_classes self.inc DoubleConv(n_channels, 64) self.down1 Down(64, 128) self.down2 Down(128, 256) self.down3 Down(256, 512) self.down4 Down(512, 512) self.up1 Up(1024, 256) self.up2 Up(512, 128) self.up3 Up(256, 64) self.up4 Up(128, 64) self.outc OutConv(64, n_classes) def forward(self, x): x1 self.inc(x) x2 self.down1(x1) x3 self.down2(x2) x4 self.down3(x3) x5 self.down4(x4) x self.up1(x5, x4) x self.up2(x, x3) x self.up3(x, x2) x self.up4(x, x1) logits self.outc(x) return logitsU-Net网络结构比较独特很适合生物医学影像分割。DoubleConv类定义了两次卷积操作中间加上批归一化和ReLU激活函数能有效提取特征。Down类先进行最大池化下采样再用DoubleConv进一步提取特征逐渐缩小图像尺寸并增加通道数。Up类则相反通过转置卷积上采样然后与下采样过程中对应的特征图拼接再经过DoubleConv处理。OutConv用于输出最终的分割结果。整个UNet类把这些模块按顺序组合起来完成从输入图像到分割结果的映射。数据加载与预处理transform transforms.Compose([ transforms.Resize((256, 256)), transforms.ToTensor() ]) train_dataset datasets.ImageFolder(roottrain_data_path, transformtransform) train_loader torch.utils.data.DataLoader(train_dataset, batch_size4, shuffleTrue)这里我们定义了数据变换先把图像尺寸调整到256x256再转换成张量。然后用ImageFolder加载训练数据通过DataLoader按批次加载数据每个批次大小设为4并打乱顺序这样训练时模型能看到更丰富的数据组合提升泛化能力。训练过程device torch.device(cuda if torch.cuda.is_available() else cpu) model UNet(n_channels3, n_classes2).to(device) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr1e-4) for epoch in range(10): running_loss 0.0 for i, data in enumerate(train_loader, 0): inputs, labels data[0].to(device), data[1].to(device) optimizer.zero_grad() outputs model(inputs) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() print(fEpoch {epoch 1}, Loss: {running_loss / len(train_loader)})首先确定使用GPU还是CPU进行训练。初始化U-Net模型设置损失函数为交叉熵损失优化器选用Adam学习率设为1e-4。在训练循环中每个epoch遍历所有批次数据。每次迭代先把输入和标签数据移到指定设备上然后清空优化器梯度前向传播得到模型输出计算损失反向传播更新梯度最后记录并打印每个epoch的平均损失。DL00642-基于卷积神经网络U-Net实现生物医学影像分割pytorch框架实现 由于数据集标注的困难并且无法使用之前标注了部分的Mask R-CNN 实例分割数据集本次仅使用30张语义分割图像数据增强到100张进行训练得到的效果较好。尽管数据集一开始很有限但通过合理的数据增强结合U-Net在PyTorch中的高效实现我们还是取得了不错的生物医学影像分割效果。希望这篇博文能给同样在这个领域探索的朋友们一些启发。