电路假说验证

1. 概述

电路假说(Circuit Hypothesis)是机制可解释性的核心假设,它声称神经网络的特定行为可以归因于网络中相对局部化、可识别的子电路。然而,验证这一假说需要严格的统计方法。本章介绍电路假说验证的理论框架和实践方法。

2. 电路假说的形式化

2.1 基本定义

给定神经网络 和行为 ,电路假说可以形式化为:

2.2 因果贡献的度量

对于电路 中的组件集合 ,定义其因果贡献为:

其中:

  • 是保留电路 的模型输出
  • 是将电路 置零的模型输出

3. 完整性充分性框架

3.1 完整性分数

完整性分数(Comprehensiveness Score) 衡量电路对行为的解释程度:

其中 是完整模型相对于基线的效应。

def comprehensiveness_score(model, circuit, test_cases, base_model=None):
    """
    计算电路的完整性分数
    """
    full_effect = compute_effect(model, test_cases, base_model)
    circuit_effect = compute_effect(model, test_cases, base_model, circuit)
    
    return circuit_effect / full_effect

3.2 充分性分数

充分性分数(Sufficiency Score) 衡量电路单独能够解释行为的程度:

def sufficiency_score(model, circuit, test_cases):
    """
    计算电路的充分性分数
    """
    isolated_effects = []
    
    for case in test_cases:
        # 仅激活电路组件,其他置零
        output = model.forward_with_circuit(case.input, circuit)
        score = evaluate_output(output, case.target)
        isolated_effects.append(score)
    
    return np.mean(isolated_effects)

3.3 组合分数

综合完整性和充分性:

4. 统计假设检验

4.1 检验统计量

定义检验统计量

其中 是第 个测试样本的因果效应。

4.2 零假设构造

通过以下方式构造零假设分布:

  1. 随机化电路:随机选择等大小的组件集合
  2. 置换测试:随机打乱样本-标签配对
  3. Bootstrap:从原始分布重采样
class CircuitHypothesisTest:
    def __init__(self, model, circuit, test_cases):
        self.model = model
        self.circuit = circuit
        self.test_cases = test_cases
        
    def permutation_test(self, num_permutations=1000):
        """
        置换检验验证电路假说
        """
        # 计算真实电路效应
        observed_effect = self.compute_circuit_effect()
        
        # 生成零假设分布
        null_distribution = []
        for _ in range(num_permutations):
            # 随机置换样本
            shuffled_cases = self.shuffle_labels(self.test_cases)
            # 计算随机电路效应
            random_effect = self.compute_effect_with_cases(shuffled_cases)
            null_distribution.append(random_effect)
        
        # 计算p值
        p_value = np.mean([
            null >= observed_effect 
            for null in null_distribution
        ])
        
        return {
            'observed_effect': observed_effect,
            'p_value': p_value,
            'significant': p_value < 0.05
        }
    
    def shuffle_labels(self, cases):
        """置换样本标签"""
        inputs = [c.input for c in cases]
        targets = [c.target for c in cases]
        shuffled_targets = targets.copy()
        np.random.shuffle(shuffled_targets)
        return [TestCase(inp, tgt) for inp, tgt in zip(inputs, shuffled_targets)]

4.3 多重比较校正

当检验多个组件时,需要进行多重比较校正:

from scipy import stats
 
def bonferroni_correction(p_values, alpha=0.05):
    """
    Bonferroni校正
    """
    n_tests = len(p_values)
    corrected_alpha = alpha / n_tests
    significant = [p < corrected_alpha for p in p_values]
    return significant
 
def fdr_correction(p_values, q=0.05):
    """
    FDR (False Discovery Rate) 校正
    """
    sorted_indices = np.argsort(p_values)
    n = len(p_values)
    
    for i, idx in enumerate(sorted_indices):
        threshold = (i + 1) / n * q
        if p_values[idx] > threshold:
            break
        significant_indices = sorted_indices[:i + 1]
    
    return [i in significant_indices for i in range(n)]

