
    6bip                         S r SSKJs  Jr  SSKJr  SSKJr  SSK	J
r
  SSK	Jr  SSKJr  SSKJr  \" S	\" 5       S
5      r " S S5      r " S S5      r\" S/ S9 " S S\R(                  5      5       rg)z>FeatureSpace structured data preprocessing & encoding utility.    N)backend)
base_layer)
saving_lib)serialization_lib)
LazyLoader)keras_exportlayersztf_keras.src.layersc                   D    \ rS rSrSS jr\S 5       rS r\S 5       r	Sr
g)	Cross   c                 d    US;  a  [        SU 35      e[        U5      U l        X l        X0l        g )N>   intone_hotzdInvalid value for argument `output_mode`. Expected one of {'int', 'one_hot'}. Received: output_mode=)
ValueErrortuplefeature_namescrossing_dimoutput_mode)selfr   r   r   s       Z/home/james-whalen/.local/lib/python3.13/site-packages/tf_keras/src/utils/feature_space.py__init__Cross.__init__    sB    00))47 
 #=1(&    c                 8    SR                  U R                  5      $ )N_X_)joinr   r   s    r   name
Cross.name+   s    zz$,,--r   c                 J    U R                   U R                  U R                  S.$ )Nr   r   r   r!   r   s    r   
get_configCross.get_config/   s'    !// --++
 	
r   c                     U " S0 UD6$ N r&   clsconfigs     r   from_configCross.from_config6       }V}r   )r   r   r   Nr   )__name__
__module____qualname____firstlineno__r   propertyr   r"   classmethodr*   __static_attributes__r&   r   r   r   r      s4    	' . .
  r   r   c                   0    \ rS rSrS rS r\S 5       rSrg)Feature;   c                     US;  a  [        SU 35      eXl        [        U[        5      (       a  [        R
                  " U5      nX l        X0l        g )N>   r   floatr   zmInvalid value for argument `output_mode`. Expected one of {'int', 'one_hot', 'float'}. Received: output_mode=)r   dtype
isinstancedictr   deserialize_keras_objectpreprocessorr   )r   r:   r>   r   s       r   r   Feature.__init__<   s\    99))47 
 
lD)),EEL )&r   c                 r    U R                   [        R                  " U R                  5      U R                  S.$ )Nr:   r>   r   )r:   r   serialize_keras_objectr>   r   r   s    r   r"   Feature.get_configK   s5    ZZ-DD!!  ++
 	
r   c                     U " S0 UD6$ r%   r&   r'   s     r   r*   Feature.from_configT   r,   r   )r:   r   r>   N)	r.   r/   r0   r1   r   r"   r3   r*   r4   r&   r   r   r6   r6   ;   s     '
  r   r6   zkeras.utils.FeatureSpace)v1c                      \ rS rSrSr\S$S j5       r\S 5       r\S%S j5       r\S&S j5       r	\S%S j5       r
\ S'S	 j5       r\    S(S
 j5       r\    S(S j5       r\S)S j5       r\S)S j5       r     S*S jrS rS rS rS rS rS rS rS rS rS rS rS rS rS r\S 5       rS r S r!S  r"S! r#S" r$S#r%g)+FeatureSpaceY   a|  One-stop utility for preprocessing and encoding structured data.

Arguments:
    feature_names: Dict mapping the names of your features to their
        type specification, e.g. `{"my_feature": "integer_categorical"}`
        or `{"my_feature": FeatureSpace.integer_categorical()}`.
        For a complete list of all supported types, see
        "Available feature types" paragraph below.
    output_mode: One of `"concat"` or `"dict"`. In concat mode, all
        features get concatenated together into a single vector.
        In dict mode, the FeatureSpace returns a dict of individually
        encoded features (with the same keys as the input dict keys).
    crosses: List of features to be crossed together, e.g.
        `crosses=[("feature_1", "feature_2")]`. The features will be
        "crossed" by hashing their combined value into
        a fixed-length vector.
    crossing_dim: Default vector size for hashing crossed features.
        Defaults to `32`.
    hashing_dim: Default vector size for hashing features of type
        `"integer_hashed"` and `"string_hashed"`. Defaults to `32`.
    num_discretization_bins: Default number of bins to be used for
        discretizing features of type `"float_discretized"`.
        Defaults to `32`.

