Wendland 紧支撑核的散点场重建方法

Wendland 紧支撑核的散点场重建方法 Wendland Functions(这篇笔记对 Wendland 核函数的数学构造有更完整的推导) 从散点到连续场 Wendland 并不是“力场重建”专用算法。它更像是一种通用工具:当你手里有一批离散采样点,想把它们变成一个连续场时,Wendland C2 紧支撑核可以作为一个很好的重建核。 问题可以抽象成这样:平面上有一组采样点 $$ (x_i, y_i, v_i), \quad i = 1,2,\dots,N $$其中 $(x_i,y_i)$ 是采样位置,$v_i$ 是这个位置的观测值。我们想得到一个连续函数 $f(x,y)$,让它在没有传感器的位置也能给出合理估计。压力传感器数据只是这个问题的一个例子。换成温度站点、高程采样点、点云属性,甚至仿真里的 collocation points,本质都是“散点样本 → 连续场”。 这里有一个容易混淆的点:这件事到底是“重建”,还是只是“平滑”?我的理解是,平滑更像后期修图,它不关心背后有没有真实函数,只是让数据看起来更顺;重建则先假设背后确实存在一个连续函数,而采样点只是对它的离散观测。对于压力传感器来说,我们认为背后存在一个连续压力分布 $P(x,y)$,传感器只是采到了若干个 $P(x_i,y_i)$,所以目标是从这些离散值恢复连续压力分布的近似,而不只是让图变得柔和。 这也是为什么我更愿意把这个问题叫“散点场重建”。它不是某个物理量专属的问题,而是一类数据重建问题。 为什么会选到 Wendland 从散点构造连续场的方法很多。最朴素的是最近邻:每个位置直接拿最近采样点的值。这很诚实,但画出来会像马赛克。线性插值或三角插值更自然一些,不过它往往需要明确的拓扑结构,边界处理也麻烦。点高斯叠加看起来很直觉:每个采样点盖一个光斑,所有光斑相加。但它有一个致命问题——如果不归一化,采样点密集的地方会天然更亮。亮度来自采样密度,而不是来自真实场值。 KNN-IDW 往前走了一步:找附近 K 个点,按距离倒数加权平均。它已经是“插值”的思路了,但邻居集合会随着像素位置切换,梯度大的地方容易出现细小斑点。局部平面拟合能表达局部趋势,不过不同邻域拟合出的平面一切换,就容易出现片状接缝。全局 RBF 插值理论上更完整,但需要解线性方程组,计算成本会比较高。 所以这个场景真正需要的不是“最花哨”的方法,而是同时满足几个工程约束的方法。第一,它要归一化,否则采样点密度会污染颜色。第二,它要局部计算,否则输出图像一大,每个像素都遍历所有采样点就不现实。第三,它要视觉连续,不能有块状边界、凸包、片状拼缝。Wendland C2 恰好把这几件事放在一起:它是归一化加权平均;它是紧支撑核,超出半径就严格为零;它在支撑边界处 C² 连续,不容易产生拼缝;同时它还是正定 RBF,作为插值或近似核有数学基础。 也就是说,Wendland 不是因为“它专门适合压力场”才被选中,而是因为当前任务具备这些条件:散点采样、需要连续场、采样密度可能不均匀、要求实时、要求视觉上没有明显伪影。 从旧的高斯光斑到 Wendland 核 旧的点高斯方案很容易理解:在每个采样点位置盖一个高斯光斑,然后把所有光斑相加。 $$ \text{field}{[x][y]} = \sum_i \text{value}_i \times \exp\!\left(-\frac{d_i^2}{2\sigma^2}\right) $$这里 $\text{value}_i$ 是第 $i$ 个采样点的值,$d_i$ 是像素到这个采样点的距离,$\sigma$ 控制光斑扩散范围。这个公式最大的问题就在求和符号上。两个采样点靠得近,光斑重叠区域就会叠得更亮。结果是:采样点密度越高的地方越亮,即便真实场值并没有更高。 ...

July 7, 2026 · 2 min · Leventure

