U
    gfS                     @   s(  d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZ ddlZddlmZ ddlmZ ddlm  mZ ddlmZ ddlmZmZmZmZmZ ee dd	Z!ee d
d	Z"ee ddZ#zddl$Z$W n e%k
r   dZ$Y nX ej&ddd ej&de'd eej(dfddZ)dVddZ*dd Z+dWddZ,eedddZ-dd  Z.dXd#d$Z/d%d& Z0dYd(d)Z1d*d+ Z2d,d- Z3d.d/ Z4ej5fd0d1Z6d2d3 Z7dZd5d6Z8d7d8 Z9d[d;d<Z:d\d?d@Z;d]dBdCZ<d^dHdIZ=d_dLdMZ>d`dPdQZ?G dRdS dSZ@G dTdU dUZAdS )azPyTorch utils.    N)contextmanager)deepcopy)Path)DistributedDataParallel)LOGGERcheck_versioncolorstr	file_dategit_describe
LOCAL_RANKRANK
WORLD_SIZE   ignorezIUser provided device_type of 'cuda', but CUDA is not available. Disabling)message)categoryz1.9.0c                    s    fdd}|S )zbApplies torch.inference_mode() if torch>=1.9.0, else torch.no_grad() as a decorator for functions.c                    s    r
t jnt j | S N)torchinference_modeno_grad)fn	torch_1_9 _/home/ankuromar296_gmail_com/GitHubProjects/OPP/Palm_Detection/Code/yolov5/utils/torch_utils.pydecorate'   s    z&smart_inference_mode.<locals>.decorater   )r   r   r   r   r   smart_inference_mode$   s    r           c                 C   s:   t tjdrtj| dS | dkr2td|  d t S )zzReturns a CrossEntropyLoss with optional label smoothing for torch>=1.10.0; warns if smoothing on lower
    versions.
    z1.10.0label_smoothingr   u   WARNING ⚠️ label smoothing z requires torch>=1.10.0)r   r   __version__nnCrossEntropyLossr   warningr   r   r   r   smartCrossEntropyLoss-   s
    r%   c                 C   sJ   t tjdddrtdt tjdr6t| tgtddS t| tgtdS dS )	zcInitializes DistributedDataParallel (DDP) for model training, respecting torch version constraints.1.12.0T)pinnedztorch==1.12.0 torchvision==0.13.0 DDP training is not supported due to a known issue. Please upgrade or downgrade torch to use DDP. See https://github.com/ultralytics/yolov5/issues/8395z1.11.0)
device_idsoutput_devicestatic_graph)r(   r)   N)r   r   r!   AssertionErrorDDPr   modelr   r   r   	smart_DDP8   s    r/     c                 C   sn  ddl m} tt| dr| jn|  d \}}t||r\|jj|krXt	
|jj||_nt|t	j
r|j|krt| |t	
|j| nt|t	jrjdd |D }t	j
|krt|d |ddd t	j
 }|| j|krt	
|| j|||< nrt	j|krjt|d |ddd t	j }|| j|krjt	j|| j||| j|| j|| jdk	d	||< dS )
zeReshapes last layer of model to match class count 'n', supporting Classify, Linear, Sequential types.r   )Classifyr.   r   c                 S   s   g | ]}t |qS r   )type.0xr   r   r   
<listcomp>P   s     z-reshape_classifier_output.<locals>.<listcomp>r   N)bias)models.commonr1   listhasattrr.   named_children
isinstancelinearout_featuresr"   Linearin_featuressetattr
SequentiallenindexConv2dout_channelsin_channelskernel_sizestrider7   )r.   nr1   namemtypesir   r   r   reshape_classifier_outputD   s$    $


""rO   
local_rankc                 c   s6   | dkrt j| gd dV  | dkr2t jdgd dS )zContext manager ensuring ordered operations in distributed training by making all processes wait for the leading
    process.
    )r   r   )r(   Nr   )distbarrierrP   r   r   r   torch_distributed_zero_first[   s
    rT   c                  C   sj   t  dkstdz:t  dkr&dnd} ttj| ddddj  d W S  t	k
