关于音频场景识别的一个基于python的程序合集dcase_util,是英文的,所以在此将其翻译成了中文,以便查阅。
dcase_util 文档描述了为声场景和事件检测和分类(DCASE)创建的实用程序集合。这些实用程序最初是为DCASE挑战基线系统(2016和2017)创建的,并捆绑到独立库中以允许其在其他研究项目中重复使用。
这些实用程序的主要目标是简化研究代码,使其更易读,更易于维护。大多数实施的实用程序都与音频数据集相关:处理元数据和各种形式的其他结构化数据,并为各种来源的音频数据集提供标准化的使用API。
dcase_util中包含的概念有:
Dataset:一组音频信号和与之相关的参考标注。
Container:类存储数据并基于要存储的数据类型,提供有意义且清晰的数据访问。
Metadata:数据注释。
Repository:容器来存储多个数据容器。
Encoder:用于将数据从不同类型转换为另一类型。
Processor:为处理数据提供统一API的类。
ProcessingChain:在一个链中连接多个数据处理器,允许构建数据的复杂处理。
在搭建好了python环境之后,使用下列pip命令安装dcase_util。
下面是各个单元的使用教程
1.Container
该库提供数据container以简化工作流程。 这些container是从标准的Python container(例如对象,列表和字典)继承的,以使它们可以与其他工具和库一起使用。 这些数据的目的是为了包装数据,使用有用的方法来访问和操作数据,以及加载和存储数据。
1.1基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13
# 1 dict_container = dcase_util.containers.DictContainer(filename='test.yaml') dict_container.load() # 2 dict_container = dcase_util.containers.DictContainer() dict_container.load(filename='test.yaml') # 3 dict_container = dcase_util.containers.DictContainer(filename='test.yaml').load() # 4 dict_container = dcase_util.containers.DictContainer().load(filename='test.yaml')
1
dict_container.save(filename='test.yaml')
如果日志记录系统在调用之前未被初始化,那么将使用带默认参数的dcase_util.utils.setup_logging来初始化它。
1.2 字典
dcase_util.containers.DictContainer
设计用于嵌套字典比标准字典数据container更容易一些。它允许通过所谓的虚线路径或路径部分列表访问嵌套字典中的字段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
dict_container = dcase_util.containers.DictContainer( {
'test': {
'field1': 1, 'field2': 2, }, 'test2': 100, 'test3': {
'field1': {
'fieldA': 1 }, 'field2': {
'fieldA': 1 }, 'field3': {
'fieldA': 1 }, } } )
1
dict_container = dcase_util.containers.DictContainer().load(filename='test.yaml')
1 2 3 4 5 6 7 8
# Field exists value = dict_container.get_path('test.field1') # Using wild card values = dict_container.get_path('test3.*') # Non existing field with default value value = dict_container.get_path('test.fieldA', 'default_value')
1 2 3 4 5
# Field exists value = dict_container.get_path(['test', 'field1']) # Non existing field with default value value = dict_container.get_path(['test', 'fieldA'], 'default_value)
1
dict_container.set_path('test.field2', 200)
1
dict_container.get_leaf_path_list()
获取嵌套字典中以’field’开头的所有叶节点的虚线路径
1
dict_container.get_leaf_path_list(target_field_startswith='field')
1
dict_container.save(filename='test.yaml')
1
dict_container.load(filename='test.yaml')
1.3 字典列表
dcase_util.containers.ListDictContainer
是用于存储dcase_util.containers.DictContainer
的列表。
1 2 3 4 5 6 7 8
listdict_container = dcase_util.containers.ListDictContainer( [ {'field1': 1, 'field2': 2}, {'field1': 10, 'field2': 20}, {'field1': 100, 'field2': 200}, ] )
1 2 3 4
print(listdict_container.search(key='field1', value=10)) # DictContainer # field1 : 10 # field2 : 20
1 2
print(ld.get_field(field_name='field2')) # [2, 20, 200]
1.4 Data Containers
其中三种是可用的几种数据容器类型:
dcase_util.containers.DataArrayContainer
,数组数据的数据容器,内部数据存储在numpy.array中。(可用)
dcase_util.containers.DataMatrix2DContainer
,二维数据矩阵的数据容器,内部数据存储在二维numpy.ndarray中。(可用)
case_util.containers.DataMatrix3DContainer`,用于三维数据矩阵的数据容器,内部数据存储在3-D numpy.ndarray中。(可用)
dcase_util.containers.BinaryMatrixContainer
,用于二维二进制数据矩阵的数据容器,内部数据存储在二维numpy.ndarray中。(不可用)
用随机矩阵10x100初始化container,并将时间分辨率设置为20ms:
1 2 3 4
data_container = dcase_util.containers.DataMatrix2DContainer( data=numpy.random.rand(10,100), time_resolution=0.02 )
当存储例如声学特征时,时间分辨率对应于特征提取帧跳长。
1 2
print(data_container.data.shape) # (10, 100)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
data_container.show() # DataMatrix2DContainer :: Class # Data # data : matrix (10,100) # Dimensions # time_axis : 1 # data_axis : 0 # Timing information # time_resolution : 0.02 sec # Meta # stats : Calculated # metadata : - # processing_chain : - # Duration # Frames : 100 # Seconds : 2.00 sec
该容器具有聚焦机制,可灵活捕捉数据矩阵的一部分。 可以根据时间进行对焦(如果时间分辨率已定义,则以秒为单位),或基于帧ID。
1 2
print(data_container.set_focus(start_seconds=0.5, stop_seconds=1.0).get_focused().shape) # (10, 25)
1 2
print(data_container.set_focus(start=10, stop=50).get_focused().shape) # (10, 40)
1 2 3
data_container.reset_focus() print(data_container.get_focused().shape) # (10, 100)
1
data_container.get_frames(frame_ids=[1,2,10,30])
1
data_container.get_frames(frame_ids=[1,2,3,4,5], vector_ids=[0])
1 2 3
transposed_data = data_container.T print(transposed_data.shape) # (100, 10)
dcase_util.containers.BinaryMatrixContainer
提供与DataMatrix2DContainer
相同的用途,但是用于二进制内容。
1.5 存储库(Repositories)
dcase_util.containers.DataRepository
和dcase_util.containers.FeatureRepository
是可用于存储多个其他数据容器的容器。 存储库存储具有两个级别信息的数据:标签和流。 标签是更高级别的密钥,流是第二级。
例如,可以使用储存库来储存与相同音频信号有关的多个不同声学特征。 流ID可用于存储从不同音频通道提取的特征。 后面的功能可以使用提取器标签和流ID进行访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
data_repository = dcase_util.containers.DataRepository( data={
'label1': {
'stream0': {
'data': 100 }, 'stream1': {
'data': 200 } }, 'label2': {
'stream0': {
'data': 300 }, 'stream1': {
'data': 400 } } } )
1 2 3 4 5 6 7 8 9 10 11
data_repository. show() # DataRepository :: Class # Repository info # Item class : DataMatrix2DContainer # Item count : 2 # Labels : ['label1', 'label2'] # Content # [label1][stream1] : {'data': 200} # [label1][stream0] : {'data': 100} # [label2][stream1] : {'data': 400} # [label2][stream0] : {'data': 300}
1 2
data_repository.get_container(label='label1',stream_id='stream1') # {'data': 200}
1 2 3 4 5 6 7 8 9 10 11 12 13
data_repository.set_container(label='label3',stream_id='stream0', container={'data':500}) data_repository. show() # DataRepository :: Class # Repository info # Item class : DataMatrix2DContainer # Item count : 3 # Labels : ['label1', 'label2', 'label3'] # Content # [label1][stream1] : {'data': 200} # [label1][stream0] : {'data': 100} # [label2][stream1] : {'data': 400} # [label2][stream0] : {'data': 300} # [label3][stream0] : {'data': 500}
2. 音频
dcase_util.containers.AudioContainer
是多声道音频的数据容器。它读取多种格式(WAV,FLAC,M4A,WEBM)并写入WAV和FLAC文件。 直接从Youtube下载音频内容也受支持。
2.1 创建container
1 2 3 4 5
audio_container = dcase_util.containers.AudioContainer(fs=44100) t = numpy.linspace(0, 2, 2 * audio_container.fs, endpoint=False) x1 = numpy.sin(220 * 2 * numpy.pi * t) x2 = numpy.sin(440 * 2 * numpy.pi * t) audio_container.data = numpy.vstack([x1, x2])
1 2 3 4 5 6 7
# AudioContainer :: Class # Sampling rate : 44100 # Channels : 2 # Duration # Seconds : 2.00 sec # Milliseconds : 2000.00 ms # Samples : 88200 samples
2.2 加载和保存
加载
1 2 3
audio_container = dcase_util.containers.AudioContainer().load( filename=dcase_util.utils.Example.audio_filename() )
显示的container信息
1 2 3 4 5 6 7 8 9
# AudioContainer :: Class # Filename : acoustic_scene.flac # Synced : Yes # Sampling rate : 44100 # Channels : 2 # Duration # Seconds : 10.00 sec # Milliseconds : 10000.02 ms # Samples : 441001 samples
1 2 3 4 5
audio_container = dcase_util.containers.AudioContainer().load_from_youtube( query_id='2ceUOv8A3FE', start=1, stop=5 )
2.3 焦点段(Focus segment)
container具有聚焦机制,可灵活捕捉部分音频数据,同时保持完整的音频信号不变。 可以根据时间进行聚焦(如果时间分辨率已定义,则以秒为单位),或基于样本ID。 可以对单声道或混音(单声道)频道进行聚焦。 音频容器内容可以通过冻结来替代焦点细分。
1 2
print(audio_container.set_focus(start_seconds=0.5, stop_seconds=1.0).get_focused().shape) # (2, 22050)
1 2
print(audio_container.set_focus(start_seconds=5, duration_seconds=2.0).get_focused().shape) # (2, 88200)
使用焦点从5秒开始持续2秒获取部分数据,混合两个立体声声道:
1 2
print(audio_container.set_focus(start_seconds=5, duration_seconds=2.0, channel='mixdown').get_focused().shape) # (88200,)
使用焦点从5秒开始2秒开始数取部分数据,在两个立体声通道左侧:
1 2
print(audio_container.set_focus(start_seconds=5, duration_seconds=2.0, channel='left').get_focused().shape) # (88200,)
使用焦点从5秒开始2秒开始数取部分数据,秒音频通道(索引从0开始):
1 2
print(audio_container.set_focus(start_seconds=5, duration_seconds=2.0, channel=1).get_focused().shape) # (88200,)
使用焦点获取样本44100和88200之间的零件数据:
1 2
print(audio_container.set_focus(start=44100, stop=88200).get_focused().shape) # (2, 44100)
1 2 3
audio_container.reset_focus() print(audio_container.get_focused().shape) # (2, 441001)
使用焦点从5秒开始2秒开始数取部分数据,,并冻结该部分
1 2 3
audio_container.set_focus(start_seconds=5, duration_seconds=2.0).freeze() print(audio_container.shape) # (2, 88200)
2.4 处理
1
audio_container.normalize()
1
audio_container.resample(target_fs=16000)
2.5 可视化
1
audio_container.plot_wave()
1
audio_container.plot_spec()
3. 声学特征
库提供基本的声学特征提取器:dcase_util.features.MelExtractor
,dcase_util.features.MfccStaticExtractor
,dcase_util.features.MfccDeltaExtractor
,dcase_util.features.MfccAccelerationExtractor
,dcase_util.features.ZeroCrossingRateExtractor
,dcase_util.features.RMSEnergyExtractor
和dcase_util.features.SpectralCentroidExtractor
。
3.1 特征提取
1 2 3 4 5 6 7 8 9 10
# Get audio in a container, mixdown of a stereo signal audio_container = dcase_util.containers.AudioContainer().load( filename=dcase_util.utils.Example.audio_filename() ).mixdown() # Create extractor mel_extractor = dcase_util.features.MelExtractor() # Extract features mels = mel_extractor.extract(audio_container)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# Get audio in a container, mixdown of a stereo signal audio_container = dcase_util.containers.AudioContainer().load( filename=dcase_util.utils.Example.audio_filename() ).mixdown() # Set focus audio_container.set_focus(start_seconds=1.0, stop_seconds=4.0) # Create extractor mel_extractor = dcase_util.features.MelExtractor() # Extract features mels = mel_extractor.extract(audio_container.get_focused()) # Plot dcase_util.containers.DataMatrix2DContainer( data=mels, time_resolution=mel_extractor.hop_length_seconds ).plot()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# Create an audio signal t = numpy.linspace(0, 2, 2 * 44100, endpoint=False) x1 = numpy.sin(220 * 2 * numpy.pi * t) # Create extractor mel_extractor = dcase_util.features.MelExtractor() # Extract features mels = mel_extractor.extract(x1) # Plot dcase_util.containers.DataMatrix2DContainer( data=mels, time_resolution=mel_extractor.hop_length_seconds ).plot()
库中提供的所有音频提取器适用于单声道音频。
3.2 可视化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# Get audio in a container, mixdown of a stereo signal audio_container = dcase_util.containers.AudioContainer().load( filename=dcase_util.utils.Example.audio_filename() ).mixdown() # Create extractor mel_extractor = dcase_util.features.MelExtractor() # Extract features mels = mel_extractor.extract(audio_container) # Plotting dcase_util.containers.DataMatrix2DContainer( data=mels, time_resolution=mel_extractor.hop_length_seconds ).plot()
4. 数据处理
4.1 数据操作
有几个不同的实用程序来操作数据:
dcase_util.data.Normalizer
,计算归一化因子和归一化数据。
dcase_util.data.RepositoryNormalizer
,一次性标准化数据存储库。
dcase_util.data.Aggregator
,聚合滑动处理窗口中的数据。
dcase_util.data.Sequence
r,对数据矩阵进行排序。
dcase_util.data.Stacker
,基于给定的矢量配方堆叠数据矩阵。
dcase_util.data.Selector
,根据具有开始和偏移量的事件选择数据的数据段。
dcase_util.data.Masker
,基于具有开始和偏移的事件来掩盖数据的数据段。
4.1.1 归一化
dcase_util.data.Normalizer
类可用于计算数据的归一化因子(平均值和标准偏差),而不一次读取所有数据。在小部分读取数据时累计中间统计数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
data = dcase_util.utils.Example.feature_container() # Initialize normalizer normalizer = dcase_util.data.Normalizer() # Accumulate -- feed data per file in normalizer.accumulate(data=data) # After accumulation calculate normalization factors (mean + std) normalizer.finalize() # Save normalizer.save(filename='norm_factors.cpickle') # Load normalizer = dcase_util.data.Normalizer().load(filename='norm_factors.cpickle')
1 2 3 4 5 6 7 8
data = dcase_util.utils.Example.feature_container() # Accumulate with dcase_util.data.Normalizer() as normalizer: normalizer.accumulate(data=data) # Save normalizer.save(filename='norm_factors.cpickle')
用预先计算的值初始化标准化器(normalizer):