概述
程序
- 导入库
import numpy as np
import keras
from keras.datasets import mnist # mnist数据集
from keras.utils import np_utils # kerass提供的工具包
from keras.models import Sequential
from keras.layers import Dense,Activation
from keras.optimizers import SGD
- 加载数据集
程序会去指定目录下(默认是: .kerasexamples) 查看是否有mnist.npz数据集。如果没有,则去 https://s3.amazonaws.com/img-datasets/mnist.npz 进行下载的。不过目前好像要用梯子。所以可以参考以下博客,他们提供了百度网盘链接供下载。参考1、参考2
# 导入数据集
# dataset_path = 'C:UsersAdministrator.kerasdatasetsmnist.npz'
# (x_train, y_train), (x_test, y_test) = mnist.load_data(path=dataset) # 不指定路径,则默认联网下载到userhome.kerasdatasetsmnist.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.0
x_test = x_test.reshape(x_test.shape[0], -1)/255.0
print('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,训练过程中计算准确率
model.compile(
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)
model.compile(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,训练过程中计算准确率
model.compile(
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,训练过程中计算准确率
model.compile(
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,训练过程中计算准确率
model.compile(
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,训练过程中计算准确率
model.compile(
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-xlab.com/course/32
博客参考:https://www.cnblogs.com/XUEYEYU/tag/keras%E5%AD%A6%E4%B9%A0/
最后
以上就是沉默小熊猫为你收集整理的4. 使用Keras-神经网络来进行MNIST手写数字分类的全部内容,希望文章能够帮你解决4. 使用Keras-神经网络来进行MNIST手写数字分类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复