相同数量音频文件下ANN语音分类任务X与y形状不匹配求解
问题根因与解决方案
你的代码存在多处核心逻辑错误,逐点修正如下:
- 数据集读取逻辑错误:循环读取音频时未做数据存储,
data和data2变量每次迭代都被新读取的音频覆盖,最终X仅存储最后一条本人音频的采样序列,y仅存储最后一条他人音频的采样序列,和你预期的36条样本数据集完全不符,两条音频时长不同自然形状不匹配。 - 标签定义完全错误:二分类任务的标签
y应为对应样本的类别标识(本人标注为1、他人标注为0即可),你当前直接把他人音频的采样序列赋值给y,完全不符合分类任务的输入要求。 - 输入特征设计不合理:直接用原始音频采样点作为ANN输入,不同音频的时长差异会导致输入维度不统一,需要先做特征归一化处理,要么将所有音频截断/补零到相同长度,要么提取MFCC、梅尔频谱等固定维度的语音特征。
- 模型结构适配错误:二分类任务输出层应设置1个神经元,搭配
sigmoid激活函数,你当前设置6个输出神经元与binary_crossentropy损失函数不匹配。
修正后可运行代码
from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler import tensorflow as tf import numpy as np from scipy.io import wavfile from pathlib import Path import os ### 配置参数 FIXED_SAMPLE_LEN = 32000 # 统一所有音频长度为32000个采样点,可根据你的音频平均长度调整 ### 数据集读取 X = [] y = [] # 读取本人语音,标签设为1 me_path = Path(os.path.abspath('Voiceclassification/Data/me/')).rglob('*.wav') for path in me_path: samplerate, data = wavfile.read(str(path)) data = data.flatten() # 统一长度:过长截断,过短补零 if len(data) > FIXED_SAMPLE_LEN: data = data[:FIXED_SAMPLE_LEN] else: data = np.pad(data, (0, FIXED_SAMPLE_LEN - len(data)), mode='constant') X.append(data) y.append(1) # 读取他人语音,标签设为0 other_path = Path(os.path.abspath('Voiceclassification/Data/other/')).rglob('*.wav') for path in other_path: samplerate, data = wavfile.read(str(path)) data = data.flatten() if len(data) > FIXED_SAMPLE_LEN: data = data[:FIXED_SAMPLE_LEN] else: data = np.pad(data, (0, FIXED_SAMPLE_LEN - len(data)), mode='constant') X.append(data) y.append(0) # 转成numpy数组 X = np.array(X) y = np.array(y) ### 数据集划分与标准化 x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=0) sc = StandardScaler() x_train = sc.fit_transform(x_train) x_test = sc.transform(x_test) ### 搭建ANN ann = tf.keras.models.Sequential() ann.add(tf.keras.layers.Dense(units=6, activation="relu")) ann.add(tf.keras.layers.Dense(units=6, activation="relu")) ann.add(tf.keras.layers.Dense(units=1, activation="sigmoid")) # 二分类输出层改1个神经元 # 编译训练 ann.compile(optimizer="adam", loss="binary_crossentropy", metrics=['accuracy']) ann.fit(x_train, y_train, batch_size=8, epochs=100) # 样本量少调小batch_size ann.save('train_model.model')
优化建议
如果想要更高的分类准确率,建议替换原始采样点为MFCC语音特征,同时可以加入数据增强(加噪、时间偏移等)提升模型泛化能力,样本量较少的情况下也可以考虑使用SVM等传统机器学习分类器替代ANN。
内容的提问来源于stack exchange,提问作者Bernardo Olisan
相关产品推荐
相关产品推荐

