https://zhuanlan.zhihu.com/p/28871960

深度学习模型中的卷积神经网络(Convolution Neural Network, CNN)近年来在图像领域取得了惊人的成绩,CNN直接利用图像像素信息作为输入,最大程度上保留了输入图像的所有信息,通过卷积操作进行特征的提取和高层抽象,模型输出直接是图像识别的结果。这种基于”输入-输出”直接端到端的学习方法取得了非常好的效果,得到了广泛的应用。

  • 卷积层(convolution layer): 执行卷积操作提取底层到高层的特征,发掘出图片局部关联性质和空间不变性质。
  • 池化层(pooling layer): 执行降采样操作。通过取卷积输出特征图中局部区块的最大值(max-pooling)或者均值(avg-pooling)。降采样也是图像处理中常见的一种操作,可以过滤掉一些不重要的高频信息。
  • 全连接层(fully-connected layer,或者fc layer): 输入层到隐藏层的神经元是全部连接的。
  • 非线性变化: 卷积层、全连接层后面一般都会接非线性变化层(探测层),例如Sigmoid、Tanh、ReLu等来增强网络的表达能力,在CNN里最常使用的为ReLu激活函数。 ReLu激活函数: $f(x) = max(0, x)$
  • Dropout [10] : 在模型训练阶段随机让一些隐层节点不工作(权重置为0),提高网络的泛化能力,一定程度上防止过拟合。

另外,在训练过程中由于每层参数不断更新,会导致下一次输入分布发生变化,这样导致训练过程需要精心设计超参数。如2015年Sergey Ioffe和Christian Szegedy提出了Batch Normalization (BN)算法 [14] 中,每个batch对网络中的每一层特征都做归一化,使得每层分布相对稳定。BN算法不仅起到一定的正则作用,而且弱化了一些超参数的设计。经过实验证明,BN算法加速了模型收敛过程,在后来较深的模型中被广泛使用。

接下来我们主要介绍VGG,GoogleNet和ResNet网络结构。(需要进一步了解,各自的优缺点和参数细节,看相应的论文)

VGG

牛津大学VGG(Visual Geometry Group)组在2014年ILSVRC提出的模型被称作VGG模型 [11] 。该模型相比以往模型进一步加宽和加深了网络结构,它的核心是五组卷积操作,每两组之间做Max-Pooling空间降维。同一组内采用多次连续的3X3卷积,五组卷积操作中卷积核的数目由较浅组的64增多到最深组的512(feature map的数目),同一组中的卷积核的数目相同,每组卷积操作由(若干组conv)->BN->ReLu->Dropout和一组pooling组成。五组卷积之后接两层全连接层【两层或以上fully connected layer就可以很好地解决非线性问题】,之后是分类层。由于每组内卷积层的不同,有11、13、16、19层这几种模型,下图展示一个16层的网络结构。VGG模型结构相对简洁,提出之后也有很多文章基于此模型进行研究,如在ImageNet上首次公开超过人眼识别的模型[19]就是借鉴VGG模型的结构。

https://arxiv.org/pdf/1405.3531.pdf  [11]

Convolutional neural networks details

CNN training

CNN fine-tuning on the target dataset

Low-dimensional CNN feature training

Data augmentation details

代码:

http://www.robots.ox.ac.uk/~vgg/research/deep_eval

http://www.robots.ox.ac.uk/~vgg/software/deep_eval/

http://x-algo.cn/index.php/2017/01/08/1471/