5. 因果效应估计

5.1 平均处理效应

5.2 方差估计

def estimate_variance(effects, bootstrap_samples=1000):
    """
    Bootstrap方差估计
    """
    n = len(effects)
    bootstrap_means = []
    
    for _ in range(bootstrap_samples):
        indices = np.random.choice(n, size=n, replace=True)
        bootstrap_mean = np.mean([effects[i] for i in indices])
        bootstrap_means.append(bootstrap_mean)
    
    return np.std(bootstrap_means)
 
def confidence_interval(effect, std_err, confidence=0.95):
    """
    计算置信区间
    """
    z = stats.norm.ppf((1 + confidence) / 2)
    margin = z * std_err
    return (effect - margin, effect + margin)

6. 实验设计

6.1 样本选择

def select_test_samples(model, task, num_samples=100):
    """
    选择具有区分性的测试样本
    """
    samples = []
    
    for _ in range(num_samples * 2):  # 预留筛选
        sample = generate_sample(task)
        prediction = model.predict(sample.input)
        
        # 选择模型确实学习的样本
        if prediction == sample.target:
            samples.append(sample)
            
        if len(samples) >= num_samples:
            break
    
    return samples

6.2 对照实验

def controlled_experiment(model, circuit, test_cases):
    """
    设计对照实验
    """
    conditions = {
        'full_model': test_cases,                    # 完整模型
        'circuit_only': test_cases,                  # 仅电路
        'no_circuit': test_cases,                   # 无电路
        'random_circuit': test_cases,               # 随机电路
    }
    
    results = {}
    for name, cases in conditions.items():
        if name == 'full_model':
            outputs = [model.predict(c.input) for c in cases]
        elif name == 'circuit_only':
            outputs = [model.forward_circuit_only(c.input, circuit) for c in cases]
        elif name == 'no_circuit':
            outputs = [model.forward_without_circuit(c.input, circuit) for c in cases]
        else:  # random_circuit
            random_circuit = sample_random_circuit(circuit)
            outputs = [model.forward_circuit_only(c.input, random_circuit) for c in cases]
        
        results[name] = {
            'accuracy': compute_accuracy(outputs, cases),
            'effect': compute_effect_from_outputs(outputs, cases)
        }
    
    return results

7. 与其他方法的对比

7.1 与SAE的对比

维度电路假说验证Sparse Autoencoders
目标验证特定行为的因果机制发现通用的语义特征
方法统计假设检验无监督字典学习
输出行为归因特征分解
可验证性直接验证间接验证

7.2 与传统归因方法的对比

def compare_methods(model, input_data, target, methods=['integrated_gradients', 'circuit', 'shap']):
    """
    比较不同归因方法的输出
    """
    results = {}
    
    for method in methods:
        if method == 'integrated_gradients':
            attr = integrated_gradients(model, input_data)
        elif method == 'circuit':
            attr = circuit_attribution(model, input_data, target)
        elif method == 'shap':
            attr = shap_values(model, input_data)
        
        results[method] = attr
    
    # 计算方法间的一致性
    correlations = compute_method_correlations(results)
    
    return results, correlations

8. 实践指南

8.1 最佳实践

  1. 多样化测试集:确保测试样本覆盖不同情境
  2. 控制混淆变量:确保实验条件一致
  3. 报告不确定性:给出置信区间和p值
  4. 可复现性:记录随机种子和实验设置

8.2 常见陷阱

  • 过拟合测试集:使用独立的验证集
  • 忽略方差:报告置信区间而非点估计
  • 多重比较:使用适当的校正方法
  • 虚假因果:注意相关不等于因果

9. 总结

电路假说验证为机制可解释性提供了严格的统计基础。通过完整性-充分性框架、假设检验和对照实验,我们可以:

  1. 量化电路对行为的因果贡献
  2. 验证电路假说的统计显著性
  3. 比较不同电路结构的解释力

这些方法对于构建可靠的、可解释的AI系统至关重要。


参考资料