o
    i e                     @   sh  d Z ddlZddlZddlZddlm  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 dd
lmZ dddddddddddddejddfddZejeejdZejeejddZejeejddZdd Z dd Z!	d%ddZ"				d&ddZ#d'ddZ$dd Z%G dd  d ej&Z'G d!d" d"ej&Z(G d#d$ d$ej&Z)dS )(zNPart of the Keras training engine related to Python generators of array data.
    N)backend)	callbacks)training_utils)training_utils_v1)
data_utils)generic_utils)ModeKeys)
tf_logging   
   Fstepsc           +      K   sH  d|v r|d }d}d}t |tjjtjjjjf}|r-|}|du r-d}tj| ||||d}t||||| |d\}}|du}t |t	j
}t|||||||||	 t| ||	d}d}|sft||||
|d\}}t||\}}|rqdnd	}tj|| ||||||||d

}|tjkrtjd|d}ntjd|d}t o| j}|rt|tjkrdnd} |   d|j_|| | ||}t||D ]9}!|jjr n1|    i }"|tjkr|!|!|" |du rt"j#}#n|}#d}$|$|#k rt$|}%|%du r)|r|rd|j_t%&d||| f  n|$dkr|$}||_'nd|j_t%&d||| f  nit(tj)*|%d j+d }|$|d}&|,|d|$|& | j- }'||% }(t |(t.sT|(g}(|$dkro|/|( |'rotj0|| |||||||d	 |1|( |2| |&|(|}&|,|d|$|& |$d7 }$|jjrn|$|#k s|3  |j4})|2| |"|)|}"t5|)dkr|)d })|rt6||!r|jjst7| ||||	|||
||tj8dd}*t |*t.s|*g}*|j2| |"|*|dd}"|tjkr|9|!|" |r|!|d k rtjjj:|}qd| _;|<| |dur|=  |r| >ddd |tjkr"| j?S |)S )a  Loop function for arrays of data with modes TRAIN/TEST/PREDICT.

    Args:
        model: Keras Model instance.
        data: Either a tuple of NumPy/Tensor inputs (i.e. `(x,)` or `(x, y)` or
          `(x, y, sample_weights)`) or a generator or
          `keras.utils.data_utils.Sequence` object or Eager Iterator or Dataset.
        steps_per_epoch: Total number of steps (batches of samples) before
          declaring one epoch finished and starting the next epoch. Ignored with
          the default value of `None`.
        epochs: Number of times to iterate over the data.
        verbose: 0, 1, or 2. Verbosity mode.
          0 = silent, 1 = progress bar, 2 = one line per epoch.
          Note that the progress bar is not particularly useful when
          logged to a file, so verbose=2 is recommended when not running
          interactively (eg, in a production environment).
        callbacks: List of callbacks to be called during training.
        validation_data: Either a tuple of NumPy/Tensor inputs (i.e. `(x,)` or
          `(x, y)` or `(x, y, sample_weights)`) or a generator or
          `keras.utils.data_utils.Sequence` object or Eager Iterator or Dataset.
        validation_steps: Total number of steps (batches of samples) before
          declaring validation finished.
        validation_freq: Only relevant if validation data is provided. Integer
          or `collections.abc.Container` instance (e.g. list, tuple, etc.). If
          an integer, specifies how many training epochs to run before a new
          validation run is performed, e.g. `validation_freq=2` runs validation
          every 2 epochs. If a Container, specifies the epochs on which to run
          validation, e.g. `validation_freq=[1, 2, 10]` runs validation at the
          end of the 1st, 2nd, and 10th epochs.
        class_weight: Dictionary mapping class indices to a weight for the
            class.
        max_queue_size: Integer. Maximum size for the generator queue. If
          unspecified, `max_queue_size` will default to 10.
        workers: Integer. Maximum number of processes to spin up when using
          process-based threading. If unspecified, `workers` will default to 1.
          If 0, will execute the generator on the main thread.
        use_multiprocessing: Boolean. If `True`, use process-based threading. If
          unspecified, `use_multiprocessing` will default to `False`. Note that
          because this implementation relies on multiprocessing, you should not
          pass non-pickleable arguments to the generator as they can't be passed
          easily to children processes.
        shuffle: Boolean. Whether to shuffle the order of the batches at the
          beginning of each epoch. Only used with instances of `Sequence`
          (`keras.utils.Sequence`). Has no effect when `steps_per_epoch` is not
          `None`.
        initial_epoch: Epoch at which to start training (useful for resuming a
          previous training run).
        mode: One of ModeKeys.TRAIN/ModeKeys.TEST/ModeKeys.PREDICT.
        batch_size: Integer batch size or None if unknown. Will only be used if
          `data` is in NumPy/Tensor format.
        steps_name: The string name of the steps argument, either `steps`,
          `validation_steps`, or `steps_per_epoch`. Only used for error message
          formatting.
        **kwargs: Additional arguments for backwards compatibility. `steps` is
          accepted as an alias for `steps_per_epoch`.

    Returns:
        - In TRAIN mode: `History` object.
        - In TEST mode: Evaluation metrics.
        - In PREDICT mode: Outputs of the Model called on inputs.

    Raises:
        ValueError: in case of invalid arguments.
    r   FNT)epochs
