TensorFlow实例(5.2)--MNIST手写数字进阶算法(卷积神经网络CNN) 之 卷积tf.nn.conv2d

在这个文章里,将通过数据的变化,来演示卷积神经网络中卷积(Convolution),
卷积(Convolution)是卷积神经网络的第一步,而本文的目的仅仅只是为了说明strides与padding参数

TensorFlow实例(5.1)--MNIST手写数字进阶算法(卷积神经网络CNN) 文章中,

第一层经网络用到下列句子

tf.nn.conv2d(p1 ,w2,strides=[1,1,1,1],padding="SAME"

关于strides步长建议参考
TensorFlow实例(5.3)--MNIST手写数字进阶算法(卷积神经网络CNN) 之 最大池化tf.nn.max_pool

在那个文章里,对strides有更详细的说明,这篇章主要是演算卷积过程中的数据变化


# -*- coding: utf-8 -*-
import numpy as np
import tensorflow as tf

def createData(height,width):
    ''' 辅助函数一
    为了能更清晰的演示,建立这个函数,目的创建数据,即第一个参数x
    因为多张图片的传入量不好表示,batch值就固定为1
    本文是为了演示卷积,所以初始通道 channels也固定为1
    返回值类型为numpy.array  
    '''
    size = height * width
    tmp = np.arange(size) + 1
    tmp = np.array([tmp]).reshape(-1,height,width,1)
    return tmp

def printData(npArr,message=""):
    '''
    打印出图片数据
    多通道图片都是模排显示,如果宽度及通道数太大,
    会每行宽度的原因自动换行,
    '''
    npArr = npArr[0]
    print("-" * 40 + " 开始:" + message)
    print("图像信息:高:%d; 宽:%d; 通道:%d。以下为图像数据" % (len(npArr),len(npArr[0]),len(npArr[0][0])))
    print("")
    for i in npArr:
        tmp = i.T
        strtmp = ''
        for j in tmp:
            strItem = ''.join([x.rjust(4) for x in j.astype(np.str).tolist()])
            strtmp = strtmp + ("" if strtmp == '' else " |") + strItem
        print(strtmp)
    print("-" * 40 + " 结束:" + message)
    print("")


data = createData(7,7).astype(np.float32) #卷积参数的设置使用np.float32
print(data.shape)#(1, 7, 7, 1) 四维数组,分别表示(图片数batch,图片高height,图片宽width,通道数channel)

printData(data.astype(np.int))
weight = np.ones([5,5,1,3])
printData(weight)
'''
关于weight
因为卷积层的构建要 data * w,为了保证卷积后数值不变化,我将weight全设为1,
四维数组,分别表示
1、切割图片高height    
2、切割图片宽width,
3、输入通道数Input_channel  这里应该与Data的最后一个参数相同
4、输出的通道数             在mnist中第一层的卷积为32层,为了后面显示方便,我只设了3
'''
#卷积
con = tf.nn.conv2d(data,weight,strides=[1,1,1,1],padding="SAME")
result = tf.Session().run(con)

#对卷积后的数据做做些微调
print(result.shape)#(1, 7, 7, 4)
printData(result,"一开始生成的数据有点精度问题")
result = result.astype(np.int) #计算后有些精度的问题,我们取整就好了
printData(result,"取整后的数据,发现三个通道的数据完全一样,")

'''
卷积后的数据的说明
千万!千万!千万! 不要被通道完全一样误导,在Mnist的例子中weight初始是一个正态分布的集合,我这里全是1
我使用1是为了说明weight=np.ones([5,5,1,3]) 中的高宽(5,5),及strides=[1,1,1,1],padding="SAME"
高宽(5,5)的意思就是某个点为中间,切割出来的5*5的小图片所有值的和
如 第三行第三列为,在DATA中是17  ,在卷积后的是425

   1   2   3   4   5   
   8   9  10  11  12  
  15  16  17  18  19     这些数加起来就是 425
  22  23  24  25  26  
  29  30  31  32  33 

第一行第一列为,在DATA中是1  因为上面和左边没数字,所以在卷积后的是 

  1  2  3
  8  9 10   这些数加起来就是 81
 15 16 17
 '''

#strides的设置变化
con = tf.nn.conv2d(data,weight,strides=[1,2,2,1],padding="SAME")
result = tf.Session().run(con)
result = result.astype(np.int) #计算后有些精度的问题,我们取整就好了
printData(result,"strides步度设置数据")
#步长就是每隔几位取一个数值,strides=[1,2,2,1],就是是取1,3,5,7行,与1,3,5,7列

#padding设置
con = tf.nn.conv2d(data,weight,strides=[1,1,1,1],padding="VALID")
result = tf.Session().run(con)
result = result.astype(np.int) #计算后有些精度的问题,我们取整就好了
printData(result,"padding步度设置数据")
#padding只能取SAME 或VALID
#VALID表示,取的数字,为中心,无法切割出5*5则不计算,如本例1,2,6,7行与列的值都无法取到5*5的图片,被舍弃
#如果还是不太清楚,可以看我另一个文章


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值