rd   Y d	S X d
S )zbReturns the number of available CUDA devices; works on Linux and Windows by invoking `nvidia-smi`.)LinuxWindowsz1device_count() only supported on Linux or WindowsrU   znvidia-smi -L | wc -lznvidia-smi -L | find /c /v ""T)shellcapture_outputcheckr   r   N)
platformsystemr+   int
subprocessrunstdoutdecodesplit	Exception)cmdr   r   r   device_countg   s    &rd    Tc              
   C   s  dt  pt  dt  dtj d}t|   	dd	dd} | dk}| d	k}|s^|rjd
t
jd< nB| r| t
jd< tj rtj t| 	ddkstd|  d|s|stj r| r| dnd}t|}|dkr|dkr|| dkstd| d| dt|d  }t|D ]N\}	}
tj|	}||	dkrPdn| d|
 d|j d|jd dd7 }q,d}n<|rttddrtjj r|d7 }d	}n|d7 }d}|s| }t| t|S )z_Selects computing device (CPU, CUDA GPU, MPS) for YOLOv5 model deployment, logging device info.u   YOLOv5 🚀 z Python-z torch- zcuda:re   nonecpumpsz-1CUDA_VISIBLE_DEVICES,zInvalid CUDA '--device z<' requested, use '--device cpu' or pass valid CUDA device(s)0r   r   zbatch-size z not multiple of GPU count zCUDA:z (, i   z.0fzMiB)
zcuda:0has_mpsFzMPS
zCPU
)r
   r	   rZ   python_versionr   r!   strstriplowerreplaceosenvironcudais_availablerd   rC   r+   ra   	enumerateget_device_propertiesrK   total_memorygetattrbackendsri   rstripr   infodevice)r   
batch_sizenewlinesrh   ri   devicesrJ   spacerN   dpargr   r   r   select_deviceq   s@    & 


"<"
r   c                   C   s   t j rt j  t S )zeSynchronizes PyTorch for accurate timing, leveraging CUDA if available, and returns the current time.)r   rv   rw   synchronizetimer   r   r   r   	time_sync   s    

r   
   c                 C   s  g }t |tjst|}tdddddddddddd	d
d	 t | trX| n| gD ]}||}d|_t |tr|n|gD ]T}t|dr||n|}t|drt |tj	r|j
tjkr| n|}dddddg  }}}	z"tj||fddd d d }
W n tk
r&   d}
Y nX zrt|D ]}t |	d< ||}t |	d< z8t |trttdd |D n|  }t |	d< W n" tk
r   td|	d< Y nX ||	d |	d  d | 7 }||	d |	d  d | 7 }q4tj rtj d nd}dd ||fD \}}t |tjrDtdd | D nd}t|d|
d|d|d|dt|d	t|d	 |||
|||||g W n6 tk
r } zt| |d W 5 d}~X Y nX tj  qq^|S )zYOLOv5 speed/memory/FLOPs profiler
    Usage:
        input = torch.randn(16, 3, 640, 640)
        m1 = lambda x: x * torch.sigmoid(x)
        m2 = nn.SiLU()
        profile(input, [m1, m2], n=100)  # profile over 100 iterations
    Paramsz>12sGFLOPszGPU_mem (GB)z>14szforward (ms)zbackward (ms)inputz>24soutputTtohalfr   Finputsverbose    eA   r   c                 s   s   | ]}|  V  qd S r   )sum)r4   yir   r   r   	<genexpr>   s     zprofile.<locals>.<genexpr>nanr0   c                 s   s(   | ] }t |tjrt|jnd V  qdS )r9   N)r<   r   Tensortupleshaper3   r   r   r   r      s     c                 s   s   | ]}|  V  qd S r   numelr3   r   r   r   r      s     12z12.4gz>14.3fz14.4gN)r<   r   r   r   printr9   r   requires_gradr:   r   dtypefloat16r   thopprofilerb   ranger   r   backwardfloatrv   rw   memory_reservedr"   Module
