Python机器学习实战:手写数字识别项目
在机器学习的世界里,手写数字识别是一个很经典的问题。本文将带领读者使用Python语言实现一个简单的手写数字识别项目,让大家了解机器学习的基本概念并掌握Python语言的运用。
1. 获取数据集
我们的手写数字识别项目需要一个数据集,MNIST就是一个非常经典的手写数字数据集,包含了60,000个训练样本和10,000个测试样本。可以使用TensorFlow库中的`keras.datasets`模块直接获取到这个数据集:
```python
import tensorflow as tf
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
```
其中,`x_train`和`y_train`是训练数据集,`x_test`和`y_test`是测试数据集。每个样本都是一个28x28的灰度图像,像素取值范围为0-255,`y_train`和`y_test`则是每个样本对应的数字标签。
2. 数据预处理
我们需要对数据进行预处理,将像素归一化为0-1之间的小数,以便于机器学习算法处理:
```python
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255
```
同时,我们需要将标签转化为独热编码(One-Hot Encoding)的形式,方便后续的训练和测试:
```python
y_train = tf.keras.utils.to_categorical(y_train, num_classes=10)
y_test = tf.keras.utils.to_categorical(y_test, num_classes=10)
```
3. 构建模型
我们使用卷积神经网络(Convolutional Neural Network,CNN)来进行手写数字识别任务。对于CNN的具体结构和优化算法,本文不做过多介绍。我们使用Keras库来搭建模型:
```python
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
```
其中,第一个卷积层使用32个3x3的滤波器,激活函数为ReLU;接着使用最大池化层(Max Pooling),池化核大小为2x2;然后将特征图展开为一维向量,接上一个全连接层(Dense),神经元数为128,激活函数为ReLU;最后接上输出层,输出10个数字的概率值,因为我们需要对0-9这10个数字进行分类,故神经元数为10,激活函数为Softmax。
4. 训练模型
使用Keras库中的`compile`方法编译模型,指定损失函数(Loss Function)、优化算法(Optimizer)和评估指标(Metrics):
```python
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
```
然后使用`fit`方法训练模型:
```python
model.fit(x_train.reshape(-1, 28, 28, 1), y_train, batch_size=100, epochs=5)
```
我们选择每次训练取100个样本数据,训练5个Epoch(一个Epoch表示将所有训练数据都过一遍),可以看到训练过程的损失函数和准确率:
```
Epoch 1/5
600/600 [==============================] - 21s 34ms/step - loss: 0.2151 - accuracy: 0.9395
Epoch 2/5
600/600 [==============================] - 19s 31ms/step - loss: 0.0705 - accuracy: 0.9785
Epoch 3/5
600/600 [==============================] - 19s 31ms/step - loss: 0.0509 - accuracy: 0.9843
Epoch 4/5
600/600 [==============================] - 19s 31ms/step - loss: 0.0383 - accuracy: 0.9887
Epoch 5/5
600/600 [==============================] - 19s 31ms/step - loss: 0.0286 - accuracy: 0.9911
```
我们可以看到,训练5个Epoch后,模型的准确率已经达到了99.11%。
5. 测试模型
最后,我们使用测试数据集进行模型的测试:
```python
test_loss, test_acc = model.evaluate(x_test.reshape(-1, 28, 28, 1), y_test)
print('Test accuracy:', test_acc)
```
可以看到,模型在测试数据集上的准确率也达到了99.15%。我们成功地完成了手写数字识别任务。