setting up last layer in tensoflow for class type of label
Since you're using categorical cross-entropy loss, the last layer (output layer) should come with softmax activation instead of identity (as being blank in layers.Dense(4)).
model = tf.keras.Sequential([
    normalize,
    ...,
    layers.Dense(4, activation=tf.keras.activations.softmax)
])

And SparseCategoricalCrossentropy is different from CategoricalCrossentropy, for categorical cross-entropy, the shape of output and label should be the same, for example:
When using categorical cross-entropy (example labels in one-hot):
Output: [[.1,.0,.9,.0],...] &lt;-- Prediction of 90% for the 3rd class, sum=100%
Label:  [[ 0, 0, 1, 0],...] &lt;-- Third class holds 100% classification possibility

When using sparse categorical cross-entry (labels are class indices):
Output: [[.1,.0,.9,.0],...] &lt;-- Prediction of 90% for the 3rd class, sum=100%
Label:  [[2]          ,...] &lt;-- Third class index is 2