使用keras对mnist手写数据集进行训练

本章为学习笔记,并不是教程,如有错误,大家可以留言告诉我
上一章讲解了如何安装keras,现在我们开始上手对mnist数据集进行训练,并且对比两次训练情况来验证dropout的减少过拟合的作用。

废话少说先把代码贴上来

import numpy as np
import pandas as pd
from keras.utils import np_utils
import matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout

# 获取mnist数据
(x_train_image, y_train_label), (x_test_image, y_test_label) = mnist.load_data()

# 对图像进行预处理
# 将图像转化为一维数组
x_Test = x_test_image.reshape(10000, 784).astype('float32')
x_Train = x_train_image.reshape(60000, 784).astype('float32')

# 将灰度控制在(0-1)的范围
x_Train_normalize = x_Train / 255
x_Test_normalize = x_Test / 255

# 将标签转化为onehot形式
y_Train_OneHot = np_utils.to_categorical(y_train_label)
y_Test_OneHot = np_utils.to_categorical(y_test_label)



# 显示图像和预测结果
def plot_image_prediction(images, labels, prediction, idx, num = 25):
    fig = plt.gcf()
    fig.set_size_inches(12, 14)
    if num > 25:
        num = 25
    for i in range(0, num):
        # 将画布分割为 5 * 5 个子图
        ax = plt.subplot(5, 5, 1 + i)
        ax.imshow(images[idx], cmap='binary')
        title = "label=" + str(labels[idx])
        if len(prediction) > 0:
            title = ",prediction=" + str(prediction[idx])
        ax.set_title(title, fontsize=10)
        ax.set_xticks([])
        ax.set_yticks([])
        idx += 1
    plt.show()

# 显示训练结果
def show_history(train_history, train, validation):
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[validation])
    # print(train_history.history[train])
    # print(train_history.history[validation])
    plt.title('Train History')
    plt.ylabel(train)
    plt.xlabel('Epoch')
    plt.legend(['train', 'validation'], loc='upper left')
    plt.show()

# 第二种训练模式
def train1():
    # 采用顺序模型
    model = Sequential()
    # 设置输入层
    model.add(Dense(units=1000, input_dim=784, kernel_initializer='normal', activation='relu'))
    # 添加dropout 方法减少过拟合的情况
    model.add(Dropout(0.5))
    model.add(Dense(units=1000, kernel_initializer='normal', activation='relu'))
    model.add(Dropout(0.5))
    # 设置输出层,有10个输出结果对应手写数字的预测结果(0-9)
    model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))
    # 设置损失函数为交叉熵,利用adam方法对梯度进行操作,目标指数为精确度
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    # split 为验证数据分割比例(用于确定适合的超参数)
    train_history = model.fit(x=x_Train_normalize, y=y_Train_OneHot, validation_split=0.2, epochs=10, batch_size=200, verbose=2)
    # 显示训练结果
    show_history(train_history, 'acc', 'val_acc')
    show_history(train_history, 'loss', 'val_loss')
    # 利用test进行预测
    scores = model.evaluate(x_Test_normalize, y_Test_OneHot)
    print()
    # 输出预测经度
    print(scores[1])

    # 从340号图片开始显示25张图片与其预测结果
    prediction = model.predict_classes(x_Test)
    plot_image_prediction(x_test_image, y_test_label, prediction, idx=340)

    # 显示混淆矩阵
    crossTable = pd.crosstab(y_test_label, prediction, rownames=['label'], colnames=['predict'])
    print(crossTable)

# 第一种训练模式
def train():
    # 采用顺序模型
    model = Sequential()
    # 设置输入层
    model.add(Dense(units=256, input_dim=784, kernel_initializer='normal', activation='relu'))
    # 设置输出层,有10个输出结果对应手写数字的预测结果(0-9)
    model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))
    # 设置损失函数为交叉熵,利用adam方法对梯度进行操作,目标指数为精确度
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    # split 为验证数据分割比例(用于确定适合的超参数)
    # split 为验证数据分割比例(用于确定适合的超参数)
    train_history = model.fit(x=x_Train_normalize, y=y_Train_OneHot, validation_split=0.2, epochs=10, batch_size=200,
                              verbose=2)
    # 显示训练结果
    show_history(train_history, 'acc', 'val_acc')
    show_history(train_history, 'loss', 'val_loss')
    # 利用test进行预测
    scores = model.evaluate(x_Test_normalize, y_Test_OneHot)
    print()
    # 输出预测经度
    print(scores[1])

    # 从340号图片开始显示25张图片与其预测结果
    prediction = model.predict_classes(x_Test)
    plot_image_prediction(x_test_image, y_test_label, prediction, idx=340)

    # 显示混淆矩阵
    crossTable = pd.crosstab(y_test_label, prediction, rownames=['label'], colnames=['predict'])
    print(crossTable)

train()
train1()

上面的代码这里不再过多解释(可以看注解),我们进行了两次训练,输出训练结果和混淆矩阵,结果如下

1. 第一次训练结果

在这里插入图片描述
可以看到,验证数据和训练数据在不断训练的过程中精度一直在上升,但是需要注意的是,在训练结束后训练数据会略高于验证数据,这样就有了过拟合的嫌疑。
在这里插入图片描述
在这里插入图片描述
可以看到,第一次训练的混淆矩阵如下,test测试精度为0.9783

第二次训练结果

第二次训练我们添加了dropout方法,并且添加了一层隐藏层用于提高精确度,结果如下
在这里插入图片描述我们可以明显看到,添加了dropout的第二次训练,验证数据和训练数据在训练结束后并没有太大区别,即减少了训练数据自己验证的精确度,减少了过拟合的情况
在这里插入图片描述
由于添加了一层隐藏层,我们的预测进度也相对提高了

在这里插入图片描述
输出一部分识别结果,如图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值