
    Ngf!                     v    d Z ddlZddlmZ ddlmZ defdZej        j	         G d d	e
                      ZdS )
a'  Argmax matcher implementation.

This class takes a similarity matrix and matches columns to rows based on the
maximum value per column. One can specify matched_thresholds and
to prevent columns from matching to rows (generally resulting in a negative
training example) and unmatched_theshold to ignore the match (generally
resulting in neither a positive or negative training example).

This matcher is used in Fast(er)-RCNN.

Note: matchers are used in TargetAssigners. There is a create_target_assigner
factory function for popular implementations.
    N   )Match)Optionalnum_classesc                     t          j        |                     d          || j        t           j                  }|                    d|                     d          d          S )Nr   )devicedtyper   )torchzerossizer   boolscatter_	unsqueeze)xr   onehots      b/var/www/html/ai-engine/env/lib/python3.11/site-packages/effdet/object_detection/argmax_matcher.pyone_hot_boolr   !   sH    [K
SSSF??1akk!nna000    c            	       \    e Zd ZdZ	 	 	 ddedee         dedefd	Zd
 Zd Z	d Z
defdZdS )ArgMaxMatchera  Matcher based on highest value.

    This class computes matches from a similarity matrix. Each column is matched
    to a single row.

    To support object detection target assignment this class enables setting both
    matched_threshold (upper threshold) and unmatched_threshold (lower thresholds)
    defining three categories of similarity which define whether examples are
    positive, negative, or ignored:
    (1) similarity >= matched_threshold: Highest similarity. Matched/Positive!
    (2) matched_threshold > similarity >= unmatched_threshold: Medium similarity.
            Depending on negatives_lower_than_unmatched, this is either
            Unmatched/Negative OR Ignore.
    (3) unmatched_threshold > similarity: Lowest similarity. Depending on flag
            negatives_lower_than_unmatched, either Unmatched/Negative OR Ignore.
    For ignored matches this class sets the values in the Match object to -2.
    NTFmatched_thresholdunmatched_thresholdnegatives_lower_than_unmatchedforce_match_for_each_rowc                 
   ||t          d          || _        d| _        ||| _        n||k    rt          d          || _        |s+| j        | j        k    rt          d| j        | j                  || _        || _        dS )aT  Construct ArgMaxMatcher.

        Args:
            matched_threshold: Threshold for positive matches. Positive if
                sim >= matched_threshold, where sim is the maximum value of the
                similarity matrix for a given column. Set to None for no threshold.
            unmatched_threshold: Threshold for negative matches. Negative if
                sim < unmatched_threshold. Defaults to matched_threshold
                when set to None.
            negatives_lower_than_unmatched: Boolean which defaults to True. If True
                then negative matches are the ones below the unmatched_threshold,
                whereas ignored matches are in between the matched and unmatched
                threshold. If False, then negative matches are in between the matched
                and unmatched threshold, and everything lower than unmatched is ignored.
            force_match_for_each_row: If True, ensures that each row is matched to
                at least one column (which is not guaranteed otherwise if the
                matched_threshold is high). Defaults to False. See
                argmax_matcher_test.testMatcherForceMatch() for an example.

        Raises:
            ValueError: if unmatched_threshold is set but matched_threshold is not set
                or if unmatched_threshold > matched_threshold.
        NzINeed to also define matched_threshold when unmatched_threshold is definedg        zEunmatched_threshold needs to be smaller or equal to matched_thresholdzzWhen negatives are in between matched and unmatched thresholds, these cannot be of equal value. matched: %s, unmatched: %s)
ValueError_matched_threshold_unmatched_threshold_force_match_for_each_row_negatives_lower_than_unmatched)selfr   r   r   r   s        r   __init__zArgMaxMatcher.__init__;   s    8 %,?,Khiii"3+-!&(9D%%"%666 !hiii(;D%- 	U(D,CCC  "X!%!8$:SU U U *B&/M,,,r   c                 j    dt          j        |j        d         t           j        |j                  z  S )aK  Performs matching when the rows of similarity matrix are empty.

        When the rows are empty, all detections are false positives. So we return
        a tensor of -1's to indicate that the columns do not match to any rows.

        Returns:
            matches:  int32 tensor indicating the row each column matches to.
        r   )r	   r   )r
   onesshapelongr   r!   similarity_matrixs     r   _match_when_rows_are_emptyz(ArgMaxMatcher._match_when_rows_are_emptyi   s/     EJ06q9TeTlmmmmmr   c                    t          j        |d          \  }}| j        | j        |k    }|| j        k    | j        |k    z  }| j        r/|                     ||d          }|                     ||d          }n.|                     ||d          }|                     ||d          }| j        r`t          j        |d          }t          ||j	        d                   }t          j        |d          \  }}	t          j
        ||	|          }
|
S |S )zPerforms matching when the rows of similarity matrix are non empty.

        Returns:
            matches:  int32 tensor indicating the row each column matches to.
        r   Nr$   r   )r
   maxr   r   r    _set_values_using_indicatorr   argmaxr   r&   where)r!   r)   matched_valsmatchesbelow_unmatched_thresholdbetween_thresholdsforce_match_column_idsforce_match_column_indicatorsforce_match_column_maskforce_match_row_idsfinal_matchess              r   _match_when_rows_are_non_emptyz,ArgMaxMatcher._match_when_rows_are_non_emptyt   s;    !&	*;Q ? ?g ".(,(AL(P%".$2K"K"&"9L"H"J 3 \::7D]_abb::7DVXZ[[::7D]_abb::7DVXZ[[) 	%*\2CQ%G%G",89OQbQhijQk,l,l);@9Ebde;f;f8#%8!K(?ATV]^^M  Nr   c                     |j         d         dk    r"t          |                     |                    S t          |                     |                    S )a  Tries to match each column of the similarity matrix to a row.

        Args:
            similarity_matrix: tensor of shape [N, M] representing any similarity metric.

        Returns:
            Match object with corresponding matches for each of M columns.
        r   )r&   r   r*   r:   r(   s     r   matchzArgMaxMatcher.match   sQ     "1%**889JKKLLL<<=NOOPPPr   valc                 T    |                     |j                  }|d|z
  z  ||z  z   S )zSet the indicated fields of x to val.

        Args:
            x: tensor.
            indicator: boolean with same shape as x.
            val: scalar with value to set.

        Returns:
            modified tensor.
        )r	   r   )tor	   )r!   r   	indicatorr=   s       r   r.   z)ArgMaxMatcher._set_values_using_indicator   s1     LLqwL//	A	M"S9_44r   )NTF)__name__
__module____qualname____doc__floatr   r   r"   r*   r:   r<   intr.    r   r   r   r   '   s         ( 9=8<27	,N ,N$),N&.uo,N 26,N ,0	,N ,N ,N ,N\	n 	n 	n  @Q Q Q5S 5 5 5 5 5 5r   r   )rD   r
   matcherr   typingr   rF   r   jitscriptobjectr   rG   r   r   <module>rM      s                 1 1 1 1 1 F5 F5 F5 F5 F5F F5 F5 F5 F5 F5r   