1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 4. 使用Keras-神经网络来进行MNIST手写数字分类

4. 使用Keras-神经网络来进行MNIST手写数字分类

时间:2024-03-17 16:30:20

相关推荐

4. 使用Keras-神经网络来进行MNIST手写数字分类

程序

导入库

import numpy as npimport kerasfrom keras.datasets import mnist # mnist数据集from keras.utils import np_utils # kerass提供的工具包from keras.models import Sequentialfrom keras.layers import Dense,Activationfrom keras.optimizers import SGD

加载数据集

程序会去指定目录下(默认是: .\keras\examples) 查看是否有mnist.npz数据集。如果没有,则去 /img-datasets/mnist.npz 进行下载的。不过目前好像要用梯子。所以可以参考以下博客,他们提供了百度网盘链接供下载。参考1、参考2

# 导入数据集# dataset_path = 'C:\Users\Administrator\.keras\datasets\mnist.npz'# (x_train, y_train), (x_test, y_test) = mnist.load_data(path=dataset) # 不指定路径,则默认联网下载到userhome\.keras\datasets\mnist.npz(x_train, y_train), (x_test, y_test) = mnist.load_data()print('x_train:',x_train.shape) # (60000, 28, 28)print('y_train:',y_train.shape) # (60000,)print('x_test:',x_test.shape) # (10000, 28, 28)print('y_test:',y_test.shape) # (10000,)

数据预处理

# 数据集预处理(不要多次运行)# 将x_train(6000, 28, 28)->(6000, 784)->归一化x_train = x_train.reshape(x_train.shape[0], -1)/255.0x_test = x_test.reshape(x_test.shape[0], -1)/255.0print('x_train:',x_train.shape) # (60000, 784)# 将label转成 one-hot 格式(代码不能多次执行,否则维数为增加)y_train = np_utils.to_categorical(y_train, num_classes=10)y_test = np_utils.to_categorical(y_test, num_classes=10)print('y_shape:',y_train.shape) # (60000, 10)

建立模型+训练模型

在compile时加入metrics = ['accuracy']来计算训练过程中的准确率。

使用model.fit来训练模型。

# 建立模型model = Sequential([Dense(units=10, input_dim=784, activation='softmax') # softmax将输出转成概率])# 定义优化器sgd = SGD(lr=0.2)# 定义优化器,loss function,训练过程中计算准确率pile(optimizer = sgd,loss = 'mse',metrics = ['accuracy'],)# 训练模型(与以前的for语句写的循环训练模型代码等价)model.fit(x_train, y_train, batch_size=32, epochs=10) # 一次训练32张图片,一个周期要训练60000/32次,共训练10个周期# 评估模型(用测试集测试)loss, accuracy = model.evaluate(x_test, y_test)print("loss: ", loss)print("accuracy: ", accuracy)

由于模型的约束,识别率只能达到91%左右。

优化一:损失函数:使用交叉熵替代均方差

loss = 'mse',替换成loss='categorical_crossentropy',

model = Sequential([Dense(units=10, input_dim=784,bias_initializer='one', activation='softmax')])sgd = SGD(lr=0.2)pile(optimizer=sgd, loss='categorical_crossentropy',metrics=['accuracy'])model.fit(x_train, y_train, batch_size=32, epochs=10)loss,accuracy = model.evaluate(x_test,y_test)print('\ntest loss',loss)print('accuracy',accuracy)

优点:

迭代速度快

精确度提高

优化二:添加隐藏层(提高模型的复杂性,但容易过拟合),Dropout(预防过拟合)

只添加隐藏层:

# 创建模型(添加隐藏层,增加网络模型的复杂度)model = Sequential([Dense(units=200,input_dim=784,bias_initializer='one',activation='tanh'),Dense(units=100,bias_initializer='one',activation='tanh'), #加入中间隐藏层Dense(units=10,bias_initializer='one',activation='softmax') # 最后输出层])# 定义优化器sgd = SGD(lr=0.2)# 定义优化器,loss function,训练过程中计算准确率pile(optimizer = sgd,loss = 'categorical_crossentropy',metrics=['accuracy'],)# 训练模型model.fit(x_train,y_train,batch_size=32,epochs=10)# 评估模型(测试集)loss,accuracy = model.evaluate(x_test,y_test)print('\ntest loss',loss)print('test accuracy',accuracy)# 评估模型(训练集)loss,accuracy = model.evaluate(x_train,y_train)print('train loss',loss)print('train accuracy',accuracy)