GTCRN:一个 23.7K 参数语音降噪网络的设计思路完整解读

GTCRN:一个 23.7K 参数语音降噪网络的设计思路完整解读 作者从零讲起:背景、骨架、模块、训练、部署、设计哲学,一篇看完。 配套材料:GTCRN 论文与公开实现都可以作为辅助阅读材料,但本文尽量按原理本身展开,不依赖具体工程代码跳转。 目录 前言:这篇文章写给谁看 第一章 设计思路与背景:作者到底要解决什么问题? 第二章 整体架构:一张图看懂 GTCRN 是怎么搭起来的 第三章 输入处理与 ERB:怎么把 257 个频点压成 129 个还不丢信息? 第四章 GT-Conv 详解:ShuffleNetV2 + 时间空洞,省到极致的卷积块 第五章 DPGRNN 详解:双路径 + 分组,RNN 的极致瘦身 第六章 SFE 与 TRA:两个"点睛"模块 第七章 输出与损失函数:复数掩码 CRM 和"混合损失"的玄学 第八章 流式推理:从离线训练到逐帧实时 第九章 设计哲学总结:从 GTCRN 学到的可迁移工程思维 前言 如果你和我一样,是一名有信号处理(STFT、滤波器组、感知声学)和经典机器学习基础的工程师,能看懂代码,知道"卷积"、“RNN”、“注意力"大概是什么,但是看到 GTCRN 这样的网络结构图时会想: “作者为什么这么搭?这些模块之间凭什么能拼成一个能降噪的东西?” “23.7K 参数怎么做到打过 RNNoise(60K参数),并且打平甚至超过几百万参数的大模型的?” “如果让我从零设计,我能想到这些 trick 吗?我和作者之间差的是什么?” 那这篇文章可能对你有用。 我不打算把它写成论文复读机,那样毫无价值——论文你自己就能看。我想做的是 还原作者的思考路径:当他坐在工位上想"我要做一个能放在耳机里跑的降噪模型”,他第一步会想什么,第二步又怎么走到 ERB、ShuffleNet、DPRNN 这些组件上,每一个看起来很骚的设计背后到底解决的是什么实际问题。 读完这一系列,你应该能: 理解 GTCRN 每个模块解决的具体问题,而不是只记住名字; 看到一个新的 SE 模型时,能识别其中哪些是骨架、哪些是 trick; 在自己的项目里能做出取舍:什么时候上 attention、什么时候用 grouped conv、什么时候 CRM 不如 mag-mask。 阅读建议: ...

June 30, 2026 · 25 min · Leventure

[RL] 强化学习指导搭建 IC2E 核反应堆

