o
    %ݫi                     @   s,   d Z ddlZddlZG dd dejjZdS )z:K-means implementation.

Authors
* Luca Della Libera 2024
    Nc                       sv   e Zd ZdZ fddZd fdd	Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zedd Zedd Z  ZS )MiniBatchKMeansSklearna  A wrapper for scikit-learn MiniBatchKMeans, providing integration with PyTorch tensors.

    See https://scikit-learn.org/stable/modules/generated/sklearn.cluster.MiniBatchKMeans.html.

    Arguments
    ---------
    *args : tuple
        Positional arguments passed to scikit-learn `MiniBatchKMeans`.
    **kwargs : dict
        Keyword arguments passed to scikit-learn `MiniBatchKMeans`.

    Example
    -------
    >>> import torch
    >>> device = "cpu"
    >>> n_clusters = 20
    >>> batch_size = 8
    >>> seq_length = 100
    >>> hidden_size = 256
    >>> model = MiniBatchKMeansSklearn(n_clusters).to(device)
    >>> input = torch.randn(batch_size, seq_length, hidden_size, device=device)
    >>> model.partial_fit(input)
    >>> labels = model(input)
    >>> labels.shape
    torch.Size([8, 100])
    >>> centers = model.cluster_centers
    >>> centers.shape
    torch.Size([20, 256])
    >>> len(list(model.buffers()))
    1
    >>> model.n_steps
    1
    >>> inertia = model.inertia(input)
    c                    sp   zddl m} W n ty   d}|d7 }t|w t   ||i || _td| _| jd| j	dd d S )	Nr   )MiniBatchKMeanszMThe optional dependency `scikit-learn` must be installed to use this module.
z*Install using `pip install scikit-learn`.
cpucluster_centersF)
persistent)
sklearn.clusterr   ImportErrorsuper__init__kmeanstorchdeviceregister_buffercluster_centers_)selfargskwargsr   err_msg	__class__ S/home/ubuntu/.local/lib/python3.10/site-packages/speechbrain/lobes/models/kmeans.pyr
   /   s   

zMiniBatchKMeansSklearn.__init__Nc                    s   || _ t |S )z*See documentation of `torch.nn.Module.to`.)r   r	   to)r   r   r   r   r   r   r   >   s   zMiniBatchKMeansSklearn.toc                 C   s   t | j| dS )zSaves the model to the specified file.

        Arguments
        ---------
        path : str
            The file path to save the model.
        N)joblibdumpr   )r   pathr   r   r   saveC   s   zMiniBatchKMeansSklearn.savec                 C   s   t || _| j| _dS )a  Loads the model from the specified file.

        Arguments
        ---------
        path : str
            The file path from which to load the model.
        end_of_epoch : bool
            Indicates if this load is triggered at the end of an epoch.
        N)r   loadr   r   r   )r   r   end_of_epochr   r   r   r   M   s   
zMiniBatchKMeansSklearn.loadc                 C   0   |  jdd  }| j| | j| _dS )zFits the model to the input data.

        Arguments
        ---------
        input : torch.Tensor
            The input data tensor of shape (..., n_features).
        end_dimN)detachflattenr   numpyr   fitr   r   r   inputnumpy_inputr   r   r   r&   Z      zMiniBatchKMeansSklearn.fitc                 C   r   )zPerforms an incremental fit of the model on the input data.

        Arguments
        ---------
        input : torch.Tensor
            The input data tensor of shape (..., n_features).
        r    r!   N)r#   r$   r   r%   r   partial_fitr   r   r'   r   r   r   r+   f   r*   z"MiniBatchKMeansSklearn.partial_fitc                 C   sP   |  jdd  }| j|}tj|| jd	 }|
|jdd }|S )a"  Predicts cluster indices for the input data.

        Arguments
        ---------
        input : torch.Tensor
            The input data tensor of shape (..., n_features).

        Returns
        -------
        torch.Tensor
            Predicted cluster indices of shape (...,).
        r    r!   r   N)r#   r$   r   r%   r   predictr   tensorr   longreshapeshape)r   r(   r)   cluster_idxesr   r   r   forwardr   s
   zMiniBatchKMeansSklearn.forwardc                 C   s>   |  jdd  }| j|}tj|| jd	  }|S )a,  Returns the inertia of the clustering.

        Arguments
        ---------
        input : torch.Tensor
            The input data tensor of shape (..., n_features).

        Returns
        -------
        torch.Tensor
            Inertia (sum of squared distances to the cluster centers).
        r    r!   r,   )
r#   r$   r   r%   r   scorer   r/   r   float)r   r(   r)   r5   inertiar   r   r   r7      s   zMiniBatchKMeansSklearn.inertiac                 C   s   | j jS )zReturns the number of minibatches processed.

        Returns
        -------
        int
            Number of minibatches processed.
        )r   n_steps_)r   r   r   r   n_steps   s   	zMiniBatchKMeansSklearn.n_stepsc                 C   s@   t | jdr| jj}tj|| jd }|S tjd| jd}|S )zReturns the cluster centers.

        Returns
        -------
        torch.Tensor
            Cluster centers of shape (n_clusters, n_features).
        r   r,   g        )hasattrr   r   r   r/   r   r6   )r   r   r   r   r   r      s   	z'MiniBatchKMeansSklearn.cluster_centers_)N)__name__
__module____qualname____doc__r
   r   r   r   r&   r+   r4   r7   propertyr9   r   __classcell__r   r   r   r   r      s    #


r   )r>   r   r   nnModuler   r   r   r   r   <module>   s    