首先介绍训练集,因为我们需要先了解训练集的结构。MNIST手写体识别数据库的官方网站是http://yann.lecun.com/exdb/mnist/,其风格略显过时。
这个图展示了全球各地不同方法对手写体识别的准确率汇总。可以看出,使用Logistic回归(线性分类器)的效果最差,因此我们后续将采用卷积神经网络(CNN)进行识别。值得注意的是,当我们使用TensorFlow时,无需自行解析数据集。
接下来介绍机器学习的开发环境。目前主流的开发环境是Python,但并不是直接用Python编写代码。数据科学家常用的开发环境是Anaconda,它集成了Python和R开发环境。
从Anaconda官网(https://www.anaconda.com/distribution/)下载安装包,根据操作系统选择合适的版本。安装过程主要是下一步、下一步,因此不再赘述。
安装完成后,打开Anaconda Prompt。虽然Anaconda也有图形界面Anaconda Navigator,但我们主要使用控制台,因为它更为便捷。
在控制台输入以下命令:
```bash
conda create -n tensorflow-cpu tensorflow
conda create -n tensorflow-gpu tensorflow-gpu ```
完成环境搭建后,激活相应的环境:
```bash
conda activate tensorflow-cpu
conda activate tensorflow-gpu ```
这使得我们可以根据需要在CPU和GPU环境中切换。接着,启动代码编辑器:
```bash
pip install numpy scipy sklearn pandas pillow matplotlib keras onnx jupyter -i https://pypi.tuna.tsinghua.edu.cn/simple
jupyter notebook ```
这样就会自动打开浏览器,进入开发环境,创建一个新的notebook。
首先导入所需的库函数:
```python
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np np.set_printoptions(suppress=True)
import matplotlib.pyplot as plt %matplotlib inline ```
这些代码导入后,就可以开始操作数据集了。
在代码块输入以下命令:
python
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
这样会自动下载数据集。如果在国内下载速度较慢,可以从其他地址下载MNIST数据集,然后解压到启动Jupyter Notebook的位置,例如C:/Users/用户名/。
我们将数据集分为训练集和测试集,训练集用于训练模型,测试集用于检测模型的准确性:
```python Xtrain = mnist.train.images ytrain = mnist.train.labels Xtest = mnist.test.images ytest = mnist.test.labels
Xtrain = Xtrain.reshape([-1, 28, 28, 1]) Xtest = Xtest.reshape([-1, 28, 28, 1]) ```
查看训练集中的第一张图片:
python
plt.imshow(X_train[0].reshape((28, 28)), cmap='gray')
查看第二张图片:
python
plt.imshow(X_train[1].reshape((28, 28)), cmap='gray')
现在可以开始构建模型了。
首先导入Keras库:
python
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Dropout
from keras.layers import Flatten
接下来构建模型:
```python def build_classifier(): classifier = Sequential()
# 第一层 Conv2D,激活函数Relu
classifier.add(Conv2D(filters=2, kernel_size=3, strides=1, padding="SAME", activation="relu", input_shape=(28, 28, 1)))
# 第二层 MaxPooling
classifier.add(MaxPooling2D(pool_size=(2, 2), padding='SAME'))
# 第三层 Dropout
classifier.add(Dropout(0.5))
# 第四层 Conv2D
classifier.add(Conv2D(filters=2, kernel_size=3, strides=1, padding="SAME", activation="relu"))
# 第五层 MaxPooling
classifier.add(MaxPooling2D(pool_size=(2, 2), padding='SAME'))
# 第六层 Dropout
classifier.add(Dropout(0.5))
# 第七层 Flatten
classifier.add(Flatten())
# 第八层 Dense
classifier.add(Dense(kernel_initializer="uniform", units=4))
# 第九层 Softmax
classifier.add(Dense(kernel_initializer="uniform", units=10, activation="softmax"))
# 使用Adam优化器
classifier.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
return classifier
```
查看模型结构:
python
classifier = build_classifier()
classifier.summary()
可以看到模型结构与之前的描述一致。
接下来开始训练模型:
```python from keras.callbacks import ModelCheckpoint checkpointer = ModelCheckpoint(filepath='minions.hdf5', verbose=1, savebestonly=True, monitor='val_loss', mode='min')
history = classifier.fit(Xtrain, ytrain, epochs=50, batchsize=50, validationdata=(Xtest, ytest), callbacks=[checkpointer]) ```
训练过程可以通过以下函数展示:
```python def plothistory(history): SMALLSIZE = 20 MEDIUMSIZE = 22 BIGGERSIZE = 24
plt.rc('font', size=SMALL_SIZE)
plt.rc('axes', titlesize=SMALL_SIZE)
plt.rc('axes', labelsize=MEDIUM_SIZE)
plt.rc('xtick', labelsize=SMALL_SIZE)
plt.rc('ytick', labelsize=SMALL_SIZE)
plt.rc('legend', fontsize=SMALL_SIZE)
plt.rc('figure', titlesize=BIGGER_SIZE)
fig = plt.figure()
fig.set_size_inches(15, 10)
plt.plot(history['loss'])
plt.plot(history['val_loss'])
plt.title('Model Loss')
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
```
用图片显示训练过程:
python
plot_history(history.history)
可以看到,训练过程中损失值逐渐下降,模型在测试集上的表现甚至优于训练集。尽管模型精度只有60%多一点,但可以尝试优化以提高性能。
可以将模型保存为Keras原生格式:
python
classifier.save("mnist.h5")
为了在STM32下使用,可以将模型转换为ONNX格式:
```python import onnx import keras2onnx
onnxmodel = keras2onnx.convertkeras(classifier, 'mnist') onnx.savemodel(onnxmodel, 'mnist.onnx') ```
这样就在默认目录下(例如C:/Users/用户名)生成了mnist.h5
和mnist.onnx
两个文件,即训练好的模型。
RT-Thread技能认证考试已经获得了社区开发者和产业界的广泛支持。如果您希望提升自己的技能、寻找更好的机会或深化对RT-Thread的理解,欢迎咨询或报名。
技能认证官网链接:https://www.rt-thread.org/page/rac.html(请在外部浏览器打开)
#题外话
如果您喜欢RT-Thread,请别忘了在GitHub上给我们一个星标,您的支持对我们非常重要!链接地址:https://github.com/RT-Thread/rt-thread
您可以添加微信18917005679为好友,注明“公司+姓名”,拉进RT-Thread官方微信群。
RT-Thread致力于简化物联网终端开发,最大化芯片价值。采用Apache 2.0协议,可以在商业产品中免费使用,无需公开源码,没有潜在商业风险。