tensorflow1.14 cnn 手写数字识别笔记

 实验内容:

1. 编写TensorFlow框架的CNN网络,利用数据流编程的方法编写2层卷积网络和全连接层等。对MNIST手写数字数据集读取和划分为测试集和训练集,定义网络的输入和输出参数的类型大小,定义损失函数、优化器最小化损失函数、正确率。最后输出模型在测试集上的正确率。

(1)参考人工智能教学实训系统,理解原理。

(2)在(1)的基础上,要求,将填充padding设置为1,步长strids设置为2,卷积核大小为3*3,然后训练网络,最终输出模型再测试集上的准确率。

实验报告要求:

实验代码:

(完整代码,适当注释)伪代码

线性回归伪代码如下:

输入:数据集D,交叉验证参数k

输出结果:参数w

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import time

mnist = input_data.read_data_sets(
'MNIST_data', one_hot=True)
learning_rate =
1e-4

keep_prob_rate = 0.9

max_epoch = 2000

def weight_variable(shape):
    initial = tf.truncated_normal(shape,
stddev=0.1)
   
return tf.Variable(initial)


def bias_variable(shape):
    initial = tf.constant(
0.1, shape=shape)
   
return tf.Variable(initial)


def conv2d(x, W):
   
return tf.nn.conv2d(x, W, strides=[1, 2,2, 1], padding='SAME')


def max_pool_2x2(x):
   
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


def compute_accuracy(v_xs, v_ys):
   
global prediction
    y_pre = sess.run(prediction,
feed_dict={xs: v_xs, keep_prob: 1})
    correct_prediction = tf.equal(tf.argmax(y_pre,
1), tf.argmax(v_ys, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    result = sess.run(accuracy,
feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
   
return result


xs = tf.placeholder(tf.float32, [
None, 784], name='x_input')
ys = tf.placeholder(tf.float32, [
None, 10], name='y_input')
keep_prob = tf.placeholder(tf.float32)
x_image = tf.reshape(xs, [-
1, 28, 28, 1])



卷积层 1
W_conv1 = weight_variable([3, 3, 1, 32])
b_conv1 = bias_variable([
32])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)


卷积层 2
W_conv2 = weight_variable([3, 3, 32, 64])  # patch 5x5, in size 32, out size 64
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

全连接层 1
W_fc1 = weight_variable([2*2 * 64, 1024])
b_fc1 = bias_variable([
1024])
h_pool2_flat = tf.reshape(h_pool2, [-
1, 2*2 * 64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)




W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([
10])
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)



cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),
                                              
reduction_indices=[1]))


train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)


with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)
   
print("step 0, test accuracy %g" %compute_accuracy(
        mnist.test.images, mnist.test.labels))
    start = time.time()
   
for i in range(max_epoch):
        batch_xs, batch_ys = mnist.train.next_batch(
100)
        sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: keep_prob_rate})
       
if (i+1) % 50 == 0:
           
print("步骤 %d, test 准确率 %g" % ((i+1), compute_accuracy(
                mnist.test.images, mnist.test.labels)))
    end = time.time()
   
print('******************************************************')
   
print("运行时间:%.2f" % (end - start))

  1. 首先加载数据

上面使用内置函数加载tensorflow的默认图片数据

里面包括60000张数据,即为60000*78428*28 图片的长和宽分别有28个像素)

其中训练集有55000 测试集有10000张,验证集有5000张。

其中的10表示0-9,因为数字有0-9,数组上面分别表示相应的概率。只要数字下标概率哪个比较大,就表示当前的图片是数字几。

这里定义了初始权重,采用的是普通正态分布,

tf.truncated_normal(shape, mean, stddev)

截断的产生正态分布的随机数,即随机数与均值的差值若大于两倍的标准差,则重新生成。

shape,生成张量的维度

mean,均值

stddev,标准差

这里维度则由传入的参数决定,stddev=0.1则表示标准差为0.1

这里则表示 维度为shape,默认填充用0.1填充,这里定义的偏置函数,所以默认偏置设置为0.1

这里定义了卷积的函数,x表示因变量。W表示函数的参数。strides=[1, 2,2, 1]则表示步长为上下步长2的卷积,后面padding=”SAME”则表示使用零填充,目的是防止某些数据读取不到,因为可能会发生数组越界,我们用0填充的话,不影响原来的数据,也保证的数据的公平。即都可以学习到。

这里定义了池化的的函数。其中的参数 ksize 表示滑动窗口为2*2的。因为不在batchchannels上做池化,所以这两个维度设为了1。同理strides=[1, 2, 2, 1],则表示步长为2*2并且不在batchchannels做池化。padding 填充的方法,SAMEVALIDSAME表示添加全0填充,VALID表示不添加。这里则表示填充0

