在本篇博客中,我将展示如何使用像素概率来构建一个简单的手写数字分类器,并在著名的MNIST数据集上进行测试。MNIST数据集包含60000个训练图像和10000个测试图像,每个图像都是28×28像素的灰度图像,代表数字0到9。通过分析每个像素在不同数字类别中的分布情况,我们可以构建一个简单但有效的分类器。
令人惊讶的是,目前网上似乎没有人尝试过这种方法。
数据预处理
首先,我们需要加载并预处理MNIST数据集。为了简单起见,我们将像素值归一化到0-1之间。
1
2
3
4
5
6
7
8
9
|
from keras.datasets import mnist
import numpy as np
# 加载MNIST数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 将数据集中的像素值归一化到0-1之间
x_train = x_train // 200.0
x_test = x_test // 200.0
|
计算像素概率
接下来,我们需要计算每个像素在每个数字类别中的概率。我们首先初始化一个二维数组pixel_counts来存储每个像素在每个数字类别中的计数,然后计算每个像素的概率。
1
2
3
4
5
6
7
8
9
10
11
|
# 初始化一个2D数组,用于存储每个像素在每个数字类别中的分布情况
pixel_counts = np.zeros((10, 28*28))
for i in range(x_train.shape[0]):
image = x_train[i].flatten() # 将图像展平为一维数组
label = y_train[i]
pixel_counts[label] += image
# 计算每个像素在每个数字类别中的概率
pixel_probabilities = pixel_counts / (len(x_train) )
|
分类器实现
有了像素概率后,我们可以实现一个简单的分类器。对于每个测试图像,我们计算它与每个数字类别像素概率的乘积,选择具有最高分的数字作为预测结果。
1
2
3
4
5
6
7
8
9
10
11
|
def classify_digit(image, pixel_probabilities):
# 将图像展平为一维数组并归一化到0-1之间
flattened_image = image.flatten() / 255.0
# 计算给定图片与每个数字类别像素概率的乘积
scores = np.dot(pixel_probabilities, flattened_image)
# 选择具有最高分对应的数字作为预测结果
predicted_digit = np.argmax(scores)
return predicted_digit
|
模型评估
最后,我们对测试集进行分类并计算分类器的准确率。
1
2
3
4
5
6
7
8
9
10
11
12
|
# 对测试集进行分类并计算准确率
correct_count = 0
for i in range(x_test.shape[0]):
image = x_test[i]
label = y_test[i]
predicted_label = classify_digit(image, pixel_probabilities)
if predicted_label == label:
correct_count += 1
accuracy = correct_count / len(x_test)
print(f"Accuracy of the classifier: {accuracy * 100:.2f}%")
|
结果
运行上述代码后,我们可以看到分类器的准确率。虽然这个简单的分类器在准确率上可能不如复杂的深度学习模型,但它展示了通过统计方法进行手写数字识别的基本原理。
在本次实验中,使用像素概率的简单分类器在MNIST数据集上的表现如下:
Accuracy of the classifier: 68.99%