首页 > 编程知识 正文

卷积神经网络cnn原理,cnn图像识别

时间:2023-05-05 23:49:20 阅读:128794 作者:3211

CNN卷积神经网络和图像识别序言神经网络(neual networks )是人工智能研究领域的一部分,目前最流行的神经网络是深度卷积神经网络(deepconvolutionalneution ) 目前,CNNs和卷积神经网络已不再特意区分学术界和工业界,一般指深层结构的卷积神经网络,层数从几层到几百层不等。

cns目前在:语音识别、图像识别、图像分割、自然语言处理等多个研究领域取得了巨大成功。 这些领域解决的问题不同,但这些应用方法都可以归纳为:

CNNs可以自动从(通常是大型)数据中学习特征,并将结果泛化为同类未知数据。

卷积神经网络-CNN基本原理网络结构基础的CNN卷积(convolution ),激活) CNN输出的结果是每个图像的特定特征空间。 处理图像分类任务时,将CNN输出的特征空间作为http://www.Sina.com/(fullyconnectedneuralnetwork,FCN ) )的输入,将输入图像到标签集的映射,即分类进行全级联当然,整个过程中最重要的工作是使用训练数据反复调整网络权重。 也就是说,池化当前主流卷积神经网络(CNNs ),例如VGG、ResNet都是由简单的CNN调节、组合构成的。

全连接层或全连接神经网络

