数字识别

简介: 【7月更文挑战第25天】数字识别

在TensorFlow目录下新建文件,命名为LeNet-5.py,利用TensorFlow解决类似于LeNet-5在MNIST数据集上进行数字识别的问题,在PyCharm中编写以下代码。

-×- coding: utf-8 -×-

载入MINIST数据需要的库

from tensorflow.examples.tutorials.mnist import input_data

保存模型需要的库

from tensorflow.python.framework.graph_util import convert_variables_to_constants
from tensorflow.python.framework import graph_util

导入其他库

import tensorflow as tf
import time
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

获取MINIST数据

mnist = input_data.read_data_sets("./MNIST_data", one_hot=True)

占位符

x是特征值,也就是像素

使用一个28×28=784列的数据来表示一个图像的构成

每一个点都是这个图像的一个特征

因为每一个点都会对图像的外观和表达的含义有影响,只是影响的大小不同而已

x = tf.placeholder("float", shape=[None, 784], name="Mul") # 输入28×28=784

y_是真实数据[0,0,0,0,1,0,0,0,0],为4

y = tf.placeholder("float", shape=[None, 10], name="y") # 输出

变量 784×10的矩阵

W表示每一个特征值(像素点)影响结果的权重

这个值很重要,因为深度学习的过程就是发现特征

经过一系列训练,得出每一个特征值对结果影响的权重

训练就是为了得到这个最佳权重值

W = tf.Variable(tf.zeros([784, 10]), name='x')
b = tf.Variable(tf.zeros([10]), 'y_')

权重

def weight_variable(shape):

  # 生成的值服从具有指定平均值和标准偏差的正态分布
  # 如果生成的值大于平均值的两个标准偏差的值,则丢弃重新选择
  initial = tf.truncated_normal(shape, stddev=0.1)  # 标准差为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):

  # 参数x指需要做卷积的输入图像,要求它是一个Tensor
  # 具有[batch, in_height, in_width, in_channels]这样的shape
  # 具体含义是[训练时一个batch的图像数量, 图像高度, 图像宽度, 图像通道数] 
  # 注意这是一个4维的Tensor,batch和in_channels在卷积层中通常设为1
  # 参数W相当于CNN中的卷积核,要求它是一个Tensor
  # 具有[filter_height, filter_width, in_channels, out_channels]这样的shape
  # 具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数]
  # 注意,第三维in_channels就是参数x的第四维
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='VALID')
  # 参数strides:卷积时在图像每一维的步长,这是一个一维的向量,长度为4
  # 参数padding:string类型的量,只能是“VALID”,不补零

最大池化

def max_pool_2x2(x):

  # x:input
  # ksize:filter,滤波器大小为2×2
  # strides:步长,2×2,表示filter窗口每次水平移动两格,每次垂直移动两格
  # padding:填充方式,补零
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                                  strides=[1, 2, 2, 1], padding='SAME')

第一层卷积

权重+偏置+激活+池化

patch为5×5;in_size为1,即图像的厚度,如果是彩色的,则为3;32个卷积核(滤波器)

W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])

对数据进行重新排列,形成图像

x_image = tf.reshape(x, [-1, 28, 28, 1])

print("x",x)

print("x_image",x_image)

ReLU操作,输出大小为28×28×32

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

Pooling操作,输出大小为14×14×32

h_pool1 = max_pool_2x2(h_conv1)

第二层卷积

权重+偏置+激活+池化

patch为5×5;in_size为32,即图像的厚度;out_size是64,即输出的大小

W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])

ReLU操作,输出大小为14×14×64

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)

Pooling操作,输出大小为7×7×64

h_pool2 = max_pool_2x2(h_conv2)

全连接一

W_fc1 = weight_variable([7 × 7 × 64, 1024])
b_fc1 = bias_variable([1024])

全连接二

W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])

输入数据变换

变换为m×n,列n为7×7×64

h_pool2_flat = tf.reshape(h_pool2, [-1, 7 × 7 × 64])

进行全连接操作

tf.nn.relu()函数可将大于0的数保持不变,将小于0的数置为0

h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

Dropout可防止过拟合,它一般用在全连接层,训练用,测试不用

Dropout就是在不同的训练过程中随机扔掉一部分神经元

Dropout可以让某个神经元的激活值以一定的概率p停止工作

