人工智能学习笔记四——手写数字识别

本文将用卷积神经网络模型,对手写数字集minist进行分类识别,用的框架是keras。

MNIST是一个手写体数字的图片数据集,该数据集来由美国国家标准与技术研究所发起整理,一共统计了来自250个不同的人手写数字图片,其中50%是高中生,50%来自人口普查局的工作人员。该数据集的收集目的是希望通过算法,实现对手写数字的识别。

训练集一共包含了 60,000 张图像和标签,而测试集一共包含了 10,000 张图像和标签。测试集中前5000个来自最初NIST项目的训练集.,后5000个来自最初NIST项目的测试集。前5000个比后5000个要规整,这是因为前5000个数据来自于美国人口普查局的员工,而后5000个来自于大学生。

该数据集自1998年起,被广泛地应用于机器学习和深度学习领域,用来测试算法的效果,例如线性分类器(Linear Classifiers)、K-近邻算法(K-Nearest Neighbors)、支持向量机(SVMs)、神经网络(Neural Nets)、卷积神经网络(Convolutional nets)等等。

图1(minist部分手写数据集)

而Keras是一个由Python编写的开源人工神经网络库,可以作为Tensorflow、Microsoft-CNTK和Theano的高阶应用程序接口,进行深度学习模型的设计、调试、评估、应用和可视化 。

Keras在代码结构上由面向对象方法编写,完全模块化并具有可扩展性,其运行机制和说明文档有将用户体验和使用难度纳入考虑,并试图简化复杂算法的实现难度。Keras支持现代人工智能领域的主流算法,包括前馈结构和递归结构的神经网络,也可以通过封装参与构建统计学习模型。在硬件和开发环境方面,Keras支持多操作系统下的多GPU并行计算,可以根据后台设置转化为Tensorflow、Microsoft-CNTK等系统下的组件。因而本文用keras做为框架。

由于手写数字的输入集的长宽都是28像素,色彩空间是黑白的,所以不需要太过于复杂的结构。我将输入数据先进行两次卷积操作,卷积核大小为3×3,再进行一次池化操作,然后接着进行两次卷积操作,再进行一次池化操作,随后将数据展平,构造128维度的全连接层,最后输出10维的数组。在整个网络中,除了最后一次外所有层的激活函数都是relu函数,最后一层的激活函数使用的是softmax函数,损失函数用的是crossentropy函数。如图2所示。

图2 卷积神经网络示意图

图3 卷积神经网络示意图

网络构造的代码如下:

#构建卷积神经网络  

def create_model():  

    model = keras.Sequential()  

    model.add(layers.Conv2D(5, (3, 3),activation='relu',input_shape=(28,28,1),padding = 'same'))  

    model.add(layers.Conv2D(5, (3, 3), activation='relu', padding = 'same'))  

    model.add(layers.MaxPooling2D(pool_size = (2,2)))  

    model.add(layers.Conv2D(10, (3, 3), activation='relu', padding = 'same'))  

    model.add(layers.Conv2D(10, (3, 3), activation='relu', padding = 'same'))  

    model.add(layers.MaxPooling2D(pool_size = (2,2)))  

    model.add(layers.Flatten())#将数据压缩成一维数组  

    model.add(layers.Dense(128, activation='relu'))  

model.add(layers.Dense(10, activation='softmax'))  

return model  

经过25个epoch的训练,最后网络的损失值降到了0.0307,准确率达到了0.99。

准确率的训练变化如图4所示,Train表示训练集的准确率变化,Test表示测试集的准确率变化。

损失值的训练变化如图5所示,Train表示训练集的损失值变化,Test表示测试集的损失值变化。

总训练过程的变化如图6所示。

图4模型准确率变化曲线

图5模型损失值变化曲线

图6 训练过程图

完整代码为:

#coding:gbk  

from PIL import Image  

import numpy as np  

from keras import layers  

import keras  

import matplotlib.pyplot as plt  

import glob  

np.set_printoptions(threshold=np.inf)  

wid = 28#定义图片的宽  

hei = 28#定义图片的长  

def process(preimg):#读取图片,将它转化成np.array的格式  

    imge = Image.open(preimg,'r')  

    imge = imge.convert('L')  

    imge = imge.resize((wid,hei))  

    return (np.asarray(imge))  

trainset = []  

trainexpe = []  

testset = []  

testexpe = []  

train_src = glob.glob("train_images//*.jpg")#训练数据

test_src = glob.glob("test_images//*.jpg")#测试数据  

