卷积神经网络(CNN)mnist手写字python源代码详解

更新时间:2023-12-11 19:01:50 阅读: 评论:0

2023年12月11日发(作者:粗线条)

-

卷积神经网络(CNN)mnist手写字python源代码详解

卷积神经网络(CNN)mnist手写字python源代码详解

首先介绍下卷积神经网络

输入层我就不讲了,我主要根据代码讲下卷积层,池化层,全连接层。

(一)

卷积层

'''

-1代表着矩阵行不确定我这里用n表示,[-1,28,28,1]的意思是n行28列,

它的子元素是一个28行1列的矩阵,例如

[[[[1]], [[1]], [[1]], [[1]]],

[[[1]], [[1]], [[1]], [[1]]]]

可以表示为【2,4,1,1】它的子元素[[1]]为1行1列。在这里这个1也可以理解为通道数为1

'''

x_image = e(x, [-1, 28, 28, 1])

'''

w_conv1代表着filter【5,5】为卷积核大小,1为通道数,32为卷积核的个数,卷积核个

数的选取需要凭经验,也许有大神知道一定的规律,这里我讲一下卷积核的通道数为什么需

要和输入的通道数一样,其实原理很简单,我们需要x_image和w_conv1相乘,也就需要它们两

个的子元素相乘,上边已经说过x_image的子元素为【28,1】,要想两者相乘,则w_conv1

子元素必须为【1,n]

'''

w_conv1 = weight_variable([5, 5, 1, 32])

卷积的计算包括两部分,输入和filter

卷积的计算(注意,下面蓝色矩阵周围有一圈灰色的框,那些就是上面所说到的填充值)

蓝色的矩阵(输入图像)对粉色的矩阵(filter)进行矩阵内积计算并将三个内积运算的结果与偏置值b相加(比如上面图的计算:2+(-2+1-

2)+(1-2-2) + 1= 2 - 3 - 3 + 1 = -3),计算后的值就是绿框矩阵的一个元素。下面的动态图形象地展示了卷积层的计算过程:

代码中我们需要定义一个方法,来实现卷积

def conv2d(x, w):

b = 2d(x, w, strides=[1, 1, 1, 1], padding='SAME')

return b

卷积运算后,输出图片尺寸缩小;

越是边缘的像素点,对于输出的影响越小,因为卷积运算在移动的时候到边缘就结束了。中间的像素点有可能会参与多次计算,但是边缘像

素点可能只参与一次。所以我们的结果可能会丢失边缘信息。

  那么为了解决这个问题,我们引入padding, 什么是padding呢,就是我们认为的扩充图片, 在图片外围补充一些像素点,把这些像

素点初始化为0.

① SAME

输出大小等于输入大小除以步长向上取整,s是步长大小;

我们这里的输入大小为28

28的图像,filter 大小为5

5, 步长strides 为1所以输出大小也为28

28,下面给出图解

假设我们输入矩阵为

我们先把矩阵扩充为

然后再与filter进行卷积运算,这样做是为了保留边界信息,否则的话我们的边界只进行了一次运算,而内部进行了多次

② VALUE

输出大小等于输入大小减去滤波器大小加上1,最后再除以步长(f为滤波器的大小,s是步长大小)。假设我们输入大小为28

28,步长为

1,filter为5

5,那么输出大小为24

24,图片有所缩小。

**(二)**激励层

把卷积层输出结果做非线性映射。

主要是增强输入输出之间的拟合性,

CNN采用的激励函数一般为ReLU(The Rectified Linear Unit/修正线性单元),它的特点是收敛快,求梯度简单,但较脆弱。代码如下

h_conv1 = (conv2d(x_image, W_conv1) + b_conv1)

**(三)**池化层

池化层夹在连续的卷积层中间, 用于压缩数据和参数的量,减小过拟合。

简而言之,如果输入是图像的话,那么池化层的最主要作用就是压缩图像。

这里再展开叙述池化层的具体作用。