def vgg_bn_drop(input):
'''
conv_block为一组卷积网络,卷积核大小为3x3,池化窗口大小为2x2,窗口滑动大小为2,groups决定每组VGG模块
是几次连续的卷积操作,dropouts指定Dropout操作的概率.num_channels是输入的通道数(卷积核的数目),一般图像作为第一层输入有RGB 3个通道
img_conv_group是在paddle.networks中预定义的模块,由若干组 Conv->BN->ReLu->Dropout 和 一组 Pooling 组成
'''
def conv_block(ipt, num_filter, groups, dropouts, num_channels=None):
return paddle.networks.img_conv_group(
input=ipt,
num_channels=num_channels,
pool_size=2,
pool_stride=2,
conv_num_filter=[num_filter] * groups,
conv_filter_size=3,
conv_act=paddle.activation.Relu(),
conv_with_batchnorm=True,
conv_batchnorm_drop_rate=dropouts,
pool_type=paddle.pooling.Max()) # 五组卷积操作
conv1 = conv_block(input, 64, 2, [0.3, 0], 3)
conv2 = conv_block(conv1, 128, 2, [0.4, 0])
conv3 = conv_block(conv2, 256, 3, [0.4, 0.4, 0])
conv4 = conv_block(conv3, 512, 3, [0.4, 0.4, 0])
conv5 = conv_block(conv4, 512, 3, [0.4, 0.4, 0])
# dropout层
drop = paddle.layer.dropout(input=conv5, dropout_rate=0.5)
# 两层512维的全连接:fc1, fc2
fc1 = paddle.layer.fc(input=drop, size=512, act=paddle.activation.Linear())
bn = paddle.layer.batch_norm(
input=fc1,
act=paddle.activation.Relu(),
layer_attr=paddle.attr.Extra(drop_rate=0.5))
fc2 = paddle.layer.fc(input=bn, size=512, act=paddle.activation.Linear())
return fc2

全连接层可由卷积操作实现:对前层是全连接的全连接层可以转化为卷积核为1x1的卷积;而前层是卷积层的全连接层可以转化为卷积核为hxw的全局卷积,h和w分别为前层卷积结果的高和宽 。卷积核数目等于全连接层的输出节点数。

如何把3x3x5的输出,转换成1x4096的形式https://www.zhihu.com/question/41037974

我们用一个3x3x5的filter【默认卷积核的channel等于输入的channel】 去卷积激活函数的输出,得到的结果就是一个fully connected layer 的一个神经元的输出,这个输出就是一个值。由于我们有4096个神经元,我们实际就是用一个3x3x5x4096的卷积层去卷积激活函数的输出。

卷积层后的全连接层的作用是把特征representation整合到一起,输出为一个值,大大减少特征位置对分类带来的影响。

GoogleNet

GoogleNet [12] 在2014年ILSVRC的获得了冠军,在介绍该模型之前我们先来了解NIN(Network in Network)模型 [13] 和Inception模块,因为GoogleNet模型由多组Inception模块组成,模型设计借鉴了NIN的一些思想。

NIN模型主要有两个特点:1) 引入了多层感知卷积网络(Multi-Layer Perceptron Convolution, MLPconv)代替一层线性卷积网络。MLPconv是一个微小的多层卷积网络,即在线性卷积后面增加若干层1x1的卷积,这样可以提取出高度非线性特征。2) 传统的CNN最后几层一般都是全连接层,参数较多。而NIN模型设计最后一层卷积层包含类别维度大小的特征图,然后采用全局均值池化(Avg-Pooling)替代全连接层,得到类别维度大小的向量,再进行分类。这种替代全连接层的方式有利于减少参数。

Inception模块如下图7所示,图(a)是最简单的设计,输出是3个卷积层和一个池化层的特征拼接(池化层的stride是多少,降维怎么办?)。这种设计的缺点是池化层不会改变特征通道数,拼接后会导致特征的通道数较大,经过几层这样的模块堆积后,通道数会越来越大,导致参数和计算量也随之增大。为了改善这个缺点,图(b)引入3个1x1卷积层进行降维,所谓的降维就是减少通道数,同时如NIN模型中提到的1x1卷积也可以修正线性特征。

GoogleNet由多组Inception模块堆积而成。另外,在网络最后也没有采用传统的多层全连接层,而是像NIN网络一样采用了均值池化层;但与NIN不同的是,池化层后面接了一层到类别数映射的全连接层。除了这两个特点之外,由于网络中间层特征也很有判别性,GoogleNet在中间层添加了两个辅助的softmax,在后向传播中增强梯度并且增强正则化(怎么增强正则化?),而整个网络的损失函数是这个三个分类器的损失加权求和。

