首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

论文笔记(9):Non-local neural networks

  • 25-03-03 17:02
  • 3815
  • 13058
blog.csdn.net

Non-local neural networks

CVPR2018

Local & non-local

Local这个词主要是针对感受野(receptive field)来说的。以卷积操作为例,它的感受野大小就是卷积核大小,而我们一般都选用 3 ∗ 3 3*3 3∗3, 5 ∗ 5 5*5 5∗5之类的卷积核,它们只考虑局部区域,因此都是local的运算。同理,池化(Pooling)也是。但其实全局的信息对于图像的任务更有价值,比如短视频分类任务等等。相反的,non-local指的就是感受野可以很大,而不是一个局部领域。

那我们碰到过什么non-local的操作吗?有的,全连接就是non-local的,而且是global的。但是全连接FC带来了大量的参数,给优化带来困难。这也是深度学习(主要指卷积神经网络)近年来流行的原因,考虑局部区域,参数大大减少了,能够训得动了。

那我们为什么还需要non-local?

我们知道,卷积层的堆叠可以增大感受野,但是如果看特定层的卷积核在原图上的感受野,它毕竟是有限的。这是local运算不能避免的。然而有些任务,它们可能需要原图上更多的信息,比如attention。**如果在某些层能够引入全局的信息,就能很好地解决local操作无法看清全局的情况,为后面的层带去更丰富的信息。**这是我个人的理解。

网络模型

Non-local block模型计算

本文的non-local可以被封装成一个block,用于任何网络。把position当成了一个权重,这里的position可以指空间,时间,或者时空关系,计算全局的关联性。

视频中第一帧的A1区域和第十帧中A3区域有关联性,或者静态图像中,有些区域有关系,如果找到这些关系,就可以更好的分析目标整体的动作。

文章对于non-local运算的设计。为了能够当作一个组件接入到以前的神经网络中,作者设计的non-local操作的输出跟原图大小一致,具体来说,是下面这个公式:
y i = 1 C ( x ) ∑ ∀ j f ( x i , x j ) g ( x j ) (1) \mathrm{y}_{i}=\frac{1}{\mathcal{C}(\mathrm{x})} \sum_{\forall j} f\left(\mathrm{x}_{i}, \mathrm{x}_{j}\right) g\left(\mathrm{x}_{j}\right) \tag{1} yi​=C(x)1​∀j∑​f(xi​,xj​)g(xj​)(1)

  • i i i 表示输出的索引,可以是空间上的、时间上的、时空上的索引位置;
  • j j j 表示所有可能位置的索引,用来做与输出位置的相关性的比较,(输入为两个位置,输出为一个位置关于另一个位置的关系);
  • x x x 是输入的向量(可以是图片,序列,视频,或者是特征), y y y是输出的向量(与输入形状相同)
  • f ( ⋅ , ⋅ ) f(\cdot,\cdot) f(⋅,⋅)是一个计算任意两点( i i i点和 j j j点)关系的函数(可以是相关性),相当于找到了当前图片或特征图中每个像素与其他所有位置像素的归一化相关性;
  • g ( ⋅ ) g(\cdot) g(⋅) 是一个一元函数,计算一个点的特征,将这个点映射成一个向量
  • 1 C ( x ) \frac{1}{C(x)} C(x)1​归一化参数

相似函数的问题

以图像为例,为了简化问题,作者简单地设置 g ( ⋅ ) g(\cdot) g(⋅)函数为一个 1 ∗ 1 1*1 1∗1的卷积。相似性度量函数 f ( ⋅ , ⋅ ) f(\cdot,\cdot) f(⋅,⋅)的选择有多种:

  • Gaussian:
    f ( x i , x j ) = e x i T ⋅ x j C ( x ) = ∑ ∀ j f ( x i , x j ) f(xi,xj)=exTi⋅xjC(x)=∑∀jf(xi,xj)
    f(xi,xj)C(x)=exTi⋅xj=∑∀jf(xi,xj)
    f(xi​,xj​)C(x)​=exiT​⋅xj​=∀j∑​f(xi​,xj​)​

image-20201222155017573