parametersrp   appendempty_cache)r   opsrJ   r   resultsr5   rL   tftbtflops_ymems_ins_outr   er   r   r   r      sN    ,
."


* (:r   c                 C   s   t | tjjtjjfkS )zYChecks if the model is using Data Parallelism (DP) or Distributed Data Parallelism (DDP).)r2   r"   parallelDataParallelr   r-   r   r   r   is_parallel   s    r   c                 C   s   t | r| jS | S )znReturns a single-GPU model by removing Data Parallelism (DP) or Distributed Data Parallelism (DDP) if applied.)r   moduler-   r   r   r   de_parallel   s    r   c                 C   s`   |   D ]R}t|}|tjkr q|tjkr8d|_d|_q|tjtjtj	tj
tjfkrd|_qdS )z|Initializes weights of Conv2d, BatchNorm2d, and activations (Hardswish, LeakyReLU, ReLU, ReLU6, SiLU) in the
    model.
    MbP?gQ?TN)modulesr2   r"   rE   BatchNorm2depsmomentum	Hardswish	LeakyReLUReLUReLU6SiLUinplace)r.   rL   r   r   r   r   initialize_weights   s    

r   c                    s    fddt | jD S )z_Finds and returns list of layer indices in `model.module_list` matching the specified `mclass`.c                    s   g | ]\}}t | r|qS r   )r<   )r4   rN   rL   mclassr   r   r6      s     
 z find_modules.<locals>.<listcomp>)rx   module_list)r.   r   r   r   r   find_modules   s    r   c                 C   s:   d\}}|   D ] }|| 7 }||dk 7 }q|| S )zzCalculates and returns the global sparsity of a model as the ratio of zero-valued parameters to total
    parameters.
    )r   r   r   )r   r   r   )r.   abr   r   r   r   sparsity   s
    r   333333?c                 C   sn   ddl m  m  m} |  D ]0\}}t|tjr |j|d|d ||d q t	
dt| dd dS )zVPrunes Conv2d layers in a model to a specified sparsity using L1 unstructured pruning.r   Nweight)rK   amountzModel pruned to z.3gz global sparsity)Ztorch.nn.utils.pruner"   utilsprunenamed_modulesr<   rE   Zl1_unstructuredremover   r~   r   )r.   r   r   rK   rL   r   r   r   r      s    r   c              
   C   s  t j| j| j| j| j| j| j| jdd	d
| jj}| j | jd}t|jt|j|j }|jt|||jj | jdkrtj| jd| jjdn| j}|j|j|jt|j|j  }|jt||ddd|  |S )	z
    Fuses Conv2d and BatchNorm2d layers into a single Conv2d layer.

    See https://tehnokv.com/posts/fusing-batchnorm-and-conv/.
    T)rH   rI   paddingdilationgroupsr7   Fr   Nr   r   r   )r"   rE   rG   rF   rH   rI   r   r   r   requires_grad_r   r   r   cloneviewr   diagdivsqrtr   running_varcopy_mmr   r7   zerossizemulrunning_meanreshape)convbn	fusedconvw_convw_bnb_convb_bnr   r   r   fuse_conv_and_bn  s,    
 *(&r   F  c                 C   s  t dd |  D }t dd |  D }|rtddddddd	d
dddddddddddd t|  D ]F\}\}}|dd}td|||j| t|j	|
 | f  qzzt|  }t| drtt| j dnd}tjd|j	d ||f|jd}	tjt| |	fddd d d }
t|trB|n||g}d|
|d  | |d  | dd }W n tk
r   d}Y nX t| d!rt| jjd"d#nd$}t| d%tt|   d&| d'| d(| 	 d)S )*z
    Prints model summary including layers, parameters, gradients, and FLOPs; imgsz may be int or list.

    Example: img_size=640 or img_size=[640, 320]
    c                 s   s   | ]}|  V  qd S r   r   r3   r   r   r   r   .  s     zmodel_info.<locals>.<genexpr>c                 s   s   | ]}|j r| V  qd S r   )r   r   r3   r   r   r   r   /  s      layerz>5rf   rK   z>40gradientz>9r   z>12r   z>20muz>10sigmazmodule_list.re   z$%5g %40s %9s %12g %20s %10.3g %10.3grI       r   r   Fr   r   r   r   rm   z.1fz GFLOPs	yaml_fileyolov5ZYOLOv5Modelz
 summary: z	 layers, z parameters, z
 gradientsN) r   r   r   rx   named_parametersrs   r   r   r9   r   meanstdnextr:   maxr\   rI   r   emptyr   r   r   r   r<   rb   r   r   stemr   r~   rC   r   )r.   r   imgszn_pn_grN   rK   r   rI   imr   fsr   r   r   
