o
    MePI                     @   s   d dl mZ d dlZd dlZddlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ g d
Zdd ZG dd deZG dd deZG dd deZG dd deZdS )    )print_functionN   )layers)ProgramVariableprogram_guard)unique_name)LayerHelper)Constant)	detection)ChunkEvaluatorEditDistanceDetectionMAPc                 C   s.   t |tsJ | j|j|j|j|j|jddS )NT)nameshapedtypetype	lod_levelpersistable)
isinstancer   Z
create_varr   r   r   r   r   )blockvar r   FD:\Projects\ConvertPro\env\Lib\site-packages\paddle/fluid/evaluator.py_clone_var_"   s   r   c                   @   s4   e Zd ZdZdd ZdddZdddZd	d
 ZdS )	Evaluatora  
    Warning: better to use the fluid.metrics.* things, more
    flexible support via pure Python and Operator, and decoupled
    with executor. Short doc are intended to urge new user
    start from Metrics.

    Base Class for all evaluators.

    Args:
        name(str): The name of evaluator. such as, "accuracy". Used for generate
            temporary variable name.
        main_program(Program, optional): The evaluator should be added to this
            main_program. Default default_main_program()
        startup_program(Program, optional):The parameter should be added to this
            startup_program. Default default_startup_program()

    Attributes:
        states(list): The list of state variables. states will be reset to zero
            when `reset` is invoked.
        metrics(list): The list of metrics variables. They will be calculate
            every mini-batch
    c                 K   s>   t d| jj| jjf t g | _g | _t|fi || _d S )NzThe %s is deprecated, because maintain a modified program inside evaluator cause bug easily, please use fluid.metrics.%s instead.)	warningswarn	__class____name__Warningstatesmetricsr	   helper)selfr   kwargsr   r   r   __init__D   s   zEvaluator.__init__Nc                 C   s   |du rt  }t|d' | jD ]}t|tsJ t| |}tj|j	d|j
|d qW d   n1 s6w   Y  || dS )a  
        reset metric states at the begin of each pass/user specified batch

        Args:
            executor(Executor|ParallelExecutor): a executor for executing the reset_program
            reset_program(Program): a single Program for reset process
        Nmain_program        r   valuer   out)r   r   r!   r   r   r   current_blockr   fill_constantr   r   run)r$   executorreset_programr   Zg_varr   r   r   resetL   s   
	zEvaluator.resetc                 C   s   t  )z
        Evaluate the statistics merged by multiple mini-batches.
        Args:
            executor(Executor|ParallelExecutor): a executor for executing the eval_program
            eval_program(Program): a single Program for eval process
        )NotImplementedError)r$   r0   eval_programr   r   r   evalb   s   zEvaluator.evalc                 C   s8   | j jdt| j j|gd||d}| j| |S )z
        Create state variable.

        Args:
            suffix(str): the state suffix.
            dtype(str|core.VarDesc.VarType): the state data type
            shape(tuple|list): the shape of state

        Returns: State variable

        _T)r   r   r   r   )r#   create_variablejoinr   generater   r!   append)r$   suffixr   r   stater   r   r   _create_statek   s   
zEvaluator._create_stateN)r   
__module____qualname____doc__r&   r2   r5   r=   r   r   r   r   r   ,   s    

	r   c                       s.   e Zd ZdZ	d fdd	ZdddZ  ZS )r   a  
    Warning: This would be deprecated in the future. Please use fluid.metrics.ChunkEvaluator 
    instead.

    Accumulate counter numbers output by chunk_eval from mini-batches and
    compute the precision recall and F1-score using the accumulated counter
    numbers.
    For some basics of chunking, please refer to
    'Chunking with Support Vector Machines <https://aclanthology.info/pdf/N/N01/N01-1025.pdf>'.

    Args:
        input (Variable): prediction output of the network.
        label (Variable): label of the test data set.
        chunk_scheme (str): can be IOB/IOE/IOBES and IO. See the chunk_eval op for details.
        num_chunk_types (int): the number of chunk type.
        excluded_chunk_types (list): A list including chunk type ids, indicating chunk types that are not counted.

    Returns:
        tuple: tuple containing: precision, recall, f1_score

    Examples:
        .. code-block:: python

            exe = fluid.executor(place)
            evaluator = fluid.Evaluator.ChunkEvaluator(input, label)
            for epoch in PASS_NUM:
                evaluator.reset(exe)
                for data in batches:
                    loss = exe.run(fetch_list=[cost])
                distance, instance_error = distance_evaluator.eval(exe)
    Nc                    s   t t| d | jj}| jdkrtd| jddgdd| _	| jddgdd| _
