Tensorflow2.0 利用cnn Lenet-5网络实现mnist手写数字识别

Tensorflow2.0 mnist手写数字识别
使用改进后的Lenet-5网络:
在这里插入图片描述

import tensorflow as tf
import tensorflow.keras.layers as layers
from tensorflow.keras import Sequential
import numpy as np
from tensorflow.keras import losses,optimizers
from tensorflow.keras import metrics

#网络层的搭建
networks=Sequential([
    layers.Conv2D(6,kernel_size=3,strides=1),
    layers.MaxPooling2D(pool_size=2,strides=2),
    layers.ReLU(), #(可以不要这一层)激活函数类并不是主要的网络计算层,不计入网络层数
    layers.Conv2D(16,kernel_size=3,strides=1),
    layers.MaxPooling2D(pool_size=2,strides=2),
    layers.ReLU(),
    layers.Flatten(),
    layers.Dense(120,activation='relu'),
    layers.Dense(84,activation='relu'),
    layers.Dense(10) #输出层,没有激活函数(激活函数为None)
    ])
networks.build(input_shape=(4,28,28,1)) #这里的4即为后面的batch_size
#networks.summary()

#数据集的导入
x=np.load('mnist.npz')
print(x.files) #使用files,输出:['x_test', 'x_train', 'y_train', 'y_test']
test_data=x['x_test'] #一定要加''号
train_data=x['x_train']
train_label,test_label=x['y_train'],x['y_test']

#为了契合networks.build(),这里需要将数据集的维度增加一维,即从一个平面,变成单通道
test_data=tf.expand_dims(test_data/255.0,axis=-1) #扩维,并归一化
train_data=tf.expand_dims(train_data/255.0,axis=-1)

#数据集的batch等处理,这里没有使用随机选取batch,而是为了方便按顺序取batch
def get_batch(batch_size,i):
    #index=np.random.randint(0,np.shape(train_data)[0],batch_size) #np.shape(train_data)表示train_data的形状
    x=4*i
    train_data_batch=train_data[x:x+4,:]
    train_lable_batch=train_label[x:x+4]
    if x+4 >= num_train_data:
        x=0
    return train_data_batch,train_lable_batch

#定义训练模型所需要的参数
epoch=5
batch_size=4  #这里必须与神经网络的输入尺寸一致
num_train_data=np.shape(train_data)[0]
batch_num=int(num_train_data//batch_size) #这里必须取整
optimizer=optimizers.Adam(learning_rate=0.001)

#模型训练     |损失函数:softmax交叉熵损失函数
#loss_object=losses.CategoricalCrossentropy(from_logits=True) #这是一个类,loss_object为类的实例化对象
for n in range(epoch):
    for i in range(batch_num):
        with tf.GradientTape() as tape: #with语句内引出需要求导的量
            x,y=get_batch(4,i)
            out=networks(x)
            y_onehot=tf.one_hot(y,depth=10)
            loss_object=losses.CategoricalCrossentropy(from_logits=True)
            loss=loss_object(y_onehot,out) #使用损失函数类来计算损失
            print('epoch:%d batch:%d loss:%f'%(n,i,loss.numpy()))
        grad=tape.gradient(loss,networks.trainable_variables) #用以自动计算梯度
        optimizer.apply_gradients(zip(grad,networks.trainable_variables))

#模型的测试,使用metrics中的SparseCategoricalAccuracy()中的update_state来对比
#由于在测试集中不需要进行参数的更新等,可使用predict来直接得出训练的结果
#最后使用SparseCategoricalAccuracy()中封装的result()来直接得出预测准确度的结果
s_c_a=metrics.SparseCategoricalAccuracy()
num_test_batch=int(np.shape(test_data)[0]//batch_size)
for num_index in range(num_test_batch):
    start_index,end_index=num_index*batch_size,(num_index+1)*batch_size
    y_predict=networks.predict(test_data[start_index:end_index])
    s_c_a.update_state(y_true=test_label[start_index:end_index],y_pred=y_predict)
print('test accuracy:%f'%s_c_a.result())

由于为经典的数据集,在训练一个epoch后的精确度可达:97.29%,后面随着epoch的增加,还会提高

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值