使用MLP多层感知器模型训练mnist数据集

  • A+
所属分类:安全闲碎

使用MLP多层感知器模型训练mnist数据集


修改mnist数据集从本地导入


找一下 mnist.py,在我这里就这俩,第二个就是


使用MLP多层感知器模型训练mnist数据集

找东西用的软件叫:listary


把原来的 path 改为本地下载的路径


使用MLP多层感知器模型训练mnist数据集


mnist数据集介绍


mnist 数据集分两部分:训练集、测试集

每集又分为:特征、标签,特征就是拿来训练和预测的数据,标签就是答案


使用 mnist.load_data() 导入数据集,可以给数据起个名字

(train_image,train_label),(test_image,test_label) = mnist.load_data()


这样,train_image 就表示训练数据,通过 print 可以看出,训练数据一共有 60000 个


使用MLP多层感知器模型训练mnist数据集


可以使用 train_image[0] 来查看训练数据中的第一个,这是像素值,因为是灰度图片,所以不是 r,g,b 那样三个值,只有一个


使用MLP多层感知器模型训练mnist数据集


可以编写一个函数,来查看图片

import matplotlib.pyplot as plt
def show_image(image):
    plt.imshow(image,cmap='gray')#这表示是灰色的图片
    plt.show()

使用MLP多层感知器模型训练mnist数据集


查看数据信息

print("训练图片样式",train_image.shape)
print("训练图片标签",train_label.shape)

根据打印结果看,有 60000 张图片,每一张都是 28*28 像素的


使用MLP多层感知器模型训练mnist数据集


MLP多层感知器模型


使用MLP多层感知器模型训练mnist数据集


它是一种全连接的模型,上一层任何一个神经元与下一层的所有神经元都有连接


可以看一下 3Blue1Brown 的介绍


数据预处理


现在的数据没法加载到模型中,因为输入层传入的数据只能是一维的那种数组数据,所以需要对数据进行处理

首先转成一维的并且改为浮点型

train_image_matric = train_image.reshape(60000784).astype(float)
test_image_matric = test_image.reshape(10000784).astype(float)


使用MLP多层感知器模型训练mnist数据集


然后标准化,去除量纲,让数据落在 0-1 之间,直接除以 255,变成都是零点几的数:

train_image_normalize = train_image_matric / 255
test_image_normalize = test_image_matric / 255

把标签改为一位有效编码(独热编码):通过使用 N 个状态寄存器来对 N 个状态进行编码

因为我们仅仅是识别数字,直接用 10 个 0 和 1 组成的编码来判断是十种中的哪一种就可以

0:1000000000

1:0100000000

2:0010000000

......

train_label_onehotencoding = np_utils.to_categorical(train_label)
test_label_onehotencoding = np_utils.to_categorical(test_label)

建立模型


做完上面那些数据的处理就可以开始建立模型

from keras.models import Sequential
from keras.layers import Dense
model = Sequential()

添加输入层与隐藏层之间的关系


units = 256 表示隐藏层有 256 个神经单元

input_dim=784 表示输入层有 784 个神经单元

kernel_initializer='normal' 表示采用正态分布的方式产生权重和偏差

activation='relu' 表示使用 relu 作为激活函数

model.add(Dense(units = 256, input_dim=784, kernel_initializer='normal', activation='relu'))


前两个不需要啥理解,关于权重与偏差是干啥的,看 3Blue1Brown 的那个视频大概 8:40 开始有解释,这里通过截图来简单说一下,假设我们希望某一个单元的作用是:识别是不是一个小横杠


使用MLP多层感知器模型训练mnist数据集


设绿色为正,红色为负,作为权重


使用MLP多层感知器模型训练mnist数据集


他俩叠加在一起,拿到每个像素的加权值,加在一起是加权和


使用MLP多层感知器模型训练mnist数据集


但不是所有情况都合适,我们想要的是一个横杠,只有加权和大于一个数的时候才算,这个数叫偏差,比如是 10,那就拿加权和减去 10 看看得出来的数是不是大于 0,如果大于 0 那表示,确实是有这么一个横杠


