暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

LeNet-5​基础介绍及代码测试

Python爬虫和数据挖掘 2021-07-07
668

文章目录


  • 文章目录

    • 1. LeNet-5 基础介绍

    • 2. 利用 TensorFlow + LeNet-5 识别 mnist 手写数字


1. LeNet-5 基础介绍

通过详解卷积神经网络 CNN[1]一文,我们对卷积神经网络的有了很多认识,接下来我们将通过几个经典的卷积神经网络,加深对卷积神经网络的理解和认识。

年, 等人在论文 《GradientBased  Learning  Applied to Document Recognition》 中提出并详细介绍了 LeNet-5 神经网络结构,并用于手写数字识别问题,能达到很高的识别率。LeNET-5 包含卷积层,池化层,全连接层,成为了卷积神经网络的经典结构,被誉为是卷积神经网络的"Hello Word"。

该网络现在来看十分简单,十分适合入门,其结构如下

Lenet-5架构

该网络共包含 层(不含输入层),我们根据以下公式计算卷积或者池化之后的特征图大小

  • 该层是一个卷积层,使用 的卷积核,步长为

    每个卷积核有 个参数,共有 个参数。

  • 该层是一个 Pooling 层,Pooling 大小为 ,步长为 .

    该层没有要学习的参数

  • 该层是一个卷积层,使用 的卷积核,步长为

    共有 个参数。

  • 该层是一个 Pooling 层,Pooling 大小为 ,步长为 .

    该层没有要学习的参数

  • 论文描述的是一个卷积层,使用 的卷积核,步长为 .

    共有 个参数

    其实这层也可以看做是一个全连接层的一个隐藏层,神经元个数为 个,输入的数据来自 层特征数据拉直。

  • 该层是一个全连接层。

    共有 个参数。

  • 该层是一个全连接层。

    共有 个参数。

我们用以下表格更加直观的看下每一层都做了什么

这里重点介绍其网络结构,部分细节可能和论文不一致,需要原论文的可联系我。

2. 利用 TesorFlow + LeNet-5 识别 mnist 手写数字

#!/usr/bin/python3

# @Time    : 2021/2/23 9:56
# @Author  :
# @File    : Lenet5
# @Software: PyCharm
# @Description : Python==3.7.3、tensorflow==2.4.1

import tensorflow as tf
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D,BatchNormalization,Activation,MaxPool2D,Dropout,Flatten,Dense,AveragePooling2D
from tensorflow.keras import Model
import os

# 设置超过多长省略显示,这里设置np.inf表示无限长
np.set_printoptions(threshold=np.inf)

# 准备数据集合
# cifar10 = tf.keras.datasets.cifar10
cifar10 = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train,x_test = x_train/255.0,x_test/255.0

# 给数据增加一个维度,使数据和网络结构匹配
x_train = x_train.reshape(x_train.shape[0], 28281)
x_test = x_test.reshape(x_test.shape[0], 28281)


# 自定义网络模型
class Letnet5Model(Model,):
    # 定义网络结构
    def __init__(self):
        super(Letnet5Model,self).__init__()
        # 定义6个 5*5的卷积核
        self.c1 = Conv2D(filters=6,kernel_size=(5,5),activation='sigmoid',padding='same')
        # 平均池化,池化大小 2*2,步长2
        self.s2 = AveragePooling2D(pool_size=(2,2),strides=2)
        # 定义16个5*5的卷积核
        self.c3 = Conv2D(filters=16,kernel_size=(5,5),activation='sigmoid')
        self.s4 = AveragePooling2D(pool_size=(2,2),strides=2)

        # 将卷积得到的特征数据拉直
        self.f = Flatten()
        # 定个一个120个神经元的全连接隐藏层
        self.c5 = Dense(units=120, activation='sigmoid')
        # 定个一个80个神经元的全连接隐藏层
        self.f6 = Dense(units=84,activation='sigmoid')
        # 定个一个10个神经元的全连接隐藏层
        self.o7 = Dense(units=10,activation='softmax')

    # 调用网络结构,实现前向传播
    def call(self, inputs, training=None, mask=None):
        inputs = self.c1(inputs)
        inputs = self.s2(inputs)
        inputs = self.c3(inputs)
        inputs = self.s4(inputs)
        inputs = self.f(inputs)
        inputs = self.c5(inputs)
        inputs = self.f6(inputs)
        y = self.o7(inputs)
        return y

def acc_loss_analyse(robot,):
    # 绘制训练集和验证集的acc和loss曲线
    acc = robot.history['sparse_categorical_accuracy']
    val_acc = robot.history['val_sparse_categorical_accuracy']
    loss = robot.history['loss']
    val_loss = robot.history['val_loss']

    plt.subplot(121)
    plt.plot(acc, label='Training Accuracy')
    plt.plot(val_acc, label='Validation Accuracy')
    plt.title("Training and Validation Accuracy")
    plt.legend()

    plt.subplot(122)
    plt.plot(loss, label='Training Loss')
    plt.plot(val_loss, label='Validation Loss')
    plt.title('Training and Validation Loss')
    plt.legend()
    plt.show()

def main():
    model = Letnet5Model()

    # 配置训练项,设定optimizer(优化器),loss(损失函数),metrics(网络评判标准)
    model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
                  metrics=['sparse_categorical_accuracy'])

    breakpoint_sava_path = './checkpoint/LeNet5.ckpt'
    if os.path.exists(breakpoint_sava_path+'.index'):
        print('-------------load the model-----------------')
        # 读取模型
        model.load_weights(breakpoint_sava_path)

    # 保存模型
    cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=breakpoint_sava_path, save_weights_only=True,save_best_only=True)
    # 开始训练
    robot = model.fit(x_train,y_train,batch_size=32,epochs=5,validation_data=(x_test,y_test),validation_freq=1,callbacks=[cp_callback])
    # 查看网络结构基本信息
    model.summary()
    acc_loss_analyse(robot, )

if __name__ == '__main__':
    main()

复制

运行代码,可以看到 打印的每层参数个数和之前的分析保持一致

训练了两百轮,最好验证集准确率为

Reference

[1]

详解卷积神经网络 CNN: https://blog.csdn.net/SpiritedAway1106/article/details/113931976


文章转载自Python爬虫和数据挖掘,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论