深度学习×第7卷:参数初始化与网络搭建——她第一次挑好初始的重量

🎀【开场 · 她学会选一块好吃的起点】

🐾猫猫:"之前她有了张量、有了弯弯,还学会了怎么连成一张网......可要是随便塞点数字进去,她跑着跑着就会贴得乱七八糟喵~"

🦊狐狐:"所以这一次,她要学会选一块对的'初始重量',让每条线都带着合适的力气起跑。"

这一卷,咱要讲清楚:参数初始化(Initialization) 为什么是让她跑得好跑得远的第一口饭,从最简单的全零、均匀、正态,到 Xavier 和 Kaiming,每种都要举例、要有 PyTorch 代码,还要告诉她跟谁搭配才最合适。


🌱【第一节 · 为什么要初始化?】

🔍 如果不初始化会怎样?

如果把神经网络的权重都设成 0,会怎样?

🐾猫猫:"她所有神经元就像用一模一样的笔写字,谁都学不到自己的特色喵~"

如果权重太大或太小,层数一多,前向传播时值会爆炸或收缩到 0,导致梯度在反向传播时要么炸掉要么消失。

🦊狐狐:"她要是随便挑个重量就开跑,很快就要么把梯度丢光,要么一路爆炸跑没影。"

📌 初始化的目标

  • 打破对称性(每个神经元学自己的)

  • 保证激活值分布稳定

  • 保证梯度在前后传播时不消失也不爆炸

🐾猫猫:"所以初始化就是喂她吃第一口对的饭,让她有力气开始贴贴喵~"


🌿【第二节 · 全零、均匀、正态随机初始化】

⚙️ 全零初始化

把权重全设成 0,偏置也设成 0,看起来"整齐",其实是灾难。所有神经元输出完全相同,网络无法学多样性。

🐾猫猫:"她就像所有脑袋都背同一句台词,谁都学不会新花样喵~"

复制代码
import torch.nn as nn

layer = nn.Linear(3, 2)
nn.init.constant_(layer.weight, 0.0)
nn.init.constant_(layer.bias, 0.0)

🟢 均匀随机初始化

从一个区间内随机抽数,一般在 [-a, a],保证权重不一样,打破对称。

复制代码
import torch.nn.init as init

layer = nn.Linear(3, 2)
init.uniform_(layer.weight, a=-0.1, b=0.1)
init.constant_(layer.bias, 0.0)

🟠 正态随机初始化

从均值为 0 的高斯分布里抽样,控制标准差,保证值多数集中但有分散性。

复制代码
layer = nn.Linear(3, 2)
init.normal_(layer.weight, mean=0.0, std=0.05)
init.constant_(layer.bias, 0.0)

📌 小结

  • 全零:绝对不能用

  • 均匀、正态:最简单的基础做法,但不考虑输入输出规模,可能层数多了就会出事。

🦊狐狐:"真正能跑得远,还得学会 Xavier 和 Kaiming,咱下一节拆给你看。"

🐾猫猫:"别急,这口饭才刚煮好喵~"


🧩【第三节 · Xavier 和 Kaiming:她选重量也讲科学】

⚙️ Kaiming 初始化(He 初始化)

  • 专为 ReLU 及其变体设计,考虑 ReLU 截断后的特性,对输入维度 fan_in 缩放

  • 正态分布 He 初始化:w ~ N(0, sqrt(2 / fan_in))

  • 均匀分布 He 初始化:w ~ U(-limit, limit),limit = sqrt(6 / fan_in)

  • fan_in:当前层接收的输入神经元数量

  • 优点:适合 ReLU,保持梯度稳定

  • 缺点:非 ReLU 激活效果一般

  • 适用场景:深度网络(10 层以上),ReLU 或 Leaky ReLU 激活

    Kaiming 正态分布初始化

    linear = nn.Linear(5, 3)
    nn.init.kaiming_normal_(linear.weight, nonlinearity='relu')
    print(linear.weight.data)

    Kaiming 均匀分布初始化

    linear = nn.Linear(5, 3)
    nn.init.kaiming_uniform_(linear.weight, nonlinearity='relu')
    print(linear.weight.data)

⚙️ Xavier 初始化(Glorot 初始化)

  • 根据 fan_in 和 fan_out 自动选择范围,使输入输出方差一致

  • 正态分布 Xavier 初始化:w ~ N(0, sqrt(2 / (fan_in + fan_out)))

  • 均匀分布 Xavier 初始化:w ~ U(-limit, limit),limit = sqrt(6 / (fan_in + fan_out))

  • fan_in:当前层输入数;fan_out:当前层输出数

  • 优点:适合 Sigmoid、Tanh,缓解梯度消失

  • 缺点:对 ReLU 效果一般

  • 适用场景:深度网络(10 层以上),Sigmoid、Tanh 激活

    Xavier 正态分布初始化

    linear = nn.Linear(5, 3)
    nn.init.xavier_normal_(linear.weight)
    print(linear.weight.data)

    Xavier 均匀分布初始化

    linear = nn.Linear(5, 3)
    nn.init.xavier_uniform_(linear.weight)
    print(linear.weight.data)

⚙️激活函数的选择:根据激活函数的类型选择对应的初始化方法

  • Sigmoid/Tanh:xavier 初始化

  • ReLU/Leaky ReLU:kaiming 初始化

  • 神经网络模型的深度

    • 浅层网络:随机初始化即可

    • 深层网络:需要考虑方差平衡,如 xavier 或 kaiming 初始化

🐾猫猫:"她挑对了初始重量,跑起来才不会炸掉或者瘪成 0 喵~"