for data in train_src:#数据填充到数组中  

    trainset.append(process(data))  

    datatem = [0] * 10  

    datatem[int(data [-5])] = 1  

    trainexpe.append(datatem)  

for data in test_src:  

    testset.append(process(data))  

    datatem = [0] * 10  

    datatem[int(data [-5])] = 1  

    testexpe.append(datatem)  

trainset = np.array(trainset).reshape((-1,wid,hei,1))  

trainexpe = np.array(trainexpe)  

testset = np.array(testset).reshape((-1,wid,hei,1))  

testexpe = np.array(testexpe)  

def create_model():  

    model = keras.Sequential()  

    model.add(layers.Conv2D(5, (3, 3), activation='relu', input_shape=(wid,hei,1),padding = 'same'))  

    ''''' 

    filters 要去训练多少个卷积核 

    kernel_size: 卷积核大小 

    activation: 非线性化所需要去使用的激活函数 

    input_shape:输入数据的形状 

    padding:same表示填充一圈,valid表示不填充 

    strides表示滑动的步长 

    '''  

    model.add(layers.Conv2D(5, (3, 3), activation='relu', padding = 'same'))#第二层添加的时候就不需要 input_shape 这个参数了,因为默认是去根据上一层输出的形状进行计算。  

    model.add(layers.MaxPooling2D(pool_size = (2,2)))#默认maxpooling大小为(2,2)  

    model.add(layers.Conv2D(10, (3, 3), activation='relu', padding = 'same'))  

    model.add(layers.Conv2D(10, (3, 3), activation='relu', padding = 'same'))  

    model.add(layers.MaxPooling2D(pool_size = (2,2)))  

    #model.summary()#显示model信息  

    model.add(layers.Flatten())#将数据压缩成一维数组  

    model.add(layers.Dense(128, activation='relu'))  

    model.add(layers.Dropout(0.5))  

    model.add(layers.Dense(10, activation='softmax'))  

    return model  

  

model = create_model()#load_model("test.h5")  

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

history = model.fit(trainset,trainexpe,batch_size=60,epochs=25,verbose=2, validation_data=(testset,testexpe))  

  

plt.plot(history.history['accuracy'])  

plt.plot(history.history['val_accuracy'])  

plt.title('Model accuracy')  

plt.ylabel('Accuracy')  

plt.xlabel('Epoch')  

plt.legend(['Train', 'Test'], loc='upper left')  

plt.show()  

# 绘制训练 & 验证的损失值  

plt.plot(history.history['loss'])  

plt.plot(history.history['val_loss'])  

plt.title('Model loss')  

plt.ylabel('Loss')  

plt.xlabel('Epoch')  

plt.legend(['Train', 'Test'], loc='upper left')  

plt.show()  

model.save('test.h5')  

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!感谢提问。下面是有关 K210 学习笔记五中串口通信的一些内容: 在 K210 开发板上,串口是一种常见的通信接口,用于将数据从一个设备传输到另一个设备。串口通信通常使用 UART (Universal Asynchronous Receiver/Transmitter) 协议。 要在 K210 上进行串口通信,首先需要使用两个引脚:一个用于接收数据(RX),一个用于发送数据(TX)。这些引脚可以通过 GPIO 端口与外部设备连接。 在 K210 的开发环境中,可以使用 MaixPy 或者 Kendryte Standalone SDK 进行串口编程。 在 MaixPy 中,可以使用 `uart` 模块来进行串口通信。例如,要初始化一个串口对象并设置波特率为 115200,可以使用以下代码: ```python from machine import UART uart = UART(UART.UART1, 115200) ``` 然后,可以使用 `uart.write()` 函数发送数据,使用 `uart.read()` 函数接收数据。例如: ```python uart.write("Hello, world!\n") data = uart.read(10) ``` 在 Kendryte Standalone SDK 中,可以使用 `uart.h` 头文件中的函数来进行串口通信。例如,要初始化一个串口对象并设置波特率为 115200,可以使用以下代码: ```c #include "uart.h" uart_init(UART_DEVICE_1, 115200); ``` 然后,可以使用 `uart_send_data()` 函数发送数据,使用 `uart_receive_data()` 函数接收数据。例如: ```c uart_send_data(UART_DEVICE_1, "Hello, world!\n", 14); char buffer[10]; uart_receive_data(UART_DEVICE_1, buffer, 10); ``` 以上是关于 K210 学习笔记五中串口通信的简要介绍。如果你有更具体的问题,请随时提问!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值