这篇论文思路简单、易实现、效果好,是一篇难得的佳作。从实现的角度理解,就是做了以下两个替换:

  1. 将线性卷积替换为多层感知机(某种程度上,线性卷积可以认为识一层感知机)。
  2. 将全连接层用global average pooling layer替换。

下面我们就来分析引入上述两个替换的妙处。首先分析第一个替换的妙处,替换的效果(图示如下)

论文中提到“The linear convolution is sufficient for abstraction when the instances of the latent concepts are linearly separable.”,然而现实太复杂,the instances of the latent concepts通常不是线性可分的。在这种情况下,通常有两种做法:一是,引入大量的linear convolution(以体量应对复杂现实);二是,干脆寻找一个能够模拟任意复杂情形的“参数化函数”(以灵活性应对复杂现实)。

可以预见,如果你计算、存储资源充裕的话,你可以采取简单暴力的第一种情形;通常情况下,计算、存储资源受限,因此第二种做法更加接近现实一点(也更容易将算法植入到计算、存储资源有限的移动设备上,如手机)。下面的问题就是寻找所需的“参数化函数”。庆幸的是,多层感知机在某种程度上能够满足我们的需求,此外它能够与BP算法完美兼容(这篇论文选择的就是多层感知机)。这样的Mlpconv layer就可以作为深度网络的几个基本block,用以构建深度网络。

在CNN当中,随着层数的加深,我们得到的特征越来越抽象。这种抽象是以组合较低一层抽象特征得到的。从这个角度理解,如果在较低层就能够比之前对应层更抽象的特征,然后整个网络的输出抽象程度将会变得更高,这样高度抽象的特征对于分类、任务迁移都是有极大帮助的。

下面分析第二个替换的妙处

传统的CNN是将最后一层的卷积输出向量化,然后输入到全连接层,全连接层之后是常用的分类损失函数,如softmax。如果最后一层卷积输出特征维度过高、类别较多,那么这一块引入的参数量是很大的,这会造成网络过拟合(还好,目前有一些防止过拟合的手段,如dropout)。

“The idea is to generate one feature map for each corresponding category of the classification task in the last mlpconv layer. Instead of adding fully connected layers on top od the feature maps, we take the advantage of each feature map, and the resulting vector is fed directly into the softmax layer”,这样做的好处是,直接在类别与feature maps之间建立了联系,“The features maps can be easily interpreted as categories confidence maps”。此外,这里没有引入要学习的参数,也间接起到了防止过拟合的效果。

在Caffe框架下实现上述网络是一个很简单的事情,以在cifar10上的网络结果为例

layers {
name: "conv1"
type: CONVOLUTION
bottom: "data"
top: "conv1"
blobs_lr:
blobs_lr:
weight_decay: .
weight_decay: .
convolution_param {
num_output:
pad:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
}
}
}
layers {
name: "relu1"
type: RELU
bottom: "conv1"
top: "conv1"
}
layers {
name: "cccp1"
type: CONVOLUTION
bottom: "conv1"
top: "cccp1"
blobs_lr:
blobs_lr:
weight_decay:
weight_decay:
convolution_param {
num_output:
group:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
value:
}
}
}
layers {
name: "relu_cccp1"
type: RELU
bottom: "cccp1"
top: "cccp1"
}
layers {
name: "cccp2"
type: CONVOLUTION
bottom: "cccp1"
top: "cccp2"
blobs_lr:
blobs_lr:
weight_decay:
weight_decay:
convolution_param {
num_output:
group:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
value:
}
}
}
layers {
name: "relu_cccp2"
type: RELU
bottom: "cccp2"
top: "cccp2"
}

两个kernel_size为1的卷积核实现的就是多层感知机的功能,全部的网络结果代码如下