其中 x i T x j x_{i}^{T} x_{j} xiT​xj​是点乘相似度(dot-product similarity)。也可以用欧式距离,但是点乘在深度学习平台上更好实现。此时归一化参数 C ( x ) = ∑ ∀ j f ( x i , x j ) \mathcal{C}(x)=\sum_{\forall j} f\left(\mathrm{x}_{i}, \mathrm{x}_{j}\right) C(x)=∑∀j​f(xi​,xj​)。

  • Embedded Gaussian:

f ( x i , x j ) = e θ ( x i ) T ⋅ ϕ ( x j ) C ( x ) = ∑ ∀ j f ( x i , x j ) f(xi,xj)=eθ(xi)T⋅ϕ(xj)C(x)=∑∀jf(xi,xj)

f(xi,xj)C(x)=eθ(xi)T⋅ϕ(xj)=∑∀jf(xi,xj)
f(xi​,xj​)C(x)​=eθ(xi​)T⋅ϕ(xj​)=∀j∑​f(xi​,xj​)​

image-20201222155309965

其中 θ ( x i ) = W θ x i \theta\left(x_{i}\right)=W_{\theta} x_{i} θ(xi​)=Wθ​xi​ 和 ϕ ( x j ) = W ϕ x j \phi\left(x_{j}\right)=W_{\phi} x_{j} ϕ(xj​)=Wϕ​xj​是两个embedding。归一化参数和之前一致,为 C ( x ) = ∑ ∀ j f ( x i , x j ) \mathcal{C}(x)=\sum_{\forall j} f\left(\mathrm{x}_{i}, \mathrm{x}_{j}\right) C(x)=∑∀j​f(xi​,xj​)这里和self attention比较相似

  • Dot Product:

f ( x i , x j ) = θ ( x i ) T ⋅ ϕ ( x j ) C ( x ) = ∣ { i ∣ i  is a valid index of  x } ∣ f(xi,xj)=θ(xi)T⋅ϕ(xj)C(x)=∣{i∣i is a valid index of x}∣

f(xi,xj)C(x)=θ(xi)T⋅ϕ(xj)=∣{i∣i is a valid index of x}∣
f(xi​,xj​)C(x)​=θ(xi​)T⋅ϕ(xj​)=∣{i∣i is a valid index of x}∣​

这里我们使用embedded version。在这里,归一化参数设为 C ( x ) = N C ( x ) = N C(x)=N ,其中 N N N是 x x x的位置的数目,而不是 f ( ⋅ ) f(\cdot) f(⋅)的和,这样可以简化梯度的计算。这种形式的归一化是有必要的,因为输入的size是变化的,所以用 x x x的size作为归一化参数有一定道理。
dot product和embeded gaussian的版本的主要区别在于是否做softmax在这里的作用相当于是一个激活函数。

  • Concatenation:

f ( x i , x j ) = ReLU ⁡ ( w f T ⋅ [ θ ( x i ) , ϕ ( x j ) ] ) C ( x ) = ∣ { i ∣ i  is a valid index of  x } ∣ f(xi,xj)=ReLU(wTf⋅[θ(xi),ϕ(xj)])C(x)=∣{i∣i is a valid index of x}∣

f(xi,xj)C(x)=ReLU(wTf⋅[θ(xi),ϕ(xj)])=∣{i∣i is a valid index of x}∣
f(xi​,xj​)C(x)​=ReLU(wfT​⋅[θ(xi​),ϕ(xj​)])=∣{i∣i is a valid index of x}∣​

image-20201222155457036

这里 [ ⋅ , ⋅ ] [\cdot,\cdot] [⋅,⋅]表示的是concat, w f w_f wf​是能够将concat的向量转换成一个标量的权重向量。这里设置$C ( x ) = N $。这相当于embedded的两个点拼接作为带ReLU激活函数全连接层的输入。它在visual reasoning中用的比较多。