model_info(  s,    >$""*
$r
        ?r   c                    s   dkr| S | j dd \}}t| t| f}tj| |ddd} |sh fdd||fD \}}tj| d	||d
  d	||d	  gddS )zScales an image tensor `img` of shape (bs,3,y,x) by `ratio`, optionally maintaining the original shape, padded to
    multiples of `gs`.
    r  r   NbilinearF)r   modealign_cornersc                 3   s$   | ]}t |     V  qd S r   )mathceilr3   gsratior   r   r   Q  s     zscale_img.<locals>.<genexpr>r   r   gS㥛?)value)r   r\   Finterpolatepad)imgr  
same_shaper  hwr   r   r  r   	scale_imgG  s    r  r   c                 C   sJ   |j  D ]:\}}t|r"||ks
|ds
||kr8q
q
t| || q
dS )zZCopies attributes from object b to a, optionally filtering with include and exclude lists.r   N)__dict__itemsrC   
startswithrA   )r   r   includeexcludekvr   r   r   	copy_attrU  s    "r$  Adamr   ?h㈵>c                 C   s  g g g f}t dd tj D }|  D ]b}|jddD ]P\}}	|dkrZ|d |	 q:|dkr|t||r||d |	 q:|d |	 q:q*|d	krtj	j
|d ||d
fd}
nz|dkrtj	j|d ||d
fdd}
nT|dkrtj	j|d ||d}
n4|dkrtj	j|d ||dd}
ntd| d|
|d |d |
|d dd ttd dt|
j d| dt|d  dt|d  d| dt|d  d |
S )z
    Initializes YOLOv5 smart optimizer with 3 parameter groups for different decay configurations.

    Groups are 0) weights with decay, 1) weights no decay, 2) biases no decay.
    c                 s   s   | ]\}}d |kr|V  qdS )NormNr   )r4   r"  r#  r   r   r   r   e  s      z"smart_optimizer.<locals>.<genexpr>r   )recurser7   r   r   r   r%  g+?)lrbetasAdamWr   )r*  r+  weight_decayRMSProp)r*  r   SGDT)r*  r   nesterovz
Optimizer z not implemented.)paramsr-  z
optimizer:rf   z(lr=z) with parameter groups z weight(decay=0.0), z weight(decay=z), z bias)r   r"   r  r  r   r   r   r<   r   optimr%  r,  RMSpropr/  NotImplementedErroradd_param_groupr   r~   r   r2   __name__rC   )r.   rK   r*  r   decaygr   r#  p_namer   	optimizerr   r   r   smart_optimizer^  s0    

Nr;  ultralytics/yolov5yolov5sc                 K   sp   t tjdrd|d< t tjdr(d|d< ztjj| |f|W S  tk
rj   tjj| |fddi| Y S X dS )zgYOLOv5 torch.hub.load() wrapper with smart error handling, adjusting torch arguments for compatibility.z1.9.1Tskip_validationr&   
trust_repoforce_reloadN)r   r   r!   hubloadrb   )repor.   kwargsr   r   r   smart_hub_load  s    rE  
yolov5s.pt,  c              	   C   s   d}| d d }| d dk	r2| | d  | d }|rb| drb|j | d    | d |_|r|d	kst| d
| d| dtd| d| d| d ||k rt| d| d  d| d || d 7 }|||fS )zkResumes training from a checkpoint, updating optimizer, ema, and epochs, with optional resume verification.r   epochr   r:  Nbest_fitnessemaupdatesr   z training to zo epochs is finished, nothing to resume.
Start a new training without --resume, i.e. 'python train.py --weights 'zResuming training from z from epoch z to z total epochsz has been trained for z epochs. Fine-tuning for z more epochs.)	load_state_dictgetrJ  r   
state_dictrK  r+   r   r~   )ckptr:  rJ  weightsepochsresumerI  start_epochr   r   r   smart_resume  s"    

 rU  c                   @   s   e Zd ZdddZdd ZdS )EarlyStopping   c                 C   s$   d| _ d| _|ptd| _d| _dS )zjInitializes simple early stopping mechanism for YOLOv5, with adjustable patience for non-improving epochs.r   r   infFN)rI  
