卷积神经网络AlexNet

卷积神经网络AlexNet

1. 概述

AlexNet卷积神经网络[1]在CNN的发展过程中起着非常重要的作用,AlexNet是由加拿大多伦多大学的Alex Krizhevsky等人提出。在当年的ImageNet图像分类竞赛,取得了大赛的冠军并且效果大大好于第二名。如今回过来看,AlexNet的主要贡献是ReLU、Dropout、Max-Pooling,这些技术基本上在AlexNet之后的大多数主流架构中都能见到。

2. 算法的基本思想

2.1. AlexNet的网络结构

AlexNet的网络结构如下图所示:

www.zeeklog.com  - 卷积神经网络AlexNet


抛开两个GPU的结构不说,这主要是因为受当时的计算环境的影响。聚焦在AlexNet的结构,AlexNet网络中包含5个卷积层和3个全连接层。参照[2]的参数格式,可以绘制出如下的网络结构:

www.zeeklog.com  - 卷积神经网络AlexNet

构建AlexNet也是通过不断堆叠各个模块,要理解各模块的作用,前提熟悉对各模块的输入输出维度。

  • data:大小为 227 × 227 × 3 227\times 227\times 3 227×227×3(此处参考文献[1]和[2]中的数值不一致,重在理解其原理)
  • conv1 & relu1
  • conv1:输入: 227 × 227 × 3 227\times 227\times 3 227×227×3
  • conv1:输出: 55 × 55 × 96 55\times 55 \times 96 55×55×96,其中,卷积核大小为 11 × 11 11\times 11 11×11,步长为 4 4 4,根据公式 ( W − F + 2 P ) / S + 1 \left ( W-F+2P \right )/S+1 (W−F+2P)/S+1(其中, W W W为输入大小, F F F为卷积核大小, P P P为padding大小,此处为 0 0 0,S为步长),求解得到输出大小为 55 55 55
  • relu1:输入: 55 × 55 × 96 55\times 55 \times 96 55×55×96
  • relu1:输出: 55 × 55 × 96 55\times 55 \times 96 55×55×96
  • norm1:输入: 55 × 55 × 96 55\times 55 \times 96 55×55×96,输出: 55 × 55 × 96 55\times 55 \times 96 55×55×96
  • pool1:输入: 55 × 55 × 96 55\times 55 \times 96 55×55×96,输出: 27 × 27 × 96 27\times 27 \times 96 27×27×96,其中,卷积核大小为 3 × 3 3\times 3 3×3,步长为 2 2 2,根据上述公式,求解得到输出大小为 27 27 27
  • conv2 & relu2
  • conv2:输入: 27 × 27 × 96 27\times 27 \times 96 27×27×96
  • conv2:输出: 27 × 27 × 256 27\times 27 \times 256 27×27×256,其中,卷积核大小为 5 × 5 5\times 5 5×5,步长为 1 1 1,padding为 2 2 2,最终的输出大小为 27 27 27
  • relu2:输入: 27 × 27 × 256 27\times 27 \times 256 27×27×256
  • relu2:输出: 27 × 27 × 256 27\times 27 \times 256 27×27×256
  • norm2:输入: 27 × 27 × 256 27\times 27 \times 256 27×27×256,输出: 27 × 27 × 256 27\times 27 \times 256 27×27×256
  • pool2:输入: 27 × 27 × 256 27\times 27 \times 256 27×27×256,输出: 13 × 13 × 256 13\times 13 \times 256 13×13×256,其中,卷积核大小为 3 × 3 3\times 3 3×3,步长为 2 2 2,根据上述公式,求解得到输出大小为 13 13 13
  • conv3 & relu3
  • conv3:输入: 13 × 13 × 256 13\times 13 \times 256 13×13×256
  • conv3:输出: 13 × 13 × 384 13\times 13 \times 384 13×13×384,其中,卷积核大小为 3 × 3 3\times 3 3×3,步长为 1 1 1,padding为 1 1 1,最终的输出大小为 13 13 13
  • relu3:输入: 13 × 13 × 384 13\times 13 \times 384 13×13×384
  • relu3:输出: 13 × 13 × 384 13\times 13 \times 384 13×13×384
  • conv4 & relu4
  • conv4:输入: 13 × 13 × 384 13\times 13 \times 384 13×13×384
  • conv4:输出: 13 × 13 × 384 13\times 13 \times 384 13×13×384,其中,卷积核大小为 3 × 3 3\times 3 3×3,步长为 1 1 1,padding为 1 1 1,最终的输出大小为 13 13 13
  • relu4:输入: 13 × 13 × 384 13\times 13 \times 384 13×13×384
  • relu4:输出: 13 × 13 × 384 13\times 13 \times 384 13×13×384
  • conv5 & relu5
  • conv5:输入: 13 × 13 × 384 13\times 13 \times 384 13×13×384
  • conv5:输出: 13 × 13 × 256 13\times 13 \times 256 13×13×256,其中,卷积核大小为 3 × 3 3\times 3 3×3,步长为 1 1 1,padding为 1 1 1,最终的输出大小为 27 27 27
  • relu5:输入: 13 × 13 × 256 13\times 13 \times 256 13×13×256
  • relu5:输出: 13 × 13 × 256 13\times 13 \times 256 13×13×256
  • pool5:输入: 13 × 13 × 256 13\times 13 \times 256 13×13×256,输出: 6 × 6 × 256 6\times 6 \times 256 6×6×256,其中,卷积核大小为 3 × 3 3\times 3 3×3,步长为 2 2 2,根据上述公式,求解得到输出大小为 6 6 6
  • fc6 & relu6 & drop6
  • fc6:输入: 6 × 6 × 256 6\times 6 \times 256 6×6×256,输出: 4096 4096 4096,通过对输入数据flatting,得到 9216 9216 9216维的数据
  • relu6:输入: 4096 4096 4096,输出: 4096 4096 4096
  • fc7 & relu7 & drop7
  • fc6:输入: 4096 4096 4096,输出: 4096 4096 4096
  • relu6:输入: 4096 4096 4096,输出: 4096 4096 4096
  • fc8:输入 4096 4096 4096,输出: 1000 1000 1000

