librosa加载音频训练模型报NumPy数组转Tensor失败错误求助
问题描述
开展音频深度学习模型训练时,使用librosa库加载指定路径下的wav格式音频数据,训练数据加载代码如下:
train_audio_path = 'C:/Users/user/OneDrive/Bureau/input1/train/audio1/' all_wave = [] all_label = [] for label in labels: print(label) waves = [f for f in os.listdir(train_audio_path + '/'+ label) if f.endswith('.wav')] for wav in waves: samples, sample_rate = librosa.load(train_audio_path + '/' + label + '/' + wav, sr = 16000) if(len(samples)>=16000 or len(samples)<=16000) : all_wave.append(samples) all_label.append(label)
模型编译与训练代码如下:
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy']) metric = 'val_accuracy' es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=10, min_delta=0.0001) mc = ModelCheckpoint('best_model.hdf5', monitor=metric, verbose=1, save_best_only=True, mode='max') # Display model architecture summary history=model.fit(x_tr, y_tr ,epochs=100, callbacks=[es,mc], batch_size=32, validation_data=(x_val,y_val))
执行model.fit启动训练时触发如下报错:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_8428/2388281761.py in <module> 1 # Display model architecture summary ----> 2 history=model.fit(x_tr, y_tr ,epochs=100, callbacks=[es,mc], batch_size=32, validation_data=(x_val,y_val)) ~\anaconda3\lib\site-packages\keras\utils\traceback_utils.py in error_handler(*args, **kwargs) 65 except Exception as e: # pylint: disable=broad-except 66 filtered_tb = _process_traceback_frames(e.__traceback__) ---> 67 raise e.with_traceback(filtered_tb) from None 68 finally: 69 del filtered_tb ~\anaconda3\lib\site-packages\tensorflow\python\framework\constant_op.py in convert_to_eager_tensor(value, ctx, dtype) 104 dtype = dtypes.as_dtype(dtype).as_datatype_enum 105 ctx.ensure_initialized() ---> 106 return ops.EagerTensor(value, ctx.device_name, dtype) 107 108 ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type numpy.ndarray).
已检索该报错的相关公开解决方案,未找到适配当前场景的有效方法,需要排查思路与解决方案。
问题根因
报错核心原因是传入model.fit的训练/验证数据是元素为numpy数组的object类型numpy数组,TensorFlow无法将这种不规则结构转换为张量,具体触发逻辑有两点:
- 音频过滤逻辑完全无效:代码中写的判断条件
if(len(samples)>=16000 or len(samples)<=16000)恒成立,所有时长的音频都被加入数据集,不同音频的采样点长度不一致,导致all_wave列表中存储的数组长度参差不齐。 - 数据转换不规范:长度不一致的数组直接用
np.array()转换时,会生成dtype为object的数组,数组内每个元素都是独立的不等长numpy数组,不符合TensorFlow的张量输入要求。
解决方案
按以下步骤修改代码即可解决:
- 修正音频加载逻辑,统一所有输入音频的长度,不要保留不等长样本。可以选择固定截断/补零到1秒(对应16kHz采样率下的16000个采样点),修改后的加载代码参考:
import numpy as np train_audio_path = 'C:/Users/user/OneDrive/Bureau/input1/train/audio1/' fixed_audio_length = 16000 # 对应16kHz采样率下1秒时长 all_wave = [] all_label = [] for label in labels: print(label) waves = [f for f in os.listdir(train_audio_path + '/'+ label) if f.endswith('.wav')] for wav in waves: samples, sample_rate = librosa.load(train_audio_path + '/' + label + '/' + wav, sr = 16000) # 短音频尾部补零到固定长度 if len(samples) < fixed_audio_length: samples = np.pad(samples, (0, fixed_audio_length - len(samples)), mode='constant') # 长音频截断尾部到固定长度 else: samples = samples[:fixed_audio_length] all_wave.append(samples) all_label.append(label)
- 加载完成后显式指定数据类型,转换为规则的数值型numpy数组,避免生成object类型数组:
# 转换音频数据为float32类型的规则数组,形状为(样本总数, 16000) all_wave = np.array(all_wave, dtype=np.float32) all_label = np.array(all_label)
- 后续划分训练集、验证集,完成标签one-hot编码后,可先执行以下代码校验数据格式,确认无问题再启动训练:
# 校验数据类型和形状 print(x_tr.dtype, x_tr.shape) print(x_val.dtype, x_val.shape) print(y_tr.dtype, y_tr.shape) print(y_val.dtype, y_val.shape)
只要输出的dtype不是object,且音频数据形状符合模型输入要求(如果用1DCNN通常需要额外加通道维度,可执行x_tr = np.expand_dims(x_tr, axis=-1)调整形状为(样本数, 16000, 1)),就不会再触发该报错。
内容的提问来源于stack exchange,提问作者chachi
相关产品推荐
相关产品推荐