steps_name)steps_per_epoch
batch_sizer   shuffleclass_weight)workersuse_multiprocessingmax_queue_sizer   samples)do_validationr   r   r   r   
count_modeverbosemoder   r
   r   zYour dataset ran out of data; interrupting training. Make sure that your dataset can generate at least `%s * epochs` batches (in this case, %d batches). You may need to use the repeat() function when building your dataset.zYour dataset iterator ran out of data; interrupting training. Make sure that your iterator can generate at least `%s * epochs` batches (in this case, %d batches). You may need touse the repeat() function when building your dataset.)batchsizebegin)r   r   r   r   r   r   r   endvalidation_steps)
r   r   r   r   r   r   r   r   r   r   val_)prefix)@
isinstancetfdataDatasetcompatv1r   infer_steps_for_datasetconvert_to_generator_liker   Sequence_validate_arguments_make_execution_function_make_enqueued_generator_get_num_samples_or_stepscbksconfigure_callbacksr   PREDICTOutputsAggregatorMetricsAggregatorexecuting_eagerlyrun_eagerlyr   eager_learning_phase_scopeTRAIN	__enter__modelstop_training_call_begin_hook#_maybe_load_initial_epoch_from_ckptrangereset_metricson_epoch_beginnpinf_get_next_batchloggingwarningr   intnestflattenshape_call_batch_hook_is_compiledlistcreateset_callback_parameters	aggregate	make_logsfinalizeresultslenshould_run_validationmodel_iterationTESTon_epoch_endmake_one_shot_iterator_successful_loop_finish_call_end_hookstop__exit__history)+r;   r&   r   r   r   r   validation_datar!   validation_freqr   r   r   r   r   initial_epochr   r   r   kwargsreset_dataset_after_each_epochoriginal_dataset
is_dataset	generatorr   is_sequencebatch_functionenqueuernum_samples_or_steps	use_stepsr   
aggregatorshould_set_learning_phaselearning_phase_scopeepoch
epoch_logstarget_stepsstep
batch_data
batch_logsis_deferred
batch_outsrS   val_results rx   U/var/www/myenv/lib/python3.10/site-packages/keras/src/engine/training_generator_v1.pyrV   $   s~  U	














P




rV   )r   )r   r   c              	   C   sX   zt | }W n ttjjfy   Y dS w t|ts|f}t|dvr*td	||S )z'Retrieves the next batch of input data.N)r
         zOutput of generator should be a tuple of 1 or 2 or 3 elements: (input,) or (input, target) or (input, target, sample_weights). Received {})
