文章目录
- **通过训练好的模型,来测试自己手写的数字,教你如何实现!以及如何调用模型和保存模型:**
- ****
- 前言
- 一、Cnn实现minist代码
- 一、Cnn实现minist代码分类--tf.nn实现,详细版
- 二、Cnn实现minist代码分类二--tensorflow.keras.layers实现,简洁版(加载数据:from tensorflow.examples.tutorials.mnist import input_data)
- 三、通过:(x_train,y_train),(x_test,y_test)=tf.keras.datasets.mnist.load_data()加载数据
- 二、多层感知器(Bp神经网络)实现minist代码
- 三、逻辑回归实现minist代码
- 四、mnist数据集下载地址,以及下载后数据集如何使用
- 总结
通过训练好的模型,来测试自己手写的数字,教你如何实现!以及如何调用模型和保存模型:
*****
前言
minist数字识别,是深度学习入门数据集。这里使用了四种方式来实现对minist数字分类。分别是逻辑回归,多层感知机,以及我们熟悉的cnn(卷积神经网络)。这里是基于tensorflow来实现的代码,很好入门。
如果出现报错:no model from tensorflow.examples.tutorials,那么请选择CNN实现版本的第三个版本。
一、Cnn实现minist代码
一、Cnn实现minist代码分类–tf.nn实现,详细版
使用的tf.nn.来构建的两层神经网络,如果对于卷积神经网络之间是怎么运算的不熟悉,可以好好研究一下,对于刚刚入门的选手来说,帮助比较大。代码二实现的是简洁版,直接利用的
import time
import tensorflow as tf
import numpy as np
from matplotlib import pyplot as plt
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets( 'Minist_data',one_hot=True)
#参数初始化
input_num = 784 # 输入的列数
labels = 10 #输出的列数
batchsize = 128 #训练集每一批次的照片
max_epochs = 1000 #迭代的次数
dropout = 0.85
#这里设置的x,y的作用是来存储输入的照片个数,和标签个数
x = tf.placeholder(tf.float32,[None, input_num])
y = tf.placeholder(tf.float32,[None, labels])
# 数据处理,标注化
def normallize( x ):
mean_x = np.mean( x )
std_x = np.std( x )
x = (x - mean_x)/ std_x
return x
#设置卷积层,x:输入的照片,w对应的权值,这里才去的是不填充
def con2d(x , w , b, strides = 1):
x = tf.nn.conv2d(x, w, strides=[1, strides,strides,1], padding = 'VALID')
x = tf.nn.bias_add(x, b)
return tf.nn.relu( x)
#池化层
def maxpool2d(x, k=2):
return tf.nn.max_pool(x, ksize=[1,k,k,1], strides =[1, k, k, 1] , padding = 'SAME')
#设置模型
def con2dnet(x, weights, biases ,dropout):
#因为输入的数据是1行784行,需要转化为28行,28列,这里只是对于一张图开始讨论的哈
x = tf.reshape(x, shape=[-1, 28, 28, 1])
#第一个卷积层 28x28x1 change to 24x24x32
con_1 = con2d( x, weights['wc1'] , biases['bd1'])
#第一个池化层 24x24x32 change to 12x12x32
con_1_maxpol = maxpool2d(con_1, k=2)
#第二个卷积层 12x12x32 change to 8x8x64
con_2 = con2d( con_1_maxpol, weights['wc2'] , biases['bd2'])
#第二个池化层 8x8x64 change to 4x4x64
con_1_maxpo2 = maxpool2d(con_2, k=2)
#全连接层 4*4*64(每一个特征图4*4,共有64个),变化成一行4*4*64,便于全连接
#这里批次是128张图,那么就是128个行4*4*64,功能如同下面代码二的:layers.flatten()
fc1 = tf.reshape(con_1_maxpo2,[-1,weight['wd1'].get_shape().as_list()[0]])
#这个就是全连接层的计算 [1,4x4x64] change to [1, 1024]
fc2 = tf.add(tf.matmul(fc1, weight['wd1']), biases['bd3'])
fc2 = tf.nn.relu(fc2)
# dropout层
fc3 = tf.nn.dropout(fc2,dropout)
# [1,1024] change to [1, 10]
fc3 = tf.add(tf.matmul(fc2, weight['wd2']),biases['bd4'])
return fc3
#设置卷积层1,2对应的卷积核的大小,这里都是5x5 通过这里你会发现
#其实每个卷积核都不一样,这样的目的是提取不同方向维度的特征值
#这里wd1,wd2是两个全连接层对应的权值,类似于神经网络的正向传递
weight = {'wc1':tf.Variable(tf.random_normal([5,5,1,32])),
'wc2':tf.Variable(tf.random_normal([5,5,32,64])),
'wd1':tf.Variable(tf.random_normal([4*4*64,1024])),
'wd2':tf.Variable(tf.random_normal([1024,10]))}
#这里是网络层的 y = wx + b
biases = {'bd1':tf.Variable(tf.random_normal([32])),
'bd2':tf.Variable(tf.random_normal([64])),
'bd3':tf.Variable(tf.random_normal([1024])),
'bd4':tf.Variable(tf.random_normal([10]))}
pred = con2dnet( x, weight, biases , dropout)
coss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels = y))
optimizer = tf.train.AdamOptimizer(learning_rate = 0.01).minimize(coss)
correct_prediction = tf.equal(tf.argmax(pred,1), tf.argmax(y,1))
corrct_num = tf.reduce_sum(tf.cast(correct_prediction, "float"))
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
accucy_list = [] #存续每次迭代后的准确率
accucy_coss = [] #存续每次迭代后的损失值率
sess.run(init_op)
for eopch in range(max_epochs):
train_x, train_y = mnist.train.next_batch(batchsize)
z = sess.run(optimizer, feed_dict={x: train_x, y: train_y})
coss_1, num_1 = sess.run([coss, corrct_num], feed_dict={x:mnist.test.images, y:mnist.test.labels})
print('epoch:{0}, accucy:{1}:'.format(eopch, num_1/10000))
accucy_list.append(num_1/10000)
accucy_coss.append(coss_1/10000)
plt.title('test_accucy')
plt.xlabel('epochs')
plt.ylabel('accucy')
plt.plot(accucy_list)
plt.show()
plt.title('test_coss')
plt.xlabel('epochs')
plt.ylabel('coss')
plt.plot(accucy_coss)
plt.show()
实现结果:
epoch:986, accucy:0.9639:
epoch:987, accucy:0.9645:
epoch:988, accucy:0.9653:
epoch:989, accucy:0.9649:
epoch:990, accucy:0.9643:
epoch:991, accucy:0.9634:
epoch:992, accucy:0.9623:
epoch:993, accucy:0.9625:
epoch:994, accucy:0.963:
epoch:995, accucy:0.9635:
epoch:996, accucy:0.9638:
epoch:997, accucy:0.9643:
epoch:998, accucy:0.9645:
epoch:999, accucy:0.964:
二、Cnn实现minist代码分类二–tensorflow.keras.layers实现,简洁版(加载数据:from tensorflow.examples.tutorials.mnist import input_data)
这里创建的和上面代码创建的网络结构是相同的,清晰易懂。
import tensorflow as tf
from tensorflow.keras import layers ,models
from tensorflow.examples.tutorials.mnist import input_data
#读取模型
mnist = input_data.read_data_sets('\Minist_data', one_hot = False)
#创建网络
model = models.Sequential()
#第一个卷积层 28x28x1 change to 24x24x32
model.add(layers.Conv2D(32,kernel_size = [5,5],activation='relu',input_shape=(28,28,1)))
#第一个池化层层24x24x32 change to 12x12x32
model.add(layers.MaxPooling2D([2,2]))
#第二个卷积层 12x12x32 change to 8x8x64
model.add(layers.Conv2D(64,kernel_size = [5,5],activation='relu'))
#第二个池化层 8x8x64 change to 4x4x64
model.add(layers.MaxPooling2D([2,2]))
#全连接层 4*4*64(每一个特征图4*4,共有64个),变化成一行4*4*64,便于全连接
model.add(layers.Flatten())
#这个就是全连接层的计算 [1,4x4x64] change to [1, 1024]
model.add(layers.Dense(1024,activation = 'relu'))
model.add(layers.Dense(10, activation = 'softmax'))
# [1,1024] change to [1, 10]
model.summary()
#把最有最优算的参数
check_path = './ckpt/cp-{epoch:04d}.ckpt'
# period 每隔5epoch保存一次
save_model_cb = tf.keras.callbacks.ModelCheckpoint(
check_path, save_weights_only=True, verbose=1, period=5)
#设置模型的优化类型
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
#填充数据,总共循环10次
model.fit(mnist.train.images.reshape((55000,28,28,1)),mnist.train.labels, epochs = 10 )
#根据算的权值,计算准确率
test_loss, test_acc = model.evaluate(mnist.test.images.reshape(10000,28,28,1)
, mnist.test.labels)
print('\n')
print('测试集的准确率:')
print("准确率: %.4f,共测试了%d张图片 " % (test_acc,len(mnist.test.images)))
运行结果:
samples seen.
Epoch 1/10
55000/55000 [==============================] - 76s 1ms/sample - loss: 0.1083 - acc: 0.9658
Epoch 2/10
55000/55000 [==============================] - 74s 1ms/sample - loss: 0.0395 - acc: 0.9873
Epoch 3/10
55000/55000 [==============================] - 76s 1ms/sample - loss: 0.0266 - acc: 0.9918
Epoch 4/10
55000/55000 [==============================] - 73s 1ms/sample - loss: 0.0196 - acc: 0.9937
Epoch 5/10
55000/55000 [==============================] - 73s 1ms/sample - loss: 0.0153 - acc: 0.9953
Epoch 6/10
55000/55000 [==============================] - 69s 1ms/sample - loss: 0.0136 - acc: 0.9957
Epoch 7/10
55000/55000 [==============================] - 69s 1ms/sample - loss: 0.0110 - acc: 0.9968
Epoch 8/10
55000/55000 [==============================] - 73s 1ms/sample - loss: 0.0103 - acc: 0.9969
Epoch 9/10
55000/55000 [==============================] - 68s 1ms/sample - loss: 0.0081 - acc: 0.9974
Epoch 10/10
55000/55000 [==============================] - 65s 1ms/sample - loss: 0.0094 - acc: 0.9970
10000/10000 [==============================] - 3s 280us/sample - loss: 0.0337 - acc: 0.9920
测试集的准确率:
准确率: 0.9920,共测试了10000张图片
三、通过:(x_train,y_train),(x_test,y_test)=tf.keras.datasets.mnist.load_data()加载数据
import tensorflow as tf
from tensorflow.keras import layers ,models
#读取模型
(x_train,y_train),(x_test,y_test)=tf.keras.datasets.mnist.load_data()
print(x_train.shape)
#创建网络
model = models.Sequential()
#第一个卷积层 28x28x1 change to 24x24x32
model.add(layers.Conv2D(32,kernel_size = [5,5],activation='relu',input_shape=(28,28,1)))
#第一个池化层层24x24x32 change to 12x12x32
model.add(layers.MaxPooling2D([2,2]))
#第二个卷积层 12x12x32 change to 8x8x64
model.add(layers.Conv2D(64,kernel_size = [5,5],activation='relu'))
#第二个池化层 8x8x64 change to 4x4x64
model.add(layers.MaxPooling2D([2,2]))
#全连接层 4*4*64(每一个特征图4*4,共有64个),变化成一行4*4*64,便于全连接
model.add(layers.Flatten())
#这个就是全连接层的计算 [1,4x4x64] change to [1, 1024]
model.add(layers.Dense(1024,activation = 'relu'))
model.add(layers.Dense(10, activation = 'softmax'))
# [1,1024] change to [1, 10]
model.summary()
#把最有最优算的参数
check_path = './ckpt/cp-{epoch:04d}.ckpt'
# period 每隔5epoch保存一次
save_model_cb = tf.keras.callbacks.ModelCheckpoint(
check_path, save_weights_only=True, verbose=1, period=5)
#设置模型的优化类型
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
#填充数据,总共循环10次
model.fit(x_train.reshape((60000,28,28,1)),y_train, epochs = 10 )
#根据算的权值,计算准确率
test_loss, test_acc = model.evaluate(x_test.reshape(10000,28,28,1)
,y_test)
print('\n')
print('测试集的准确率:')
print("准确率: %.4f,共测试了%d张图片 " % (test_acc,len(mnist.test.images)))
二、多层感知器(Bp神经网络)实现minist代码
这里关于bp神经网络的知识,如果不懂,可以去复习哈。理论知识也很简单。
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import time
mnist = input_data.read_data_sets('Minist_data', one_hot=True)
n_input = 784 #input num
n_labels = 10 # output num
n_hidden_layer = 30 # hidden layer
max_epochs = 10000
batch_size = 100
alphy = 0.2
seed = 0
# 设置sigmoid 函数求导公式
def sigmoid_derivation( x ):
return tf.multiply(tf.sigmoid( x ), tf.subtract(tf.constant(1.0), tf.sigmoid( x)))
# 设置权重
weigths = {'w_1':tf.Variable(tf.random_normal([ n_input, n_hidden_layer], seed=seed)), 'w_2':tf.Variable(tf.random_normal([n_hidden_layer, n_labels],seed=seed))}
basis = {'basis_1': tf.Variable(tf.random_normal([1,n_hidden_layer],seed=seed)),'basis_2':tf.Variable(tf.Variable(tf.random_normal([1,n_labels],seed=seed)))}
#设置占位符
x_in = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_labels])
def creat_model(x_in , weight, basis):
h_1 = tf.matmul(x_in, weight['w_1']) + basis['basis_1']
o_1 = tf.sigmoid( h_1 )
h_2 = tf.matmul( o_1, weight['w_2']) + basis['basis_2']
o_2 = tf.sigmoid (h_2)
return h_1, o_1, h_2, o_2
#Forward pass
h_1, o_1, h_2, y_hat = creat_model(x_in, weigths, basis)
# #error
error = y_hat - y
#backward pass
delta_2 = tf.multiply( error, sigmoid_derivation( h_2 ))
delta_w_2 = tf.matmul(tf.transpose(o_1), delta_2)
wtd_error = tf.matmul(delta_2, tf.transpose(weigths['w_2']))
delta_1 = tf.multiply(wtd_error, sigmoid_derivation( h_1 ))
delta_w_1 = tf.matmul(tf.transpose(x_in), delta_1 )
alphy = tf.constant( alphy )
# #upgraduate weights
step = [tf.assign(weigths['w_1'], tf.subtract(weigths['w_1'],tf.multiply(alphy, delta_w_1)))
,tf.assign(weigths['w_2'], tf.subtract(weigths['w_2'],tf.multiply(alphy, delta_w_2)))]
acc_mat = tf.equal(tf.argmax(y_hat,1), tf.argmax(y,1))
acc_num = tf.reduce_sum(tf.cast(acc_mat, tf.float32))
#initiallizer
initi_op = tf.global_variables_initializer()
#start session
with tf.Session( ) as sess:
sess.run(initi_op)
for epoch in range(max_epochs):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
sess.run(step, feed_dict={x_in:batch_xs, y : batch_ys})
if epoch % 1000 == 0:
acc_test = sess.run(acc_num, feed_dict={x_in:mnist.test.images, y:mnist.test.labels})
acc_train = sess.run(acc_num, feed_dict={x_in:mnist.train.images, y:mnist.train.labels})
print('Epoch:{0} , accurcy_test:{1}, accurcy_train:{2}'.format(epoch, acc_test/10000,acc_train/55000))
实现结果:
Epoch:0 , accurcy_test:0.1063, accurcy_train:0.10627272727272727
Epoch:1000 , accurcy_test:0.653, accurcy_train:0.6551636363636364
Epoch:2000 , accurcy_test:0.6668, accurcy_train:0.6692
Epoch:3000 , accurcy_test:0.6667, accurcy_train:0.6737272727272727
Epoch:4000 , accurcy_test:0.7601, accurcy_train:0.7695272727272727
Epoch:5000 , accurcy_test:0.7634, accurcy_train:0.7738181818181818
Epoch:6000 , accurcy_test:0.8517, accurcy_train:0.862890909090909
Epoch:7000 , accurcy_test:0.858, accurcy_train:0.8671454545454546
Epoch:8000 , accurcy_test:0.8631, accurcy_train:0.8733090909090909
Epoch:9000 , accurcy_test:0.9413, accurcy_train:0.9572
三、逻辑回归实现minist代码
使用我们自己熟悉的logistic 回归
#利用逻辑回归实现对于mnist的数据分类
import tensorflow as tf
import matplotlib.pyplot as plt, matplotlib.image as mpimg
from tensorflow.examples.tutorials.mnist import input_data
#读取数据
mnist = input_data.read_data_sets('\Minist_data',one_hot = True)
#给权值赋值
w = tf.Variable(tf.zeros([784,10]), name = 'w')
b = tf.Variable(tf.zeros([10]), name = 'b')
# x = tf.Variable(tf.float32, name = 'x', shape = [None,784])
# y = tf.Variable(tf.float32, name = 'y', shape = [None,10])
#设置x,y的占位符,很简单,对于x 784一个照片的大小,None 不知道你每次需要训练的批次大小
x = tf.placeholder(tf.float32, [None,784],name = 'x')
y = tf.placeholder(tf.float32, [None,10], name = 'y')
# 设置预测值
y_hat = tf.matmul(x,w)+b
#设置损失函数,交叉熵 tf.reduce_mean求得是所有交叉熵的平均值
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = y, logits = y_hat))
#选择最优梯度下降参数
optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.01).minimize(loss)
#预测
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_hat,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
#初始化
initi_op = tf.global_variables_initializer()
with tf.Session() as sess:
total = [] #便于画图
sess.run(initi_op)
for epoch in range(50):
loss_avg = 0
batch_size = 100
num_of_batch = int(mnist.train.num_examples/batch_size)
for i in range(num_of_batch):
batch_xs,batch_ys = mnist.train.next_batch(100)
_, l = sess.run([optimizer, loss], feed_dict = {x:batch_xs, y:batch_ys})
loss_avg = loss_avg + l
print('Epoch :{0} ,loss: {1}'.format(epoch,loss_avg/num_of_batch))
total.append(loss_avg/num_of_batch)
print('Done')
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y:mnist.test.labels}))
plt.plot(total)
plt.show()
实现结果:
Epoch :49 ,loss: 0.2860406456481327
Epoch :49 ,loss: 0.2863932258974422
Epoch :49 ,loss: 0.2869208517399701
Epoch :49 ,loss: 0.28743210982192646
Epoch :49 ,loss: 0.28812870155681264
Epoch :49 ,loss: 0.2885602289167317
Epoch :49 ,loss: 0.28918006840077315
Epoch :49 ,loss: 0.28969469279050825
Epoch :49 ,loss: 0.29052486633712593
Epoch :49 ,loss: 0.29099014274098656
Epoch :49 ,loss: 0.2915572559020736
Epoch :49 ,loss: 0.29206312930042094
Epoch :49 ,loss: 0.29243259806524624
Epoch :49 ,loss: 0.2931043164567514
Epoch :49 ,loss: 0.29356380319053477
Epoch :49 ,loss: 0.29405322256413374
Epoch :49 ,loss: 0.2947297677397728
Epoch :49 ,loss: 0.29508687217127194
Epoch :49 ,loss: 0.29597209028222343
Epoch :49 ,loss: 0.2963061141154983
Epoch :49 ,loss: 0.2969307041439143
Epoch :49 ,loss: 0.2975302829796618
Epoch :49 ,loss: 0.29785606977614487
Epoch :49 ,loss: 0.29842295774004673
Epoch :49 ,loss: 0.2990792263366959
Epoch :49 ,loss: 0.299645564745773
Epoch :49 ,loss: 0.3001909241080284
Epoch :49 ,loss: 0.30061151071028275
Epoch :49 ,loss: 0.30132105106657203
Epoch :49 ,loss: 0.30179316797039724
Epoch :49 ,loss: 0.3024873532490297
Epoch :49 ,loss: 0.3029060740362514
Epoch :49 ,loss: 0.3035559590296312
Epoch :49 ,loss: 0.30405486394058573
Epoch :49 ,loss: 0.30449492687528784
Done
0.9191
该处使用的url网络请求的数据。
四、mnist数据集下载地址,以及下载后数据集如何使用
mnist 数据集下载网址:http://yann.lecun.com/exdb/mnist/
one_hot = True labels(标签)对应的是 1 0 0 0 0 0 0 0 0 0 = 1
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('\Minist_data', one_hot = True)
print(mnist.test.labels)
[[0. 0. 0. ... 1. 0. 0.]
[0. 0. 1. ... 0. 0. 0.]
[0. 1. 0. ... 0. 0. 0.]
...
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]]
one_hot = False labels(标签)对应的就是我们常用的数字1,2,3,4,5,6,7,8,9
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('\Minist_data', one_hot = False)
print(mnist.test.labels)
[7 2 1 ... 4 5 6]
注意:依次下载完后,应该是下面这个图(注意,不用解压,不用解压):
然后把路径复制到这里就可以使用了。
你也可以直接利用函数下载,只是这样速度很慢,而且还可能报错,所以如果可以,还是尽量把数据集下载下来。
import os
# mnist数据集存储的位置,如何不存在将自动下载
data_path = os.path.abspath(os.path.dirname(
__file__)) + '/../data_set_tf2/mnist.npz'
总结
代码简单,易懂。通过对比,你会发现cnn的运算数度慢,准确率卷积CNN的准确度相对较高。大家有什么问题可以提出来,如果我能回答,我一定回及时回答。