【AI邪修·神经网络】神经网络基础—代码分析—手写数字识别

1. 代码地址

https://github.com/king-wang123/PyTorch-DeepLearning-Practice-Projects

不需要安装jupter notebook,安装很麻烦,直接用cursor打开,然后安装jupter notebook插件。

2. 代码分析

2.1 数据获取阶段

2.2 数据预处理阶段

  1. 图像数据集合转张量
    这个不用说了,张量是核心数据结构,所有图像数据都要转张量才能进行后续处理。
  2. 张量数据标准化
    标准化公式: normalized = (input - mean) / std
    mean:平均值
    std:标准差

问题:

  1. 为什么用标准化不用归一化?
  • 标准化能更好地处理数据分布,让训练更稳定
  • 归一化到0-1容易受极值影响。如果一张图片中有几个特别亮的像素点(异常值),那么其他像素值被压缩到很小的范围,图像对比度降低。

另外:

  • MNIST 数据集的固定尺寸是 28×28

2.3 数据训练阶段

AI解释构建CNN网络代码:

复制代码
init_ 方法(初始化网络结构)
1. 继承和初始化
class Net(torch.nn.Module):    def __init__(self):        super(Net, self).__init__()
继承 torch.nn.Module,这是 PyTorch 中所有神经网络的基类
super() 调用父类初始化,让网络能正常工作

2. 第一个卷积块 conv1
self.conv1 = torch.nn.Sequential(    torch.nn.Conv2d(1, 32, kernel_size=3),    torch.nn.BatchNorm2d(32),    torch.nn.ReLU(),    torch.nn.MaxPool2d(kernel_size=2),)
Conv2d(1, 32, kernel_size=3):卷积层
输入:1 个通道(灰度图)
输出:32 个特征图
卷积核:3×3
作用:提取边缘、线条等特征
尺寸变化:28×28 → 26×26(无 padding)
BatchNorm2d(32):批量归一化
对 32 个特征图分别归一化
作用:稳定训练,加速收敛
ReLU():激活函数
负值置 0,保留正值
作用:引入非线性
MaxPool2d(kernel_size=2):最大池化
2×2 窗口取最大值
作用:降维、保留主要特征
尺寸变化:26×26 → 13×13

3. 第二个卷积块 conv2
self.conv2 = torch.nn.Sequential(    torch.nn.Conv2d(32, 64, kernel_size=3),    torch.nn.BatchNorm2d(64),    torch.nn.ReLU(),    torch.nn.MaxPool2d(kernel_size=2),)
Conv2d(32, 64, kernel_size=3)
输入:32 个特征图
输出:64 个特征图
作用:提取更复杂的特征(如曲线、组合形状)
尺寸变化:13×13 → 11×11
BatchNorm2d(64)、ReLU()、MaxPool2d:同上
尺寸变化:11×11 → 5×5

4. 全连接层 fc
self.fc = torch.nn.Sequential(    torch.nn.Linear(1600, 50),    torch.nn.ReLU(),    torch.nn.Dropout(0.5),    torch.nn.Linear(50, 10))
Linear(1600, 50)
输入:1600(64×5×5,展平后)
输出:50
作用:将特征映射到中间表示
ReLU():同上
Dropout(0.5)
训练时随机将 50% 的神经元置 0
作用:减少过拟合
Linear(50, 10)
输入:50
输出:10(对应 0-9)
作用:输出每个数字的得分

forward 方法(前向传播)
def forward(self, x):    batch_size = x.size(0)    x = self.conv1(x)    x = self.conv2(x)    x = x.view(batch_size, -1)    x = self.fc(x)    return x
batch_size = x.size(0):获取批次大小
x = self.conv1(x):通过第一个卷积块
x = self.conv2(x):通过第二个卷积块
x = x.view(batch_size, -1):展平
从 (batch, 64, 5, 5) 变为 (batch, 1600)
-1 表示自动计算该维度
x = self.fc(x):通过全连接层
return x:返回 (batch, 10) 的得分

数据流动过程
输入:(batch, 1, 28, 28) 的图片
↓
conv1 → (batch, 32, 13, 13)
↓
conv2 → (batch, 64, 5, 5)
↓
展平 → (batch, 1600)
↓
全连接层 → (batch, 10)
↓
输出:10 个数字的得分
总结
卷积层:提取图像特征
池化层:降维并保留主要特征
全连接层:将特征映射到分类结果
激活函数:引入非线性
批量归一化:稳定训练
Dropout:减少过拟合
这个网络通过逐层提取特征,最终输出每个数字(0-9)的得分,得分最高的就是预测结果

