卷积神经网络学习笔记

一、卷积神经网络结构:

卷积层

conv作用:

卷积层是一个n*n*m的权重矩阵,下图一目了然:

单个卷积核

channel:一个卷积层的核数,对rgb图像channel = 3

kernel size:卷积核的维度

步长(step size):卷积核每次移动的像素点个数

边距(padding size):图像边缘补齐的像素点个数,目的是增加卷积核扫描到原始图像边缘的几率,理论上padding size超过卷积核的dimension--n之后将失去意义(个人理解:不会再增加扫描到原始边缘像素的概率)

池化层

作用:1、减少参数 2、提取特征

卷积之后的结果代表了这个卷积窗口的特征,但是这些特征有冗余,pooling的目的就是去除冗余信息,同时pooling之后也丢失了局部信息。

MaxPooling Over Time

CNN模型中最常见的一种下采样操作。意思是对于某个Conv Filter抽取到若干特征值,只取其中得分最大的那个值作为Pooling层保留值,其它特征值全部抛弃,值最大代表只保留这些特征中最强的,而抛弃其它弱的此类特征。

K-Max Pooling

K-MaxPooling的意思是:原先的Max Pooling Over Time从Convolution层一系列特征值中只取最强的那个值,那么我们思路可以扩展一下,K-Max Pooling可以取所有特征值中得分在Top –K的值,并保留这些特征值原始的先后顺序(图3是2-max Pooling的示意图),就是说通过多保留一些特征信息供后续阶段使用。

Chunk-Max Pooling

Chunk-MaxPooling的思想是:把某个Filter对应的Convolution层的所有特征向量进行分段,切割成若干段后,在每个分段里面各自取得一个最大特征值,比如将某个Filter的特征向量切成3个Chunk,那么就在每个Chunk里面取一个最大值,于是获得3个特征值。(如图4所示,不同颜色代表不同分段)

Average pooling 和 Max-pooling

Average pooling在历史上用的更多, 但是由于max-pooling通常效果更好, 所以现在max-pooling更常使用. Max-pooling和average pooling都对数据进行下采样, 除此之外, max-pooling还提供了非线性, 这是max-pooling效果更好的一个重要原因.Average pooling并非一无是处, 现在average pooling更多的是用在global average pooling中. 这最早由Network in network提出, 目前在ResNet, GoogLeNet等主流网络中都有使用. 
分类问题上max-pooling相当于特征选择,选出有利于分类辨识度高的特征去分类。 

----来源 知乎

参考文章:如何理解卷积与pooling-----如何理解 卷积 和pooling - 白婷 - 博客园

卷积层和池化层的作用:

1、不变性:平移(translation)旋转(rotation)尺度(scale)

2、保留主要特征同时减少参数。减少计算量,防止过拟合

http://www.360doc.com/content/17/1127/11/42392246_707519156.shtml

二、Tensorflow中CNN的创建:

卷积层

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

# 除去name参数用以指定该操作的name,与方法有关的一共五个参数:

# # 第一个参数input:指需要做卷积的输入图像,它要求是一个Tensor,具有 [batch, in_height, in_width, in_channels] 这样的shape,具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一

# # 第二个参数filter:相当于CNN中的卷积核,它要求是一个Tensor,具有 [filter_height, filter_width, in_channels, out_channels]这样的shape,具体含义是 [卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维

# # 第三个参数strides:卷积时在图像每一维的步长,这是一个一维的向量,长度4

# # 第四个参数padding:string类型的量,只能是"SAME","VALID"其中之一,这个值决定了不同的卷积方式(后面会介绍)

# # 第五个参数:use_cudnn_on_gpu:bool类型,是否使用cudnn加速,默认为true

# # 结果返回一个Tensor,这个输出,就是我们常说的feature map

参考博客:TF-卷积函数 tf.nn.conv2d 介绍 - .每天进步一点点 - 博客园

具体实现:

# [batch, in_height, in_width, in_channels]
input_arg  = tf.Variable(tf.ones([4, 5, 5, 5]))
# [filter_height, filter_width, in_channels, out_channels]
filter_arg = tf.Variable(tf.ones([3 ,3 , 5 ,7]))
op2 = tf.nn.conv2d(input_arg, filter_arg, strides=[1,2,2,1], use_cudnn_on_gpu=False, padding='SAME')
oplist.append([op2, "case 8"])

with tf.Session() as a_sess:
    a_sess.run(tf.global_variables_initializer())
    for aop in oplist:
        print("----------{}---------".format(aop[1]))
        print(a_sess.run(aop[0]))
        print('---------------------\n\n')

输出结果为 7*5*5*4的一个张量。分别表示:

7:卷积核每运行一次输出的feature数量

5:卷积核在width方向移动的次数

5:卷积核在height方向移动的次数

4:训练时一个batch的图片数量

运行结果:

----------case 8---------
[[[[ 20. 20. 20. 20. 20. 20. 20.]
[ 30. 30. 30. 30. 30. 30. 30.]
[ 20. 20. 20. 20. 20. 20. 20.]]

[[ 30. 30. 30. 30. 30. 30. 30.]
[ 45. 45. 45. 45. 45. 45. 45.]
[ 30. 30. 30. 30. 30. 30. 30.]]

[[ 20. 20. 20. 20. 20. 20. 20.]
[ 30. 30. 30. 30. 30. 30. 30.]
[ 20. 20. 20. 20. 20. 20. 20.]]]


[[[ 20. 20. 20. 20. 20. 20. 20.]
[ 30. 30. 30. 30. 30. 30. 30.]
[ 20. 20. 20. 20. 20. 20. 20.]]

[[ 30. 30. 30. 30. 30. 30. 30.]
[ 45. 45. 45. 45. 45. 45. 45.]
[ 30. 30. 30. 30. 30. 30. 30.]]

[[ 20. 20. 20. 20. 20. 20. 20.]
[ 30. 30. 30. 30. 30. 30. 30.]
[ 20. 20. 20. 20. 20. 20. 20.]]]


[[[ 20. 20. 20. 20. 20. 20. 20.]
[ 30. 30. 30. 30. 30. 30. 30.]
[ 20. 20. 20. 20. 20. 20. 20.]]

[[ 30. 30. 30. 30. 30. 30. 30.]
[ 45. 45. 45. 45. 45. 45. 45.]
[ 30. 30. 30. 30. 30. 30. 30.]]

[[ 20. 20. 20. 20. 20. 20. 20.]
[ 30. 30. 30. 30. 30. 30. 30.]
[ 20. 20. 20. 20. 20. 20. 20.]]]


[[[ 20. 20. 20. 20. 20. 20. 20.]
[ 30. 30. 30. 30. 30. 30. 30.]
[ 20. 20. 20. 20. 20. 20. 20.]]

[[ 30. 30. 30. 30. 30. 30. 30.]
[ 45. 45. 45. 45. 45. 45. 45.]
[ 30. 30. 30. 30. 30. 30. 30.]]

[[ 20. 20. 20. 20. 20. 20. 20.]
[ 30. 30. 30. 30. 30. 30. 30.]
[ 20. 20. 20. 20. 20. 20. 20.]]]]
---------------------

池化层

以最大池化方法为例:

tf.nn.max_pool(value, ksize, strides, padding, name=None)

参数是四个,和卷积很类似:

第一个参数value:需要池化的输入,一般池化层接在卷积层后面,所以输入通常是feature map,依然是[batch, height, width, channels]这样的shape

第二个参数ksize:池化窗口的大小,取一个四维向量,一般是[1, height, width, 1],因为我们不想在batch和channels上做池化,所以这两个维度设为了1

第三个参数strides:和卷积类似,窗口在每一个维度上滑动的步长,一般也是[1, stride,stride, 1]

第四个参数padding:和卷积类似,可以取'VALID' 或者'SAME'

返回一个Tensor,类型不变,shape仍然是[batch, height, width, channels]这种形式


示例源码:

假设有这样一张图,双通道

第一个通道:

第二个通道:

用程序作最大池化:

import tensorflow as tf  
  
a=tf.constant([  
        [[1.0,2.0,3.0,4.0],  
        [5.0,6.0,7.0,8.0],  
        [8.0,7.0,6.0,5.0],  
        [4.0,3.0,2.0,1.0]],  
        [[4.0,3.0,2.0,1.0],  
         [8.0,7.0,6.0,5.0],  
         [1.0,2.0,3.0,4.0],  
         [5.0,6.0,7.0,8.0]]  
    ])  
  
a=tf.reshape(a,[1,4,4,2])  
  
pooling=tf.nn.max_pool(a,[1,2,2,1],[1,1,1,1],padding='VALID')  
with tf.Session() as sess:  
    print("image:")  
    image=sess.run(a)  
    print (image)  
    print("reslut:")  
    result=sess.run(pooling)  
    print (result)

输出结果:

image:  
[[[[ 1.  2.]  
   [ 3.  4.]  
   [ 5.  6.]  
   [ 7.  8.]]  
  
  [[ 8.  7.]  
   [ 6.  5.]  
   [ 4.  3.]  
   [ 2.  1.]]  
  
  [[ 4.  3.]  
   [ 2.  1.]  
   [ 8.  7.]  
   [ 6.  5.]]  
  
  [[ 1.  2.]  
   [ 3.  4.]  
   [ 5.  6.]  
   [ 7.  8.]]]]  
reslut:  
[[[[ 8.  7.]  
   [ 6.  6.]  
   [ 7.  8.]]  
  
  [[ 8.  7.]  
   [ 8.  7.]  
   [ 8.  7.]]  
  
  [[ 4.  4.]  
   [ 8.  7.]  
   [ 8.  8.]]]]  

池化后的图片:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值