name: "CIFAR10_full"
layers {
name: "cifar"
type: DATA
top: "data"
top: "label"
data_param {
source: "cifar-train-leveldb"
batch_size:
}
include: { phase: TRAIN }
}
layers {
name: "cifar"
type: DATA
top: "data"
top: "label"
data_param {
source: "cifar-test-leveldb"
batch_size:
}
include: { phase: TEST }
}
layers {
name: "conv1"
type: CONVOLUTION
bottom: "data"
top: "conv1"
blobs_lr:
blobs_lr:
weight_decay: .
weight_decay: .
convolution_param {
num_output:
pad:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
}
}
}
layers {
name: "relu1"
type: RELU
bottom: "conv1"
top: "conv1"
}
layers {
name: "cccp1"
type: CONVOLUTION
bottom: "conv1"
top: "cccp1"
blobs_lr:
blobs_lr:
weight_decay:
weight_decay:
convolution_param {
num_output:
group:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
value:
}
}
}
layers {
name: "relu_cccp1"
type: RELU
bottom: "cccp1"
top: "cccp1"
}
layers {
name: "cccp2"
type: CONVOLUTION
bottom: "cccp1"
top: "cccp2"
blobs_lr:
blobs_lr:
weight_decay:
weight_decay:
convolution_param {
num_output:
group:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
value:
}
}
}
layers {
name: "relu_cccp2"
type: RELU
bottom: "cccp2"
top: "cccp2"
}
layers {
name: "pool1"
type: POOLING
bottom: "cccp2"
top: "pool1"
pooling_param {
pool: MAX
kernel_size:
stride:
}
}
layers {
name: "drop3"
type: DROPOUT
bottom: "pool1"
top: "pool1"
dropout_param {
dropout_ratio: 0.5
}
}
layers {
name: "conv2"
type: CONVOLUTION
bottom: "pool1"
top: "conv2"
blobs_lr:
blobs_lr:
weight_decay: .
weight_decay: .
convolution_param {
num_output:
pad:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
}
}
}
layers {
name: "relu2"
type: RELU
bottom: "conv2"
top: "conv2"
}
layers {
name: "cccp3"
type: CONVOLUTION
bottom: "conv2"
top: "cccp3"
blobs_lr:
blobs_lr:
weight_decay:
weight_decay:
convolution_param {
num_output:
group:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
value:
}
}
}
layers {
name: "relu_cccp3"
type: RELU
bottom: "cccp3"
top: "cccp3"
}
layers {
name: "cccp4"
type: CONVOLUTION
bottom: "cccp3"
top: "cccp4"
blobs_lr:
blobs_lr:
weight_decay:
weight_decay:
convolution_param {
num_output:
group:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
value:
}
}
}
layers {
name: "relu_cccp4"
type: RELU
bottom: "cccp4"
top: "cccp4"
}
layers {
name: "pool2"
type: POOLING
bottom: "cccp4"
top: "pool2"
pooling_param {
pool: AVE
kernel_size:
stride:
}
}
layers {
name: "drop6"
type: DROPOUT
bottom: "pool2"
top: "pool2"
dropout_param {
dropout_ratio: 0.5
}
}
layers {
name: "conv3"
type: CONVOLUTION
bottom: "pool2"
top: "conv3"
blobs_lr: .
blobs_lr: .
weight_decay: .
weight_decay: .
convolution_param {
num_output:
pad:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
}
}
}
layers {
name: "relu3"
type: RELU
bottom: "conv3"
top: "conv3"
}
layers {
name: "cccp5"
type: CONVOLUTION
bottom: "conv3"
top: "cccp5"
blobs_lr:
blobs_lr:
weight_decay:
weight_decay:
convolution_param {
num_output:
group:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
value:
}
}
}
layers {
name: "relu_cccp5"
type: RELU
bottom: "cccp5"
top: "cccp5"
}
layers {
name: "cccp6"
type: CONVOLUTION
bottom: "cccp5"
top: "cccp6"
blobs_lr: 0.1
blobs_lr: 0.1
weight_decay:
weight_decay:
convolution_param {
num_output:
group:
kernel_size:
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
value:
}
}
}
layers {
name: "relu_cccp6"
type: RELU
bottom: "cccp6"
top: "cccp6"
}
layers {
name: "pool3"
type: POOLING
bottom: "cccp6"
top: "pool3"
pooling_param {
pool: AVE
kernel_size:
stride:
}
}
layers {
name: "accuracy"
type: ACCURACY
bottom: "pool3"
bottom: "label"
top: "accuracy"
include: { phase: TEST }
}
layers {
name: "loss"
type: SOFTMAX_LOSS
bottom: "pool3"
bottom: "label"
top: "loss"
}

总结:这篇文章引入的改进网络结构的方式、global average pooling启发了后续很多算法,以后有时间再慢慢分析。

