第二节,TensorFlow 使用前馈神经网络实现手写数字识别
一 感知器
1.1 感知机介绍
感知器(Perceptron)是二分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别,取+1和-1。这种算法的局限性很大:
- 只能将数据分为 2 类;
- 数据必须是线性可分的;
虽然有这些局限,但是感知器是 ANN 和 SVM 的基础,理解了感知器的原理,对学习ANN 和 SVM 会有帮助,所以还是值得花些时间的。
感知器可以表示为$ f:R^n -> \{-1,+1\}$的映射函数,其中$f$的形式如下:
$$f(x) = sign(w \cdot x+b)$$
其中$w$,$b$都是$n$维列向量,$w$表示权重,$b$表示偏置,$w \cdot x$表示$w$和$x$的内积。感知器的训练过程其实就是求解$w$和$b$的过程,正确的$w$和$b$所构成的超平面$w \cdot x + b=0$恰好将两类数据点分割在这个平面的两侧。
二 神经网络
2.1 MINIST数据集下载
今天,使用的神经网络就是由一个个类似感知器的神经元模型叠加拼接成的。目前常用的神经元包括S型神经元,ReLU神经元,tanh神经元,Softmax神经元等等。
手写数字识别是目前在学习神经网络中普遍使用的案例。在这个案例中将的是简单的全连接网络实现手写数字识别,这个例子主要包括三个部分。
- .模型搭建;
- 确定目标函数,设置损失和梯度值;
- 选择算法,设置优化器选择合适的学习率更新权重和偏置;
MNIST数据集可以从这里下载:https://github.com/mnielsen/neural-networks-and-deep-learning,也可以使用TensorFlow提供的一个库,可以直接用来自动下载和安装MNIST:
from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('MNIST-data',one_hot=True)
运行上面代码,会自动下载数据集并将文件解压到当前代码所在统计目录下的MNIST_data文件夹下。其中one_hot = True,表示将样本转换为one_hot编码。也就是二值化。
2.2 数字识别代码
数字识别代码如下:
# -*- coding: utf-8 -*- """ Created on Sun Apr 1 19:16:15 2018 @author: Administrator """ ''' 使用TnsorFlow实现手写数字识别 ''' import numpy as np import matplotlib.pyplot as plt #绘制训练集准确率,以及测试集准确率曲线 def plot_overlay_accuracy(training_accuracy,test_accuaracy): ''' test_accuracy,training_accuracy:训练集测试集准确率 ''' #迭代次数 num_epochs = len(test_accuaracy) #获取一个figure实例 fig = plt.figure()
#使用面向对象的方式添加Axes实例,参数1:子图总行数 参数2:子图总列数 参数3:子图位置 ax = fig.add_subplot(111) ax.plot(np.arange(0, num_epochs), [accuracy*100.0 for accuracy in test_accuaracy], color='#2A6EA6', label="Accuracy on the test data") ax.plot(np.arange(0, num_epochs), [accuracy*100.0 for accuracy in training_accuracy], color='#FFA933', label="Accuracy on the training data") ax.grid(True) ax.set_xlim([0, num_epochs]) ax.set_xlabel('Epoch') ax.set_ylim([90, 100]) ax.legend(loc="lower right") #右小角 plt.show() #绘制训练集代价和测试集代价函数曲线 def plot_overlay_cost(training_cost,test_cost): ''' test,reaining:训练集测试集代价 list类型 ''' #迭代次数 num_epochs = len(test_cost) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(np.arange(0, num_epochs), [cost for cost in test_cost], color='#2A6EA6', label="Cost on the test data") ax.plot(np.arange(0, num_epochs), [cost for cost in training_cost], color='#FFA933', label="Cost on the training data") ax.grid(True) ax.set_xlim([0, num_epochs]) ax.set_xlabel('Epoch') #ax.set_ylim([0, 0.75]) ax.legend(loc="upper right") plt.show() from sklearn.metrics import classification_report from sklearn.metrics import confusion_matrix ''' 打印图片 images:list或者tuple,每一个元素对应一张图片 title:list或者tuple,每一个元素对应一张图片的标题 h:高度的像素数 w:宽度像素数 n_row:输出行数 n_col:输出列数 ''' def plot_gallery(images,title,h,w,n_row=3,n_col=4): #pyplt的方式绘图 指定整个绘图对象的宽度和高度 plt.figure(figsize=(1.8*n_col,2.4*n_row)) plt.subplots_adjust(bottom=0,left=.01,right=.99,top=.90,hspace=.35) #绘制每个子图 for i in range(n_row*n_col): #第i+1个子窗口 默认从1开始编号 plt.subplot(n_row,n_col,i+1) #显示图片 传入height*width矩阵 https://blog.csdn.net/Eastmount/article/details/73392106?locationNum=5&fps=1 plt.imshow(images[i].reshape((h,w)),cmap=plt.cm.gray) #cmap Colormap 灰度 #设置标题 plt.title(title[i],size=12) plt.xticks(()) plt.yticks(()) plt.show() ''' 打印第i个测试样本对应的标题 Y_pred:测试集预测结果集合 (分类标签集合) Y_test: 测试集真实结果集合 (分类标签集合) target_names:分类每个标签对应的名称 i:第i个样本 ''' def title(Y_pred,Y_test,target_names,i): pred_name = target_names[Y_pred[i]].rsplit(' ',1)[-1] true_name = target_names[Y_test[i]].rsplit(' ',1)[-1] return 'predicted:%s\ntrue: %s' %(pred_name,true_name) import tensorflow as tf #设置tensorflow对GPU使用按需分配 config = tf.ConfigProto() config.gpu_options.allow_growth = True sess = tf.InteractiveSession(config=config) ''' 一 导入数据 ''' from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('MNIST-data',one_hot=True) print(type(mnist)) #<class 'tensorflow.contrib.learn.python.learn.datasets.base.Datasets'> print('Training data shape:',mnist.train.images.shape) #Training data shape: (55000, 784) print('Test data shape:',mnist.test.images.shape) #Test data shape: (10000, 784) print('Validation data shape:',mnist.validation.images.shape) #Validation data shape: (5000, 784) print('Training label shape:',mnist.train.labels.shape) #Training label shape: (55000, 10) ''' 二 搭建前馈神经网络模型 搭建一个包含输入层分别为 784,1024,10个神经元的神经网络 ''' #初始化权值和偏重 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) #input layer None表示张量第一维度可以是任意长度的 x_ = tf.placeholder(tf.float32,shape=[None,784]) y_ = tf.placeholder(tf.float32,shape=[None,10]) #隐藏层 w_h = weight_variable([784,1024]) b_h = bias_variable([1024]) hidden = tf.nn.relu(tf.matmul(x_,w_h) + b_h) #输出层 w_o = weight_variable([1024,10]) b_o = bias_variable([10]) output = tf.nn.softmax(tf.matmul(hidden,w_o) + b_o) ''' 三 设置对数似然损失函数 ''' #代价函数 J =-(Σy.logaL)/n .表示逐元素乘 cost = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(output),axis=1)) ''' 四 求解 ''' train = tf.train.AdamOptimizer(0.001).minimize(cost) #预测结果评估 #tf.argmax(output,1) 按行统计最大值得索引 correct = tf.equal(tf.argmax(output,1),tf.argmax(y_,1)) #返回一个数组 表示统计预测正确或者错误 accuracy = tf.reduce_mean(tf.cast(correct,tf.float32)) #求准确率 #创建list 保存每一迭代的结果 training_accuracy_list = [] test_accuracy_list = [] training_cost_list=[] test_cost_list=[] #使用会话执行图 sess.run(tf.global_variables_initializer()) #初始化变量 #开始迭代 使用Adam优化的随机梯度下降法 for i in range(5000): #一个epoch需要迭代次数计算公式:测试集长度 / batch_size x_batch,y_batch = mnist.train.next_batch(batch_size = 64) #开始训练 train.run(feed_dict={x_:x_batch,y_:y_batch}) if (i+1)%200 == 0: #输出训练集准确率 #training_accuracy = accuracy.eval(feed_dict={x_:mnist.train.images,y_:mnist.train.labels}) training_accuracy,training_cost = sess.run([accuracy,cost],feed_dict={x_:mnist.train.images,y_:mnist.train.labels}) training_accuracy_list.append(training_accuracy) training_cost_list.append(training_cost) print('{0}:Training set accuracy {1},cost {2}.'.format(i+1,training_accuracy,training_cost)) #输出测试机准确率 #test_accuracy = accuracy.eval(feed_dict={x_:mnist.test.images,y_:mnist.test.labels}) test_accuracy,test_cost = sess.run([accuracy,cost],feed_dict={x_:mnist.test.images,y_:mnist.test.labels}) test_accuracy_list.append(test_accuracy) test_cost_list.append(test_cost) print('{0}:Test set accuracy {1},cost {2}.'.format(i+1,test_accuracy,test_cost)) #绘制曲线图 plot_overlay_cost(training_cost_list,test_cost_list) plot_overlay_accuracy(training_accuracy_list,test_accuracy_list) #取24个样本,可视化显示预测效果 x_batch,y_batch = mnist.test.next_batch(batch_size = 24) #获取x_batch图像对象的数字标签 y_test = np.argmax(y_batch,1) #获取预测结果 y_pred = np.argmax(output.eval(feed_dict={x_:x_batch,y_:y_batch}),1) #显示与分类标签0-9对应的名词 target_names = ['number 0','number 1','number 2','number 3','number 4','number 5','number 6','number 7','number 8','number 9'] #需要测试的真实的标签和预测作为比较 显示主要的分类指标,返回每个类标签的精确、召回率及F1值 print(classification_report(y_test,y_pred,target_names = target_names)) #建立一个n*n 分别对应每一组真实的和预测的值 用于呈现一种可视化效果 print(confusion_matrix(y_test,y_pred,labels = range(len(target_names)))) #标题 prediction_titles = [title(y_pred,y_test,target_names,i) for i in range(y_pred.shape[0])] #打印图片 plot_gallery(x_batch,prediction_titles,28,28,6,4)
2.3 运行
运行结果如下:
亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。
日期 | 姓名 | 金额 |
---|---|---|
2023-09-06 | *源 | 19 |
2023-09-11 | *朝科 | 88 |
2023-09-21 | *号 | 5 |
2023-09-16 | *真 | 60 |
2023-10-26 | *通 | 9.9 |
2023-11-04 | *慎 | 0.66 |
2023-11-24 | *恩 | 0.01 |
2023-12-30 | I*B | 1 |
2024-01-28 | *兴 | 20 |
2024-02-01 | QYing | 20 |
2024-02-11 | *督 | 6 |
2024-02-18 | 一*x | 1 |
2024-02-20 | c*l | 18.88 |
2024-01-01 | *I | 5 |
2024-04-08 | *程 | 150 |
2024-04-18 | *超 | 20 |
2024-04-26 | .*V | 30 |
2024-05-08 | D*W | 5 |
2024-05-29 | *辉 | 20 |
2024-05-30 | *雄 | 10 |
2024-06-08 | *: | 10 |
2024-06-23 | 小狮子 | 666 |
2024-06-28 | *s | 6.66 |
2024-06-29 | *炼 | 1 |
2024-06-30 | *! | 1 |
2024-07-08 | *方 | 20 |
2024-07-18 | A*1 | 6.66 |
2024-07-31 | *北 | 12 |
2024-08-13 | *基 | 1 |
2024-08-23 | n*s | 2 |
2024-09-02 | *源 | 50 |
2024-09-04 | *J | 2 |
2024-09-06 | *强 | 8.8 |
2024-09-09 | *波 | 1 |
2024-09-10 | *口 | 1 |
2024-09-10 | *波 | 1 |
2024-09-12 | *波 | 10 |
2024-09-18 | *明 | 1.68 |
2024-09-26 | B*h | 10 |
2024-09-30 | 岁 | 10 |
2024-10-02 | M*i | 1 |
2024-10-14 | *朋 | 10 |
2024-10-22 | *海 | 10 |
2024-10-23 | *南 | 10 |
2024-10-26 | *节 | 6.66 |
2024-10-27 | *o | 5 |
2024-10-28 | W*F | 6.66 |
2024-10-29 | R*n | 6.66 |
2024-11-02 | *球 | 6 |
2024-11-021 | *鑫 | 6.66 |
2024-11-25 | *沙 | 5 |
2024-11-29 | C*n | 2.88 |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了