手写数字识别

手写数字识别

1.建立卷积神经网络层并进行训练模型

  • 导入MNIST数据集,定义变量x和y,并进行设置形状,控制图片大小为28*28
mnist = input_data.read_data_sets('./MNIST_data/', one_hot=True)  
 
sess = tf.InteractiveSession()  
 
#训练数据  
x = tf.placeholder("float", shape=[None, 784])  
#训练标签数据  
y_ = tf.placeholder("float", shape=[None, 10])  
#把x更改为4维张量,第1维代表样本数量,第2维和第3维代表图像长宽, 第4维代表图像通道数, 1表示黑白  
x_image = tf.reshape(x, [-1,28,28,1])  
  • 第一层:开始建立卷积层,定义Weights和Biases,建立过滤器大小为5*5,当前深度为1,过滤器深度为32,并建立卷积函数,再通过relu进行一次激活函数,其作用是去线性化
    在这里插入图片描述
#第一层:卷积层  
conv1_weights = tf.get_variable("conv1_weights", [5, 5, 1, 32], initializer=tf.truncated_normal_initializer(stddev=0.1)) #过滤器大小为5*5, 当前层深度为1, 过滤器的深度为32  
conv1_biases = tf.get_variable("conv1_biases", [32], initializer=tf.constant_initializer(0.0))  
conv1 = tf.nn.conv2d(x_image, conv1_weights, strides=[1, 1, 1, 1], padding='SAME') #移动步长为1, 使用全0填充  
relu1 = tf.nn.relu( tf.nn.bias_add(conv1, conv1_biases) ) #激励函数Relu去线性化  

提取特征值

  • 第二层:建立最大池化层
#第二层:最大池化层  
#池化层过滤器的大小为2*2, 移动步长为2,使用全0填充  
pool1 = tf.nn.max_pool(relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')  

在这里插入图片描述

max_pool的作用:

  1. invariance(不变性),这种不变性包括translation(平移),rotation(旋转),scale(尺度)
  2. 保留主要的特征同时减少参数(降维,效果类似PCA)和计算量,防止过拟合,提高模型泛化能力
  • 第三层;再一次建立卷积层进行收集数据集
#第三层:卷积层  
conv2_weights = tf.get_variable("conv2_weights", [5, 5, 32, 64], initializer=tf.truncated_normal_initializer(stddev=0.1)) #过滤器大小为5*5, 当前层深度为32, 过滤器的深度为64  
conv2_biases = tf.get_variable("conv2_biases", [64], initializer=tf.constant_initializer(0.0))  
conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME') #移动步长为1, 使用全0填充  
relu2 = tf.nn.relu( tf.nn.bias_add(conv2, conv2_biases) )  
  • 第四层:再次建立最大池化层
#第四层:最大池化层  
#池化层过滤器的大小为2*2, 移动步长为2,使用全0填充  
pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')  
  • Dropout层处理
#为了减少过拟合,加入Dropout层  
keep_prob = tf.placeholder(tf.float32)  
fc1_dropout = tf.nn.dropout(fc1, keep_prob)  
  • 第五层:建立全连接层,把前一层的输出变成特征向量
#第五层:全连接层  
fc1_weights = tf.get_variable("fc1_weights", [7 * 7 * 64, 1024], initializer=tf.truncated_normal_initializer(stddev=0.1)) #7*7*64=3136把前一层的输出变成特征向量  
fc1_baises = tf.get_variable("fc1_baises", [1024], initializer=tf.constant_initializer(0.1))  
pool2_vector = tf.reshape(pool2, [-1, 7 * 7 * 64])  
fc1 = tf.nn.relu(tf.matmul(pool2_vector, fc1_weights) + fc1_baises) 
  • 第六层:搭建全连接层
#第六层:全连接层  
fc2_weights = tf.get_variable("fc2_weights", [1024, 10], initializer=tf.truncated_normal_initializer(stddev=0.1)) #神经元节点数1024, 分类节点10  
fc2_biases = tf.get_variable("fc2_biases", [10], initializer=tf.constant_initializer(0.1))  
fc2 = tf.matmul(fc1_dropout, fc2_weights) + fc2_biases  
  • 第七层:输出层,对网络最后一层的输出做一个softmax,这一步通常是求取输出属于某一类的概率,reduce_mean函数用来降低损失值
#第七层:输出层  
# softmax  
y_conv = tf.nn.softmax(fc2)  
 
#定义交叉熵损失函数  
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices=[1])) 
  • 再使用选择优化器进行梯度计算并进行训练
#选择优化器,并让优化器最小化损失函数/收敛, 反向传播  
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)  
 
# tf.argmax()返回的是某一维度上其数据最大所在的索引值,在这里即代表预测值和真实值  
# 判断预测值y和真实值y_中最大数的索引是否一致,y的值为1-10概率  
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))  
 
# 用平均值来统计测试准确率  
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 
  • 将训练好的数据集存储在文件中
saver_path = saver.save(sess, "/home/cris/AI/MNIST/save/model.ckpt")  # 将模型保存到save/model.ckpt文件
print("Model saved in file:", saver_path)

2.安装opencv第三方库,进行剪裁图片,在建立神经网络模型的时候我们已控制图片的大小为28*28,通过opencv的剪裁功能进行控制图片的大小,再将图片进行二值化,并进行保存

    img = cv2.imread('/home/cris/AI/MNIST/image/hei9.png')  # 手写数字图像所在位置
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换图像为单通道(灰度图)
    cv2.namedWindow('image')
    cv2.setMouseCallback('image', on_mouse) # 调用回调函数
    cv2.imshow('image', img)
    cv2.waitKey(0)
min_x = min(point1[0], point2[0])     
        min_y = min(point1[1], point2[1])
        width = abs(point1[0] - point2[0])
        height = abs(point1[1] -point2[1])
        cut_img = img[min_y:min_y+height, min_x:min_x+width]
        resize_img = cv2.resize(cut_img, (28,28)) # 调整图像尺寸为28*28
        ret, thresh_img = cv2.threshold(resize_img,127,255,cv2.THRESH_BINARY) # 二值化
        cv2.imshow('result', thresh_img)
        cv2.imwrite('/home/cris/AI/MNIST/image/text.png', thresh_img)  # 预处理后图像保存位置

3.调用第一步训练好的模型,再通过Image库打开剪裁后的图片,并建立卷积神经网络层,进行手写数字识别功能

file_name='/home/cris/AI/MNIST/image/hei8.png'#导入自己的图片地址
    #进行灰度处理
    im = Image.open(file_name).convert('L')
    #将图片进行剪裁成28*28像素大小
    img = im.resize((28, 28), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
#导入训练好的模型
sess = tf.InteractiveSession()
saver = tf.train.Saver()
tf.global_variables_initializer().run()
saver.restore(sess, "/home/cris/AI/MNIST/save/model.ckpt")

最终进行识别数据,将结果打印出来,最终纯白底黑字的图片识别率较高,图片较模糊底色偏暗的图片情况识别率较低

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值