fit() handles the entire training loop internally: splitting the data into batches, running each batch through the model, computing the loss, backpropagating gradients, and updating weights via the configured optimizer, repeating this for the specified number of epochs, full passes over the training data. Passing validation_data evaluates the model on a separate held-out dataset after each epoch, without using it for training, letting you monitor for overfitting as training progresses. fit() returns a History object recording the loss and metric values from every epoch.
1Understanding model.fit()
fit() handles the entire training loop internally: splitting the data into batches, running each batch through the model, computing the loss, backpropagating gradients, and updating weights via the configured optimizer, repeating this for the specified number of epochs, full passes over the training data. Passing validation_data evaluates the model on a separate held-out dataset after each epoch, without using it for training, letting you monitor for overfitting as training progresses. fit() returns a History object recording the loss and metric values from every epoch.
Always pass a validation_data set to fit() when training for more than a handful of epochs — without it, you have no way to notice overfitting happening as training progresses, since training loss alone keeps improving even after the model stops generalizing.
import tensorflow as tf
import numpy as np
from tensorflow.keras import layers, Sequential
model = Sequential([layers.Dense(1, input_shape=(1,))])
model.compile(optimizer='sgd', loss='mse')
x = np.array([1, 2, 3, 4])
y = np.array([2, 4, 6, 8])
history = model.fit(x, y, epochs=5, verbose=0)
print(len(history.history['loss']))2Practical Example
Here is a real-world application of model.fit() showing how it is used in production TensorFlow code.
import tensorflow as tf
import numpy as np
from tensorflow.keras import layers, Sequential
model = Sequential([layers.Dense(1, input_shape=(1,))])
model.compile(optimizer='sgd', loss='mse')
x_train, y_train = np.array([1, 2, 3, 4]), np.array([2, 4, 6, 8])
x_val, y_val = np.array([5, 6]), np.array([10, 12])
history = model.fit(x_train, y_train, epochs=3, validation_data=(x_val, y_val), verbose=0)
print(list(history.history.keys()))3Best Practices
Follow these guidelines when working with model.fit():
1. Pass validation_data, or validation_split, to fit() so you can monitor for overfitting via validation loss/metrics, not just training loss
2. Store the returned History object and inspect its .history dictionary to plot loss/metric curves after training
3. Use the callbacks argument, such as EarlyStopping, to automatically stop training once validation performance stops improving, rather than guessing a fixed number of epochs
Tip: Always pass a validation_data set to fit() when training for more than a handful of epochs — without it, you have no way to notice overfitting happening as training progresses, since training loss alone keeps improving even after the model stops generalizing.
import tensorflow as tf
import numpy as np
from tensorflow.keras import layers, Sequential
model = Sequential([layers.Dense(1, input_shape=(1,))])
model.compile(optimizer='sgd', loss='mse')
x = np.array([1, 2, 3, 4])
y = np.array([2, 4, 6, 8])
history = model.fit(x, y, epochs=5, verbose=0)
print(len(history.history['loss']))