o
    iA                     @   s\  d dl mZ d dlZd dlZd dlmZ d dlmZmZm	Z	m
Z
 ejg dddd Zejd	d
gddd Zejg dddd Zejg dddd Zejdd Zejdd Zejdd Zejdd Zejdd Zdd Zd6d d!Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ ZG d,d- d-eZejjd.d/ Z d0d1 Z!d2d3 Z"d4d5 Z#dS )7    )partialN)assert_allclose)LinearNumpyOpsReluchain)      	   )paramsc                 C      | j S Nparamrequest r   X/home/ubuntu/.local/lib/python3.10/site-packages/thinc/tests/layers/test_feed_forward.pynB
      r   r      c                 C   r   r   r   r   r   r   r   nI   r   r   )r         c                 C   r   r   r   r   r   r   r   nH   r   r   )r   r	      r
   c                 C   r   r   r   r   r   r   r   nO   r   r   c                 C      t | | }|S r   )r   
initialize)r   r   modelr   r   r   model1      r    c                 C   r   r   )r   r   )r   r   r   r   r   r   model2$   r!   r"   c                 C   s   t j| |fddd S Nfdtype      ?)numpyones)r   r   r   r   r   
input_data*      r*   c                 C   s   t j| |fddd S r#   )r(   zeros)r   r   r   r   r   gradient_data/   r+   r-   c                 C   s   t | | S r   )r   r   )r    r"   r   r   r   r   4   s   r   c                 C   sd   t  }| }tt||D ]#\}\}}||}|dkr!||dk9 }tj||dgdggd| }q|S )Nr   r   )axes)r   	enumeratezipasarrayr(   	tensordot)r*   Wsbs	numpy_opsXiWbr   r   r   get_expected_predict9   s   
r:   -C6?c                 C   s(   | || }| || }|| d|  S )Nr	   r   )predictweightsepsilonout1out2r   r   r   numeric_gradientD   s   rA   c                 C   s`   |  dj||fksJ |  dj|fksJ | dj||fks#J | dj|fks.J d S )Nr8   r9   )	get_paramshape)r    r"   r   r   r   r   r   r   test_models_have_shapeJ   s   rD   c                 C   s4   |  d| dksJ |  d| dksJ d S )Nr   r   )get_dim)r   r    r"   r   r   r   r   r   r   test_model_shapeQ   s   rF   c                  C   s   t dd} | jdd}| jdd}| dd u sJ | dd u s%J | j||d | ddks5J | ddks>J d S )	N皙?)dropout   r   r	   r   r   )r6   Y)r   opsalloc2fhas_dimr   rE   )r   r6   rJ   r   r   r   test_infer_output_shapeV   s   
rN   c                 C   sl   t ||} | |}| |\}}t|| t||d|dg|d|dg}t||ddd d S )Nr8   r9   g{Gz?r;   atolrtol)r   r<   begin_updater   r:   rB   )r   r    r"   r*   via_predict
via_update_expectedr   r   r   #test_predict_and_begin_update_matcha   s   


rW   c                     s   i  d fdd	} t d}t d}t d}t| d|_t| d|_t| d|_t|t||} r3J |   d s=J  d sCJ  d sIJ d S )Nc                    s   d | < d S )NTr   )namer   r6   rJ   init_was_calledr   r   register_initq   s   z5test_init_functions_are_called.<locals>.register_initr   onetwothree)NN)r   r   initr   r   )r[   layer1layer2layer3r   r   rY   r   test_init_functions_are_calledn   s   rc   c                   @   s   e Zd Zdd Zdd ZdS )GradientSpyc                 C   s   d | _ d | _d S r   r=   	d_weights)selfr   r   r   __init__      
zGradientSpy.__init__c                 C   s   || _ || _d S r   re   )rg   r=   gradr   r   r   __call__   ri   zGradientSpy.__call__N)__name__
__module____qualname__rh   rk   r   r   r   r   rd      s    rd   c                  C   s   t jttfdd} d| d< tt\}}|||   tjD ]$}|jD ]}|	|
 }t||t}t||j| }t||ddd q"qd S )Nfloat32r%   r'   r   rG   rO   )r(   r,   r   r   r   rR   r*   layersparam_namesget_gradravelget_predictget_numeric_gradientsizer   )truthguessbackproplayerrX   agradr<   ngradr   r   r   test_gradient   s   

r}   c                    s    fdd}|S )zHelper for gradient check. To do the numeric gradient check, we have
    to be able to wiggle one value in a parameter, and check the prediction
    before and after. So we need to get a callback that gives an output
    given a change to one weight.
    c                    sp    }|j}| }||   |7  < ||  }||   |8  < || ||S r   )rB   rC   rs   	set_paramreshaper<   )r7   r>   r   rC   outputsinputsrz   
param_namer   r   r<      s   


zget_predict.<locals>.predictr   )rz   r   r   r<   r   r   r   rt      s   rt   c           	      C   sb   t |}t|D ]%}| |d}| |d}t||}t||}|| d ||< td||| q	|S )Nr;   g-C6g-C6*?NGrad)r(   r,   range	_get_lossprint)	r<   ntargetgradientr7   r?   r@   err1err2r   r   r   ru      s   




ru   c              	   C   s    t t dt | |  dS )Ng      ?r   )r(   sumsquare)rw   rx   r   r   r   r      s    r   )r;   )$	functoolsr   r(   pytestnumpy.testingr   	thinc.apir   r   r   r   fixturer   r   r   r   r    r"   r*   r-   r   r:   rA   rD   rF   rN   rW   rc   objectrd   markskipr}   rt   ru   r   r   r   r   r   <module>   sH    