GoogleNet整体网络结构如图8所示,总共22层网络:开始由3层普通的卷积组成;接下来由三组子网络组成,第一组子网络包含2个Inception模块,第二组包含5个Inception模块,第三组包含2个Inception模块;然后接均值池化层、全连接层。

上面介绍的是GoogleNet第一版模型(称作GoogleNet-v1)。GoogleNet-v2 [14] 引入BN层;GoogleNet-v3 [16] 对一些卷积层做了分解,进一步提高网络非线性能力和加深网络;GoogleNet-v4 [17] 引入下面要讲的ResNet设计思路。从v1到v4每一版的改进都会带来准确度的提升,介于篇幅,这里不再详细介绍v2到v4的结构。

ResNet

ResNet(Residual Network) [15] 是2015年ImageNet图像分类、图像物体定位和图像物体检测比赛的冠军。针对训练卷积神经网络时加深网络导致准确度下降的问题【梯度消失】,ResNet提出了采用残差学习。在已有设计思路(BN, 小卷积核,全卷积网络)的基础上,引入了残差模块。每个残差模块包含两条路径,其中一条路径是输入特征的直连通路,另一条路径对该特征做两到三次卷积操作得到该特征的残差,最后再将两条路径上的特征相加

残差模块如图9所示,左边是基本模块连接方式,由两个输出通道数相同的3x3卷积组成。右边是瓶颈模块(Bottleneck)连接方式,之所以称为瓶颈,是因为上面的1x1卷积用来降维(图示例即256->64),下面的1x1卷积用来升维(图示例即64->256),这样中间3x3卷积的输入和输出通道数都较小(图示例即64->64)。

一张500 * 500且厚度depth为100 的图片在20个filter上做1*1的卷积,那么结果的大小为500*500*20。1*1的卷积核是要和要处理的数据通道保持一致的,要处理的如果是RGB原始图,那么1*1卷积核应该是1*1*3,灰度图是1*1,(纯粹线性变换),要处理的如果是N个特征图对应的数据,那么1*1卷积核大小应该是1*1*N了。filter的数量控制了下一层的channel数

如果卷积的输出输入都只是一个平面,那么1x1卷积核并没有什么意义,它是完全不考虑像素与周边其他像素关系。但卷积的输出输入是长方体,所以1x1卷积实际上是对每个像素点,在不同的channels上进行线性组合(前提:channel > 1)(信息整合),且保留了图片的原有平面结构,调控depth,从而完成升维或降维的功能。

