TensorFlow实现音频分类时DecodeWav报Data too short错误如何解决
问题根因
报错来自tf.audio.decode_wav算子,TensorFlow 2.6版本的该算子对WAV文件头的兼容性较差,RAVDESS数据集中部分WAV的头格式不符合算子默认解析规则,即使文件本身大小正常、没有损坏也会触发该错误。
同时代码存在隐含问题:get_label函数直接对全路径做分割,若路径中包含-会导致标签提取错误,后续也会引发额外异常。
解决方案
方案1:调整解码参数,兼容现有代码逻辑
修改decode_audio函数,显式指定音频声道数和采样长度,绕过默认头解析的限制:
def decode_audio(audio_binary): # RAVDESS所有音频均为单声道、16000采样率,单条时长约3秒 audio, _ = tf.audio.decode_wav( audio_binary, desired_channels=1, desired_samples=48000 ) return tf.squeeze(audio, axis=-1)
同时修正标签提取逻辑,避免路径符号干扰:
def get_label(file_path): # 先提取路径末尾的纯文件名再做分割 file_name = tf.strings.split(file_path, os.path.sep)[-1] parts = tf.strings.split(file_name, "-") # RAVDESS文件名结构中第3位为情感标签,索引从0开始为2 return parts[2]
方案2:改用librosa加载音频(推荐,兼容性更高)
tf.audio模块功能较为局限,换用成熟的音频处理库librosa可彻底避免这类解码问题。首先安装依赖:pip install librosa
随后修改预处理逻辑即可:
import librosa def load_audio(file_path): path = file_path.numpy().decode("utf-8") # 加载音频,指定采样率16000、单声道 audio, sr = librosa.load(path, sr=16000, mono=True) # 统一长度为3秒,不足补零、过长截断 if len(audio) < 48000: audio = np.pad(audio, (0, 48000 - len(audio))) else: audio = audio[:48000] return tf.convert_to_tensor(audio, dtype=tf.float32) def get_waveform_and_label(file_path): label = get_label(file_path) waveform = tf.py_function(func=load_audio, inp=[file_path], Tout=tf.float32) waveform.set_shape((48000,)) return waveform, label
内容的提问来源于stack exchange,提问作者Nathan Montanez
相关产品推荐
相关产品推荐