这里有两点需要提一下:

  1. 后两种选择的归一化系数 C ( x ) \mathcal{C}(x) C(x)选择为 x x x的点数,只是为了简化计算,同时,还能保证对任意尺寸的输入,不会产生数值上的尺度伸缩。
  2. Embedding的实现方式,以图像为例,在文章中都采用 1 ∗ 1 1*1 1∗1的卷积,也就是 θ ( ⋅ ) \theta(\cdot) θ(⋅) 和都 ϕ ( ⋅ ) \phi(\cdot) ϕ(⋅)是卷积操作。

为了能让non-local操作作为一个组件,可以直接插入任意的神经网络中,作者把non-local设计成residual block的形式,让non-local操作去学 x x x的residual:

z i = W z ⋅ y i + x i \mathrm{z}_{i}=W_{z} \cdot \mathrm{y}_{i}+\mathrm{x}_{i} zi​=Wz​⋅yi​+xi​
W s W_s Ws​实际上是一个卷积操作,它的输出channel数跟 x x x一致。这样以来,non-local操作就可以作为一个组件,组装到任意卷积神经网络中。

网络具体实现

如果按照上面的公式,用for循环实现肯定是很慢的。此外,如果在尺寸很大的输入上应用non-local layer,也是计算量很大的。

解决方案如下图所示

image-20201222195333685

image-20201222171529296

只在高阶语义层中引入non-local layer减少计算量;

通过对embedding( θ ( ⋅ ) \theta(\cdot) θ(⋅) 和 ϕ ( ⋅ ) \phi(\cdot) ϕ(⋅))的结果加pooling层来进一步地减少计算量;

注意到 f ( ⋅ ) f(\cdot) f(⋅)的计算可以化为矩阵运算,我们实际上可以将整个non-local化为矩阵乘法运算+卷积运算。(在tensorflow和pytorch中,batch matrix multiplication可以用matmul函数实现。在keras中,可以用batch_dot函数或者dot layer实现。)

  • 其中 c c c为output_channels,卷积操作的输出filter数量。
  • ⊗ \otimes ⊗ 矩阵乘法
  • ⊕ \oplus ⊕基于元素的矩阵加法
  • bottleneck结构压缩计算量,增加编码效果
  • 归一化使用 1 N \frac{1}{N} N1​

Non-local block为什么可以反映注意力

根据公式(1),为了计算输出层的一个点,需要将输入的每个点都考虑一遍,而且考虑的方式很像attention:输出的某个点在原图上的attention,而mask则是相似性给出。参看下图。

image-20201222153410250

空间注意力

当考虑是图片时候,故可以直接设置 T = 1 T=1 T=1,或者说不存在。首先网络输入是 x ∈ R H ∗ W ∗ 1024 x\in \mathbb R^{H*W*1024} x∈RH∗W∗1024,经过Embedded Gaussian中的两个嵌入权重变换 W θ , W ϕ W_\theta,W_\phi Wθ​,Wϕ​得到两个$ \mathbb R^{HW512} 其 实 这 里 的 目 的 是 降 低 通 道 数 , 减 少 计 算 量 ; 然 后 分 别 对 这 两 个 输 出 进 行 ‘ r e s h a p e ‘ 操 作 , 变 成 其实这里的目的是降低通道数,减少计算量;然后分别对这两个输出进行`reshape`操作,变成 其实这里的目的是降低通道数,减少计算量;然后分别对这两个输出进行‘reshape‘操作,变成 \mathbb R^{(HW)1024} , 后 对 这 两 个 输 出 进 行 矩 阵 乘 ( 其 中 一 个 要 转 置 ) , 计 算 相 似 性 , 得 到 ,后对这两个输出进行矩阵乘(其中一个要转置),计算相似性,得到 ,后对这两个输出进行矩阵乘(其中一个要转置),计算相似性,得到\mathbb R^{(HW)(HW)} , 然 后 在 第 2 个 维 度 即 后 一 个 维 度 上 进 行 ‘ s o f t m a x ‘ 操 作 , 得 到 ,然后在第2个维度即后一个维度上进行`softmax`操作,得到 ,然后在第2个维度即后一个维度上进行‘softmax‘操作,得到\mathbb R^{(HW)*(HW)}$,这样做就是空间注意力,相当于找到了当前图片或特征图中每个像素与其他所有位置像素的归一化相关性;