**Available feature types:**

Note that all features can be referred to by their string name,
e.g. `"integer_categorical"`. When using the string name, the default
argument values are used.

```python
# Plain float values.
FeatureSpace.float(name=None)

# Float values to be preprocessed via featurewise standardization
# (i.e. via a `keras.layers.Normalization` layer).
FeatureSpace.float_normalized(name=None)

# Float values to be preprocessed via linear rescaling
# (i.e. via a `keras.layers.Rescaling` layer).
FeatureSpace.float_rescaled(scale=1., offset=0., name=None)

# Float values to be discretized. By default, the discrete
# representation will then be one-hot encoded.
FeatureSpace.float_discretized(
    num_bins, bin_boundaries=None, output_mode="one_hot", name=None)

# Integer values to be indexed. By default, the discrete
# representation will then be one-hot encoded.
FeatureSpace.integer_categorical(
    max_tokens=None, num_oov_indices=1, output_mode="one_hot", name=None)

# String values to be indexed. By default, the discrete
# representation will then be one-hot encoded.
FeatureSpace.string_categorical(
    max_tokens=None, num_oov_indices=1, output_mode="one_hot", name=None)

# Integer values to be hashed into a fixed number of bins.
# By default, the discrete representation will then be one-hot encoded.
FeatureSpace.integer_hashed(num_bins, output_mode="one_hot", name=None)

# String values to be hashed into a fixed number of bins.
# By default, the discrete representation will then be one-hot encoded.
FeatureSpace.string_hashed(num_bins, output_mode="one_hot", name=None)
```

Examples:

**Basic usage with a dict of input data:**

```python
raw_data = {
    "float_values": [0.0, 0.1, 0.2, 0.3],
    "string_values": ["zero", "one", "two", "three"],
    "int_values": [0, 1, 2, 3],
}
dataset = tf.data.Dataset.from_tensor_slices(raw_data)

feature_space = FeatureSpace(
    features={
        "float_values": "float_normalized",
        "string_values": "string_categorical",
        "int_values": "integer_categorical",
    },
    crosses=[("string_values", "int_values")],
    output_mode="concat",
)
# Before you start using the FeatureSpace,
# you must `adapt()` it on some data.
feature_space.adapt(dataset)

# You can call the FeatureSpace on a dict of data (batched or unbatched).
output_vector = feature_space(raw_data)
```

**Basic usage with `tf.data`:**

```python
# Unlabeled data
preprocessed_ds = unlabeled_dataset.map(feature_space)

# Labeled data
preprocessed_ds = labeled_dataset.map(lambda x, y: (feature_space(x), y))
```

**Basic usage with the TF-Keras Functional API:**

```python
# Retrieve a dict TF-Keras Input objects
inputs = feature_space.get_inputs()
# Retrieve the corresponding encoded TF-Keras tensors
encoded_features = feature_space.get_encoded_features()
# Build a Functional model
outputs = keras.layers.Dense(1, activation="sigmoid")(encoded_features)
model = keras.Model(inputs, outputs)
```

**Customizing each feature or feature cross:**

```python
feature_space = FeatureSpace(
    features={
        "float_values": FeatureSpace.float_normalized(),
        "string_values": FeatureSpace.string_categorical(max_tokens=10),
        "int_values": FeatureSpace.integer_categorical(max_tokens=10),
    },
    crosses=[
        FeatureSpace.cross(("string_values", "int_values"), crossing_dim=32)
    ],
    output_mode="concat",
)
```

