speechbrain.processing.diarization 模块

此脚本包含用于说话人分割的基本功能。 此脚本对开源scikit-learn(sklearn)库有可选的依赖。 根据需求,此脚本中修改了一些scikit-learn函数。

参考

这段代码是使用以下内容编写的:

Authors
  • 纳曼·达瓦拉塔巴德 2020

摘要

类:

Spec_Clust_unorm

该类实现了使用未归一化的亲和矩阵进行谱聚类。

Spec_Cluster

使用sklearn在嵌入上执行谱聚类。

函数:

distribute_overlap

将重叠的语音均匀分配给具有不同说话者的相邻段。

do_AHC

对嵌入执行凝聚层次聚类。

do_kmeans_clustering

对嵌入执行kmeans聚类。

do_spec_clustering

对嵌入进行谱聚类。

get_oracle_num_spkrs

返回录音中实际说话者的数量,基于真实数据。

is_overlapped

如果段重叠,则返回True。

merge_ssegs_same_speaker

合并来自同一说话者的相邻子段。

prepare_subset_csv

为给定的录音ID准备csv文件。

read_rttm

读取并返回列表格式的RTTM。

spectral_clustering_sb

执行谱聚类。

spectral_embedding_sb

返回谱嵌入。

write_ders_file

写入单个录音的最终DERs。

write_rttm

以RTTM格式(一种标准的NIST格式)写入段列表。

参考

speechbrain.processing.diarization.read_rttm(rttm_file_path)[source]

读取并返回列表格式的RTTM。

Parameters:

rttm_file_path (str) – 要读取的RTTM文件的路径。

Returns:

rttm – 包含RTTM文件行的列表。

Return type:

list

speechbrain.processing.diarization.write_ders_file(ref_rttm, DER, out_der_file)[source]

为单个录音写入最终的DERs。

Parameters:
  • ref_rttm (str) – 参考RTTM文件。

  • DER (array) – 包含每个录音的DER值的数组。

  • out_der_file (str) – 用于写入DERs的文件。

speechbrain.processing.diarization.prepare_subset_csv(full_diary_csv, rec_id, out_csv_file)[source]

为给定的录音ID准备csv文件。

Parameters:
  • full_diary_csv (csv) – 包含所有录音的完整csv文件

  • rec_id (str) – 需要为其准备csv的录音ID

  • out_csv_file (str) – 输出csv文件的路径。

speechbrain.processing.diarization.is_overlapped(end1, start2)[source]

如果段重叠,则返回True。

Parameters:
  • end1 (float) – 第一个片段的结束时间。

  • start2 (float) – 第二段的开始时间。

Returns:

overlapped – 如果段重叠则为True,否则为False。

Return type:

bool

Example

>>> from speechbrain.processing import diarization as diar
>>> diar.is_overlapped(5.5, 3.4)
True
>>> diar.is_overlapped(5.5, 6.4)
False
speechbrain.processing.diarization.merge_ssegs_same_speaker(lol)[source]

合并来自同一发言者的相邻子段。

Parameters:

lol (listlist) – 每个列表包含 [rec_id, sseg_start, sseg_end, spkr_id]。

Returns:

new_lol – new_lol 包含从同一说话者ID合并的相邻片段。

Return type:

listlist

Example

>>> from speechbrain.processing import diarization as diar
>>> lol=[['r1', 5.5, 7.0, 's1'],
... ['r1', 6.5, 9.0, 's1'],
... ['r1', 8.0, 11.0, 's1'],
... ['r1', 11.5, 13.0, 's2'],
... ['r1', 14.0, 15.0, 's2'],
... ['r1', 14.5, 15.0, 's1']]
>>> diar.merge_ssegs_same_speaker(lol)
[['r1', 5.5, 11.0, 's1'], ['r1', 11.5, 13.0, 's2'], ['r1', 14.0, 15.0, 's2'], ['r1', 14.5, 15.0, 's1']]
speechbrain.processing.diarization.distribute_overlap(lol)[source]

将重叠的语音均匀地分配给相邻的不同说话者的片段。

Parameters:

lol (list of list) – 每个列表结构为 [rec_id, sseg_start, sseg_end, spkr_id]。

Returns:

new_lol – 它包含在不同说话者ID的相邻段之间平均分配的重复部分。

Return type:

listlist

Example

>>> from speechbrain.processing import diarization as diar
>>> lol = [['r1', 5.5, 9.0, 's1'],
... ['r1', 8.0, 11.0, 's2'],
... ['r1', 11.5, 13.0, 's2'],
... ['r1', 12.0, 15.0, 's1']]
>>> diar.distribute_overlap(lol)
[['r1', 5.5, 8.5, 's1'], ['r1', 8.5, 11.0, 's2'], ['r1', 11.5, 12.5, 's2'], ['r1', 12.5, 15.0, 's1']]
speechbrain.processing.diarization.write_rttm(segs_list, out_rttm_file)[source]