2.2. 卷积过程

上面通过数据的输入到输出维度的变化对AlexNet的结构做了详细的描述,那么conv1中,数据是如何从 227 × 227 × 3 227\times 227\times 3 227×227×3到 55 × 55 × 96 55\times 55 \times 96 55×55×96的转换的,同时,参数的个数是多少?

参考文献[3]给出了具体的计算过程,输入的维度为 5 × 5 × 3 5\times 5\times 3 5×5×3,卷积核的大小为 3 × 3 × 3 3\times 3\times 3 3×3×3,卷积核的个数为 2 2 2,padding为 1 1 1,则最终的输出维度为 3 × 3 × 2 3\times 3\times 2 3×3×2。其具体的计算过程如下图(在参考文献[3]的图上增加了标记)所示:

www.zeeklog.com  - 卷积神经网络AlexNet

最终的输出的计算方法为:

o 0 = x 0 w 0 0 + x 1 w 0 1 + x 2 w 0 2 + b 0 o_0=x_0w0_0+x1w0_1+x2w0_2+b0 o0​=x0​w00​+x1w01​+x2w02​+b0

对于一个卷积核,其参数个数为 3 × 3 × 3 + 1 3\times 3\times 3 + 1 3×3×3+1,那么从 227 × 227 × 3 227\times 227\times 3 227×227×3到 55 × 55 × 96 55\times 55 \times 96 55×55×96的转换,需要的参数个数为 ( 11 × 11 × 3 + 1 ( o p t ) ) × 96 \left ( 11\times 11\times 3 + 1\left ( opt \right ) \right )\times 96 (11×11×3+1(opt))×96。

2.3. ReLU激活函数

在神经网络中,使用的激活函数通常有:Sigmoid函数,Tanh函数。这两个激活函数属于饱和非线性(saturating nonlinearities),在训练的过程中会出现梯度弥散的现象(反向传播时梯度接近为0),在梯度下降法过程中比非饱和非线性的激活函数的训练速度慢,而Rectified Linear Units(ReLUs) 。

ReLU激活函数的具体形式为:

f ( x ) = m a x ( 0 , x ) f\left ( x \right )=max\left ( 0,x \right ) f(x)=max(0,x)

其函数的图像如下图所示:

www.zeeklog.com  - 卷积神经网络AlexNet

2.4. Dropout

在AlexNet中,提出使用Dropout[3]避免模型的过拟合。Dropout策略是在模型的训练过程中,网络以概率 1 − p 1-p 1−p随机丢弃一些神经元,如下图所示:

www.zeeklog.com  - 卷积神经网络AlexNet

模型训练后,在进行测试时,不再使用Dropout丢弃神经元,而是将每个权重值乘上保留概率 p p p,表示他们对最后的预测结果的平均贡献,以达到与在训练时使用Dropout相同的效果,具体过程如下图所示:

www.zeeklog.com  - 卷积神经网络AlexNet
Q:为什么Dropout通常应用在全连接层?
A:在卷积层中,由于卷积和ReLU激活函数引入的稀疏化等原因,Dropout策略在卷积层中使用较少。Dropout是用来防止网络模型的过拟合,而当模型过于复杂(即网络参数过多)才会容易过拟合,因此在卷积层中没必要。

2.5. Max-Pooling

Max-Pooling是指在核的大小覆盖区域内做max的操作,如下图所示,原始的输入大小为 4 × 4 4\times 4 4×4,核的大小为 2 × 2 2\times 2 2×2,步长为 2 2 2,则最终的输出大小为 2 × 2 2\times 2 2×2。以左上的红色区域为例,Max-Pooling在 1 , 1 , 5 , 6 1,1,5,6 1,1,5,6中选择最大的值作为最终的输出。

www.zeeklog.com  - 卷积神经网络AlexNet

2.6. 输入图像的处理