best_epochr   patiencepossible_stop)selfrZ  r   r   r   __init__  s    zEarlyStopping.__init__c              	   C   sf   || j kr|| _|| _ || j }|| jd k| _|| jk}|rbtd| j d| j d| j d |S )zaEvaluates if training should stop based on fitness improvement and patience, returning a boolean.r   z;Stopping training early as no improvement observed in last z( epochs. Best results observed at epoch z@, best model saved as best.pt.
To update EarlyStopping(patience=zr) pass a new patience value, i.e. `python train.py --patience 300` or use `--patience 0` to disable EarlyStopping.)rI  rY  rZ  r[  r   r~   )r\  rH  fitnessdeltastopr   r   r   __call__  s    


zEarlyStopping.__call__N)rW  )r6  
__module____qualname__r]  ra  r   r   r   r   rV    s   
rV  c                   @   s,   e Zd ZdZdddZdd ZdddZdS )ModelEMAa#  Updated Exponential Moving Average (EMA) from https://github.com/rwightman/pytorch-image-models
    Keeps a moving average of everything in the model state_dict (parameters and buffers)
    For EMA details see https://www.tensorflow.org/api_docs/python/tf/train/ExponentialMovingAverage
    H.?  r   c                    sF   t t| | _|| _ fdd| _| j D ]}|d q2dS )zInitializes EMA with model parameters, decay rate, tau for decay adjustment, and update count; sets model to
        evaluation mode.
        c                    s    dt |     S )Nr   )r  exp)r5   r7  taur   r   <lambda>      z#ModelEMA.__init__.<locals>.<lambda>FN)r   r   evalrJ  rK  r7  r   r   )r\  r.   r7  ri  rK  r   r   rh  r   r]    s
    zModelEMA.__init__c                 C   sj   |  j d7  _ | | j }t| }| j  D ]0\}}|jjr4||9 }|d| ||   7 }q4dS )z`Updates the Exponential Moving Average (EMA) parameters based on the current model's parameters.r   N)	rK  r7  r   rO  rJ  r  r   is_floating_pointdetach)r\  r.   r   msdr"  r#  r   r   r   update  s    zModelEMA.updater   process_groupreducerc                 C   s   t | j||| dS )zUpdates EMA attributes by copying specified attributes from model to EMA, excluding certain attributes by
        default.
        N)r$  rJ  )r\  r.   r   r!  r   r   r   update_attr  s    zModelEMA.update_attrN)re  rf  r   )r   rq  )r6  rb  rc  __doc__r]  rp  rt  r   r   r   r   rd    s   

rd  )r   )r0   )re   r   T)r   N)r   )Fr   )r  Fr   )r   r   )r%  r   r&  r'  )r<  r=  )NrF  rG  T)Bru  r  rt   rZ   r]   r   warnings
contextlibr   copyr   pathlibr   r   torch.distributeddistributedrR   torch.nnr"   Ztorch.nn.functional
functionalr  Ztorch.nn.parallelr   r,   utils.generalr   r   r   r	   r
   r\   getenvr   r   r   r   ImportErrorfilterwarningsUserWarningr!   r   r%   r/   rO   rT   rd   r   r   r   r   r   r   rE   r   r   r   r   r
  r  r$  r;  rE  rU  rV  rd  r   r   r   r   <module>   sb   
	



%
5
"


	
%

