U-Net: Convolutional Networks for Biomedical Image Segmentation(CVPR2015)


文章目录

  • Abstract
  • Introduction
  • Network Architecture
  • Conclusion
  • torch code

hh
源代码

Abstract

人们普遍认为,深度网络的成功训练需要成千上万个带注释的训练样本。在这篇论文中,我们提出了一个网络和训练策略,该策略依赖于数据增强的强大使用,以更有效地利用可用的注释样本该体系结构包括捕获上下文的收缩路径和支持精确定位的对称扩展路径。我们表明,这样的网络可以从很少的图像中进行端到端训练,并且在ISBI挑战中优于先前的最佳方法(滑动窗口卷积网络),以分割电子显微镜堆栈中的神经元结构。

使用在透射光显微镜图像(相位对比和DIC)上训练的相同网络,我们在这些类别中以很大的优势赢得了2015年ISBI细胞跟踪挑战赛。此外,网络速度很快。在最新的GPU上,512x512图像的分割需要不到一秒的时间。

Introduction

在本文中,我们构建了一个更优雅的架构,即所谓的“全卷积网络”[9]。我们修改和扩展了这种架构,使其适用于很少的训练图像,并产生更精确的分割;参见图1。[9]中的主要思想是通过连续的层来补充通常的收缩网络,其中池化算子被上采样算子取代。因此,这些层增加了输出的分辨率。为了定位,从收缩路径的高分辨率特征与上采样输出相结合。然后,连续的卷积层可以根据这些信息学习组装更精确的输出。

我们架构中的一个重要修改是,在上采样部分,我们也有大量的特征通道,这允许网络将上下文信息传播到更高分辨率的层因此,扩张路径或多或少与收缩路径对称,并产生u形架构。网络没有任何完全连接的层,只使用每个卷积的有效部分,即分割映射只包含像素,在输入图像中可以获得完整的上下文。该策略允许通过重叠贴图策略对任意大的图像进行无缝分割(见图2)。为了预测图像边界区域的像素,通过镜像输入图像来推断缺失的上下文。这种平铺策略对于将网络应用于大型图像非常重要,因为否则分辨率将受到GPU内存的限制。
为了实现输出分割映射的无缝平铺(参见图2),选择输入平铺大小是很重要的,这样所有2x2最大池化操作都应用于具有均匀x和y大小的层

任意大图像无缝分割的重叠贴图策略(这里是EM堆栈中的神经元结构分割)。对黄色区域的分割进行预测,需要蓝色区域内的图像数据作为输入。通过镜像推断缺失的输入数据

对于我们的任务,可用的训练数据很少,我们通过对可用的训练图像应用弹性变形来使用过度的数据增强。这允许网络学习这种变形的不变性,而不需要在注释的图像语料库中看到这些转换。这在生物医学分割中尤其重要,因为变形曾经是组织中最常见的变化,并且可以有效地模拟真实的变形。Dosovitskiy等人[2]在无监督特征学习的范围内证明了数据增强对学习不变性的价值。

在许多细胞分割任务中的另一个挑战是同一类触摸物体的分离;参见图3。为此,我们建议使用加权损失,其中触摸单元之间的分离背景标签在损失函数中获得较大的权重。

(a)原始图像。(b)叠加与地面真值分割。不同的颜色表示海拉细胞的不同实例。©生成分割蒙版(白色:前景,黑色:背景)。(d)使用逐像素的损失权值来强迫网络学习边界像素。

Network Architecture

网络体系结构如图1所示。它包括一条收缩路径(左侧)和一条扩张路径(右侧)。
收缩路径遵循卷积网络的典型架构。它由两个3x3卷积(未填充卷积)的重复应用组成,每个卷积后面都有一个整流线性单元(ReLU)和一个2x2 max池化操作,步幅为2,用于下采样在每个降采样步骤中,我们将特征通道的数量加倍

扩展路径中的每一步都包括特征映射的上采样2x2卷积(“反卷积”),将特征通道的数量减半,与收缩路径中相应裁剪的特征映射进行连接,以及两个3x3卷积,每个卷积都有一个ReLU由于在每次卷积中边界像素的损失,裁剪是必要的。在最后一层,使用1x1卷积将每个64个分量的特征向量映射到所需的类数,这个网络总共有23个卷积层。

每个蓝框对应一个多通道特征图。通道的数量表示在盒子的顶部。x-y尺寸在框的左下边缘提供。白框表示复制的特征图。箭头表示不同的操作。

Conclusion

UNet的收缩路径(左侧)进行特征提取,并且随着网络层次的加深,感受野也会逐渐扩大,分辨率低、语义强获取的是图像整体性的特征,而浅层网络呢(分辨率高、语义弱)获取的是细粒度特征。
右侧进行反卷积上采样,但因为卷积进行的下采样会导致部分边缘信息的丢失,失去的特征并不能从上采样中找回,因此作者采用了特征拼接操作来弥补,后续FPN貌似是延用了这一思想,通过横向连接将低分辨率语义强的特征和高分辨率语义弱的特征结合起来

torch code

import torch
import torch.nn as nn
import torch.nn.functional as Fclass double_conv2d_bn(nn.Module):def __init__(self,in_channels,out_channels,kernel_size=3,strides=1,padding=1):super(double_conv2d_bn,self).__init__()self.conv1 = nn.Conv2d(in_channels,out_channels,kernel_size=kernel_size,stride = strides,padding=padding,bias=True)self.conv2 = nn.Conv2d(out_channels,out_channels,kernel_size = kernel_size,stride = strides,padding=padding,bias=True)self.bn1 = nn.BatchNorm2d(out_channels)self.bn2 = nn.BatchNorm2d(out_channels)def forward(self,x):out = F.relu(self.bn1(self.conv1(x)))out = F.relu(self.bn2(self.conv2(out)))return outclass deconv2d_bn(nn.Module):def __init__(self,in_channels,out_channels,kernel_size=2,strides=2):super(deconv2d_bn,self).__init__()self.conv1 = nn.ConvTranspose2d(in_channels,out_channels,kernel_size = kernel_size,stride = strides,bias=True)self.bn1 = nn.BatchNorm2d(out_channels)def forward(self,x):out = F.relu(self.bn1(self.conv1(x)))return outclass Unet(nn.Module):def __init__(self):super(Unet,self).__init__()self.layer1_conv = double_conv2d_bn(1,8)self.layer2_conv = double_conv2d_bn(8,16)self.layer3_conv = double_conv2d_bn(16,32)self.layer4_conv = double_conv2d_bn(32,64)self.layer5_conv = double_conv2d_bn(64,128)self.layer6_conv = double_conv2d_bn(128,64)self.layer7_conv = double_conv2d_bn(64,32)self.layer8_conv = double_conv2d_bn(32,16)self.layer9_conv = double_conv2d_bn(16,8)self.layer10_conv = nn.Conv2d(8,1,kernel_size=3,stride=1,padding=1,bias=True)self.deconv1 = deconv2d_bn(128,64)self.deconv2 = deconv2d_bn(64,32)self.deconv3 = deconv2d_bn(32,16)self.deconv4 = deconv2d_bn(16,8)self.sigmoid = nn.Sigmoid()def forward(self,x):conv1 = self.layer1_conv(x)pool1 = F.max_pool2d(conv1,2)conv2 = self.layer2_conv(pool1)pool2 = F.max_pool2d(conv2,2)conv3 = self.layer3_conv(pool2)pool3 = F.max_pool2d(conv3,2)conv4 = self.layer4_conv(pool3)pool4 = F.max_pool2d(conv4,2)conv5 = self.layer5_conv(pool4)convt1 = self.deconv1(conv5)concat1 = torch.cat([convt1,conv4],dim=1)conv6 = self.layer6_conv(concat1)convt2 = self.deconv2(conv6)concat2 = torch.cat([convt2,conv3],dim=1)conv7 = self.layer7_conv(concat2)convt3 = self.deconv3(conv7)concat3 = torch.cat([convt3,conv2],dim=1)conv8 = self.layer8_conv(concat3)convt4 = self.deconv4(conv8)concat4 = torch.cat([convt4,conv1],dim=1)conv9 = self.layer9_conv(concat4)outp = self.layer10_conv(conv9)outp = self.sigmoid(outp)return outpmodel = Unet()
inp = torch.rand(10,1,224,224)
outp = model(inp)
print(outp.shape)
==> torch.Size([10, 1, 224, 224])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/240007.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netty 与 RPC(一)

Netty 与 RPC Netty 原理 Netty 是一个高性能、异步事件驱动的 NIO 框架,基于 JAVA NIO 提供的 API 实现。它提供了对TCP、UDP 和文件传输的支持,作为一个异步 NIO 框架,Netty 的所有 IO 操作都是异步非阻塞的,通过 Future-List…

React学习计划-React16--React基础(四)生命周期和diffing算法,key的作用

1. 生命周期 1. 声命周期的三个阶段(旧) 初始化阶段:由ReactDOM.render()触发—初次渲染 1. constructor() 2. componentWillMount() 3. render() 4. componentDidMount() > 常用一般在这个钩子中做一些初始化的事情,例如&am…

亚马逊测评的重要性和技术选择

亚马逊测评是指卖家通过各种途径,如测评平台、社区、红人等,联系到亚马逊的买家,让其对卖家的产品进行评价和留下真实的综合评价,这对于跨境电商卖家来说非常重要,因为亚马逊的排名和转化率很大程度上取决于产品的评价…

Python代码示例 | 时间序列数据的组成

时间序列数据是以固定的时间间隔记录或收集的数据点序列。它是一种跟踪变量随时间演变的数据,如销售,股票价格,温度等。定期的时间间隔可以是每天,每周,每月,每季度或每年,数据通常表示为线图或…

Java小案例-Bean是如何注入到Spring中的,有几种注入方式

前言 关于Bean注入Spring容器的方式网上也有很多相关文章,但是很多文章可能会存在以下常见的问题 注入方式总结的不全 没有分析可以使用这些注入方式背后的原因 没有这些注入方式在源码中的应用示例 ... 所以本文就带着解决上述的问题的目的来重新梳理一下Bea…

关于增强监控以检测针对Outlook Online APT活动的动态情报

一、基本内容 2023年6月,联邦民事行政部门(FCEB)在其Microsoft 365(M365)云环境中发现了可疑活动。该机构迅速向Microsoft和网络安全和基础设施安全局(CISA)报告了此情况。经过深入调查&#x…

【数字通信原理】复习笔记

哈喽ノhi~ 小伙伴们许久没有更新啦~ 花花经历了漫长的考试周~ 要被累成花干啦。今天来更新《数字通信原理》手写笔记给需要的小伙伴~ (注:这是两套笔记,是需要结合来看的哦~) 第一套的笔记请结合bilibili:张锦皓的复习课程来哦。 第…

图神经网络并在 TensorFlow 中实现

asokraju.medium.com 一、说明 本文将引导您了解图神经网络 (GNN) 并使用 TensorFlow 实现该网络。在后续的 文章中,我们讨论 GNN 的不同变体及其实现。这是一个分步计划: 图神经网络 (GNN) 的使用:我们首先讨论 GNN 是什么、它们如何工作以及…

Leetcode—415.字符串相加【简单】