一组残差模块,由若干个残差模块堆积而成,
resnet_cifar10 的连接结构: 输入 -> 卷积层 -> 三组残差模块 -> 池化层
# conv_bn_layer : 带BN的卷积层,(img_conv -> linear) -> (bn -> relu)
def conv_bn_layer(input,
ch_out,
filter_size,
stride,
padding,
active_type=paddle.activation.Relu(),
ch_in=None):
tmp = paddle.layer.img_conv(
input=input,
filter_size=filter_size,
num_channels=ch_in,
num_filters=ch_out,
stride=stride,
padding=padding,
act=paddle.activation.Linear(),
bias_attr=False)
return paddle.layer.batch_norm(input=tmp, act=active_type) # shortcut : 残差模块的”直连”路径,”直连”实际分两种形式:残差模块输入和输出特征通道数不等时,采用1x1卷积的
# 升维操作;残差模块输入和输出通道相等时,采用直连操作。
def shortcut(ipt, ch_in, ch_out, stride):
if ch_in != ch_out:
return conv_bn_layer(ipt, ch_out, 1, stride, 0,
paddle.activation.Linear())
else:
return ipt # basicblock : 一个基础残差模块,由两组3x3卷积组成的路径和一条”直连”路径组成
def basicblock(ipt, ch_in, ch_out, stride):
tmp = conv_bn_layer(ipt, ch_out, 3, stride, 1)
tmp = conv_bn_layer(tmp, ch_out, 3, 1, 1, paddle.activation.Linear())
short = shortcut(ipt, ch_in, ch_out, stride)
return paddle.layer.addto(input=[tmp, short], act=paddle.activation.Relu()) # layer_warp : 一组残差模块,由若干个残差模块堆积而成
def layer_warp(block_func, ipt, ch_in, ch_out, count, stride):
tmp = block_func(ipt, ch_in, ch_out, stride)
for i in range(1, count):
tmp = block_func(tmp, ch_out, ch_out, 1)
return tmp '''
resnet_cifar10 的连接结构: 输入 -> 卷积层 -> 三组残差模块 -> 池化层
1、底层输入连接一层 conv_bn_layer,即带BN的卷积层。
2、然后连接3组残差模块即下面配置3组 layer_warp ,每组采用图 10 左边残差模块组成。
3、最后对网络做均值池化并返回该层。
'''
def resnet_cifar10(ipt, depth=32):
# depth should be one of 20, 32, 44, 56, 110, 1202
assert (depth - 2) % 6 == 0
n = (depth - 2) / 6
nStages = {16, 64, 128}
conv1 = conv_bn_layer(
ipt, ch_in=3, ch_out=16, filter_size=3, stride=1, padding=1)
res1 = layer_warp(basicblock, conv1, 16, 16, n, 1)
res2 = layer_warp(basicblock, res1, 16, 32, n, 2)
res3 = layer_warp(basicblock, res2, 32, 64, n, 2)
pool = paddle.layer.img_pool(
input=res3, pool_size=8, stride=1, pool_type=paddle.pooling.Avg())
return pool

神经网络参数计算https://zhuanlan.zhihu.com/p/57437131

卷积层: $K^2 * C_i * C_0 + C_0$

其中  为卷积核大小,  为输入channel数,  为输出的channel数(也是filter的数量),算式第二项是偏置项的参数量 。(虽然一般不写偏置项,因为不会影响总参数量的数量级,但是我们为了准确起见,把偏置项的参数量也考虑进来)

BN层:$2 * C_i$, 其中$C_i$为输入的channel数

(BN层有两个需要学习的参数,平移因子和缩放因子)

全连接层:$T_i * T_0 + T_0$, $T_i$为输入向量的长度,$T_0$为输出向量的长度,其中第二项为偏置项参数量。

作者:小鸭子蛋
链接:https://www.nowcoder.com/discuss/37873?type=0&order=0&pos=28&page=1
来源:牛客网

1-4轮技术面:
      caffe的好处。
      手绘alexnet网络图,alexnet优点,为什么不用lenet,为什么不考虑更深的网络。
      svm原理,knn kmeans原理,kmeans k的取值原理和方法。
      sigmoid激活函数是什么,什么作用,为什么用relu不用sigmoid
      alexnet 改进方案(我大概提了一下squeezenet)
      小的卷积核跟大的卷积核什么区别。
      PCA原理,为什么用PCA做人脸识别
      线性,逻辑回归问题,决策树问题。
 
 
作者:Polaris045217
链接:https://www.nowcoder.com/discuss/48981?type=0&order=0&pos=16&page=1
来源:牛客网

 
4.如何在测试中,加速1000倍(不改变网络结构)
5.pooling层的作用,以及为什么会选择maxpooling
6.有没有从头开始训练一个模型 vgg16 resnet googlenet收敛问题

