当前位置: 首页 > news >正文

从零开始:手写数字识别程序的深度学习实践

从零开始:手写数字识别程序的深度学习实践

  • 一、环境搭建与数据准备
  • 二、加载数据集
  • 三、神经网络类设计与实现
    • 3.1 初始化方法
    • 3.2 训练方法(核心)
    • 3.3 预测方法
  • 四、数据预处理:为模型输入做准备
    • 4.1训练数据处理
    • 4.2测试数据处理
    • 4.3标签转换为one-hot编码
  • 五、模型训练过程解析
    • 5.1初始化网络并开始训练:
  • 六、模型评估与测试
    • 6.1训练完成后,在测试集上评估模型性能:
  • 七、总结与学习心得
    • 7.1 核心收获
    • 7.2 遇到的问题与解决
    • 7.3 改进方向

引言:作为一名AI初学者,我选择从经典的MNIST手写数字识别项目开始深度学习之旅。本文记录了我根据书本参考代码,从零开始实现一个能够识别0-9手写数字程序的全过程。通过这个项目,我深刻理解了神经网络的基本原理和实现细节。

一、环境搭建与数据准备

在项目开始前,需要搭建Python环境并导入必要的库:

import numpy
from keras.datasets import mnist
import scipy.special
from keras.utils import to_categorical

关键库的作用:
1.numpy:科学计算基础库,处理矩阵运算
2.keras.datasets:提供经典数据集(这里使用MNIST)
3.scipy.special:包含特殊数学函数(如sigmoid)
4.to_categorical:将标签转换为one-hot编码

二、加载数据集

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

MNIST数据集包含:
1.60,000张28×28像素的训练图片
2.10,000张测试图片
3.每张图片对应0-9的数字标签

三、神经网络类设计与实现

实现了一个三层全连接神经网络类NeuralNetWork:

3.1 初始化方法

def __init__(self, _input_nodes, _hidde_nodes, _output_nodes, _learning_rate):self.inputnodes = _input_nodes  # 输入层节点数(784)self.hiddenodes = _hidde_nodes  # 隐藏层节点数(100)self.outputnodes = _output_nodes  # 输出层节点数(10)self.lr = _learning_rate  # 学习率# 初始化权重矩阵(-0.5到0.5的随机值)self.wih = numpy.random.rand(self.hiddenodes, self.inputnodes) - 0.5self.who = numpy.random.rand(self.outputnodes, self.hiddenodes) - 0.5

3.2 训练方法(核心)

def fit(self, inputs_list, targets_list):# 数据转换inputs = numpy.array(inputs_list, ndmin=2).Ttargets = numpy.array(targets_list, ndmin=2).T# 前向传播hidden_inputs = numpy.dot(self.wih, inputs)hidden_outputs = scipy.special.expit(hidden_inputs)  # sigmoid激活final_inputs = numpy.dot(self.who, hidden_outputs)final_outputs = scipy.special.expit(final_inputs)  # sigmoid激活# 误差计算output_errors = targets - final_outputshidden_errors = numpy.dot(self.who.T, output_errors)# 权重更新(反向传播)self.who += self.lr  numpy.dot((output_errors  final_outputs * (1 - final_outputs)), numpy.transpose(hidden_outputs))self.wih += self.lr  numpy.dot((hidden_errors  hidden_outputs * (1 - hidden_outputs)), numpy.transpose(inputs))

3.3 预测方法

def evaluate(self, inputs):# 前向传播计算输出hidden_inputs = numpy.dot(self.wih, inputs)hidden_outputs = scipy.special.expit(hidden_inputs)final_inputs = numpy.dot(self.who, hidden_outputs)final_outputs = scipy.special.expit(final_inputs)return final_outputs

四、数据预处理:为模型输入做准备

原始数据需要经过预处理才能输入神经网络:

4.1训练数据处理

train_images_number = 60000
train_images = train_images.reshape((train_images_number, 28 * 28))  # 扁平化
train_images = train_images.astype('float32') / 25  # 归一化

4.2测试数据处理

test_images_number = 10000
test_images = test_images.reshape(test_images_number, 28 * 28)
test_images = test_images.astype('float32') / 255  # 更精确的归一化

4.3标签转换为one-hot编码

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

数据处理要点:
1.扁平化:将28×28的二维图片转换为一维向量(784维)
2.归一化:像素值从[0,255]缩放到[0,1]区间
3.One-hot编码:数字标签转换为向量形式(如"3"变为[0,0,0,1,0,0,0,0,0,0])

五、模型训练过程解析

5.1初始化网络并开始训练:

