
    ijRU                         d dl Z d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZ d d	lmZ  ed
       G d de             Zy)    N)backend)ops)utils)keras_export)Layer)GRU)LSTM)serialization_libzkeras.layers.Bidirectionalc                        e Zd ZdZ	 	 	 d fd	Zd ZddZ	 	 	 ddZddZd Z	ddZ
d	 Zd
 Zd Zed        ZddZd Z fdZedd       Z xZS )Bidirectionala~  Bidirectional wrapper for RNNs.

    Args:
        layer: `keras.layers.RNN` instance, such as
            `keras.layers.LSTM` or `keras.layers.GRU`.
            It could also be a `keras.layers.Layer` instance
            that meets the following criteria:
            1. Be a sequence-processing layer (accepts 3D+ inputs).
            2. Have a `go_backwards`, `return_sequences` and `return_state`
            attribute (with the same semantics as for the `RNN` class).
            3. Have an `input_spec` attribute.
            4. Implement serialization via `get_config()` and `from_config()`.
            Note that the recommended way to create new RNN layers is to write a
            custom RNN cell and use it with `keras.layers.RNN`, instead of
            subclassing `keras.layers.Layer` directly.
            When `return_sequences` is `True`, the output of the masked
            timestep will be zero regardless of the layer's original
            `zero_output_for_mask` value.
        merge_mode: Mode by which outputs of the forward and backward RNNs
            will be combined. One of `{"sum", "mul", "concat", "ave", None}`.
            If `None`, the outputs will not be combined,
            they will be returned as a list. Defaults to `"concat"`.
        backward_layer: Optional `keras.layers.RNN`,
            or `keras.layers.Layer` instance to be used to handle
            backwards input processing.
            If `backward_layer` is not provided, the layer instance passed
            as the `layer` argument will be used to generate the backward layer
            automatically.
            Note that the provided `backward_layer` layer should have properties
            matching those of the `layer` argument, in particular
            it should have the same values for `stateful`, `return_states`,
            `return_sequences`, etc. In addition, `backward_layer`
            and `layer` should have different `go_backwards` argument values.
            A `ValueError` will be raised if these requirements are not met.

    Call arguments:
        The call arguments for this layer are the same as those of the
        wrapped RNN layer. Beware that when passing the `initial_state`
        argument during the call of this layer, the first half in the
        list of elements in the `initial_state` list will be passed to
        the forward RNN call and the last half in the list of elements
        will be passed to the backward RNN call.

    Note: instantiating a `Bidirectional` layer from an existing RNN layer
    instance will not reuse the weights state of the RNN layer instance -- the
    `Bidirectional` layer will have freshly initialized weights.

    Examples:

    ```python
    model = Sequential([
        Input(shape=(5, 10)),
        Bidirectional(LSTM(10, return_sequences=True),
        Bidirectional(LSTM(10)),
        Dense(5, activation="softmax"),
    ])
    model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

    # With custom backward layer
    forward_layer = LSTM(10, return_sequences=True)
    backward_layer = LSTM(10, activation='relu', return_sequences=True,
                          go_backwards=True)
    model = Sequential([
        Input(shape=(5, 10)),
        Bidirectional(forward_layer, backward_layer=backward_layer),
        Dense(5, activation="softmax"),
    ])
    model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
    ```
    c                 V   t        |t              st        d|       |t        |t              st        d|       |dvrt        d| d      t        	|   di | t        j                  |      }dt        j                  |j                  d       |d   d<   t        j                  |      | _        |at        j                  |      }d	|d   d
<   dt        j                  |j                  d       |d   d<   t        j                  |      | _        n|| _        t        |d      r6|j                  | j                  _        |j                  | j                  _        | j                          d } || j                          || j                         || _        |r9t#        |      }|d |dz   | j                  _        ||dz  d  | j                  _        |j&                  | _        |j(                  | _        |j*                  | _        d	| _        |j.                  | _        y )NzXPlease initialize `Bidirectional` layer with a `keras.layers.Layer` instance. Received: zG`backward_layer` need to be a `keras.layers.Layer` instance. Received: )summulaveconcatNzInvalid merge mode. Received: zC. Merge mode should be one of {"sum", "mul", "ave", "concat", None}forward_confignameTgo_backwards	backward_	use_cudnnc                 B    t        | dd       | j                  | _        y y )Nzero_output_for_mask)getattrreturn_sequencesr   )layers    w/var/www/html/emotional.easysim.app/public_html/venv/lib/python3.12/site-packages/keras/src/layers/rnn/bidirectional.pyforce_zero_output_for_maskz:Bidirectional.__init__.<locals>.force_zero_output_for_mask   s&    u4d;G-2-C-C* H        )
isinstancer   
ValueErrorsuper__init__r
   serialize_keras_objectr   removeprefixr   deserialize_keras_objectforward_layerbackward_layerhasattrr   _verify_layer_config
