o
    #j!                     @   s|   d dl Z d dl mZ ddlmZ ddlmZ ddlmZ g Zddd	Z	d
d Z
dd ZG dd dZdddZdddZdS )    N)_C_ops   )check_variable_and_dtype)LayerHelper)in_dynamic_mode-q=c                 C   s   t | jdkr	d}t r$t| |d u rdn||d\}}tj||gdS t| ddd tdi t	 }|j
| jd	}|j
| jd	}|jdd| i||d
|d u rQdn||dd tj||gdS )N   r   FaxisX)Zfloat32Zfloat64norml2_normalizedtype)ZOutZNorm)r
   epsilon)typeinputsZoutputsattrs)r   )lenshaper   r   r   paddleZsqueezer   r   localsZ"create_variable_for_type_inferencer   Z	append_op)xr
   r   nameoutr   helper r   a/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddle/nn/utils/weight_norm_hook.pyl2_norm   s$    	r   c                 C   s   | j }t|}|dkrttt| d S |dkr,t| |d df}t|ddS ||d krBt| d|d f}t|ddS tt	|}||d< d||< t
| |}t|dS Nr   r   r   r	   )r   r   r   sqrtsumsquarereshaper   listrange	transposenorm_except_dim)pdimr   ndimsp_matrixpermp_transposedr   r   r   r(   1   s   
r(   c                 C   sD  | j }t|}|dkr| ttt| d  }nu|dkr9t| |d df}tjjj	|dd}t||}nW||d krYt| d|d f}tjjj	|dd}t||}n7t
t|}||d< d||< t| |}|j }	t||j d df}tjjj	|dd}t||	}t||}tjjj|||d ur|ndd}
|
S r   )r   r   r   r!   r"   r#   r$   nnZ
functional	normalizer%   r&   r'   ZtensormathZ_multiply_with_axis)vgr*   r   r+   Zv_normalizedr,   r-   r.   Ztransposed_shapeweightr   r   r   _weight_normD   s2    r5   c                   @   s8   e Zd Zdd Zdd Zedd Zdd Zd	d
 ZdS )
WeightNormc                 C   s   |d u rd}|| _ || _d S )Nr    )r   r*   )selfr   r*   r   r   r   __init__c   s   
zWeightNorm.__init__c                 C   s.   t || jd }t || jd }t||| jS )N_g_v)getattrr   r5   r*   )r7   layerr3   r2   r   r   r   compute_weighti   s   zWeightNorm.compute_weightc                 C   sL  | j  D ]\}}t|tr|j|krtd| q|d u r!d}t| j| j}||k r3|d| ks7J d|dkrA|| | }t||}t	| |}| j|= t
||}| j|j|jd}	| |d |	 | j|j|jd}
| |d |
 t  t||	 t||
 W d    n1 sw   Y  t| |||  | | |S )Nz<Cannot register two weight_norm hooks on the same parameter r    z>dim must set between [-R, R), R means the dimension of weight.r   r:   r9   )_forward_pre_hooksitems
isinstancer6   r   RuntimeErrorr   _parametersr   r;   r(   create_parameterr   add_parameterr   no_gradassignsetattrr=   Zregister_forward_pre_hook)r<   r   r*   khookZ
weight_dimfnwZg_varr2   r3   r   r   r   applyn   s>   




zWeightNorm.applyc                 C   s   |  |}t|| j |j| jd = |j| jd = |j|j|jd}|| j| t	  t
|| W d    d S 1 s?w   Y  d S )Nr9   r:   r   )r=   delattrr   rB   rC   r   r   rD   r   rE   rF   )r7   r<   Zw_varrK   r   r   r   remove   s   

"zWeightNorm.removec                 C   s   t || j| | d S )N)rG   r   r=   )r7   r<   r   r   r   r   __call__   s   zWeightNorm.__call__N)	__name__
__module____qualname__r8   r=   staticmethodrL   rN   rO   r   r   r   r   r6   b   s    
%
r6   r4   c                 C   s   t | || | S )a  
    Applies weight normalization to a parameter according to the
    following formula:

    .. math::

        \mathbf{w} = g \dfrac{v}{\|v\|}

    Weight normalization is a reparameterization of the weight vectors in a neural network that
    decouples the magnitude of those weight vectors from their direction. Weight normalization
    replaces the parameter specified by ``name`` (eg: 'weight') with two parameters: one parameter
    specifying the magnitude (eg: 'weight_g') and one parameter specifying the direction
    (eg: 'weight_v'). Weight normalization has been implemented as discussed in this paper:

    `Weight Normalization: A Simple Reparameterization to Accelerate Training of Deep Neural Networks
    <https://arxiv.org/pdf/1602.07868.pdf>`_.

    Parameters:
        layer(Layer): Layer of paddle, which has weight.
        name(str, optional): Name of the weight parameter. Default: 'weight'.
        dim(int, optional): Dimension over which to compute the norm. Dim is a non-negative number
              which is less than the rank of weight Tensor. For Example, dim can be chosen from 0,
              1, 2, 3 for convolution whose weight shape is [cout, cin, kh, kw] and rank is 4.
              If dim is set to None, meaning that all elements will be normalized. Default: 0.

    Returns:
        Origin layer with weight norm hook.

    Examples:
        .. code-block:: python

          >>> from paddle.nn import Conv2D
          >>> from paddle.nn.utils import weight_norm

          >>> conv = Conv2D(3, 5, 3)
          >>> wn = weight_norm(conv)
          >>> print(conv.weight_g.shape)
          [5]
          >>> print(conv.weight_v.shape)
          [5, 3, 3, 3]
    )r6   rL   )r<   r   r*   r   r   r   weight_norm   s   *rT   c                 C   sV   | j  D ]\}}t|tr |j|kr ||  | j |= |   S qtd| d|  )a  
    remove weight normalization from layer.

    Parameters:
        layer(Layer): Layer of paddle, which has weight.
        name(str, optional): Name of the weight parameter. Default: 'weight'.

    Returns:
        Layer, the origin layer without weight norm

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> from paddle.nn import Conv2D
            >>> from paddle.nn.utils import weight_norm, remove_weight_norm
            >>> paddle.seed(2023)

            >>> conv = Conv2D(3, 5, 3)
            >>> wn = weight_norm(conv)
            >>> print(conv.weight_g)
            Parameter containing:
            Tensor(shape=[5], dtype=float32, place=Place(cpu), stop_gradient=False,
                   [1.35883713, 1.32126212, 1.56303072, 1.20874095, 1.22893476])
            >>> remove_weight_norm(conv)
            >>> # The following is the effect after removing the weight norm:
            >>> # print(conv.weight_g)
            >>> # AttributeError: 'Conv2D' object has no attribute 'weight_g'
    zweight_norm of 'z' not found in )r>   r?   r@   r6   r   rN   
ValueError)r<   r   rH   rI   r   r   r   remove_weight_norm   s   
rV   )r   N)r4   r   )r4   )r   r   Zbase.data_feederr   Zbase.layer_helperr   Z	frameworkr   __all__r   r(   r5   r6   rT   rV   r   r   r   r   <module>   s   

@.