Minecraft 工业2 实验版核反应堆计算 强化学习模块训练路径 最近在玩Minecraft IC2 Classic,但是对于摆核反应堆总是感觉不是很得心应手,不管怎么摆效率都很低,为了解决这个问题,所以我写了一个强化学习的模块,让神经网络自己去学习如何摆弄这个网络。 不过看了下,IC2 Classic 的核反应堆因为似乎不涉及中子流,所以任务是比较简单的,为了节目效果,我准备研究一下IC2 experiment版的核电站,这个玩起来更有趣,学习的深度也更深。 任务简单分为三步: 明确任务目标和行为 搭建网络 训练 一、任务目标和行为指南 这一步往往是比较重要的,因为这一步决定了AI到底要学什么,以及怎么学。 1.1 问题定义 IC2E的核反应堆设计本质上是一个组合优化问题。你有一个9×6的网格,54个位置,每个位置可以放18种不同的组件(包括空槽位)。理论上有18^54种可能的配置,这个数字大到宇宙中的原子都数不过来。 但问题是,这些配置里99.99%都是垃圾——要么发电量低得可怜,要么直接爆炸。我们要找的是那0.01%既能高效发电,又不会炸的设计。 1.2 核反应堆的物理机制 在开始训练之前,得先搞清楚IC2E核反应堆到底是怎么工作的。不然AI学出来的东西可能完全不符合物理规律。 核脉冲机制: 燃料棒工作时会向四周发射核脉冲 相邻的燃料棒接收到核脉冲后,发电量会成倍增加 中子反射板可以把核脉冲反射回去,相当于"虚拟"的燃料棒 举个例子,一个单铀棒(U): 单独放置:发电5 EU/t 旁边有1个燃料棒:发电10 EU/t 旁边有2个燃料棒:发电15 EU/t 旁边有4个燃料棒:发电25 EU/t 所以燃料棒越密集,发电效率越高。但问题来了—— 热量产生机制: 燃料棒产生的热量跟相邻的燃料棒/反射板数量有关,公式是: 热量 = 倍数 × (n+1) × (n+2) 其中n是相邻的燃料棒或反射板数量(0-4)。 这个公式很狠,是二次增长的。比如单铀棒(倍数=2): n=0(孤立):2×1×2 = 4 HU/tick n=1(1个邻居):2×2×3 = 12 HU/tick n=2(2个邻居):2×3×4 = 24 HU/tick n=4(4个邻居):2×5×6 = 60 HU/tick 看到没?发电量是线性增长(5→25),但热量是二次增长(4→60)。这就是核反应堆设计的核心矛盾:你想要高功率,就得承受高热量。 散热系统: 热量如果散不出去,反应堆温度就会一路飙升,到10000 HU就爆炸。所以必须有足够的散热系统: 散热片(H):自身散热6 HU/tick 反应堆散热片(R):从堆温吸热5 HU/tick,然后自己散热5 HU/tick 高级散热片(A):自身散热12 HU/tick 超频散热片(O):自身散热20 HU/tick 还有热交换器,可以在组件之间转移热量,把热量从燃料棒转移到散热片上。 ...

June 18, 2026 · 4 min · Leventure

GTCRN 演进路径:v4 → v5 → 落地

GTCRN 演进路径:v4 → v5 → 落地 记录噪声抑制模型从架构精简开始,经历质量优化、极限压缩,到最终在嵌入式 C 端落地的全过程。 前言 v4.1 把 464 KB 的推理管线交到了 C 端手里。这个数字已经够小——能在大多数嵌入式芯片上跑起来,RTF 不到 0.04。但我们还想要更多。 不是「把模型再做小一点」这么简单。键盘敲击声和风扇底噪的压制效果已经不错了,如果裁剪的过程中把这两个能力丢掉,小就没有意义。换句话说,压缩是手段,质量是底线。每次下手之前,先问一句:压完之后,瞬态噪声还能不能盖住?听感会不会变差? v5 这条线走了四个月。它从 v4.1 的 464 KB 跑到了最终的 412 KB,中间踩了不少坑。这份文档把踩过的坑、走通的路、放弃的岔路都记下来。 时间线:2026-03(v4.1 交付) → 2026-06(v5.6 C 端落地) 版本总览 版本 改了什么 参数 关键指标 内存 结论 v4.1 INT8 混合精度 C 推理 87K PESQ 2.037 464 KB 基线,已交付 v5.1 架构定型 (4层, CH=20) 55.6K PESQ 2.462 ~466 KB 可靠起点 v5.2 多模块 all-in 73.9K PESQ ~1.20 ~538 KB 失败,复盘后放弃 v5.3 网络优化,单模块消融 61.6K [5,10) PESQ 1.92 ~466 KB n4 被接受 v5.4 宽度裁剪 CH→16 41.2K [5,10) PESQ 1.46 ~400 KB 失败,暂停 v5.5 极限压缩 (INT4/INT8) — PESQ drop < 0.05 ~314-349 KB (投) 过门,主线收敛 v5.6 C 端落地:GTC6/INT4/hidden INT8 60.3K DNSMOS SIG +0.86 412 KB 交付 网络结构 (v5.3-n4 最终) 输入 spec (B, 513, T, 2) │ ▼ ERB_48k.bm(): 513 → 219 │ ▼ in_conv: Conv2d(2→3) │ ▼ ┌─ CausalEncoder ───────────────────────────┐ │ DSConv: 219→110 ← skip1 │ │ DSConv: 110→55 ← skip2 │ │ CausalGTConv×4 (d=1,2,4,2) ← skip3-6│ │ SubbandAttention │ └───────────────────────────────────────────┘ │ ▼ CausalDPGRNN × 2 │ intra: 双向GRU (频率轴) │ inter: 单向GRU (时间轴) │ ▼ ┌─ CausalDecoder ───────────────────────────┐ │ SkipResidualFusion + CausalGTConv×4 │ │ Fuse + DSDeconv: 55→110 │ │ SkipResidualFusion + DSDeconv: 110→219 │ └───────────────────────────────────────────┘ │ ▼ out_conv → ERB_48k.bs() → CRM → 输出 相比 v4,decoder 的 skip 连接从简单的 x + skip 换成了带门控和残差分支的融合模块。 ...

June 18, 2026 · 7 min · Leventure

PPG 情绪识别:几条路线的取舍与实测

PPG 情绪识别:几条路线的取舍与实测 写在前面 这个工作并不算solid,目前正在数据收集和实测阶段,涉及的数据集也只有WESAD和DEAP,并没有很强的参考意义,请谨慎参考。 摘要 要解决的问题很简单:在手表侧只有 PPG 和三轴加速度这两类输入的前提下,能不能先估计 valence 和 arousal,再映射到 Russell 情绪模型中的象限和离散标签,从而形成一条可闭环的情绪识别链路。 当前项目一共走过三条路线。第一条是 XGBoost Feature Baseline,它使用 HRV + ACC + SQI 这类手工特征,目标是先把任务跑通,并给后续复杂模型提供一个稳定参照。第二条是 EMCNN PPG-only,它直接建模单通道 PPG 波形,是当前的默认主方案。第三条是 EMCNN + aux,在 EMCNN 的基础上再加入 ACC/SQI 辅助输入,作为实验增强路线。 在当前 WESAD LOSO 实测下,EMCNN PPG-only 是综合表现最好的方案:它同时超过了 XGBoost 基线,并且比 EMCNN + aux 保持了更好的连续回归误差。EMCNN + aux 虽然在分类指标上更强,但 VA MAE 更差,更像分类增强方案。除此之外,本文还补充了推理性能、CPU/GPU、并发、内存和显存开销的实测,目的是把“能不能识别”和“值不值得部署”放在同一张桌子上讨论。 本文不公开项目实现和数据实测,仅作交流学习。 这个工作并不算solid,目前正在数据收集和实测阶段,涉及的数据集也只有WESAD和DEAP,并没有很强的参考意义,请谨慎参考。 一、这件事到底在做什么 当前项目的目标不是做一个泛泛的“情绪分类器”,而是要在手表侧有限传感器条件下,建立一条可以闭环的 Russell 情绪建模链路。输入是 PPG + ACC,中间层输出是连续的 valence 和 arousal,最后再映射到 Russell 情绪模型中的象限和离散标签。当前仓库中的推理接口已经对应到了这条链路: 连续层:valence / arousal 决策层:quadrant 展示层:21 个 Russell 标签 + Top-3 这里有一个必须讲清楚的前提:当前项目并不预设 PPG 能直接“表达情绪”,也不假设 PPG 和 valence/arousal 之间存在简单、稳定、显式的一一对应关系。更稳妥的说法是,情绪状态会通过自主神经系统影响心率、血管张力、外周循环和节律变化,而 PPG 恰好能观测到这些变化的一部分。因此,当前项目真正检验的是这样一个工程假设:PPG/ACC 中可能存在与 valence/arousal 相关的可学习统计模式。如果这个假设成立,就有机会在手表侧形成一套弱侵入、持续性的情绪状态估计能力。 ...

June 18, 2026 · 4 min · Leventure

带噪信号的趋势分析方法

