Search code examples
tensorflowkeras

ValueError: Layer 'p_re_lu' expected 1 variables, but received 0 variables during loading


I'm trying to load a model I built containing the PReLU activation function. When accessing the load function I get ValueError: Layer 'p_re_lu' expected 1 variables, but received 0 variables during loading. Expected: ['dense_2/p_re_lu/alpha:0'] as an error message. I have no idea what this means or what I did wrong. Haven't tried anything yet, as I haven't found anything on the internet related to this.

MWE:

import numpy as np
import tensorflow as tf
from tensorflow import keras
from keras import callbacks
import pandas as pd
from sklearn.model_selection import train_test_split

def create_train_model(epoch):
    data = pd.read_csv('data/merge3')
    labels = data.pop('label').to_numpy()

    features = data.to_numpy()
    x_train, x_test, y_train, y_test = train_test_split(features, labels, test_size=0.1)


    output_bias = tf.keras.initializers.Constant(-0.89) # literally guessed

    prelu = tf.keras.layers.PReLU()
    leakyrelu = tf.keras.layers.LeakyReLU()
    model = keras.Sequential([
        keras.layers.InputLayer(input_shape=(8,)),
        keras.layers.Dense(16, activation=leakyrelu),
        keras.layers.Dense(64, activation=prelu),
        keras.layers.Dense(64, activation=prelu),
        keras.layers.Dense(64, activation=prelu),
        keras.layers.Dropout(.2),
        keras.layers.Dense(192, activation=leakyrelu),
        keras.layers.Dense(64, activation=leakyrelu),
        keras.layers.Dense(64, activation=prelu),
        keras.layers.Dense(64, activation=prelu),
        keras.layers.Dense(12, activation=leakyrelu),
        keras.layers.Dense(1, activation='sigmoid', bias_initializer=output_bias),
    ])

    model.compile(optimizer='adam',
                loss='binary_crossentropy', #sparse_categorical_crossentropy
                metrics=['accuracy'])
    earlystopping = callbacks.EarlyStopping(monitor="accuracy",
                                            mode="max", patience=30000,
                                            restore_best_weights=True, start_from_epoch=100000)

    history = model.fit(x_train, y_train, epochs=epoch, batch_size=12288, callbacks=[earlystopping])

    test_loss, test_accuracy = model.evaluate(x_test, y_test)
    print('Test accuracy:', test_accuracy)


    try:
        model.save('models/29_2144.keras')
    except:
        model.save('exception.keras')
    return model

def load_model(path):
    return tf.keras.models.load_model(path)


model = load_model('models/29_2144.keras')


Solution

  • PReLU has parameters, so re-using the same layer object as you are doing comes with some caveats. There are multiple reasons for why this might crash, but I don't think you want to do this either way. You can fix it by creating a separate PReLU object for each layer, like so:

    keras.layers.Dense(64, activation=tf.keras.layers.PReLU()),
    keras.layers.Dense(64, activation=tf.keras.layers.PReLU()),
    etc...
    

    Or just don't use PReLU, it's rather untypical to have different activation functions in different layers anyway.