图片识别项目
最基础版本
import numpy as np
from torchvision import datasets, transforms
from scipy.special import expit # sigmoid function
class DigitRecognizer:
def __init__(self):
# 加载 MNIST 数据集
mnist = datasets.MNIST('data', train=True, download=True, transform=transforms.ToTensor())
# 将 28x28 图像展平为 784 维向量,并归一化到 0-1 范围
self.x_train = mnist.data.numpy().reshape(-1, 784) / 255.0
self.y_train = mnist.targets.numpy()
# 初始化权重和偏置
self.weights = np.random.randn(784, 10) * 0.01 # 784个输入特征,10个输出类别
self.biases = np.zeros(10) # 每个输出类别一个偏置
self.learning_rate = 0.01
self.epochs = 5
def train(self):
print("开始训练...")
for epoch in range(self.epochs):
for i in range(len(self.x_train)):
# 准备训练数据
x = self.x_train[i] # 当前样本
y = np.zeros(10) # 创建one-hot编码标签
y[self.y_train[i]] = 1
# 前向传播
predictions = self.predict(x)
# 反向传播
error = predictions - y
# 更新权重和偏置
self.weights -= self.learning_rate * np.outer(x, error)
self.biases -= self.learning_rate * error
print(f"完成第 {epoch + 1}/{self.epochs} 轮训练")
def predict(self, x):
# 计算输出: sigmoid(wx + b)
z = np.dot(x, self.weights) + self.biases
return expit(z) # 使用sigmoid函数
def predict_digit(self, image):
"""
预测单个28x28的图像
image: 28x28的numpy数组
返回: 预测的数字和每个数字的概率
"""
# 确保图像被展平为784维向量
if image.shape != (784,):
image = image.reshape(784)
# 归一化图像数据
image = image / 255.0 if image.max() > 1 else image
# 获取预测概率
probabilities = self.predict(image)
# 返回预测的数字和所有概率
predicted_digit = np.argmax(probabilities)
return predicted_digit, probabilities
# 使用示例
if __name__ == "__main__":
# 创建模型
model = DigitRecognizer()
# 训练模型
model.train()
# 测试预测 - 使用训练集中的第一个样本作为示例
test_image = model.x_train[0]
predicted_digit, probabilities = model.predict_digit(test_image)
print(f"\n预测结果: {predicted_digit}")
print("各个数字的概率:")
for digit, prob in enumerate(probabilities):
print(f"数字 {digit}: {prob*100:.2f}%")有gui版本
Last updated