如何从HuggingFace的wav2vec2预训练模型中提取embedding特征
两个输出的区别与选择
extract_features是wav2vec2前端7层卷积层的输出,属于低层级声学特征,仅包含基础的语音声学属性(比如音色、音调、音素轮廓),没有经过后续Transformer层的上下文建模。last_hidden_state是经过所有Transformer层编码后的输出,包含了全局上下文依赖的高层语义信息,绝大多数非语音识别的分类任务(比如说话人识别、情感分类、语音场景分类)用这个效果更好。- 你可以两种特征都提取后分别训练SVM,根据实际验证集效果选择最优即可。
特征提取方式的正确性说明
你当前的写法没有逻辑错误,但有两个可以优化的点:
- 纯提取特征不需要用到分词器组件,把
Wav2Vec2Processor换成更轻量的Wav2Vec2FeatureExtractor即可,原有参数不需要调整。 - 提取特征前需要加
model.eval()切换推理模式,同时用with torch.no_grad()关闭梯度计算,避免不必要的显存占用和计算开销。 - 你拿到的
last_hidden_state形状为[批量大小, 时间步长, 特征维度],是变长序列特征,无法直接喂给SVM,需要在时间维度做聚合得到固定长度特征,常用方法是取时间维度的均值/最大值,或者拼接均值、方差、最大最小值得到统计特征。
指定层embedding获取方法
加载模型时传入output_hidden_states=True参数,模型返回结果中的hidden_states字段会返回所有层的特征 tuple:
- tuple第0位就是
extract_features对应的卷积层输出 - 第1位到最后一位依次是第1层到第N层Transformer的输出,你要取指定层的话直接按索引取值即可,比如取倒数第二层Transformer输出就用
outputs.hidden_states[-2]。
完整参考代码
import torch from transformers import Wav2Vec2FeatureExtractor, Wav2Vec2Model model_name = "jonatasgrosman/wav2vec2-large-xlsr-53-german" feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(model_name) # 开启output_hidden_states才能拿到所有层的输出 model = Wav2Vec2Model.from_pretrained(model_name, output_hidden_states=True) model.eval() # 切换推理模式 input_values = feature_extractor( train_dataset[:10]["speech"], return_tensors="pt", padding=True, sampling_rate=16000 ).input_values with torch.no_grad(): # 关闭梯度计算 outputs = model(input_values) # 最后一层Transformer输出 last_hidden = outputs.last_hidden_state # 卷积层输出 cnn_out = outputs.extract_features # 取第12层Transformer输出 layer_12_out = outputs.hidden_states[12] # 时间维度平均池化得到固定长度特征,转numpy格式可直接喂给SVM fixed_len_feat = last_hidden.mean(dim=1).numpy()
内容的提问来源于stack exchange,提问作者Synapse
相关产品推荐
相关产品推荐