我们采用 relu 这个激活函数,只有当大于 0 的时候才有值,对应上面的例子就是只有当 加权和 - 10 > 0 的时候才激活


使用MLP多层感知器模型训练mnist数据集


添加隐藏层与输出层之间的关系


激活函数 softmax 让每个神经单元都会计算出当前样本属于本类的概率

model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))


查看当前神经网络模型,每一层神经单元的关联数:上一层神经单元个数*本层神经单元个数+本层神经单元个数200960 = 784*256+256


使用MLP多层感知器模型训练mnist数据集


配置训练模型


loss='categorical_crossentropy' 设置损失函数,预测值与真实值之间的误差称为:损失,用于计算损失的函数称为损失函数,通过损失函数来判断模型的好坏

optimizer='adam' 设置优化器

metrics=['accuracy'] 目的是提高准确度

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])


训练模型


train_history = model.fit(train_image_normalize, train_label_onehotencoding, validation_split=0.2, epochs=10, batch_size=200, verbose=2)
#train_image_normalize   训练的数据
#train_label_onehotencoding   训练的标签
#validation_split=0.2   取一定比例用来验证
#epochs=10   训练次数
#batch_size=200   每次训练取出多少数据用于训练
#verbose=2    显示训练过程


其中,val_loss 跟 val_accuracy 是验证损失和验证准确率


使用MLP多层感知器模型训练mnist数据集


训练过程中训练相关的数据都记录在了 train_history 中,可以使用 train_history.history 来查看

print(train_history.history['accuracy'])#打印精确度历史
print(train_history.history['val_accuracy'])#打印验证精确度历史
print(train_history.history['loss'])#打印损失历史
print(train_history.history['val_loss'])#打印验证损失历史


借助 matplotlib 展示准确率


import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.plot(train_history.history['accuracy'])
plt.plot(train_history.history['val_accuracy'])
plt.legend(['训练准确率''验证准确率'], loc = 'upper left')
plt.title("训练历史")
plt.xlabel('训练次数')
plt.ylabel('准确率')
plt.show()

使用MLP多层感知器模型训练mnist数据集


使用MLP多层感知器模型训练mnist数据集


验证模型准确率


之前说过 mnist 包含了 10000 个用来测试的数据,接下来用这些数据验证模型准确率

model.evaluate 的两个参数分别是测试用的图片跟标签(经过预处理)

scores = model.evaluate(test_image_normalize, test_label_onehotencoding)
print(scores)

可以看到,我们训练后的模型准确率是 0.9775


使用MLP多层感知器模型训练mnist数据集


预测图片

from PIL import Image
img = Image.open('9.bmp')#打开图片
number_data = img.getdata()#获取图片的数据
number_data_array = np.array(number_data)#把数据转换为数组
number_data_array = number_data_array.reshape(1,784).astype(float)#数组转换为一维的
number_data_normalize = number_data_array / 255    #标准化
prediction = model.predict(number_data_normalize)  #带入模型进行预测
print(prediction)
np.max(prediction)
np.argmax(prediction)


使用MLP多层感知器模型训练mnist数据集


可以看到可能性最大的是最后一个,即数字 9,可能性为:0.96087...

可以用 np.argmax() 查看最大可能性的那个是谁


导出模型


model.save('number_model.h5')


提高精度


增加神经单元个数、增加训练次数等

增加隐藏层,输入来自上层可以直接去掉

model.add(Dense(units = 256, kernel_initializer='normal', activation='relu'))


解决过度拟合


值得注意的是随着训练次数的增加训练准确率很高了,但是验证准确率却越来越平,上不去了


使用MLP多层感知器模型训练mnist数据集


为了解决这个问题,有一个简单粗暴的方法 Dropout,每次训练都随机忽略一部分神经单元

要先:from keras.layers import Dropout

然后在每层之间添加一个:model.add(Dropout(0.5))


使用MLP多层感知器模型训练mnist数据集


效果不错!

本文始发于微信公众号(陈冠男的游戏人生):使用MLP多层感知器模型训练mnist数据集

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: