音声識別や音響イベント検出の特徴量として、対数メルスペクトルがよく用いられています。この対数メルスペクトルに代わる特徴量として、2017年にPer-Channel Energy Normalization(PCEN)が提案され、性能が向上することが報告されています。今回は、librosaを使って、PCENを算出します。
Per-Channel Energy Normalization(PCEN)とは
PCENは、 ICASSP2017でGoogleから提案された方法で、以下式から算出されます。
Eにはメルフィルターバンクのエネルギー、Mは平滑化したエネルギーで、εはゼロ割防止の小さな定数、aによって正規化の強さを設定します。δはオフセット、rはダイナミックレンジの圧縮係数になります。これらの係数の設計指針は以下論文に記載されています。また、この論文によるとPCENで性能があがる理由は、背景雑音の振幅がガウス分布により近づき、チャンネル間相関が低くなるためです。
librosaを用いたPCENの算出方法
librosaライブラリでPCENを算出するための、librosa.pcenの使い方を見ていきます。
PCENを算出する音源を、librosaのサンプルから読み込みます。
!pip install git+https://github.com/librosa/librosa # librosaの最新バージョンをインストール
import librosa
y, sr = librosa.load( librosa.example('robin'))
PCENと比較のため、対数メルスペクトルも算出します。まず、メルスペクトルを算出し、librosa.pcenの第一引数に指定するだけでPCENが算出されます。
import numpy as np
S = librosa.feature.melspectrogram(y=y, sr=sr, power=1) # メルスペクトルの算出
log_S = librosa.amplitude_to_db(S+1e-6, ref=np.max) # 対数メルスペクトルへ変換
pcen_S = librosa.pcen(S*(2**31), sr=sr) # PCENの算出
対数メルスペクトルとPCENを表示します。
import matplotlib.pyplot as plt
# 表示用関数
def plot_spectrogram(spec, title=None, ylabel="mel_bin", aspect="auto", xmax=None):
fig, axs = plt.subplots(1, 1)
axs.set_title(title or "Spectrogram (db)")
axs.set_ylabel(ylabel)
axs.set_xlabel("frame")
im = axs.imshow(spec, origin="lower", aspect=aspect)
if xmax:
axs.set_xlim((0, xmax))
fig.colorbar(im, ax=axs)
plt.show(block=False)
plot_spectrogram((log_S-log_S.mean())/log_S.std(), title='logmel')
plot_spectrogram(pcen_S, title='PCEN')
コメント