从代码案例入门keras1:LeNet对手写数字Mnist分类

本文是针对有一定深度学习基础的初学者,通过keras库实现LeNet模型对MNIST手写数字进行分类。首先介绍LeNet论文,接着展示如何加载和预处理MNIST数据,包括将标签转换为one-hot编码。接着构建模型,重点解释Conv2D层的设置,包括数据格式和填充方式。最后,配置损失函数、优化器,并进行训练。完整代码可在GitHub找到,作者将持续更新关于参数调整的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

本系列文章适合有深度学习基础(上过课,看得懂代码,但是想自己上手觉得困难的初学者)

首先上LeNet论文:

===Y. LeCun, L. Bottou, Y. Bengio, and P. Haffner. (1998).
Gradient-based Learning applied to document recognition. 
Proceedings of the IEEE, 86(11), 2278–2324.===========

首先我们从导入数据集观察它可以干什么开始

import keras

from keras.datasets import mnist

print(dir(mnist))

结果显示:

然后我们可以看到我们可以操作的几个基本的功能:'absolute_import', 'division', 'get_file', 'load_data', 'np', 'print_function'

这里我们用得着加载数据:load_data

这个函数的返回值如下:

所以为了好操作 ,我们弄四个数组接住这些数值:

(x_train, y_train), (x_test, y_test)=mnist.load_data()

这时候我们得注意这些数据的形态可以导入numpy(np.shape())查看:

数组名形态
x_train(60000, 28, 28)
y_train(60000, 28, 28)
x_test(10000, 28, 28)
y_test(10000,)

60000张训练数据,28*28的图像,0,1表示像素点,把它想成黑像素和白像素(对这个理解不能的同学可以去搜搜mnist可视化的文章这里就不介绍了)

然后我们可以开始写模型了。

f:id:ohke:20190316135330p:image:w500
网络结构

我们现在的标签是1,2,6,3,5这样的我们需要把它变成onehot模式:

keras有提供好的keras.utils.to_categorical 所以这里就直接用它了,里面有两个参数,一个是导入的label数据,一个是标签的种类总个数。

classNumber=len(set(y_test))
Y_train = keras.utils.to_categorical(y_train,classNumber)
Y_test = keras.utils.to_categorical(y_test ,classNumber)

set是个列表的去重函数,去重后的列表长度就是标签的总数,放进classNumber里。

我们看第一层是二维卷积层,也就是keras的layers里的Conv2D:

keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

这里要注意你的训练数据图像格式是颜色信息在后还是在前data_format='channels_first'还是data_format='channels_last'

 

第一层的input_shape需要指定传进图像的规格(长,宽,颜色通道数)或者(颜色通道数,长,宽):我们取得的数据是(n,28,28)的单色通道数据 所以在最后加一维度比较方便我们把input_shape设置成(28,28,1)这时候我们可能会意识到我们得去调整下我们的训练数据,查看文档官方要求的卷积层输入是(batch_size, rows, cols, channels)或者(batch_size, channels, rows, cols)把大家末尾加一维:

X_train = x_train.reshape(x_train.shape + (1,))

X_test = x_test.reshape(x_test.shape + (1,))

把这个放到标签数据处理的后面,这个时候我们可以看到我们的数据是:

参数名格式
X_train(60000,28,28,1)
X_test(10000,28,28,1)
Y_train(60000,10)
Y_test(10000,10)

 

好的看到第一个傲娇的卷积层的设置需求被吓到去整理训练数据的我们可以开始继续搭建模型啦!!别忘了先告诉keras你要开始搭建模型啦,让他给你一个装模型的通道:


model = Sequential()
然后你就可以搭建你的模型啦!
model.add(Conv2D(6, kernel_size=(5, 5), strides=(1, 1), padding='same', activation='tanh', input_shape=input_shape))
model.add(AveragePooling2D((2, 2), strides=(2, 2)))
model.add(Conv2D(16, kernel_size=(5, 5), strides=(1, 1), padding='valid', activation='tanh'))
model.add(AveragePooling2D((2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(120, activation='tanh'))
model.add(Dense(84, activation='tanh'))
model.add(Dense(classNumber, activation='softmax'))

关于padding是什么 就是,你的图如果不在最外层填上一层0,因为在卷积的时候你设置的strides这些会给整个过程带来影响,推荐一篇博客:https://medium.com/@ayeshmanthaperera/what-is-padding-in-cnns-71b21fb0dd7

然后设置损失函数和optimizer

model.compile(
    loss=keras.losses.categorical_crossentropy,
    optimizer=keras.optimizers.Adam(),
    metrics=['accuracy']
)

然后设定一次训练的批量 batch_size 和训练次数epochs你就可以去fit你的data了:

epochs = 300                                                                                                          
batch_size = 200                                                                                                  
                                                                                                                    
model.fit(x=X_train,y=Y_train, epochs=epochs, batch_size=batch_size, validation_data=(X_test, Y_test), verbose=1)   

总结:

import keras                                                                                                               
                                                                                                                           
from keras.datasets import mnist                                                                                           
from keras import Sequential                                                                                               
from keras.layers import AveragePooling2D                                                                                  
from keras.layers import Conv2D                                                                                            
from keras.layers import Flatten                                                                                           
from keras.layers import Dense                                                                                             
import matplotlib.pyplot as plt                                                                                            
import numpy as np                                                                                                         
                                                                                        
                                                                                                                           
(x_train, y_train), (x_test, y_test)=mnist.load_data()                                                                     
                                                                                                                           
classNumber=len(set(y_test))                                                                                               
Y_train = keras.utils.to_categorical(y_train,classNumber)                                                                  
Y_test = keras.utils.to_categorical(y_test ,classNumber)                                                                   
X_train = x_train.reshape(x_train.shape + (1,))                                                                            
                                                                                                                           
X_test = x_test.reshape(x_test.shape + (1,))                                                                               
input_shape =(28,28,1)                                                                                                     
                                                                                                       
                                                                                                                           
model = Sequential()                                                                                                       
                                                                                                                           
model.add(Conv2D(6, kernel_size=(5, 5), strides=(1, 1), padding='same', activation='tanh', input_shape=input_shape))       
model.add(AveragePooling2D((2, 2), strides=(2, 2)))                                                                        
model.add(Conv2D(16, kernel_size=(5, 5), strides=(1, 1), padding='valid', activation='tanh'))                              
model.add(AveragePooling2D((2, 2), strides=(2, 2)))                                                                        
model.add(Flatten())                                                                                                       
model.add(Dense(120, activation='tanh'))                                                                                   
model.add(Dense(84, activation='tanh'))                                                                                    
model.add(Dense(classNumber, activation='softmax'))                                                                        
                                                                                                                           
model.compile(                                                                                                             
    loss=keras.losses.categorical_crossentropy,                                                                            
    optimizer=keras.optimizers.Adam(),                                                                                     
    metrics=['accuracy']                                                                                                   
)                                                                                                                          
epochs = 300                                                                                                                 
batch_size = 1000                                                                                                          
                                                                                                                           
history=model.fit(x=X_train,y=Y_train, epochs=epochs, batch_size=batch_size, validation_data=(X_test, Y_test), verbose=1)  

Github:https://github.com/timcanby/Kares__StudyNotes/blob/master/20191219.py

抱走代码的同时给小星星的是好少年!!

 

接下来的更新我会详细写改一些什么样的参数会造成怎样的结果~~(全文原创未经允许严谨未注明出处的转载)

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值