nextStopIterationr%   errorsOutOfRangeErrorr$   tuplerT   
ValueErrorformat)rf   generator_outputrx   rx   ry   rD     s   
rD   c	                 C   s   | s|r|dkrt td |du r&|s&|tjkrdnd}	td|	 dt|p1t|t	j
j}
|
r@t|tjs@|s@tdtd	d
 |D rUtddd |D  dS )aU  Raises errors if arguments are invalid.

    Args:
      is_sequence: Boolean, whether data is a `keras.utils.data_utils.Sequence`
        instance.
      is_dataset: Boolean, whether data is a dataset instance.
      use_multiprocessing: Boolean. If `True`, use process-based threading. If
        unspecified, `use_multiprocessing` will default to `False`. Note that
        because this implementation relies on multiprocessing, you should not
        pass non-pickleable arguments to the generator as they can't be passed
        easily to children processes.
      workers: Integer. Maximum number of processes to spin up when using
        process-based threading. If unspecified, `workers` will default to 1. If
        0, will execute the generator on the main thread.
      steps_per_epoch: Total number of steps (batches of samples) before
        declaring one epoch finished and starting the next epoch. Ignored with
        the default value of `None`.
      validation_data: Either a tuple of NumPy/Tensor inputs (i.e. `(x,)` or
        `(x, y)` or `(x, y, sample_weights)`) or a generator or
        `keras.utils.data_utils.Sequence` object or Eager Iterator or Dataset.
      validation_steps: Total number of steps (batches of samples) before
        declaring validation finished.
      mode: One of ModeKeys.TRAIN/ModeKeys.TEST/ModeKeys.PREDICT.
      kwargs: Additional arguments for backwards compatibility.

    Raises:
      ValueError: If `steps_per_epoch` or `validation_steps` are not passed
        for data types that require them, or if unrecognized keyword
        arguments are passed.
    r
   zUsing a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.Nr   r   z,Please specify the number of steps via the `z` argument.z/Please specify the `validation_steps` argument.c                 s   s    | ]}|d kV  qdS )r   Nrx   .0krx   rx   ry   	<genexpr>      z&_validate_arguments.<locals>.<genexpr>zInvalid arguments passed: c                 S   s   g | ]}|d kr|qS r   rx   r   rx   rx   ry   
<listcomp>  s    z'_validate_arguments.<locals>.<listcomp>)rE   rF   UserWarningr   r9   r   r   is_generator_or_sequencer$   r%   r&   Iteratorr,   any)rg   re   r   r   r   r_   r!   r   rb   arg_nameval_genrx   rx   ry   r-     s8   )	

r-   c                    s   t | trtdd | D } t| st | tjjr,t | tjr(|du r(t| }| |fS t | tjj	r=tj
jj| |fS ttj| d jd  du rRtdtt  } fdd}|| |fS )a  Make a generator out of NumPy or EagerTensor inputs.

    Args:
      data: Either a generator or `keras.utils.data_utils.Sequence` object or
        `Dataset`, `Iterator`, or a {1,2,3}-tuple of NumPy arrays or
        EagerTensors.  If a tuple, the elements represent `(x, y,
        sample_weights)` and may be `None` or `[None]`.
      batch_size: Used when creating a generator out of tuples of NumPy arrays
        or EagerTensors.
      steps_per_epoch: Steps of the generator to run each epoch. If `None` the
        number of steps will be read from the data (for
        `keras.utils.data_utils.Sequence` types).
      epochs: Total number of epochs to run.
      shuffle: Whether the data should be shuffled.

    Returns:
      - Generator, `keras.utils.data_utils.Sequence`, or `Iterator`.

    Raises:
      - ValueError: If `batch_size` is not provided for NumPy or EagerTensor
        inputs.
    c                 s   s.    | ]}t d d tj|D s|V  qdS )c                 s   s    | ]}|d u V  qd S Nrx   )r   erx   rx   ry   r     r   z6convert_to_generator_like.<locals>.<genexpr>.<genexpr>N)allr%   rH   rI   )r   elerx   rx   ry   r     s    
z,convert_to_generator_like.<locals>.<genexpr>Nr   zvWhen passing input data as arrays, do not specify `steps_per_epoch`/`steps` argument. Please use `batch_size` instead.c                 3   s~    t }tD ]2}rt j| t }|D ]\}}||| }tjt	j
| | d}t	j
| |V  qq
dS )z;Makes a generator out of a structure of NumPy/EagerTensors.)
contiguousN)rB   aranger?   randomr   r   make_batchesr   slice_arraysr%   rH   rI   pack_sequence_as)r&   index_array_batchesbatch_start	batch_end	batch_idsflat_batch_datar   r   num_samplesr   rx   ry   _gen  s   
z'convert_to_generator_like.<locals>._gen)r$   r   r   r   r%   r&   r   r,   rT   r'   r(   r)   rY   rG   rH   rI   rJ   r   mathceil)r&   r   r   r   r   r   rx   r   ry   r+     s*   
r+   c                 C   s|   t | tj}d}|dkr-|rtj| ||d}ntj| |d}|j||d | }||fS |r8t| }||fS | }||fS )z:Create a buffered queue of next elements of the generator.Nr   )r   r   )r   )r   r   )r$   r   r,   OrderedEnqueuerGeneratorEnqueuerstartgetiter_sequence_infinite)rf   r   r   r   r   rg   ri   output_generatorrx   rx   ry   r/   &  s(   
r/   c                    s\   |t jkrtj j|d}n|t jkr j}n	d fdd	}|}|t jkr,tj|dd}|S )z2Makes function to run one step of model execution.r   Nc                    s
     | S r   )predict_on_batch)xysample_weightsr;   rx   ry   r   N  s   
z2_make_execution_function.<locals>.predict_on_batchF)r@   )NN)r   r9   	functoolspartialtrain_on_batchrW   test_on_batchr3   )r;   r   r   fr   rx   r   ry   r.   E  s   


r.   c                 C   s8   t j| }t|d drt|d jd dfS |dfS )zLReturns number of samples or steps, and whether to use steps count
    mode.r   rJ   FT)r%   rH   rI   hasattrrG   rJ   )r&   r   flat_inputsrx   rx   ry   r0   Z  s   r0   c                   @   st   e Zd ZdZ																		dd	d
Z										dddZ							dddZdS )GeneratorOrSequenceTrainingLoopzGenerator-like.

    Input is Python generator, or Sequence object.

    The difference between this class and `GeneratorLikeTrainingFunction` is
    that this class only handles inputs that with x, y and sample_weight fused
    into one param.
    Nr
           Tr   r   Fc                 C   sF   | ||| tj|||d t|||||||	|||||||
|ddS )N)validation_splitr   )r   r   r   r   r_   r!   r`   r   r   r   r   r   ra   r   )_validate_or_infer_batch_sizer   check_generator_argumentsfit_generator)selfr;   r   r   r   r   r   r   r   r_   r   r   sample_weightra   r   r!   r`   r   r   r   rx   rx   ry   fitm  s,   z#GeneratorOrSequenceTrainingLoop.fitc              
   C   s2   | ||| t|| t||||||	|
|dS N)r   r   r   r   r   r   )r   r   r   evaluate_generator)r   r;   r   r   r   r   r   r   r   r   r   r   rx   rx   ry   evaluate  s   z(GeneratorOrSequenceTrainingLoop.evaluatec
           
   
   C   s&   | ||| t||||||||	dS r   r   predict_generator)
r   r;   r   r   r   r   r   r   r   r   rx   rx   ry   predict  s   z'GeneratorOrSequenceTrainingLoop.predict)NNNr
   r
   Nr   NTNNr   NNr
   r   r
   F)