**Returning a dict of integer-encoded features:**

```python
feature_space = FeatureSpace(
    features={
        "string_values": FeatureSpace.string_categorical(output_mode="int"),
        "int_values": FeatureSpace.integer_categorical(output_mode="int"),
    },
    crosses=[
        FeatureSpace.cross(
            feature_names=("string_values", "int_values"),
            crossing_dim=32,
            output_mode="int",
        )
    ],
    output_mode="dict",
)
```

**Specifying your own TF-Keras preprocessing layer:**

```python
# Let's say that one of the features is a short text paragraph that
# we want to encode as a vector (one vector per paragraph) via TF-IDF.
data = {
    "text": ["1st string", "2nd string", "3rd string"],
}

# There's a TF-Keras layer for this: TextVectorization.
custom_layer = layers.TextVectorization(output_mode="tf_idf")

# We can use FeatureSpace.feature to create a custom feature
# that will use our preprocessing layer.
feature_space = FeatureSpace(
    features={
        "text": FeatureSpace.feature(
            preprocessor=custom_layer, dtype="string", output_mode="float"
        ),
    },
    output_mode="concat",
)
feature_space.adapt(tf.data.Dataset.from_tensor_slices(data))
output_vector = feature_space(data)
```

**Retrieving the underlying TF-Keras preprocessing layers:**

```python
# The preprocessing layer of each feature is available in `.preprocessors`.
preprocessing_layer = feature_space.preprocessors["feature1"]

# The crossing layer of each feature cross is available in `.crossers`.
# It's an instance of keras.layers.HashedCrossing.
crossing_layer = feature_space.crossers["feature1_X_feature2"]
```

**Saving and reloading a FeatureSpace:**