2023每日刷题(六十八) Leetcode—415.字符串相加 实现代码 class Solution { public:string addStrings(string num1, string num2) {string ans;int len1 num1.size();int len2 num2.size();int i len1 - 1, j len2 - 1;int sum 0, c 0;while(i…

MFC 自定义压缩,解压缩工具

界面效果如下: 对外提供的接口如下: public: void setCallback(zp::Callback callback, void* param); bool open(const zp::String& path, bool readonly false); bool create(const zp::String& path, const zp::String& inputPath)…

关于“Python”的核心知识点整理大全37

目录 13.6.2 响应外星人和飞船碰撞 game_stats.py settings.py alien_invasion.py game_functions.py ship.py 注意 13.6.3 有外星人到达屏幕底端 game_functions.py 13.6.4 游戏结束 game_stats.py game_functions.py 13.7 确定应运行游戏的哪些部分 alien_inva…

C#学习笔记 - C#基础知识 - C#从入门到放弃 - C# 结构、类与属性

C# 入门基础知识 - C# 结构、类与属性 第9节 结构、类与属性9.1 结构的使用9.2 枚举9.3 面向对象概述9.4 类与对象的关系9.5 类的声明9.6 属性的使用9.6.1 属性9.6.2 属性使用 9.7 构造函数和析构函数9.7.1 构造函数9.7.2 析构函数 9.8 类的继承9.9 类的封装9.10 类的多态 更多…

非阻塞 IO(NIO)

文章目录 非阻塞 IO(NIO)模型驱动程序应用程序模块使用 非阻塞 IO(NIO) 上一节中 https://blog.csdn.net/tyustli/article/details/135140523,使用等待队列头实现了阻塞 IO 程序使用时,阻塞 IO 和非阻塞 IO 的区别在于文件打开的时候是否使用了 O_NONB…

Zookeeper的学习笔记

Zookeeper概念 Zookeeper是一个树形目录服务,简称zk。 Zookeeper是一个分布式的、开源的分布式应用程序的协调服务 Zookeeper提供主要的功能包括:配置管理,分布式锁,集群管理 Zookeeper命令操作 zk数据模型 zk中的每一个节点…

15-高并发-如何扩容

对于一个发展初期的系统来说,不太确定商业模型到底行不行,最好的办法是按照最小可行产品方法进行产品验证,因此,刚开始的功能会比较少,是一个大的单体应用,一般按照三层架构进行设计开发,使用单…

数字信号的理解

1 数字信号处理简介 数字信号处理 digital signal processing(DSP)经常与实际的数字系统相混淆。这两个术语都暗示了不同的概念。数字信号处理在本质上比实际的数字系统稍微抽象一些。数字系统是涉及的硬件、二进制代码或数字域。这两个术语之间的普遍混…

理解按需自动导入 unplugin-auto-import unplugin-vue-components

文章目录 unplugin-auto-import基础使用构建工具引入插件配置插件 import:配置自动导入规则使用预设自动引入第三方库自动导入 TypeScript 类型vue 预设的自动导入配置 dts:让编辑器环境识别 ts 类型eslintrc:解决 eslint 检查错误dirs&#…

使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错问题

目录 1、问题说明 2、问题分析思路 3、问题分析过程 3.1、使用Dependency Walker打开软件主程序,查看库与库的依赖关系,查看出问题的库 3.2、使用PE工具查看dll库的时间戳 3.3、解决办法 4、最后 VC常用功能开发汇总(专栏文章列表&…

链表常见题型(1)

1.反转链表 1.1反转链表 如果我们想要反转链表,那应该有head的next指针指向空,其余结点的next指针反过来,指向它的上一个结点,那我们在执行该操作的时候就需要定义变量cur(current)表示我们当前遍历到的结点,变量pre(…

【后台报错】插入时sql报错,varchar撑爆

后台的一个报错。按照正常的需要复现,或者查一下日志。但是凭借多年经验和大胆猜测,以及对自己代码要自信 引用一下文章 目测7*15 105项。每个id有9个数字加上分隔符刚好十个。大概就是超过了定义的一千的varchar长度。直接改数据库就好了。 简单粗暴…