o
    0j-$                  	   @   s   d dl mZmZ d dlZd dlmZ ddlmZ ddlm	Z	m
Z
 ddlmZ dd	ed
edee defddZG dd dejZG dd dejZG dd dejZG dd dejZG dd de
ZG dd de	e
ZdS )    )ListOptionalN   )ACT2FN)BatchNormHFStateDictMixinPretrainedModel   )PPLCNetConfig   vdivisor	min_valuereturnc                 C   sB   |du r|}t |t| |d  | | }|d|  k r||7 }|S )aV  
    Ensure the number of channels is a multiple of the specified divisor (common optimization for mobile networks)

    Args:
        v: Original number of channels
        divisor: Divisor, default 8
        min_value: Minimum number of channels, default None (takes divisor)

    Returns:
        Adjusted number of channels (integer)
    N   g?)maxint)r   r   r   new_v r   /var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddlex/inference/models/image_classification/modeling/pplcnet.pymake_divisible   s   r   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )PPLCNetSqueezeExcitationModulez
    Squeeze-and-Excitation (SE) Module: Adaptive feature recalibration
    Enhances the model's ability to focus on important channels by learning channel-wise attention weights.
       c                    s~   t    td| _t | _||| t g|| |t gfD ]\}}}| j	tj
||ddddd | j	| q"d S )Nr   r   Tin_channelsout_channelskernel_sizestridepaddingbias)super__init__nnAdaptiveAvgPool2Davg_pool	LayerListconvolutionsZReLUZHardsigmoidappendConv2d)selfZchannel	reductionr   r   
activation	__class__r   r   r    7   s$   


z'PPLCNetSqueezeExcitationModule.__init__c                 C   s.   |}|  |}| jD ]}||}q
|| }|S N)r#   r%   )r(   hidden_stateZresiduallayerr   r   r   forwardL   s   


z&PPLCNetSqueezeExcitationModule.forward)r   __name__
__module____qualname____doc__r    r0   __classcell__r   r   r+   r   r   1   s    r   c                       sH   e Zd Z				ddededededed	ef fd
dZdd Z  ZS )PPLCNetConvLayerr   r   	hardswishr   r   r   r   r*   groupsc              	      sX   t    tj|||||d d|d| _t|| _|d ur%t| | _	d S t | _	d S )Nr   F)r   r   r   r   r9   )
r   r    r!   r'   convolutionZBatchNorm2Dnormalizationr   Identityr*   )r(   r   r   r   r   r*   r9   r+   r   r   r    W   s   
		zPPLCNetConvLayer.__init__c                 C   s"   |  |}| |}| |}|S r-   )r:   r;   r*   )r(   inputr.   r   r   r   r0   o   s   


zPPLCNetConvLayer.forward)r   r   r8   r   )r2   r3   r4   r   strr    r0   r6   r   r   r+   r   r7   V   s&    r7   c                       s(   e Zd ZdZ fddZdd Z  ZS )"PPLCNetDepthwiseSeparableConvLayerz
    Depthwise Separable Convolution Layer: Depthwise Conv -> SE Module (optional) -> Pointwise Conv
    Core component of lightweight models (e.g., MobileNet, PP-LCNet) that significantly reduces
    the number of parameters and computational cost.
    c                    sV   t    t||||||jd| _|rt||jnt | _	t|d|d|jd| _
d S )N)r   r   r   r   r9   r*   r   r   r   r   r   r*   )r   r    r7   
hidden_actdepthwise_convolutionr   r)   r!   r<   squeeze_excitation_modulepointwise_convolution)r(   r   r   r   r   use_squeeze_excitationconfigr+   r   r   r    }   s(   
	
z+PPLCNetDepthwiseSeparableConvLayer.__init__c                 C   s"   |  |}| |}| |}|S r-   )rB   rC   rD   )r(   r.   r   r   r   r0         


z*PPLCNetDepthwiseSeparableConvLayer.forwardr1   r   r   r+   r   r?   v   s    r?   c                       s$   e Zd Z fddZdd Z  ZS )PPLCNetBlockc              	      s   t    || _|j| }t | _|D ])\}}}}}t||j |j	}	t||j |j	}
t
|	|
||||d}| j| qd S )N)r   r   r   r   rE   rF   )r   r    rF   block_configsr!   r$   layersr   scaler   r?   r&   )r(   rF   stage_indexblocksr   r   r   r   rE   Zscaled_in_channelsZscaled_out_channelsZdepthwise_blockr+   r   r   r       s6   


zPPLCNetBlock.__init__c                 C   s   | j D ]}||}q|S r-   )rJ   )r(   hidden_statesr/   r   r   r   r0      s   

zPPLCNetBlock.forward)r2   r3   r4   r    r0   r6   r   r   r+   r   rH      s    rH   c                       s.   e Zd Zdeddf fddZdd Z  ZS )PPLCNetEncoderrF   r   Nc                    sl   t  | tddt|j|j |j|j|jd| _	t
 | _tt|jD ]}t||}| j| q&d S )Nr   r@   )r   r    r7   r   Zstem_channelsrK   r   Zstem_striderA   r:   r!   r$   rM   rangelenrI   rH   r&   )r(   rF   rL   blockr+   r   r   r       s   


zPPLCNetEncoder.__init__c                 C   s"   |  |}| jD ]}||}q|S r-   )r:   rM   )r(   pixel_valuesrN   rR   r   r   r   r0      rG   zPPLCNetEncoder.forward)r2   r3   r4   r	   r    r0   r6   r   r   r+   r   rO      s    rO   c                       sD   e Zd ZeZdeddf fddZdedefddZd	d
 Z  Z	S )PPLCNetrF   r   Nc                    s   t  | t|| _|| _|j| _|jd d d }td| _	tj
t||j |j|jddddd| _t|j | _|j| _tjddd| _|jdkrWt|j|j| _d S t | _d S )Nr   r   r   Fr   )Z
start_axisZ	stop_axis)r   r    rO   encoderrF   Z
num_labelsrI   r!   r"   r#   r'   r   rK   r   Zclass_expandlast_convolutionr   rA   act_fnhidden_dropout_probZFlattenflattenZLinearr<   head)r(   rF   Zlast_block_out_channelsr+   r   r   r       s0   


zPPLCNet.__init__xc                 C   sn   t |d }| |}| |}| |}| |}|d| j  }| |}| |}|	 }|
  gS )Nr   r   )paddleZ	to_tensorrV   r#   rW   rX   rY   rZ   r[   Zsoftmaxcpunumpy)r(   r\   rS   ZoutputsZlast_hidden_stater   r   r   r0     s   





zPPLCNet.forwardc                 C   sJ   dg}g }|    D ]\}}|D ]}||v r!|dr!|| qq|S )Nr[   weight)Zget_hf_state_dictitemsendswithr&   )r(   Zt_layerskeyskey_Zt_layerr   r   r   get_transpose_weight_keys  s   
z!PPLCNet.get_transpose_weight_keys)
r2   r3   r4   r	   Zconfig_classr    r   r0   rf   r6   r   r   r+   r   rT      s
    rT   )r
   N)typingr   r   r]   Z	paddle.nnr!   Zcommon.transformers.activationsr   Z common.transformers.transformersr   r   _configr	   floatr   r   ZLayerr   r7   r?   rH   rO   rT   r   r   r   r   <module>   s    % .%