o
    )j                     @   s   d dl mZmZmZ d dlZd dlZd dlZd dlZd dl	Z	d dl
mZ d dlmZ d dlmZmZ d dlmZ G dd dZG d	d
 d
ZejejejdG dd deZdS )    )AnyDictUnionNk_means)Models)MODELS
TorchModel)Tasksc                   @   sV   e Zd ZdZdddZddd	Zd
d Zdd Zdd ZdddZ	dd Z
dd ZdS )SpectralClusterzA spectral clustering method using unnormalized Laplacian of affinity matrix.
    This implementation is adapted from https://github.com/speechbrain/speechbrain.
          I+?c                 C   s   || _ || _|| _d S N)min_num_spksmax_num_spkspval)selfr   r   r    r   k/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/models/audio/sv/cluster_backend.py__init__   s   
zSpectralCluster.__init__Nc           
      C   sL   |  |}| |}d||j  }| |}| ||\}}| ||}	|	S )Ng      ?)get_sim_mat	p_pruningTget_laplacianget_spec_embscluster_embs)
r   X
oracle_numZsim_matZprunned_sim_matZsym_prund_sim_matZ	laplacianemb
num_of_spklabelsr   r   r   __call__   s   


zSpectralCluster.__call__c                 C   s   t jj||}|S r   )sklearnZmetricspairwiseZcosine_similarity)r   r   Mr   r   r   r   0   s   zSpectralCluster.get_sim_matc                 C   s   |j d | j dk rd|j d  }n| j}td| |j d  }t|j d D ]}t||d d f }|d| }d|||f< q'|S )Nr      g      @r   )shaper   intrangenpZargsort)r   Ar   Zn_elemsiZlow_indexesr   r   r   r   5   s   zSpectralCluster.p_pruningc                 C   s>   d|t |jd < t jt |dd}t |}|| }|S )Nr   r   axis)r*   Zdiag_indicesr'   sumabsZdiag)r   r%   DLr   r   r   r   F   s
   
zSpectralCluster.get_laplacianc                 C   sh   t j|\}}|d ur|}n| || jd | jd  }t|| j }|d d d |f }||fS Nr   )scipylinalgZeighgetEigenGapsr   r   r*   argmax)r   r2   Zk_oracleZlambdasZeig_vecsr    Zlambda_gap_listr   r   r   r   r   M   s   zSpectralCluster.get_spec_embsc                 C   s   t ||\}}}|S r   r   )r   r   k_r!   r   r   r   r   Z   s   zSpectralCluster.cluster_embsc                 C   sD   g }t t|d D ]}t||d  t||  }|| q
|S r3   )r)   lenfloatappend)r   Zeig_valsZeig_vals_gap_listr,   gapr   r   r   r6   ^   s
   zSpectralCluster.getEigenGaps)r   r   r   r   )__name__
__module____qualname____doc__r   r"   r   r   r   r   r   r6   r   r   r   r   r      s    


r   c                   @   s,   e Zd ZdZ					dddZdd	 Zd
S )UmapHdbscanz
    Reference:
    - Siqi Zheng, Hongbin Suo. Reformulating Speaker Diarization as Community Detection With
      Emphasis On Topological Structure. ICASSP2022
       <   
   cosinec                 C   s"   || _ || _|| _|| _|| _d S r   )n_neighborsn_componentsmin_samplesmin_cluster_sizemetric)r   rG   rH   rI   rJ   rK   r   r   r   r   m   s
   
zUmapHdbscan.__init__c                 C   sL   t j| jdt| j|jd d | jd|}tj	| j
| jdd|}|S )Ng        r      )rG   Zmin_distrH   rK   T)rI   rJ   Zallow_single_cluster)umapZUMAPrG   minrH   r'   rK   Zfit_transformhdbscanZHDBSCANrI   rJ   Zfit_predict)r   r   Zumap_Xr!   r   r   r   r"   y   s    zUmapHdbscan.__call__N)rC   rD   rE   rE   rF   )r>   r?   r@   rA   r   r"   r   r   r   r   rB   f   s    
rB   )module_namec                       s>   e Zd ZdZdeeef f fddZdd Zdd Z	  Z
S )	ClusterBackendzPerform clustering for input embeddings and output the labels.
    Args:
        model_dir: A model dir.
        model_config: The model config.
    model_configc                    s<   t  j||g|R i | || _|| _t | _t | _d S r   )superr   rR   Zother_configr   spectral_clusterrB   umap_hdbscan_cluster)r   Z	model_dirrR   argskwargs	__class__r   r   r      s
   zClusterBackend.__init__c                 K   s   d|v r|d nd }t |jdksJ d|jd dk r&tj|jd ddS |jd dk s1|d ur8| ||}n| |}|d u rPd	| jv rP| ||| jd	 }|S )
Nr   rL   z5modelscope error: the shape of input should be [N, C]r   rC   r(   )Zdtypei   Z	merge_thr)r:   r'   r*   ZzerosrT   rU   rR   merge_by_cos)r   r   paramsr8   r!   r   r   r   forward   s$   
zClusterBackend.forwardc                 C   s$  |dkr|dks
J 	 |  d }|dkr	 |S g }t|D ]}|||k d}|| qt|dks7J tj|dd}|tjj|ddd }t	||j
}	t|	d}	tt|	|	j}
|	|
 |k ri	 |S tt|D ]!}|| |
d kr|
d ||< qo|| |
d kr||  d8  < qoq)Nr   r   Tr-   )r.   Zkeepdims)maxr)   meanr<   r:   r*   stackr5   Znormmatmulr   ZtriuZunravel_indexr7   r'   )r   r!   ZembsZcos_thrZspk_numZ
spk_centerr,   Zspk_embZnorm_spk_centerZaffinityZspksr   r   r   rZ      s8   zClusterBackend.merge_by_cos)r>   r?   r@   rA   r   strr   r   r\   rZ   __classcell__r   r   rX   r   rQ      s
    	rQ   )typingr   r   r   rO   numpyr*   r4   r#   rM   Zsklearn.cluster._kmeansr   Zmodelscope.metainfor   Zmodelscope.modelsr   r	   Zmodelscope.utils.constantr
   r   rB   Zregister_moduleZspeaker_diarizationZcluster_backendrQ   r   r   r   r   <module>   s    U!