首页 > 编程知识 正文

为什么有多层卷积层池化层,卷积层 激活层 池化层

时间:2023-05-03 14:54:43 阅读:181969 作者:3875

是时候建立最简单的网络后,加入卷积和池化了。 这个,虽然还没有开始构想,但我知道一定是很长的文章。

除了所有连接层之外,卷积神经网络(CNN )与卷积层进行池化(因为可能不包括所有连接层) 卷积层用于提取特征,池化层可以减少参数数量。

卷积层首先谈谈卷积层的工作原理。

我们使用卷积核提取特征。 卷积核可以说是矩阵。 假设卷积内核设置了3*3的矩阵,并且我们的照片是分辨率为5*5的照片。 卷积核的任务如下。

来自: https://mlnotebook.github.io/post/CNN1/

从左上角开始,卷积内核对应于数据的3*3的矩阵范围,进行乘法相加得到值。 在这个过程中,如果每隔1个像素操作,就会得到9个值。 由这九个值形成的矩阵称为“活动贴图”(Activation map )。 这就是卷积层的结构。 另请参阅以下gif:

其中,卷积核是

101010101 1 0 1 0 1 0 1 0 1

来自: https://blog.csdn.net/yun Piao 123456/article/details/52437794

其实我们平时举的卷积核已经翻转了180度,主要是为了计算过程。 我不知道详细情况,但原理是一样的。

但其实我们输入的图片一般是三维的,即包含r、g、b三个通道。 但是,实际上经过卷积核,三维变成一维。 当整个屏幕滑动时,实际上三个通道的值会累积,最终输出一维矩阵。 然后,由多个卷积核(一个卷积层的卷积核的数量是自己决定的)滑动形成的Activation Map叠加在一起,再经过激活函数后成为一个卷积层的输出。

来自: CS231n,卷积与池化

卷积层有两个重要参数:步长和步长。

步骤是指控制卷积核移动的距离。 在上面的示例中,您可以看到所有卷积核都映射在一个像素之间。 那么,可以隔开两个、三个。 这个距离称为步骤。

padding是我们对数据进行的操作。 一般有不进行操作的和为了不改变卷积后的主动映射的大小而补0的两种。 上面可以看到5*5*3数据卷积在3*3卷积内核上的映射图。 形状为3*3。 也就是说,形状与最初的数据不同。 为了避免这种变化,可以使用“补0”方法——在数据外部补0。

示意图如下所示。

第二步(照片来自机器的心) )。

弥补0的变化(照片来自机器的心) )。

了解卷积发展史的人应该知道,卷积神经网络APP应用的第一次出现是LeCun (名字真的很像中国人)识别手写数字后制作的LeNet-5。

后面爆炸是因为AlexNet在ImageNet比赛中拔了头,勉强把误差降到了去年的一半。 从此,卷积网络成为AI的一大热点,众多论文和网络不断发挥其潜能,其黑匣子性也不断得到阐释。

你能直观地解释卷积神经网络的结构吗? - Owl of Minerva女士的回答-介绍了我们通过平滑操作图像,卷积核是如何读取特征的。

首先需要明确。 实验表明,人的视觉从图像的边缘开始就很敏感。 我的理解是,那就是我们对现有事物的想象,是先提取边界特征,再逐渐完善后再组装的。 我们的卷积层很好地实现了这一点。

3https://ujwalkarn.me/2016/08/11/intuitive-explanation-convnets /

这是两个不同的卷积核滑动整个图像的结果,经过卷积可以看出图像边界更直观。 也可以看到在VGG-16网络的第一层卷积中提取的特征:

从这件事也可以看出为什么我们不能只有一个卷积核。 我的理解是,如果我们只有一个卷积核,我们可能只能提取一个边界。 但是,我们有很多卷积核检测的不同边界,不同的边界又构成了不同的物体。 这就是我们

怎么从视觉图像检测物体的凭据了。所以,深度学习的“深”不仅仅是代表网络,也代表我们能检测的物体的深度。即越深,提取的特征也就越多。

Google提出了一个项目叫Deepdream,里面通过梯度上升、反卷积形象的告诉我们一个网络究竟想要识别什么。之前权重更新我们讲过梯度下降,而梯度上升便是计算卷积核对输入的噪声的梯度,然后沿着上升的方向调整我们的输入。详细的以后再讲,但得出的图像能够使得这个卷积核被激活,也就是说得到一个较好的值。所以这个图像也就是我们卷积核所认为的最规范的图像(有点吓人):


其实这鹅看着还不错,有点像孔雀。

池化层 (pooling layer)

前面说到池化层是降低参数,而降低参数的方法当然也只有删除参数了。

一般我们有最大池化和平均池化,而最大池化就我认识来说是相对多的。需要注意的是,池化层一般放在卷积层后面。所以池化层池化的是卷积层的输出!


来自:https://blog.csdn.net/yunpiao123456/article/details/52437794

扫描的顺序跟卷积一样,都是从左上角开始然后根据你设置的步长逐步扫描全局。有些人会很好奇最大池化的时候你怎么知道哪个是最大值,emmm,其实我也考虑过这个问题。CS2131n里面我记得是说会提前记录最大值保存在一个矩阵中,然后根据那个矩阵来提取最大值。