然后将 g ( ⋅ ) g(\cdot) g(⋅)也采用一样的操作,先通道降维,然后reshape;然后和 R ( H W ) ∗ ( H W ) \mathbb R^{(HW)*(HW)} R(HW)∗(HW)进行矩阵乘,得到 R ( H W ) ∗ 512 \mathbb R^{(HW)*512} R(HW)∗512,即将空间注意力机制应用到了所有通道的每张特征图对应位置上,本质就是输出的每个位置值都是其他所有位置的加权平均值,通过softmax操作可以进一步突出共性。最后经过一个1x1卷积恢复输出通道 R H ∗ W ∗ 1024 \mathbb R^{H*W*1024} RH∗W∗1024,保证输入输出尺度完全相同。

实验与讨论

如何让nonlocal高效?

当non-local用于高层的feature map时, T H W THW THW(视频信号所以多一个维度)都比较小,这样它的运算量就比较轻量了。

  • W g , W θ , W ϕ W_g, W_\theta , W_\phi Wg​,Wθ​,Wϕ​将 x x x的channel变成原始输入的一半,然后 W z W_z Wz​ 再变回来
  • 有一个subsampling的trick可以进一步使用,就是将(1)式变为: y i = 1 / C ( x ^ ) ∑ ∀ j f ( x i , x ^ j ) g ( x ^ j ) y_{i}=1 / C(\hat{x}) \sum_{\forall j} f\left(x_{i}, \hat{x}_{j}\right) g\left(\hat{x}_{j}\right) yi​=1/C(x^)∑∀j​f(xi​,x^j​)g(x^j​),其中 x ^ j \hat x_j x^j​是 x x x下采样得到的(比如通过pooling),我们将这个方式在空间域上使用,可以减小 1 4 \frac{1}{4} 41​的pairwise function的计算量。这个trick并不会改变non-local的行为,而是使计算更加稀疏了。这个可以通过在图2中的 ϕ ( ⋅ ) \phi(\cdot) ϕ(⋅)和 g ( ⋅ ) g(\cdot) g(⋅)后面增加一个较小尺度的max pooling层实现。

跟全连接层的联系

  • non-local block利用两个点的相似性对每个位置的特征做加权
  • 全连接层则是利用position-related的weight对每个位置做加权。于是,全连接层可以看成non-local block的一个特例。
  • non-local block反应的是任意两位置之间的关系(相似性),是需要通过位置坐标取出来的值等计算的。但是全连接层的这个任意两点关系仅跟两点的位置有关,与位置上的值无关,即 f ( x i , x j ) = w i j f(x_i,x_j) = w_{ij} f(xi​,xj​)=wij​
  • 全连接中 g ( ⋅ ) g(\cdot) g(⋅)是identity函数,直接取值就可以, g ( x i ) = x i g(x_i) = x_i g(xi​)=xi​
  • 全连接层归一化系数为 1 1 1。归一化系数跟输入无关
  • 全连接层不能处理任意尺寸的输入。

跟Self-attention的联系

这部分在原文中也提到了。Embedding的1*1卷积操作可以看成矩阵乘法:

{ θ ( x i ) = W θ ⋅ x i ϕ ( x j ) = W ϕ ⋅ x j ⇒ { θ ( x ) = W θ ⋅ x ϕ ( x ) = W ϕ ⋅ x {θ(xi)=Wθ⋅xiϕ(xj)=Wϕ⋅xj⇒{θ(x)=Wθ⋅xϕ(x)=Wϕ⋅x

{θ(xi)=Wθ⋅xiϕ(xj)=Wϕ⋅xj⇒{θ(x)=Wθ⋅xϕ(x)=Wϕ⋅x
{θ(xi​)=Wθ​⋅xi​ϕ(xj​)=Wϕ​⋅xj​​⇒{θ(x)=Wθ​⋅xϕ(x)=Wϕ​⋅x​​
于是,

y = softmax ⁡ ( x T ⋅ W θ T ⋅ W ϕ ⋅ x ) ⋅ g ( x ) y=\operatorname{softmax}\left(\mathrm{x}^{T} \cdot W_{\theta}^{T} \cdot W_{\phi} \cdot \mathrm{x}\right) \cdot g(\mathrm{x}) y=softmax(xT⋅WθT​⋅Wϕ​⋅x)⋅g(x)
这就是文章Attention is all you need提出来的self-attention。

跟Gram matrix的联系

Gram matrix第一次被应用到风格迁移任务中(文章A neural algorithm of artistic style),并在后来成为style loss的标配。

gram matrix把一个channel看成一个点(坐标就是整个filter,长度等于一个feature map大小H*W)

而公式(1)则是把每个空间位置看成点(坐标是feature map在该空间所有位置上的值,长度等于channel数)。两者都是计算任意两个点之间的内积。它们的差别在于沿着feature map的不同方向做内积。

基于gram matrix的style loss可以捕捉到纹理信息;从上一节我们知道,non-local层试图起到attention的作用。由(文章Demystifying neural style transfer)我们知道,匹配gram matrix相当于最小化feature map的二次多项式核的MMD距离。而non-local暂时不知道。

实验结果比较

image-20201222194126317

  • 比较不同的相似关系函数

表2a比较了不同的non-local block的形式插入到C2D得到的结果(插入位置在res4的最后一个residual block之前)。发现即使只加一个non-local block都能得到~1%的提高。

有意思的是不同的non-local block的形式效果差不多,说明是non-local block的结构在起作用,而对具体的表达方式不敏感。本文后面都采用embedded Gaussian进行实验,因为这个版本有softmax,可以直接给出[0,1]之间的scores

  • 模块位置敏感性

表2b比较了一个non-local block加在resnet的不同stage的效果,具体加在不同stage的最后一个residual block之前。发现在res2,res3,res4层上加non-local block效果类似,加在res5上效果稍差。这个的可能原因是res5的spatial size比较小,只有7*7,可能无法提供精确的spatial信息了。

  • 不同数量的模块影响,同时比较参数量证明参数增加的更有价值

加入更多的non-local blocks。表2c给出了加入更多non-local block的结果,我们在resnet-50上加1 block(在res4),加5 block(3个在res4,2个在res3,每隔1个residual block加1个non-local block),加10 block(在res3和res4每个residual block都加non-local block)。在resnet101的相同位置加block。发现更多non-local block通常有更好的结果。我们认为这是因为更多的non-local block能够捕获长距离多次转接的依赖。信息可以在时空域上距离较远的位置上进行来回传递,这是通过local models无法实现的。

另外需要提到的是增加non-local block得到的性能提升并不只是因为它给base model增加了深度。为了说明这一点,表2c中resnet50 5blocks能够达到73.8的acc,而resnet101 baseline是73.1,同时resnet50 5block只有resnet101的约70%的参数量和80%的FLOPs。说明non-local block得到的性能提升并不只是因为它增加了深度。

  • 不同维度使用模块的评价

表2d给出了在时间维度,空间维度和时空维度分别做non-local的结果。仅在空间维度上做就相当于non-local的依赖仅在单帧图像内部发生,也就是说在式(1)上仅对index i i i的相同帧的index j j j做累加。仅在时间维度上做也类似。表2d显示只做时间维度或者只做空间维度的non-local,都比C2D baseline要好,但是没有同时做时空维度的效果好。

参考文献

论文地址:Non-local Neural Networks

论文开源代码:GitHub - facebookresearch/video-nonlocal-net: Non-local Neural Networks for Video Classification

Keras复现:GitHub - titu1994/keras-non-local-nets: Keras implementation of Non-local Neural Networks

Pytorch复现:GitHub - AlexHex7/Non-local_pytorch: Implementation of Non-local Block.

Non-local neural networks - 知乎

语义分割之Dual Attention Network for Scene Segmentation - Hebye - 博客园

Non-local Neural Networks_CV大白菜的博客-CSDN博客

Non-local Neural Networks 原理详解及自注意力机制思考 - Jerry_Jin - 博客园

non-local NN论文解读_湖心亭-CSDN博客

注:本文转载自blog.csdn.net的呆呆象呆呆的文章"https://blog.csdn.net/qq_41554005/article/details/111566137"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top