问题1:

池化是降低分辨率的过程,池化后的图像分辨率尺寸怎么算?

AI答:

MaxPool2d(kernel_size=2) 的工作原理:

池化窗口:2×2

步长:2(默认等于 kernel_size)

每次移动 2 个像素,取 2×2 区域的最大值

26×26 → 13×13:

26 ÷ 2 = 13

每 2 个像素取一个值,所以尺寸减半

公式:

输出尺寸 = 输入尺寸 ÷ 步长 = 26 ÷ 2 = 13

总结: 核大小为 2、步长为 2 时,输出尺寸是输入的一半。


问题2:

图像和卷积核卷积为什么会让图片变小?变小后有什么常见的处理方式?

AI答:

为什么卷积会让图片变小?

卷积核在边缘无法完全覆盖,输出尺寸 = 输入尺寸 - 核大小 + 1,所以会变小。

变小后的常见处理方式

Padding:周围加0,保持尺寸不变

Stride:增大步长,快速缩小

接受变小:直接使用,通常不影响效果

池化层:进一步缩小,提取主要特征

上采样:用转置卷积恢复尺寸(用于生成/分割任务)

你的代码

采用方式3+4:卷积变小 → 池化再缩小 → 逐步提取特征,适合分类任务。


问题3:

torch.nn.Dropout(0.5)怎么通俗理解,来自什么理论?

AI答:

是什么:

训练时随机让 50% 的神经元输出为 0,测试时全部使用。

作用:

防止过拟合,提高泛化能力。

理论来源:

2012 年 Geoffrey Hinton 等人提出,防止神经元过度依赖。

你的代码:

Dropout(0.5) # 训练时随机丢弃50%神经元

总结: 训练时随机"关闭"部分神经元,测试时全部使用,用于减少过拟合。


问题4:

Dropout必须用吗,不用会怎么样,影响大吗?

AI答:

不是必须的。

不用会怎么样?

可能过拟合(模型过度记住训练数据)

测试准确率可能下降

影响大吗?

取决于数据量和模型复杂度:

数据少/模型复杂:影响大

数据多/模型简单:影响小

你的情况

你的网络已有 BatchNorm,可以尝试不用 Dropout。对于 MNIST 这种简单任务,影响可能不大。

总结: 不是必须的,不用可能过拟合,但影响取决于具体情况。


问题5:

这不是玄学吗?

AI回答:

为什么像玄学:

效果不确定,需要试错

依赖经验,没有绝对标准

但有理论支撑:

Dropout、BatchNorm 有数学证明和实验验证

但最佳参数仍需实验

实用建议:

先用经典配置(你的代码已很好)

不要过度纠结细节

先跑通,再优化

总结: 有经验成分,但背后有理论。对初学者,先用经典配置,跑通后再优化。


问题6:

torch.nn.BatchNorm2d(32)是干嘛的,每次卷积后都需要吗?

AI答:

功能:

对 32 个特征图做批量归一化,将分布标准化(均值 0,方差 1)。

好处:

加速训练收敛

提高训练稳定性

是否每次卷积后都需要?

不是必须的。

常见用法:

卷积后加 BatchNorm(你的代码就是这样)

也可以不加

什么时候需要:

深层网络、训练不稳定时建议加

简单网络可以不加

总结: BatchNorm2d 用于稳定训练和加速收敛。不是必须的,但卷积后加 BatchNorm 是常见做法。你的代码加了,效果不错,可以保持。


问题7:

BatchNorm2d是归一化还是标准化?

AI答:

BatchNorm 做的是标准化(Standardization),不是归一化(Normalization)。

区别:

标准化(Standardization):

公式:(x - mean) / std

结果:均值为 0,标准差为 1

BatchNorm 就是这样做

归一化(Normalization):

公式:(x - min) / (max - min)

结果:数值在 0-1 之间

为什么容易混淆?

术语问题:

英文 "Normalization" 在中文可译为"归一化"或"标准化"

深度学习里,BatchNorm 实际做的是标准化

中文资料中这两个词常混用

总结

BatchNorm 中的 "Norm" 实际是标准化(Standardization),不是归一化。它把数据转换为均值为 0、标准差为 1 的分布。


问题8:

x = x.view(batch_size, -1)详细解释这行代码

AI答:

将多维张量"压扁"成一维,输入给self.fc函数。

笔者注:fc是full connect,意为全连接。全连接层,就是把多维张量变成一维数组的过程。因为最后的结果它是N选1的单选题,而你的图片以及中间结果都是张量,想要通过张量映射到一个单选结果,只能把张量"铺平"了,把张量中的每个"像素点"和结果选项通过神经元(权重+偏置)连接到候选项中,加以训练调参,这就是全连接层干的事情。


问题9:

模型总参数数量是什么意思,一个神经元算一个参数吗?

AI答:

参数数量 ≠ 神经元数量

参数包括:

权重(weights):连接权重

偏置(bias):每个神经元的偏置值

计算方式:

Linear(1600, 50):

权重:1600 × 50 = 80,000

偏置:50

总计:80,050 个参数

Conv2d(1, 32, kernel_size=3):

权重:1 × 32 × 3 × 3 = 288

偏置:32

总计:320 个参数

总结

参数数量 = 所有权重 + 所有偏置

不是神经元数量,而是需要训练的数字个数

你的模型有 99,568 个参数,这些参数数值会在训练中不断调整。

笔者注:在此项目中,参数量包含卷积核的参数和神经元的参数两种类型,它们之和才是总参数量。


问题10:

一个神经元有几个输入几个输出?

AI答:

基本结构:

一个神经元 = N 个输入 + 1 个输出

不同网络类型的神经元

  1. 全连接层(Linear/Dense):
    N 个输入,1 个输出
  2. 卷积层(Conv2d):
    输入:局部区域(如 3×3)
    输出:1 个特征值
    本质相同,只是输入来自局部区域
  3. RNN/LSTM:
    输入:当前输入 + 上一时刻的隐藏状态
    输出:1 个隐藏状态
    结构相同,有时序信息
  4. Transformer:
    注意力机制:多个输入,1 个输出
    全连接层:N 个输入,1 个输出

总结

大部分神经网络中,一个神经元 = N 个输入 + 1 个输出

这是神经元的基本结构

不同网络主要在输入来源和连接方式上有差异

笔者注:每个输入都要权重参数,但是一个神经元只有一个偏置。因为偏置是针对输出的,只有一个输出的话,当然只有一个偏置。


问题11:

有没有可能,一个神经元可以有多个输入多个输出呢?

AI答:

有研究多输入多输出的神经元,但较少见

Capsule Networks 是相关方向

更常见的是用多个传统神经元组合实现多输出

传统设计(N 输入 + 1 输出)仍是主流,因为简单有效


问题12:

模型可训练参数数量是啥意思?

AI答:

含义:

在训练过程中会被更新(通过反向传播)的参数数量。

如果某些参数被冻结,可训练参数数量会小于总参数数量。比如在迁移学习场景下,需要使用预训练模型(如 ImageNet 上训练的模型),冻结部分层,只训练新层,利用已有知识,适应新任务。这种情况下,模型可训练参数数量 = 模型参数总量 - 冻结参数量。


问题13:

p.numel()是什么意思

AI答:

p为张量,我们知道张量在计算器中和多维数组类似。p.numel()就是计算多维数组中元素总数。

相关推荐
idkmn_2 小时前
Daily AI 20251219 (PyTorch基础回顾3)
人工智能·pytorch·python·深度学习·神经网络
baby_hua2 小时前
20251011_Pytorch深度学习(快速预览)
人工智能·pytorch·深度学习
盼小辉丶3 小时前
PyTorch实战(17)——神经风格迁移
pytorch·深度学习·风格迁移
baby_hua15 小时前
20251024_PyTorch深度学习快速入门教程
人工智能·pytorch·深度学习
hopsky1 天前
经典Transformer的PyTorch实现
pytorch·深度学习·transformer
brave and determined1 天前
CANN训练营 学习(day7)昇腾AI训练全流程实战:从模型迁移到性能优化的深度指南
pytorch·ai·ai训练·昇腾ai·msprobe·模型性能调优·训练配置
baby_hua1 天前
20251011_Pytorch从入门到精通
人工智能·pytorch·python
道19931 天前
PyTorch 高级进阶教程之深度实战实例(四)
人工智能·pytorch·python
Francek Chen1 天前
【自然语言处理】应用02:情感分析:使用循环神经网络
人工智能·pytorch·rnn·深度学习·神经网络·自然语言处理