a
    db                     @   s   U d dl mZmZ d dlZd dlmZ d dlm  mZ d dl	m
Z
 i Zeeef ed< ded< ded< d	ed
< G dd dejZG dd dejZdS )    )CallableDictN)KORNIA_CHECK_SHAPEurlsz]https://github.com/DagnyT/hardnet/raw/master/pretrained/pretrained_all_datasets/HardNet++.pthz	hardnet++znhttps://github.com/DagnyT/hardnet/raw/master/pretrained/train_liberty_with_aug/checkpoint_liberty_with_aug.pthliberty_augz/http://cmp.felk.cvut.cz/~mishkdmy/hardnet8v2.pt
hardnet8v2c                       s^   e Zd ZdZdZdedd fddZedej	e
ej	d	d
dZej	ej	dddZ  ZS )HardNeta}  Module, which computes HardNet descriptors of given grayscale patches of 32x32.

    This is based on the original code from paper "Working hard to know your neighbor's
    margins: Local descriptor learning loss". See :cite:`HardNet2017` for more details.

    Args:
        pretrained: Download and set pretrained weights to the model.

    Returns:
        torch.Tensor: HardNet descriptor of the patches.

    Shape:
        - Input: :math:`(B, 1, 32, 32)`
        - Output: :math:`(B, 128)`

    Examples:
        >>> input = torch.rand(16, 1, 32, 32)
        >>> hardnet = HardNet()
        >>> descs = hardnet(input) # 16x128
        FN)
pretrainedreturnc                    sT  t    ttjddddddtjdddt tjddddddtjdddt tjddddddd	tjdddt tjddddddtjdddt tjdd
ddddd	tjd
ddt tjd
d
ddddtjd
ddt tdtjd
d
dddtjd
dd| _|rHdd }t	j
jtd |d}| j|d dd |   d S )N   r	      Fkernel_sizepaddingbiasZaffine@      r   Zstrider   r      333333?   r   r   c                 S   s   | S N Zstoragelocr   r   _/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/feature/hardnet.py<lambda>D       z"HardNet.__init__.<locals>.<lambda>r   Zmap_locationZ
state_dictTstrict)super__init__nn
SequentialConv2dBatchNorm2dReLUDropoutfeaturestorchhubload_state_dict_from_urlr   load_state_dictevalselfr
   Zstorage_fcnZpretrained_dict	__class__r   r   r%   (   s:    
zHardNet.__init__ư>xepsr   c                 C   s,   t j| ddd\}}| |  | |  S z4Utility function that normalizes the input by batch.)T)dimZkeepdimr-   Zstd_meandetachr8   r9   spmpr   r   r   _normalize_inputI   s    zHardNet._normalize_inputinputr   c                 C   sB   t |g d | |}| |}||dd}tj|ddS N)B132rJ   r   r=   r   )r>   )r   rD   r,   viewsizeF	normalize)r3   rF   x_norm
x_featuresZx_outr   r   r   forwardR   s
    

zHardNet.forward)F)r6   )__name__
__module____qualname____doc__
patch_sizeboolr%   staticmethodr-   TensorfloatrD   rQ   __classcell__r   r   r4   r   r      s   !r   c                       sh   e Zd ZdZdZded fddZedd Zede	j
ee	j
d
ddZe	j
e	j
dddZ  ZS )HardNet8aT  Module, which computes HardNet8 descriptors of given grayscale patches of 32x32.

    This is based on the original code from paper "Improving the HardNet Descriptor".
    See :cite:`HardNet2020` for more details.

    Args:
        pretrained: Download and set pretrained weights to the model.

    Returns:
        torch.Tensor: HardNet8 descriptor of the patches.

    Shape:
        - Input: :math:`(B, 1, 32, 32)`
        - Output: :math:`(B, 128)`

    Examples:
        >>> input = torch.rand(16, 1, 32, 32)
        >>> hardnet = HardNet8()
        >>> descs = hardnet(input) # 16x128
    r	   F)r
   c                    s  t    ttjddddddtjdddt tjddddddtjdddt tjddddddd	tjdddt tjddddddtjdddt tjdd
ddddd	tjd
ddt tjd
d
ddddtjd
ddt tjd
dddddtjdddt tdtjdddddtjddd| _| j	| j
 | dtjdd
tjd | dtjdtjd |rdd }tjjtd |d}| j|dd |   d S )Nr   r	   r   Fr   r   r   r   r   r      r   i   r   r   
components)Zdtypemeanc                 S   s   | S r   r   r   r   r   r   r      r    z#HardNet8.__init__.<locals>.<lambda>r   r!   Tr"   )r$   r%   r&   r'   r(   r)   r*   r+   r,   applyweights_initZregister_bufferr-   ZonesrZ   zerosr.   r/   r   r0   r1   r2   r4   r   r   r%   q   sF    
zHardNet8.__init__c                 C   s@   t | tjr<tjj| jjdd | jd ur<tj| jjd d S )Ng333333?)Zgaing{Gz?)	
isinstancer&   r(   initZorthogonal_Zweightdatar   Z	constant_)mr   r   r   ra      s    
zHardNet8.weights_initHz>r7   c                 C   s,   t j| ddd\}}| |  | |  S r:   r?   rA   r   r   r   rD      s    zHardNet8._normalize_inputrE   c                 C   s|   t |g d | |}| |}tjtj| j}tjtj| j}t	
||dd}t|| |}t	j
|ddS rG   )r   rD   r,   r-   ZjitZannotaterY   r_   r^   rM   rN   rK   rL   mm)r3   rF   rO   rP   r_   r^   Zx_prePCAZpcar   r   r   rQ      s    

zHardNet8.forward)F)rg   )rR   rS   rT   rU   rV   rW   r%   rX   ra   r-   rY   rZ   rD   rQ   r[   r   r   r4   r   r\   Z   s   '
r\   )typingr   r   r-   Ztorch.nnr&   Ztorch.nn.functionalZ
functionalrM   Zkornia.testingr   r   str__annotations__Moduler   r\   r   r   r   r   <module>   s   I