带噪信号的趋势分析方法 前言 手头有两组时域采样数据,每组大约240个采样点。采样周期固定,信号值在两千到四千之间游走。 肉眼扫过去——毛刺很多,高频抖动明显。但拉远了看,似乎底下藏着某种缓慢变化的结构。就像隔着一层磨砂玻璃看一幅画,大色块能辨认,细节却糊成一团。 DSP里降噪去扰的招数不少。卡尔曼、Holt-Winters、高斯平滑、巴特沃斯、Savitzky-Golay,各有各的路子。我想试试——把这套工具搬到这个信号上,看谁能把底下的轮廓挖出来,谁会被噪声带跑偏。 另外再拿两组最简单的滑动平均(SMA和EMA)当参考线,看看"简单粗暴"和"精心设计"之间到底差多少。 信号概览 先看一眼这两组信号的素颜: 特征 Signal A Signal B 值域 2,863 ~ 3,652 3,097 ~ 4,030 振幅(span) 789 933 采样点 242 243 逐点变化率 std 1.17% 1.53% 均值 3,174 3,575 Signal A的振幅比Signal B小,但逐点变化率的峰值很大——有过几次接近 ±5% 的跳变。整体走势像一条被反复折叠的绳子:先往下摔,弹回来,又摔一次,再弹。方向频繁切换。 Signal B的振幅更大,但方向很一致——从头到尾在往上走。中途有几次小幅回撤,但不改大方向。 这两组信号的差异,决定了后面每种方法的命运。 一、卡尔曼滤波——让状态方程替你猜 原理 卡尔曼不直接相信观测值,也不全信预测值。它在两者之间做加权,权重由各自的不确定性决定。 设一个状态向量 $x_k = [p_k, v_k]^T$,装着"当前位置"和"变化速度"。假设信号按匀速模型演化: $$ x_k = F x_{k-1} + w_k, \quad F = \begin{bmatrix}1 & \Delta t \\ 0 & 1\end{bmatrix} $$每来一个新的观测 $z_k$,先预测、再修正: ...

June 18, 2026 · 3 min · Leventure

浮点数的 IEEE 754 标准与内存表达

前言 项目上遇到了double类型数据精度问题,嵌入式开发和算法争论了一会有关double和float的精度问题,究竟是强转造成的精度损失更多,还是在计算的过程中精度损失更多?这个问题很显然是使用float在计算过程中造成的精度损失更多,但是面对这样的问题,不能只靠猜测,而是需要进行一系列量化的测算。 IEEE754标注中的浮点数表达公式 $$ value = (-1)^{sign} \times 2^{exponent} \times (1 + mantissa) $$其中,sign为符号位,exponent为指数位,mantissa为尾数位。 float float类型通常占用4个字节(32位)的内存。具体分配如下: 符号位(Sign bit):1位 指数位(Exponent):8位 尾数位(Fraction/Mantissa):23位 内存布局示例 假设我们有一个单精度浮点数3.14,它的二进制表示如下: 符号位:0 指数位:10000000 尾数位:10010001111010111000011 0 10000000 10010001111010111000011 double 符号位(Sign bit):1位 指数位(Exponent):11位 尾数位(Fraction/Mantissa):52位 内存布局 假设我们有一个双精度浮点数3.14,它的二进制表示如下: 符号位:0 指数位:10000000000 尾数位:1001000111101011100001010001111010111000010100011110101110000101 float与doule之间的转换 float转double 这种转换称为扩展转换(promotion),因为double有更多的位数来表示数字。 1.内存模型变化: float使用32位存储,而double使用64位存储。 在将float转换为double时,计算机会将float的值复制到double的尾数部分,并扩展指数部分。 由于double的尾数部分更长,可以精确表示的有效数字更多,所以这种转换通常不会损失精度。 2.转换过程 符号位保持不变。 指数位从float的8位扩展到double的11位,计算机会根据需要调整指数的偏移量。 尾数位从23位扩展到52位,不足的部分用0填充。 double 转 float 这种转换称为缩减转换(narrowing),因为float有较少的位数来表示数字。 1. 内存模型变化: double使用64位存储,而float使用32位存储。 在将double转换为float时,计算机会将double的值截断或舍入以适应float的尾数部分和指数部分。 由于float的尾数部分较短,这种转换可能会损失精度。 2.转换过程 符号位保持不变。 指数位从double的11位缩减到float的8位,计算机会调整指数的偏移量,并可能会进行舍入。 尾数位从52位缩减到23位,超出的部分会被截断或舍入,这可能导致精度损失。 这里需要注意的是,在C++中,并不是做了简单的截断,而是做了舍入操作,这也是为什么我们在实际操作中,可以观测到逢7进1 例子: float转换double 假设我们有一个float值3.14: float: 0 10000000 10010001111010111000011 ...

