tensorflow 之 卷积神经网络

Easter79
• 阅读 822

应用场景

  1. 图像识别与检索
  2. 人脸识别
  3. 性别/年龄/情绪识别
  4. 物体检测
  5. 视频处理
  6. 语音分析

概述

一般一个卷积神经网络由多个卷积层构成,在卷基层内部通常会有如下几个操作:

  1. 图像通过多个卷积核滤波,添加偏置,提取局部特征每个卷积核会映射出一个新的2D图像。
  2. 卷积核的滤波结果输出到激活函数中,激活函数通常选ReLU
  3. 对激活函数的结果进行池化操作,池化就是对图像分割成不同的小区域后取平均值或最大值。一般取最大值。

上述几个步骤就构成了最常见的卷积层。在池化的后面还可以加上batch normalization等操作。

一个卷积层中可以有不同的卷积核,而每一个卷积核都对应一个滤波后映射出的新图像,同一个新图像的每一个像素都来自完全相同的卷积核。这种卷积核的权值共享可以有效降低模型负责度,减轻过拟合,减少计算量。

卷积神经网络结构

建立卷积神经网络对手写数字识别问题进行优化,构建由两个卷积层(包含池化层),两个全连接层构成的卷积神经网络。输入图像是28×28的单通道数据,输出是10×1的one_hot编码的向量。

第一层:卷积核大小是[5,5],输入通道1,输出通道32,padding选择SAME模式,激活函数为relu。
第二层:池化层,池化核大小是[2,2],步长[2,2]。
第三层:卷积核大小是[5,5],输入通道32,输出通道64,padding选择SAME模式,激活函数为relu。
第四层:池化层,设置同上。
第五层:全连接层,首先将图像数据矩阵flatten化,变成1维向量,输出维度是1024, 之后dropout掉一定的数据防止过拟合
第六层:全连接层,输出维度10,激活函数为softmax

tensorflow 之 卷积神经网络

一个卷积神经网络主要由以下五种结构组成:
(1)输入层 输入层是整个神经网络的输入,在处理图像的卷积神经网络中,它一般代表了一张图片的像素矩阵。从输入层开始,卷积神经网络通过不同的神经网络结构将上一层的三维矩阵转化为下一层的三维矩阵,直到最后的全连接层。
(2)卷积层 前一层的特征图与卷积核进行卷积运算,运算的结果再加偏置,经过激活函数后形成这一层的神经元,每个神经元的输入与前一层局部感知野 (receptive field)相连接,并提取该局部特征。一单该局部特征被提取,它与其他特征之间的位置关系就被确定。卷积层中每一个节点的输入只是上一层神经网络的一小块,这个小块(也叫过滤器,滤波器,卷积核,权重)常用的大小有3×3或5×5。卷积层试图将神经网络中的每一小块进行更加深入地分析从而得到抽象程度更高的特征。一般通过卷积层处理过的节点矩阵会变得更深。

卷积神经网络有两种神器可以降低参数数目。
  第一种神器叫做局部感知野,一般认为人对外界的认知是从局部到全局的,而图像的空间联系也是局部的像素联系较为紧密,而距离较远的像素相关性则较弱。因而,每个神经元其实没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。
  第二种神器,即权值(权重或卷积核或过滤器)共享。
tensorflow 之 卷积神经网络

tensorflow 之 卷积神经网络

上述操作处理图像得到新图像的操作称为卷积, 在图像处理中卷积核也被称为过滤器(filter).

卷积得到的结果矩阵通常用于表示原图的某种特征(如边缘), 因此卷积结果被称为特征图(Feature Map).

每个卷积核可以包含一个偏置参数b, 即对卷积结果的每一个元素都加b作为输出的特征图.

(3)池化层
池化层神经网络不会改变三维矩阵的深度,但可以缩小矩阵的大小。池化操作可以认为是将一张分辨率较高的图片转化为分辨率较低的图片。通过池化层,能进一步缩小最后全连接层中的节点数,达到减少整个神经网络中参数的目的。这层利用图像局部相关性的原理,对图像进行子抽样,可以减少数据处理量同时保留有用信息,相当于图像压缩。

用16个小方阵的均值组成一个4x4方阵便是均值池化, 类似地还有最大值池化等操作. 均值池化对保留背景等特征较好, 最大值池化对纹理提取更好. 随机池化则是根据像素点数值大小赋予概率(权值), 然后按其加权求和.

tensorflow 之 卷积神经网络

池化操作用于减少图的宽度和高度, 但不能减少通道数。

(4)全连接层
输入信号经过多次卷积池化运算后,输出为多组信号,经过全连接运算,将多组信号一次组合为一组信号。可以将卷积层和池化层看成自动图像特征提取的过程。在特征提取完成后,需要使用全连接层来完成分类任务。

(5)Softmax层
用于分类问题,得到当前样例属于不同种类的概率分布情况。

卷积操作细节,输入输出维度的思维训练

