[FIXED] Keras Model.fit() TypeError: __init__() missing 1 required positional argument: 'normalizer'

Issue

I am attempting to build a sequential model in Keras and use it to do image classification. I am getting the following error in the Anaconda3 (Python 3.9) terminal and haven’t been able to track down the cause:

(tf) >python image_classification.py 10

Building Sequential Model ...

Compiling ...

Fitting Sequential Model with (X_train, Y_train) ...

Epoch 1/10
Traceback (most recent call last):
  File "C:\%\image_classification.py", line 121, in <module>
    high_level_neural_net(X_train, Y_train, X_test, Y_test,  M, Nnodes1, Nnodes2, inject_layer, af, MAKE_PLOTS)
  File "C:\%\image_classification.py", line 67, in high_level_neural_net
    model.fit(x=X_train, y=Y_train, epochs=M)
  File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\utils\traceback_utils.py", line 67, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "C:\%\AppData\Local\Temp\__autograph_generated_filev98m50s2.py", line 15, in tf__train_function
    retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
TypeError: in user code:

    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\training.py", line 1051, in train_function  *
        return step_function(self, iterator)
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\training.py", line 1040, in step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\training.py", line 1030, in run_step  **
        outputs = model.train_step(data)
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\training.py", line 894, in train_step
        return self.compute_metrics(x, y, y_pred, sample_weight)
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\training.py", line 987, in compute_metrics
        self.compiled_metrics.update_state(y, y_pred, sample_weight)
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\compile_utils.py", line 480, in update_state
        self.build(y_pred, y_true)
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\compile_utils.py", line 393, in build
        self._metrics = tf.__internal__.nest.map_structure_up_to(
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\compile_utils.py", line 526, in _get_metric_objects
        return [self._get_metric_object(m, y_t, y_p) for m in metrics]
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\compile_utils.py", line 526, in <listcomp>
        return [self._get_metric_object(m, y_t, y_p) for m in metrics]
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\engine\compile_utils.py", line 545, in _get_metric_object
        metric_obj = metrics_mod.get(metric)
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\metrics\__init__.py", line 182, in get
        return deserialize(str(identifier))
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\metrics\__init__.py", line 138, in deserialize
        return deserialize_keras_object(
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\utils\generic_utils.py", line 718, in deserialize_keras_object
        return obj()
    File "C:\%\Anaconda3\envs\tf\lib\site-packages\keras\dtensor\utils.py", line 141, in _wrap_function
        init_method(instance, *args, **kwargs)

    TypeError: __init__() missing 1 required positional argument: 'normalizer'

So far, I haven’t seen the ‘normalizer’ argument mentioned in the Tensorflow/Keras documentation or on the stackoverflow forums. Here is my source code:

import os
import sys
import math
import scipy as sp
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam
import matplotlib.pyplot as plt

def get_dataset():
    
    SHOW_IMAGE = False

    mnist = tf.keras.datasets.mnist     # 28x28 images of hand-written digits 0-9
    (X_train, Y_train), (X_test, Y_test) = mnist.load_data()
    
    X_train = tf.keras.utils.normalize(X_train,axis=1)  # Normalize input datasets between 0 and 1, Helps the NN converge.
    X_test = tf.keras.utils.normalize(X_test,axis=1)

    if (SHOW_IMAGE):
        plt.imshow(X_train[0])
        plt.show()
        input()
        plt.imshow(Y_train[0])
        plt.show()
        input()

    return X_train, Y_train, X_test, Y_test

def high_level_neural_net(X_train, Y_train, X_test, Y_test, M, Nnodes1, Nnodes2, inject_layer, af, MAKE_PLOTS):
    
    class InjectInputCallback(tf.keras.callbacks.Callback):

        # Inject input data to layer between residual blocks; I'm unsure if this works yet.

        def __init__(self,train_dataset,layer,logs=None):
            self.first_trainds = train_dataset
            self.inject_layer = layer

        def on_layer_end(self,layer,logs=None):
            model.layers[self.inject_layer].output = model.layers[self.inject_layer].output + self.first_trainds
           
    print('\n')
    
    print('Building Sequential Model ...\n')
   
    model = Sequential()
    model.add(Flatten())
    model.add(Dense(Nnodes2, activation=tf.nn.relu))                                   # Residual block 1 (hidden layers) 
    model.add(Dense(Nnodes2, activation=tf.nn.relu))                                   # ...
    model.add(Dense(10, activation=tf.nn.relu))                                         # Output layer of residual block 1/Input layer of residual block 2
    model.add(Dense(Nnodes2, activation=tf.nn.relu))                                   # Residual block 2 (hidden layers)
    model.add(Dense(Nnodes2, activation=tf.nn.relu))                                   # ...
    model.add(Dense(10, activation=tf.nn.relu))                                 # Output layer of residual block 2/Output of neural net 

    print('Compiling ...\n')
    model.compile(optimizer=Adam(learning_rate=0.001),  # Uses Adam algorithm as loss function optimizer
                 loss='MeanSquaredError',                                  # sets the model to use MSE as loss function during training
                 metrics=['MeanRelativeError'])                            
    
    print('Fitting Sequential Model with (X_train, Y_train) ...\n') 
    
    #tf.print('X_train = ', X_train, 'with shape', tf.shape(X_train), '\n')
    #tf.print('Y_train = ', Y_train, 'with shape', tf.shape(Y_train), '\n')

    model.fit(x=X_train, y=Y_train, epochs=M)
    #callbacks=[InjectInputCallback(X_train,inject_layer)]

    if (MAKE_PLOTS):
        plt.plot(history.history['MeanSquareError'])
        plt.title('Model Training')
        plt.ylabel('Mean Squared Error')
        plt.xlabel('Epoch')
        plt.legend(['X_Train','Y_Train'], loc='upper right')
        plt.show()

    #print('Evaluating Sequential Model with Analytic Solution...')
    #model.evaluate()
    
    #print('Predicting')
    #model.predict()

    model.build(tf.shape(X_train)) 
    tf.print(model.summary())

if (__name__ == "__main__"):
 
    print("\n")

    MAKE_PLOTS = True               # Turns on plots during training and evaluation of neural net

    M = int(sys.argv[1])            # Number of training iterations
   
    Ninputs = 3             # Number of node inputs
    Nnodes1 = 10            # Number of nodes in layers
    Nnodes2 = 30            # Number of nodes in 2nd and 4th layers
    inject_layer = 3        # layer of neural net where we inject input data to output of layer

    X_train, Y_train, X_test, Y_test = get_dataset()
    high_level_neural_net(X_train, Y_train, X_test, Y_test,  M, Nnodes1, Nnodes2, inject_layer, af, MAKE_PLOTS)

Solution

As stated here, MeanRelativeError metric needs a required argument called normalizer.
Use it in your compile method like this:

metrics=[tf.keras.metrics.MeanRelativeError(normalizer=[.....])])

The normalizer values should be the same shape as predictions

Answered By – Kaveh

Answer Checked By – Mary Flores (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published