可以看到模型在训练集上表现极好,测试集上略差。表示模型存在过拟合现象(所以需要使用dropout)

添加隐藏层+Dropout层(需要导入库:from keras.layers import Dense,Dropout)

# 创建模型(添加隐藏层,增加网络模型的复杂度)model = Sequential([Dense(units=200,input_dim=784,bias_initializer='one',activation='tanh'),Dropout(0.4),Dense(units=100,bias_initializer='one',activation='tanh'),Dropout(0.4),Dense(units=10,bias_initializer='one',activation='softmax')])# 定义优化器sgd = SGD(lr=0.2)# 定义优化器,loss function,训练过程中计算准确率pile(optimizer = sgd,loss = 'categorical_crossentropy',metrics=['accuracy'],)# 训练模型model.fit(x_train,y_train,batch_size=32,epochs=10)# 评估模型(测试集)loss,accuracy = model.evaluate(x_test,y_test)print('\ntest loss',loss)print('test accuracy',accuracy)# 评估模型(训练集)loss,accuracy = model.evaluate(x_train,y_train)print('train loss',loss)print('train accuracy',accuracy)

精确度下降是因为网络节点不再全连接的了,而是会忽略一半的特征检测器(让一半的隐层节点值为0),具体可以参考:神经网络之dropout层

还有一点就是,可以看到模型在训练集上的预测结果和测试集上的结果相差不大了,即一定程度上避免了过拟合现象

优化三:添加正则化项

导入库:from keras.regularizers import l2# 引入 L2 正则项

正则化器允许在优化过程中对层的参数或层的激活情况进行惩罚。 网络优化的损失函数也包括这些惩罚项。

# 创建模型model = Sequential([# 添加了正则化项的模型Dense(units=200,input_dim=784,bias_initializer='one',activation='tanh',kernel_regularizer=l2(0.0003)),Dense(units=100,bias_initializer='one',activation='tanh',kernel_regularizer=l2(0.0003)),Dense(units=10,bias_initializer='one',activation='softmax',kernel_regularizer=l2(0.0003))])# 定义优化器sgd = SGD(lr=0.2)# 定义优化器,loss function,训练过程中计算准确率pile(optimizer = sgd,loss = 'categorical_crossentropy',metrics=['accuracy'],)# 训练模型model.fit(x_train,y_train,batch_size=32,epochs=10)# 评估模型loss,accuracy = model.evaluate(x_test,y_test)print('\ntest loss',loss)print('test accuracy',accuracy)loss,accuracy = model.evaluate(x_train,y_train)print('train loss',loss)print('train accuracy',accuracy)

可以看到过拟合现象也不是特别严重,正则化项的应用要看具体情况而定

优化四:优化器的应用

引入库:from keras.optimizers import SGD,Adam

大多数情况下:adam比sgd效果要比较好,且优化速度比较快

下面程序在使用交叉熵后的代码上进行修改(使用adam替换sgd)的:

# 创建模型,输入784个神经元,输出10个神经元model = Sequential([Dense(units=10,input_dim=784,bias_initializer='one',activation='softmax')])# 定义优化器sgd = SGD(lr=0.2)adam = Adam(lr=0.001) # 定义adam优化器# 定义优化器,loss function,训练过程中计算准确率pile(optimizer = adam, # 使用Adam优化器loss = 'categorical_crossentropy',metrics=['accuracy'],)# 训练模型model.fit(x_train,y_train,batch_size=32,epochs=10)# 评估模型loss,accuracy = model.evaluate(x_test,y_test)print('\ntest loss',loss)print('accuracy',accuracy)

其他优化。。。。。。

参考:

视频: 覃秉丰老师的“Keras入门”:http://www.ai-/course/32

博客参考:/XUEYEYU/tag/keras%E5%AD%A6%E4%B9%A0/

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。