June 18, 2026 · 3 min · Leventure

要团结

最近听了未明子一个很简短的切片,叫世界之野,大概讲的是一个双向的女孩问他,悲伤了怎么办 他说,悲伤了要用愤怒,去找到悲伤的根源,把根源解决掉,勇敢面对又不害怕。 他说,我感觉自己这个答案答错了,会后悔一辈子,有一辈子负罪感。 最后女孩去世了,内疚感一直在折磨他。 再让他答一遍,悲伤了怎么办。 他说:“要团结起来,要与众人团结起来,要体谅,要柔和,要坚决的去行动,要呵护这个悲伤的孤独的孩子,而不是要愤怒。” 他说,我可能没有第二次机会回答这个问题了。 我想起很多往事,自己曾经也交往过一个双向的女孩,她没有问过我这个问题,可能她并不打心底信任过我,可我也在脑海里想过很多次很多次这个问题,如果还有机会,我也许当时会告诉她:”去爱,带着对世界的温柔,去包容和实践。“ 我其实一直不是很喜欢未明子这个人,但是我相信他肯定也在无数个夜里深深地问过自己如果能回到过去,他会如何回答这个问题。 但是经历过很多事情之后,在经历后AI时代的席卷之后,我才后知后觉的明白,要团结。

June 18, 2026 · 1 min · Leventure

ONNX - 它到底快在哪,又慢在哪

ONNX - 它到底快在哪,又慢在哪 一、ONNX 是什么 ONNX(Open Neural Network Exchange)本质上是一种模型的中间表示格式(IR),类似于编译器里的 LLVM IR。 用 PyTorch 训练完一个模型之后,模型的计算逻辑是用 Python 描述的,跑推理的时候要经过 Python 解释器、PyTorch 的调度器、再到底层的 CUDA kernel。这条链路很长,开销不小。ONNX 做的事情是:把模型的计算图从 PyTorch 的世界里"导出"成一个独立的、与框架无关的静态计算图,然后交给专门的推理引擎(比如 ONNX Runtime)去执行。 打个比方:PyTorch 训练出来的模型像一份 Python 脚本,每次执行都要解释器逐行翻译;ONNX 导出后的模型像一份编译好的二进制文件,直接跑就行。 一个典型的 ONNX 文件(.onnx)里面存的是: 计算图的拓扑结构(哪些算子、怎么连接) 每个算子的类型和参数(Conv、MatMul、Relu 等) 模型的权重(以 protobuf 格式序列化) 输入输出的 shape 和数据类型 这里要注意一点:ONNX 本身只是一个格式规范,它不负责执行。真正跑推理的是 ONNX Runtime(简称 ORT)或者其他兼容 ONNX 的推理引擎(TensorRT、OpenVINO 等)。说"用 ONNX 加速",实际上是"用 ONNX Runtime 加速"。 二、ONNX Runtime 为什么能快 理解了 ONNX 是什么之后,关键问题来了:为什么换个引擎跑就能快? 2.1 去掉了 Python 开销 PyTorch 推理时,即使模型本身的计算是在 GPU 上跑的,Python 层面仍然有大量开销: ...

March 13, 2026 · 3 min · Konpaku Youran

NSF-HiFiGAN-声码器学习笔记