【paddle学习】图像分类的更多相关文章

  1. 【paddle学习】识别数字

    Softmax回归(Softmax Regression) 最简单的Softmax回归模型是先将输入层经过一个全连接层得到的特征,然后直接通过softmax 函数进行多分类 输入层的数据$X$传到输出 ...

  2. 【paddle学习】词向量

    http://spaces.ac.cn/archives/4122/   关于词向量讲的很好 上边的形式表明,这是一个以2x6的one hot矩阵的为输入.中间层节点数为3的全连接神经网络层,但你看右 ...

  3. 不用写代码就能实现深度学习?手把手教你用英伟达 DIGITS 解决图像分类问题

    2006年,机器学习界泰斗Hinton,在Science上发表了一篇使用深度神经网络进行维数约简的论文 ,自此,神经网络再次走进人们的视野,进而引发了一场深度学习革命.深度学习之所以如此受关注,是因为 ...

  4. 用tensorlayer导入Slim模型迁移学习

    上一篇博客[用tensorflow迁移学习猫狗分类]笔者讲到用tensorlayer的[VGG16模型]迁移学习图像分类,那麽问题来了,tensorlayer没提供的模型怎么办呢?别担心,tensor ...

  5. 深度学习识别CIFAR10:pytorch训练LeNet、AlexNet、VGG19实现及比较(一)

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 前面几篇文章介绍了MINIST,对这种简单图片的识别,LeNet-5可以达到99%的识别率. CIFA ...

  6. zz2019年主动学习有哪些进展?答案在这三篇论文里

    2019年主动学习有哪些进展?答案在这三篇论文里 目前推广应用的机器学习方法或模型主要解决分类问题,即给定一组数据(文本.图像.视频等),判断数据类别或将同类数据归类等,训练过程依赖于已标注类别的训练 ...

  7. AI移动自动化测试框架设计(解读)

    声明:原文出自"前端之巅"微信公众号"爱奇艺基于AI的移动端自动化测试框架的设计"一文,作者:何梁伟,爱奇艺Android架构师.文章提供了一种基于AI算法的自 ...

  8. 深度自适应增量学习(Incremental Learning Through Deep Adaptation)

    深度自适应增量学习(Incremental Learning Through Deep Adaptation) 2018-05-25 18:56:00 木呆呆瓶子 阅读数 10564  收藏 更多 分 ...

  9. ApacheCN 计算机视觉译文集 20211110 更新

    OpenCV3 和 Qt5 计算机视觉 零.前言 一.OpenCV 和 Qt 简介 二.创建我们的第一个 Qt 和 OpenCV 项目 三.创建一个全面的 Qt + OpenCV 项目 四.Mat和Q ...

随机推荐

  1. kvm虚拟化存储管理

    1. kvm虚拟化存储介绍 KVM 的存储虚拟化是通过存储池(Storage Pool)和卷(Volume)来管理的.Storage Pool 是宿主机上可以看到的一片存储空间,可以是多种型: Vol ...

  2. UNIX环境C语言进程通信

    一.信号管理 1.函数signal signal函数是UNIX系统信号机制最简单的接口 #include <signal.h> typedef void (*sighandler_t)(i ...

  3. mysql 审核引擎 goInception 的基本使用

    官网地址 github.com 安装 git clone https://github.com/hanchuanchuan/goInception.git cd goInception 修改配置 开启 ...

  4. centos 装 jdk

    1.源码包准备: 首先到官网下载jdk,http://www.oracle.com/technetwork/java/javase/downloads/jdk7- downloads-1880260. ...

  5. CodeForces 321C Ciel the Commander

    Ciel the Commander Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on CodeForc ...

  6. hdu2042

    #include <stdio.h> int main(){ int t,i,n,res; while(~scanf("%d",&t)){ while(t--) ...

  7. 04-offsetLeft和style.left的区别

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  8. phpstorm 修改头部注释

    点击“setting”->"File  Templates"  ->"PHP File Header"    

  9. php排序介绍_冒泡排序_选择排序法_插入排序法_快速排序法

    这里我们介绍一些常用的排序方法,排序是一个程序员的基本功,所谓排序就是对一组数据,按照某个顺序排列的过程. 充效率看 冒泡排序法<选择排序法<插入排序法 排序分两大类: 内部排序法 交换式 ...

  10. 怎么样给CentOS6.5增加swap分区

    再给服务器添加zabbix监控的时候,发现服务器有个报错“Lack of free swap space on localhost”,通过查找得知,在安装服务器的时候忘了划分swap分区.为了减少报错 ...