LeNet手写数字识别
简介
LeNet 是由Y.Lecun等人在1998年提出的第一个真正的卷积神经网络,现在的LeNet现在主要指LeNet5,其主要特点是卷积层和下采样层相结合作为网络的基本结构,其包括3个卷积层和2个下采样层和2个全连接层。最初设计LeNet的目的是识别手写字符和打印字符,效果非常好,曾被广泛应用于美 国银行支票手写体识别,取得了很大成功 。文章会用keras 和pytorch 搭建网络。
网络结构
直接上图看着更直观。
- C1层是卷积层,包含6个特征图,是由6个5x5的卷积核对输入图像卷积得到。
- S1层是一个下采样层,包含6个特征图,是由C1层的特征图经过2x2,步长为2的窗口进行平均池化,在利用sigmoid激活函数变换得到。
- C3是卷积层包含16个特征图,是由16个5x5的卷积核对S2进行卷积得到。
- S4是一个下采样层,包含16个特征图,是由C3层的特征图经过2x2,步长为2的窗口进行平均池化,在利用sigmoid激活函数变换得到。
- C5是卷积层包含120个特征图,是由120个5x5的卷积核对S2进行卷积得到。
- F6是包含84个神经元的全连接层,采用双曲正切激活函数。
注意事项
通过图片可以看到,LeNet的输入是32x32大小的图片,本文使用的手写数字识别数据集是mnist。图片大小为28x28。所以需要对数据集边界补充0。通过一下函数补充
x = ZeroPadding2D(((4, 0), (4, 0)))(img_input)
Keras搭建LeNet
我是根据keras中搭建VGG16为参考编写的。
import keras.losses
from keras.utils import layer_utils
from sklearn.model_selection import train_test_split
from tensorflow.python.keras import backend
from tensorflow.keras import layers
from tensorflow.python.keras.engine import training
import matplotlib.pyplot as plt
import tensorflow as tf
import pandas as pd
from tensorflow.keras.layers import ZeroPadding2D
def letNet5(input_shape=(28, 28, 1), input_tensor=None, classes=10):
if input_tensor is None:
img_input = layers.Input(shape=input_shape)
else:
if not backend.is_keras_tensor(input_tensor):
img_input = layers.Input(tensor=input_tensor, shape=input_shape)
else:
img_input = input_tensor
x = ZeroPadding2D(((4, 0), (4, 0)))(img_input) #填充图片
x = layers.Conv2D(6, (5, 5), strides=1, padding='valid', name='block1_conv1')(x)
x = layers.AveragePooling2D((2, 2), (2, 2), name='block1_pool')(x)
x=layers.Activation('sigmoid')(x)
x = layers.Conv2D(16, (5, 5), strides=1, padding=<