Praca magisterska · Synteza audio · Dawid Nowak · 2026
Conditional HiFi-GAN · normal / murmur / extrastole · SR 4 000 Hz · 3 s
Synteza i augmentacja dźwięków serca przy użyciu warunkowych generatywnych sieci antagonistycznych (cGAN).
Celem pracy jest wytrenowanie generatora który na podstawie wektora szumu i etykiety klasy produkuje realistyczne 3-sekundowe nagrania audio bicia serca. Wygenerowane próbki mają służyć jako augmentacja datasetu — w szczególności klasy extrastole, która posiada zaledwie 64 przykłady treningowe, podczas gdy klasy normal i murmur mają ich ponad 20 000 każda.
Model warunkowy (cGAN) pozwala sterować klasą generowanego dźwięku przez embedding etykiety konkatenowany z wektorem latentnym i wstrzykiwany do każdej warstwy dyskryminatora. Docelowa miara jakości: test słuchowy — odsetek poprawnych klasyfikacji real/fake przez słuchaczy (50% = model oszukuje ludzi).
Trzy publiczne zbiory danych, preprocessowane do jednolitego formatu: pliki WAV, 4 000 Hz,
3 sekundy, bez zero-paddingu. Pliki krótsze niż 3 s są odrzucane (MIN_DURATION=3.0).
| Źródło | Normal | Murmur | Extrastole |
|---|---|---|---|
| PhysioNet 2016 (sety a–e) | ~5 305 | ~17 482 | 0 |
| PhysioNet/CirCor 2022 | 17 987 | 4 475 | 0 |
| Bentley Dataset B | 251 | 159 | 64 * |
| Łącznie | 23 543 | 22 116 | 64 |
* Ze 86 oryginalnych nagrań extrastole z Bentley, 22 zostały odrzucone jako zbyt krótkie (< 3 s).
Łącznie 43 056 klipów treningowych. Nierównowagę klas kompensuje WeightedRandomSampler.
ConvTranspose1d(stride=4), dyskryminator WGAN-GP.ConvTranspose1d(stride=4) przy SR = 4 kHz generuje
aliasing przy częstotliwości 4000 / 4 = 1 000 Hz — dokładnie w centrum pasma słyszalnego.
To fundamentalna wada architektury WaveGAN przy tak niskim SR.ConvTranspose1d użyto
Upsample(nearest) + Conv1d — eliminuje aliasing bez zmiany SR.CLASS_EMB_DIM=16 korelacja
Pearsona między próbkami normal i murmur osiągnęła +0.80 (epoka ~15).
Fix: CLASS_EMB_DIM=64, restart od zera.loss_D spadało do ~1.08
zbyt szybko, generator nie miał z czego się uczyć.
Fix: LR_D = 1e-4 (było 2e-4).spectral_norm na pierwszym MSD → deadlock Metal → zamieniono na weight_normF.pad(mode='reflect') w PeriodDiscriminator → hang MPS → zmieniono na mode='replicate'torch.mps.empty_cache() po każdym batchu — zapobiega kumulowaniu pamięci Metal| Epoka | loss_D | loss_G | adv | fm | sd | Czas |
|---|---|---|---|---|---|---|
| 1 | 5.0636 | 11.8026 | 6.318 | 2.743 | 0.364 | 3h 04m * |
| 2 | 4.2646 | 17.1723 | 7.438 | 4.867 | 0.434 | 3h 32m * |
| 3 | 3.0879 | 23.4549 | 9.271 | 7.092 | 0.566 | 3h 38m * |
| 4 | 2.5547 | 26.7011 | 10.036 | 8.333 | 0.614 | 1h 01m |
| 5 | 2.4442 | 28.1772 | 10.240 | 8.969 | 0.624 | 1h 02m |
| 6 | 2.4733 | 29.0384 | 10.182 | 9.428 | 0.607 | 1h 02m |
| 7 | 2.4674 | 29.8040 | 10.225 | 9.789 | 0.609 | 1h 05m |
* Epoki 1–3 wolne z powodu jednorazowej kompilacji shaderów Metal (Apple MPS). Rosnące loss_G i fm przy malejącym loss_D świadczą o zdrowej dynamice GAN — dyskryminator nie dominuje.
Test słuchowy (metoda podstawowa): słuchacze (niekoniecznie medycy) odsłuchują mieszane próbki bez etykiet i próbują odróżnić prawdziwe od syntetycznych. Miara: procent poprawnych klasyfikacji — wynik 50% oznacza, że model skutecznie oszukuje ludzi.
Protokół: anchor (najlepsza prawdziwa + najgorsza syntetyczna jako punkt odniesienia), następnie ocena binarna dla próbek bez etykiet.
Alternatywna ewaluacja (rozważana z promotorem): klasyfikator ML trenowany na zbiorze real vs. real+synthetic — bardziej obiektywna miara użyteczności augmentacji do zadań downstream (np. klasyfikacja patologii).