"""
卷积神经网络 解决全连接神经网络参数过多的问题。
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)
input: 需要做卷积的图像,是一个tensor,形状是 [batch, in_height, in_width, in_channels].具体含义是:
      “训练一个batch的图片数量,图片高度,图片宽度,图片通道数”,注意这是一个四维的tensor。要求类型为float32或float64.
filter: 相当于CNN的卷结核,是一个tensor,具有[filter_height, filter_width, in_channels, out_channels]具体含义是:
        "卷积核的高度,滤波器的宽度,图像通道数,滤波器个数",要求类型与input相同。有一个地方需要注意,第三维in_channels,就是
        input的第四维。
strides: 卷积时在图像每一维的步长,这是一个一维的向量,长度 4
padding: 定义元素边框与元素内容之间的空间。值为“VALID”表示边缘不填充,“SAME”表示填充到滤波器可以到达图像边缘。
use_cudnn_on_gpu: bool类型,是否使用cudnn加速,默认使用。
返回值:是一个tensor,即 feature map.

"""
import tensorflow as tf

# [batch, in_height, in_width, in_channels] [训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数]
# 定义三个输入变量,来模拟输入图片。分别是 5x5大小 1个通道的矩阵。。。并将里面的的值统统赋值为1
input = tf.Variable(tf.constant(1.0, shape=[1, 5, 5, 1]))
input2 = tf.Variable(tf.constant(1.0, shape=[1, 5, 5, 2]))
input3 = tf.Variable(tf.constant(1.0, shape=[1, 4, 4, 1]))

# [filter_height, filter_width, in_channels, out_channels] [卷积核的高度,卷积核的宽度,图像通道数,卷积核个数]
# 定义5个卷积核变量, 每个卷积核都是2x2的矩阵, 只是输入,输出的通道数有差别.
filter1 = tf.Variable(tf.constant([-1.0, 0, 0, -1], shape=[2, 2, 1, 1]))
filter2 =  tf.Variable(tf.constant([-1.0,0,0,-1,-1.0,0,0,-1],shape = [2, 2, 1, 2]))
filter3 =  tf.Variable(tf.constant([-1.0,0,0,-1,-1.0,0,0,-1,-1.0,0,0,-1],shape = [2, 2, 1, 3])) # 输入1通道,输出3通道。
filter4 =  tf.Variable(tf.constant([-1.0,0,0,-1,
                                    -1.0,0,0,-1,
                                    -1.0,0,0,-1,
                                    -1.0,0,0,-1],shape = [2, 2, 2, 2]))
filter5 =  tf.Variable(tf.constant([-1.0,0,0,-1,-1.0,0,0,-1],shape = [2, 2, 2, 1]))

# 定义卷积操作
# padding的值为‘VALID’,表示边缘不填充, 当其为‘SAME’时,表示填充到卷积核可以到达图像边缘
op1 = tf.nn.conv2d(input, filter1, strides=[1, 2, 2, 1], padding='SAME')  # 1个通道输入,生成1个feature map, 步长为2x2
op2 = tf.nn.conv2d(input, filter2, strides=[1, 2, 2, 1], padding='SAME')  # 1个通道输入,生成2个feature map, 步长为2x2
op3 = tf.nn.conv2d(input, filter3, strides=[1, 2, 2, 1], padding='SAME')  # 1个通道输入,生成3个feature map, 步长为2x2

op4 = tf.nn.conv2d(input2, filter4, strides=[1, 2, 2, 1], padding='SAME') # 2个通道输入,生成2个feature
op5 = tf.nn.conv2d(input2, filter5, strides=[1, 2, 2, 1], padding='SAME') # 2个通道输入,生成一个feature map

vop1 = tf.nn.conv2d(input, filter1, strides=[1, 2, 2, 1], padding='VALID') # 5*5 对于pading不同而不同
op6 = tf.nn.conv2d(input3, filter1, strides=[1, 2, 2, 1], padding='SAME')
vop6 = tf.nn.conv2d(input3, filter1, strides=[1, 2, 2, 1], padding='VALID')  #4*4与pading无关

init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    # print("op1:\n",sess.run([op1, filter1]))# 1-1  后面补0
    # print("------------------")
    #
    print("op2:\n",sess.run([op2,filter2])) #1-2多卷积核 按列取
    print("op3:\n",sess.run([op3,filter3])) #1-3
    # print("------------------")

    # print("op4:\n",sess.run([op4,filter4]))#2-2    通道叠加
    # print("op5:\n",sess.run([op5,filter5]))#2-1
    # print("------------------")


    print("op1:\n",sess.run([op1,filter1]))#1-1
    print("vop1:\n",sess.run([vop1,filter1]))
    print("op6:\n",sess.run([op6,filter1]))
    print("vop6:\n",sess.run([vop6,filter1]))

tensorflow 之 卷积神经网络

结果可以看出: 5x5 矩阵通过卷积操作生成了 3X3矩阵,对padding的补0情况是在后面和下面,所以会在矩阵的右边和下边生成-1.

tensorflow 之 卷积神经网络

结果可以看出:
对于 op1和vop1的比较可以看出, 5x5 矩阵在padding 模式为 'SAME'时生成 3x3 矩阵,而在 'VALID' 时生成 2x2.

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
CNN中常用的四种卷积详解
卷积现在可能是深度学习中最重要的概念。正是靠着卷积和卷积神经网络,深度学习才超越了几乎其他所有的机器学习手段。这期我们一起学习下深度学习中常见的卷积有哪些?1\.一般卷积卷积在数学上用通俗的话来说就是输入矩阵与卷积核(卷积核也是矩阵)进行对应元素相乘并求和,所以一次卷积的结果的输出是一个数,最后对整个输入输入矩阵进行遍历,
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k