#网络参数设置input_nodes = 784  # 对应28×28=784像素
hidden_nodes = 100  # 隐藏层神经元数量
output_nodes = 10   # 对应0-9十个数字
learning_rate = 0.02#初始化网络
n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)#训练过程total = train_images_number
i = 0for train_image, train_label in zip(train_images, train_labels):n.fit(train_image, train_label)
i = i + 1print(f"\r完成第{i}次训练", end='', flush=True)

训练细节:
1.采用随机梯度下降(SGD),每次输入一个样本
2.使用进度显示直观展示训练进度
3.学习率设置为0.02(经实验调整后的较优值)
4.完整训练需要遍历60,000张图片

六、模型评估与测试

6.1训练完成后,在测试集上评估模型性能:

scores = []
j = 0for test_image, test_label in zip(test_images, test_labels):output = n.evaluate(test_image)evaluate_label = numpy.argmax(output)  # 获取预测值correct_label = numpy.argmax(test_label)  # 获取真实值
j = j + 1print(f"\r完成第{j}次测试", end='', flush=True)# 记录预测结果if evaluate_label == correct_label:scores.append(1)else:scores.append(0)#计算准确率scores_array = numpy.asarray(scores)
print("模型准确率为:", scores_array.sum() / scores_array.size)

评估逻辑:
1.遍历所有测试图片(10,000张)
2.模型预测输出10维概率向量
3.取最大概率值对应的索引作为预测数字
4.统计预测正确率

七、总结与学习心得

通过这个项目,我获得了以下宝贵经验:

7.1 核心收获

1.神经网络基础:深入理解了三层神经网络的前向传播、反向传播机制
2.数据预处理重要性:认识到归一化和数据格式转换对模型性能的关键影响
3.超参数调优:通过实验发现0.02的学习率比参考书的0.3更适合本模型
4.实践出真知:亲手调试代码比单纯看书更能理解算法细节

7.2 遇到的问题与解决

1.维度匹配错误:初次实现时因矩阵形状不匹配导致运算失败
解决:仔细检查每层输入的维度并添加转置操作
2.梯度消失问题:使用sigmoid激活函数在深层网络中出现梯度消失
解决:将隐藏层节点增加到100个缓解此问题
3.归一化差异:发现训练集和测试集使用了不同归一化系数
解决:统一使用/255进行标准化

7.3 改进方向

1.改用ReLU激活函数解决梯度消失问题
2.实现批量训练(Batch Training)提高效率
3.添加正则化技术减少过拟合
4.尝试卷积神经网络(CNN)提升图像识别准确率

学习感悟:从理论到实践的跨越充满挑战,但每次成功运行代码、看到准确率提升都带来巨大成就感。这个简单但完整的项目为我打开了深度学习的大门,期待在计算机视觉领域继续探索!

http://www.dtcms.com/a/355807.html

相关文章:

  • 《实际项目》空调水系统群控方案
  • TensorFlow 深度学习 | 三种创建模型的 API
  • Promptalot-Midjourney提示词分享平台
  • Java爬虫是什么,如何获取API接口
  • 嵌入式开发学习———Qt软件环境下的C++学习(七)
  • Nginx中`location`路径匹配规则
  • 20250828_学习JumpServer开源堡垒机使用:统一访问入口 + 安全管控 + 操作审计
  • AI翻唱-RVC在线使用-AutoDL
  • 现代数据架构中的核心技术组件解析
  • RPM Spec 文件中 `Provides` 与 `%py_provides` 实现原理及应用场景解析
  • AP化学课程知识点解析学习计划及培训机构推荐
  • 解决pycharm中已经设置python解释器但是terminal中没有变成对应的conda环境
  • 步进电机、直流电机常见问题
  • ASCM-专有云公共云
  • C#写的一键自动测灯带的应用 AI帮写的。
  • 梯度下降,梯度消失,梯度爆炸
  • hintcon2025 Verilog OJ
  • 若依cloud集训总结
  • 对于冯诺依曼体系的理解
  • Linux:信号详解--醍醐灌顶
  • 基于Spring Cloud Gateway构建API网关
  • 第三章:Cesium 矢量数据可视化(点、线、面)
  • Shell脚本(1)
  • 机器学习可解释库Shapash的快速使用教程(五)
  • 全能工程软件 Siemens NX:从设计到制造的全流程解决方案,附安装指南
  • 滑台模组如何实现电子制造精密加工?
  • HVV面经总结(二)
  • 自动量化交易
  • 将Ollama应用安装至其他盘
  • 通信算法之323:verilog中带参数实体模版