卷积神经网络,在图像识别和天然语言处理中有很大的做用,讲cnn的中文博客也很多,可是我的感受说的脉络清晰清晰易懂的很少.python
无心中看到这篇博客,写的很好,图文并茂.建议英文好的直接去看原文.英文很差的就直接看我这篇,算是读后总结吧.原文里对数学原理的着墨很少,在这篇文章里我会留着相关的标题,待往后慢慢补充这篇文章.git
以上是一个cnn的典型结构.包含如下3种结构github
这是数字8的图片,图片其实就是一堆像素点的组合,能够理解为一个M*N的矩阵,矩阵中每个元素的值就是像素值,取值从0-255.彩色的图有RGB三个通道,能够理解为3个M*N矩阵.为了简化讨论,咱们以灰度图为例,灰度图是单通道的.算法
假设咱们有一个5*5的图片网络
咱们有一个3*3的矩阵,在CNN中,咱们称之为‘filter‘ or ‘kernel’ or ‘feature detector’。app
,ide
咱们用这个kenel对输入的图像作卷积,过程以下所示:函数
其中,卷积的过程,用filter与input的相应位置相乘再相加.获得新的矩阵的对应元素的值.ui
而后滑动这个filter矩阵,滑动x个像素,x称之为步长stride(在这个例子中步长=1),算出下一个矩阵对应元素的值.不断重复这个过程. 完整过程以下所示:this
卷积后获得的这个3*3的矩阵称之为‘Activation Map’ or the ‘Feature Map‘.
卷积层完成了特征提取.
不一样的filter有不一样的效果.好比上图展现了边缘检测,锐化,模糊等等.
下图很好的展现了cnn卷积操做作了什么:
不一样的filter提取出了图片的不一样角度的特征,获得了不一样的特征图.注意将上述的图片都理解为一个一个的矩阵.
It is important to note that the Convolution operation captures the local dependencies in the original image.
depth与filter数量是一致的.不一样的独立的filter提取出不一样的特征. 好比以下,有3个filter对原始图片进行处理,获得的特征图能够理解为3个叠在一块儿的矩阵.
步长是filter矩阵在输入矩阵上每次滑动的距离.步长越大,最终获得的特征图越小.
补零操做,在原始矩阵周围补0. 添加补0的卷积叫wide convolution, 不添加补0的卷积叫 narrow convolution.
以原始图像为32*32,filter为5*5为例,不作补0的话,获得的特征图矩阵大小为28*28.在神经网络的前几层,咱们但愿保留尽量多的信息,好提取更多的特征.即咱们但愿依然获得一个32*32的矩阵.
https://adeshpande3.github.io/A-Beginner%27s-Guide-To-Understanding-Convolutional-Neural-Networks-Part-2/
Now, let’s take a look at padding. Before getting into that, let’s think about a scenario. What happens when you apply three 5 x 5 x 3 filters to a 32 x 32 x 3 input volume? The output volume would be 28 x 28 x 3. Notice that the spatial dimensions decrease. As we keep applying conv layers, the size of the volume will decrease faster than we would like. In the early layers of our network, we want to preserve as much information about the original input volume so that we can extract those low level features. Let’s say we want to apply the same conv layer but we want the output volume to remain 32 x 32 x 3. To do this, we can apply a zero padding of size 2 to that layer. Zero padding pads the input volume with zeros around the border. If we think about a zero padding of two, then this would result in a 36 x 36 x 3 input volume.
卷积为何能够提取特征,背后的数学原理,往后补充
ReLU做用于卷积后获得的特征图. 将矩阵中的负数替换为0.
ReLU为卷积神经网络引入非线性.真实世界里的数据绝大多数是非线性的(卷积是一种线性操做)
The purpose of ReLU is to introduce non-linearity in our ConvNet, since most of the real-world data we would want our ConvNet to learn would be non-linear (Convolution is a linear operation – element wise matrix multiplication and addition, so we account for non-linearity by introducing a non-linear function like ReLU)
对特征图中的每个像素作ReLU操做后的效果如上图所示.
其余的非线性函数还有tanh,sigmoid。可是实际使用中,大多状况下ReLU效果更好.
上面通过多个filter卷积,以及ReLU处理以后,咱们获得了多个特征图.
此时咱们想减少特征矩阵的维度,可是又保留下最重要的特征.和上面介绍的卷积过程相似,咱们定义一个空间池.池化操做有Max, Average, Sum etc.
Spatial Pooling (also called subsampling or downsampling) reduces the dimensionality of each feature map but retains the most important information. Spatial Pooling can be of different types: Max, Average, Sum etc.
下图展现了用一个2*2的filter作最大池化后的效果:
下图展现了实际的特征图作不一样的池化操做的效果:
池化有如下4个做用
- makes the input representations (feature dimension) smaller and more manageable
- reduces the number of parameters and computations in the network, therefore, controlling overfitting [4]
- makes the network invariant to small transformations, distortions and translations in the input image (a small distortion in input will not change the output of Pooling – since we take the maximum / average value in a local neighborhood).
- helps us arrive at an almost scale invariant representation of our image (the exact term is “equivariant”). This is very powerful since we can detect objects in an image no matter where they are located (read [18] and [19] for details).
全链接层是一个在输出层使用了softmax激活函数的多层感知机.
卷积层和池化层的输出的特征图矩阵,表明了输入图像的高层次特征(high-level features).全链接层使用这些高层次特征对输入图片进行分类.
除了用于分类,添加一个全链接层一般也是一种为特征组合添加非线性的方式.对分类任务来讲,使用卷积和池化层输出的特征就已经能取得不错的结果,可是把这些特征组合到一块儿,效果会更好.
全链接层输出的分类几率之和为1.这是由softmax保证的.
以上述图片识别为例,咱们要识别出来这张图应该被分类为dog/cat/boat/bird?
上文说过了,卷积层和池化层的做用是特征提取,全链接层的做用是分类.
整个神经网络的训练过程以下:
这样咱们的神经网络的filter/parameters/weights这些就肯定下来了,当来了一个新的图片,咱们就能够按照前面说的卷积-池化-全链接这个过程处理图片对其进行分类.
几点要注意的:
这是一个1024个像素点(32*32)的图片。
卷积层1有6个filter,每一个filter是5*5矩阵(stride=1)。 28*28
池化层1作2*2 max pooling(stride=2)。
能够看出来作max pooling以后,图片留下了最亮的点.
卷积层2有6个filter,每一个filter是5*5矩阵(stride=1)。
池化层2作2*2 max pooling(stride=2)。
接下来是3个全链接层
cnn识别手写数字集
model = Sequential() model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same',activation ='relu', input_shape = (28,28,1))) model.add(Conv2D(filters = 64, kernel_size = (5,5),padding = 'Same', activation ='relu')) model.add(MaxPool2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dense(256, activation = "relu")) model.add(Dropout(0.2)) model.add(Dense(10, activation = "softmax")) model.compile(optimizer = "SGD" , loss = "categorical_crossentropy", metrics=["accuracy"]) model.fit(X_train, Y_train, batch_size=100, verbose=1,epochs=5,validation_data=(X_val, Y_val))
完整代码见https://github.com/sdu2011/nlp/blob/master/keras.ipynb.