函数传入的是v_xs, v_ys

V_xs为测试的图片x

v_ys则为测试的图片的y值,即为真实值

这里定义了计算预测率的函数。首先global prediction 声明全局变量。Prediction是我们通过cnn学习出来的参数值,将x输入进去然后得出预测值correct_prediction,然后再通过tf.reduce_mean降维度得到平均值,最终返回result拿到准确率。

Xs表示加载因变量x 55000*784

Ys表示加载真实值y555000*10

keep_prob 我的理解是这里生成一个变量然后后面的有进行用到

x_image:则表示转换成图片的维度,前面-1表示任意多张图片。然后图片维度是28*28的。后面的1表示单通道。因为是黑白图片,后面可以直接用plt进行画图直接将图片画出来。

好下面进行卷积层1

首先生成一个W_conv1= weight_variable([3, 3, 1, 32]) 这里呢我们就是想一张图片卷积32次,然后的卷积核的大小为3*3,图片为单通道1.所以即为33,1,32

然后生成偏置变量b_conv1。因为卷积个数为32次,所以这里的维度应该为32

h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)

这里我们用relu的激活函数,然后进行计算卷积核大小。

h_pool1 = max_pool_2x2(h_conv1)下面调用函数进行池化。

下面是卷积层1的维度分析:

1.首先一张图片的维度为28*28,然后想卷积32次,假设一张图片,那么卷积后的维度则应该为

28+2-3/2+1 取整得到14所以此时一张图片的维度为14*14*32

2.下面进行池化,由于我们进行的是最大池化,并且窗口大小为2*2,步长为2*2所以计算得到出维度应该降为原来的一半即一张图片的维度为 7*7*32

下面是卷积层2的维度分析:

1.首先通过卷积层一后一张图片的维度为7*7*32,那么卷积后的维度则应该为

7+2-3/2+1 取整得到3所以此时一张图片的维度为3*3*32

2.下面进行池化,由于我们进行的是最大池化,并且窗口大小为2*2,步长为2*2所以计算得到出维度应该降为原来的一半即一张图片的维度为 2*2*32

下面是连接层1的维度分析:

1. h_pool2_flat = tf.reshape(h_pool2, [-1, 2*2 * 64])这里通过reshape函数将 卷积层2后的图片维度 转换成 **256的其中-1表示可以有多张图片。

然后再下面通过激活函数relu和交叉熵损失函数。维度为(**256

下面是连接层2的维度分析:

1.初始w 1024*10  因为连接层的维度为-1* 1024  那么矩阵相乘后得到的则为-1*10其中-1表示多张图片,10表示数字0-9,从而将多维的展开成一维的。

2.其中softmax即为做归一化处理,即将数据转化成(01)的数值,这样可以加快计算,也有利于数据的处理。

下面则是定义交叉熵损失函数,以及用adam优化器进行梯度下降。这里计算得到了交叉熵函数,我们最终使用梯度下降的方法来求解交叉熵函数的最小值,不断迭代更新w从而得到最佳的权重w

这里则是通过主函数进行计算预测的准确率。有了解到tensorflow是通过图来进行计算的,

with tf.Session() as sess:

加载自变量x数据

以及加载因变量y的真实值

其中keep_prob_rate这里则为防止过拟合的意思。这里我设置成0.9

通过查官网上了解到的解释是:

意思是每个元素被保留的概率,那么 keep_prob:1就是所有元素全部保留的意思。

一般在大量数据训练时,为了防止过拟合,添加Dropout层,设置一个0~1之间的小数。

其中max_epoch表示学习的次数。这里可以设置为3000次,即梯度下降迭代3000次。

实验结果:

实验反思或感想:本次实验设置两个卷积层和两个连接层,本实验的基本原理是将一张图片(28*28)首先卷积32次得到28*28*32,1次卷积后后14*14*32,2次卷积后为7*7*32,连接一次为-1*(256),连接两次后为-1*(10),其中的-1表示为多张图片。最终得到一个一维张量,然后再判断0-9哪个下表的数组的概率大,就可以判断出本张图片是数字几。

每一步骤都要加激活函数,relu,因为不加激活函数的话,我们永远进行的是线性操作,那么我觉得人工神经网络存在的意义就不是很大,即他就和线性回归基本一样了。正因为激活函数的存在,我们划分的分界线就可以是曲线了,从而更能体现人工神经网络的价值所在。

实际上则为 先将图片的局部特征提取出来,最终再拟合成一维张量。

然后呢,最终得到一个交叉熵的损失函数,其中的因变量是w,我们通过求解梯度下降的方法来求解交叉熵函数的最小值,不断迭代更新w,这样我们通过3000次的更新后就基本得到了比较的w的参数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值