[CWS-PResUNet] 機械学習でブラウザだけでボーカル抽出 [Python]

2022年3月18日金曜日

Artificial Intelligence

本記事では、CWS-PResUNetと呼ばれる機械学習手法を用いて、音楽からボーカルのみを抽出する方法をご紹介します。

アイキャッチ
出典: 2021-ISMIR-MSS-Challenge-CWS-PResUNet

CWS-PResUNet

概要

Channel-wise Subband Phase-aware ResUNet(CWS-PResUNet)は、音声ソース分離(Music source separation:MSS)タスクを実現する技術です。

従来技術の多くは、境界比マスクを推定し、スペクトログラムを分離しています。CWS-PResUNetでは、入力信号をサブバンドに分解し、各ソースのunbound complex ideal ratio mask(cIRM)を推定することによって分離を実現しています。また、CWS機能を利用して、スペクトログラムで共有される不要なグローバルウェイトを制限し計算リソースを削減することにより、より大きなアーキテクチャが計算可能になっています。

CWS-PResUNetのアーキテクチャ

詳細はこちらの論文をご参照ください。

本記事では、上記手法を用いて、任意の音楽からボーカルを抽出する方法をご紹介します。

免責事項

下記のデモでは、Youtube上の動画を取得し、編集等行います。著作権等にご注意いただき正しくご利用頂くようお願い致します。

これからご紹介する技術はあくまでご自身の技術理解を深めるためにのみご活用ください。本記事を参考にして生じたいかなる損害に関しても当ブログは責任を負いません。

デモ(Colaboratory)

それでは、実際に動かしながらボーカル抽出を行っていきます。
ソースコードは本記事にも記載していますが、下記のGitHubでも取得可能です。
GitHub - Colaboratory demo

また、下記から直接Google Colaboratoryで開くこともできます。
Open In Colab

なお、このデモはPythonで実装しています。
Pythonの実装に不安がある方、Pythonを使った機械学習について詳しく勉強したい方は、以下の書籍やオンライン講座などがおすすめです。

環境セットアップ

それではセットアップしていきます。 Colaboratoryを開いたら下記を設定しGPUを使用するようにしてください。

「ランタイムのタイプを変更」→「ハードウェアアクセラレータ」をGPUに変更

まず、論文発表元のGitHubからソースコードを取得します。

%cd /content

!git clone https://github.com/haoheliu/2021-ISMIR-MSS-Challenge-CWS-PResUNet.git

次に、ボーカル抽出に必要なライブラリをインストールします。

%cd /content/2021-ISMIR-MSS-Challenge-CWS-PResUNet

!pip install --upgrade gdown

! pip3 install -r requirements.txt
# ModuleNotFoundError: No module named 'torchtext.legacy' 回避のため torchtextはバージョン固定
! pip3 install torchtext==0.8.1 demucs==3.0.1

以上で、セットアップは完了です。

ボーカル抽出(wavファイル)

まず、クローンしたソースコードに付随していたテスト用wavファイルからボーカル音声を抽出します。

%cd /content/2021-ISMIR-MSS-Challenge-CWS-PResUNet

!python3 main.py -i example/test -o example/results -s vocals other --cuda

ipd.Audio("example/results/xuemaojiao/vocals.wav", rate=44100)

上記を実行すると、/content/2021-ISMIR-MSS-Challenge-CWS-PResUNet/example/results/xuemaojiao/vocals.wavがボーカル抽出音声として出力されます。

ボーカル抽出(Youtube)

続いて、任意のYoutube動画からボーカルを抽出していきます。
まず、必要なライブラリをインストール・インポートします。

!pip install yt-dlp moviepy

from yt_dlp import YoutubeDL

from moviepy.video.fx.resize import resize
from moviepy.editor import VideoFileClip, AudioFileClip, ImageSequenceClip, CompositeAudioClip
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip

次に、Youtubeから取得する動画のURLなどを指定します。

video_url = 'https://www.youtube.com/watch?v=Qd01-6xVSHk' #@param {type:"string"}

#@markdown 動画の切り抜き範囲(秒)を指定してください。\
#@markdown 30秒以上の場合OOM発生の可能性が高いため注意
start_sec =  57#@param {type:"integer"}
end_sec =  69#@param {type:"integer"}

(start_pt, end_pt) = (start_sec, end_sec)

start_sec, end_secは、動画中の開始、終了区間です。目安として30秒以内になるように指定してください。
あまりに長いと後続の処理でメモリが足らずエラーになります。

本記事では、フリー楽曲である魔王魂様のシャイニングスターを使用させていただきます。

設定に基づいて動画を取得します。

!mkdir -p /content/2021-ISMIR-MSS-Challenge-CWS-PResUNet/videos/results


download_resolution = 360
full_video_path = '/content/2021-ISMIR-MSS-Challenge-CWS-PResUNet/videos/full_video.mp4'
input_clip_path = '/content/2021-ISMIR-MSS-Challenge-CWS-PResUNet/videos/input_clip.mp4'
input_audio_path = '/content/2021-ISMIR-MSS-Challenge-CWS-PResUNet/videos/input_clip.wav'

# 動画ダウンロード
ydl_opts = {'format': f'best[height<={download_resolution}]', 'overwrites': True, 'outtmpl': full_video_path}
with YoutubeDL(ydl_opts) as ydl:
    ydl.download([video_url])

指定区間を切り出した動画を作成します。

# extract the relevant subclip:
with VideoFileClip(full_video_path) as video:
    subclip = video.subclip(start_pt, end_pt)
    subclip.write_videofile(input_clip_path)

切り出した動画から音声ファイルを生成します。

clip = VideoFileClip(input_clip_path)
clip.audio.write_audiofile(input_audio_path, codec='pcm_s16le')

ipd.Audio(input_audio_path, rate=44100)

それでは、生成した音声ファイルをCWS-PResUNetに入力してボーカルを抽出します。

!python3 main.py -i {input_audio_path} -o /content/2021-ISMIR-MSS-Challenge-CWS-PResUNet/videos/results -s vocals other --cuda

最後に元の動画の音声を抽出したボーカル音声に差し替えます。

videoclip = VideoFileClip(input_clip_path)
audioclip = AudioFileClip("/content/2021-ISMIR-MSS-Challenge-CWS-PResUNet/videos/results/input_clip/vocals.wav")

new_audioclip = CompositeAudioClip([audioclip])
videoclip.audio = new_audioclip
videoclip.write_videofile("/content/2021-ISMIR-MSS-Challenge-CWS-PResUNet/videos/results/input_clip/vocals.mp4")

生成結果は以下の通りです。
ボーカル以外の音声が除去されています。

まとめ

本記事では、CWS-PResUNetを用いたボーカル抽出を行いました。
これを機に機械学習に興味を持つ方が一人でもいらっしゃいましたら幸いです。

また本記事では、機械学習を動かすことにフォーカスしてご紹介しました。
もう少し学術的に体系立てて学びたいという方には以下の書籍などがお勧めです。ぜひご一読下さい。


また動かせるだけから理解して応用できるエンジニアの足掛かりに下記のUdemyなどもお勧めです。

参考文献

1.  論文 - CWS-PResUNet: Music Source Separation with Channel-wise Subband Phase-aware ResUNet

2. GitHub - 2021-ISMIR-MSS-Challenge-CWS-PResUNet

AIで副業ならココから!

まずは無料会員登録

プロフィール

メーカーで研究開発を行う現役エンジニア
組み込み機器開発や機会学習モデル開発に従事しています

本ブログでは最新AI技術を中心にソースコード付きでご紹介します


Twitter

カテゴリ

このブログを検索

ブログ アーカイブ

TeDokology