Shogun187
Shogun187

Reputation: 88

TF Keras - ValueError: No gradients provided for any variable

I am doing a simple TF tutorial but when I try to start training the model, I am getting this error:

ValueError: No gradients provided for any variable: (['dense/kernel:0', 'dense/bias:0', 'dense_1/kernel:0', 'dense_1/bias:0'],). Provided `grads_and_vars` is ((None, <tf.Variable 'dense/kernel:0' shape=(10, 10) dtype=float32>), (None, <tf.Variable 'dense/bias:0' shape=(10,) dtype=float32>), (None, <tf.Variable 'dense_1/kernel:0' shape=(10, 1) dtype=float32>), (None, <tf.Variable 'dense_1/bias:0' shape=(1,) dtype=float32>)).

Any ideas on what the issue might be? I tried changing the model and the parameters on the compile method but none of that seemed to work. I did some research on this issue but could not find anything that resembles this particular exercise.

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Normalization, Dense, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.metrics import MeanAbsoluteError
import pandas as pd
import numpy as np
import seaborn as sns


def get_dataset() -> pd.DataFrame:
    """ Get dataset from the web. """
    url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data'
    cols = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight', 'Acceleration', 'Model Year', 'Origin']
    return pd.read_csv(
        url,
        names=cols,
        na_values='?',
        comment='\t',
        sep=' ',
        skipinitialspace=True
    )


def plot_data_distribution(df: pd.DataFrame):
    return sns.pairplot(df[['MPG', 'Cylinders', 'Displacement', 'Weight']], diag_kind='kde')


def get_normalization_layer(data: np.array) -> Normalization:
    """ Build a normalization layer and adapt it to the features in the dataset. """
    layer = Normalization(axis=-1, input_shape=[10])
    layer.adapt(data)
    return layer


def build_neural_network(normalization_layer: Normalization) -> Sequential:
    """ Build a simple neural network. """
    model = Sequential([
        normalization_layer,
        Dense(10, activation='relu'),
        Dropout(0.2),
        Dense(1, activation='relu')
    ])
    model.compile(
        optimizer=Adam(learning_rate=0.1),
        loss=MeanAbsoluteError(),
        metrics=['accuracy']
    )
    return model


def main():
    """ Run script. """
    # Clean raw data:
    df = get_dataset()
    avg_hp_by_cylinder = df.groupby(['Cylinders']).Horsepower.mean()
    avg_hp_by_cylinder.name = 'avg_hp_by_cylinder'
    df = df.join(avg_hp_by_cylinder, on='Cylinders')
    df.loc[df.Horsepower.isna(), 'Horsepower'] = df.loc[df.Horsepower.isna(), 'avg_hp_by_cylinder']
    df.Origin = df.Origin.map({1: "USA", 2: "Europe", 3: "Japan"})
    df = pd.get_dummies(df, columns=['Origin'], prefix='', prefix_sep='')

    # Split data into Train/Test sets:
    train_df = df.sample(frac=0.8, random_state=69)
    test_df = df.drop(train_df.index)

    # Separate labales from features:
    train_labels = train_df.pop('MPG')
    test_labels = test_df.pop('MPG')

    # Convert dataframes into arrays:
    train_labels = train_labels.values
    test_labels = test_labels.values
    train_df = train_df.values
    test_df = test_df.values

    # Build model and start training:
    EPOCHS = 10
    normalization_layer = get_normalization_layer(train_df)
    model = build_neural_network(normalization_layer)
    training_history = model.fit(x=train_df, y=train_labels, epochs=EPOCHS)

    return {}


if __name__ == "__main__":
    pd.set_option('expand_frame_repr', False)
    main()

Upvotes: 1

Views: 3085

Answers (1)

Innat
Innat

Reputation: 17219

The error is because of using the metric module as a loss function. You should do as follows:

from tensorflow.keras import losses
model.compile(
        optimizer=...,
        loss=losses.MeanAbsoluteError(),
        metrics=..
    )

Also, it seems like a regression problem, if so, the acc for regression metric is not proper to use. Also, the last layer activation is set as relu, whereas probably it should be linear. A better approach you might consider as follows:

model = [
        ...
        Dropout(0.2),
        Dense(1)
    ])

model.compile(
    optimizer='adam',
    loss='mse',
    metrics=[keras.metrics.MeanAbsoluteError()])

Upvotes: 3

Related Questions