[深度学习-2.3] 正则化减少过拟合

在开发一个分类器的时候如果出现了过拟合问题(高方差),其中一个有效的方法是增加更多的训练数据,但很多情况下无法获取到更多的数据,这时候就应该考虑另一个很有效的方法——正则化

正则化的原理

  以Logistic回归分类器为例。使用单神经元和Logistic回归构建的分类器,损失函数(即需要优化的目标函数)为 (1) min ⁡ J ( w , b ) = 1 m ∑ i = 1 m L ( y ( i ) , y ^ ( i ) ) \min J(w, b)=\frac{1}{m} \sum_{i=1}^{m} L\left(y^{(i)}, \hat{y}^{(i)}\right)\tag{1} minJ(w,b)=m1i=1mL(y(i),y^(i))(1)

w w w b b b 是逻辑回归的参数,对于Logistic回归来说, w ∈ R n x w \in R^{n_x} wRnx n x n_x nx 表示特征向量的维数, b b b 为实数。正则化就是给上面这样的损失函数加上正则化项,一般来说这个正则化项是 w w w 的加权值。如果使用L2正则化,损失函数会变成下面这样
(2) min ⁡ J ( w , b ) = 1 m ∑ i = 1 m L ( y ( i ) , y ^ ( i ) ) + λ 2 m ∥ w ∥ 2 2 \min J(w, b)=\frac{1}{m} \sum_{i=1}^{m} L\left(y^{(i)}, \hat{y}^{(i)}\right)+\frac{\lambda}{2m}\|w\|_{2}^{2} \tag{2} minJ(w,b)=m1i=1mL(y(i),y^(i))+2mλw22(2)

相比式(1)来说多了 λ 2 m ∥ w ∥ 2 2 \frac{\lambda}{2 m}\|w\|_{2}^{2} 2mλw22一项,即L2正则化项。其中 λ \lambda λ 是正则化参数(是一个超参数), m m m 表示样本数量, ∥ w ∥ 2 2 \|w\|_{2}^{2} w22 w w w 二范数的平方:
(3) ∥ w ∥ 2 2 = ∑ j = 1 n x w j 2 = w T w \|w\|_{2}^{2}=\sum_{j=1}^{n_x} w_j^{2}=w^Tw \tag{3} w22=j=1nxwj2=wTw(3)

L2正则化是最常使用的,此外还有L1正则化,在原损失函数后面加上L1正则化项 λ m ∥ w ∥ 1 \frac{\lambda}{m}\|w\|_{1} mλw1 ∥ w ∥ 1 \|w\|_{1} w1 表示 w w w 的一范数:
(4) ∥ w ∥ 1 = ∑ j = 1 n x ∣ w j ∣ \|w\|_{1}= \sum_{j=1}^{n_x} |w_j| \tag{4} w1=j=1nxwj(4)
  上面是以简单的Logistic为例,权重参数 w w w 是一个向量,接下来将其推广到深层神经网络。对于深层神经网络来说,损失函数的参数包含了 W [ 1 ] \bold{W}^{[1]} W[1] W [ L ] \bold{W}^{[L]} W[L] L L L为网络层数,并且对于任意一层 l l l 来说, W [ l ] \bold{W}^{[l]} W[l] 往往是一个二维矩阵而不是前面的向量形式。此时,加上正则化项后的损失函数为: (5) min ⁡ J = 1 m ∑ i = 1 m L ( y ( i ) , y ^ ( i ) ) + λ 2 m ∑ l = 1 L ∥ W [ l ] ∥ 2 \min J=\frac{1}{m} \sum_{i=1}^{m} L\left(y^{(i)}, \hat{y}^{(i)}\right)+\frac{\lambda}{2 m} \sum_{l=1}^{L}\|\bold{W}^{[l]}\|^{2} \tag{5} minJ=m1i=1mL(y(i),y^(i))+2mλl=1LW[l]2(5)