以RTTM格式(一种标准的NIST格式)写入段列表。

Parameters:
  • segs_list (list of list) – 每个列表包含 [rec_id, sseg_start, sseg_end, spkr_id]。

  • out_rttm_file (str) – 输出RTTM文件的路径。

speechbrain.processing.diarization.get_oracle_num_spkrs(rec_id, spkr_info)[source]

返回录音中实际说话者的数量,这是基于真实情况的。 这可以在条件为说话者数量的预言时使用。

Parameters:
  • rec_id (str) – 需要获取说话者数量的录音ID。

  • spkr_info (list) – RTTM文件的头部。以SPKR-INFO开头。

Returns:

num_spkrs

Return type:

int

Example

>>> from speechbrain.processing import diarization as diar
>>> spkr_info = ['SPKR-INFO ES2011a 0 <NA> <NA> <NA> unknown ES2011a.A <NA> <NA>',
... 'SPKR-INFO ES2011a 0 <NA> <NA> <NA> unknown ES2011a.B <NA> <NA>',
... 'SPKR-INFO ES2011a 0 <NA> <NA> <NA> unknown ES2011a.C <NA> <NA>',
... 'SPKR-INFO ES2011a 0 <NA> <NA> <NA> unknown ES2011a.D <NA> <NA>',
... 'SPKR-INFO ES2011b 0 <NA> <NA> <NA> unknown ES2011b.A <NA> <NA>',
... 'SPKR-INFO ES2011b 0 <NA> <NA> <NA> unknown ES2011b.B <NA> <NA>',
... 'SPKR-INFO ES2011b 0 <NA> <NA> <NA> unknown ES2011b.C <NA> <NA>']
>>> diar.get_oracle_num_spkrs('ES2011a', spkr_info)
4
>>> diar.get_oracle_num_spkrs('ES2011b', spkr_info)
3
speechbrain.processing.diarization.spectral_embedding_sb(adjacency, n_components=8, norm_laplacian=True, drop_first=True)[source]

返回光谱嵌入。

Parameters:
  • 邻接 (数组形式稀疏图) – 形状 - (n_samples, n_samples) 要嵌入的图的邻接矩阵。

  • n_components (int) – 投影子空间的维度。

  • norm_laplacian (bool) – 如果为True,则计算归一化拉普拉斯矩阵。

  • drop_first (bool) – 是否删除第一个特征向量。

Returns:

embedding – 每个样本的谱嵌入。

Return type:

数组

Example

