o
    i                     @   s  d dl mZmZmZmZmZ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mZ ddlmZmZ ddlmZmZmZmZmZmZ ed	Zed
ZedZededZededZ 	d)de!dede dee"df deee!ef  deegef fddZ#dddedfdedee dee dee dee de!deeef fdd Z$d!eeef ded"e%deeef fd#d$Z&d%d& Z'd'd( Z(dS )*    )AnyCallableDictOptionalTupleTypeTypeVarN   )
tensorflow)Model)TensorFlowShimkeras_model_fnsmaybe_handshake_model)
ArgsKwargsArrayXd)assert_tensorflow_installedconvert_recursiveis_tensorflow_arrayis_xp_arraytensorflow2xpxp2tensorflowInTOutTInFuncXType)boundYTypenameXYinput_shape.compile_argsreturnc                    s<   ddd}du r|ni | fdd}|S )ao  Decorate a custom keras subclassed model with enough information to
    serialize and deserialize it reliably in the face of the many restrictions
    on keras subclassed models.

    name (str): The unique namespace string to use to represent this model class.
    X (Any): A sample X input for performing a forward pass on the network.
    Y (Any): A sample Y input for performing a backward pass on the network.
    input_shape (Tuple[int, ...]): A set of input shapes for building the network.
    compile: Arguments to pass directly to the keras `model.compile` call.

    RETURNS (Callable): The decorated class.
    adammse)	optimizerlossNc                    s   t fdd _t fdd _t fdd _t fdd _t fdd _t fdd} jfd	d
}| _ S )Nc                        S N inst)r   r)   R/home/ubuntu/.local/lib/python3.10/site-packages/thinc/layers/tensorflowwrapper.py<lambda>6       z1keras_subclass.<locals>.call_fn.<locals>.<lambda>c                    r'   r(   r)   r*   )r    r)   r,   r-   7   r.   c                    r'   r(   r)   r*   )r!   r)   r,   r-   8   r.   c                    r'   r(   r)   r*   )r   r)   r,   r-   9   r.   c                    r'   r(   r)   r*   )r   r)   r,   r-   :   r.   c                     s    | i |S r(   r)   )	call_argscall_kwargs)clazzr)   r,   create_component<   s   z9keras_subclass.<locals>.call_fn.<locals>.create_componentc              
      sf    | g|R i | zt | t | W n ty* } ztd| d }~ww t||| _d S )NzIn order to serialize Keras Subclass models, the constructor arguments must be serializable. This allows thinc to recreate the code-based model with the same configuration.
The encountered error is: )srsly
json_dumpsBaseException
ValueErrorr   eg_args)selfargskwargs_err)wrapped_initr)   r,   __init__C   s   
z1keras_subclass.<locals>.call_fn.<locals>.__init__)propertycatalogue_nameeg_shape
eg_compileeg_xeg_yr   r=   )r1   r2   r=   r   r   r!   r    r   )r1   r<   r,   call_fn4   s   zkeras_subclass.<locals>.call_fnr)   )r   r   r   r    r!   compile_defaultsrE   r)   rD   r,   keras_subclass   s   
!rG   r
   tensorflow_modelconvert_inputsconvert_outputsr%   model_class
model_namec                 C   sl   t   t| tjjjsdt|  }t|t| } |du r t	}|du r&t
}||tt| |dg||ddS )zWrap a TensorFlow model, so that it has the same API as Thinc models.
    To optimize the model, you'll need to create a TensorFlow optimizer and call
    optimizer.apply_gradients after each batch.
    z%Expected tf.keras.models.Model, got: N)r%   )rI   rJ   )shimsattrs)r   
isinstancetfkerasmodelsr   typer6   r   _convert_inputs_convert_outputsforwardr   )rH   rI   rJ   r%   rK   rL   errr)   r)   r,   TensorFlowWrapperX   s   rX   modelis_trainc           
         s~   | j d }| j d }| jd }|| ||\} |r!|||\}n|||}|| ||\}dtdtf fdd}	||	fS )zReturn the output of the wrapped TensorFlow model for the given input,
    along with a callback to handle the backward pass.
    rI   rJ   r   dYr"   c                    s   | }|} |S r(   r)   )r[   dY_tensorflowdX_tensorflowget_dXget_dY_tensorflowtensorflow_backpropr)   r,   backprop   s   zforward.<locals>.backprop)rN   rM   r   r   )
rY   r   rZ   rI   rJ   rH   X_tensorflowY_tensorflowr   rb   r)   r^   r,   rV   u   s   



rV   c                    s    fdd}t t||}t|trdd }||fS t|tr+dd }tt |d|fS t|ttfr>dd }t|i d|fS dd }t|fi d|fS )	Nc                    s   t |  dS )N)requires_grad)r   )xrZ   r)   r,   r-      s    z!_convert_inputs.<locals>.<lambda>c                 S      t tt| S r(   r   r   r   )dXtfr)   r)   r,   reverse_conversion      z+_convert_inputs.<locals>.reverse_conversionc                 S      t tt| }|jS r(   )r   r   r   r:   rj   dXr)   r)   r,   rk         )r9   r:   c                 S   rm   r(   r   r   r   r9   rn   r)   r)   r,   rk      rp   c                 S   s   t tt| }|jd S )Nr   rq   rn   r)   r)   r,   rk      s   
)r   r   rO   r   dicttuplelist)rY   r   rZ   xp2tensorflow_	convertedrk   r)   rg   r,   rT      s   

rT   c                 C   s   t tt|}dd }||fS )Nc                 S   rh   r(   )r   r   r   )r[   r)   r)   r,   rk      rl   z,_convert_outputs.<locals>.reverse_conversionri   )rY   YtfrZ   r   rk   r)   r)   r,   rU      s   rU   r(   ))typingr   r   r   r   r   r   r   r3   compatr
   rP   rY   r   rM   r   r   r   typesr   r   utilr   r   r   r   r   r   r   r   r   r   r   strintrG   rX   boolrV   rT   rU   r)   r)   r)   r,   <module>   sb   $ 	

@

* 