Views
No views yet
git clone https://github.com/PhilipAmadasun/SER-Model-for-dimensional-attribute-prediction.git1import torch
2import torchaudio
3from SER_Model_setup import SERModel
4
5device = "cuda" if torch.cuda.is_available() else "cpu"
6
7checkpoint_path = "<model.pt file>"
8checkpoint = torch.load(checkpoint_path, map_location=device)
9
10# Create the model architecture and load weights
11model = SERModel()
12model.load_state_dict(checkpoint['model_state_dict'])
13model.to(device)
14model.eval()
15
16audio_path = "<wav file>"
17audio, sr = torchaudio.load(audio_path)
18
19if sr != model.sample_rate:
20 resampler = torchaudio.transforms.Resample(sr, model.sample_rate)
21 audio = resampler(audio)
22#print(audio.shape[0])
23
24if audio.shape[0] > 1:
25 audio = torch.mean(audio, dim=0, keepdim=True)
26
27audio_len = audio.shape[-1]
28
29# Create waveform tensor (shape: [1, audio_len])
30waveform = torch.zeros(1, audio_len, dtype=torch.float32)
31# print(waveform)
32# print()
33# print(f"waveform shape: {waveform.shape}")
34# print()
35waveform[0, :audio_len] = audio
36# print(waveform)
37# print()
38# Create mask as 2D tensor: shape [1, audio_len] with ones in valid region
39mask = torch.ones(1, audio_len, dtype=torch.float32)
40# print(mask)
41# print()
42# print(f"mask shape: {mask.shape}")
43
44# Move waveform and mask to device
45waveform = waveform.to(device)
46mask = mask.to(device)
47
48# Normalize waveform using model's mean and std
49mean = model.mean.to(device)
50std = model.std.to(device)
51waveform = (waveform - mean) / (std + 1e-6)
52
53with torch.no_grad():
54 predictions = model(waveform, mask) # predictions shape: [1, 3]
55
56# Extract predictions: [0,0] for arousal, [0,1] for valence, [0,2] for dominance
57arousal = predictions[0, 0].item()
58valence = predictions[0, 1].item()
59dominance = predictions[0, 2].item()
60
61print(f"Arousal: {arousal:.3f}")
62print(f"Valence: {valence:.3f}")
63print(f"Dominance: {dominance:.3f}")1import os
2import glob
3import torch
4import torchaudio
5from SER_Model_setup import SERModel # Adjust if your model code is elsewhere
6
7def load_model_from_checkpoint(checkpoint_path, device='cpu'):
8 """
9 Loads the SERModel and weights from a checkpoint, moves to device, sets eval mode.
10 """
11 checkpoint = torch.load(checkpoint_path, map_location=device)
12
13 # Create the model architecture
14 model = SERModel()
15 model.load_state_dict(checkpoint['model_state_dict'])
16
17 model.to(device)
18 model.eval()
19 return model
20
21def batch_inference(model, file_paths, device='cpu', normalize=True):
22 """
23 Perform true batch inference on multiple .wav files in one forward pass.
24
25 Args:
26 model (SERModel): The loaded SER model in eval mode
27 file_paths (list[str]): List of paths to .wav files
28 device (str or torch.device): 'cpu' or 'cuda'
29 normalize (bool): Whether to normalize waveforms (subtract mean, divide std)
30
31 Returns:
32 dict: {filename: {"arousal": float, "valence": float, "dominance": float}}
33 """
34
35 # ----------------------------------------
36 # 1) Load & store all waveforms in memory
37 # ----------------------------------------
38 waveforms_list = []
39 lengths = []
40 for fp in file_paths:
41 # Load audio
42 audio, sr = torchaudio.load(fp)
43
44 # Resample if needed
45 if sr != model.sample_rate:
46 resampler = torchaudio.transforms.Resample(sr, model.sample_rate)
47 audio = resampler(audio)
48
49 # Convert stereo -> mono if needed
50 if audio.shape[0] > 1:
51 audio = torch.mean(audio, dim=0, keepdim=True)
52
53 # audio shape => [1, num_samples]
54 lengths.append(audio.shape[-1])
55 waveforms_list.append(audio)
56
57 # ----------------------------------------
58 # 2) Determine max length
59 # ----------------------------------------
60 max_len = max(lengths)
61
62 # ----------------------------------------
63 # 3) Pad each waveform to max length & build masks
64 # ----------------------------------------
65 batch_size = len(waveforms_list)
66 batched_waveforms = torch.zeros(batch_size, 1, max_len, dtype=torch.float32)
67 masks = torch.zeros(batch_size, max_len, dtype=torch.float32)
68
69 for i, audio in enumerate(waveforms_list):
70 cur_len = audio.shape[-1]
71 batched_waveforms[i, :, :cur_len] = audio
72 masks[i, :cur_len] = 1.0 # valid portion
73
74 # ----------------------------------------
75 # 4) Move batched data to device BEFORE normalization
76 # ----------------------------------------
77 batched_waveforms = batched_waveforms.to(device)
78 masks = masks.to(device)
79
80 # ----------------------------------------
81 # 5) Normalize if needed (model.mean, model.std)
82 # ----------------------------------------
83 if normalize:
84 # model.mean and model.std are buffers; ensure they're on the correct device
85 mean = model.mean.to(device)
86 std = model.std.to(device)
87 batched_waveforms = (batched_waveforms - mean) / (std + 1e-6)
88
89 # ----------------------------------------
90 # 6) Single forward pass
91 # ----------------------------------------
92 with torch.no_grad():
93 predictions = model(batched_waveforms, masks)
94 # predictions shape => [batch_size, 3]
95
96 # ----------------------------------------
97 # 7) Build result dict
98 # ----------------------------------------
99 results = {}
100 for i, fp in enumerate(file_paths):
101 arousal = predictions[i, 0].item()
102 valence = predictions[i, 1].item()
103 dominance = predictions[i, 2].item()
104 filename = os.path.basename(fp)
105 results[filename] = {
106 "arousal": arousal,
107 "valence": valence,
108 "dominance": dominance
109 }
110
111 return results
112
113if __name__ == "__main__":
114 # -----------------------------------------
115 # Example usage
116 # -----------------------------------------
117 device = "cuda" if torch.cuda.is_available() else "cpu"
118
119 checkpoint_path = "<weights.pt>"
120 model = load_model_from_checkpoint(checkpoint_path, device=device)
121
122 # Suppose you have a folder of .wav files
123 wav_folder = "<directory containing .wav files>"
124 wav_paths = glob.glob(os.path.join(wav_folder, "*.wav"))
125
126 # Do a single pass of batch inference
127 all_results = batch_inference(model, wav_paths, device=device, normalize=True)
128
129 # Print results
130 for fname, preds in all_results.items():
131 print(f"{fname}: Arousal={preds['arousal']:.3f}, "
132 f"Valence={preds['valence']:.3f}, Dominance={preds['dominance']:.3f}")