前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用MLP多层感知器模型训练mnist数据集

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

作者头像
yichen
发布2021-02-15 12:48:37
2.5K0
发布2021-02-15 12:48:37
举报

修改mnist数据集从本地导入

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

找东西用的软件叫:listary

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

mnist数据集介绍

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

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

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

代码语言:javascript
复制
(train_image,train_label),(test_image,test_label) = mnist.load_data()

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

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

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

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

查看数据信息

代码语言:javascript
复制
print("训练图片样式",train_image.shape)
print("训练图片标签",train_label.shape)
代码语言:javascript
复制

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

MLP多层感知器模型

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

可以看一下 3Blue1Brown 的介绍

数据预处理

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

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

代码语言:javascript
复制
train_image_matric = train_image.reshape(60000, 784).astype(float)
test_image_matric = test_image.reshape(10000, 784).astype(float)

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

代码语言:javascript
复制
train_image_normalize = train_image_matric / 255
test_image_normalize = test_image_matric / 255
代码语言:javascript
复制

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

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

0:1000000000

1:0100000000

2:0010000000

......

代码语言:javascript
复制
train_label_onehotencoding = np_utils.to_categorical(train_label)
test_label_onehotencoding = np_utils.to_categorical(test_label)

建立模型

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

代码语言:javascript
复制
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
代码语言:javascript
复制

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

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

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

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

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

代码语言:javascript
复制
model.add(Dense(units = 256, input_dim=784, kernel_initializer='normal', activation='relu'))

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

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

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

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

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

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

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

代码语言:javascript
复制
model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))

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

配置训练模型

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

optimizer='adam' 设置优化器

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

代码语言:javascript
复制
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

训练模型

代码语言:javascript
复制
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 是验证损失和验证准确率

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

代码语言:javascript
复制
print(train_history.history['accuracy'])#打印精确度历史
print(train_history.history['val_accuracy'])#打印验证精确度历史
print(train_history.history['loss'])#打印损失历史
print(train_history.history['val_loss'])#打印验证损失历史
代码语言:javascript
复制

借助 matplotlib 展示准确率

代码语言:javascript
复制
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()
代码语言:javascript
复制

验证模型准确率

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

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

代码语言:javascript
复制
scores = model.evaluate(test_image_normalize, test_label_onehotencoding)
print(scores)
代码语言:javascript
复制

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

预测图片

代码语言:javascript
复制
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)

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

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

导出模型

model.save('number_model.h5')

提高精度

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

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

代码语言:javascript
复制
model.add(Dense(units = 256, kernel_initializer='normal', activation='relu'))

解决过度拟合

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

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

要先:from keras.layers import Dropout

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

效果不错!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陈冠男的游戏人生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 修改mnist数据集从本地导入
  • mnist数据集介绍
  • MLP多层感知器模型
    • 数据预处理
      • 添加输入层与隐藏层之间的关系
        • 添加隐藏层与输出层之间的关系
          • 配置训练模型
            • 借助 matplotlib 展示准确率
              • 验证模型准确率
                • 预测图片
                  • 导出模型
                    • 提高精度
                    相关产品与服务
                    内容识别
                    内容识别(Content Recognition,CR)是腾讯云数据万象推出的对图片内容进行识别、理解的服务,集成腾讯云 AI 的多种强大功能,对存储在腾讯云对象存储 COS 的数据提供图片标签、图片修复、二维码识别、语音识别、质量评估等增值服务。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档