1. 特征不变性,也就是我们在图像处理中经常提到的特征的尺度不变性,池化操作就是图像的resize,平时一张狗的图像被缩小了一倍

我们还能认出这是一张狗的照片,这说明这张图像中仍保留着狗最重要的特征,我们一看就能判断图像中画的是一只狗,图像压缩时

去掉的信息只是一些无关紧要的信息,而留下的信息则是具有尺度不变性的特征,是最能表达图像的特征。

2. 特征降维,我们知道一幅图像含有的信息是很大的,特征也很多,但是有些信息对于我们做图像任务时没有太多用途或者有重复,我

们可以把这类冗余信息去除,把最重要的特征抽取出来,这也是池化操作的一大作用。

3. 在一定程度上防止过拟合,更方便优化。

池化层用的方法有Max pooling 和 average pooling,而实际用的较多的是Max pooling。

这里就说一下Max pooling,其实思想非常简单。

对于每个2

2的窗口选出最大的数作为输出矩阵的相应元素的值,比如输入矩阵第一个2

2窗口中最大的数是6,那么输出矩阵的第一个元素

就是6,如此类推。

(四)全连接层

全连接层在我看来不大好理解,下面给出我自己的理解,全连接层的目的是将网络学习到的特征映射到样本的标记空间中。全连接层会把卷

积输出的二维特征图(featureMap)转化成一个一维的向量。本案例中我们进行了2次卷积,最后得到了64个7

7的二维特征图

(featureMap),我们需要把它转化为一维的,即7

7*64,代码如下

h_pool2_flat = e(h_pool2, [-1, 7*7*64]) #reshape成向量

W_fc1 = weight_variable([7 * 7 * 64, 1024]) #1024代表卷积个数,我们可以任意取

b_fc1 = bias_variable([1024])

h_fc1 = ((h_pool2_flat, W_fc1) + b_fc1)

这里我给个例子帮助你们理解e(),请看代码

import numpy as np

import tensorflow as tf

input = le([[[[1]], [[1]], [[1]], [[1]]],

[[[1]], [[1]], [[1]], [[1]]]], dtype=float)

b = e(input, [1, 8])

print((input))

print((b))

运行结果为, 从结果中我们可以看出,转换规则为,2

4

1

1=1

8

同理,因为我们全连接层的输入,就是卷积层的输出,我们经过两次卷积后的输出为h_pool2= [-1, 7, 7, 64],为什么是-1,是因为我们最

初的输入x_image = [-1, 28, 28, 1] , -1 代表着行数不确定。

h_pool2_flat = e(h_pool2, [-1, 7*7*64]) #reshape成向量

我们就把 [-1, 7, 7, 64]转换为 [-1, 7

7

64]。

谨记,全连接层不是卷积层,所以这里是

h_fc1 = ((h_pool2_flat, W_fc1) + b_fc1)

我们用()只是把得到的特征值与权重w相乘再加上偏执b。

最后我们需要加上,

keep_prob = older("float")

h_fc1_drop = t(h_fc1, keep_prob)

t()是tensorflow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层

最后给出我们整个运算过程并附上代码。

代码

import tensorflow as tf

import tensorflow as tf

import _data as input_data

mnist = input__data_ts("MNIST_data/", one_hot=True)

x = older(32, [None, 784]) # 占位用,因为图片大小为28*28,所以为784,

# 但是我们并不清楚有多少副,所以设为None,后续来添加

y_actual = older(32, shape=[None, 10]) # 同理占位用,因为我们要测的是0-9一共10个数,即一共10个类别

'''

ted_normal(shape, mean, stddev) :shape表示生成张量的维度,mean是均值,stddev是标准差。

这个函数产生正太分布,均值和标准差自己设定。就是说产生正太分布的值如果与均值的差值大于两倍的标准差,那就重新生成。

和一般的正太分布的产生随机数据比起来,这个函数产生的随机数与均值的差距不会超过两倍的标准差,但是一般的别的函数是可能的。

谨记 filter中的值是经过训练后确定的(代表着权重w)

'''

def weight_variable(shape):