参数keep_prob:设置神经元被选中的概率,在初始化时keep_prob是一个占位符

TensorFlow在运行时设置keep_prob具体的值,如keep_prob: 0.5

keep_prob = tf.placeholder("float", name='rob')
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

用于训练的softmax()函数将所有数据归一化到0~1之间,大的数据特征更明显

y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2, name='res')

训练完成后,进行测试用的softmax()函数

y_conv2 = tf.nn.softmax(tf.matmul(h_fc1, W_fc2) + b_fc2, name="final_result")

交叉熵的计算,返回包含了损失值/误差的Tensor

熵是衡量事物混乱程度的一个值

cross_entropy = -tf.reducesum(y × tf.log(y_conv))

优化器,负责最小化交叉熵

train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

tf.argmax():取出该数组最大值的下角标

correct_prediction = tf.equal(tf.argmax(yconv, 1), tf.argmax(y, 1))

计算准确率

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

创建会话

with tf.Session() as sess:
time_begin = time.time()

  # 初始化所有变量
  sess.run(tf.global_variables_initializer())
  # print(sess.run(W_conv1))
  # 保存输入/输出,可以在之后用
  tf.add_to_collection('res', y_conv)
  tf.add_to_collection('output', y_conv2)
  tf.add_to_collection('x', x)
  # 训练开始
  for i in range(10000):
         # 取出MNIST数据集中的50个数据
         batch = mnist.train.next_batch(50)
         # run()可以看作输入相关值到函数中的占位符,然后计算出结果
         # 这里将batch[0]给x,将batch[1]给y_
         # 执行训练过程并传入真实数据
         train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
         if i % 100 == 0:
               train_accuracy = accuracy.eval(feed_dict={x: batch[0],\
                                                                            y_: batch[1], 

keep_prob: 1.0})
print("step %d, training accuracy %g" % (i, train_accuracy))
time_elapsed = time.time() - time_begin
print("训练所用时间:%d秒" % time_elapsed)

  # 用saver 保存模型
  saver = tf.train.Saver()
  saver.save(sess, "model_data/model")
目录
相关文章
|
3月前
|
机器学习/深度学习 文字识别 TensorFlow
手写数字识别
【8月更文挑战第8天】手写数字识别。
49 1
|
4月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
数字识别
【7月更文挑战第26天】数字识别。
31 2
|
5月前
|
机器学习/深度学习 存储 算法
使用支持向量机算法解决手写体识别问题
使用支持向量机算法解决手写体识别问题
32 2
|
5月前
|
机器学习/深度学习 算法 PyTorch
【从零开始学习深度学习】44. 图像增广的几种常用方式并使用图像增广训练模型【Pytorch】
【从零开始学习深度学习】44. 图像增广的几种常用方式并使用图像增广训练模型【Pytorch】
|
6月前
|
机器学习/深度学习 PyTorch 算法框架/工具
Python用GAN生成对抗性神经网络判别模型拟合多维数组、分类识别手写数字图像可视化
Python用GAN生成对抗性神经网络判别模型拟合多维数组、分类识别手写数字图像可视化
|
6月前
|
机器学习/深度学习 数据采集 PyTorch
PyTorch使用神经网络进行手写数字识别实战(附源码,包括损失图像和准确率图像)
PyTorch使用神经网络进行手写数字识别实战(附源码,包括损失图像和准确率图像)
137 0
|
机器学习/深度学习 算法 BI
【深度学习】基于知识库的手写体数字识别(Matlab代码实现)
【深度学习】基于知识库的手写体数字识别(Matlab代码实现)
163 0
|
TensorFlow 算法框架/工具 Python
【学习】手写数字生成
【学习】手写数字生成
273 0
|
机器学习/深度学习 传感器 算法
【图像分类】基于卷积神经网络实现花朵图像分类附matlab代码
【图像分类】基于卷积神经网络实现花朵图像分类附matlab代码
|
机器学习/深度学习 算法
阿旭机器学习实战【5】KNN算法实战练习2:利用KNN模型进行手写体数字识别
阿旭机器学习实战【5】KNN算法实战练习2:利用KNN模型进行手写体数字识别
阿旭机器学习实战【5】KNN算法实战练习2:利用KNN模型进行手写体数字识别