| jddgd	d| _tj|||||d
\}}}	}
}}tj| j	|
g| j	d tj| j
|g| j
d tj| j|g| jd | j|||	g d S )N
chunk_evalr   +You can only invoke Evaluator in root blockint64r   num_infer_chunksr   r   r;   num_label_chunksnum_correct_chunks)inputlabelchunk_schemenum_chunk_typesexcluded_chunk_typesrI   r,   )superr   r&   r#   r(   r-   idx
ValueErrorr=   rE   rG   rH   r   rB   sumsr"   extend)r$   rI   rJ   rK   rL   rM   r(   	precisionrecallf1_scorerE   rG   rH   r   r   r   r&      s@   zChunkEvaluator.__init__c           	         s   |d u rt  }|  |j| fdd| jD d\}}}|d }|d }|d }|r1t|| nd}|r;t|| nd}|rKtd| | ||  nd}tj|gddtj|gddtj|gddfS )Nc                    s   g | ]}t  |qS r   )r   ).0r<   r   r   r   
<listcomp>   s    z'ChunkEvaluator.eval.<locals>.<listcomp>Z
fetch_listr      float32)r   )r   r-   r/   r!   floatnparray)	r$   r0   r4   rE   rG   rH   rT   rU   rV   r   rY   r   r5      sJ   zChunkEvaluator.evalr>   r   r?   r@   rA   r&   r5   __classcell__r   r   rW   r   r      s
    &%r   c                       s,   e Zd ZdZd fdd	ZdddZ  ZS )r   a@  
    Warning: This would be deprecated in the future. Please use fluid.metrics.EditDistance
    instead.
    Accumulate edit distance sum and sequence number from mini-batches and
    compute the average edit_distance and instance error of all batches.

    Args:
        input: the sequences predicted by network.
        label: the target sequences which must have same sequence count
        with input.
        ignored_tokens(list of int): Tokens that should be removed before
        calculating edit distance.

    Examples:
        .. code-block:: python

            exe = fluid.executor(place)
            distance_evaluator = fluid.Evaluator.EditDistance(input, label)
            for epoch in PASS_NUM:
                distance_evaluator.reset(exe)
                for data in batches:
                    loss = exe.run(fetch_list=[cost])
                distance, instance_error = distance_evaluator.eval(exe)

        In the above example:
        'distance' is the average of the edit distance in a pass.
        'instance_error' is the instance error rate in a pass.

    Nc                    s0  t t| jdi | | jj}| jdkrtd| jddgdd| _	| jddgd	d| _
| jddgd
d| _tj|||d\}}tjdgddd}t||}	tj|	dd}
t|
}tj||d}t|}tj| j	|g| j	d tj| j
|g| j
d tj| j|g| jd | j| | j| d S )Nedit_distancer   rC   r]   r   total_distancerF   rD   seq_numinstance_error)rI   rJ   ignored_tokensr)   )r   r+   r   xr   ri   yrN   )rc   )rO   r   r&   r#   r(   r-   rP   rQ   r=   rd   re   rf   r   rc   r.   equalcastZ
reduce_sumZelementwise_subrR   r"   r:   )r$   rI   rJ   rg   r%   r(   Z	distancesre   zeroZcompare_resultZcompare_result_intZseq_right_countZinstance_error_countrd   rW   r   r   r&      sJ   


zEditDistance.__init__c           
      C   s   |d u rt  }| }t|d? t|| j}t|| j}t|| j}tj|dd}tj|dd}tj	||d}tj	||d}|j
