1

I would like to use a custom accuracy function. I would prefer to add the custom object to the model when creating it (not saving the model and loading it again to add the object).

I first load the following libraries:

import pickle
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import gradient_descent_v2
from sklearn.model_selection import train_test_split
from tensorflow import keras
import keras.backend as K
from keras.models import load_model

Then, I define my custom function as below:

def cust_acc(y_true, y_pred):
    acc = ((y_true == y_pred) & (y_true == 0)) | \
          (y_true * y_pred > 0) | \
          ((y_true == 0) & (y_pred < 0)) | \
          ((y_true < 0) & (y_pred == 0))

    return K.sum(acc) / K.size(acc)

Here, I read the input values and define the structure of the NN model:

InstNum = 'Base'                     # Instance number
file = open('Overtime_Prediction_Inst' + str(InstNum) + '.pkl', 'rb')
X, y, inp, b1, b2 = pickle.load(file)
file.close

nL = 3
alpha = 0.01

act = [' ',
       'relu',
       'linear']

nN = [0, 10, 1]

And here is where I normalize the data points and build the model:

scaler = MinMaxScaler()
scaler.fit(X)
nX = scaler.transform(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20)

# define model
term = keras.callbacks.TerminateOnNaN()
model = Sequential()
model.add(Dense(nN[1], input_dim=nN[0], activation=act[1]))
for i in range(2, nL):
    model.add(Dense(nN[i], activation=act[i]))

# compile model
model = load_model(model, custom_objects={'cust_acc': cust_acc})
model.compile(loss='MeanAbsoluteError',
              optimizer=gradient_descent_v2.SGD(learning_rate=0.01, momentum=0.9),
              accuracy=['cust_acc'])
# fit model
history = model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=30, callbacks=[term])
# evaluate the model
train_mse = model.evaluate(X_train, y_train)
test_mse = model.evaluate(X_test, y_test)

But I get an error in line model = load_model(model, custom_objects={'amir_acc': amir_acc}) as follows:

'Unable to load model. Filepath is not an hdf5 file (or h5py is not '
OSError: Unable to load model. Filepath is not an hdf5 file (or h5py is not available) or SavedModel. Received: filepath=<keras.engine.sequential.Sequential object at 0x000001FE209BAD08>

Let me know if you want actual data to be able to reproduce the results. Thanks for the help.

mdslt
  • 155
  • 1
  • 10
  • 1
    You are using load_model in a nonsensical way, it is used to load models from files, not to add custom objects. You do not even need it, you just need to specify your custom accuracy as a metric (with metrics=[cust_acc]), note the lack of quotes as it is not a string, and the parameter to model.compile is not called accuracy – Dr. Snoopy May 24 '22 at 20:13

0 Answers0