merge_modeleninitial_weightsstatefulr   return_statesupports_masking
input_spec)
selfr   r-   weightsr*   kwargsr   r   nw	__class__s
            r   r%   zBidirectional.__init__V   s8    %'<<A7D  %j.O''5&68  BB0 =8 8 
 	"6" #99%@u))%**jABC 	x  /GGO!&==eDF/3F8^,E..uzz;GHI 8V$ #4"L"L#D #1D5+&+0??D(,1OOD)!!#	D
 	#4#5#56"4#6#67$WB18271CD.29"')2DD/ % 6 6!.. $**r   c           
      n   | j                   j                  | j                  j                  k(  r9t        d| j                   j                   d| j                  j                         d}|D ]H  }t	        | j                   |      }t	        | j                  |      }||k7  s5t        d| d| d| d       y)	zBEnsure the forward and backward layers have valid common property.zrForward layer and backward layer should have different `go_backwards` value. Received: forward_layer.go_backwards z, backward_layer.go_backwards=)r0   r   r1   zTForward layer and backward layer are expected to have the same value for attribute "z", got "z" for forward layer and "z" for backward layerN)r)   r   r*   r#   r   )r4   common_attributesaforward_valuebackward_values        r   r,   z"Bidirectional._verify_layer_config   s    **d.A.A.N.NN. %%223 4/&&3346  M" 		A#D$6$6:M$T%8%8!<N. 556C 8% '&'';= 			r   c                 v   | j                   j                  |      }| j                  r
|d   |dd  }}| j                  dk(  r$t	        |      }|dxx   dz  cc<   t        |      }n| j                  ||g}| j                  r/| j                  t        |      z   |z   S t        |g      z   |z   S t        |      S )Nr      r   r    )r)   compute_output_shaper1   r-   listtuple)r4   sequences_shapeinitial_state_shapeoutput_shapestate_shapes        r   rA   z"Bidirectional.compute_output_shape   s    ))>>O(4Qab9I+L??h&-L! .L__$(,7L&\*[8;FF,(K8KHH\""r   c                 x   | j                  ||      r	 | j                  ||      S | j                  ||      r	 | j	                  ||      S i }| j
                  j                  r||d<   | j
                  j                  r||d<   |||}}t        |      dz  }|d | }	||d  }
n	||}}d\  }	}
 | j
                  |fd|	i|} | j                  |fd|
i|}| j                  rt        |dd  |dd  z         }|d   }|d   }t        j                  || j                        }t        j                  || j                        }| j                  rt        j                   |d      }| j"                  d	k(  rt        j$                  ||gd
      }nl| j"                  dk(  r||z   }nW| j"                  dk(  r	||z   dz  }n?| j"                  dk(  r||z  }n*| j"                  ||f}nt'        d| j"                   d      | j                  r| j"                  |z   S |fz   S |S # t        $ r Y w xY w# t        $ r Y w xY w)Ntrainingmaskr    NNinitial_stater?   r   axisr   r@   r   r   r   /Unrecognized value for `merge_mode`. Received: z0Expected one of {"concat", "sum", "ave", "mul"}.)_can_attempt_fused_lstm_call_fused_lstmNotImplementedError_can_attempt_fused_gru_call_fused_grur)   _call_has_training_arg_call_has_mask_argr.   r*   r1   rC   r   castcompute_dtyper   flipr-   concatenater#   )r4   	sequencesrL   rJ   rI   r6   forward_inputsbackward_inputshalfforward_statebackward_stateyy_revstatesoutputs                  r   callzBidirectional.call   s    ''m<,,YFF &&t];++I}EE 44!)F:00!F6N$
 /8ON}%*D)%40M*451N.7ON,6)M>D
*7
;A
 $##
