训练不稳定诱导平坦偏向

引言

训练不稳定在梯度下降中通常被视为需要避免的问题。但最新研究表明1训练不稳定性实际上通过诱导参数向平坦区域移动来改善泛化

本文系统介绍这一反直觉发现的理论机制和实验验证。


背景:Edge of Stability

Edge of Stability现象

当使用大学习率训练深度网络时,观察到:

  1. 非单调损失下降:损失虽然振荡但整体下降
  2. Hessian振荡 附近振荡
  3. 隐式平坦化:收敛到相对平坦的最小值

经典稳定性理论

传统分析要求学习率 以保证:

  • 单调损失下降
  • 稳定收敛

实际训练中的反常

def demonstrate_unstable_benefit():
    """
    展示不稳定训练的优势
    """
    configs = [
        ('stable', {'lr': 0.001}),      # 稳定区域
        ('edge_of_stability', {'lr': 0.01}),  # Edge of Stability
        ('unstable', {'lr': 0.1})        # 不稳定区域
    ]
    
    results = {}
    for name, config in configs:
        model = train_model(config)
        
        # 评估
        test_acc = evaluate(model, test_set)
        sharpness = compute_sharpness(model)
        robustness = evaluate_robustness(model)
        
        results[name] = {
            'test_accuracy': test_acc,
            'sharpness': sharpness,
            'robustness': robustness
        }
    
    return results

典型结果:

配置测试准确率锐度鲁棒性
稳定区域91.2%0.1552%
Edge of Stability93.5%0.0871%
不稳定区域92.8%0.0668%

观察:不稳定训练反而导致更好的泛化和更平坦的最小值!


理论机制:旋转极性(Rotational Polarity)

核心发现

训练不稳定性通过**旋转极性(Rotational Polarity of Eigenvectors, RPE)**机制诱导平坦化。

Hessian特征向量旋转

在不稳定阶段,Hessian的主要特征向量发生旋转:

def observe_eigenvector_rotation(model, dataloader):
    """
    观察Hessian特征向量旋转
    """
    # 计算Hessian
    hessian = compute_hessian(model, dataloader)
    
    # 特征分解
    eigenvalues, eigenvectors = np.linalg.eigh(hessian)
    
    # 跟踪特征向量变化
    rotations = []
    prev_eigenvectors = None
    
    for step in range(num_steps):
        eigenvalues_t, eigenvectors_t = compute_hessian_eigendecomposition(model)
        
        if prev_eigenvectors is not None:
            # 计算旋转角度
            rotation = compute_rotation_angle(
                prev_eigenvectors, 
                eigenvectors_t
            )
            rotations.append(rotation)
        
        prev_eigenvectors = eigenvectors_t
    
    return rotations

旋转与学习率的关系

定理:特征向量旋转角度 与学习率 正相关:

旋转的泛化效应

def analyze_rotation_effect():
    """
    分析旋转对泛化的影响
    """
    # 小旋转:停留在当前谷底
    # 大旋转:探索新的参数方向
    
    return {
        'small_rotation': {
            'path': 'local_valley',
            'sharpness': 'high',
            'generalization': 'poor'
        },
        'large_rotation': {
            'path': 'exploration',
            'sharpness': 'low',
            'generalization': 'good'
        }
    }

探索性动力学

不稳定阶段的探索

训练不稳定性引发探索性动力学

  1. 方向探索:特征向量旋转探索不同参数方向
  2. 深度探索:跳出尖锐局部最小值
  3. 广度探索:发现更平坦的解

动力学方程

考虑Hessian特征向量 的演化:

其中 为正交方向, 为旋转角。

探索效率

def measure_exploration_efficiency(model, initial_params):
    """
    测量探索效率
    """
    # 跟踪参数轨迹
    trajectory = []
    sharpness_history = []
    
    for step in range(num_steps):
        trajectory.append(get_params(model))
        sharpness_history.append(compute_sharpness(model))
        train_step(model)
    
    # 计算探索覆盖
    coverage = compute_param_space_coverage(trajectory)
    
    # 计算平坦化程度
    flatness_improvement = sharpness_history[0] - sharpness_history[-1]
    
    return {
        'coverage': coverage,
        'flatness_improvement': flatness_improvement
    }

理论证明

引理1:旋转诱导平坦化

引理:当特征向量旋转时,参数空间中的曲率估计会平均化:

引理2:不稳定→平坦映射

引理:不稳定训练的不稳定程度与最终解的平坦程度正相关:

定理:不稳定诱导平坦偏向

定理:梯度下降在不稳定区域运行时,隐式最小化以下目标:

其中 随学习率增加。

证明概要

def proof_outline():
    """
    证明概要
    """
    steps = [
        "1. 将GD动态分解为沿Hessian特征向量的分量",
        "2. 证明不稳定阶段的旋转效果",
        "3. 推导旋转与曲率的关系",
        "4. 建立旋转与平坦化的联系",
        "5. 证明隐式优化目标"
    ]
    
    return steps

扩展到SGD

随机梯度的影响

SGD中的梯度噪声也诱导类似效应:

def analyze_sgd_noise_effect():
    """
    分析SGD噪声对平坦化的影响
    """
    # 噪声协方差
    noise_cov = compute_gradient_noise_covariance(model)
    
    # 有效旋转
    effective_rotation = compute_effective_rotation(
        learning_rate,
        noise_cov,
        hessian
    )
    
    return {
        'noise_covariance': noise_cov,
        'effective_rotation': effective_rotation,
        'stability_contribution': 'noise vs learning_rate'
    }

关键发现

发现:在SGD中,不稳定性诱导的平坦化效应超过小批量噪声的影响:

实验验证

设置学习率噪声水平锐度泛化误差
SGD大batch0.010.128.8%
SGD小batch0.010.097.2%
SGD大batch + 不稳定0.050.055.9%

与自适应优化器的结合

Adam中的不稳定性恢复

发现:在Adam中恢复训练不稳定性可以进一步改善泛化:

def experiment_adam_instability():
    """
    Adam + 不稳定训练实验
    """
    configs = [
        ('adam_standard', {'optimizer': 'adam', 'lr': 1e-3}),
        ('adam_eps_small', {'optimizer': 'adam', 'lr': 1e-3, 'eps': 1e-8}),
        ('adam_recovered_instability', {
            'optimizer': 'adam', 
            'lr': 1e-3, 
            'eps_schedule': 'increasing'
        })
    ]
    
    results = {}
    for name, config in configs:
        model = train_model(config)
        results[name] = evaluate(model)
    
    return results
配置测试准确率锐度
Adam标准93.1%0.10
Adam eps=1e-893.4%0.08
Adam恢复不稳定94.2%0.05

机制解释

def explain_mechanism():
    """
    机制解释
    """
    return {
        'adam_standard': {
            'bias_correction': 'reduce effective lr',
            'instability': 'suppressed',
            'flatness': 'moderate'
        },
        'adam_recovered': {
            'bias_correction': 'preserved',
            'instability': 'restored',
            'flatness': 'enhanced'
        }
    }

实践指导

学习率调度

class InstabilityAwareScheduler:
    """
    不稳定性感知的学习率调度
    """
    
    def __init__(self, base_lr, model):
        self.base_lr = base_lr
        self.model = model
        self.stability_threshold = 2.0  # λ_max / lr
    
    def step(self):
        """单步调度"""
        current_lr = self.get_current_lr()
        
        # 测量稳定性
        hessian = compute_hessian(self.model)
        lambda_max = torch.linalg.eigvalsh(hessian).max()
        stability = lambda_max / current_lr
        
        # 如果过于稳定,增加学习率
        if stability > self.stability_threshold * 1.2:
            new_lr = current_lr * 1.1
        # 如果过于不稳定,减少学习率
        elif stability < self.stability_threshold * 0.8:
            new_lr = current_lr * 0.9
        else:
            new_lr = current_lr
        
        self.set_lr(new_lr)
    
    def get_current_lr(self):
        """获取当前学习率"""
        return self.optimizer.param_groups[0]['lr']

最优不稳定性水平

def find_optimal_instability(model, dataloader):
    """
    寻找最优不稳定性水平
    """
    results = []
    
    for lr in [0.001, 0.005, 0.01, 0.02, 0.05, 0.1]:
        model_copy = copy.deepcopy(model)
        train_with_lr(model_copy, dataloader, lr)
        
        sharpness = compute_sharpness(model_copy)
        accuracy = evaluate(model_copy, test_set)
        
        results.append({
            'lr': lr,
            'sharpness': sharpness,
            'accuracy': accuracy
        })
    
    # 找到最优配置
    best = max(results, key=lambda x: x['accuracy'])
    
    return best

诊断工具

class StabilityMonitor:
    """
    稳定性监控器
    """
    
    @staticmethod
    def diagnose(model, dataloader):
        """
        诊断当前训练的稳定性
        """
        # 计算Hessian特征值
        hessian = compute_hessian(model, dataloader)
        eigenvalues = torch.linalg.eigvalsh(hessian)
        
        # 计算稳定性指标
        lambda_max = eigenvalues[-1]
        lr = get_current_lr(model)
        stability_ratio = lambda_max / (2 / lr)
        
        return {
            'lambda_max': lambda_max.item(),
            'stability_ratio': stability_ratio.item(),
            'status': 'stable' if stability_ratio < 0.8 else 
                     'edge_of_stability' if stability_ratio < 1.2 else 
                     'unstable'
        }

与其他工作的关系

相比SAM

方面SAM不稳定性诱导平坦化
机制显式扰动隐式旋转
计算成本2×前向传播无额外成本
效果相当或更好
可控性

相比Weight Decay

方面Weight Decay不稳定性诱导
参数锐度影响增加增加
函数锐度影响降低降低
泛化效果
机制显式正则化隐式探索

总结

本文揭示了训练不稳定性改善泛化的理论机制:

  1. 反直觉发现:训练不稳定反而改善泛化
  2. 旋转极性机制:特征向量旋转诱导参数探索
  3. 探索性动力学:不稳定阶段探索更多参数方向
  4. SGD扩展:不稳定性效应超过噪声影响
  5. 实践指导:恢复Adam中的不稳定性可进一步改善

这一发现为理解和利用训练动态提供了新视角,也为设计更好的优化算法提供了启示。


参考文献

相关链接:edge-of-stability-convergence-rates | function-centric-minima-perspective | sharp-flat-minima

Footnotes

  1. Anonymous. “Training Instabilities Induce Flatness Bias in Gradient Descent.” arXiv:2511.12558 (2025).