机器学习简单的来说,分为监督式学习
和无监督式学习
;
对于监督式学习就是需要人为的来告诉计算机这是什么,需要我们给他一个标签
(答案)。
无监督式学习就是不需要我们给出标签
(答案)。
图像识别(Image Recognition)是指利用计算机对图像进行处理、分析、计算以识别各种不同模式的目标和对像的技术。
手写数字识别是机器学习以及学习CNN
的一个入门案例,计算机通过手写体写出来的数字来识别出图片中的字;但是与印刷字体不同的是,印刷体的字体规则整齐,而不同人的手写体风格迥异,大小不一, 造成了计算机对手写识别任务的一些困难。所以就需要寻找大量的数据集来供应计算机学习。
数字手写体识别由于其有限的类别(0~9共10个数字)成为了相对简单 的手写识别任务。MNIST
是常用的数字手写识别数据集
手写数字识别
一、下载数据集
TensorFlow所用版本为1.14版本的
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets("MNIST_data",one_hot=True)
数据集根据MNIST函数调用下载,并且转换为onehot编码
;
所谓onehot编码就是由01做组成的一组数,例如0100000000,000010000等字样的数据,他们分别代表了数1
和4
,根据0123456789他们所在的位置来表示数的。
本次手写数字识别train是55000个训练数据,测试是10000个测试集;大小都为28*28的手写图片。
#列出(图片个数,像素点个数)
print("'trainimg' 的shape是:{}".format(mnist.train.images.shape))
print("'trainlabel' 的shape是: {}".format(mnist.train.labels.shape))
print("'testing' 的shape是: {}" .format(mnist.test.images.shape))
print("'testlabel' 的shape是:{} ".format(mnist.test.labels.shape))
'trainimg' 的shape是:(55000, 784)
'trainlabel' 的shape是: (55000, 10)
'testing' 的shape是: (10000, 784)
'testlabel' 的shape是:(10000, 10)
二、构建神经网络
#神经网络构成
n_hidden_1 = 256
n_hidden_2 = 128
n_input = 784
n_classes = 10
#输入与输出
x = tf.placeholder("float", [None, n_input])
y = tf.placeholder("float", [None, n_classes])
#神经网络初始化参数
stddev = 0.1
#权重选择高斯初始化,关键在于out权重矩阵
weights = {
'w1': tf.Variable(tf.random_normal([n_input, n_hidden_1],stddev=stddev)),
'w2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2], stddev=stddev)),
'out': tf.Variable(tf.random_normal([n_hidden_2, n_classes], stddev=stddev))
}
#偏置可以选择0值或者也采用高斯初始化
biases = {
'b1': tf.Variable(tf.random_normal([n_hidden_1])),
'b2': tf.Variable(tf.random_normal([n_hidden_2])),
'out': tf.Variable(tf.random_normal([n_classes]))
}
三、构建优化函数和损失函数
#前向传播,返回10个类别的输出,所有的输出不是神经网络的层,直接返回即可
def multilayer_perceptron(_X, _weights, _biases):
layer_1 = tf.nn.relu6(tf.add(tf.matmul(_X, _weights['w1']), _biases['b1']))
layer_2 = tf.nn.relu6(tf.add(tf.matmul(layer_1, _weights['w2']), _biases['b2']))
return(tf.matmul(layer_2, _weights['out']) + _biases['out'])
#Prediction,定义预测值
pred = multilayer_perceptron(x, weights, biases)
#反向传播
#损失函数采用 交叉熵函数softmax_cross_entropy_with_logits(pred,y) 输入:第一参数:预测值,即一次前向传播的结果;第二参数实际的label值
#平均的loss reduce_mean 表示最后的结果除以n
#tf.nn.softmax_cross_entropy_with_logits()函数参数要设置更新!
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
#优化器选择:梯度下降
#optm = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(cost)
optm = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)
#定义精度值,tf.cast()将True和False转换为1和0
corr = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accr = tf.reduce_mean(tf.cast(corr, 'float'))
#变量初始化
init = tf.global_variables_initializer()
四、训练模型
#超参数定义
training_epochs = 40
batch_size = 100
display_step = 2
#加载计算图
sess = tf.Session()
sess.run(init)
#optimize
print("开始训练:")
for epoch in range(training_epochs):
avg_cost = 0
total_batch = int(mnist.train.num_examples/batch_size)
#Iteraton
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
feeds = {x: batch_xs, y: batch_ys}
sess.run(optm, feed_dict=feeds)
avg_cost += sess.run(cost, feed_dict=feeds)
avg_cost = avg_cost/total_batch
#display
if (epoch) % display_step == 0:
print("循环次数: %03d/%03d 损失: %.9f" % (epoch, training_epochs, avg_cost))
feeds = {x: batch_xs, y: batch_ys}
train_acc = sess.run(accr, feed_dict=feeds)
print("训练集正确率: %.3f" % (train_acc))
模型在训练几轮之后,训练集正确率就会达到97%,之后就会出现模型过拟合。大家可以通过调参,优化函数等方法来改进,使模型能够更近一步;
五、验证结果
预测错误
print('现在随机显示25个错误的预测:')
randidx = np.random.randint(incorrectImages.shape[0],size = 25)
plt.figure(figsize=(8,8))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(True)
curr_img = np.reshape(incorrectImages[randidx[i],:],(28,28))
rightLabel=np.argmax(incorrectLabels[randidx[i],:]) #label
predictedLabel=np.argmax(incorrectPredications[randidx[i],:])
curr_label = '{}: {}(v) -> {}(x)'.format(randidx[i],rightLabel,predictedLabel)
plt.imshow(curr_img,cmap=plt.cm.binary)
plt.xlabel(curr_label)
#plt.imshow(mnist.test.images[i], cmap=plt.cm.binary)
#plt.xlabel(mnist.test.labels[i])
correctGuesses=sess.run(corr, feed_dict=\
{x: mnist.test.images, \
y: mnist.test.labels})
incorrectImages=mnist.test.images[correctGuesses]
incorrectLabels=mnist.test.labels[correctGuesses]
incorrectPredications=sess.run(pred, feed_dict={x:incorrectImages})
print('测试集中有{}个预测正确'.format(incorrectImages.shape[0]))
print('现在随机显示25个正确的预测:')
randidx = np.random.randint(incorrectImages.shape[0],size = 25)
plt.figure(figsize=(8,8))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(True)
curr_img = np.reshape(incorrectImages[randidx[i],:],(28,28))
rightLabel=np.argmax(incorrectLabels[randidx[i],:]) #label
predictedLabel=np.argmax(incorrectPredications[randidx[i],:])
curr_label = '{}: {}(v) -> {}(x)'.format(randidx[i],rightLabel,predictedLabel)
plt.imshow(curr_img,cmap=plt.cm.binary)
plt.xlabel(curr_label)
#plt.imshow(mnist.test.images[i], cmap=plt.cm.binary)
#plt.xlabel(mnist.test.labels[i])
结论:
手写数字来说,神经网络是一个很好的,并且非常好的一个方法。
谢谢点赞评论!