```python
feature_space.save("myfeaturespace.keras")
reloaded_feature_space = keras.models.load_model("myfeaturespace.keras")
```
c                     [        XUS9$ )N)r   )r   )r(   r   r   r   s       r   crossFeatureSpace.cross   s    ]kJJr   c                     [        XU5      $ N)r6   )r(   r:   r>   r   s       r   featureFeatureSpace.feature$  s    uK88r   Nc                     SSK Jn  U=(       d    [        R                  " S5      nUR	                  SU S3S9n[        SUSS9$ )Nr   )identityr9   float32_preprocessor)r:   r   rA   )tf_keras.src.layers.corerR   r   unique_object_nameIdentityr6   )r(   r   rR   r>   s       r   r9   FeatureSpace.float(  sQ    5:w11':((TF-"8 ) 
 ,G
 	
r   c                     U=(       d    [         R                  " S5      n[        R                  XU S3S9n[	        SUSS9$ )Nfloat_rescaledrT   )scaleoffsetr   rS   r9   rA   )r   rV   r	   	Rescalingr6   )r(   r[   r\   r   r>   s        r   rZ   FeatureSpace.float_rescaled4  sO    Cw112BC''v]-C ( 
 ,G
 	
r   c                     U=(       d    [         R                  " S5      n[        R                  SU S3S9n[	        SUSS9$ )Nfloat_normalizedrT   )axisr   rS   r9   rA   )r   rV   r	   Normalizationr6   )r(   r   r>   s      r   r`   FeatureSpace.float_normalized>  sO    Ew112DE++TF-0 , 
 ,G
 	
r   c                     U=(       d    [         R                  " S5      n[        R                  UUU S3S9n[	        SXSS9$ )Nfloat_discretizedrT   )num_binsbin_boundariesr   rS   rA   )r   rV   r	   Discretizationr6   )r(   rg   rh   r   r   r>   s         r   rf   FeatureSpace.float_discretizedH  sS     Fw112EF,,)6' - 

 ,
 	
r   c                     U=(       d    [         R                  " S5      n[        R                  U S3UUS9n[	        SXSS9$ )Ninteger_categoricalrT   r   
max_tokensnum_oov_indicesint64rA   )r   rV   r	   IntegerLookupr6   r(   rn   ro   r   r   r>   s         r   rl    FeatureSpace.integer_categoricalV  sS     Hw112GH++6'!+ , 

 
 	
r   c                     U=(       d    [         R                  " S5      n[        R                  U S3UUS9n[	        SXSS9$ )Nstring_categoricalrT   rm   stringrA   )r   rV   r	   StringLookupr6   rr   s         r   ru   FeatureSpace.string_categoricalh  sS     Gw112FG**6'!+ + 

 
 	
r   c                     U=(       d    [         R                  " S5      n[        R                  U S3US9n[	        SXBS9$ )Nstring_hashedrT   r   rg   rv   rA   r   rV   r	   Hashingr6   r(   rg   r   r   r>   s        r   rz   FeatureSpace.string_hashedz  sJ    Bw11/B~~6'( & 
 
 	
r   c                     U=(       d    [         R                  " S5      n[        R                  U S3US9n[	        SXBS9$ )Ninteger_hashedrT   r{   rp   rA   r|   r~   s        r   r   FeatureSpace.integer_hashed  sK    Cw112BC~~6'( & 
 
 	
r   c           	         U(       d  [        S5      eX@l        XPl        X`l        UR	                  5        VVs0 s H  u  pxXpR                  Xx5      _M     snnU l        / U l        U(       a  [        UR                  5       5      n	U H  n
[        U
[        5      (       a  [        R                  " U
5      n
[        U
[        5      (       a  U R                  R                  U
5        M`  U(       d  [        S5      eU
 H  nX;  d  M
  [        SU
 35      e   U R                  R                  [        XS95        M     U R                   V
s0 s H  oR                   U
_M     sn
U l        US;  a  [        SU 35      eX l        U R                  R	                  5        VVs0 s H  u  pxXpR'                  Xx5      _M     snnU l        U R                  R	                  5        VVs0 s H  u  pxXxR*                  _M     snnU l        S U l        U R                   V
s0 s H  oR                   U R1                  U
5      _M      sn
U l        0 U l        SU l        SU l        S U l        S U l        S U l        g s  snnf s  sn
f s  snnf s  snnf s  sn
f )Nz0The `features` argument cannot be None or empty.zzWhen specifying `crosses`, the argument `crossing_dim` (dimensionality of the crossing space) should be specified as well.zwAll features referenced in the `crosses` argument should be present in the `features` dict. Received unknown features: )r   >   r<   concatzdInvalid value for argument `output_mode`. Expected one of {'dict', 'concat'}. Received: output_mode=F) r   r   hashing_dimnum_discretization_binsitems_standardize_featurefeaturescrossessetkeysr;   r<   r   r=   r   appendr   crosses_by_namer   _feature_to_inputinputsr>   preprocessorsencoded_features_cross_to_crossercrossersone_hot_encodersbuilt_is_adaptedr   _preprocessed_features_names_crossed_features_names)r   r   r   r   r   r   r   r   valuefeature_setrK   keys               r   r   FeatureSpace.__init__  sm    OPP(&'>$  (~~/
/ ++D88/
 hmmo.K eT**-FFuMEeU++LL''.'(;   %1",!> ?DW!F#   % LL''e(OP+ !, @D||L|e

E 1|L00))47 
 '  $}}224
4 ((554

 9=8K8K8M
8MD$$$8M
 !%CG<<
CO%JJ..u55<
 !#
 ,0)'+$o
:  M


s   I/	I5I:!J %Jc                 @    [         R                  SUR                  US9$ )N)   )shaper:   r   )r	   Inputr:   r   r   rO   s      r   r   FeatureSpace._feature_to_input  s    ||$gmm$|GGr   c                 2   [        U[        5      (       a  U$ [        U[        5      (       a  [        R                  " U5      $ US:X  a  U R                  US9$ US:X  a  U R                  US9$ US:X  a  U R                  US9$ US:X  a  U R                  XR                  S9$ US:X  a  U R                  US9$ US:X  a  U R                  US9$ US	:X  a  U R                  U R                  US9$ US
:X  a  U R                  U R                  US9$ [        SU 35      e)Nr9   r   r`   rZ   rf   r{   rl   ru   r   rz   zInvalid feature type: )r;   r6   r<   r   r=   r9   r`   rZ   rf   r   rl   ru   r   r   rz   r   r   s      r   r   !FeatureSpace._standardize_feature  sG   gw''Ngt$$$==gFFg::4:((**((d(33((&&D&11++))$@$@ *   --+++66,,***55((&&t'7'7d&CC'%%d&6&6T%BB5gY?@@r   c                 R    [         R                  UR                  UR                  S9$ )Nr   )r	   HashedCrossingr   r   )r   rK   s     r   r   FeatureSpace._cross_to_crosser  s"    $$U%7%7ejj$IIr   c                    / nU R                   R                  5        Hd  nU R                  U   n[        U[        R
                  5      (       a  UR                  b  M@  [        US5      (       d  MS  UR                  U5        Mf     U$ )Nadapt)	r   r   r   r;   r	   rc   
input_meanhasattrr   )r   adaptable_preprocessorsr   r>   s       r   _list_adaptable_preprocessors*FeatureSpace._list_adaptable_preprocessors  sv    "$MM&&(D--d3L ,(<(<==**6|W--'..t4 ) '&r   c                 @  ^ [        U[        R                  R                  5      (       d  [	        SU S[        U5       S35      eU R                  5        H  mUR                  U4S j5      nU R                  T   nUR                  S5       H  nM     WR                  R                  S:X  a  UR                  S5      nUR                  R                  S;   a  UR                  S	 5      nUR                  U5        M     S
U l        U R                  5         S
U l        g )NzE`adapt()` can only be called on a tf.data.Dataset. Received instead: 
 (of type )c                    > U T   $ rN   r&   )xr   s    r   <lambda>$FeatureSpace.adapt.<locals>.<lambda>  s	    AdGr   r   r       >   r   r   c                 0    [         R                  " U S5      $ )Nra   )tfexpand_dims)r   s    r   r   r   !  s    bnnQ3r   T)r;   r   dataDatasetr   typer   mapr   taker   rankbatchr   r   get_encoded_featuresr   )r   datasetfeature_datasetr>   r   r   s        @r   r   FeatureSpace.adapt  s   '277??33%%,IZWaI 
 668D &kk*;<O--d3L %))!, -ww||q "1"7"7";ww||v% #2"5"53# /1 92  !!#
r   c                 :    U R                  5         U R                  $ rN   )_check_if_builtr   r   s    r   
get_inputsFeatureSpace.get_inputs(  s    {{r   c                     U R                  5         U R                  cC  U R                  U R                  5      nU R	                  U5      nU R                  X5      nX0l        U R                  $ rN   )_check_if_adaptedr   _preprocess_featuresr   _cross_features_merge_features)r   preprocessed_featurescrossed_featuresmerged_featuress       r   r   !FeatureSpace.get_encoded_features,  sh       ($($=$=dkk$J!#334IJ"22%O %4!$$$r   c                 x    UR                  5        Vs0 s H  nX R                  U   " X   5      _M     sn$ s  snf rN   )r   r   )r   r   r   s      r   r   !FeatureSpace._preprocess_features8  sD     !
' $$T*8>::'
 	
 
s   !7c                     0 nU R                    HN  nUR                   Vs/ s H  oAU   PM	     nnU R                  UR                     " U5      nXbUR                  '   MP     U$ s  snf rN   )r   r   r   r   )r   r   all_outputsrK   r   r   outputss          r   r   FeatureSpace._cross_features>  sd    \\E161D1DE1Dtn1DFEmmEJJ/7G&-

# "  Fs   A#c                 ^   U R                   (       d<  [        UR                  5       5      U l         [        UR                  5       5      U l        U R                   U R                  -   nU R                    Vs/ s H  nX   PM	     snU R                   Vs/ s H  oBU   PM	     sn-   nU R                  S:X  a  0 nO/ nU R
                  (       a  [        X55       HX  u  pHU R                  R                  US 5      n	U	(       a  U	" U5      nU R                  S:X  a  UWU'   MG  WR                  U5        MZ     U R                  S:X  a  W$ U R                  W5      $ U R                    Vs/ s H  o@R                  U   PM     snU R                   Vs/ s H  o@R                  U   PM     sn-   n
[        X5U
5       GH&  u  pHnUR                  R                  nUR                  S:X  Ga  U R                  R                  U5      =(       d    U R                   R                  U5      nS nUR                  R                  R#                  S5      (       d  [%        SU SU S35      e['        U[(        R*                  [(        R,                  45      (       a  UR/                  5       nO['        U[(        R0                  5      (       a  UR2                  nOw['        U[(        R4                  5      (       a  UR6                  nOK['        U[(        R8                  [(        R:                  45      (       a  UR6                  nO[%        SU S35      eUb*  [(        R1                  USS	9n	XR                  U'   U	" U5      nU R                  S
:X  aX  UR                  R                  nUR#                  S5      (       d  US:X  a  [%        SU SU S35      eWR                  U5        GM!  UWU'   GM)     U R                  S
:X  a)  [(        R=                  SS9U l
        U R                  W5      $ W$ s  snf s  snf s  snf s  snf )Nr<   r   r   z	Feature 'zh' has `output_mode='one_hot'`. Thus its preprocessor should return an int64 dtype. Instead it returns a z dtype.z' has `output_mode='one_hot'`. However it isn't a standard feature and the dimensionality of its output space is not known, thus it cannot be one-hot encoded. Try using `output_mode='int'`.	multi_hot)
num_tokensr   r   rv   z-Cannot concatenate features because feature 'z%' has not been encoded (it has dtype z'). Consider using `output_mode='dict'`.ra   rb   )r   sortedr   r   r   r   zipr   getr   r   r   r   r:   r   r   r   
startswithr   r;   r	   rq   rw   vocabulary_sizeCategoryEncodingr   ri   rg   r   r}   Concatenate)r   r   r   	all_namesr   all_featuresoutput_dictfeatures_to_concatrO   encoder	all_specsspecr:   r>   cardinalitys                  r   r   FeatureSpace._merge_featuresF  s   0006%**,1D- ,22B2G2G2I+JD( --0L0LL 	
 99
9 "'9
 150L0LM0Ld#0LMN
 v%K!#::!$Y!=//33D$?%g.G##v-(/K%&--g6 "> 6)""{{#566
 -1,M,M
,MDMM$,M
 483O3O
3O4  &3O

	
 $'y	#JD4MM&&E9,#1155   -]]&&t,  #}}))44U;;$#D6 *005wg?   6#7#79L9L"M  #/">">"@Kf.E.EFF"."9"9Kf.C.CDD"."7"7K 6#8#8&.."I  #/"7"7K$#D6 *9 9  *$55#.K 6 G 3:))$/%g.G8+**##E**ex.?$Gv N>>CW E?? 
 #))'2$+D!i $Kl x' ,,",5DK;;122u
 N0

s   5PP $P%P*c                 v    U R                   (       d(  U R                  5       (       d  SU l         g [        S5      eg )NTzUYou need to call `.adapt(dataset)` on the FeatureSpace before you can start using it.)r   r   r   r   s    r   r   FeatureSpace._check_if_adapted  s9    5577#'  5 	  r   c                 v    U R                   (       d(  U R                  5         U R                  5         SU l         g g NT)r   r   r   r   s    r   r   FeatureSpace._check_if_built  s-    zz""$%%'DJ	 r   c                    U R                  5         [        U[        5      (       d  [        SU S[	        U5       35      eUR                  5        VVs0 s H  u  p#U[        R                  " U5      _M     nnnSnUR                  5        Hs  u  pVUR                  R                  S:X  a  [        R                  " USS/5      X'   SnM>  UR                  R                  S:X  d  MZ  [        R                  " US5      X'   Mu     U R                  U5      nU R                  U5      nU R                  Xx5      n	U(       a  U R                  S:X  a*  U	R                  S   S:X  d   e[        R                   " U	SS	9$ U	R                  5        HM  u  pVUR                  R                  S
:X  d  M!  UR                  S   S:X  d  M6  [        R                   " USS	9X'   MO     U	$ s  snnf )Nz>A FeatureSpace can only be called with a dict. Received: data=r   Fr   r   Tra   r   r      )r   r;   r<   r   r   r   r   convert_to_tensorr   r   reshaper   r   r   r   r   squeeze)
r   r   r   r   	rebatchedr   r   preprocessed_datacrossed_datamerged_datas
             r   __call__FeatureSpace.__call__  s   $%%""&z$t*? 
 DH::<P<ZSR))%00<P	zz|GDww||q ZZAq62
 	"^^Ar2
 $ !55d;++,=>**+<K8+"((+q000zz+A66*002GDww||q(QWWQZ1_,.JJqq,A)  3 ) Qs   #Gc                     [         R                  " U R                  5      U R                  [         R                  " U R                  5      U R
                  U R                  U R                  S.$ )N)r   r   r   r   r   r   )r   rB   r   r   r   r   r   r   r   s    r   r"   FeatureSpace.get_config  sT    )@@O++(??M --++'+'C'C
 	
r   c                     U " S0 UD6$ r%   r&   r'   s     r   r*   FeatureSpace.from_config  r,   r   c                     U R                   R                  5        VVs0 s H  u  pXR                  R                  5       _M!     snn$ s  snnf rN   )r   r   r>   get_build_configr   s      r   r  FeatureSpace.get_build_config  sJ     "&!4!4!6
!6 &&7799!6
 	
 
s   &Ac                     UR                  5        H-  nU R                  U   R                  R                  X   5        M/     SU l        g r   )r   r   r>   build_from_configr   )r   r)   r   s      r   r  FeatureSpace.build_from_config  s9    KKMDMM$,,>>v|L "r   c                 0    [         R                  " X5        g)zSave the `FeatureSpace` instance to a `.keras` file.

You can reload it via `keras.models.load_model()`:

```python
feature_space.save("myfeaturespace.keras")
reloaded_feature_space = keras.models.load_model("myfeaturespace.keras")
```
N)r   
save_model)r   filepaths     r   saveFeatureSpace.save  s     	d-r   c                     g rN   r&   r   stores     r   save_own_variablesFeatureSpace.save_own_variables       r   c                     g rN   r&   r  s     r   load_own_variablesFeatureSpace.load_own_variables  r  r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r-   rN   )g      ?g        N)Nr   N)Nr   r   N)r   N)r   Nr   r   r   )&r.   r/   r0   r1   __doc__r3   rK   rO   r9   rZ   r`   rf   rl   ru   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r"   r*   r  r  r  r  r  r4   r&   r   r   rH   rH   Y   s   CJ K K 9 9 	
 	
 
 
 
 
 HL
 
  
 
"  
 
" 
 
 
 
  "E,NHA8J'"H
%
dL<
  
 

.r   rH   )r  tensorflow.compat.v2compatv2r   tf_keras.srcr   tf_keras.src.enginer   tf_keras.src.savingr   r    tf_keras.src.utils.generic_utilsr    tensorflow.python.util.tf_exportr   globalsr	   r   r6   LayerrH   r&   r   r   <module>r!     sv    E ! !   * * 1 7 :	Hgi)>	? 8 < (R0j
:## j
 1j
r   