其中矩阵范数 ∥ W [ l ] ∥ 2 \|\bold{W}^{[l]}\|^{2} W[l]2 表示矩阵中所有元素的平方求和。注意到 W [ l ] \bold{W}^{[l]} W[l] 是一个 n [ l ] × n [ l − 1 ] n^{[l]}\times n^{[l-1]} n[l]×n[l1] 的二维矩阵,因此
(6) ∥ W [ l ] ∥ 2 = ∑ i = 1 n [ l ] ∑ i = 1 n [ l − 1 ] ( w i j ) 2 \|\bold{W}^{[l]}\|^{2}= \sum_{i=1}^{n^{[l]}}\sum_{i=1}^{n^{[l-1]}}(w_{ij})^2 \tag{6} W[l]2=i=1n[l]i=1n[l1](wij)2(6)

注意,在加入正则化项之后,损失函数的梯度相应的也多了一项,对于 l l l 层来说,用 d W [ l ] d\bold{W}^{[l]} dW[l]表示没有正则化项的梯度,可以很容易地推导出则加入正则化之后,梯度变为
(7) d W [ l ] ′ = d W [ l ] + λ m W [ l ] d\bold{W}^{[l]'}=d\bold{W}^{[l]}+\frac{\lambda}{m}\bold{W}^{[l]} \tag{7} dW[l]=dW[l]+mλW[l](7)

为什么正则化可以减少过拟合

  从直观上来理解,一个深度网络模型出现过拟合的原因是大量的隐藏神经元能够将输入特征向量的大量特征都考虑到,甚至一些数据噪声考虑在内。加入正则化后,由于正则项的存在,导致在优化损失函数的时候会将正则项的值也朝着小的方向优化,这样的结果就是神经网络中有部分连接的值会变得很小(跟 λ \lambda λ有关),这样网络的结构得到了优化,某些特征的影响会变小。简化后的神经网络更不容易出现过拟合的情况。但是 λ \lambda λ 很大的时候,当很多权重值都变得很小,此时网络会变得欠拟合,得到高偏差的结果,因此 λ \lambda λ 需要通过验证集来帮助配置。
  从数学原理上理解贝叶斯减少过拟合可以参考这一篇文章,我觉得解释的很清楚。

<think>首先,用户的问题是关于手写体数字识别模型的问题:模型输出结果全为6,准确率10%,交叉熵损失函数值恒定在2.29 - 2.3。用户想知道原因和解决办法。 回顾系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 用户引用了之前的快速排序示例,但这与当前问题无关。用户说:“参考站内引用:。上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。”这表明我需要专注于当前问题,而不是之前的示例。上一次问题和回答是关于快速排序的,但用户现在问的是深度学习模型问题。所以,我应该忽略快速排序的引用,直接针对这个新问题回答。 用户的需求是:查找手写体数字识别模型输出结果都为6,准确率10%(回想一下,MNIST手写数字有10个类,所以随机猜测准确率是10%,这暗示模型可能没有学习),交叉熵损失函数值稳定在2.29-2.3。我需要解释原因并提供解决方案。 关键点: - 输出全为6:模型总是预测类别6。 - 准确率10%:因为有10个类,平均随机准确率是10%,这表明模型可能没有学习任何东西。 - 交叉熵损失稳定在2.29-2.3:计算一下。对于10个类的分类问题,交叉熵损失定义为: $$ L = -\frac{1}{N} \sum_{i=1}^{N} \sum_{c=1}^{C} y_{i,c} \log(p_{i,c}) $$ 其中$y_{i,c}$是真实标签(one-hot编码),$p_{i,c}$是预测概率。 如果模型预测所有样本为概率1 for class 6(输出全为6),那么对于任何样本,如果真实标签是c,预测概率p_i = [0,0,0,0,0,1,0,0,0,0](假设类索引从0到9),那么log(p_i)只在真实标签是6时是0,否则-log(0)是无穷大,但实际中由于softmax和数值稳定,不会精确为0。 如果模型输出全为6,那么预测概率p_i,c = 1 for c=6, 0 otherwise。但softmax会确保概率和为1,所以如果logits输出很高给一个类,softmax后接近1。 假设模型输出logits使得softmax后p(6)=1,其他p(c)=0(数值上很小)。 对于真实标签: - 如果真实标签是6,损失贡献为 -log(1) = 0 - 如果真实标签是其他类,损失贡献为 -log(0) ≈ +∞,但实际中由于精度,可能是一个大数如-log(epsilon)。 在MNIST数据集上,每个类大约10%的样本。假设有N个样本,真实标签均匀分布(实际MNIST接近均匀)。 Loss = - \frac{1}{N} \left[ \sum_{\text{true=6}} \log(1) + \sum_{\text{true≠6}} \log(\epsilon) \right] ≈ - \frac{1}{N} \left[ 0 + (0.9N) \log(\epsilon) \right] = -0.9 \log(\epsilon) 通常,epsilon是10^{-7}或类似,log(epsilon) ≈ log(1e-7) ≈ -16.118, so loss ≈ -0.9 * (-16.118) ≈ 14.5, 但用户报告损失在2.29-2.3,所以不是完美输出全1。 或许模型输出不是完美one-hot。损失值2.3提示我们计算理想情况。 对于10类均匀分布,如果模型预测均匀概率[0.1,0.1,...,0.1],那么损失为 -log(0.1) = 2.302585(因为每个样本损失= -sum y_c log(p_c) = -1*log(0.1) since one-hot, so L = -log(0.1) ≈ 2.302) 用户报告损失在2.29-2.3,非常接近2.302585!这意味着模型可能总是在预测接近均匀分布的概率,即每个类概率约为0.1。 但用户说输出结果全为6,意思是argmax总是6,所以预测概率p_i的最大值在索引6,但值可能不高。 argmax总是6,但概率值可能不高;例如,p(6)=0.11, p(other)=0.09 or something, but that wouldn&#39;t give loss around 2.3. 如果argmax总是6,但概率分布是softmax输出,如果总是预测相同类,但由于softmax,如果logits差异小,概率可能接近均匀。 具体计算:假设模型输出logits z_c,对所有样本相同(因为是恒定输出)。假设z_c = 0 for all c? 那么softmax p_c = e^0 / sum e^0 = 1/10 for each c. 此时损失L = -log(1/10) = log(10) ≈ 2.302585,准确率:如果真实标签均匀,argmax随机,准确率约10%,平均损失恒定。 但argmax会随机选择类,因为所有概率相等。用户说输出全为6,所以argmax总是6,这意味着logit for 6 is higher than others. 假设模型输出logits where z_6 = a, z_c = 0 for c≠6. Then softmax p_6 = e^a / (e^a + 9*e^0) = e^a / (e^a + 9) p_c = 1 / (e^a + 9) for c≠6. 损失对于真实标签: - 如果真实=6,损失 = -log(p_6) = -log( e^a / (e^a + 9) ) - 如果真实≠6,损失 = -log(p_c) = -log( 1 / (e^a + 9) ) = log(e^a + 9) 平均损失 L = 0.1 * [ -log( e^a / (e^a + 9) ) ] + 0.9 * log(e^a + 9) 令x = e^a, then L = 0.1 * [ -log(x / (x + 9)) ] + 0.9 * log(x + 9) = 0.1 * [ - (log(x) - log(x+9)) ] + 0.9 * log(x+9) = 0.1 * [ -log(x) + log(x+9) ] + 0.9 * log(x+9) = 0.1 * [-log(x)] + 0.1 * log(x+9) + 0.9 * log(x+9) = -0.1 log(x) + (0.1 + 0.9) log(x+9) = -0.1 log(x) + log(x+9) 现在,L ≈ 2.3,所以 -0.1 log(x) + log(x+9) ≈ log(10) 因为 log(10)≈2.302 例如,如果x=1 (a=0), then L = -0.1*log(1) + log(1+9) = 0 + log(10) ≈2.302 但此时p_6 = 1/(1+9)=0.1, p_c=0.1 for all, so argmax is random, not always 6. 用户说输出全为6,所以argmax总是6,这意味着p_6 > p_c for other c, so z_6 > z_c, so x>1. 假设x large, say x=100, then p_6 = 100/(100+9)≈0.917, p_c≈0.009 for c≠6. 损失L = -0.1 log(100) + log(100+9) = -0.1*4.605 + log(109) ≈ -0.4605 + 4.691 ≈ 4.2305, which is higher than 2.3. 如果x=10, p_6=10/(10+9)≈0.526, p_c=1/19≈0.0526 L = -0.1 log(10) + log(19) = -0.1*2.3026 + 2.9444 ≈ -0.2303 + 2.9444 ≈ 2.714 仍然高于2.3。 如果x=1, L=2.302 as above, but argmax not always 6. 为了argmax总是6,需要p_6 > p_c for all c, so e^a / (e^a + sum e^{z_c}) > e^{z_c} / denominator for each c≠6, which requires z_6 > max_{c≠6} z_c. 但为了损失接近2.3,概率需要接近均匀。 然而,用户报告损失在2.29-2.3,恒定,准确率10%,输出全为6。 可能模型在训练中没有更新,权重初始化为零或有偏置,导致输出偏向类6。 常见原因: - 学习率太高或太低。 - 权重初始化问题。 - 数据没有正确归一化或预处理。 - 输出层偏置设置不当。 - 损失函数实现有问题。 - 梯度消失或爆炸。 - 数据泄漏或标签不平衡,但MNIST是平衡的。 准确率10%表示随机水平,损失恒定表示模型没有学习。 输出全为6:可能初始预测偏向类6,例如,如果输出层的偏置为类6设置得较高。 在神经网络中,对于分类,最后一层全连接层输出logits。如果权重初始化为零,偏置初始化为零,那么初始logits全为零,softmax后概率均匀,argmax随机,损失≈log(10),准确率10%。 但用户说输出全为6,所以argmax总是6,不是随机。这意味着初始预测偏向类6。 可能的原因: 1. 权重初始化不当:例如,类6的权重初始化较大。 2. 数据问题:训练数据中类6的样本更多?但MNIST是平衡的。 3. 实现bug:在模型中,类6的偏置被错误设置。 4. 优化器问题:梯度没有正确传播。 5. 损失函数错误:交叉熵实现有误。 解决方案: - 检查权重初始化:确保权重随机初始化,偏置为零。 - 检查学习率:尝试调整学习率,使用更小的值。 - 监视梯度:打印梯度,看它们是否接近于零(梯度消失)或很大(爆炸)。 - 简化模型:从简单模型开始诊断。 - 数据检查:确保数据加载正确,标签正确。 - 计算损失手动:在代码中手动计算损失,验证是否正确。 - 使用调试工具:逐步调试训练循环。 现在,结构回答: - 逐步解决问题。 - 先解释原因可能是什么。 - 然后提供解决方案列表。 - 最后生成相关问题。 使用中文。 引用:如果需要引用一般知识,可以添加引用标记,但这不是学术文本,所以可能不需要。系统指令说“引用的段落末尾自然地添加引用标识”,但这里没有具体引用来源。我应该基于通用知识。 生成相关问题:在最后添加相关问题。 回答结构: 1. **原因分析**:解释为什么模型输出全为6,准确率10%,损失恒定。 2. **解决方案**:列出步骤来修复问题。 3. **相关问题**:生成几个相关问题。 原因: - 模型初始化或训练问题导致预测偏向特定类(这里是6),且没有学习。 - 损失恒定在2.3表示模型预测概率接近均匀分布,但argmax总是6矛盾?除非概率分布有轻微偏向类6,但损失仍近2.3。 例如,假设 logits: z_6 = 0.1, z_c=0 for c≠6. Then p_6 = e^{0.1}/(e^{0.1} + 9) ≈ 1.105 / (1.105 + 9) ≈ 1.105/10.105 ≈ 0.1094, p_c≈1/10.105≈0.099. 损失: for true=6, -log(0.1094)≈2.17; for true≠6, -log(0.099)≈2.31; average ≈0.1*2.17 + 0.9*2.31≈0.217+2.079=2.296, close to 2.3. 准确率: if argmax always 6, then when true=6, correct, else wrong. So accuracy = P(true=6) = 10% since uniform. 完美匹配!所以模型可能在输出 logits where only z_6 is slightly higher, others zero or low. 可能原因: - 权重初始化为小值,但类6的偏置初始化为正小值。 - 数据预处理问题,导致输入偏向类6的特征。 - 优化器未能更新权重。 解决方案: 1. **检查初始化**:确保权重随机初始化(例如,使用He或Xavier初始化),偏置初始化为零。 2. **调整学习率**:学习率可能太高(导致振荡)或太低(不更新)。尝试标准值如0.001或使用学习率调度。 3. **监视梯度**:在训练中打印梯度范数;如果梯度太小,可能是梯度消失;如果太大,可能是爆炸。 4. **验证数据加载**:确保训练数据正确加载和归一化(例如,MNIST像素值缩放为0-1)。 5. **简化模型**:尝试更小的模型或单个层,以排除架构问题。 6. **检查损失函数**:确保交叉熵实现正确,特别是在处理logits和softmax时。 7. **添加正则化**:如果过拟合或欠拟合,添加dropout或L2正则化。 8. **训练日志**:监视训练和验证损失、准确率;如果损失不下降,可能需要更长时间训练或调整。 9. **调试代码**:仔细检查训练循环、优化器步骤、梯度计算。 相关问题: 1. 如何初始化神经网络权重以获得更好训练? 2. 如何选择合适的学习率? 3. 交叉熵损失函数在PyTorch或TensorFlow中如何正确实现? 4. 手写体数字识别中常见的数据预处理步骤有哪些? 5. 为什么梯度消失会影响模型训练?如何解决? </think>### 手写体数字识别模型输出全为6、准确率10%且损失恒定的原因及解决方案 在训练手写体数字识别模型(如基于MNIST数据集)时,遇到输出结果全为类别6、准确率约10%、交叉熵损失值恒定在2.29-2.3之间的问题,表明模型未能有效学习。以下我将逐步分析原因并提供解决方案,确保回答基于深度学习原理和常见实践[^1]。 --- ### 原因分析 模型出现这种行为,通常源于训练过程中的初始化问题、优化器失效或数据预处理错误。关键点如下: 1. **恒定损失值≈2.3的数学解释**: 对于10类分类问题(类别0-9),交叉熵损失定义为: $$ L = -\frac{1}{N} \sum_{i=1}^{N} \sum_{c=0}^{9} y_{i,c} \log(p_{i,c}) $$ 其中$y_{i,c}$是真实标签(one-hot编码),$p_{i,c}$是模型预测的概率。 - 如果模型预测概率接近均匀分布(即每个类别$p_{i,c} \approx 0.1$),则损失值理论计算为$-\log(0.1) \approx 2.302585$,这与您报告的2.29-2.3高度一致[^1]。 - 准确率10%对应随机猜测水平,因为MNIST数据集类别分布均匀(每个类约占10%样本)。 2. **输出全为类别6的成因**: - **权重初始化不当**:模型输出层的权重或偏置可能初始化不当,导致logits(未归一化的分数)偏向类别6。例如: - 如果输出层偏置$b_6$被初始化为一个小正数(如0.1),而其他偏置为0,则softmax后$p_6$略高于其他类别(如$p_6 \approx 0.109$,其他$p_c \approx 0.099$),使得$\arg\max$始终输出6,但概率分布整体接近均匀,损失≈2.3- 计算示例:假设logits $z_6 = 0.1$, $z_c = 0$($c \neq 6$),则$p_6 = e^{0.1} / (e^{0.1} + 9) \approx 0.109$,损失平均值为$0.1 \times (-\log(0.109)) + 0.9 \times (-\log(0.099)) \approx 2.296$。 - **优化器失效**:学习率不当(过高或过低)、梯度消失或实现错误可能阻止权重更新,模型停滞在初始状态,无法从数据中学习。 - **数据或预处理问题**:输入数据未正确归一化(如MNIST像素值未缩放到[0,1]),或标签编码错误,导致模型无法捕捉特征差异。 - **损失函数实现bug**:自定义交叉熵损失计算可能有误,例如未正确处理logits或softmax,导致梯度无法反向传播。 3. **损失恒定的深层原因**: - 表示模型参数在训练中未更新,梯度接近于零(梯度消失)或优化器失效,常见于学习率设置错误或初始化权重过大/过小[^1]。 --- ### 解决方案 以下是针对该问题的逐步解决方案,建议按顺序排查: 1. **检查并修复权重初始化**: - 确保输出层权重使用随机初始化(如He初始化或Xavier初始化),偏置初始化为零。例如在PyTorch中: ```python import torch.nn as nn model = nn.Sequential( nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 10) # 默认使用均匀分布初始化偏置为0 ) # 显式初始化偏置为零 nn.init.zeros_(model[2].bias) ``` - 验证初始化后预测分布:在训练前运行模型,检查输出概率是否均匀(不应偏向任何类)。 2. **调整优化器和学习率**: - 尝试较小学习率(例如0.001),并使用自适应优化器如Adam: ```python import torch.optim as optim optimizer = optim.Adam(model.parameters(), lr=0.001) ``` - 添加学习率调度器(如`ReduceLROnPlateau`),在损失不下降时自动调整。 - 监视梯度:在训练循环中打印梯度范数,确保其非零: ```python for epoch in range(epochs): optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() # 打印梯度均值 print(f"Gradient norm: {torch.norm(model[2].weight.grad)}") optimizer.step() ``` 如果梯度接近零,需检查反向传播或降低初始化权重。 3. **验证数据预处理和加载**: - MNIST数据应归一化:像素值除以255.0,缩放至[0,1]。 - 确保标签正确编码(整数0-9),无顺序错误。 - 使用数据增强(如随机旋转)测试是否改善学习。 4. **检查损失函数实现**: - 使用框架内置损失函数(如PyTorch的`nn.CrossEntropyLoss()`或TensorFlow的`tf.keras.losses.SparseCategoricalCrossentropy()`), 避免手动实现错误。 - 手动验证损失计算:对于一批数据,比对手动计算与框架输出是否一致。 5. **简化模型和训练过程**: - 从简单模型起步(如单层全连接网络),排除架构复杂性影响。 - 减少训练数据量:在小数据集(如512个样本)上测试,loss应快速下降;若不下降,则是初始化或优化器问题。 - 添加Dropout层(如`nn.Dropout(0.2)`)或L2正则化,防止过拟合导致的停滞。 6. **监视训练指标**: - 记录每个epoch的训练/验证损失和准确率。如果损失不下降且准确率停滞,需早停并调整超参数。 - 可视化权重分布:使用工具(如TensorBoard)检查输出层权重是否更新。 通过以上步骤,多数情况下模型能恢复正常学习。典型修复后,损失应开始下降,准确率提升(如MNIST上可达98%+)。 --- ### 相关问题 1. 如何诊断神经网络中的梯度消失或爆炸问题? 2. 权重初始化方法(如He初始化)如何影响模型训练稳定性? 3. 在图像分类任务中,有哪些常见的数据预处理最佳实践? 4. 为什么优化器选择(如Adam vs SGD)对模型收敛至关重要? 5. 如何调整学习率调度器以加速模型收敛? [^1]: Deep Learning (Ian Goodfellow et al.), Chapter 8: Optimization for Training Deep Models.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值