The split that drives all of training
TF has two fundamentally different containers: tf.constant (immutable) and tf.Variable (mutable). Understanding the difference is essential — the entire training loop is built on top of it.
tf.constant creates a read-only tensor. Perfect for input data, hyperparameters, fixed lookup tables.
tf.Variable is mutable. Its values can be updated in place via assign, assign_add, assign_sub. Critically, tf.Variables are automatically watched by tf.GradientTape, which is what makes gradient-based parameter updates possible.
Every Keras Dense or Conv2D layer's weights are tf.Variables. Every optimizer step calls assign_sub on them. The constant/Variable distinction is exactly the trainable/non-trainable distinction.