对于一个任意大小的图片来说,要想输入到CNN网络中,需要对图像的大小做处理,使得其图像具有固定的维度,如上述的 227 × 227 × 3 227\times 227\times 3 227×227×3,但通常一开始会将图片处理成 256 × 256 × 3 256\times 256\times 3 256×256×3。首先需要按照短边缩放到 256 256 256,再根据中心裁剪出 256 × 256 256\times 256 256×256的大小,其具体过程如下图所示:

www.zeeklog.com  - 卷积神经网络AlexNet

至于 256 × 256 × 3 256\times 256\times 3 256×256×3到 227 × 227 × 3 227\times 227\times 3 227×227×3,可以通过多次的裁剪生成多组训练数据,这也能起到一定的数据增强作用。对于输入到模型中的数据,每个像素点需要减去训练数据在该维度上的均值。

2.7. Local Response Normalization

局部响应归一化LRN(Local Response Normalization)是一种增强模型泛化能力的方法,在LRN中,通过对局部神经元的活动创建竞争机制,使其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,其具体公式如下所示:

b x , y i = a x , y i / ( k + α ∑ j = m a x ( 0 , i − n / 2 ) m i n ( N − 1 , i + n / 2 ) ( a x , y j ) 2 ) β b_{x,y}^i=a_{x,y}^i/\left ( k+\alpha \sum_{j=max\left ( 0,i-n/2 \right )}^{min\left ( N-1,i+n/2 \right )}\left ( a_{x,y}^j \right )^2 \right )^\beta bx,yi​=ax,yi​/⎝   ⎛​k+αj=max(0,i−n/2)∑min(N−1,i+n/2)​(ax,yj​)2⎠   ⎞​β

其中, a x , y i a_{x,y}^i ax,yi​表示卷积核 i i i在坐标 ( x , y ) \left ( x,y\right) (x,y)处的神经元激活值, b x , y i b_{x,y}^i bx,yi​表示归一化后的激活值。

3. 总结

AlexNet网络的提出是在传统机器学习方法向深度学习转变的时期,通过在ImageNet图像分类竞赛中的优秀表现,也证实了卷积神经网络在图像领域的优秀表现,同时在AlexNet中提出的方法在后续的网络中一直被沿用,如ReLU、Dropout、Max-Pooling。通过对AlexNet网络的分析,我们发现对于一个深度卷积神经网络,通常应该具备如下的模块:

  • 卷积模块
  • Pooling模块
  • 激活函数
  • 归一化

然而在后续的CNN中,局部响应归一化LRN并未得到延续。

参考文章

[1] Krizhevsky A, Sutskever I, Hinton G E. Imagenet classification with deep convolutional neural networks[J]. Advances in neural information processing systems, 2012, 25.

[2] http://dgschwend.github.io/netscope/#/preset/alexnet

[3] https://cs231n.github.io/convolutional-networks/

[3] Srivastava N , Hinton G , Krizhevsky A , et al. Dropout: A Simple Way to Prevent Neural Networks from Overfitting[J]. Journal of Machine Learning Research, 2014, 15(1):1929-1958.

[4]

Read more

深入理解 Proxy 和 Object.defineProperty

在JavaScript中,对象是一种核心的数据结构,而对对象的操作也是开发中经常遇到的任务。在这个过程中,我们经常会使用到两个重要的特性:Proxy和Object.defineProperty。这两者都允许我们在对象上进行拦截和自定义操作,但它们在实现方式、应用场景和灵活性等方面存在一些显著的区别。本文将深入比较Proxy和Object.defineProperty,包括它们的基本概念、使用示例以及适用场景,以帮助读者更好地理解和运用这两个特性。 1. Object.defineProperty 1.1 基本概念 Object.defineProperty 是 ECMAScript 5 引入的一个方法,用于直接在对象上定义新属性或修改已有属性。它的基本语法如下: javascript 代码解读复制代码Object.defineProperty(obj, prop, descriptor); 其中,obj是目标对象,prop是要定义或修改的属性名,descriptor是一个描述符对象,用于定义属性的特性。 1.2 使用示例 javascript 代码解读复制代码//

By Ne0inhk

Proxy 和 Object.defineProperty 的区别

Proxy 和 Object.defineProperty 是 JavaScript 中两个不同的特性,它们的作用也不完全相同。 Object.defineProperty 允许你在一个对象上定义一个新属性或者修改一个已有属性。通过这个方法你可以精确地定义属性的特征,比如它是否可写、可枚举、可配置等。该方法的使用场景通常是需要在一个对象上创建一个属性,然后控制这个属性的行为。 Proxy 也可以用来代理一个对象,但是相比于 Object.defineProperty,它提供了更加强大的功能。使用 Proxy 可以截获并重定义对象的基本操作,比如访问属性、赋值、函数调用等等。在这些操作被执行之前,可以通过拦截器函数对这些操作进行拦截和修改。因此,通过 Proxy,你可以完全重写一个对象的默认行为。该方法的使用场景通常是需要对一个对象的行为进行定制化,或者需要在对象上添加额外的功能。 对比 以下是 Proxy 和 Object.defineProperty 的一些区别对比: 方面ProxyObject.defineProperty语法使用 new Proxy(target,

By Ne0inhk