NMFで音源分離を試してみる
ずーーっと前に、 NMFアルゴリズムの導出(ユークリッド距離版) - LESS IS MORE で実際に実装してみてやってみると書いていたのに、まったくやっていなかったことに気づいたのでやりました。
音楽に対してやってみたのですが、簡単な曲だったら、まぁぼちぼち期待通りに動いたかなぁという印象です。コードとノートを挙げたので、興味のある方はどうぞ。
Github
https://github.com/r9y9/julia-nmf-ss-toy
ノート
NMF-based Music Source Separation Demo.ipynb | nbviewer
NMFのコード (Julia)
NMFの実装の部分だけ抜き出しておきます。
function nmf_euc(Y::AbstractMatrix, K::Int=4;
maxiter::Int=100)
H = rand(size(Y, 1), K)
U = rand(K, size(Y, 2))
const ϵ = 1.0e-21
for i=1:maxiter
H = H .* (Y*U') ./ (H*U*U' + ϵ)
U = U .* (H'*Y) ./ (H'*H*U + ϵ)
U = U ./ maximum(U)
end
return H, U
end
いやー簡単ですねー。NMFアルゴリズムの導出(ユークリッド距離版) - LESS IS MORE で導出した更新式ほぼそのままになってます(異なる点としては、ゼロ除算回避をしているのと、Uをイテレーション毎に正規化していることくらい)。
B3, B4くらいの人にとっては参考になるかもしれないと思ってあげてみた。
おわり