scipy.signal.welch维度缩减问题求助:如何保留维度实现通道拼接
解决
scipy.signal.welch维度缩减与时域频域拼接维度不匹配问题 问题根源:为什么welch会缩减维度?
你遇到的核心问题是**scipy.signal.welch返回的功率谱密度(PSD)长度和原始时域信号不一致**。这是welch的工作特性决定的:
- 它会把时域信号分段、加窗(默认汉宁窗)
- 对每段做FFT后平均得到PSD
- 由于实信号的FFT结果是对称的,welch只返回正频率部分,输出的频率点数量为
nperseg//2 + 1(nperseg是每段的长度,默认取min(256, 信号长度))
比如你的时域长度是16,默认nperseg会取16,正频率点数量就是16//2 +1 =9——这就是你看到的m1: [2 x 9]里9的来源,和时域的16长度不匹配,最终导致拼接后模型输入维度错误。
两种解决方案,让频域特征和时域长度一致
方案1:用FFT直接计算幅度谱(最简单,长度完全匹配)
如果你的需求是获取频域特征并和时域拼接,不一定要用welch的PSD。直接用FFT计算幅度谱,输出长度会和原始时域完全一致:
import numpy as np # 假设你的时域信号形状是[batches, channels, sample_length] = [2,1,16] x = np.random.rand(2, 1, 16) # 计算FFT幅度谱(保留和时域一致的长度) fft_amplitude = np.abs(np.fft.fft(x, axis=-1)) # 拼接时域和频域特征,axis=1对应channels维度 combined_signal = np.concatenate([x, fft_amplitude], axis=1) print(combined_signal.shape) # 输出(2, 2, 16),完全符合你的期望!
方案2:对welch的PSD进行插值,拉伸到时域长度
如果你一定要使用welch的PSD结果,可以通过插值把PSD的长度拉伸到和时域一致:
from scipy.signal import welch from scipy.interpolate import interp1d import numpy as np x = np.random.rand(2, 1, 16) sample_length = x.shape[-1] # 用welch计算PSD frequencies, psd = welch(x, axis=-1) # 创建插值函数,把PSD从原频率点长度插值到sample_length new_frequencies = np.linspace(frequencies[0], frequencies[-1], sample_length) interpolator = interp1d(frequencies, psd, axis=-1, kind="linear") psd_interpolated = interpolator(new_frequencies) # 拼接时域和插值后的频域 combined_signal = np.concatenate([x, psd_interpolated], axis=1) print(combined_signal.shape) # 输出(2,2,16),满足要求
关于报错的额外说明
你看到的size mismatch, m1: [2 x 9], m2: [16 x 16],是因为你直接把长度为9的PSD和长度为16的时域信号拼接后,模型的某一层(比如全连接层)期望输入是16维度的特征,但实际传入了9维度的特征,导致权重矩阵(16x16)无法和输入(2x9)做矩阵乘法。用上面的两种方案解决维度匹配问题后,这个错误就会消失。
内容的提问来源于stack exchange,提问作者Dr. Prof. Patrick
相关产品推荐
相关产品推荐

