o
    pi+&                     @   sl   d dl Zd dlmZ d dlmZ d dlmZ d dlm	Z	 ddl
mZ g Ze								 		dd
dZdS )    N)static_only)LayerHelper)	ParamAttr)Assign   )check_variable_and_dtypeuniformFc           #         s  t d'i t  t| dddgd t|ddgd | jdkr'td| j d	| jd
 }|jd
 } j j||gd| jd}i } j	rT j j	|d
gd| jd}||d<  j
| jd} j
| jd} j
|jd}| |d< ||d< ||d< |dur{|ng |d< |dkrd}n|dkrd
}n|dkr|	dusJ |}dg| }dg| }g }g }t|D ],}|	| | }|d dkr|||f qd| dkr|||f q|||< d||< qt|r>t|r>|d}|d}|d }|d
 }|d
 ||d < |||d < |d
 |d
  d
 }|d dkr|||f nd| dkr-|||f n|||< d||< t|r>t|st|rT|d}d||d < d||d < t|rj|d}d||d < d||d <  fdd} | t|	d|d< | t|d|d< | t|d|d < d}ntd!|du rd"}nt|}|}!td# t|||
|||!d$}" jd||||d%|"d& ||d
  S )(a  
    :api_attr: Static Graph

    Compute and return the noise-contrastive estimation training loss. See `Noise-contrastive estimation: A new estimation principle
    for unnormalized statistical models <http://www.jmlr.org/proceedings/papers/v9/gutmann10a/gutmann10a.pdf>`_.
    By default this operator uses a uniform distribution for sampling.

    Args:
        input (Tensor): Input tensor, 2-D tensor with shape [batch_size, dim],
            and data type is float32 or float64.
        label (Tensor): Input label, 2-D tensor with shape [batch_size, num_true_class],
            and data type is int64.
        num_total_classes (int): Total number of classes in all samples.
        sample_weight (Tensor|None): A Tensor of shape [batch_size, 1]
            storing a weight for each sample. The default weight for each
            sample is 1.0.
        param_attr (ParamAttr|None): To specify the weight parameter attribute.
            Default: None, which means the default weight parameter property is
            used. See usage for details in :ref:`api_paddle_ParamAttr` .
        bias_attr (ParamAttr|None): To specify the bias parameter attribute.
            Default: None, which means the default bias parameter property is
            used. See usage for details in :ref:`api_paddle_ParamAttr` .
        num_neg_samples (int): The number of negative classes. The default value is 10.
        name(str|None): For detailed information, please refer to
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
        sampler (str, optional): The sampler used to sample class from negative classes.
                       It can be 'uniform', 'log_uniform' or 'custom_dist'.
                       default: 'uniform'.
        custom_dist (nd.array|None): A numpy ndarray with size=num_total_classes.
                       It is used when sampler is set to 'custom_dist'.
                       custom_dist[i] is the probability of i-th class to be sampled.
                       default: None.
        seed (int, optional): The seed used in sampler. Default 0, means no random seed.
        is_sparse(bool, optional): The flag indicating whether to use sparse update,
            the weight@GRAD and bias@GRAD will be changed to SelectedRows. Default False.

    Returns:
        Tensor: The output nce loss.

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> import numpy as np

            >>> paddle.enable_static()

            >>> window_size = 5
            >>> words = []
            >>> for i in range(window_size):
            ...     words.append(paddle.static.data(
            ...         name='word_{0}'.format(i), shape=[-1, 1], dtype='int64'))

            >>> dict_size = 10000
            >>> label_word = int(window_size / 2) + 1

            >>> embs = []
            >>> for i in range(window_size):
            ...     if i == label_word:
            ...         continue
            ...
            ...     emb = paddle.static.nn.embedding(input=words[i], size=[dict_size, 32],
            ...                         param_attr='embed', is_sparse=True)
            ...     embs.append(emb)

            >>> embs = paddle.concat(x=embs, axis=1)                # concat from 4 * [(-1, 1, 32)] to (-1, 4, 32)
            >>> embs = paddle.reshape(x=embs, shape=(-1, 4 * 32))   # reshape to (batch_size = -1, dim = 4*32)
            >>> loss = paddle.static.nn.nce(input=embs, label=words[label_word],
            ...             num_total_classes=dict_size, param_attr='nce.w_0',
            ...             bias_attr='nce.b_0')

            # or use custom distribution
            >>> dist = np.array([0.05,0.5,0.1,0.3,0.05])
            >>> loss = paddle.static.nn.nce(input=embs, label=words[label_word],
            ...         num_total_classes=5, param_attr='nce.w_1',
            ...         bias_attr='nce.b_1',
            ...         num_neg_samples=3,
            ...         sampler="custom_dist",
            ...         custom_dist=dist)
    nceinputZfloat32Zfloat64labelZint64   z,The rank of `input` must be 2, but received .   F)attrshapeZis_biasdtypeTZBias)r   ZInputLabelZWeightNZSampleWeightr   r   Zlog_uniformcustom_distg      ?c                    s&    j t | j| jt| d}d|_|S )N)r   r   r   Zdefault_initializerT)create_parameterr   r   r   r   Zstop_gradient)Znumpy_arrayrethelper \/home/app/PaddleOCR-VL/.venv_paddleocr/lib/python3.10/site-packages/paddle/static/nn/loss.py_init_by_numpy_array   s   z!nce.<locals>._init_by_numpy_arrayZCustomDistProbsZint32ZCustomDistAliasZCustomDistAliasProbszUnsupported sampler type.
   zWWith sparse mode, if your models has only small parameter prefetch may cause speed down)num_total_classesnum_neg_samplesseedsampler	is_sparseremote_prefetch)ZCostZSampleLogitsZSampleLabels)typeinputsZoutputsattrs)r	   )r   localsr   ndim
ValueErrorr   r   
param_attrr   	bias_attrZ"create_variable_for_type_inferencerangeappendlenpopnparrayZastype	ExceptionintprintZ	append_op)#r
   r   r   Zsample_weightr)   r*   r   namer    r   r   r!   dimZnum_true_classwr$   bZcostZsample_logitsZsample_labelsZcustom_dist_lenZalias_probs_Zalias_ZbigsZlittlesiZnormal_probbiglittleZbig_idxZbig_probZbig_leftr   r"   r%   r   r   r   r	       s   _














	
r	   )	NNNNNr   Nr   F)numpyr/   Zpaddle.base.frameworkr   Zpaddle.base.layer_helperr   Zpaddle.base.param_attrr   Zpaddle.nn.initializerr   Zbase.data_feederr   __all__r	   r   r   r   r   <module>   s$   