+9
=C
 1QR559,-F!A!HEHHQ**+ 2 23  HHU+E??h&__aZb9F__%YF__%%i1_F__%YF__$ZF!__-BC 
 &&9v%%A ' 
 ' s"   H H, 	H)(H),	H98H9c                 B   || j                   ry|t        |      dk7  ry| j                  | j                  }}t	        |t
              rt	        |t
              sy|j                  dvry|j                  dvry|j                  j                  s|j                  j                  ry|j                  j                  s|j                  j                  ry|j                  j                  |j                  j                  k7  ry|j                  j                  |j                  j                  ury|j                  j                  |j                  j                  ury|j                  j                  r|j                  j                  sy|j                  r|j                  syy)NF   TautoT)r0   r.   r)   r*   r"   r	   r   celldropoutrecurrent_dropoutunits
activationrecurrent_activationuse_biasbuiltr4   rJ   rL   fwdbwds        r   rP   z%Bidirectional._can_attempt_fused_lstm  s1    t}}$]);q)@%%t':':S#t$JsD,A==.==.88sxx9988sxx9988>>SXX^^+88chh&9&9988((0M0MMxx  (9(9yy		r   c                    | j                   j                  }| j                  j                  }|j                  }t	        j
                  |      }t	        j                  |      d   }|/t	        j                  ||f|j                        }||||f\  }}	}
}n|\  }}	}
}t        j                  |||	|
|d |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  | j                   | j                   j"                        \  }}|\  }}}|\  }}}| j                   r||}}n||}}t	        j$                  || j&                        }t	        j$                  || j&                        }| j(                  dk(  rt	        j*                  ||gd      }nl| j(                  dk(  r||z   }nW| j(                  dk(  r	||z   d	z  }n?| j(                  d
k(  r||z  }n*| j(                  ||f}nt-        d| j(                   d      | j.                  r%t1        ||z         }| j(                  ||z   S |f|z   S |S )Nr   dtype)rJ   
fwd_kernelfwd_recurrent_kernelfwd_bias
bwd_kernelbwd_recurrent_kernelbwd_biasrn   ro   r   unrollr   r@   rM   r   r   r    r   rO   2. Expected one of {"concat", "sum", "ave", "mul"}.)r)   rj   r*   rm   r   convert_to_tensorshapezerosrw   r   bidirectional_lstmkernelrecurrent_kernelbiasrn   ro   r   r~   rW   rX   r-   rZ   r#   r1   rC   )r4   r[   rL   fwd_cellbwd_cellrm   
batch_sizer   fwd_h0fwd_c0bwd_h0bwd_c0fwd_outbwd_outfwd_lastfwd_seq
fwd_statesbwd_lastbwd_seq
bwd_statesra   rb   rd   rc   s                           r   rQ   zBidirectional._call_fused_lstm5  sT   %%**&&++)))4	YYy)!,
 IIz51IE-2E5%-G*FFFF-:*FFFF"55!)!:!:]]!)!:!:]]**!)!>!>!22%%,,!
$ )0%':(/%':  uAuAHHQ**+ 2 23
 ??h&__aZb9F__%YF__%%i1_F__%YF__$ZF!__- .CC  :
