海南省住房和城乡建设厅网站网上版,html代码特效,企业所得税是利润的25%吗,提高景区网站建设知识要点 卷积神经网络的几个主要结构: 卷积层#xff08;Convolutions#xff09;: Valid :不填充#xff0c;也就是最终大小为卷积后的大小. Same#xff1a;输出大小与原图大小一致#xff0c;那么N 变成了N2P. padding-零填充. 池化层#xff08;Subsampli…知识要点 卷积神经网络的几个主要结构: 卷积层Convolutions: Valid :不填充也就是最终大小为卷积后的大小. Same输出大小与原图大小一致那么N 变成了N2P. padding-零填充. 池化层Subsampling, 主要对卷积层学习到的特征图进行亚采样处理 最大池化Max Pooling, 取窗口内的最大值作为输出 平均池化Avg Pooling, 取窗口内的所有值的均值作为输出 全连接层Full connection 卷积层激活层池化层可以看成是CNN的特征学习/特征提取层而学习到的特征Feature Map最终应用于模型任务,需要先对所有 Feature Map 进行扁平化. 激活函数 softmax, relu, selu, sigmoid filters , 卷积核, 必须是4维的tensor(卷积核的高度和宽度, 输入图片的通道数, 卷积核的个数)strides, 步长, 卷积核在图片的各个维度的移动步长, (1, 1, 1)padding, 0填充, valid和same, valid 表示不填充, same表示输入图片和输出图片的大小保持一致, (会自动计算)显示卷积过程中的图像:
# 边缘检测
input_img tf.constant(cat_gray.reshape(1, 456, 730, 1), dtype tf.float32)
filters tf.constant(np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]]).reshape(3, 3, 1, 1), dtype tf.float32)
strides [1, 1, 1, 1]
conv2d tf.nn.conv2d(input input_img, filters filters, strides strides, padding SAME)
plt.figure(figsize (10, 8))
plt.imshow(conv2d.numpy().reshape(456, 730), cmap gray) 一 卷积神经网络(CNN)原理
1.1 卷积神经网络的组成
1.1.1 简介 卷积神经网络由一个或多个卷积层、池化层以及全连接层等组成。与其他深度学习结构相比卷积神经网络在图像等方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他浅层或深度神经网络卷积神经网络需要考量的参数更少使之成为一种颇具吸引力的深度学习结构。
我们来看一下卷积网络的整体结构什么样子。 其中包含了几个主要结构 卷积层Convolutions 池化层Subsampling 全连接层Full connection 激活函数
1.1.2 卷积层 目的: 卷积运算的目的是提取输入的不同特征某些卷积层可能只能提取一些低级的特征如边缘、线条和角等层级更多层的网路能从低级特征中迭代提取更复杂的特征。 参数 size: 卷积核/过滤器大小选择有1 *1 3* 3 5 * 5 padding零填充Valid 与Same stride: 步长通常默认为1 计算公式 1.1.3 卷积运算过程
对于之前介绍的卷积运算过程我们用一张动图来表示更好理解些。一下计算中假设图片长宽相等设为N, 一个步长, 3 X 3 卷积核运算。
假设是一张5 X 5 的单通道图片通过使用3 X 3 大小的卷积核运算得到一个 3 X 3大小的运算结果图片像素数值仅供参考 我们会发现进行卷积之后的图片变小了假设N为图片大小F为卷积核大小
相当于:
如果我们换一个卷积核大小或者加入很多层卷积之后图像可能最后就变成了1 X 1 大小这不是我们希望看到的结果。并且对于原始图片当中的边缘像素来说只计算了一遍二对于中间的像素会有很多次过滤器与之计算这样导致对边缘信息的丢失。
缺点: 图像变小 边缘信息丢失
1.1.4 padding-零填充
零填充在图片像素的最外层加上若干层0值若一层记做p 1。 为什么增加的是0
因为0在权重乘积和运算中对最终结果不造成影响也就避免了图片增加了额外的干扰信息。
这张图中还是移动一个像素并且外面增加了一层0。那么最终计算结果我们可以这样用公式来计算, P为1那么最终特征结果为5。实际上我们可以填充更多的像素假设为2层则 这样得到的观察特征大小比之前图片大小还大。所以我们对于零填充会有一些选择该填充多少 1.1.5 Valid and Same卷积
有两种形式所以为了避免上述情况大家选择都是Same这种填充卷积计算方式 Valid :不填充也就是最终大小为: Same输出大小与原图大小一致那么N 变成了N2P:
那也就意味着之前大小与之后的大小一样得出下面的等式
所以当知道了卷积核的大小之后就可以得出要填充多少层像素。
1.1.6 奇数维度的过滤器 (卷积核)
通过上面的式子如果F不是奇数而是偶数个那么最终计算结果不是一个整数造成0.5,1.5.....这种情况这样填充不均匀所以也就是为什么卷积核默认都去使用奇数维度大小 1 *13* 3 5 *57* 7 另一个解释角度 奇数维度的过滤器有中心便于指出过滤器的位置
当然这个都是一些假设的原因最终原因还是在F对于计算结果的影响。所以通常选择奇数维度的过滤器是大家约定成俗的结果可能也是基于大量实验奇数能得出更好的结果。
1.1.7 stride-步长
以上例子中我们看到的都是每次移动一个像素步长的结果如果将这个步长修改为2,3那结果如何 这样如果以原来的计算公式那么结果:
但是移动2个像素才得出一个结果所以公式变为: 如果相除不是整数的时候向下取整为2。这里并没有加上零填充。
所以最终的公式就为
对于输入图片大小为N过滤器大小为F步长为S零填充为P:
1.2 多通道卷积
当输入有多个通道channel时(例如图片可以有 RGB 三个通道)卷积核需要拥有相同的channel 数, 每个卷积核 channel 与输入层的对应 channel 进行卷积将每个 channel 的卷积结果按位相加得到最终的 Feature Map。 1.2.1 多卷积核
当有多个卷积核时可以学习到多种不同的特征对应产生包含多个 channel 的 Feature Map, 例如上图有两个 filter所以 output 有两个 channel。这里的多少个卷积核也可理解为多少个神经元。相当于我们把多个功能的卷积核的计算结果放在一起比如水平边缘检测和垂直边缘检测器。 1.2.2 卷积总结
我们来通过一个例子看一下结算结果以及参数的计算 假设我们有10 个Filter每个Filter3 X 3 X 3计算RGB图片并且只有一层卷积那么参数有多少
计算每个Filter参数个数为 个权重参数总共28 * 10 280个参数即使图片任意大小我们这层的参数也就这么多。 假设一张200 *200* 3的图片进行刚才的Filter,步长为1最终为了保证最后输出的大小为200 * 200需要设置多大的零填充
1.2.3 设计单个卷积Filter的计算公式
假设神经网络某层l的输入 inputs: 卷积层参数设置 :filter的大小 :padding的大小 :stride大小 :filter的总数量 outputs
所以通用的表示每一层 每个Filter 权重Weights 应用激活函数Activations 偏差bias 通常会用4维度来表示
之前的式子我们就可以简化成,假设多个样本编程向量的形式:
1.3 池化层(Pooling)
池化层主要对卷积层学习到的特征图进行亚采样subsampling处理主要由两种 最大池化Max Pooling, 取窗口内的最大值作为输出 平均池化Avg Pooling, 取窗口内的所有值的均值作为输出
意义在于 降低了后续网络层的输入维度缩减模型大小提高计算速度 提高了Feature Map 的鲁棒性防止过拟合 对于一个输入的图片我们使用一个区域大小为2 *2步长为2的参数进行求最大值操作。同样池化也有一组参数f, s得到2* 2的大小。当然如果我们调整这个超参数比如说3 * 3那么结果就不一样了通常选择默认都是f 2 * 2, s 2
池化超参数特点不需要进行学习不像卷积通过梯度下降进行更新。
如果是平均池化则 1.4 全连接层
卷积层激活层池化层可以看成是CNN的特征学习/特征提取层而学习到的特征Feature Map最终应用于模型任务分类、回归 先对所有 Feature Map 进行扁平化flatten, 即 reshape 成 1 x N 向量 再接一个或多个全连接层进行模型学习 二 图像数据与边缘检测
2.1 为什么需要卷积神经网络
在计算机视觉领域通常要做的就是指用机器程序替代人眼对目标图像进行识别等。那么神经网络也好还是卷积神经网络其实都是上个世纪就有的算法只是近些年来电脑的计算能力已非当年的那种计算水平同时现在的训练数据很多于是神经网络的相关算法又重新流行起来因此卷积神经网络也一样流行。 1974年Paul Werbos提出了误差反向传导来训练人工神经网络使得训练多层神经网络成为可能。 1979年Kunihiko Fukushima福岛邦彦提出了Neocognitron 卷积、池化的概念基本形成。 1986年Geoffrey Hinton与人合著了一篇论文Learning representations by back-propagation errors。 1989年Yann LeCun提出了一种用反向传导进行更新的卷积神经网络称为LeNet。 1998年Yann LeCun改进了原来的卷积网络LeNet-5。
2.2 图像特征数量对神经网络效果压力
假设下图是一图片大小为28 * 28 的黑白图片时候每一个像素点只有一个值单通道。那么总的数值个数为 784个特征。 那现在这张图片是彩色的那么彩色图片由RGB三通道组成也就意味着总的数值有28 28 3 2352个值。 从上面我们得到一张图片的输入是2352个特征值即神经网路当中与若干个神经元连接假设第一个隐层是10个神经元那么也就是23520个权重参数。
如果图片再大一些呢假设图片为1000 *1000* 3那么总共有3百万数值同样接入10个神经元那么就是3千万个权重参数。这样的参数大小神经网络参数更新需要大量的计算不说也很难达到更好的效果大家就不倾向于使用多层神经网络了。
所以就有了卷积神经网络的流行那么卷积神经网络为什么大家会选择它。那么先来介绍感受野以及边缘检测的概念。
2.3 感受野
1962年Hubel和Wiesel通过对猫视觉皮层细胞的研究提出了感受野(receptive field)的概念 Fukushima基于感受野概念提出的神经认知机(neocognitron)可以看作是卷积神经网络的第一个实现网络。
单个感受器与许多感觉神经纤维相联系感觉信息是通过许多感受神经纤维发放总和性的空间与时间类型不同的冲动相当于经过编码来传递。 2.4 边缘检测
为了能够用更少的参数检测出更多的信息基于上面的感受野思想。通常神经网络需要检测出物体最明显的垂直和水平边缘来区分物体。比如 看一个列子一个 6×6的图像卷积与一个3×3的过滤器Filter or kenel进行卷积运算符号为 ** 也可能是矩阵乘法所以通常特别指定是卷积的时候代表卷积意思。 相当于将 Filter 放在Image 上从左到右、从上到下地默认一个像素移动过整个Image分别计算 ImageImage 被 Filter 盖住的部分与 Filter的逐元素乘积的和 在这个6×6 的图像中左边一半像素的值全是 10右边一半像素的值全是 0中间是一条非常明显的垂直边缘。这个图像与过滤器卷积的结果中中间两列的值都是 30两边两列的值都是 0即检测到了原 6×66×6 图像中的垂直边缘。
注虽然看上去非常粗是因为我们的图像太小只有5个像素长、宽所以最终得到结果看到的是两个像素位置如果在一个500 x 500的图当中就是一个竖直的边缘了。 随着深度学习的发展我们需要检测更复杂的图像中的边缘与其使用由人手工设计的过滤器还可以将过滤器中的数值作为参数通过反向传播来学习得到。算法可以根据实际数据来选择合适的检测目标无论是检测水平边缘、垂直边缘还是其他角度的边缘并习得图像的低层特征。
三 图片卷积实操
3.1 均值滤波
# 登月图
moon plt.imread(./moonlanding.png)
print(moon.shape) # (474, 630)
plt.figure(figsize(10, 8))
plt.imshow(moon, cmap gray) # 均值滤波 # 平滑处理, 用卷积直接扫描
input_img tf.constant(moon.reshape(1, 474, 630, 1), dtype tf.float32)
filters tf.constant(np.array([[1/9, 1/9, 1/9], [1/9, 1/9, 1/9], [1/9, 1/9, 1/9]]).reshape(3, 3, 1, 1),dtype tf.float32)
strides [1, 1, 1, 1]
conv2d tf.nn.conv2d(input input_img, filters filters, strides strides, padding SAME)
plt.figure(figsize (10, 8))
plt.imshow(conv2d.numpy().reshape(474, 630), cmap gray) # 高斯滤波 # 平滑处理, 用卷积直接扫描
input_img tf.constant(moon.reshape(1, 474, 630, 1), dtype tf.float32)
filters tf.constant(np.array([[1/9, 2/9, 1/9], [2/9, 3/9, 2/9], [1/9, 2/9, 1/9]]).reshape(3, 3, 1, 1), dtype tf.float32)
strides [1, 1, 1, 1]
conv2d tf.nn.conv2d(input input_img, filters filters, strides strides, padding SAME)
plt.figure(figsize (10, 8))
plt.imshow(conv2d.numpy().reshape(474, 630), cmap gray) # 均值滤波 # 平滑处理, 用卷积直接扫描
input_img tf.constant(moon.reshape(1, 474, 630, 1), dtype tf.float32)
filters tf.constant(np.array([[9/9, 9/9, 9/9, 9/9, 9/9], [9/9, 9/9, 9/9, 9/9, 9/9],[9/9, 9/9, 9/9, 9/9, 9/9], [9/9, 9/9, 9/9, 9/9, 9/9],[9/9, 9/9, 9/9, 9/9, 9/9]]).reshape(5, 5, 1, 1), dtype tf.float32)
strides [1, 1, 1, 1]
conv2d tf.nn.conv2d(input input_img, filters filters, strides strides, padding SAME)
plt.figure(figsize (10, 8))
plt.imshow(conv2d.numpy().reshape(474, 630), cmap gray) 3.2 边缘检测
cat plt.imread(./cat.jpg)
plt.figure(figsize (12, 8))
plt.imshow(cat) # 把猫变成黑白图片
cat_gray cat.mean(axis 2)
plt.figure(figsize (12, 8))
plt.imshow(cat_gray, cmap gray) # 边缘检测
input_img tf.constant(cat_gray.reshape(1, 456, 730, 1), dtype tf.float32)
filters tf.constant(np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]]).reshape(3, 3, 1, 1), dtype tf.float32)
strides [1, 1, 1, 1]
conv2d tf.nn.conv2d(input input_img, filters filters, strides strides, padding SAME)
plt.figure(figsize (10, 8))
plt.imshow(conv2d.numpy().reshape(456, 730), cmap gray) 3.3 锐化效果
# 边缘检测
input_img tf.constant(cat_gray.reshape(1, 456, 730, 1), dtype tf.float32)
filters tf.constant(np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]]).reshape(3, 3, 1, 1), dtype tf.float32)
strides [1, 1, 1, 1]
conv2d tf.nn.conv2d(input input_img, filters filters, strides strides, padding SAME)
plt.figure(figsize (10, 8))
plt.imshow(conv2d.numpy().reshape(456, 730), cmap gray) europe plt.imread(./欧式.jpg)
plt.figure(figsize(10, 8))
plt.imshow(europe)
print(europe.shape) # (582, 1024, 3) # 彩色图片
# 把每个通道当做一张图 # transpose通过索引调换维度位置
input_img tf.constant(europe.reshape(1, 582, 1024, 3).transpose([3, 1, 2, 0]), dtype tf.float32)
filters tf.constant(np.array([[1/9, 1/9, 1/9], [1/9, 1/9, 1/9], [1/9, 1/9, 1/9]]).reshape(3, 3, 1, 1), dtype tf.float32)
strides [1, 1, 1, 1]
conv2d tf.nn.conv2d(input input_img, filters filters, strides strides, padding SAME)
print(conv2d.shape) # (3, 582, 1024, 1)
plt.figure(figsize (10, 8))
plt.imshow(conv2d.numpy().reshape(3, 582, 1024).transpose([1, 2, 0])/255)