Keras搭建经典CNN LeNet5网络进行手写体识别

1 简介

LeNet-5 模型是Yann LeCun 教授于 1998 年在论文 Gradient-based learning applied to document recognition中提出的,它是第一个成功应用于数字识别问题的卷积神经网络。在 MNIST 数据集上, LeNet-5 模型可以达到大约 **99.2%**的正确率。

LeNet-5的网络结构如下:

minst手写体数据集基础上构建LeNet-5网络,其结构如下:
在这里插入图片描述
其中,T表示tanh激活函数,S代表softmax

2 数据处理和展示

原始mnist数据格式为**[6000,28,28],但是卷积层所需要的格式为[None,28,28,1]None 代表任何个[28,28,1]数据,其中28为宽高**,1代表颜色通道(一般颜色通道为3,rgb,这里采用灰色).

 def load_data(self):  
        print('loaddata')  
        (X_train, y_train), (X_test, y_test) = mnist.load_data()  
        X_train = X_train.reshape(-1, 28, 28, 1)  # normalize  
 		X_test = X_test.reshape(-1, 28, 28, 1)  # normalize  
		X_train = X_train / 255  
 		X_test = X_test / 255  
 		y_train = to_categorical(y_train, num_classes=10)  
        y_test = to_categorical(y_test, num_classes=10)  
        return (X_train, y_train), (X_test, y_test)  

我们选取了数据中9张图进行展示:
在这里插入图片描述

3 模型搭建

其中LeNet5中的5代表5层,我已经在下面用彩色数字标注出来了。
在这里插入图片描述

4 代码实现

import tensorflow as tf  
from tensorflow.keras.datasets import mnist  
from tensorflow.keras.layers import Dense, Conv2D, AveragePooling2D, Flatten  
from tensorflow.keras.models import Sequential  
from tensorflow.keras.utils import to_categorical  

class LeNet5:  
    def __init__(self):  
        self.model = Sequential()  
  
    def load_data(self):  
        print('loaddata')  
        (X_train, y_train), (X_test, y_test) = mnist.load_data()  
        X_train = X_train.reshape(-1, 28, 28, 1)  # normalize  
 		X_test = X_test.reshape(-1, 28, 28, 1)  # normalize  
		X_train = X_train / 255  
 		X_test = X_test / 255  
 		y_train = to_categorical(y_train, num_classes=10)  
        y_test = to_categorical(y_test, num_classes=10)  
        return (X_train, y_train), (X_test, y_test)  
  
    def train(self, x, y):  
        print("build")  
        self.model.add(Conv2D(input_shape=(28, 28, 1),  
                              filters=6,  
                              kernel_size=(5, 5),  
                              strides=1,  
                              activation=tf.keras.activations.tanh))  
        self.model.add(AveragePooling2D(pool_size=(2, 2)))  
        self.model.add(Conv2D(filters=6,  
                              kernel_size=(5, 5),  
                              strides=1,  
                              activation=tf.keras.activations.tanh))  
        self.model.add(AveragePooling2D(pool_size=(2, 2)))  
        self.model.add(Flatten())  
        self.model.add(Dense(120, activation=tf.keras.activations.tanh))  
        self.model.add(Dense(84, activation=tf.keras.activations.tanh))  
        self.model.add(Dense(10, activation=tf.keras.activations.softmax)) 
		
        # Compile model  
 		self.model.compile(loss=tf.keras.losses.CategoricalCrossentropy(),  
                           optimizer="adam",  
                           metrics=['accuracy'])  
        print("train")  
        self.model.fit(x=x, y=y, batch_size=1, epochs=100, verbose=1)  
        return self.model  
  
    def predict(self, x):  
        print("predict")  
        for result in self.model.predict(x):  
            print(tf.argmax(result))  
  
  
if __name__ == "__main__":  
    lenet = LeNet5()  
    (X_train, y_train), (X_test, y_test) = lenet.load_data()  
  
    lenet.train(X_train, y_train)  
    lenet.predict(X_test)

5 评估

模型结构:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 24, 24, 6)         156       
_________________________________________________________________
average_pooling2d (AveragePo (None, 12, 12, 6)         0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 8, 8, 6)           906       
_________________________________________________________________
average_pooling2d_1 (Average (None, 4, 4, 6)           0         
_________________________________________________________________
flatten (Flatten)            (None, 96)                0         
_________________________________________________________________
dense (Dense)                (None, 120)               11640     
_________________________________________________________________
dense_1 (Dense)              (None, 84)                10164     
_________________________________________________________________
dense_2 (Dense)              (None, 10)                850       
=================================================================
Total params: 23,716
Trainable params: 23,716
Non-trainable params: 0
_________________________________________________________________

为了快速得到结果,设置epoch=1得到训练结果:

loss: 0.1207 - accuracy: 0.9625
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为您提供该问题的代码实现。以下是基于Keras搭建的LeNet-5网络对Mnist手写数字进行识别的代码: ```python # 导入所需的库 from keras.layers import Conv2D, AveragePooling2D, Flatten, Dense from keras.models import Sequential from keras.datasets import mnist from keras.utils import np_utils # 载入数据集 (X_train, y_train), (X_test, y_test) = mnist.load_data() # 数据预处理 X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32') X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32') X_train /= 255 X_test /= 255 y_train = np_utils.to_categorical(y_train, 10) y_test = np_utils.to_categorical(y_test, 10) # 构建模型 model = Sequential() model.add(Conv2D(filters=6, kernel_size=(5,5), activation='relu', input_shape=(28,28,1))) model.add(AveragePooling2D(pool_size=(2,2))) model.add(Conv2D(filters=16, kernel_size=(5,5), activation='relu')) model.add(AveragePooling2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dense(units=120, activation='relu')) model.add(Dense(units=84, activation='relu')) model.add(Dense(units=10, activation='softmax')) # 编译模型 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # 训练模型 model.fit(X_train, y_train, validation_data=(X_test, y_test), batch_size=128, epochs=10) # 评估模型 score = model.evaluate(X_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) ``` 在运行代码后,您将会得到模型的测试准确率,该模型可以识别0-9手写数字。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术人Howzit

钱不钱的无所谓,这是一种鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值