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')
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.