本文解读内容是IBN-Net, 笔者最初是在很多行人重识别的库中频繁遇到比如ResNet-ibn这样的模型,所以产生了阅读并研究这篇文章的兴趣,文章全称是: 《Two at Once: Enhancing Learning and Generalization Capacities via IBN-Net》。IBN-Net和SENet非常相似:

  • 可以方便地集成到现有网络模型中。
  • 在多个视觉任务中有着出色的表现,如分类、分割。
  • 拿到了比赛第一名,IBN-Net拿到了 WAD 2018 Challenge Drivable Area track ,一个分割比赛的第一名。SENet拿到了最后一届ImageNet比赛的冠军。

1. 概述

IBN-Net出发点是:提升模型对图像外观变化的适应性。在训练数据和测试数据有较大的外观差异的时候,模型的性能会显著下降,这就是不同域之间的gap。比如训练数据中的目标光线强烈,测试数据中的目标光线昏暗,这样一般效果都不是很好。

之前有一个群友就是在研究一个域的数据如何迁移到另外一个分布不一致的域中的问题,当时认为在机器学习中训练的数据和测试数据的分布应该尽可能一致,这样才符合要求。但是实际应用中不可避免遇到训练数据无法将所有情况下(色调变化,明暗变化 )的数据都收集到,所以如何提升模型对图像外观变化的适应性、如何提高模型在不同域之间的泛化能力也是一个非常值得研究的课题。

IBN-Net能够有效提升模型在一个域中的效果(比如cityscapes-真实场景的数据),同时可以做到不fine-tuning就可以泛化到另外一个域中(比如GTA5-非真实场景的数据)。

文章主要有三个贡献:

  • 通过深入IN和BN,发现IN对目标的外观变化具有不变性,比如光照、颜色、风格、虚拟和现实,BN可以保存内容相关的信息。
  • IBN-Net可以应用到现有的STOA网络架构中,比如DenseNet, ResNet, ResNeXt, SENet等网络中,可以再不增加模型计算代价的情况下,有效提升模型的效果。
  • IBN-Net域适应能力非常强,在cityscape数据集训练的模型,不需要再GTA5上fine-tuning就可以有比较可观的效果。

2. 方法

(b) 图是对原图进行亮度调整和色彩平移(c)图是对原图使用了两种风格化方法 (d)图是对(c)图使用Instance Norm以后的结果,这说明IN可以过滤掉复杂的外观差异。

通常IN用于处理底层视觉任务,比如图像风格化,而BN用于处理高层视觉任务,比如目标检测,图像识别等。IBN-Net首次将BN和IN集成起来,同时提高了模型的学习能力和泛化能力。

此外,IBN-Net设计原则是:

  • 在网络的浅层同时使用IN和BN
  • 在网络的深层仅仅使用BN

作者做了一个实验,下图展示了随着网络深度的变化,特征差异的变化情况:

蓝色代表外观差异带来的特征差异,橙色代表图片内容之间的特征差异。可以看出在浅层是由外观差异带来的特征差异,这部分可以使用BN和IN联合起来解决;在深层网络,外观差异带来的特征差异已经非常小了,内容之间的差异是主导地位,所以这部分使用BN来解决。

这部分是论文的核心,作者提出了两个结合BN和IN的模块,IBN-a和IBN-b。(a)图其实是ResNet中的一个残差模块,(b)和(c)图都是在此基础上融入了IN和BN

  • 具体哪个算浅层哪个算深层?

ResNet由4组残差块组成,在IBN-Net的改进中,仅仅在Conv2_x, Conv3_x, Conv4_x三个块中加入IN,Conv5_x不进行改动。

  • IBN-a的改动理由:

第一,在ResNet论文中说明了恒等映射路径的必要性,所以IN应该添加在残差路径上。

第二,残差网络可以用以下公式来表达:

\[y=F(x, \{W_i\})+x
\]

其中的\(F(x,\{W_i\})\)是为了能够得到与恒等映射路径对齐的特征,所以IN被添加在残差模块中第一个卷积以后,而不是最后一个卷积以后,这样可以防止特征出现不对齐的问题。

第三,根据之前提到的设计原则,浅层应当同时使用BN和IN,所以选择将一半通道通过BN计算,另一半通道通过IN进行计算。

  • IBN-b的改动理由:

为了更充分地利用IN来提高模型的泛化的能力,对IBN-a进行了改进。作者认为目标的表观信息将保留在残差路径或者恒等映射路径上,所以可以考虑将IN直接添加在加法之后。同时需要说明的是和IBN-a不同,IBN-b使用的范围是(Conv2_x和Conv3_x)

除了上述两种BN和IN结合方法,作者还探索出更多变体,如下图所示:

(a)图中,IBN-c的做法是将IN和BN分成两路,然后将得到的特征进行concate。

(b)图中,IBN-d的做法是在IBN-b基础上进行了改动,对其中一半通道的feature map施加IN。