|||gd}	W d    n1 sRw   Y  t|	d t|	d fS )Nr'   r]   rh   rj   r[   r   r   )r   r-   r   r   rd   re   rf   r   rm   Zelementwise_divr/   r_   r`   )
r$   r0   r4   r   rd   re   rf   Zavg_distanceZavg_instance_errorresultr   r   r   r5     s$   zEditDistance.evalr>   ra   r   r   rW   r   r      s    "r   c                       s@   e Zd ZdZ						d fdd	Zd	d
 ZdddZ  ZS )r   a
  
    Warning: This would be deprecated in the future. Please use fluid.metrics.DetectionMAP
    instead.
    Calculate the detection mean average precision (mAP).

    The general steps are as follows:
    1. calculate the true positive and false positive according to the input
        of detection and labels.
    2. calculate mAP value, support two versions: '11 point' and 'integral'.

    Please get more information from the following articles:
      https://sanchom.wordpress.com/tag/average-precision/
      https://arxiv.org/abs/1512.02325

    Args:
        input (Variable): The detection results, which is a LoDTensor with shape
            [M, 6]. The layout is [label, confidence, xmin, ymin, xmax, ymax].
        gt_label (Variable): The ground truth label index, which is a LoDTensor
            with shape [N, 1].
        gt_box (Variable): The ground truth bounding box (bbox), which is a
            LoDTensor with shape [N, 4]. The layout is [xmin, ymin, xmax, ymax].
        gt_difficult (Variable|None): Whether this ground truth is a difficult
            bounding bbox, which can be a LoDTensor [N, 1] or not set. If None,
            it means all the ground truth labels are not difficult bbox.
        class_num (int): The class number.
        background_label (int): The index of background label, the background
            label will be ignored. If set to -1, then all categories will be
            considered, 0 by default.
        overlap_threshold (float): The threshold for deciding true/false
            positive, 0.5 by default.
        evaluate_difficult (bool): Whether to consider difficult ground truth
            for evaluation, True by default. This argument does not work when
            gt_difficult is None.
        ap_version (string): The average precision calculation ways, it must be
            'integral' or '11point'. Please check
            https://sanchom.wordpress.com/tag/average-precision/ for details.
            - 11point: the 11-point interpolated average precision.
            - integral: the natural integral of the precision-recall curve.

    Examples:
        .. code-block:: python

            exe = fluid.executor(place)
            map_evaluator = fluid.Evaluator.DetectionMAP(input,
                gt_label, gt_box, gt_difficult)
            cur_map, accum_map = map_evaluator.get_map_var()
            fetch = [cost, cur_map, accum_map]
            for epoch in PASS_NUM:
                map_evaluator.reset(exe)
                for data in batches:
                    loss, cur_map_v, accum_map_v = exe.run(fetch_list=fetch)

        In the above example:

        'cur_map_v' is the mAP of current mini-batch.
        'accum_map_v' is the accumulative mAP of one pass.
    Nr         ?Tintegralc
                    s.  t t| d tj||jd}|r%tj||jd}tj|||gdd}
n	tj||gdd}
tj||
|||||	d}| j	dd dd | j	d	d d
d | j	d	d dd d | _
| jjdddgd}| jj|ttddd || _
tj||
||||| j
| j| j|	d
}tj| j
jd| j
j| j
d || _|| _d S )NZmap_evalrh   r   )Zaxis)overlap_thresholdevaluate_difficult
ap_versionZint32Zaccum_pos_countrF   r]   Zaccum_true_posZaccum_false_posT)r   r   r   r   )r+   )initializer)rr   rs   	has_stateZinput_statesZ
out_statesrt   r*   )rO   r   r&   r   rm   r   concatr   Zdetection_mapr=   rv   r#   r7   Zset_variable_initializerr
   intr!   r.   r   cur_map	accum_map)r$   rI   Zgt_labelZgt_boxZgt_difficultZ	class_numZbackground_labelrr   rs   rt   rJ   mapr   rz   rW   r   r   r&   h  s`   


zDetectionMAP.__init__c                 C   s   | j | jfS r>   )ry   rz   )r$   r   r   r   get_map_var  s   zDetectionMAP.get_map_varc                 C   sl   |d u rt  }t|d t| | j}tj|jd|j|d W d    n1 s*w   Y  |	| d S )Nr'   r   r*   )
r   r   r   r-   rv   r   r.   r   r   r/   )r$   r0   r1   r   r   r   r   r2     s   zDetectionMAP.reset)NNr   rp   Trq   r>   )r   r?   r@   rA   r&   r|   r2   rb   r   r   rW   r   r   -  s    >?r   )
__future__r   r   numpyr_    r   Z	frameworkr   r   r   r   Zlayer_helperr	   ru   r
   r   __all__r   objectr   r   r   r   r   r   r   r   <module>   s   
TZS