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

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

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

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

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

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


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

🔍 如果不初始化会怎样?

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

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

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

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

📌 初始化的目标

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

  • 保证激活值分布稳定

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

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


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

⚙️ 全零初始化

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

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

import torch.nn as nnlayer = 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 initlayer = 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 initclass MyMLP(nn.Module):def __init__(self):super(MyMLP, self).__init__()self.fc1 = nn.Linear(4, 5)   # 输入4,输出5self.fc2 = nn.Linear(5, 3)   # 输入5,输出3self.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 xmodel = 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 summarysummary(model, input_size=(2, 4))
  • input_size 指定 batch 大小和输入维度

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

📝 核对点

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

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

  • requires_grad = True 保证可训练

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

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


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

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

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

🦊狐狐:“跑、回头、再跑,这才是她和你之间真正的‘训练’。”


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

相关文章:

  • ZW3D 二次开发-创建椭球体
  • 灰度发布策略制定方案时可以参考的几个维度
  • 递推+高精度加法 P1255 数楼梯
  • apt -y参数的含义
  • 计算机视觉 之 数字图像处理基础(一)
  • Kubernetes 1.23.6 kube-scheduler 默认打分和排序机制详解
  • 多商户商城系统源码选型指南:开源 vs 定制,哪种更适合?
  • 救回多年未用kubeadm搭建的kubernetes集群
  • 5. isaac sim4.2 教程-Core API-操作机械臂
  • 用黑盒测试与白盒测试,读懂专利审查的 “双重关卡”​​
  • K8S的CNI之calico插件升级至3.30.2
  • 深度学习中的 Seq2Seq 模型与注意力机制
  • 解释sync.WaitGroup的用途和工作原理。在什么情况下应该使用它?
  • 时间显示 蓝桥云课Java
  • Android ViewBinding 使用与封装教程​​
  • Netron的基本使用介绍
  • UNet改进(20):融合通道-空间稀疏注意力的医学图像分割模型
  • 客户频繁问询项目进度,如何提高响应效率
  • Java 中的多线程实现方式
  • Spring AI 系列之八 - MCP Server
  • NFS文件存储及部署论坛(小白的“升级打怪”成长之路)
  • (鱼书)深度学习入门2:手搓感知机
  • PostgreSQL创建新实例并指定目录
  • 下一代防火墙混合模式部署
  • Jupyter介绍
  • MySQL事务实现原理
  • SpringCloud系列 - 分布式锁(八)
  • html页面,当鼠标移开A字标就隐藏颜色框
  • Spring Boot项目中大文件上传的优化策略与实践
  • 华为鸿蒙3.0 4.0完全关闭纯净模式的方法以及临时绕过纯净模式检测的方法