(c)图中,IBN-a&d的做法很显然结合了IBN-a和IBN-d

(d)图中,IBN-ax2在IBN-a基础上,多增加了一对BN和IN,用于测试添加更多BN和IN是否能够提升模型泛化能力。

IBN-a和IBN-b代码:

这部分代码来自: https://github.com/pprp/reid_for_deepsort

IBN-a:

class IBN(nn.Module):
def __init__(self, planes):
super(IBN, self).__init__()
half1 = int(planes / 2)
self.half = half1
half2 = planes - half1
self.IN = nn.InstanceNorm2d(half1, affine=True)
self.BN = nn.BatchNorm2d(half2) def forward(self, x):
split = torch.split(x, self.half, 1)
out1 = self.IN(split[0].contiguous())
out2 = self.BN(split[1].contiguous())
out = torch.cat((out1, out2), 1)
return out

IBN-b:

class Bottleneck(nn.Module):
expansion = 4 def __init__(self, inplanes, planes, stride=1, downsample=None, IN=False):
super(Bottleneck, self).__init__()
self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(
planes,
planes,
kernel_size=3,
stride=stride,
padding=1,
bias=False
)
self.bn2 = nn.BatchNorm2d(planes)
self.conv3 = nn.Conv2d(
planes, planes * self.expansion, kernel_size=1, bias=False
)
self.bn3 = nn.BatchNorm2d(planes * self.expansion)
self.IN = None
if IN:
self.IN = nn.InstanceNorm2d(planes * 4, affine=True)
self.relu = nn.ReLU(inplace=True)
self.downsample = downsample
self.stride = stride def forward(self, x):
residual = x out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out) out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out) out = self.conv3(out)
out = self.bn3(out) if self.downsample is not None:
residual = self.downsample(x) out += residual
if self.IN is not None:
out = self.IN(out)
out = self.relu(out) return out

3. 实验

可以看到,IBN-a可以提升在原先域(训练数据)内的泛化能力,比原来ResNet50要高1-2个百分点。IBN-b可以提升在目标域(训练数据中未出现的数据)的泛化能力,可以看到要比ResNet50提高4个百分点。

上图是采用了不同的外观转换比如RGB直接+50,R+50等方法,可以发现,依然遵从上一条发现,IBN-a可以提升原有域的泛化能力,IBN-b可以提升目标域的泛化能力,可以看到除了Monet风格化对IBN-b影响稍大,其他几种影响非常之小。

可以看到,IBN-a最好是施加在前三个block中,效果最好。

这个比例是IN/BN, 可以看出IN/BN=0.25的时候top1 最好,IN/BN=0.5的时候top5最好,一般默认还是设置为0.5.

以上是分类问题,再来看看分割问题,cityscape数据集和GTA5数据集上的结果如下:

可以看到,训练集和测试集来自同一个数据的时候,IBN-a模型的mIoU是能够比原模型ResNet50高4个百分点。而训练集和测试集不同的时候,IBN-b模型更占优势,说明IBN-b能够在跨域的问题上表现更好。

上图的实验还可以证明IBN-a和ResNet50同时在目标域进行fine tuning, IBN-a微调的效果要远远好于ResNet50。

4. 总结

IBN-Net中有几个重要结论,在总结部分梳理一下:

  • IBN-Net在浅层同时使用IN和BN,深层网络仅仅使用BN。

  • IBN-Net中有两个出色的模型IBN-a和IBN-b,IBN-a适用于当前域和目标域一致的问题,比如说提升ResNet50的分类能力,可以用IBN-a,并且IBN-a微调以后结果是比原模型结果更好的。

  • IBN-b适合使用在当前域和目标域不一致的问题,比如说在行人重识别中,训练数据是在白天收集的,但是想在黄昏的时候使用的时候。这也是为何IBN-Net在行人重识别领域用的非常多的原因。

  • cityscape和GTA5这个实验非常有说服力,证明了IBN-Net的泛化能力,效果提升非常明显,在分割问题上对模型带来的提升效果更大。

5. 参考

https://arxiv.org/pdf/1512.03385

https://arxiv.org/pdf/1807.09441

https://github.com/XingangPan/IBN-Net

https://github.com/pprp/reid_for_deepsort/tree/master/models

