configures the model for training example python model compile optimizerkeras optimizers adamlearningrate1e3 losskeras losses binarycrossentropy metrics keras metrics binaryaccuracy keras metrics falsenegatives args optimizer string name of optimizer or optimizer instance see keras optimizers loss loss function may be a string name of loss function or a keras losses loss instance see keras losses a loss function is any callable with the signature loss fnytrue ypred where ytrue are the ground truth values and ypred are the model s predictions ytrue should have shape batchsize d0 dn except in the case of sparse loss functions such as sparse categorical crossentropy which expects integer arrays of shape batchsize d0 dn1 ypred should have shape batchsize d0 dn the loss function should return a float tensor lossweights optional list or dictionary specifying scalar coefficients python floats to weight the loss contributions of different model outputs the loss value that will be minimized by the model will then be the weighted sum of all individual losses weighted by the lossweights coefficients if a list it is expected to have a 1 1 mapping to the model s outputs if a dict it is expected to map output names strings to scalar coefficients metrics list of metrics to be evaluated by the model during training and testing each of this can be a string name of a builtin function function or a keras metrics metric instance see keras metrics typically you will use metrics accuracy a function is any callable with the signature result fnytrue pred to specify different metrics for different outputs of a multioutput model you could also pass a dictionary such as metrics a accuracy b accuracy mse you can also pass a list to specify a metric or a list of metrics for each output such as metrics accuracy accuracy mse or metrics accuracy accuracy mse when you pass the strings accuracy or acc we convert this to one of keras metrics binaryaccuracy keras metrics categoricalaccuracy keras metrics sparsecategoricalaccuracy based on the shapes of the targets and of the model output a similar conversion is done for the strings crossentropy and ce as well the metrics passed here are evaluated without sample weighting if you would like sample weighting to apply you can specify your metrics via the weightedmetrics argument instead weightedmetrics list of metrics to be evaluated and weighted by sampleweight or classweight during training and testing runeagerly bool if true this model s forward pass will never be compiled it is recommended to leave this as false when training for best performance and to set it to true when debugging stepsperexecution int the number of batches to run during each a single compiled function call running multiple batches inside a single compiled function call can greatly improve performance on tpus or small models with a large python overhead at most one full epoch will be run each execution if a number larger than the size of the epoch is passed the execution will be truncated to the size of the epoch note that if stepsperexecution is set to n callback onbatchbegin and callback onbatchend methods will only be called every n batches i e beforeafter each compiled function execution not supported with the pytorch backend jitcompile bool or auto whether to use xla compilation when compiling a model for jax and tensorflow backends jitcompileauto enables xla compilation if the model supports it and disabled otherwise for torch backend auto will default to eager execution and jitcompiletrue will run with torch compile with the inductor backend autoscaleloss bool if true and the model dtype policy is mixedfloat16 the passed optimizer will be automatically wrapped in a lossscaleoptimizer which will dynamically scale the loss to prevent underflow value was never set resolve it now jitcompile auto with the pytorch backend defaults to eager disable xla on cpuonly machines compute the total loss validate it and return it subclasses can optionally override this method to provide custom loss computation logic example python class mymodelmodel def initself args kwargs super initargs kwargs self losstracker metrics meanname loss def computelossself x y ypred sampleweight loss ops meansypred y 2 loss ops sumself losses self losstracker updatestateloss return loss def resetmetricsself self losstracker resetstate property def metricsself return self losstracker inputs layers inputshape10 name myinput outputs layers dense10inputs model mymodelinputs outputs model addlossops sumoutputs optimizer sgd model compileoptimizer loss mse stepsperexecution10 dataset model fitdataset epochs2 stepsperepoch10 printfcustom loss model losstracker result args x input data y target data ypred predictions returned by the model output of modelx sampleweight sample weights for weighting the loss function allowempty if false the method will error out if no loss has been computed by the model if true then if no loss is computed the method returns 0 returns the total loss as a scalar tensor or none if no loss results which is the case when called by model teststep update metric states and collect all metrics to be returned subclasses can optionally override this method to provide custom metric updating and collection logic example python class mymodelsequential def computemetricsself x y ypred sampleweight this super call updates self compiledmetrics and returns results for all metrics listed in self metrics metricresults super computemetrics x y ypred sampleweight note that self custommetric is not listed in self metrics self custommetric updatestatex y ypred sampleweight metricresults metricname self custommetric result return metricresults args x input data y target data ypred predictions returned by the model output of model callx sampleweight sample weights for weighting the loss function returns a dict containing values that will be passed to keras callbacks callbacklist ontrainbatchend typically the values of the metrics listed in self metrics are returned example loss 0 2 accuracy 0 7 returns the model s metrics values as a dict if any of the metric result is a dict containing multiple metrics each of them gets added to the top level returned dict of this method returns a dict containing values of the metrics listed in self metrics example loss 0 2 accuracy 0 7 trains the model for a fixed number of epochs dataset iterations args x input data it could be a numpy array or arraylike or a list of arrays in case the model has multiple inputs a tensor or a list of tensors in case the model has multiple inputs a dict mapping input names to the corresponding arraytensors if the model has named inputs a tf data dataset should return a tuple of either inputs targets or inputs targets sampleweights a keras utils pydataset returning inputs targets or inputs targets sampleweights y target data like the input data x it could be either numpy arrays or backendnative tensors if x is a dataset generator or keras utils pydataset instance y should not be specified since targets will be obtained from x batchsize integer or none number of samples per gradient update if unspecified batchsize will default to 32 do not specify the batchsize if your data is in the form of datasets generators or keras utils pydataset instances since they generate batches epochs integer number of epochs to train the model an epoch is an iteration over the entire x and y data provided unless the stepsperepoch flag is set to something other than none note that in conjunction with initialepoch epochs is to be understood as final epoch the model is not trained for a number of iterations given by epochs but merely until the epoch of index epochs is reached verbose auto 0 1 or 2 verbosity mode 0 silent 1 progress bar 2 one line per epoch auto becomes 1 for most cases note that the progress bar is not particularly useful when logged to a file so verbose2 is recommended when not running interactively e g in a production environment defaults to auto callbacks list of keras callbacks callback instances list of callbacks to apply during training see keras callbacks note keras callbacks progbarlogger and keras callbacks history callbacks are created automatically and need not be passed to model fit keras callbacks progbarlogger is created or not based on the verbose argument in model fit validationsplit float between 0 and 1 fraction of the training data to be used as validation data the model will set apart this fraction of the training data will not train on it and will evaluate the loss and any model metrics on this data at the end of each epoch the validation data is selected from the last samples in the x and y data provided before shuffling this argument is not supported when x is a dataset generator or keras utils pydataset instance if both validationdata and validationsplit are provided validationdata will override validationsplit validationdata data on which to evaluate the loss and any model metrics at the end of each epoch the model will not be trained on this data thus note the fact that the validation loss of data provided using validationsplit or validationdata is not affected by regularization layers like noise and dropout validationdata will override validationsplit validationdata could be a tuple xval yval of numpy arrays or tensors a tuple xval yval valsampleweights of numpy arrays a tf data dataset a python generator or keras utils pydataset returning inputs targets or inputs targets sampleweights shuffle boolean whether to shuffle the training data before each epoch this argument is ignored when x is a generator or a tf data dataset classweight optional dictionary mapping class indices integers to a weight float value used for weighting the loss function during training only this can be useful to tell the model to pay more attention to samples from an underrepresented class when classweight is specified and targets have a rank of 2 or greater either y must be onehot encoded or an explicit final dimension of 1 must be included for sparse class labels sampleweight optional numpy array of weights for the training samples used for weighting the loss function during training only you can either pass a flat 1d numpy array with the same length as the input samples 1 1 mapping between weights and samples or in the case of temporal data you can pass a 2d array with shape samples sequencelength to apply a different weight to every timestep of every sample this argument is not supported when x is a dataset generator or keras utils pydataset instance instead provide the sampleweights as the third element of x note that sample weighting does not apply to metrics specified via the metrics argument in compile to apply sample weighting to your metrics you can specify them via the weightedmetrics in compile instead initialepoch integer epoch at which to start training useful for resuming a previous training run stepsperepoch integer or none total number of steps batches of samples before declaring one epoch finished and starting the next epoch when training with input tensors such as backendnative tensors the default none is equal to the number of samples in your dataset divided by the batch size or 1 if that cannot be determined if x is a tf data dataset and stepsperepoch is none the epoch will run until the input dataset is exhausted when passing an infinitely repeating dataset you must specify the stepsperepoch argument if stepsperepoch1 the training will run indefinitely with an infinitely repeating dataset validationsteps only relevant if validationdata is provided total number of steps batches of samples to draw before stopping when performing validation at the end of every epoch if validationsteps is none validation will run until the validationdata dataset is exhausted in the case of an infinitely repeated dataset it will run into an infinite loop if validationsteps is specified and only part of the dataset will be consumed the evaluation will start from the beginning of the dataset at each epoch this ensures that the same validation samples are used every time validationbatchsize integer or none number of samples per validation batch if unspecified will default to batchsize do not specify the validationbatchsize if your data is in the form of datasets or keras utils pydataset instances since they generate batches validationfreq only relevant if validation data is provided specifies how many training epochs to run before a new validation run is performed e g validationfreq2 runs validation every 2 epochs unpacking behavior for iteratorlike inputs a common pattern is to pass an iterator like object such as a tf data dataset or a keras utils pydataset to fit which will in fact yield not only features x but optionally targets y and sample weights sampleweight keras requires that the output of such iteratorlikes be unambiguous the iterator should return a tuple of length 1 2 or 3 where the optional second and third elements will be used for y and sampleweight respectively any other type provided will be wrapped in a lengthone tuple effectively treating everything as x when yielding dicts they should still adhere to the toplevel tuple structure e g x0 x0 x1 x1 y keras will not attempt to separate features targets and weights from the keys of a single dict a notable unsupported data type is the namedtuple the reason is that it behaves like both an ordered datatype tuple and a mapping datatype dict so given a namedtuple of the form namedtupleexampletuple y x it is ambiguous whether to reverse the order of the elements when interpreting the value even worse is a tuple of the form namedtupleothertuple x y z where it is unclear if the tuple was intended to be unpacked into x y and sampleweight or passed through as a single element to x returns a history object its history history attribute is a record of training loss values and metrics values at successive epochs as well as validation loss values and validation metrics values if applicable returns the loss value metrics values for the model in test mode computation is done in batches see the batchsize arg args x input data it could be a numpy array or arraylike or a list of arrays in case the model has multiple inputs a tensor or a list of tensors in case the model has multiple inputs a dict mapping input names to the corresponding arraytensors if the model has named inputs a tf data dataset should return a tuple of either inputs targets or inputs targets sampleweights a generator or keras utils pydataset returning inputs targets or inputs targets sampleweights y target data like the input data x it could be either numpy arrays or backendnative tensors if x is a tf data dataset or keras utils pydataset instance y should not be specified since targets will be obtained from the iteratordataset batchsize integer or none number of samples per batch of computation if unspecified batchsize will default to 32 do not specify the batchsize if your data is in the form of a dataset generators or keras utils pydataset instances since they generate batches verbose auto 0 1 or 2 verbosity mode 0 silent 1 progress bar 2 single line auto becomes 1 for most cases note that the progress bar is not particularly useful when logged to a file so verbose2 is recommended when not running interactively e g in a production environment defaults to auto sampleweight optional numpy array of weights for the test samples used for weighting the loss function you can either pass a flat 1d numpy array with the same length as the input samples 1 1 mapping between weights and samples or in the case of temporal data you can pass a 2d array with shape samples sequencelength to apply a different weight to every timestep of every sample this argument is not supported when x is a dataset instead pass sample weights as the third element of x steps integer or none total number of steps batches of samples before declaring the evaluation round finished ignored with the default value of none if x is a tf data dataset and steps is none evaluation will run until the dataset is exhausted callbacks list of keras callbacks callback instances list of callbacks to apply during evaluation returndict if true loss and metric results are returned as a dict with each key being the name of the metric if false they are returned as a list returns scalar test loss if the model has a single output and no metrics or list of scalars if the model has multiple outputs andor metrics the attribute model metricsnames will give you the display labels for the scalar outputs generates output predictions for the input samples computation is done in batches this method is designed for batch processing of large numbers of inputs it is not intended for use inside of loops that iterate over your data and process small numbers of inputs at a time for small numbers of inputs that fit in one batch directly use call for faster execution e g modelx or modelx trainingfalse if you have layers such as batchnormalization that behave differently during inference note see this faq entry https keras iogettingstartedfaqwhatsthedifferencebetweenmodelmethodspredictandcall for more details about the difference between model methods predict and call args x input samples it could be a numpy array or arraylike or a list of arrays in case the model has multiple inputs a tensor or a list of tensors in case the model has multiple inputs a tf data dataset a keras utils pydataset instance batchsize integer or none number of samples per batch if unspecified batchsize will default to 32 do not specify the batchsize if your data is in the form of dataset generators or keras utils pydataset instances since they generate batches verbose auto 0 1 or 2 verbosity mode 0 silent 1 progress bar 2 single line auto becomes 1 for most cases note that the progress bar is not particularly useful when logged to a file so verbose2 is recommended when not running interactively e g in a production environment defaults to auto steps total number of steps batches of samples before declaring the prediction round finished ignored with the default value of none if x is a tf data dataset and steps is none predict will run until the input dataset is exhausted callbacks list of keras callbacks callback instances list of callbacks to apply during prediction returns numpy arrays of predictions runs a single gradient update on a single batch of data args x input data must be arraylike y target data must be arraylike sampleweight optional array of the same length as x containing weights to apply to the model s loss for each sample in the case of temporal data you can pass a 2d array with shape samples sequencelength to apply a different weight to every timestep of every sample classweight optional dictionary mapping class indices integers to a weight float to apply to the model s loss for the samples from this class during training this can be useful to tell the model to pay more attention to samples from an underrepresented class when classweight is specified and targets have a rank of 2 or greater either y must be onehot encoded or an explicit final dimension of 1 must be included for sparse class labels returndict if true loss and metric results are returned as a dict with each key being the name of the metric if false they are returned as a list returns a scalar loss value when no metrics and returndictfalse a list of loss and metric values if there are metrics and returndictfalse or a dict of metric and loss values if returndicttrue test the model on a single batch of samples args x input data must be arraylike y target data must be arraylike sampleweight optional array of the same length as x containing weights to apply to the model s loss for each sample in the case of temporal data you can pass a 2d array with shape samples sequencelength to apply a different weight to every timestep of every sample returndict if true loss and metric results are returned as a dict with each key being the name of the metric if false they are returned as a list returns a scalar loss value when no metrics and returndictfalse a list of loss and metric values if there are metrics and returndictfalse or a dict of metric and loss values if returndicttrue returns predictions for a single batch of samples args x input data it must be arraylike returns numpy arrays of predictions returns a serialized config with information for compiling the model this method returns a config dictionary containing all the information optimizer loss metrics etc with which the model was compiled returns a dict containing information for compiling the model compiles the model with the information given in config this method uses the information in the config optimizer loss metrics etc to compile the model args config dict containing information for compiling the model create optimizer variables turns logs dict into a list as per key order of metricsnames metricnames m name for m in self metrics results for name in metricnames if name in logs results appendlogsname for key in sortedlogs keys if key not in metricnames results appendlogskey if lenresults 1 return results0 return results def assertcompilecalledself methodnamenone if not self compiled msg you must call compile before if metricsmodule msg using the model else msg fcalling methodname raise valueerrormsg def modelsupportsjitmodel xla not supported with tf on macos gpu if platform system darwin and arm in platform processor lower if backend backend tensorflow from keras utils moduleutils import tensorflow as tf if tf config listphysicaldevicesgpu return false xla not supported by some layers if allx supportsjit for x in model flattenlayers return true return false configures the model for training example python model compile optimizer keras optimizers adam learning_rate 1e 3 loss keras losses binarycrossentropy metrics keras metrics binaryaccuracy keras metrics falsenegatives args optimizer string name of optimizer or optimizer instance see keras optimizers loss loss function may be a string name of loss function or a keras losses loss instance see keras losses a loss function is any callable with the signature loss fn y_true y_pred where y_true are the ground truth values and y_pred are the model s predictions y_true should have shape batch_size d0 dn except in the case of sparse loss functions such as sparse categorical crossentropy which expects integer arrays of shape batch_size d0 dn 1 y_pred should have shape batch_size d0 dn the loss function should return a float tensor loss_weights optional list or dictionary specifying scalar coefficients python floats to weight the loss contributions of different model outputs the loss value that will be minimized by the model will then be the weighted sum of all individual losses weighted by the loss_weights coefficients if a list it is expected to have a 1 1 mapping to the model s outputs if a dict it is expected to map output names strings to scalar coefficients metrics list of metrics to be evaluated by the model during training and testing each of this can be a string name of a built in function function or a keras metrics metric instance see keras metrics typically you will use metrics accuracy a function is any callable with the signature result fn y_true _pred to specify different metrics for different outputs of a multi output model you could also pass a dictionary such as metrics a accuracy b accuracy mse you can also pass a list to specify a metric or a list of metrics for each output such as metrics accuracy accuracy mse or metrics accuracy accuracy mse when you pass the strings accuracy or acc we convert this to one of keras metrics binaryaccuracy keras metrics categoricalaccuracy keras metrics sparsecategoricalaccuracy based on the shapes of the targets and of the model output a similar conversion is done for the strings crossentropy and ce as well the metrics passed here are evaluated without sample weighting if you would like sample weighting to apply you can specify your metrics via the weighted_metrics argument instead weighted_metrics list of metrics to be evaluated and weighted by sample_weight or class_weight during training and testing run_eagerly bool if true this model s forward pass will never be compiled it is recommended to leave this as false when training for best performance and to set it to true when debugging steps_per_execution int the number of batches to run during each a single compiled function call running multiple batches inside a single compiled function call can greatly improve performance on tpus or small models with a large python overhead at most one full epoch will be run each execution if a number larger than the size of the epoch is passed the execution will be truncated to the size of the epoch note that if steps_per_execution is set to n callback on_batch_begin and callback on_batch_end methods will only be called every n batches i e before after each compiled function execution not supported with the pytorch backend jit_compile bool or auto whether to use xla compilation when compiling a model for jax and tensorflow backends jit_compile auto enables xla compilation if the model supports it and disabled otherwise for torch backend auto will default to eager execution and jit_compile true will run with torch compile with the inductor backend auto_scale_loss bool if true and the model dtype policy is mixed_float16 the passed optimizer will be automatically wrapped in a lossscaleoptimizer which will dynamically scale the loss to prevent underflow value was never set resolve it now jit_compile auto with the pytorch backend defaults to eager disable xla on cpu only machines compute the total loss validate it and return it subclasses can optionally override this method to provide custom loss computation logic example python class mymodel model def __init__ self args kwargs super __init__ args kwargs self loss_tracker metrics mean name loss def compute_loss self x y y_pred sample_weight loss ops means y_pred y 2 loss ops sum self losses self loss_tracker update_state loss return loss def reset_metrics self self loss_tracker reset_state property def metrics self return self loss_tracker inputs layers input shape 10 name my_input outputs layers dense 10 inputs model mymodel inputs outputs model add_loss ops sum outputs optimizer sgd model compile optimizer loss mse steps_per_execution 10 dataset model fit dataset epochs 2 steps_per_epoch 10 print f custom loss model loss_tracker result args x input data y target data y_pred predictions returned by the model output of model x sample_weight sample weights for weighting the loss function allow_empty if false the method will error out if no loss has been computed by the model if true then if no loss is computed the method returns 0 returns the total loss as a scalar tensor or none if no loss results which is the case when called by model test_step the default implementation does not use x update metric states and collect all metrics to be returned subclasses can optionally override this method to provide custom metric updating and collection logic example python class mymodel sequential def compute_metrics self x y y_pred sample_weight this super call updates self compiled_metrics and returns results for all metrics listed in self metrics metric_results super compute_metrics x y y_pred sample_weight note that self custom_metric is not listed in self metrics self custom_metric update_state x y y_pred sample_weight metric_results metric_name self custom_metric result return metric_results args x input data y target data y_pred predictions returned by the model output of model call x sample_weight sample weights for weighting the loss function returns a dict containing values that will be passed to keras callbacks callbacklist on_train_batch_end typically the values of the metrics listed in self metrics are returned example loss 0 2 accuracy 0 7 the default implementation does not use x returns the model s metrics values as a dict if any of the metric result is a dict containing multiple metrics each of them gets added to the top level returned dict of this method returns a dict containing values of the metrics listed in self metrics example loss 0 2 accuracy 0 7 trains the model for a fixed number of epochs dataset iterations args x input data it could be a numpy array or array like or a list of arrays in case the model has multiple inputs a tensor or a list of tensors in case the model has multiple inputs a dict mapping input names to the corresponding array tensors if the model has named inputs a tf data dataset should return a tuple of either inputs targets or inputs targets sample_weights a keras utils pydataset returning inputs targets or inputs targets sample_weights y target data like the input data x it could be either numpy array s or backend native tensor s if x is a dataset generator or keras utils pydataset instance y should not be specified since targets will be obtained from x batch_size integer or none number of samples per gradient update if unspecified batch_size will default to 32 do not specify the batch_size if your data is in the form of datasets generators or keras utils pydataset instances since they generate batches epochs integer number of epochs to train the model an epoch is an iteration over the entire x and y data provided unless the steps_per_epoch flag is set to something other than none note that in conjunction with initial_epoch epochs is to be understood as final epoch the model is not trained for a number of iterations given by epochs but merely until the epoch of index epochs is reached verbose auto 0 1 or 2 verbosity mode 0 silent 1 progress bar 2 one line per epoch auto becomes 1 for most cases note that the progress bar is not particularly useful when logged to a file so verbose 2 is recommended when not running interactively e g in a production environment defaults to auto callbacks list of keras callbacks callback instances list of callbacks to apply during training see keras callbacks note keras callbacks progbarlogger and keras callbacks history callbacks are created automatically and need not be passed to model fit keras callbacks progbarlogger is created or not based on the verbose argument in model fit validation_split float between 0 and 1 fraction of the training data to be used as validation data the model will set apart this fraction of the training data will not train on it and will evaluate the loss and any model metrics on this data at the end of each epoch the validation data is selected from the last samples in the x and y data provided before shuffling this argument is not supported when x is a dataset generator or keras utils pydataset instance if both validation_data and validation_split are provided validation_data will override validation_split validation_data data on which to evaluate the loss and any model metrics at the end of each epoch the model will not be trained on this data thus note the fact that the validation loss of data provided using validation_split or validation_data is not affected by regularization layers like noise and dropout validation_data will override validation_split validation_data could be a tuple x_val y_val of numpy arrays or tensors a tuple x_val y_val val_sample_weights of numpy arrays a tf data dataset a python generator or keras utils pydataset returning inputs targets or inputs targets sample_weights shuffle boolean whether to shuffle the training data before each epoch this argument is ignored when x is a generator or a tf data dataset class_weight optional dictionary mapping class indices integers to a weight float value used for weighting the loss function during training only this can be useful to tell the model to pay more attention to samples from an under represented class when class_weight is specified and targets have a rank of 2 or greater either y must be one hot encoded or an explicit final dimension of 1 must be included for sparse class labels sample_weight optional numpy array of weights for the training samples used for weighting the loss function during training only you can either pass a flat 1d numpy array with the same length as the input samples 1 1 mapping between weights and samples or in the case of temporal data you can pass a 2d array with shape samples sequence_length to apply a different weight to every timestep of every sample this argument is not supported when x is a dataset generator or keras utils pydataset instance instead provide the sample_weights as the third element of x note that sample weighting does not apply to metrics specified via the metrics argument in compile to apply sample weighting to your metrics you can specify them via the weighted_metrics in compile instead initial_epoch integer epoch at which to start training useful for resuming a previous training run steps_per_epoch integer or none total number of steps batches of samples before declaring one epoch finished and starting the next epoch when training with input tensors such as backend native tensors the default none is equal to the number of samples in your dataset divided by the batch size or 1 if that cannot be determined if x is a tf data dataset and steps_per_epoch is none the epoch will run until the input dataset is exhausted when passing an infinitely repeating dataset you must specify the steps_per_epoch argument if steps_per_epoch 1 the training will run indefinitely with an infinitely repeating dataset validation_steps only relevant if validation_data is provided total number of steps batches of samples to draw before stopping when performing validation at the end of every epoch if validation_steps is none validation will run until the validation_data dataset is exhausted in the case of an infinitely repeated dataset it will run into an infinite loop if validation_steps is specified and only part of the dataset will be consumed the evaluation will start from the beginning of the dataset at each epoch this ensures that the same validation samples are used every time validation_batch_size integer or none number of samples per validation batch if unspecified will default to batch_size do not specify the validation_batch_size if your data is in the form of datasets or keras utils pydataset instances since they generate batches validation_freq only relevant if validation data is provided specifies how many training epochs to run before a new validation run is performed e g validation_freq 2 runs validation every 2 epochs unpacking behavior for iterator like inputs a common pattern is to pass an iterator like object such as a tf data dataset or a keras utils pydataset to fit which will in fact yield not only features x but optionally targets y and sample weights sample_weight keras requires that the output of such iterator likes be unambiguous the iterator should return a tuple of length 1 2 or 3 where the optional second and third elements will be used for y and sample_weight respectively any other type provided will be wrapped in a length one tuple effectively treating everything as x when yielding dicts they should still adhere to the top level tuple structure e g x0 x0 x1 x1 y keras will not attempt to separate features targets and weights from the keys of a single dict a notable unsupported data type is the namedtuple the reason is that it behaves like both an ordered datatype tuple and a mapping datatype dict so given a namedtuple of the form namedtuple example_tuple y x it is ambiguous whether to reverse the order of the elements when interpreting the value even worse is a tuple of the form namedtuple other_tuple x y z where it is unclear if the tuple was intended to be unpacked into x y and sample_weight or passed through as a single element to x returns a history object its history history attribute is a record of training loss values and metrics values at successive epochs as well as validation loss values and validation metrics values if applicable returns the loss value metrics values for the model in test mode computation is done in batches see the batch_size arg args x input data it could be a numpy array or array like or a list of arrays in case the model has multiple inputs a tensor or a list of tensors in case the model has multiple inputs a dict mapping input names to the corresponding array tensors if the model has named inputs a tf data dataset should return a tuple of either inputs targets or inputs targets sample_weights a generator or keras utils pydataset returning inputs targets or inputs targets sample_weights y target data like the input data x it could be either numpy array s or backend native tensor s if x is a tf data dataset or keras utils pydataset instance y should not be specified since targets will be obtained from the iterator dataset batch_size integer or none number of samples per batch of computation if unspecified batch_size will default to 32 do not specify the batch_size if your data is in the form of a dataset generators or keras utils pydataset instances since they generate batches verbose auto 0 1 or 2 verbosity mode 0 silent 1 progress bar 2 single line auto becomes 1 for most cases note that the progress bar is not particularly useful when logged to a file so verbose 2 is recommended when not running interactively e g in a production environment defaults to auto sample_weight optional numpy array of weights for the test samples used for weighting the loss function you can either pass a flat 1d numpy array with the same length as the input samples 1 1 mapping between weights and samples or in the case of temporal data you can pass a 2d array with shape samples sequence_length to apply a different weight to every timestep of every sample this argument is not supported when x is a dataset instead pass sample weights as the third element of x steps integer or none total number of steps batches of samples before declaring the evaluation round finished ignored with the default value of none if x is a tf data dataset and steps is none evaluation will run until the dataset is exhausted callbacks list of keras callbacks callback instances list of callbacks to apply during evaluation return_dict if true loss and metric results are returned as a dict with each key being the name of the metric if false they are returned as a list returns scalar test loss if the model has a single output and no metrics or list of scalars if the model has multiple outputs and or metrics the attribute model metrics_names will give you the display labels for the scalar outputs generates output predictions for the input samples computation is done in batches this method is designed for batch processing of large numbers of inputs it is not intended for use inside of loops that iterate over your data and process small numbers of inputs at a time for small numbers of inputs that fit in one batch directly use __call__ for faster execution e g model x or model x training false if you have layers such as batchnormalization that behave differently during inference note see this faq entry https keras io getting_started faq whats the difference between model methods predict and call for more details about the difference between model methods predict and __call__ args x input samples it could be a numpy array or array like or a list of arrays in case the model has multiple inputs a tensor or a list of tensors in case the model has multiple inputs a tf data dataset a keras utils pydataset instance batch_size integer or none number of samples per batch if unspecified batch_size will default to 32 do not specify the batch_size if your data is in the form of dataset generators or keras utils pydataset instances since they generate batches verbose auto 0 1 or 2 verbosity mode 0 silent 1 progress bar 2 single line auto becomes 1 for most cases note that the progress bar is not particularly useful when logged to a file so verbose 2 is recommended when not running interactively e g in a production environment defaults to auto steps total number of steps batches of samples before declaring the prediction round finished ignored with the default value of none if x is a tf data dataset and steps is none predict will run until the input dataset is exhausted callbacks list of keras callbacks callback instances list of callbacks to apply during prediction returns numpy array s of predictions runs a single gradient update on a single batch of data args x input data must be array like y target data must be array like sample_weight optional array of the same length as x containing weights to apply to the model s loss for each sample in the case of temporal data you can pass a 2d array with shape samples sequence_length to apply a different weight to every timestep of every sample class_weight optional dictionary mapping class indices integers to a weight float to apply to the model s loss for the samples from this class during training this can be useful to tell the model to pay more attention to samples from an under represented class when class_weight is specified and targets have a rank of 2 or greater either y must be one hot encoded or an explicit final dimension of 1 must be included for sparse class labels return_dict if true loss and metric results are returned as a dict with each key being the name of the metric if false they are returned as a list returns a scalar loss value when no metrics and return_dict false a list of loss and metric values if there are metrics and return_dict false or a dict of metric and loss values if return_dict true test the model on a single batch of samples args x input data must be array like y target data must be array like sample_weight optional array of the same length as x containing weights to apply to the model s loss for each sample in the case of temporal data you can pass a 2d array with shape samples sequence_length to apply a different weight to every timestep of every sample return_dict if true loss and metric results are returned as a dict with each key being the name of the metric if false they are returned as a list returns a scalar loss value when no metrics and return_dict false a list of loss and metric values if there are metrics and return_dict false or a dict of metric and loss values if return_dict true returns predictions for a single batch of samples args x input data it must be array like returns numpy array s of predictions returns a serialized config with information for compiling the model this method returns a config dictionary containing all the information optimizer loss metrics etc with which the model was compiled returns a dict containing information for compiling the model compiles the model with the information given in config this method uses the information in the config optimizer loss metrics etc to compile the model args config dict containing information for compiling the model create optimizer variables one index the user facing epoch turns logs dict into a list as per key order of metrics_names xla not supported with tf on macos gpu xla not supported by some layers
import platform
import warnings