NNNr
   NNNr   r
   F)Nr   NNr   r
   F__name__
__module____qualname____doc__r   r   r   rx   rx   rx   ry   r   c  sP    
0
r   c                   @   b   e Zd ZdZ															dddZ							dd	d
Z				dddZdS )"EagerDatasetOrIteratorTrainingLoopz9A non-distributed Dataset or iterator in eager execution.Nr
   r   Tr   c                 K   sj   | ||| t|||| t|tjjjjtjjfr#|
r#t	| t
|||||||	|||d|
|ddS )Nr   r   )r   r   r   r   r_   r!   r`   r   r   r   ra   r   )r   r   validate_dataset_inputr$   r%   r(   r)   r&   r'   verify_dataset_shuffledr   )r   r;   r   r   r   r   r   r   r   r_   r   r   r   ra   r   r!   r`   rb   rx   rx   ry   r     s2   
z&EagerDatasetOrIteratorTrainingLoop.fitc	           
      K   s0   | ||| t||| t||||d|dS Nr   )r   r   r   r   )r   r   r   r   )
r   r;   r   r   r   r   r   r   r   rb   rx   rx   ry   r     s   z+EagerDatasetOrIteratorTrainingLoop.evaluatec                 K   s"   | ||| t||||d|dS r   r   )r   r;   r   r   r   r   r   rb   rx   rx   ry   r     s   
z*EagerDatasetOrIteratorTrainingLoop.predictNNNr
   r
   Nr   NTNNr   NNr
   NNNr
   NNNNr   NNr   rx   rx   rx   ry   r     s>    
3
r   c                   @   r   )GeneratorLikeTrainingLoopaG  TrainingLoop that handle inputs like python generator.

    This is the default handler for most of the input data types, includes
    symbolic tensors or Numpy array-like, Datasets and iterators in graph mode
    (since they generate symbolic tensors). This Function is used to handle
    model with `run_eagerly` = True.
    Nr
   r   Tr   c                 K   s   | |||}|j|||||dd|||
d
\}}}|	r#||	||}	n(|rEd|  k r/dk rEn nt||||\}}}}}}|||f}	n|rKtdt||||f||||||	||d|
|ddS )	NTr   )r   r   r   check_stepsr   r   r   r   r   g      ?zH`validation_steps` should not be specified if `validation_data` is None.r   )r   r   r   r   r   r_   r!   r`   r   r   ra   r   )r   _standardize_user_data_prepare_validation_datar   "split_training_and_validation_datar   r   )r   r;   r   r   r   r   r   r   r   r_   r   r   r   ra   r   r!   r`   rb   r   val_xval_yval_sample_weightsrx   rx   ry   r   7  sf   zGeneratorLikeTrainingLoop.fitc	              	   K   sH   | |||}|j||||dd|d\}}}
t||||
f|||d|dS )NTr   )r   r   r   r   r   r   r   r   r   r   r   )r   r   r   )r   r;   r   r   r   r   r   r   r   rb   r   rx   rx   ry   r     s&   	z"GeneratorLikeTrainingLoop.evaluatec           	   	   K   s<   | |||}|j|dd|d\}}}t|||||d|dS )NTr   )r   r   r   r   r   )r   r   r   )	r   r;   r   r   r   r   r   rb   r   rx   rx   ry   r     s   
z!GeneratorLikeTrainingLoop.predictr   r   r   r   rx   rx   rx   ry   r   .  s>    
O
$r   )NNr
   F)r
   Fr   Fr   )*r   r   r   numpyrB   tensorflow.compat.v2r(   v2r%   	keras.srcr   r   r1   keras.src.enginer   r   keras.src.utilsr   r   keras.src.utils.mode_keysr   tensorflow.python.platformr	   rE   r9   rV   r   r   rW   r   r3   r   rD   r-   r+   r/   r.   r0   TrainingLoopr   r   r   rx   rx   rx   ry   <module>   sj   
  VJ
I

	k`