Views
No views yet
1import numpy as np
2import torch
3import torch.nn as nn
4from transformers import Wav2Vec2Processor
5from transformers.models.wav2vec2.modeling_wav2vec2 import (
6 Wav2Vec2Model,
7 Wav2Vec2PreTrainedModel,
8)
9
10
11class ModelHead(nn.Module):
12 r"""Classification head."""
13
14 def __init__(self, config, num_labels):
15
16 super().__init__()
17
18 self.dense = nn.Linear(config.hidden_size, config.hidden_size)
19 self.dropout = nn.Dropout(config.final_dropout)
20 self.out_proj = nn.Linear(config.hidden_size, num_labels)
21
22 def forward(self, features, **kwargs):
23
24 x = features
25 x = self.dropout(x)
26 x = self.dense(x)
27 x = torch.tanh(x)
28 x = self.dropout(x)
29 x = self.out_proj(x)
30
31 return x
32
33
34class AgeGenderModel(Wav2Vec2PreTrainedModel):
35 r"""Speech emotion classifier."""
36
37 def __init__(self, config):
38
39 super().__init__(config)
40
41 self.config = config
42 self.wav2vec2 = Wav2Vec2Model(config)
43 self.age = ModelHead(config, 1)
44 self.gender = ModelHead(config, 3)
45 self.init_weights()
46
47 def forward(
48 self,
49 input_values,
50 ):
51
52 outputs = self.wav2vec2(input_values)
53 hidden_states = outputs[0]
54 hidden_states = torch.mean(hidden_states, dim=1)
55 logits_age = self.age(hidden_states)
56 logits_gender = torch.softmax(self.gender(hidden_states), dim=1)
57
58 return hidden_states, logits_age, logits_gender
59
60
61
62# load model from hub
63device = 'cpu'
64model_name = 'audeering/wav2vec2-large-robust-6-ft-age-gender'
65processor = Wav2Vec2Processor.from_pretrained(model_name)
66model = AgeGenderModel.from_pretrained(model_name)
67
68# dummy signal
69sampling_rate = 16000
70signal = np.zeros((1, sampling_rate), dtype=np.float32)
71
72
73def process_func(
74 x: np.ndarray,
75 sampling_rate: int,
76 embeddings: bool = False,
77) -> np.ndarray:
78 r"""Predict age and gender or extract embeddings from raw audio signal."""
79
80 # run through processor to normalize signal
81 # always returns a batch, so we just get the first entry
82 # then we put it on the device
83 y = processor(x, sampling_rate=sampling_rate)
84 y = y['input_values'][0]
85 y = y.reshape(1, -1)
86 y = torch.from_numpy(y).to(device)
87
88 # run through model
89 with torch.no_grad():
90 y = model(y)
91 if embeddings:
92 y = y[0]
93 else:
94 y = torch.hstack([y[1], y[2]])
95
96 # convert to numpy
97 y = y.detach().cpu().numpy()
98
99 return y
100
101
102print(process_func(signal, sampling_rate))
103# Age child female male
104# [[ 0.3079211 0.00848487 0.0051472 0.9863679 ]]
105
106print(process_func(signal, sampling_rate, embeddings=True))
107# Pooled hidden states of last transformer layer
108# [[ 0.00409924 0.00365688 0.02392936 ... 0.02349018 -0.13294911
109# 0.1538802 ]]