深度学习之参数初始化和损失函数(四)
文章目录
- 深度学习之参数初始化和损失函数(四)
- 一、参数初始化
- 1.1 固定值初始化(仅演示,**权重不要用**)
- 1.2 随机初始化(打破对称性的起点)
- 1.3 Xavier(Glorot)初始化 —— 均衡前向与反向方差
- 1.4 He(Kaiming)初始化 —— 专为 ReLU 优化
- 1.5 高级初始化速览
- 二、损失函数
- 2.1 回归任务
- 2.2 分类任务
- 2.2.1 多类单标签 —— CrossEntropyLoss
- 2.2.2 二分类 / 多标签 —— BCEWithLogitsLoss
- 三、总结
- 四、案例
关键词:参数初始化、Xavier / He 初始值、对称性破坏、损失函数、MAE / MSE / CrossEntropy / BCE
一、参数初始化
1.1 固定值初始化(仅演示,权重不要用)
方法 | 代码 | 缺陷 |
---|
全零 | nn.init.zeros_(w) | 对称性未被破坏,所有神经元等价 |
全一 | nn.init.ones_(w) | 同上,且激活后输出恒等 |
任意常数 | nn.init.constant_(w, val) | 仍无法打破对称性 |
import torch.nn as nn
fc = nn.Linear(4, 3)
nn.init.zeros_(fc.weight)
1.2 随机初始化(打破对称性的起点)
分布 | 代码 | 方差公式 | 备注 |
---|
均匀 | nn.init.uniform_(w, a, b) | (b−a)212\displaystyle \frac{(b-a)^2}{12}12(b−a)2 | 需手动调区间 |
正态 | nn.init.normal_(w, mean, std) | σ2\displaystyle \sigma^2σ2 | std 难校准 |
局限:未考虑前向/反向方差,深层网络仍需“自适应”方法。
1.3 Xavier(Glorot)初始化 —— 均衡前向与反向方差
激活函数 | 数学依据 | PyTorch API |
---|
Sigmoid / Tanh | Var(W)=2nin+nout\displaystyle \text{Var}(W)=\frac{2}{n_{\text{in}}+n_{\text{out}}}Var(W)=nin+nout2 | xavier_uniform_ / xavier_normal_ |
- 均匀区间:[−6nin+nout,6nin+nout][-\sqrt{\frac{6}{n_{\text{in}}+n_{\text{out}}}},\; \sqrt{\frac{6}{n_{\text{in}}+n_{\text{out}}}}][−nin+nout6,nin+nout6]
- 正态方差:2nin+nout\frac{2}{n_{\text{in}}+n_{\text{out}}}nin+nout2
fc = nn.Linear(128, 64)
nn.init.xavier_uniform_(fc.weight, gain=nn.init.calculate_gain('tanh'))
1.4 He(Kaiming)初始化 —— 专为 ReLU 优化
模式 | 方差公式 | 场景 | API |
---|
fan_in | 2nin\frac{2}{n_{\text{in}}}nin2 | 前向方差稳定 | kaiming_normal_(..., mode='fan_in') |
fan_out | 2nout\frac{2}{n_{\text{out}}}nout2 | 反向梯度稳定 | kaiming_uniform_(..., mode='fan_out') |
fc = nn.Linear(256, 128)
nn.init.kaiming_normal_(fc.weight, nonlinearity='relu')
1.5 高级初始化速览
方法 | 一句话说明 | 代码 |
---|
orthogonal_ | 生成(半)正交矩阵,保持动态等距 | nn.init.orthogonal_(w) |
sparse_ | 指定稀疏度的高斯权重 | nn.init.sparse_(w, sparsity=0.9) |
二、损失函数
2.1 回归任务
损失 | 公式 | PyTorch |
---|
MAE (L1) | $\frac{1}{n}\sum | y_i-\hat y_i |
MSE (L2) | 1n∑(yi−y^i)2\frac{1}{n}\sum(y_i-\hat y_i)^2n1∑(yi−y^i)2 | nn.MSELoss() |
pred = torch.randn(32, 1)
target = torch.randn(32, 1)
print("MSE:", nn.MSELoss()(pred, target).item())
print("MAE:", nn.L1Loss()(pred, target).item())
2.2 分类任务
2.2.1 多类单标签 —— CrossEntropyLoss
- 已内置 Softmax,不要再手动
softmax
。 - 公式:
L=−1N∑ilogexi,yi−max(xi)∑jexi,j−max(xi)\displaystyle \mathcal{L}=-\frac{1}{N}\sum_{i}\log\frac{e^{x_{i,y_i}-\max(x_i)}}{\sum_j e^{x_{i,j}-\max(x_i)}}L=−N1i∑log∑jexi,j−max(xi)exi,yi−max(xi)
logits = torch.randn(16, 10)
labels = torch.randint(0, 10, (16,))
loss = nn.CrossEntropyLoss()(logits, labels)
print("CrossEntropy:", loss.item())
2.2.2 二分类 / 多标签 —— BCEWithLogitsLoss
- 已内置 Sigmoid,推荐一步到位。
- 公式:
−1N∑i[yilogy^i+(1−yi)log(1−y^i)]\displaystyle -\frac{1}{N}\sum_{i}\left[y_i\log\hat y_i+(1-y_i)\log(1-\hat y_i)\right]−N1i∑[yilogy^i+(1−yi)log(1−y^i)]
logits = torch.randn(8, 5)
targets = torch.randint(0, 2, (8, 5)).float()
loss = nn.BCEWithLogitsLoss()(logits, targets)
print("Multi-label BCE:", loss.item())
三、总结
任务类型 | 输出层 | 初始化 | 损失 | 备注 |
---|
线性回归 | 无激活 | Xavier / He 均可 | MSE / MAE | 输出无需激活 |
二分类 | 1 个神经元 + Sigmoid | He | BCEWithLogitsLoss | 标签 0/1 |
多类单标签 | Softmax | He | CrossEntropyLoss | 无需手动 Softmax |
多标签 | Sigmoid(每个类) | He | BCEWithLogitsLoss | 标签多热编码 |
四、案例
完整训练片段:初始化 + 损失
import torch
import torch.nn as nn
import torch.optim as optimclass MLP(nn.Module):def __init__(self, in_dim=784, hidden=256, out_dim=10):super().__init__()self.net = nn.Sequential(nn.Linear(in_dim, hidden),nn.ReLU(),nn.Linear(hidden, out_dim))self._init_weights()def _init_weights(self):for m in self.modules():if isinstance(m, nn.Linear):nn.init.kaiming_normal_(m.weight, nonlinearity='relu')nn.init.zeros_(m.bias)def forward(self, x):return self.net(x)model = MLP()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
x = torch.randn(64, 784)
y = torch.randint(0, 10, (64,))
out = model(x)
loss = criterion(out, y)optimizer.zero_grad()
loss.backward()
optimizer.step()
print("Step loss:", loss.item())