Non-local Neural Networks
1. 摘要
卷积和循环神经网络中的操作都是一次处理一个局部邻域,在这篇文章中,作者提出了一个非局部的操作来作为捕获远程依赖的通用模块。
受计算机视觉中经典的非局部均值方法启发,我们的非局部操作计算某一位置的响应为所有位置特征的加权和。而且,这个模块可以插入到许多计算机视觉网络架构中去。
2. 介绍
在深度神经网络中,捕获远程依赖非常重要。卷积神经网络依靠大的感知野来对远程依赖建模,这是通过重复叠加卷积块来实现的。但同时,它也有一些限制。首先,它在计算上效率低下。其次,它会导致需要仔细解决的优化难题。最后,这些挑战使得多跳依赖性建模非常困难,例如,当需要在远程位置之间来回传递消息时。
假设有一个 3×3 的卷积核,那我们的每一个激活值就只与这 9 个点的值有关,所以也就是局部(local)的。所谓非局部(non-local),也就是说,每一个激活值可能不至与它相邻近的点有关,还可能与离它比较远的点也有关。比如下面第一帧的球,就与后两帧的球相关。
因此,作者提出的非局部操作计算某一位置的响应为所有位置特征的加权和,这些位置可以是空间的、时间的或者时空的。
使用非局部操作有几个优点:(a)与循环和卷积操作的渐进行为相反,非本地操作通过计算任意两个位置之间的相互关系直接捕获远程依赖性,而不管它们的位置距离如何;(b)非局部操作非常有效,即使只有几层(例如5)也能达到最佳效果;(c)最后,非本地操作保持可变的输入大小,并且可以很容易地与其他操作组合(例如卷积)。
3. 网络结构
3.1. 定义
我们要计算输出位置 i 的响应,j 枚举了所有的位置,函数 f 则计算 i 和所有 j 的关系,最后再进行一个归一化。因为 j 考虑了所有可能的位置,所以这个操作是非局部的。而卷积操作只考虑某一个区域,循环操作只考虑当前和最近的时间序列,它们都是局部的。至于全连接,它的权重是学习到的,不是 i 和 j 的一个函数关系。此外,上面的公式可以接受不同的输入大小,并且能保持输出大小和输入一致,而全连接则必须固定输入和输出大小。
3.2. 实例
当然了,f 和 g 可以有不同的选择。但是实验发现,模型对 f 和 g 的选择并不敏感,也就是说通用的非局部操作才是改进的关键。
为了简化,g 只考虑线性形式:
W 是要学习的权重,这也就可以通过一个 1×1 的卷积来实现。
函数 f 则有多种选择:
- Gaussian
高斯函数是最常见的,欧氏距离也同样适用,不过点积在深度学习平台实现则更友好。归一化则采取:
- Embedded Gaussian
另一种则是在嵌入空间使用高斯函数:
采取两个映射:
归一化则与上面保持一样。给定 i,上面的公式实际上也就是沿着 j 方向的一个 Softmax:
为了说明 Softmax 并不是必须的,作者还提出了另外两个选择,它们的归一化用位置 j 的数量 N 来实现。
- Dot product
- Concatenation
3.3. 非局部块
作者进而将上面的方程包装到一个非局部块,从而可以方便地插入到现有的框架中去,一个局部块定义如下:
’+‘ 是引入了残差连接,这样将非局部块插入到现有训练好的模型中后,如果权重系数初始化为零,就可以维持原状态不变。
整个流程如上图所示,为了减小计算,引入了瓶颈结构,先将通道数减为一半。除此之外,还可以对 x 进行空间下采样,也就是在上图中的 φ 和 g 后面加入最大池化,这样可以进一步提高效率。其一个 TensorFlow 实现如下:
def NonLocalBlock(input, subsample=True):
"""
@Non-local Neural Networks
Non-local Block
"""
_, height, width, channel = input.get_shape().as_list() # (B, H, W, C)
theta = tf.layers.conv2d(input, channel // 2, 1) # (B, H, W, C // 2)
theta = tf.reshape(theta, [-1, height*width, channel // 2]) # (B, H*W, C // 2)
phi = tf.layers.conv2d(input, channel // 2, 1) # (B, H, W, C // 2)
if subsample:
phi = tf.layers.max_pooling2d(phi, 2, 2) # (B, H / 2, W / 2, C // 2)
phi = tf.reshape(phi, [-1, height * width // 4, channel // 2]) # (B, H * W / 4, C // 2)
else:
phi = tf.reshape(phi, [-1, height * width, channel // 2]) # (B, H*W, C // 2)
phi = tf.transpose(phi, [0, 2, 1]) # (B, C // 2, H*W)
f = tf.matmul(theta, phi) # (B, H*W, H*W)
f = tf.nn.softmax(f) # (B, H*W, H*W)
g = tf.layers.conv2d(input, channel // 2, 1) # (B, H, W, C // 2)
if subsample:
g = tf.layers.max_pooling2d(g, 2, 2) # (B, H / 2, W / 2, C // 2)
g = tf.reshape(g, [-1, height * width // 4, channel // 2]) # (B, H*W, C // 2)
else:
g = tf.reshape(g, [-1, height * width, channel // 2]) # (B, H*W, C // 2)
y = tf.matmul(f, g) # (B, H*W, C // 2)
y = tf.reshape(y, [-1, height, width, channel // 2]) # (B, H, W, C // 2)
y = tf.layers.conv2d(y, channel, 1) # (B, H, W, C)
y = tf.add(input, y) # (B, W, H, C)
return y
4. 实验结果
对比了几种 f 的选择,发现它们对模型的表现并没有起到决定性的作用,最根本的还是非局部的思想对实验结果有提升。
在第二三四个残差块之后加入非局部块效果相似,都有比较明显的提升;但在第五个残差块之后添加的话,效果没有之前那样明显。作者猜测可能是最后一个残差块的空间分辨率比较小只有 7×7,不足够提供精确的空间信息。
添加更多的非局部块,模型的表现相对来说会更好。
获取更多精彩,请关注「seniusen」!
Non-local Neural Networks的更多相关文章
- Local Binary Convolutional Neural Networks ---卷积深度网络移植到嵌入式设备上?
前言:今天他给大家带来一篇发表在CVPR 2017上的文章. 原文:LBCNN 原文代码:https://github.com/juefeix/lbcnn.torch 本文主要内容:把局部二值与卷积神 ...
- Spurious Local Minima are Common in Two-Layer ReLU Neural Networks
目录 引 主要内容 定理1 推论1 引理1 引理2 Safran I, Shamir O. Spurious Local Minima are Common in Two-Layer ReLU Neu ...
- 论文解读(LA-GNN)《Local Augmentation for Graph Neural Networks》
论文信息 论文标题:Local Augmentation for Graph Neural Networks论文作者:Songtao Liu, Hanze Dong, Lanqing Li, Ting ...
- 【转】Artificial Neurons and Single-Layer Neural Networks
原文:written by Sebastian Raschka on March 14, 2015 中文版译文:伯乐在线 - atmanic 翻译,toolate 校稿 This article of ...
- Deep Learning 16:用自编码器对数据进行降维_读论文“Reducing the Dimensionality of Data with Neural Networks”的笔记
前言 论文“Reducing the Dimensionality of Data with Neural Networks”是深度学习鼻祖hinton于2006年发表于<SCIENCE > ...
- [转]Neural Networks, Manifolds, and Topology
colah's blog Blog About Contact Neural Networks, Manifolds, and Topology Posted on April 6, 2014 top ...
- [CS231n-CNN] Training Neural Networks Part 1 : activation functions, weight initialization, gradient flow, batch normalization | babysitting the learning process, hyperparameter optimization
课程主页:http://cs231n.stanford.edu/ Introduction to neural networks -Training Neural Network ________ ...
- Hacker's guide to Neural Networks
Hacker's guide to Neural Networks Hi there, I'm a CS PhD student at Stanford. I've worked on Deep Le ...
- Stanford机器学习---第五讲. 神经网络的学习 Neural Networks learning
原文 http://blog.csdn.net/abcjennifer/article/details/7758797 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归 ...
- 深度学习笔记(三 )Constitutional Neural Networks
一. 预备知识 包括 Linear Regression, Logistic Regression和 Multi-Layer Neural Network.参考 http://ufldl.stanfo ...
随机推荐
- Thinkphp3.2 Redis支持REDIS_AUTH验证
原有的Redis类在Library/Think/Cache/Driver/中 换成下面的: <?php // +----------------------------------------- ...
- RabbitMq学习5-路由(Routing)
一.路由(Routing) 在前面的教程中,我们实现了一个简单的日志系统.可以把日志消息广播给多个接收者. 本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集.例如,我们只需要把严重的错 ...
- 客户端通过url向后端传递参数
在前端我们不仅可以通过get请求携带参数的方式向服务端传数据: https://127.0.0.1/index/?id=1&name=alex Django也允许通过,path路径的方式向se ...
- 自己写的SqlHelper,提示在调用"Fill"前,SelectCommand 属性尚未初始化.错误
namespace 操作数据{ class SqlHelper { public DataSet SqlTODs(string cmdstring) { ...
- 模拟select下拉框、复选框效果
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- java中使用SimpleDateFormat实现字符串和日期的相互转换
java中使用SimpleDateFormat实现字符串和日期的相互转换 import java.text.ParseException; import java.text.SimpleDateFor ...
- CentOS6.4运维知识点1
系统的基础优化 1. 修改yum源(CentOS6.4 Mini) wget http://mirrors.163.com/.help/CentOS6-Base-163.repo cd /etc/yu ...
- Netty学习第三章 Linux网络编程使用的I/O模型
一.同步阻塞IO:blocking IO(BIO) 1.过程分析: 当进程进行系统调用时,内核就会去准备数据,当数据准备好后就复制数据到内核缓冲器,复制完成后将数据拷贝到用户进程内存,整个过程都是阻塞 ...
- Java数据封装成树形结构,多级
参考地址:https://blog.csdn.net/chendu500qiang/article/details/91493147 1.实体类 @data public class PublishS ...
- PHP程序员要看的书单
想提升自己,还得多看书!多看书!多看书! 下面是我收集到的一些PHP程序员应该看得书单及在线教程,自己也没有全部看完.共勉吧! Github地址:https://github.com/52fhy/ph ...