---
title: 在長期時頻譜圖上執行聲源分離
description: Spectrogram-based source separation
tags: soundscape viewer, tutorial, ecoacoustics, source separation
disqus: hackmd
---
# 在長期時頻譜圖上執行聲源分離
LTS 上經常可以看到多個聲源同時出現,這種聲源之間互相干涉 (simultaneous source interference) 的現象,可能會導致分析結果出現誤差。例如:聲壓值較高,可能是因為同時接收到人為噪音與動物聲音,若是將聲壓值作為發聲動物活動的指標,則會誤判發聲動物活動的主要時間。為了解決這個問題,可以應用 Soundscape Viewer 來進行聲源分離,目前提供非監督式 (Unsupervised) 和監督式 (Supervised) 兩種聲源分離的模式。
## 非監督式聲源分離
非監督式的聲源分離,就是不需要人工標註資料來進行模型訓練,演算法能夠自行從分析資料中學習到不同聲源的差異。Soundscape Viewer 的週期性編碼非負矩陣分解法 (Periodicity-coded non-negative matrix factorization,PC-NMF),是一種基於雙層 NMF 網路來學習輸入資料中的頻率特徵與出現時間,只要使用者輸入待分離的聲源數量,即能夠透過學習到的週期性模式來進行盲聲源分離 (Blind source separation)。
是否能夠有效運用 PC-NMF 進行聲源分離,最主要的因素就是分析資料是否符合 PC-NMF 的假設:不同聲源具有獨特的週期性模式。以我們過去的研究為例,PC-NMF 可以被運用在森林聲景中,分離動物合唱和其他聲音。在海洋聲景中,則可以用來分離魚類合唱、鯨豚聲音與船隻噪音。大部分的動物活動,都可能會隨著日夜、潮汐、季節而變,若是週期性模式夠明顯,且 LTS 涵蓋的時間範圍足夠,一般來說皆能夠有效應用 PC-NMF 分離不同聲源。
### pcnmf
雖然在應用 PC-NMF 的時候,不需要提供人工標註資料,但仍需要透過數學方法來引導模型,以提升模型學習聲源特徵的能力。首先,我們必須定義 pcnmf 的幾個參數,包含:特徵數量、每個特徵容納的錄音片段長度與稀疏度。
* 模型的特徵數量 (*basis_num*):大於1的整數,預設為60
* 特徵容納的錄音片段長度 (*feature_length*):大於0的整數
* 特徵稀疏度 (*sparseness*):0或是0到1之間的值 (不包含1)
模型的特徵數量越多,代表模型的參數量越大。舉例來說,每一篇文章都可以拆解成一本「字典」,這本字典包含了在這篇文章中用到的所有的字。若文章越長、越複雜,字典中的字就會越多,否則就無法重建文章。理論上若輸入資料越複雜,則越需要提高模型的特徵數量。
雖然 PC-NMF 會自己學習輸入資料的頻譜特徵,但我們也可以透過指定特徵容納的錄音片段長度來控制特徵學習。特徵容納的錄音片段長度越大,代表特徵越有可能學到聲源頻譜隨著時間而變的特性。在許多聲音資料中,例如鯨豚的哨叫聲,這些聲音的主要音頻會隨時間而變,而呈現出豐富的曲調變化。若我們讓 PC-NMF 的每個特徵只能學單一聲音片段的頻譜特性時,那就需要多個特徵才能完整學習一個聲源的頻率變化特性。因此,我們可以提高特徵可容納的錄音片段長度,讓單一特徵具有較多的參數空間,以學習單一聲源的頻率變化特性。
此外,特徵的稀疏度也是一個重要的參數。稀疏度是一種資料分布特性的量化方式,當稀疏度越高,表示資料大多分布在少數的類別中;相反的,當稀疏度越低,則表示資料在許多類別中都有被觀測到。在 PC-NMF 中,稀疏度控制的是每個特徵中0值的比例,若是稀疏度越接近1,則通常會學習到窄頻、短時距的特徵;相反的,若稀疏度越接近0,則通常會學習到寬頻、長時距的特徵。
定義完 PC-NMF 模型參數後,便可以將輸入資料準備好,並指定希望從輸入資料中分離出來的聲源數量 (*source_num*)。待聲源分離模型學習完成後,我們可以運用 **pcnmf.plot_pcnmf** 視覺化模型學到的頻譜特徵,並指定對應的聲源 (*source_num*),看看聲源分離的成果。
```python=
# Import pcnmf and define model parameters
from soundscape_IR.soundscape_viewer import pcnmf
model=pcnmf(sparseness=0, feature_length=12, basis_num=60)
# Unsupervised separation
input_data,f=LTS.input_selection('median', prewhiten_percent=10, threshold=0)
model.unsupervised_separation(input_data, f, source_num=2)
# Visualize the spectral features and the result of source #1
model.plot_pcnmf(source=1)
# Visualize the spectral features and the result of source #2
model.plot_pcnmf(source=2)
# Save model parameter
# Directly save the model in your Drive folder by specifying the folder_id
model.save_model(filename='LTS_median_pcnmf.mat', folder_id=[])
```

上圖為針對分離的第一個聲源,運用 PC-NMF 學習到的頻譜特徵,可以看到因為我們讓每個特徵可以容納12筆錄音片段,因此有些特徵便反映出頻率隨時間變化的特性。下圖為分離出第一個聲源之後,重建的長期時頻譜圖。

這張圖和前一張圖類似,但內容為針對分離的第二個聲源,運用 PC-NMF 學習到的頻譜特徵與重建的長期時頻譜圖。可以看到兩個聲源之間的頻譜與時間特性都有相當大的差異,顯示在這個例子中,PC-NMF 能夠有效地進行盲聲源分離。
確定聲源分離模型符合我們的期待之後,記得要運用 **pcnmf.save_model** 來儲存模型參數(也可以透過指定 *folder_id* 把檔案直接儲存至 Drive 資料夾)。這些已完成訓練的聲源分離模型,未來可以運用在新的待測資料上,預測兩種不同聲源的變化趨勢。
## 監督式聲源分離
監督式的聲源分離,則是先透過人工標註資料後,讓演算法能夠從被標註的訓練資料中學習不同聲源的差異。目前 (2020/5/31) Soundcape Viewer 僅能匯入已完成訓練的聲源分離模型,並以此針對新的待測資料進行預測,近期將會再增加運用標註資料訓練模型的工具。
```python=
# Load an existing PC-NMF model
model=pcnmf()
model.load_model(filename='LTS_median_pcnmf.mat')
# Load another dataset of LTS and run supervised separation
input_data,f=LTS.input_selection('median', prewhiten_percent=10, threshold=0)
model.supervised_separation(input_data, f)
```
在運用傳統的監督式聲源分離新的待測資料時,並不會改變已經學習到的聲源頻譜特徵,僅會依據這些頻譜特徵來預測各聲源的時間變化趨勢。因此,若是新的待測資料中含有之前沒有學習過的聲源,就可能因為「沒看過」而誤判。舉例來說,A地的錄音資料訓練的聲源分離模型,在B地的錄音資料中無法有效進行聲源分離,這可能是因為兩地點的主要發聲動物組成與人為活動有所不同。這些問題,可以運用其他方法來解決,例如「適應性 (Adaptive)」或是「半監督式 (Semi-supervised)」的聲源分離模型架構。