tf.squeeze对音频的作用、MP3加载方法及频谱图生成问题排查
tf.squeeze 作用说明
tf.squeeze的功能是移除张量中所有长度为1的维度,也可以通过axis参数指定要移除的特定维度,只有指定维度的长度确实为1时操作才会成功。比如形状为(1000, 1)的张量调用tf.squeeze(axis=-1)后会变成(1000,),但如果是(1000,2)的张量做同样操作就会报错,和你遇到的情况一致。
报错根因
- 第一个
squeeze报错:你使用的测试音频是双声道(立体声)音频,加载后的AudioIOTensor形状为(音频总采样数, 2),最后一维长度为2不符合squeeze的维度要求,因此触发参数错误。 - 第二个频谱图展示报错:直接调用
audio.to_tensor()得到的张量保留了声道维度,tfio.audio.spectrogram生成频谱时会对每个声道单独计算,最终输出形状为(时间步长, 声道数, 频率维度),不符合plt.imshow要求的2维输入格式,因此触发形状错误。
修复方案
先将双声道音频转为单声道后再做后续处理即可,完整代码如下:
import pathlib import tensorflow as tf import tensorflow_io as tfio import matplotlib.pyplot as plt from IPython.display import Audio data_dir = pathlib.Path('recordings') sample_file = data_dir/'testA.mp3' audio = tfio.audio.AudioIOTensor(str(sample_file)) # 加载为张量,形状为 (采样点数, 声道数) audio_tensor = audio.to_tensor() # 双声道转单声道:对两个声道取平均,也可直接取单个声道,例:audio_tensor[:,0] 取左声道 audio_mono = tf.reduce_mean(audio_tensor, axis=-1) # 裁剪开头100个采样点 audio_slice = audio_mono[100:] # 数值归一化 tensor = tf.cast(audio_slice, tf.float32) / 32768.0 print("Audio Tensor: " + str(tensor)) plt.figure() plt.plot(tensor.numpy()) plt.title("音频波形图") plt.show() # 生成频谱图 spectrogram = tfio.audio.spectrogram(tensor, nfft=512, window=512, stride=256) plt.figure() # 转置+设置origin='lower' 符合常规频谱图横轴为时间、纵轴为频率的展示习惯 plt.imshow(tf.math.log(spectrogram).numpy().T, origin='lower') plt.title("对数频谱图") plt.show()
内容的提问来源于stack exchange,提问作者João Marques
相关产品推荐
相关产品推荐