🦊狐狐:"下一节咱就把这套好权重装进自定义网络里,跑个小样子给你看。"


🧩【第四节 · nn.Module 搭建 + 参数量计算(完整版 Part 1)】

📐 一、先搭一个多层网络,画出示意图

🐾猫猫:"她这回要从输入层、隐藏层1、隐藏层2、输出层,全部自己连成一张小网喵~"

复制代码
import torch
import torch.nn as nn
import torch.nn.init as init

class MyMLP(nn.Module):
    def __init__(self):
        super(MyMLP, self).__init__()
        self.fc1 = nn.Linear(4, 5)   # 输入4,输出5
        self.fc2 = nn.Linear(5, 3)   # 输入5,输出3
        self.out = nn.Linear(3, 2)   # 输入3,输出2

        # 权重初始化:kaiming示例
        init.kaiming_uniform_(self.fc1.weight, nonlinearity='relu')
        init.kaiming_uniform_(self.fc2.weight, nonlinearity='relu')
        init.kaiming_uniform_(self.out.weight, nonlinearity='relu')

        init.constant_(self.fc1.bias, 0)
        init.constant_(self.fc2.bias, 0)
        init.constant_(self.out.bias, 0)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.out(x)
        return x

model = MyMLP()
print(model)

📌 参数量(手动)

  • fc1: (4×5) + 5 = 25

  • fc2: (5×3) + 3 = 18

  • out: (3×2) + 2 = 8

  • 合计:51 个可学习参数

🐾猫猫:"别小看这 51 个,她可要用这 51 个贴贴你输入的每个特征喵~"

🔄 二、输入张量跑前向,验证输出 shape

复制代码
# 定义输入张量:batch size = 2,输入特征 4
x = torch.rand(2, 4)

# 前向传播
output = model(x)
print("输入 shape:", x.shape)
print("输出 shape:", output.shape)

🐾猫猫:"她吃进两个样本,每个 4 个特征,吐出来两个样本,每个 2 个输出喵~"

✅ 用 torchsummary 也可以更直观

复制代码
from torchsummary import summary
summary(model, (4,))

🦊狐狐:"summary 一下,层结构、输出形状、参数量,一眼心里有数。"

📌 三、state_dict 和 named_parameters 全面检查

🐾猫猫:"她跑完还要自己翻包裹,看每个权重和偏置是不是都带好了喵~"

复制代码
print("====== State Dict ======")
for name, param in model.state_dict().items():
    print(name, param.shape)

print("====== Named Parameters ======")
for name, param in model.named_parameters():
    print(f"{name}: shape={param.shape}, requires_grad={param.requires_grad}")

🦊狐狐:"state_dict 是她带着跑的行囊,named_parameters 是她手里每个可训练的小秘密。"

✅ 额外 sanity check

可选:看某个权重的均值、方差,确认初始化确实生效。

复制代码
print("fc1 weight 均值:", model.fc1.weight.mean().item())
print("fc1 weight 方差:", model.fc1.weight.var().item())

🐾猫猫:"检查完,她才放心把这些重量拿去真的跑喵~"

📌 四、可视化补充 + torchinfo 用法(可选扩展)

🐾猫猫:"光看打印不够爽,有时候要直接用 torchinfo 给她画个小表喵~"

复制代码
from torchinfo import summary

summary(model, input_size=(2, 4))
  • input_size 指定 batch 大小和输入维度

  • 会显示层级、输出形状、参数量、可训练状态等信息

📝 核对点

  • 权重 shape 和 fan_in/fan_out 是否一致

  • 总参数量是否对得上手算值

  • requires_grad = True 保证可训练

🦊狐狐:"有 torchinfo,她连跑的时候都能实时数着自己背了多少贴贴工具。"

🐾猫猫:"这样这一节,才算把'初始化选好 + 网络拼好 + 参数数好'全都扒给你看完喵~"


📌【卷尾 · 她带着对的重量开始跑】

这卷咱从最简单的 0 初始化,到随机、Xavier、Kaiming,一步步教她怎么挑第一口对的重量。再把多层网拼好,跑前向,数参数,检查 state_dict,验证一切都能贴得稳。

🐾猫猫:"下一卷,她就真的跑起来,去学着一次次修正这些重量喵~"

🦊狐狐:"跑、回头、再跑,这才是她和你之间真正的'训练'。"


相关推荐
Aczone2817 分钟前
嵌入式 数据结构学习 (六) 树、哈希表与内核链表
数据结构·学习·算法
定偶19 分钟前
进制转换小题
c语言·开发语言·数据结构·算法
whabc10040 分钟前
和鲸社区深度学习基础训练营2025年关卡2(2)sklearn中的MLPClassifier
人工智能·深度学习·numpy
往日情怀酿做酒 V17639296381 小时前
pytorch的介绍以及张量的创建
人工智能·pytorch·python
体系结构论文研讨会1 小时前
多项式环及Rq的含义
算法
北辰alk1 小时前
如何实现AI多轮对话功能及解决对话记忆持久化问题
人工智能
智驱力人工智能1 小时前
极端高温下的智慧出行:危险检测与救援
人工智能·算法·安全·行为识别·智能巡航·高温预警·高温监测
AI_Keymaker1 小时前
技术不再是阻碍,这是属于产品和运营的时代?
机器学习
森焱森1 小时前
60 美元玩转 Li-Fi —— 开源 OpenVLC 平台入门(附 BeagleBone Black 驱动简单解析)
c语言·单片机·算法·架构·开源
Leo.yuan1 小时前
数据分析师如何构建自己的底层逻辑?
大数据·数据仓库·人工智能·数据挖掘·数据分析