机器学习入门之:keras重写手写数字识别

1. 导入模块

import numpy as np					# 科学的矩阵运算库
import cv2							# 进行图片可视化的库
import matplotlib.pyplot as plt		# 进行图片可视化的库
from keras import layers			# 构建神经网络的各种层
from keras import models			# 负责将各个神经网络层进行链接形成模型
from keras.utils import to_categorical	# 负责将特征编码成独热码

2. 读取数据

由于我这边的数据是直接从网络上下载的 mnist 数据集,所以我写的代码是读取的本地的 mnist.npz 文件,如果你直接从网络上加载或者是直接使用 tensorflow 库中自带的 mnist 数据集,你可以自己去找一些别的教程

这里附上 mnist.npz 下载的网址,大家可以直接下载~
https://s3.amazonaws.com/img-datasets/mnist.npz

data = np.load('mnist.npz') 
print(data.files)

x_test = data['x_test']
x_train = data['x_train']
y_train = data['y_train']
y_test = data['y_test']

在这里插入图片描述

numpy这个工具包为我们提供了很好的读写数据支持,所以直接用 numpy 读取 npz 文件即可。读完了之后可以用 .files 来看一下这写数据中文件的分类,可以看到这些数据分为四个部分 ;我们使用四个变量对这些数据进行提取解包。

3. 数据集可视化一下

这个时候就可以对这些解包的数据打印出来看一下他们的结构

print(x_test)

在这里插入图片描述

也可以看一下这些数据的结构和维度

print(x_train.shape)
print(x_test.shape)
print(y_train.shape)
print(y_test.shape)

在这里插入图片描述

看来这个测试集早就分好了是 10000 张图片,训练集是 60000 张图片每个图片是 28 * 28 大小,图片都是灰度图;下面让我们把测试集的第一张图片拿出来看看

print(x_test[0])

在这里插入图片描述

没有展示完全,但是可以看出和 x_test.shape 描述的信息是相符的;如果你觉得不够直观的话,我们可以用 matplotlib 或者 从cv2 等库把这个图片展示出来

test_img = x_test[0]
cv2.imwrite('example.jpg',test_img)			# 把这张样图保存
cv2.imshow('example',test_img)
cv2.waitKey(0)								

在这里插入图片描述

也可以用 matplotlib 库,同时展示多张测试集的图片

# 打印前九个例子
for i in range(1,10):
    sample = x_train[i]
    plt.subplot(3,3,i)
    plt.imshow(sample)
plt.show()

在这里插入图片描述

想一下,为什么这里的图不是灰度图?对这个问题有疑问的可以参考我的另外一篇博客:
Opencv学习之:解决用 plt 显示 opencv 读取的图片时,有色差问题

4. 搭建模型

network = models.Sequential()				
network.add(layers.Dense(512 ,activation='relu', input_shape=(28*28,)))  
network.add(layers.Dense(10,activation='softmax')) 
network.compile(metrics=['accuracy', 'mse'],optimizer='Adam',loss='categorical_crossentropy')  
  • 建立一个线性模型,从前到后的 sequential模型
  • 添加一个隐藏层,有 512 个神经元,激活函数是 relu,输入的维度是一个含有 28 * 28 = 784 个数据的一维数组;注意维度不是 1行 784 列 (这是个二维概念),注意这个概念
  • 添加一个输出层,有 10 个神经元,激活函数是 softmax
  • 将已有的层进行串联,建立模型,模型的整体优化器是 adam,损失是 交叉熵,想要得到的结果是 accuracy(精度) 和 mse(均方误差)

5. 把数据处理后喂给模型

5.1 数据处理

input_data = x_train.reshape((60000, 28*28))

从第三步数据集可视化里我们知道 无论是训练的数据还是测试的数据,维度都是三维,训练数据是 (60000, 28, 28) 测试集是 (10000, 28, 28),我们又知道输入神经网络的维度是 (784, ) 也就是说我们也要将训练集的每张图片在输入神经网络之前变成一维的(784, ) 所以,这里我们将训练集进行 reshape 操作

input_data = x_train.reshape((60000, 28*28))

由此,这个训练集就变成了 60000 张图片,每个图片的维度都是 一维的 (784, )

同时我们也需要对输入的 label 进行处理;也就是 y_train 的数据

input_label = to_categorical(y_train)

我们先来看一下如果不处理输入的标签,它原本是什么样子

print(y_train)

在这里插入图片描述

不处理的话,它是一个 (60000, ) 的一维数组,每一个数据代表训练集的一幅图的标签;那么处理后的情况我们也来看一下:

dealed_y_train = to_categorical(y_train)
np.savetxt('dealed_y_train.txt',dealed_y_train,fmt='%d')

在这里插入图片描述

print(dealed_y_train.shape)

在这里插入图片描述

可以看出,当进行独热编码之后,整个标签的维度变成了 (60000,10)60000 个标签,每个标签用 10 个数字来表示;为什么要这么做呢?因为我们在做分类的时候有 10 类,所以通热编码的方式方便最后的输出层进行训练,每次训练之后 softmax 函数都会给出被训练图片的概率分布,比如:
在这里插入图片描述
这些概率分布会拿去和独热编码的 label 进行比对,然后进行损失计算并通过反向传播进行迭代和更新神经网络的参数,来得到最好结果;所以用于分类的标签需要使用独热编码。
具体损失函数是如何通过最后的概率分布何 独热编码的标签来进行计算的,有兴趣的可以参考这篇文章 深层神经网络——分类、回归的损失函数 这里截取部分:
在这里插入图片描述

以上是在输入网络前的数据 x_train, y_train 进行的一些处理,同样的,当我们训练好模型之后,也需要对测试的数据 x_test, y_test 进行同样的处理:

test_data = x_test.reshape(10000,28*28)
test_label = to_categorical(y_test)

接下来要进行的就是将训练数据和标签投喂到神经网络模型中,然后去训练模型

5.2 数据投入模型训练

network.fit(input_data,input_label,epochs=10,batch_size=128)

一行代码解决,这 60000 个训练数据,分为 128 投喂到模型中进行训练作为 1 个 epoch,一共做 10 次 epoch 保证数据集中的数据被充分的利用。

6. 模型的评估

test_loss, test_acc = network.evaluate(x_test,y_test)
print(test_loss,test_acc)

最后用 network.evaluate 把测试的数据和标签扔进模型,得到损失和精度。

7. 完整代码

这里拿掉了所有中途展示可视化的代码,比如输出数据的维度、展示图片等,只保留了从加载数据到处理数据到训练模型的主干代码,仅供参考:

import numpy as np
from keras import layers
from keras import models
from keras.utils import to_categorical

data = np.load('mnist.npz')

# 解包
x_test = data['x_test']
x_train = data['x_train']
y_train = data['y_train']
y_test = data['y_test']


network = models.Sequential()
network.add(layers.Dense(512 ,activation='relu', input_shape=(28*28,)))
network.add(layers.Dense(10,activation='softmax'))
network.compile(metrics=['accuracy', 'mse'],optimizer='Adam',loss='categorical_crossentropy')


input_data = x_train.reshape((60000, 28*28))
input_label = to_categorical(y_train)
test_data = x_test.reshape(10000,28*28)
test_label = to_categorical(y_test)


network.fit(input_data,input_label,epochs=10,batch_size=128)

test_loss, test_acc = network.evaluate(x_test,y_test)
print(test_loss,test_acc)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暖仔会飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值