23F&&9v%%r   c                    || j                   ry|t        |      dk7  ry| j                  | j                  }}t	        |t
              rt	        |t
              sy|j                  dvry|j                  dvry|j                  j                  s|j                  j                  ry|j                  j                  s|j                  j                  ry|j                  j                  |j                  j                  k7  ry|j                  j                  |j                  j                  ury|j                  j                  |j                  j                  ury|j                  j                  r|j                  j                  sy|j                  j                  r|j                  j                  sy|j                  r|j                  syy)NFr    rh   T)r0   r.   r)   r*   r"   r   r   rj   rk   rl   rm   rn   ro   rp   reset_afterrq   rr   s        r   rS   z$Bidirectional._can_attempt_fused_gru{  sM    t}}$]);q)@%%t':':S#s#:c3+?==.==.88sxx9988sxx9988>>SXX^^+88chh&9&9988((0M0MMxx  (9(9xx##388+?+?yy		r   c                    | j                   j                  }| j                  j                  }|j                  }t	        j
                  |      }t	        j                  |      d   }|(t	        j                  ||f|j                        }||}	}n|\  }}	t        j                  |||	d |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  | j                   | j                   j"                  |j$                        \  }
}|
\  }}}|\  }}}| j                   r||}}n||}}t	        j&                  || j(                        }t	        j&                  || j(                        }| j*                  dk(  rt	        j,                  ||gd      }nl| j*                  dk(  r||z   }nW| j*                  dk(  r	||z   d	z  }n?| j*                  d
k(  r||z  }n*| j*                  ||f}nt/        d| j*                   d      | j0                  r%t3        ||z         }| j*                  ||z   S |f|z   S |S )Nr   rv   )rJ   rx   ry   rz   r{   r|   r}   rn   ro   r   r~   r   r   r@   rM   r   r   r    r   rO   r   )r)   rj   r*   rm   r   r   r   r   rw   r   bidirectional_grur   r   r   rn   ro   r   r~   r   rW   rX   r-   rZ   r#   r1   rC   )r4   r[   rL   r   r   rm   r   r   r   r   r   r   r   r   r   r   r   r   ra   rb   rd   rc   s                         r   rT   zBidirectional._call_fused_gru  sB   %%**&&++)))4	YYy)!,
 IIz51IE"EFF*NFF"44!)!:!:]]!)!:!:]]**!)!>!>!22%%,, ,,
" )0%':(/%':  uAuAHHQ**+ 2 23??h&__aZb9F__%YF__%%i1_F__%YF__$ZF!__- .CC  :
23F&&9v%%r   c                 $    | j                          y N)reset_stater4   s    r   reset_stateszBidirectional.reset_states  s    r   c                     | j                   st        d      | j                  j                          | j                  j                          y )NzLayer must be stateful.)r0   AttributeErrorr)   r   r*   r   s    r   r   zBidirectional.reset_state  s9    }} !:;;&&('')r   c                     | j                   j                  rL| j                  j                  r6t        | j                   j                  | j                  j                  z         S y r   )r)   rc   r*   rC   r   s    r   rc   zBidirectional.states  sJ    $$)<)<)C)C++22T5H5H5O5OOPPr   c                     | j                   j                  s| j                   j                  |       | j                  j                  s| j                  j                  |       y y r   )r)   rq   buildr*   )r4   rD   rE   s      r   r   zBidirectional.build  sM    !!''$$_5""((%%o6 )r   c                 (   t        |t              r|d   }| j                  r| j                  s||f}n|}n| j                  sdnd }| j                  r@| j
                  4d | j
                  D        }t        |t              r||dz  z   S |f|dz  z   S |S )Nr   rK   c              3       K   | ]  }d   y wr   r!   ).0_s     r   	<genexpr>z-Bidirectional.compute_mask.<locals>.<genexpr>  s     41$4s   r    )r"   rB   r   r-   r1   rc   )r4   r   rJ   output_mask
state_masks        r   compute_maskzBidirectional.compute_mask  s    dD!7D  ??#Tl".2oo,4K!844J+t,"Z!^33>JN22r   c                     d| j                   i}t        j                  | j                        |d<   t        j                  | j                        |d<   t
        |          }i ||S )Nr-   r   r*   )r-   r
   r&   r)   r*   r$   
get_config)r4   r   base_configr8   s      r   r   zBidirectional.get_config	  sn    0+BB
w $5#K#K$
  g(*(+(((r   c                     t        j                  |      }t        j                  |d   |      |d<   |j	                  dd       }|t        j                  ||      }||d<    | di |}|S )Nr   )custom_objectsr*   r!   )copydeepcopyr
   r(   pop)clsr   r   backward_layer_configr*   r   s         r   from_configzBidirectional.from_config  s{     v&+DD7ON
w !'

+;T B ,.GG%nN (6F#$fr   )r   NNr   )NNN)__name__
__module____qualname____doc__r%   r,   rA   re   rP   rQ   rS   rT   r   r   propertyrc   r   r   r   classmethodr   __classcell__)r8   s   @r   r   r      s    ET D+L0#, JX DDL"H@D*  
7$	)  r   r   )r   	keras.srcr   r   r   keras.src.api_exportr   keras.src.layers.layerr   keras.src.layers.rnn.grur   keras.src.layers.rnn.lstmr	   keras.src.savingr
   r   r!   r   r   <module>r      sD        - ( ( * . *+WE W ,Wr   