from keras import backend
from keras import metrics as metrics_module
from keras import ops
from keras import optimizers
from keras.optimizers.loss_scale_optimizer import LossScaleOptimizer
from keras.saving import serialization_lib
from keras.trainers.compile_utils import CompileLoss
from keras.trainers.compile_utils import CompileMetrics
from keras.utils import traceback_utils
from keras.utils import tracking


class Trainer:
    def __init__(self):
        self._lock = False
        self._run_eagerly = False
        self._jit_compile = None
        self.compiled = False
        self.loss = None
        self.steps_per_execution = 1

    @traceback_utils.filter_traceback
    @tracking.no_automatic_dependency_tracking
    def compile(
        self,
        optimizer="rmsprop",
        loss=None,
        loss_weights=None,
        metrics=None,
        weighted_metrics=None,
        run_eagerly=False,
        steps_per_execution=1,
        jit_compile="auto",
        auto_scale_loss=True,
    ):
        
        self.optimizer = optimizers.get(optimizer)
        if (
            auto_scale_loss
            and self.dtype_policy.name == "mixed_float16"
            and self.optimizer
            and not isinstance(self.optimizer, LossScaleOptimizer)
        ):
            self.optimizer = LossScaleOptimizer(
                self.optimizer, name="loss_scale_optimizer"
            )
        if hasattr(self, "output_names"):
            output_names = self.output_names
        else:
            output_names = None
        if loss is not None:
            self._compile_loss = CompileLoss(
                loss, loss_weights, output_names=output_names
            )
            self.loss = loss
        else:
            self._compile_loss = None
        if metrics is not None or weighted_metrics is not None:
            self._compile_metrics = CompileMetrics(
                metrics, weighted_metrics, output_names=output_names
            )
        else:
            self._compile_metrics = None
        if jit_compile == "auto":
            if run_eagerly:
                jit_compile = False
            else:
                jit_compile = self._resolve_auto_jit_compile()
        if jit_compile and run_eagerly:
            jit_compile = False
            warnings.warn(
                "If `run_eagerly` is True, then `jit_compile` "
                "cannot also be True. Disabling `jit_compile`.",
                stacklevel=2,
            )

        self.jit_compile = jit_compile
        self.run_eagerly = run_eagerly
        self.stop_training = False
        self.compiled = True
        self._loss_tracker = metrics_module.Mean(name="loss")
        self.steps_per_execution = steps_per_execution

        self.train_function = None
        self.test_function = None
        self.predict_function = None

        self._compile_config = serialization_lib.SerializableDict(
            optimizer=optimizer,
            loss=loss,
            loss_weights=loss_weights,
            metrics=metrics,
            weighted_metrics=weighted_metrics,
            run_eagerly=run_eagerly,
            steps_per_execution=steps_per_execution,
            jit_compile=jit_compile,
        )

    @property
    def jit_compile(self):
        if self._jit_compile is None:
            
            self._jit_compile = self._resolve_auto_jit_compile()
        return self._jit_compile

    @jit_compile.setter
    def jit_compile(self, value):
        if value and not model_supports_jit(self):
            warnings.warn(
                "Model doesn't support `jit_compile=True`. "
                "Proceeding with `jit_compile=False`."
            )
            self._jit_compile = False
        else:
            self._jit_compile = value

    def _resolve_auto_jit_compile(self):
        if backend.backend() == "torch":
            
            return False

        if backend.backend() == "tensorflow":
            import tensorflow as tf

            devices = tf.config.list_physical_devices()
            if not list(filter(lambda x: x.device_type != "CPU", devices)):
                
                return False

        if model_supports_jit(self):
            return True
        return False

    @property
    def run_eagerly(self):
        return self._run_eagerly

    @run_eagerly.setter
    def run_eagerly(self, value):
        self._run_eagerly = value

    @property
    def metrics(self):
        metrics = [self._loss_tracker] if self.compiled else []
        metrics.extend(self._metrics[:])
        if self.compiled and self._compile_metrics is not None:
            metrics += [self._compile_metrics]
        return metrics

    @property
    def metrics_names(self):
        return [m.name for m in self.metrics]

    @property
    def metrics_variables(self):
        vars = []
        for metric in self.metrics:
            vars.extend(metric.variables)
        return vars

    def reset_metrics(self):
        for m in self.metrics:
            m.reset_state()

    def compute_loss(
        self, x=None, y=None, y_pred=None, sample_weight=None, allow_empty=False
    ):
        
        del x  
        losses = []
        if self._compile_loss is not None:
            loss = self._compile_loss(y, y_pred, sample_weight)
            if loss is not None:
                losses.append(loss)
        for loss in self.losses:
            losses.append(ops.cast(loss, dtype=backend.floatx()))
        if not allow_empty and len(losses) == 0:
            raise ValueError(
                "No loss to compute. Provide a `loss` argument in `compile()`."
            )
        if len(losses) == 1:
            total_loss = losses[0]
        elif len(losses) == 0:
            total_loss = ops.zeros(())
        else:
            total_loss = ops.sum(losses)
        return total_loss

    def compute_metrics(self, x, y, y_pred, sample_weight=None):
        
        del x  
        if self._compile_metrics is not None:
            self._compile_metrics.update_state(y, y_pred, sample_weight)
        return self.get_metrics_result()

    def get_metrics_result(self):
        
        return_metrics = {}
        for metric in self.metrics:
            result = metric.result()
            if isinstance(result, dict):
                return_metrics.update(result)
            else:
                return_metrics[metric.name] = result
        return self._pythonify_logs(return_metrics)

    def fit(
        self,
        x=None,
        y=None,
        batch_size=None,
        epochs=1,
        verbose="auto",
        callbacks=None,
        validation_split=0.0,
        validation_data=None,
        shuffle=True,
        class_weight=None,
        sample_weight=None,
        initial_epoch=0,
        steps_per_epoch=None,
        validation_steps=None,
        validation_batch_size=None,
        validation_freq=1,
    ):
        
        raise NotImplementedError

    def evaluate(
        self,
        x=None,
        y=None,
        batch_size=None,
        verbose="auto",
        sample_weight=None,
        steps=None,
        callbacks=None,
        return_dict=False,
        **kwargs,
    ):
        
        raise NotImplementedError

    def predict(
        self, x, batch_size=None, verbose="auto", steps=None, callbacks=None
    ):
        
        raise NotImplementedError

    def train_on_batch(
        self,
        x,
        y=None,
        sample_weight=None,
        class_weight=None,
        return_dict=False,
    ):
        
        raise NotImplementedError

    def test_on_batch(
        self,
        x,
        y=None,
        sample_weight=None,
        return_dict=False,
    ):
        
        raise NotImplementedError

    def predict_on_batch(self, x):
        
        raise NotImplementedError

    def get_compile_config(self):
        
        if self.compiled and hasattr(self, "_compile_config"):
            return self._compile_config.serialize()

    def compile_from_config(self, config):
        
        has_overridden_compile = self.__class__.compile != Trainer.compile
        if has_overridden_compile:
            warnings.warn(
                "`compile()` was not called as part of model loading "
                "because the model's `compile()` method is custom. "
                "All subclassed Models that have `compile()` "
                "overridden should also override "
                "`get_compile_config()` and `compile_from_config(config)`. "
                "Alternatively, you can "
                "call `compile()` manually after loading.",
                stacklevel=2,
            )
            return
        config = serialization_lib.deserialize_keras_object(config)
        self.compile(**config)
        if hasattr(self, "optimizer") and self.built:
            
            self.optimizer.build(self.trainable_variables)

    def _should_eval(self, epoch, validation_freq):
        epoch = epoch + 1  
        if isinstance(validation_freq, int):
            return epoch % validation_freq == 0
        elif isinstance(validation_freq, list):
            return epoch in validation_freq
        else:
            raise ValueError(
                "Expected `validation_freq` to be a list or int. "
                f"Received: validation_freq={validation_freq} of the "
                f"type {type(validation_freq)}."
            )

    def _pythonify_logs(self, logs):
        result = {}
        for key, value in sorted(logs.items()):
            if isinstance(value, dict):
                result.update(self._pythonify_logs(value))
            else:
                try:
                    value = float(value)
                except:
                    pass
                result[key] = value
        return result

    def _flatten_metrics_in_order(self, logs):
        
        metric_names = [m.name for m in self.metrics]
        results = []
        for name in metric_names:
            if name in logs:
                results.append(logs[name])
        for key in sorted(logs.keys()):
            if key not in metric_names:
                results.append(logs[key])
        if len(results) == 1:
            return results[0]
        return results

    def _assert_compile_called(self, method_name=None):
        if not self.compiled:
            msg = "You must call `compile()` before "
            if metrics_module:
                msg += "using the model."
            else:
                msg += f"calling `{method_name}()`."
            raise ValueError(msg)


def model_supports_jit(model):
    
    if platform.system() == "Darwin" and "arm" in platform.processor().lower():
        if backend.backend() == "tensorflow":
            from keras.utils.module_utils import tensorflow as tf

            if tf.config.list_physical_devices("GPU"):
                return False
    
    if all(x.supports_jit for x in model._flatten_layers()):
        return True
    return False