论文笔记 Network In Network的更多相关文章

  1. 论文笔记系列-Neural Network Search :A Survey

    论文笔记系列-Neural Network Search :A Survey 论文 笔记 NAS automl survey review reinforcement learning Bayesia ...

  2. 论文笔记-Deep Affinity Network for Multiple Object Tracking

    作者: ShijieSun, Naveed Akhtar, HuanShengSong, Ajmal Mian, Mubarak Shah 来源: arXiv:1810.11780v1 项目:http ...

  3. 论文笔记——N2N Learning: Network to Network Compression via Policy Gradient Reinforcement Learning

    论文地址:https://arxiv.org/abs/1709.06030 1. 论文思想 利用强化学习,对网络进行裁剪,从Layer Removal和Layer Shrinkage两个维度进行裁剪. ...

  4. 【论文笔记】Malware Detection with Deep Neural Network Using Process Behavior

    [论文笔记]Malware Detection with Deep Neural Network Using Process Behavior 论文基本信息 会议: IEEE(2016 IEEE 40 ...

  5. 论文笔记: Dual Deep Network for Visual Tracking

    论文笔记: Dual Deep Network for Visual Tracking  2017-10-17 21:57:08  先来看文章的流程吧 ... 可以看到,作者所总结的三个点在于: 1. ...

  6. Face Aging with Conditional Generative Adversarial Network 论文笔记

    Face Aging with Conditional Generative Adversarial Network 论文笔记 2017.02.28  Motivation: 本文是要根据最新的条件产 ...

  7. 论文《Network in Network》笔记

    论文:Lin M, Chen Q, Yan S. Network In Network[J]. Computer Science, 2013. 参考:关于CNN中1×1卷积核和Network in N ...

  8. 论文笔记 《Maxout Networks》 && 《Network In Network》

    论文笔记 <Maxout Networks> && <Network In Network> 发表于 2014-09-22   |   1条评论 出处 maxo ...

  9. [论文阅读笔记] Structural Deep Network Embedding

    [论文阅读笔记] Structural Deep Network Embedding 本文结构 解决问题 主要贡献 算法原理 参考文献 (1) 解决问题 现有的表示学习方法大多采用浅层模型,这可能不能 ...

  10. [论文阅读笔记] Unsupervised Attributed Network Embedding via Cross Fusion

    [论文阅读笔记] Unsupervised Attributed Network Embedding via Cross Fusion 本文结构 解决问题 主要贡献 算法原理 实验结果 参考文献 (1 ...

随机推荐

  1. 移动端测试方案--sptt

    sptt sptt是移动端UI自动化测试的一种解决方案,全称为special tool of test.sptt提供了一套测试解决方案,并使用命令行完成相关操作,最终可集成在各种后续的流程中. spt ...

  2. 速成制作rpm包

    FPM 由于很多软件在安装时需要编译,这会浪费不少的时间,为了提升部署效率,于是就想到制作rpm包.通常rpm包的制作是使用rpmbuild命令来制作,但是你需要知道它的语法,比较繁琐.这就用到了FP ...

  3. CSAcademy Beta Round #5 Long Journey

    题目链接:https://csacademy.com/contest/arhiva/#task/long_journey/ 大意是有一张无向不带权的图,两个人同时从s点出发,分别前往a点和b点,且每个 ...

  4. Java设计模式:代理模式(二)

    承接上文 三.计数代理 计数代理的应用场景是:当客户程序需要在调用服务提供者对象的方法之前或之后执行日志或者计数等额外功能时,就可以用到技术代理模式.计数代理模式并不是把额外操作的代码直接添加到原服务 ...

  5. nginx参数的详细说明

    #开启进程数 <=CPU数 worker_processes 1; #错误日志保存位置 #error_log logs/error.log; #error_log logs/error.log ...

  6. MySQL AutoCommit带来的问题

    现象描述 测试中发现,服务A在得到了服务B的注册用户成功response以后,开始调用查询用户信息接口,却发现无法查询出任何结果.检查binlog发现,在查询请求之前,数据库确实已经完成了commit ...

  7. Hush Framework框架配置

    在写这篇文章的时候,楼主已经饿的不行了,因为我从3点开始就在折腾Hush Framework,走了很多弯路,打铁要趁热,先把基本的过程记录下来,留待以后翻阅,同时记录其中容易走弯路的地方,特别是对于一 ...

  8. Android中EditText设置输入条件

    一.应用场景 之前做商城应用时,会有对用户资料的设置情况进行限制,如下: (1)用户邮箱,应当只允许输入英文字母,数字和@.两个符号, (2)用户手机,应当只能输入数字,禁止输入其他字符. (3)用户 ...

  9. 分针网—每日分享: 怎么轻松学习JavaScript

    js给初学者的印象总是那么的"杂而乱",相信很多初学者都在找轻松学习js的途径.   我试着总结自己学习多年js的经验,希望能给后来的学习者探索出一条"轻松学习js之路& ...

  10. 玩转spring boot——ajax跨域

    前言  java语言在多数时,会作为一个后端语言,为前端的php,node.js等提供API接口.前端通过ajax请求去调用java的API服务.今天以node.js为例,介绍两种跨域方式:Cross ...