从 HiFi-GAN 到 NSF-HiFi-GAN:声码器学习笔记 本文基于 RVC(Retrieval-based Voice Conversion)项目的实际代码,从零开始梳理 HiFi-GAN 声码器的原理,再过渡到 RVC 中真正使用的 NSF-HiFi-GAN 变体。 代码位置:infer/lib/infer_pack/models.py 和 infer/lib/infer_pack/modules.py 一、先搞清楚声码器在干什么 在语音合成或语音转换的流程里,声码器处在最后一环。它的上游会输出某种"中间表示"——可能是 mel 频谱图,也可能是某个隐空间的向量。声码器要做的事情就一件:把这个中间表示变回可以听的音频波形。 说得直白点:频谱图是一张"图",声码器要把这张图"念"出来。 传统做法(Griffin-Lim 之类的)靠数学迭代来恢复相位信息,结果通常比较糊。HiFi-GAN 走的是神经网络的路线——用一个生成器直接输出波形采样点,同时用判别器来监督生成质量。 二、HiFi-GAN 的基本结构 HiFi-GAN 的论文是 2020 年发的(Jungil Kong 等人),核心思路可以用一句话概括: 转置卷积做上采样,残差块做波形精炼,多尺度判别器做质量监督。 2.1 生成器的整体流程 在 RVC 的代码里,标准 HiFi-GAN 生成器对应的是 Generator 类(models.py:204)。它的结构其实很规整: HiFi-GAN 生成器结构(40kHz 配置为例) ┌─────────────────────────────────────────────────────────────┐ │ 输入:隐变量 z │ │ [batch, 192, T帧] │ └────────────────────┬────────────────────────────────────────┘ │ ▼ ┌────────────────────┐ │ 预处理卷积层 │ │ Conv1d(192→512) │ ← 把输入投射到高维空间 │ kernel_size=7 │ └────────┬───────────┘ │ ┌────────────┴────────────┐ │ 上采样 Stage 1 (×10) │ │ ConvTranspose1d(512→256)│ ← 时间轴拉长到 T×10 └────────┬─────────────────┘ │ ┌────────┴──────────────────────────────────┐ │ MRF (多感受野融合) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐│ │ │ResBlock │ │ResBlock │ │ResBlock ││ │ │kernel=3 │ │kernel=7 │ │kernel=11 ││ │ └──────────┘ └──────────┘ └──────────┘│ │ 输出取平均 │ └────────┬──────────────────────────────────┘ │ ┌────────┴────────────┐ │ 上采样 Stage 2 (×10)│ │ ConvTranspose1d(256→128)│ ← 时间轴拉长到 T×100 └────────┬─────────────┘ │ ┌────────┴──────────────────────────────────┐ │ MRF 融合 │ │ ResBlock×3 (kernel=3/7/11) → 平均 │ └────────┬──────────────────────────────────┘ │ ┌────────┴────────────┐ │ 上采样 Stage 3 (×2) │ │ ConvTranspose1d(128→64)│ ← 时间轴拉长到 T×200 └────────┬─────────────┘ │ ┌────────┴──────────────────────────────────┐ │ MRF 融合 │ │ ResBlock×3 (kernel=3/7/11) → 平均 │ └────────┬──────────────────────────────────┘ │ ┌────────┴────────────┐ │ 上采样 Stage 4 (×2) │ │ ConvTranspose1d(64→32) │ ← 时间轴拉长到 T×400 └────────┬─────────────┘ │ ┌────────┴──────────────────────────────────┐ │ MRF 融合 │ │ ResBlock×3 (kernel=3/7/11) → 平均 │ └────────┬──────────────────────────────────┘ │ ┌────┴────────────┐ │ 后处理卷积层 │ │ Conv1d(32→1) │ ← 压缩到单声道 │ kernel_size=7 │ └────┬─────────────┘ │ ▼ ┌────────────┐ │ Tanh │ ← 限幅到 [-1, 1] └─────┬──────┘ │ ▼ ┌──────────────────┐ │ 输出波形 │ │ [batch, 1, T×400]│ └──────────────────┘ 上采样的总倍率 = 10 × 10 × 2 × 2 = 400。这个数字等于 hop_length(帧移),含义是:输入的每一帧对应输出的 400 个采样点。对于 40kHz 采样率来说,一帧就是 10ms。 ...

February 14, 2026 · 13 min · Konpaku Youran