MMS-MSGは、音声混合物を生成するための非常にモジュール式で柔軟なフレームワークです。混合信号生成のSMS-WSJデータベースのコードベースを拡張して、会議スタイルの音声混合物と古典的な音声混合データベースに対応する混合信号の両方を生成できるようにします。
会議データは、非常に動的な設定について説明します。 MMS-MSGの両方の環境は、単一の新しいデータベースを提供することを目指していません。
代わりに、できるだけ多くの環境でプロセスと転写システムを満たすプロトタイピングと評価を可能にする適応可能なフレームワークを提供したいと考えています。
MMS-MSGの中心的な側面は、会議スタイルのデータの生成です。会議はモジュール形式で生成されます。調整可能なパラメーターは次のとおりです。
サンプリングプロセスはモジュール化されているため、サンプリングパイプラインをわずかに変更することで多くのシナリオを作成できます。単一のモジュールの使用方法を示すためのサンプルクラスを提供します。シナリオがサポートされていない場合、MMS-MSGを要件に適応させるために、新しいサンプリングモジュールを簡単に実装できます。
MMS-MSGのデータシミュレーションプロセスは、パラメーターサンプリングと実際のデータ生成に分割されます。これを通じて、オンデマンドデータ生成をサポートします。このようにして、ソースデータと会議パラメーターのみを保存する必要があり、必要なディスクスペースを最小限に抑えながら、さまざまな会議シナリオのシミュレーションを可能にします。ただし、ワークフローに必要なハードディスクに保存する場合、会議データのオフライン生成もサポートしています。
現在使用されているソース分離データベースの仕様に従って音声混合物を生成するコードを提供します。このコードでは、複数のスピーカーの単一の発話が部分的または完全に互いに重複しています。 MMS-MSGを使用してこれらのデータベースのトレーニングデータを生成することにより、動的混合のネイティブサポートを提供します。
サポートされている音声混合データベース:
計画:
混合ジェネレーターはlazy_datasetを使用します。 MMS_MSGのコア機能はLazy_Datasetなしで使用できますが、一部の機能(動的ミキシングやデータベースの抽象化など)は利用できません。
from mms_msg . databases . classical . full_overlap import WSJ2Mix
from mms_msg . sampling . utils import collate_fn
db = WSJ2Mix ()
# Get a train dataset with dynamic mixing
# This dataset only emits the metadata of the mixtures, it doesn't load
# the data yet
ds = db . get_dataset ( 'train_si284_rng' )
# The data can be loaded by mapping a database's load_example function
ds = ds . map ( db . load_example )
# Other dataset modifications (see lazy_dataset doc)
ds = ds . shuffle ( reshuffle = True )
ds = ds . batch ( batch_size = 8 ). map ( collate_fn )
# ...
# Parallelize data loading with lazy_dataset
ds = ds . prefetch ( num_workers = 8 , buffer_size = 16 )
# The dataset can now be used in any training loop
for example in ds :
# ... do fancy stuff with the example.
# The loaded audio data is in example['audio_data']
print ( example )
他のデータ変更ルーチンは、例を読み込んだ後にds
にマッピングできます。
lazy_dataset.Dataset
は、 torch.utils.data.DataLoader
に差し込むことができます:
from mms_msg . databases . classical . full_overlap import WSJ2Mix
db = WSJ2Mix ()
ds = db . get_dataset ( 'train_si284_rng' ). map ( db . load_example )
# Parallelize data loading with torch.utils.data.DataLoader
from torch . utils . data import DataLoader
loader = DataLoader ( ds , batch_size = 8 , shuffle = True , num_workers = 8 )
for example in loader :
print ( example )
入力例には、この構造が必要です。
example = {
'audio_path' : {
'observation' : 'single_speaker_recording.wav'
},
'speaker_id' : 'A' ,
'num_samples' : 1234 , # Number of samples of the observation file
# 'num_samples': {'observation': 1234} # Alernative, if other audios are present
'dataset' : 'test' , # The input dataset name
'example_id' : 'asdf1234' , # Unique ID of this example. Optional if the input data is passes as a dict
'scenario' : 'cafe-asdf1234' , # (Optional) If provided, mms_msg makes sure that all examples of the same speaker in a mixture share the same scenario
# ... (any additional keys)
}
混合物の発話を選択した後、これらの発話の例は正規化され、「照合」され、これに類似した構造が得られます。
example = {
'audio_path' : {
'original_source' : [
'source1.wav' ,
'source2.wav' ,
],
},
'speaker_id' : [
'A' , 'B'
],
'num_samples' : { # The structure under some keys mirrors the structure in 'audio_path'
'original_source' : [
1234 , 4321
]
},
'source_id' : [ # Reference to the source examples this mixture was created from
'asdf1234' , 'asdf1235'
],
...
}
このような構造から始めて、サンプリングモジュールを適用して、例、たとえば発話のオフセットやスケーリングなど、より多くの情報を例に記入できます。
データベースのクラスまたは定義は、 mms_msg.databases
のいくつかの一般的なシナリオに対して提供されます。各データベースクラスは、2つの方法を定義する必要があります。
get_mixture_dataset
は、「サンプリング」段階をカプセル化し、サンプリングモジュールのパイプラインを構築します。load_example
は、「シミュレーション」段階、つまり、オーディオデータの読み込みとミキシングを提供します。基本的な(パラメーターフリー)データベースは次のようになります。
from mms_msg . databases . database import MMSMSGDatabase
from lazy_dataset . database import JsonDatabase
import mms_msg
class MyDatabase ( JsonDatabase , MMSMSGDatabase ):
def get_mixture_dataset ( self , name , rng ):
ds = mms_msg . sampling . source_composition . get_composition_dataset (
input_dataset = super (). get_dataset ( name ),
num_speakers = 2 ,
rng = rng ,
)
ds = ds . map ( mms_msg . sampling . pattern . classical . ConstantOffsetSampler ( 8000 ))
ds = ds . map ( mms_msg . sampling . environment . scaling . ConstantScalingSampler ( 0 ))
return ds
def load_example ( self , example ):
return mms_msg . simulation . anechoic . anechoic_scenario_map_fn ( example )
そして、インスタンス化することができます
db = MyDatabase ( 'path/to/source/database.json' )
データセットサンプリングパイプラインの構造については、次のセクションで説明します。
これは、単一のデータセット用の単純なサンプリングパイプラインの例です。
import mms_msg
input_ds = ... # Get source utterance examples from somewhere
# Compute a composition of base examples. This makes sure that the speaker distribution
# in the mixtures is equal to the speaker distribution in the original database.
ds = mms_msg . sampling . source_composition . get_composition_dataset ( input_dataset = input_ds , num_speakers = 2 )
# If required: Offset the utterances
ds = ds . map ( mms_msg . sampling . pattern . classical . ConstantOffsetSampler ( 0 ))
# If required: Add log_weights to simulate volume differences
ds = ds . map ( mms_msg . sampling . environment . scaling . UniformScalingSampler ( max_weight = 5 ))
サンプリングプロセスは、常に「ソース構成」、すなわち各混合物のサンプリング(ベース)発話の作成から始まります。これはget_composition_dataset
で行われます。これは、ソースデータベースからの各発言を同様に頻繁に使用するSMS-WSJと同様のサンプリングアルゴリズムを実装しています。
この後、サンプリングモジュールを適用して、さまざまなスピーキングパターンまたは環境をシミュレートできます。上記の例では、すべてのオフセットをゼロ(つまり、すべての発話が混合物の先頭から始まる)に設定し、 ConstantOffsetSampler
を使用して、均一なUniformScalingSampler
を使用して最大5dBのランダムスケールをサンプリングします。
他の多くのサンプリングモジュールが利用可能です。これには、会議スタイルのスピーキングパターンをシミュレートするものも含まれます。これの例は、このノートブックにあります。
mms_msg
の混合物は、個々のサンプリングモジュールを次々と例に適用することにより作成されます。各サンプリングモジュールは完全に決定論的です。つまり、その出力はハイパーパラメーターと入力例にのみ依存しますが、可変状態を維持することは許可されていません。これは、再現性を確保するためです。サンプリングは、混合物が生成される順序、モジュールが適用される数または順序に依存しません。
サンプリングモジュールは、(中間)混合物を辞書として受信し、それを変更し、返す呼び出し可能です。ハイパーパラメーターのない関数として実装された基本的なサンプリングモジュールは、次のようになります。
import mms_msg
def my_sampling_module ( example : dict ) -> dict :
# Get a deterministic random number generator based on the input example
# and an additional seed string. The seed string ensures that the RNGs
# differ between different sampling modules
rng = mms_msg . sampling . utils . rng . get_rng_example ( example , 'my_sampler' )
# Sample whatever based on RNG and possibly the contents of example
example [ 'my_random_number' ] = rng . random ()
return example
重要な部分は、 mms_msg.sampling.utils.rng.get_rng_example
関数です。例の辞書(例-IDおよびデータセット)からの基本情報から計算されたシードと追加のシード文字列から計算された種子で初期化されたnp.random.Generator
オブジェクトを返します。つまり、モジュールで生成された乱数は、モジュールが同じ入力例に適用されるたびに等しくなることを意味します。
サンプリングモジュールにハイパーパラメーターがある場合は、不変性を確保するために凍結したデータカラスをお勧めします。
import mms_msg
from dataclasses import dataclass
@ dataclass ( frozen = True )
class MySamplingModule :
size : int = 42
def __call__ ( self , example ):
rng = mms_msg . sampling . utils . rng . get_rng_example ( example , 'my_sampler' )
# Sample whatever based on RNG and possibly the contents of example
example [ 'my_random_number' ] = rng . random ( self . size )
return example
このノートブックには、より実用的な例が記載されています。
MMS-MSGは、次の出版物で提案されました。
@inproceedings { cordlandwehr2022mms_msg ,
title = { MMS-MSG: A Multi-purpose Multi-Speaker Mixture Signal Generator } ,
author = { Tobias Cord-Landwehr and Thilo von Neumann and Christoph Boeddeker and Reinhold Haeb-Umbach } ,
year = { 2022 } ,
booktitle = { International Workshop on Acoustic Signal Enhancement (IWAENC) } ,
publisher = { {IEEE} } ,
} ```