initial = ted_normal(shape, stddev=0.1)

return le(initial)

# 偏置b

def bias_variable(shape):

initial = nt(0.1, shape=shape)

return le(initial)

# 卷积

def conv2d(x, w):

return 2d(x, w, strides=[1, 1, 1, 1], padding='SAME')

# 池化层

def max_pool(x):

return _pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

x_image = e(x, [-1, 28, 28, 1])

'''

w_conv1代表着filter【5,5】为卷积核大小,1为通道数,32为卷积核的个数,卷积核个

数的选取需要凭经验,也许有大神知道一定的规律,这里我讲一下卷积核的通道数为什么需

要和输入的通道数一样,其实原理很简单,我们需要x_image和w_conv1,也就表示它们两

个的子元素相乘,上边已经说过x_image的子元素为【28,1】,要想两者相乘,则w_conv1

子元素必须为【1,n]

'''

w_conv1 = weight_variable([5, 5, 1, 32])

b_conv1 = bias_variable([32])

h_conv1 = (conv2d(x_image, w_conv1) + b_conv1)

h_pool1 = max_pool(h_conv1)

w_conv2 = weight_variable([5, 5, 32, 64])

b_conv2 = bias_variable([64])

h_conv2 = (conv2d(h_pool1, w_conv2) + b_conv2)

h_pool2 = max_pool(h_conv2)

'''

7*7*64表示7*7的图片64个,也就表示一共有7*7*64个特征值(包含0),1024是实际上的特征值,使我们需要保留的

'''

w_fc1 = weight_variable([7*7*64, 1024])

w_fc1 = weight_variable([7*7*64, 1024])

b_fc1 = bias_variable([1024])

h_pool2_flat = e(h_pool2, [-1, 7*7*64])

h_fc1 = ((h_pool2_flat, w_fc1) + b_fc1)

'''

Dropout就是在不同的训练过程中随机扔掉一部分神经元。也就是让某个神经元的激活值以一定的概率p,

让其停止工作,这次训练过程中不更新权值,也不参加神经网络的计算。但是它的权重得保留下来(只是暂时不更新而已),

因为下次样本输入时它可能又得工作了,keep_prob表示丢弃的概率

'''

keep_prob = older("float")

h_fc1_drop = t(h_fc1, keep_prob)

w_fc2 = weight_variable([1024, 10])

b_fc2 = bias_variable([10])

y_predict = x((h_fc1_drop, w_fc2) + b_fc2)

cross_entropy = -_sum(y_actual * (y_predict)) # 根据公式求和

train_step = ntDescentOptimizer(1e-3).minimize(cross_entropy) # 梯度下降法寻找最优解,训练时,不断的调整权重w

correct_prediction = ((y_predict, 1),

(y_actual, 1)) # 返回的true或fal,返回的是最大值的下标,

# 0表示按列来,1表示按行来

accuracy = _mean(

(correct_prediction, "float")) # dtype = float可以把bool(True or Fal)类型转化为float类型(数据),

# _mean()求平均值,同样,0表示对列求平均,1表示对行求平均,既没有0也没有1的话对整个矩阵求平均

ss = ctiveSession()

(_variables_initializer())

for i in range(20000):

batch = _batch(50)

if i % 100 == 0: # 训练100次,验证一次

train_(feed_dict={x: batch[0], y_actual: batch[1], keep_prob: 0.5})

test_acc = (feed_dict={x: , y_actual: , keep_prob: 1.0})

print("test accuracy %g" % test_acc)

-

卷积神经网络(CNN)mnist手写字python源代码详解

本文发布于:2023-12-11 19:01:50,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/zhishi/a/1702292510118512.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:卷积神经网络(CNN)mnist手写字python源代码详解.doc

本文 PDF 下载地址:卷积神经网络(CNN)mnist手写字python源代码详解.pdf

标签:卷积   矩阵   图像   输入   输出   表示   特征   信息
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 实用文体写作网旗下知识大全大全栏目是一个全百科类宝库! 优秀范文|法律文书|专利查询|