# AutoEncoding **Repository Path**: char-x/auto-encoding ## Basic Information - **Project Name**: AutoEncoding - **Description**: 音频卡顿分析脚本AutoEncoding - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-16 - **Last Updated**: 2026-07-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 音频异常检测工具集 --- ## 安装 **macOS (Apple Silicon):** ```bash chmod +x setup_mac.sh && ./setup_mac.sh ``` **Windows / Linux:** ```bash pip install torch librosa numpy scipy matplotlib soundfile ``` --- ## Bark 尺度变换 ### 频率 → Bark ``` Bark(f) = 13·arctan(0.00076·f) + 3.5·arctan((f/7500)²) ``` ### Bark → 频率 (Newton-Raphson) ``` 初始值: f₀ = 1960·(z + 0.53) / (26.28 - z) 导数: d(f) = 13·0.00076 / (1+(0.00076f)²) + 3.5·2·(f/7500)·(1/7500) / (1+(f/7500)²) 迭代: f ← f + (z - Bark(f)) / d(f), 直到 |Δ| < 1e-6 ``` ### 24 组三角滤波器 滤波器 k 由三个边界频率定义:`[lo_k, center_k, hi_k]`。 `center_k = Bark⁻¹(linspace(Bark(0), Bark(Nyquist), 26))`。 每带响应为三角窗:边界处=0,中心=1。 Bark 带能量 = `FFT_power @ H.T`(矩阵乘,一次性完成映射)。 ### 频率表 (标准临界频带,1 Bark/带) "带号" = 该带在 Bark 尺度上的起始值。 | 带 | Bark 范围 | 下界 Hz | 中心 Hz | 上界 Hz | 带宽 Hz | |----|----------|--------|---------|--------|---------| | 1 | [0, 1) | 0 | 50 | 101 | 101 | | 2 | [1, 2) | 101 | 152 | 203 | 102 | | 3 | [2, 3) | 203 | 255 | 308 | 105 | | 4 | [3, 4) | 308 | 362 | 416 | 108 | | 5 | [4, 5) | 416 | 472 | 530 | 114 | | 6 | [5, 6) | 530 | 589 | 651 | 121 | | 7 | [6, 7) | 651 | 714 | 780 | 130 | | 8 | [7, 8) | 780 | 849 | 922 | 142 | | 9 | [8, 9) | 922 | 998 | 1078 | 156 | | 10 | [9, 10) | 1078 | 1164 | 1254 | 176 | | 11 | [10, 11) | 1254 | 1351 | 1456 | 202 | | 12 | [11, 12) | 1456 | 1568 | 1690 | 234 | | 13 | [12, 13) | 1690 | 1823 | 1968 | 278 | | 14 | [13, 14) | 1968 | 2127 | 2302 | 334 | | 15 | [14, 15) | 2302 | 2496 | 2710 | 408 | | 16 | [15, 16) | 2710 | 2948 | 3211 | 501 | | 17 | [16, 17) | 3211 | 3502 | 3822 | 611 | | 18 | [17, 18) | 3822 | 4172 | 4553 | 731 | | 19 | [18, 19) | 4553 | 4966 | 5411 | 858 | | 20 | [19, 20) | 5411 | 5892 | 6413 | 1002 | | 21 | [20, 21) | 6413 | 6984 | 7617 | 1204 | 21 带共覆盖 0–21 Bark,与 16kHz Nyquist (≈21.28 Bark) 对齐。 低频带宽约 100Hz,高频带宽达 1200Hz,符合人耳临界带宽特性。 --- ## 1. 平滑度分歧检测(推荐,无需训练) 前后拉格朗日外推分歧 + LPF 百分位自适应阈值 + 双峰边缘配对。 ```bash python3 smoothness_detect.py sample.m4a python3 smoothness_detect.py sample.m4a --save-excep --pct 99.99 ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--window` | 50 | 配对窗口 ms | | `--lpf` | 10 | LPF 基线窗口 ms | | `--pct` | 99.99 | 百分位阈值 | | `--save-excep` | — | 保存事件图到 `bimodal_events/` | | `--show` | — | GUI 弹窗 | ### 公式 ``` pf = 3·x[i-1] - 3·x[i-2] + 1·x[i-3] (前向拉格朗日) pb = 3·x[i+1] - 3·x[i+2] + 1·x[i+3] (后向拉格朗日) e = |pf-pb| + |pf-x| + |pb-x| (三向分歧) r = e / LPF(e, 10ms) (局部自归一化) ``` 阈值 = ratio 的 P0.01%。边缘配对:50ms 内方向相反 → 上报事件。 --- ## 2. 频谱自编码器(配置文件驱动) 音频分块 FFT → N 维频谱 → 全连接 AE → 重建误差检测异常。 RAW 模式:线性频点;FFT 模式:log-magnitude (dB);BARK 模式:24 组三角滤波器 → log-power。 ```bash python3 speech_ae_detect.py -f config_train.json # 训练 python3 speech_ae_detect.py -f config_infer.json # 推理 ``` ### MLP 结构 按输入维度自适应(第1隐层=输入×¾,隐空间=第1隐层/2上取整): | 输入 | 结构 | 参数量 | |------|------|--------| | 10 (bark≥11) | 10→7→7→4 | ~390 | | 18 (bark全) | 18→13→13→7 | ~1,100 | | 32 (raw/fft) | 32→24→24→12 | ~3,500 | 所有层间加 BatchNorm + ReLU,输出 Sigmoid 到 [0,1]。 ### 损失函数 统一使用 **MSE + 平坦惩罚**(Bark 和 RAW 模式相同): ``` Loss = MSE(recon, target) + λ / (σ_freq + 1e-4) σ_freq = std(recon, dim=freq) ← 重建频谱方差 λ = 0.05 (lambda_flat) ← 平坦惩罚权重(Bark模式降低) ``` ### 训练配置 `config_train.json`: ```json { "mode": "train", "train_files": ["sample.m4a", "verify.wav"], "exclude_intervals": [[[9, 12], [310, 315]], []], "exclude_csv": ["sample_exclude.csv", "verify_exclude.csv"], "fft_size": 64, "hop": 32, "spectrum_mode": "bark", "bark_min": 11, "window_type": "blackmanharris", "batch_size": 512, "epochs": 150, "lr": 0.0003, "lambda_flat": 0.5, "patience": 25, "output_model": "speech_ae_model.pt" } ``` - `train_files`: 支持多文件 - `exclude_intervals`: 硬编码排除区间,与文件一一对应 - `exclude_csv`: Audition 导出的 CSV,每行 `Start` 列 ±10ms 排除,与文件一一对应 - `hop: 32`: 64 点 FFT 下 50% 重叠,训练样本翻倍 - `bark_min: 11`: 只取 Bark ≥11 的高频带(10维输入),聚焦杂音敏感频段 - CSV 支持 `mm:ss.ms` 和秒数两种格式 ### 推理配置 `config_infer.json`: ```json { "mode": "inference", "file": "sample.m4a", "model": "speech_ae_model.pt", "batch_size": 256, "glitch_intervals": [[310, 315]], "sigma": 4.0, "save_events": true, "events_dir": "spec_events" } ``` ### 完整字段 | 字段 | 模式 | 默认值 | 说明 | |------|------|--------|------| | `mode` | 共用 | 必填 | `train` / `inference` | | `train_files` | train | 必填 | 训练文件路径列表 | | `exclude_intervals` | train | `[]` | 硬编码排除区间,与文件一一对应 | | `exclude_csv` | train | `[]` | CSV 排除文件,`Start` 列 ±10ms,与文件一一对应 | | `fft_size` | train | 64 | FFT 点数 | | `hop` | train | fft | 滑动步长(32=50%重叠) | | `spectrum_mode` | 共用 | `raw` | `raw` / `fft` / `bark` | | `bark_min` | 共用 | 11 | Bark 最低带(只取高频 ≥11) | | `window_type` | 共用 | `blackmanharris` | FFT 窗 | | `batch_size` | 共用 | 512/256 | 批次大小 | | `epochs` | train | 150 | 最大轮数 | | `lr` | train | 0.001 | 学习率 | | `lambda_flat` | train | 0.5 | 平坦惩罚系数 | | `patience` | train | 25 | 早停轮数 | | `output_model` | train | — | 模型保存路径 | | `file` | inference | 必填 | 待检测文件 | | `model` | inference | 必填 | 预训练模型路径 | | `glitch_intervals` | inference | `[]` | 阈值排除区间 | | `sigma` | inference | 4.0 | 阈值倍数 | | `save_events` | inference | false | 导出事件图 | | `events_dir` | inference | `spec_events` | 事件图目录 | ### 窗类型 | 值 | 窗函数 | |----|--------| | `hann` | Hann | | `hamming` | Hamming | | `blackman` | Blackman | | `blackmanharris` | Blackman-Harris (4-term) | | `bartlett` | Bartlett | | 缺省 | Hann | ### 日志 ``` Epoch 50 | train=0.108 val_max=0.15 val_mean=0.06 lr=2.50e-04 ``` | 字段 | 含义 | |------|------| | train | 训练 Loss | | val_max | 验证集最大 MSE | | val_mean | 验证集平均 MSE | | lr | 学习率 (Plateau 自动衰减) | --- ## 3. Bark 热力图 256pt FFT + 24 组三角 Bark 滤波器 → 时间-Bark 带能量热力图。 支持格式:`.wav` / `.m4a` ```bash python3 bark_heatmap.py sample.m4a python3 bark_heatmap.py sample.m4a --n-fft 128 --t-start 310 --t-end 315 ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--n-fft` | 256 | FFT 点数 | | `--hop` | n_fft/2 | 滑动步长 (采样点) | | `--n-bark` | 24 | Bark 滤波器组数 | | `--t-start` | None | 起始时间 (秒),不指定=从头 | | `--t-end` | None | 结束时间 (秒),不指定=到尾 | | `--show` | None | 弹出 GUI 窗口 | --- ## 4. 分频带平坦度 64pt FFT 分块,0-4kHz 和 4-8kHz 分别计算频谱平坦度(几何/算术均值比)。 低于 -90dB 的频点忽略,纵轴对数坐标。 ```bash python3 flatness_plot.py sample.m4a ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--fft` | 64 | FFT 点数 | | `--win` | 32 | 滑动平滑窗口 (块数) | | `--show` | None | 弹出 GUI | --- ## 5. 急动度绘图 三阶导数 (jerk = d³x/dt³),对波形突变极度敏感。 ```bash python3 jerk_plot.py sample.m4a ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--t-start` | 311.965 | 目标区起始 (s) | | `--t-end` | 311.970 | 目标区结束 (s) | | `--show` | None | 弹出 GUI | --- ## 6. 边缘状态机 前向拉格朗日预测 + 动态阈值 + 状态机配对。 ```bash python3 edge_state_detect.py sample.m4a ``` --- ## 7. 交互式频谱分析器 (spectrum_analyzer.py) 四面板实时频谱分析:波形 / 频谱热力图 / FFT 线谱 / Bark 谱 + 心理声学掩蔽阈值。 ```bash python spectrum_analyzer.py # 自动检测当前目录音频 python spectrum_analyzer.py audio.wav # 打开指定文件 python spectrum_analyzer.py audio.m4a --fft 512 --window 0.1 --silence -80 --mask -60 ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--fft` | 512 | FFT 点数 | | `--window` | 0.1 | 波形窗口 ±秒 | | `--time` | 0.0 | 起始时间 (秒) | | `--silence` | -80 | 绝对静音阈值 (dB),控制 ATH 曲线锚点 | | `--mask` | -60 | 掩蔽音最低能量阈值 (dB) | GUI 控制面板:Time / FFT Size / Window / Silence Thr / Mask E Thr 文本框 → 点击 **Update** 按钮渲染。Prev/Next 按半窗口步长移动时间。 ### 心理声学掩蔽模型 #### 扩散函数 (Spreading Function) MPEG-1 心理声学模型 (ISO 11172-3) 的 Schröder 扩散函数: ``` SF(dz) = 15.811389 + 7.5·(dz + 0.474) - 17.5·√(1 + (dz + 0.474)²) [dB] ``` 其中 `dz` 是 Bark 带间距(|i-j|)。同带 z=0 时 SF(0)≈0dB,z=5 时衰减约 -40dB。 **来源:** M. R. Schröder, B. S. Atal, J. L. Hall, "Optimizing Digital Speech Coders by Exploiting Masking Properties of the Human Ear," J. Acoust. Soc. Am. 66(6), 1979. #### 绝对听阈 (Absolute Threshold of Hearing) MPEG-1 / ISO 226 频率相关的绝对听阈曲线: ``` ATH(f) = 3.64·(f/1000)^(-0.8) - 6.5·exp(-0.6·(f/1000 - 3.3)²) + 10^(-3)·(f/1000)^4 [dB SPL] ``` 呈 U 形:2–4 kHz 最敏感 (≈ -3 dB SPL),低频和高频大幅抬升。映射到 Bark 带后锚定到 `silence_thresh`: ``` ATH_per_band(k) = ATH_raw(f_center(k)) - min(ATH_raw) + silence_thresh ``` `silence_thresh` 参数模拟不同重放音量下的人耳感知基线。 **来源:** ISO 226:2003, "Acoustics — Normal equal-loudness-level contours." #### 两遍掩蔽阈值算法 ``` Pass 1(初步阈值): ① 所有 energy > mask_energy_thresh 的 Bark 带作为候选掩蔽源 ② 每个掩蔽源加 -6dB 音调偏移后经扩散函数向所有带扩散(排除自掩蔽) ③ 线性域叠加后与 ATH_per_band 取 max → 初步阈值 筛选: 候选掩蔽源中,energy > 自身初步阈值的 = 真正掩蔽源 (被邻近强峰掩蔽的弱带在此剔除) Pass 2(最终阈值): ④ 仅用真正掩蔽源重复步骤②③ → 最终掩蔽阈值折线 ``` Bark 柱颜色判定:`bark_energy >= mask_threshold` → 蓝色(可闻),否则 → 灰色(被掩蔽)。 --- ## 8. 2D-CNN 杂音概率检测(有监督训练) 对每个采样点输出"发生杂音的概率":输入是该点及前后 ±64 点处三个 64 点 FFT(Blackman-Harris 窗,dB 幅度,32 谱线)组成的 3×32 patch,3 层 3×3 Conv2d → 全局池化 → Sigmoid。 ### 配置文件(推荐) 脚本行为由 JSON 配置文件驱动,优先级:**命令行参数 > JSON 配置 > 内置默认**。JSON 字段与参数同名(`--val-every` ↔ `val_every`)。 ```bash python3 glitch_cnn_train.py -f glitch_train.json # 训练 python3 glitch_cnn_train.py -f glitch_infer.json # 推理 (连乘阈值在文件里改 thresh) python3 glitch_cnn_train.py --mode infer --file a.wav --thresh 0.8 # CLI 覆盖 ``` 不带 `-f` 时自动读 `glitch_.json`;不带任何参数行为与默认一致(训练 verify.wav)。 `glitch_train.json`:`wav` / `csv` / `steps` / `batch` / `lr` / `seed` / `val_every` / `out` / `device`。 `glitch_infer.json`:`file`(推理音频)、`model`(模型路径)、`thresh`(6 点连乘累积概率触发阈值,默认 0.9)、`ms`(出图半窗 ±ms)、`device`。 ### 命令行参数(CLI 覆盖配置) ```bash python3 glitch_cnn_train.py # 默认 verify.wav + verifyIntervalMasked.csv python3 glitch_cnn_train.py --steps 10000 # 全量训练 python3 glitch_cnn_train.py --steps 200 --val-every 100 # 快速冒烟 ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--wav` | `verify.wav` | 训练音频 | | `--csv` | `verifyIntervalMasked.csv` | 杂音区间(Start/Duration 列) | | `--steps` | 10000 | 训练步数(每步 256 均衡采样:128 正 + 128 负) | | `--batch` | 256 | 批大小 | | `--lr` | 1e-3 | 学习率(Cosine 退火) | | `--seed` | 42 | 区间对半划分与采样随机种子 | | `--val-every` | 500 | 验证间隔步数 | | `--out` | `glitch_cnn_model.pt` | 最优模型保存路径 | 标签规则:区间内为三角函数 0.95(两端)→1.0(中点)线性插值,区间外为 0。 防过拟合:随机取一半区间参与训练,另一半仅用于验证(不参与训练); 所有区间核心外侧 ±256 采样点一律不参与训练。 设备自动选择 **MPS (Apple Silicon) > CUDA > CPU**。 ### 训练日志指标 ``` Step 100 | loss=0.1899 | val_auc=0.974 | det_rate=1.000 | fpr=0.1705 | lr=5.00e-04 ``` | 字段 | 含义 | 参考值 | |------|------|--------| | `loss` | 当前批的 BCE 损失。每步采样 128 正 + 128 负均衡批,目标为 0(正常)或 0.95–1.0(区间内三角标签)。0.693 ≈ 随机猜测(ln2),越小越好 | < 0.2 收敛良好 | | `val_auc` | 保留区间验证 AUC(ROC 曲线下面积)。验证集 = 全部保留区间核心点(正)+ 2000 个随机正常点(负),每 `--val-every` 步计算一次。1.0 = 完美区分,0.5 = 随机 | > 0.9 优秀 | | `det_rate` | 检出率:保留区间中"核心内最大预测概率 > 0.5"的占比,即 29 个未参与训练的杂音区间里检出了几个 | 1.000 = 全部检出 | | `fpr` | 误报率:验证集正常点中预测概率 > 0.5 的占比 | 越低越好(目标 < 0.05) | | `lr` | 当前学习率(Cosine 退火,随步数线性降到 0) | — | 保存规则:仅在 `val_auc` 创新高时覆盖保存 `--out` 模型,中途最优模型不会因后续过拟合而丢失。 ### 推理(检测新音频) ```bash python3 glitch_cnn_train.py --mode infer --file audio.wav [--model glitch_cnn_model.pt] python3 glitch_cnn_train.py --mode infer --file audio.m4a --thresh 0.9 --ms 5 ``` | 参数 | 默认 | 说明 | |------|------|------| | `--mode` | `train` | `train` / `infer` | | `--file` | — | 推理音频(wav/m4a,infer 必需) | | `--model` | `glitch_cnn_model.pt` | 训练好的模型 | | `--thresh` | 0.9 | 累积概率触发阈值 | | `--ms` | 5 | 出图半窗 ±ms | | `--plot-events` | — | 逐事件出图(默认只出总图;配置 `plot_events` 同理) | 流程:模型对每个采样点输出杂音概率 p_infer → 累积概率 p[i] = Π_{k∈[i-5,i]} p_infer[k](6 点连乘)→ 默认只输出**总图** `<音频文件名>_summary.png`(逐点 p 曲线 + 阈值线,如 `verify.wav` → `verify_summary.png`),控制台打印事件列表。加 `--plot-events`(或配置 `plot_events: true`)时,每个事件额外保存 ±ms 时域图到与音频同名的文件夹(`audio.wav` → `audio/`,文件名 = 事件时刻秒数,如 `160.455.png`)。 --- ## 设备加速 自动选择 **MPS (Apple Silicon) > CUDA > CPU**。 --- ## 支持格式 `.wav`, `.m4a`。其他格式需先用 ffmpeg 转换。