IBN-Net: 提升模型的域自适应性的更多相关文章

  1. Bert文本分类实践(三):处理样本不均衡和提升模型鲁棒性trick

    目录 写在前面 缓解样本不均衡 模型层面解决样本不均衡 Focal Loss pytorch代码实现 数据层面解决样本不均衡 提升模型鲁棒性 对抗训练 对抗训练pytorch代码实现 知识蒸馏 防止模 ...

  2. NLP(十八)利用ALBERT提升模型预测速度的一次尝试

    前沿   在文章NLP(十七)利用tensorflow-serving部署kashgari模型中,笔者介绍了如何利用tensorflow-serving部署来部署深度模型模型,在那篇文章中,笔者利用k ...

  3. 【漏洞复现篇】CVE-2020-1472-微软NetLogon权限提升-手把手教学-简单域环境搭建与Exp执行

    一.漏洞简介 NetLogon 远程协议是一种在 Windows 域控上使用的 RPC 接口,被用于各种与用户和机器认证相关的任务.最常用于让用户使用 NTLM 协议登录服务器,也用于 NTP 响应认

  4. Java内存模型-final域的内存语义--没明白,预留以后继续理解

    https://www.cnblogs.com/yuanfy008/p/9349275.html 来自 Java并发编程(1)-Java内存模型

  5. Java内存模型-final域的内存语义

    一 引言 说到final你肯定知道它是Java中的关键字,那么它所在Java中的作用你知道吗?不知道的话,请前往这篇了解下https://www.cnblogs.com/yuanfy008/p/802 ...

  6. (转载)ECCV 2018:IBN-Net:打开域适应的新方式

    (本文转自极视角) 本文由香港中文大学发表于ECCV2018,论文探索了IN和BN的优劣,据此提出的IBN-Net在语义分割的域适应任务上取得了十分显著的性能提升. 论文地址:https://arxi ...

  7. .net架构设计读书笔记--第三章 第8节 域模型简介(Introducing Domain Model)

    一.数据--行为转变     很长的时间,典型的分析方法或多或少是以下两种,第一,收集需求并做一些分析,找出有关实体 (例如,客户. 订单. 产品) 和进程来实现. 第二,手持这种理解你尝试推断一个物 ...

  8. django “如何”系列3:如何编写模型域(model filed)

    django自带很多的域类--CharField,DateField等等--,如果django的这些域都不能满足你精确的要求,那么你可以编写自己的模型域. django自带的域没有和数据库列类型一一对 ...

  9. C++11 并发指南七(C++11 内存模型一:介绍)

    第六章主要介绍了 C++11 中的原子类型及其相关的API,原子类型的大多数 API 都需要程序员提供一个 std::memory_order(可译为内存序,访存顺序) 的枚举类型值作为参数,比如:a ...

随机推荐

  1. 关于Html+css阶段学习总结

    一.学习经历 进入大学不久,就加入了社团,从而对前端有了一个初步的了解,之后也做过一些学校的官网,积累了一些微小的经验. 到了大二的时候,学校开设了专门的html+css课程,从中也学到许多新的htm ...

  2. css的相对定位与绝对定位

    css相对定位:是相对于它本身最近的父级定位 css绝对定位:是对于它本身最接近的参照物来定位,如果没有就对于body来定位

  3. 《即时消息技术剖析与实战》学习笔记11——IM系统如何保证服务高可用:流量控制和熔断机制

    IM 系统的不可用主要有以下两个原因: 一是无法预测突发流量,即使进行了服务拆分.自动扩容,但流量增长过快时,服务已经不可用了: 二是业务中依赖的这些接口.资源不可用或变慢时,比如发消息可能需要依赖& ...

  4. startUML5.0中的tools下怎么没有java、c等选项

    这也是帮一个直系学妹弄得,哈哈~~~ 具体做法如下: 进入到StartUML\modules目录下,里面有很多文件夹,比如startuml-cpp.startuml-csharp等等, 进入到每个文件 ...

  5. HTML5 基础知识(1)——基本标签

    ## HTML**概念**:是最基础的网页开发语言(Hyper Text Markup Langage 超文本标记语言) > 1.超文本:超文本是用超链接的方式i,将各种不同空间的文字组织在一起 ...

  6. 在Java中使用Collections.sort 依据多个字段排序

    一.如何使用Collections工具类进行排序 使用Collections工具类进行排序主要有两种方式: 1.对象实现Comparable接口,重写compareTo方法 /** * @author ...

  7. 按 ctrl 时会触发 shift ,导致不能正常使用 ctrl + c 复制

    问题描述 不能使用 ctrl 功能键组合,原因是按 ctrl 时 shift 也会被触发. win 10 电脑为例,可以打开虚拟键盘查看按键情况. 当我按下 ctr时 可见 shift 也被触发了. ...

  8. SpringBoot 集成MQTT配置

    目录 1. 前言 2. MQTT介绍 3. SpringBoot 集成MQTT 3.1 导入mqtt库 3.2 配置MQTT订阅者 3.3 配置MQTT发布者 3.4 MQTT消息处理和发送 3.4. ...

  9. asp.net core 3.1 引用的元包dll版本兼容性问题解决方案

    自从.netcore 3.1出来后,大家都想立马升级到最新版本.我也是如此,微软也对.netcore 3.1的官方组件不断升级,几乎每隔几天就会有部分元包可以升级.每次打开Nuget包管理器,“更新” ...

  10. ASP.NET Core应用的7种依赖注入方式

    ASP.NET Core框架中的很多核心对象都是通过依赖注入方式提供的,如用来对应用进行初始化的Startup对象.中间件对象,以及ASP.NET Core MVC应用中的Controller对象和V ...