深度学习入门!四种方式实现minist分类!全部详细代码实现!Cnn(卷积神经网络,两种方式),感知机(Bp神经网络),逻辑回归!代码详细注释!!minist数据集该怎么使用?

通过训练好的模型,来测试自己手写的数字,教你如何实现!以及如何调用模型和保存模型:

https://blog.csdn.net/weixin_41146894/article/details/110010179


*****

前言

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):
    #因为输入的数据是1784行,需要转化为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的准确度相对较高。大家有什么问题可以提出来,如果我能回答,我一定回及时回答。

  • 18
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值