图片识别项目

最基础版本

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