我在使用wav2vec库进行音频嵌入时遇到问题,同时试图使用来自EMODB数据集(德语中的情感数据集)的音频信号对情感进行分类。我使用以下代码提取嵌入:
feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained('facebook/wav2vec2-large-xlsr-53') #XLSR is for SR, not specifically Emotion Rec.
input_audio, sample_rate = librosa.load(emodb + file, sr=16000)
extraction = feature_extractor(input_audio, sampling_rate=16000, return_tensors="np", padding="max_length", max_length=max_len).input_values
向量的嵌入和形状如下:
(1, 143652)
特性的wav2vec
(3, 162)
特性的mfcc
请注意,我已将其填充到最高值。音频文件的长度约为1至2秒。
我的任务是检测情绪。我计划使用音频文件和文本中的这些嵌入作为情绪分类的下游模型,为此,我计划使用多模式方法,使用音频和文本嵌入。
因此,我在这些嵌入上训练了一个LSTM模型,但是它总是对训练数据过度拟合(~100%的准确率和~20%的测试)。
然后,我决定使用wav2vec嵌入和MFCC嵌入来完成一个简单的分类任务。当我在一个简单的支持向量机分类器中使用结果嵌入时,我得到了wav2vec嵌入的随机结果(15%-30%)。作为比较,当我使用MFCC提取特征并在同一分类器中使用时,我的准确率约为70%。
当然,我使用TSNE可视化了嵌入,以检查输入的质量,我发现得到了奇怪的结果。具体来说,当我绘制7种情绪时,所产生的情节就形成了螺旋形。当我只绘制2种情绪时,产生的情节是不同的,也是奇怪的。当我添加更多特性(3+)时,映射又是循环的。
我无法理解为什么我要得到这些结果,以及为什么嵌入如此糟糕。我想知道这是否是因为我使用了一个通用的XLSR模型,而没有对它进行微调来识别情感。
对于如何更好地使用wav2vec提取特性,或者任何可能有帮助的文章或实现,我将不胜感激。
发布于 2023-02-05 05:05:06
我想知道这是否是因为我使用了一个通用的XLSR模型,而没有对它进行微调来识别情感。
这可能仍然是正确的,但是您的方法包含了一个您应该首先消除的基本错误。您正在使用类Wav2Vec2FeatureExtractor从音频文件中提取特征,但这个类不是神经网络。它是一种预处理器,它将浮点时间序列从librosa中提取出来并进行规范化。正如文档所述,规范化确保数组具有:
零均值和单位方差
因此,这些特性只对使用它进行培训的模型有意义。当你用它训练一个支持向量机时,你实际上比较了一个支持向量机是否能打败wav2vec2,而不是wav2vec2是否比它更好!
要从wav2vec2模型获得实际的嵌入,可以使用以下代码:
import librosa
import torch
from transformers import Wav2Vec2FeatureExtractor, Wav2Vec2Model
input_audio, sample_rate = librosa.load("/content/bla.wav", sr=16000)
model_name = "facebook/wav2vec2-large-xlsr-53"
feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(model_name)
model = Wav2Vec2Model.from_pretrained(model_name)
i= feature_extractor(input_audio, return_tensors="pt", sampling_rate=sample_rate)
with torch.no_grad():
o= model(i.input_values)
print(o.keys())
print(o.last_hidden_state.shape)
print(o.extract_features.shape)
输出:
odict_keys(['last_hidden_state', 'extract_features'])
torch.Size([1, 1676, 1024])
torch.Size([1, 1676, 512])
有关last_hidden_state
和extract_features
之间的区别,请参阅此D10
。正如您所看到的,这些特性对于我的file ()来说是多维的,这意味着您可能希望应用一些池(例如平均值)。
P.S.:当我看到你的问题时,我想到的另一点是,这些嵌入本身是否真的有意义。对于纯伯特,我们知道的句子嵌入:
我不知道这些向量是什么,因为伯特不生成有意义的句子向量。
我想您可能需要对wav2vec2进行一点微调。为此,可以使用huggingfaces Wav2Vec2ForSequenceClassification类。
https://datascience.stackexchange.com/questions/118121
复制