至于要深入到计算过程与否,应该是没有必要的。所以我也没去查证过程。而且给的都是示例图,其实具体的计算过程应该也是不同的,但效果我们可以知道就好了。

至于为什么选择最大池化,应该是为了提取最明显的特征,所以选用的最大池化。平均池化呢,就是顾及每一个像素,所以选择将所有的像素值都相加然后再平均。

池化层也有padding的选项。但都是跟卷积层一样的,在外围补0,然后再池化。

代码解析 import tensorflow as tfimport numpy as npfrom tensorflow.examples.tutorials.mnist import input_datamnist = input_data.read_data_sets("MNIST_data/", one_hot=True)summary_dir = './summary'#批次batch_size = 100n_batch = mnist.train.num_examples // batch_sizex = tf.placeholder(tf.float32, [None, 784], name='input')y = tf.placeholder(tf.float32, [None, 10], name='label')def net(input_tensor): conv_weights = tf.get_variable('weight', [3, 3, 1, 32], initializer=tf.truncated_normal_initializer(stddev=0.1)) conv_biases = tf.get_variable('biase', [32], initializer=tf.constant_initializer(0.0)) conv = tf.nn.conv2d(input_tensor, conv_weights, strides=[1, 1, 1, 1], padding='SAME') relu = tf.nn.relu(tf.nn.bias_add(conv, conv_biases)) pool = tf.nn.max_pool(relu, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME') pool_shape = pool.get_shape().as_list() nodes = pool_shape[1] * pool_shape[2] * pool_shape[3] pool_reshaped = tf.reshape(pool, [-1, nodes]) W = tf.Variable(tf.zeros([nodes, 10]), name='weight') b = tf.Variable(tf.zeros([10]), name='bias') fc = tf.nn.softmax(tf.matmul(pool_reshaped, W) + b) return fcreshaped = tf.reshape(x, (-1, 28, 28, 1))prediction = net(reshaped)loss_ = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(y, 1), logits=prediction, name='loss')loss = tf.reduce_mean(loss_)train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1))accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name='accuracy')init = tf.global_variables_initializer()with tf.Session() as sess: sess.run(init) for epoch in range(31): for batch in range(n_batch): batch_xs, batch_ys = mnist.train.next_batch(batch_size) sess.run(train_step, feed_dict={x: batch_xs, y: batch_ys}) acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels}) print('Iter' + str(epoch) + ",Testing Accuracy" + str(acc))

这相对于我第一个只用全连接的网络只多了一个net函数,还有因为卷积层的关系进来的数据x需要改变形状。只讲这两部分:

reshaped = tf.reshape(x, (-1, 28, 28, 1))prediction = net(reshaped)

由于我们feedict上面是,feed_dict={x: mnist.test.images, y: mnist.test.labels},而这样子调用tensorflow的句子我们得到的x是固定的形状。因此我们应用tf.reshape(x_need_reshaped,object_shape)来得到需要的形状。

其中的 −1 − 1 表示拉平,不能用None,是固定的。

conv_weights = tf.get_variable('weight', [3, 3, 1, 32], initializer=tf.truncated_normal_initializer(stddev=0.1))conv_biases = tf.get_variable('biase', [32], initializer=tf.constant_initializer(0.0))conv = tf.nn.conv2d(input_tensor, conv_weights, strides=[1, 1, 1, 1], padding='SAME')relu = tf.nn.relu(tf.nn.bias_add(conv, conv_biases))pool = tf.nn.max_pool(relu, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')

大部分都是应用内置的函数,来初始化weight(就是卷积核)和biases(偏置项)。偏置项我们没有提到,但其实就是多了一个参数来调控,因此我们讲卷积层的时候也没怎么讲。按照代码就是出来Activation Map之后再分别加上bias。池化也是用到了最大池化。

注意一下relu。它也是一个激活函数,作用可以说跟之前讲的softmax一样,不过它在卷积层用的比较多,而且也是公认的比较好的激活函数。它的变体有很多。有兴趣大家可以自己去查阅资料。以后才会写有关这方面的文章。

pool_shape = pool.get_shape().as_list() nodes = pool_shape[1] * pool_shape[2] * pool_shape[3] pool_reshaped = tf.reshape(pool, [-1, nodes]) W = tf.Variable(tf.zeros([nodes, 10]), name='weight')

池化层的输出我们并不知道它是如何的形状(当然,你也可以动手算)。因此就算把池化层拉成一维的矩阵,我们也不知道W需要如何的形状。因此,我们查看pool(即池化层的输出)的形状,我暗地里print了一下为[None, 14, 14, 32],因此pool拉平后,就是[None, 14*14*32, 10]。为了接下来进行全连接层的计算,我们的W的形状也应该为[14*14*32, 10]。这段代码的原理就是如此。

准确率也一样取后15次:

emmm, 不用跟之前比了,明显比以前好很多了。下一章决定总结一下,优化的方法好了。

参考
https://mlnotebook.github.io/post/CNN1/(可惜是全英)
能否对卷积神经网络工作原理做一个直观的解释? - Owl of Minerva的回答 - 知乎
CS231n

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。