>>> import numpy as np
>>> from speechbrain.processing import diarization as diar
>>> affinity = np.array([[1, 1, 1, 0.5, 0, 0, 0, 0, 0, 0.5],
... [1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
... [1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
... [0.5, 0, 0, 1, 1, 1, 0, 0, 0, 0],
... [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
... [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
... [0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
... [0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
... [0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
... [0.5, 0, 0, 0, 0, 0, 1, 1, 1, 1]])
>>> embs = diar.spectral_embedding_sb(affinity, 3)
>>> # Notice similar embeddings
>>> print(np.around(embs , decimals=3))
[[ 0.075  0.244  0.285]
 [ 0.083  0.356 -0.203]
 [ 0.083  0.356 -0.203]
 [ 0.26  -0.149  0.154]
 [ 0.29  -0.218 -0.11 ]
 [ 0.29  -0.218 -0.11 ]
 [-0.198 -0.084 -0.122]
 [-0.198 -0.084 -0.122]
 [-0.198 -0.084 -0.122]
 [-0.167 -0.044  0.316]]
speechbrain.processing.diarization.spectral_clustering_sb(affinity, n_clusters=8, n_components=None, random_state=None, n_init=10)[source]

执行谱聚类。

Parameters:
  • affinity (matrix) – 亲和矩阵。

  • n_clusters (int) – kmeans的聚类数量。

  • n_components (int) – 在估计谱嵌入时保留的组件数量。

  • random_state (int) – 由kmeans使用的伪随机数生成器。

  • n_init (int) – k-means算法将使用不同的质心种子运行的次数。

Returns:

labels – 每个样本的聚类标签。

Return type:

数组

Example

>>> import numpy as np
>>> from speechbrain.processing import diarization as diar
>>> affinity = np.array([[1, 1, 1, 0.5, 0, 0, 0, 0, 0, 0.5],
... [1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
... [1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
... [0.5, 0, 0, 1, 1, 1, 0, 0, 0, 0],
... [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
... [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
... [0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
... [0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
... [0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
... [0.5, 0, 0, 0, 0, 0, 1, 1, 1, 1]])
>>> labs = diar.spectral_clustering_sb(affinity, 3)
>>> # print (labs) # [2 2 2 1 1 1 0 0 0 0]
class speechbrain.processing.diarization.Spec_Cluster(n_clusters=8, *, eigen_solver=None, n_components=None, random_state=None, n_init=10, gamma=1.0, affinity='rbf', n_neighbors=10, eigen_tol='auto', assign_labels='kmeans', degree=3, coef0=1, kernel_params=None, n_jobs=None, verbose=False)[source]

基础:SpectralClustering

使用sklearn在嵌入上执行谱聚类。

perform_sc(X, n_neighbors=10)[source]

使用sklearn在嵌入上执行谱聚类。

Parameters:
  • X (array (n_samples, n_features)) – 需要聚类的嵌入。

  • n_neighbors (int) – 在估计亲和矩阵时的邻居数量。

Returns:

  • Spec_Cluster

  • 参考

  • ———

  • https (//github.com/scikit-learn/scikit-learn/blob/0fb307bf3/sklearn/cluster/_spectral.py)

class speechbrain.processing.diarization.Spec_Clust_unorm(min_num_spkrs=2, max_num_spkrs=10)[source]

基础类:object

该类实现了使用未归一化的亲和矩阵进行谱聚类。 当亲和矩阵基于余弦相似度时非常有用。

Parameters:
  • min_num_spkrs (int) – 预期说话者的最小数量。

  • max_num_spkrs (int) – 预期的最大说话者数量。

  • 参考

  • ---------

  • Luxburg ()

  • 17 (U. 关于谱聚类的教程。统计计算)

  • (2007). (395–416)

  • https (//doi.org/10.1007/s11222-007-9033-z)

Example

>>> from speechbrain.processing import diarization as diar
>>> clust = diar.Spec_Clust_unorm(min_num_spkrs=2, max_num_spkrs=10)
>>> emb = [[ 2.1, 3.1, 4.1, 4.2, 3.1],
... [ 2.2, 3.1, 4.2, 4.2, 3.2],
... [ 2.0, 3.0, 4.0, 4.1, 3.0],
... [ 8.0, 7.0, 7.0, 8.1, 9.0],
... [ 8.1, 7.1, 7.2, 8.1, 9.2],
... [ 8.3, 7.4, 7.0, 8.4, 9.0],
... [ 0.3, 0.4, 0.4, 0.5, 0.8],
... [ 0.4, 0.3, 0.6, 0.7, 0.8],
... [ 0.2, 0.3, 0.2, 0.3, 0.7],
... [ 0.3, 0.4, 0.4, 0.4, 0.7],]
>>> # Estimating similarity matrix
>>> sim_mat = clust.get_sim_mat(emb)
>>> print (np.around(sim_mat[5:,5:], decimals=3))
[[1.    0.957 0.961 0.904 0.966]
 [0.957 1.    0.977 0.982 0.997]
 [0.961 0.977 1.    0.928 0.972]
 [0.904 0.982 0.928 1.    0.976]
 [0.966 0.997 0.972 0.976 1.   ]]
>>> # Pruning
>>> pruned_sim_mat = clust.p_pruning(sim_mat, 0.3)
>>> print (np.around(pruned_sim_mat[5:,5:], decimals=3))
[[1.    0.    0.    0.    0.   ]
 [0.    1.    0.    0.982 0.997]
 [0.    0.977 1.    0.    0.972]
 [0.    0.982 0.    1.    0.976]
 [0.    0.997 0.    0.976 1.   ]]
>>> # Symmetrization
>>> sym_pruned_sim_mat = 0.5 * (pruned_sim_mat + pruned_sim_mat.T)
>>> print (np.around(sym_pruned_sim_mat[5:,5:], decimals=3))
[[1.    0.    0.    0.    0.   ]
 [0.    1.    0.489 0.982 0.997]
 [0.    0.489 1.    0.    0.486]
 [0.    0.982 0.    1.    0.976]
 [0.    0.997 0.486 0.976 1.   ]]
>>> # Laplacian
>>> laplacian = clust.get_laplacian(sym_pruned_sim_mat)
>>> print (np.around(laplacian[5:,5:], decimals=3))
[[ 1.999  0.     0.     0.     0.   ]
 [ 0.     2.468 -0.489 -0.982 -0.997]
 [ 0.    -0.489  0.975  0.    -0.486]
 [ 0.    -0.982  0.     1.958 -0.976]
 [ 0.    -0.997 -0.486 -0.976  2.458]]
>>> # Spectral Embeddings
>>> spec_emb, num_of_spk = clust.get_spec_embs(laplacian, 3)
>>> print(num_of_spk)
3
>>> # Clustering
>>> clust.cluster_embs(spec_emb, num_of_spk)
>>> # print (clust.labels_) # [0 0 0 2 2 2 1 1 1 1]
>>> # Complete spectral clustering
>>> clust.do_spec_clust(emb, k_oracle=3, p_val=0.3)
>>> # print(clust.labels_) # [0 0 0 2 2 2 1 1 1 1]
do_spec_clust(X, k_oracle, p_val)[source]

用于谱聚类的函数。

Parameters:
  • X (数组) – (n_samples, n_features). 从模型中提取的嵌入。

  • k_oracle (int) – 说话者数量(当为说话者数量的预言时)。

  • p_val (float) – 用于修剪亲和矩阵的p百分比值。

get_sim_mat(X)[source]

返回基于余弦相似度的相似度矩阵。

Parameters:

X (数组) – (n_samples, n_features). 从模型中提取的嵌入。

Returns:

M – (n_samples, n_samples). 相似度矩阵,包含每对嵌入之间的余弦相似度。

Return type:

数组

p_pruning(A, pval)[source]

通过将不太相似的值设为零来优化亲和矩阵。

Parameters:
  • A (数组) – (n_samples, n_samples). 亲和矩阵。

  • pval (float) – 在亲和矩阵的每一行中保留的p值。

Returns:

A – (n_samples, n_samples). 基于p_val修剪的亲和矩阵。

Return type:

数组

get_laplacian(M)[source]

返回给定亲和矩阵的非归一化拉普拉斯矩阵。

Parameters:

M (数组) – (n_samples, n_samples) 亲和矩阵。

Returns:

L – (n_samples, n_samples) 拉普拉斯矩阵。

Return type:

数组

get_spec_embs(L, k_oracle=4)[source]

返回频谱嵌入并使用最大特征间隙估计说话者数量。

Parameters:
  • L (数组 (n_samples, n_samples)) – 拉普拉斯矩阵。

  • k_oracle (int) – 当条件为说话者数量的oracle时,表示说话者的数量,否则为None。

Returns:

  • emb (array (n_samples, n_components)) – 每个样本的谱嵌入,具有n个特征分量。

  • num_of_spk (int) – 估计的说话者数量。如果条件设置为oracle说话者数量,则返回k_oracle。

cluster_embs(emb, k)[source]

使用kmeans对嵌入进行聚类。

Parameters:
  • emb (array (n_samples, n_components)) – 每个样本的谱嵌入,具有n个特征分量。

  • k (int) – kmeans的聚类数量。

getEigenGaps(eig_vals)[source]

返回特征值之间的差异(间隙)。

Parameters:

eig_vals (list) – 特征值列表

Returns:

eig_vals_gap_list – 相邻特征值之间的差异(间隔)列表。

Return type:

list

speechbrain.processing.diarization.do_spec_clustering(diary_obj, out_rttm_file, rec_id, k, pval, affinity_type, n_neighbors)[source]

对嵌入执行谱聚类。此函数根据亲和力调用特定的聚类算法。

Parameters:
  • diary_obj (StatObject_SB 类型) – 包含在 diary_obj.stat1 中的嵌入和在 diary_obj.segset 中的段 ID。

  • out_rttm_file (str) – 输出RTTM文件的路径。

  • rec_id (str) – 正在处理的录音的录音ID。

  • k (int) – 说话者数量(如果必须估计,则为None)。

  • pval (float) – pval 用于修剪亲和矩阵。

  • affinity_type (str) – 用于获取亲和矩阵的相似性类型(cos 或 nn)。

  • n_neighbors (int) – 用于聚类的邻居数量

speechbrain.processing.diarization.do_kmeans_clustering(diary_obj, out_rttm_file, rec_id, k_oracle=4, p_val=0.3)[source]

对嵌入执行kmeans聚类。

Parameters:
  • diary_obj (StatObject_SB 类型) – 包含在 diary_obj.stat1 中的嵌入和在 diary_obj.segset 中的段 ID。

  • out_rttm_file (str) – 输出RTTM文件的路径。

  • rec_id (str) – 正在处理的录音的录音ID。

  • k_oracle (int) – 说话者数量(如果必须估计,则为None)。

  • p_val (float) – pval 用于修剪亲和矩阵。仅在说话者数量未知时使用。请注意,这仅用于实验。为了获得更好的聚类结果,建议使用谱聚类。

speechbrain.processing.diarization.do_AHC(diary_obj, out_rttm_file, rec_id, k_oracle=4, p_val=0.3)[source]

对嵌入执行凝聚层次聚类。

Parameters:
  • diary_obj (StatObject_SB 类型) – 包含在 diary_obj.stat1 中的嵌入和在 diary_obj.segset 中的段 ID。

  • out_rttm_file (str) – 输出RTTM文件的路径。

  • rec_id (str) – 正在处理的录音的录音ID。

  • k_oracle (int) – 说话者数量(如果必须估计,则为None)。

  • p_val (float) – pval 用于修剪亲和矩阵。仅在说话者数量未知时使用。请注意,这仅用于实验。为了获得更好的聚类结果,建议使用谱聚类。