卷积层:卷积层负责提取图像中的局部特征; 池化层(池化层用于大幅降低参数水平(降维); 全连接层:一种类似于全连接层传统神经网络的部分,用于输出期望的结果。 在卷积CNN的情况下,卷积可被近似地视为后向传播算法,并且简单地说是提取图像的纹理、边缘等的特征信息的滤波器。 以下是一个简单的例子,说明特征提取运算符是如何工作的。

比如有猫的照片。 人类在理解这张照片的时候,可能会观察到圆圆的眼睛、可爱的耳朵。 于是,我判断这是猫。 但是,机器如何处理这个问题呢? 在传统的计算机视觉方法中,通常设计一些算子(特征提取滤波器)来发现诸如眼睛边界、耳朵边界等信息,并将这些特征进行集成,以得出——这是猫的结论。

卷积神经网络做了类似的事情。 卷积使一个运算符在原始图上不断滑动,从而产生过滤结果——。 我们称为“特征图”(Feature Map ),这些运算符称为“卷积核”(Convolution Kernel )。 区别在于,我们用随机初始化而不是典型的 CNN 由3个部分构成:得到了很多卷积核(算子),通过反向传播优化了这些卷积核,希望能得到更好的识别结果。

卷积的运算过程可以用下图表示。

已知卷积运算后数据变少,并且如果经过很多层进行卷积,则在输出尺寸变小的同时,可能会迅速丢失图像的边缘信息,从而对模型的性能产生了不可忽视的影响。 为了减少因卷积操作而导致的边缘信息的消失,需要在原始图像周围进行填充(padding ),在该填充中添加一圈值为“0”的像素点“zero Padding”。 然后,输出维和输入维匹配。

上面的卷积过程不考虑彩色图像中有RGB三维通道。 考虑到RGB通道,每个通道都需要卷积核心:

如果输入中有多个信道,那么我们的卷积核也需要相同数量的信道。 上图输入了RGB的三个通道。 卷积核心也有三个通道。 但是,在计算过程中,卷积核心的每个通道都会在相应的通道中滑动。 (卷积核心的第一个通道用输入图像的红色通道滑动,卷积核心的中央通道用输入图像的绿色通道滑动,卷积核心的最后一个通道用输入图像的蓝色通道滑动。 )如果要合并三个通道的信息,请注意输出三个通道的计算只有一个通道。

特征提取算子

提取图像特征,且卷积核权重可以学习,卷积操作可以突破传统滤波器的限制,通过目标函数提取期望的特征; 参数共享会降低网络参数,提高培训效率。 池化(池化(Pooling ) )在某些位置也称为收敛,实际上是降采样(Down-sample )过程。 因为输入的图像的尺寸可能很大,所以这时需要缩减像素采样以缩小图像的尺寸。 池化层在缩小模型规模、提高运算速度的同时,还可以提高提取特征的鲁棒性。

本文主要介绍最大池化(Max Pooling )和平均池化(Average Pooling )。

最大池化是指在一定区域中选择并保留数值最大的。 例如,区域大小为2*2、步长为2的池化过程如下,左侧为池化前,右侧为池化后。 每个池化区域取最大值。

最大池化是最常用的,通常采用2*2的区域大小,步长为2。

平均池化取各地区的平均,下图显示了两种池化的比较

全连接层

全连接层就是把卷积层和池化层的输出展开成一维形式,在后面接上与普通网络结构相同的回归网络或者分类网络,一般接在池化层后面,这一层的输出即为我们神经网络运行的结果。

代码示例

下面以AlexNet为例子,给出一个详细的卷积神经网络架构,首先AlexNet架构如下图所示:

代码如下:

import tensorflow as tfimport numpy as np# 定义各层功能# 最大池化层def maxPoolLayer(x, kHeight, kWidth, strideX, strideY, name, padding = "SAME"): """max-pooling""" return tf.nn.max_pool(x, ksize = [1, kHeight, kWidth, 1], strides = [1, strideX, strideY, 1], padding = padding, name = name) # dropoutdef dropout(x, keepPro, name = None): """dropout""" return tf.nn.dropout(x, keepPro, name) # 归一化层def LRN(x, R, alpha, beta, name = None, bias = 1.0): """LRN""" return tf.nn.local_response_normalization(x, depth_radius = R, alpha = alpha, beta = beta, bias = bias, name = name) # 全连接层def fcLayer(x, inputD, outputD, reluFlag, name): """fully-connect""" with tf.variable_scope(name) as scope: w = tf.get_variable("w", shape = [inputD, outputD], dtype = "float") b = tf.get_variable("b", [outputD], dtype = "float") out = tf.nn.xw_plus_b(x, w, b, name = scope.name) if reluFlag: return tf.nn.relu(out) else: return out # 卷积层def convLayer(x, kHeight, kWidth, strideX, strideY, featureNum, name, padding = "SAME", groups = 1): """convolution""" channel = int(x.get_shape()[-1]) conv = lambda a, b: tf.nn.conv2d(a, b, strides = [1, strideY, strideX, 1], padding = padding) with tf.variable_scope(name) as scope: w = tf.get_variable("w", shape = [kHeight, kWidth, channel/groups, featureNum]) b = tf.get_variable("b", shape = [featureNum]) xNew = tf.split(value = x, num_or_size_splits = groups, axis = 3) wNew = tf.split(value = w, num_or_size_splits = groups, axis = 3) featureMap = [conv(t1, t2) for t1, t2 in zip(xNew, wNew)] mergeFeatureMap = tf.concat(axis = 3, values = featureMap) # print mergeFeatureMap.shape out = tf.nn.bias_add(mergeFeatureMap, b) return tf.nn.relu(tf.reshape(out, mergeFeatureMap.get_shape().as_list()), name = scope.name) class alexNet(object): """alexNet model""" def __init__(self, x, keepPro, classNum, skip, modelPath = "bvlc_alexnet.npy"): self.X = x self.KEEPPRO = keepPro self.CLASSNUM = classNum self.SKIP = skip self.MODELPATH = modelPath #build CNN self.buildCNN() # 构建AlexNet def buildCNN(self): """build model""" conv1 = convLayer(self.X, 11, 11, 4, 4, 96, "conv1", "VALID") lrn1 = LRN(conv1, 2, 2e-05, 0.75, "norm1") pool1 = maxPoolLayer(lrn1, 3, 3, 2, 2, "pool1", "VALID") conv2 = convLayer(pool1, 5, 5, 1, 1, 256, "conv2", groups = 2) lrn2 = LRN(conv2, 2, 2e-05, 0.75, "lrn2") pool2 = maxPoolLayer(lrn2, 3, 3, 2, 2, "pool2", "VALID") conv3 = convLayer(pool2, 3, 3, 1, 1, 384, "conv3") conv4 = convLayer(conv3, 3, 3, 1, 1, 384, "conv4", groups = 2) conv5 = convLayer(conv4, 3, 3, 1, 1, 256, "conv5", groups = 2) pool5 = maxPoolLayer(conv5, 3, 3, 2, 2, "pool5", "VALID") fcIn = tf.reshape(pool5, [-1, 256 * 6 * 6]) fc1 = fcLayer(fcIn, 256 * 6 * 6, 4096, True, "fc6") dropout1 = dropout(fc1, self.KEEPPRO) fc2 = fcLayer(dropout1, 4096, 4096, True, "fc7") dropout2 = dropout(fc2, self.KEEPPRO) self.fc3 = fcLayer(dropout2, 4096, self.CLASSNUM, True, "fc8") def loadModel(self, sess): """load model""" wDict = np.load(self.MODELPATH, encoding = "bytes").item() #for layers in model for name in wDict: if name not in self.SKIP: with tf.variable_scope(name, reuse = True): for p in wDict[name]: if len(p.shape) == 1: #bias sess.run(tf.get_variable('b', trainable = False).assign(p)) else: #weights sess.run(tf.get_variable('w', trainable = False).assign(p))

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