Add custom objects to a keras model while building it - keras

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.

Related

List object not callable in SVM

I'm trying to run this SVM using stratified K fold in Python,however I keep on getting the error like below
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.utils import shuffle
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import accuracy_score, zero_one_loss, confusion_matrix
import pandas as pd
import numpy as np
z = pd.read_csv('/home/User/datasets/gtzan.csv', header=0)
X = z.iloc[:, :-1]
y = z.iloc[:, -1:]
X = np.array(X)
y = np.array(y)
# Performing standard scaling
scaler = preprocessing.MinMaxScaler()
X_scaled = scaler.fit_transform(X)
# Defining the SVM with 'rbf' kernel
svc = SVC(kernel='rbf', C=100, random_state=50)
#X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.10, shuffle=True)
skf = StratifiedKFold(n_splits=10, shuffle=True)
accuracy_score = []
#skf.get_n_splits(X, y)
for train_index, test_index in skf.split(X, y):
X_train, X_test = X_scaled[train_index], X_scaled[test_index]
y_train, y_test = y[train_index], y[test_index]
# Training the model
svc.fit(X_train, np.ravel(y_train))
# Prediction on test dataste
y_pred = svc.predict(X_test)
# Obtaining the accuracy scores of the model
score = accuracy_score(y_test, y_pred)
accuracy_score.append(score)
# Print the accuarcy of the svm model
print('accuracy score: %0.3f' % np.mean(accuracy_score))
however, it gives me an error like below
Traceback (most recent call last):
File "/home/User/Test_SVM.py", line 55, in <module>
score = accuracy_score(y_test, y_pred)
TypeError: 'list' object is not callable
What makes this score list uncallable and how do I fix this error?
accuracy_scoreis a list in my code and I was also calling the same list as a function, which is overriding the existing functionality of function accuarcy_score. Changed the list name to acc_score which solved the problem.

Keras TimeseriesGenerator: error when checking input

When I try to use the TimeSeriesGenerator function, my Keras LSTM NN starts training for a few moments but then gives a ValueError message. What's wrong? I wonder how it can start training and then get an error.
My similar implementation without this function runs smoothly but then the quality of the predictions are awful (and I'm not sure that this function, once successfully implemented, would make a difference).
See the code below:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Nadam
from tensorflow.keras.layers import Input, LSTM, Dense
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, TerminateOnNaN
from tensorflow.keras.preprocessing.sequence import TimeseriesGenerator
data = pd.read_excel('example.xlsx',usecols=['wave','wind','current','X','Y','RZ'])
data = data.apply(lambda x: (x - np.mean(x)) / np.std(x))
n_cutoff = 200
X = np.array(data.loc[n_cutoff:,['wave','wind']])
Y = np.array(data.loc[n_cutoff:,['RZ']])
X = X.reshape(len(X),2)
X = np.append(X, [[0]*np.size(X, axis=1)], axis=0)
Y = Y.reshape(len(Y),1)
Y = np.insert(Y, 0, 0)
n_lag = 3
n_batch = 15
n = int(0.75*len(X))
generator = TimeseriesGenerator(X, Y, length=n_lag, batch_size=n_batch)
inputs = Input(shape=(n_lag,2))
hidden1 = LSTM(units=100,
activation='softmax',
recurrent_activation='linear',
dropout=0.5,
recurrent_dropout=0.5,
return_sequences=True)(inputs)
hidden2 = LSTM(units=30,
activation='softmax',
recurrent_activation='linear',
dropout=0.5,
recurrent_dropout=0.5,
return_sequences=False)(hidden1)
outputs = Dense(units=1,
activation='linear')(hidden2)
model = Model(inputs=inputs, outputs=outputs)
optimizer = Nadam(learning_rate=1e-2, beta_1=0.95, beta_2=0.9, epsilon=1e-7)
model.compile(loss='mean_squared_error', optimizer=optimizer)
history = model.fit(generator,
verbose=1,
steps_per_epoch=int(n/n_batch),
epochs=1,
shuffle=False,
callbacks=[EarlyStopping(monitor='loss', min_delta=0, patience=20, verbose=1, mode='auto'),
ReduceLROnPlateau(monitor='loss', factor=0.5, patience=10, verbose=1, mode='auto', cooldown=1),
TerminateOnNaN()])
Y_hat = model.predict(X[n:])

How To Do Model Predict Using Distributed Dask With a Pre-Trained Keras Model?

I am loading my pre-trained keras model and then trying to parallelize a large number of input data using dask? Unfortunately, I'm running into some issues with this relating to how I'm creating my dask array. Any guidance would be greatly appreciated!
Setup:
First I cloned from this repo https://github.com/sanchit2843/dlworkshop.git
Reproducible Code Example:
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.model_selection import train_test_split
from keras.models import load_model
import keras
from keras.models import Sequential
from keras.layers import Dense
from dask.distributed import Client
import warnings
import dask.array as DaskArray
warnings.filterwarnings('ignore')
dataset = pd.read_csv('data/train.csv')
X = dataset.drop(['price_range'], axis=1).values
y = dataset[['price_range']].values
# scale data
sc = StandardScaler()
X = sc.fit_transform(X)
ohe = OneHotEncoder()
y = ohe.fit_transform(y).toarray()
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2)
# Neural network
model = Sequential()
model.add(Dense(16, input_dim=20, activation="relu"))
model.add(Dense(12, activation="relu"))
model.add(Dense(4, activation="softmax"))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=100, batch_size=64)
# Use dask
client = Client()
def load_and_predict(input_data_chunk):
def contrastive_loss(y_true, y_pred):
margin = 1
square_pred = K.square(y_pred)
margin_square = K.square(K.maximum(margin - y_pred, 0))
return K.mean(y_true * square_pred + (1 - y_true) * margin_square)
mlflow.set_tracking_uri('<uri>')
mlflow.set_experiment('clean_parties_ml')
runs = mlflow.search_runs()
artifact_uri = runs.loc[runs['start_time'].idxmax()]['artifact_uri']
model = mlflow.keras.load_model(artifact_uri + '/model', custom_objects={'contrastive_loss': contrastive_loss})
y_pred = model.predict(input_data_chunk)
return y_pred
da_input_data = da.from_array(X_test, chunks=(100, None))
prediction_results = da_input_data.map_blocks(load_and_predict, dtype=X_test.dtype).compute()
The Error I'm receiving:
AttributeError: '_thread._local' object has no attribute 'value'
Keras/Tensorflow don't play nicely with other threaded systems. There is an ongoing issue on this topic here: https://github.com/dask/dask-examples/issues/35

Error when checking input: expected lstm_132_input to have 3 dimensions, but got array with shape (23, 1, 3, 1)

I have a data set include with temperature, humidity and wind. Here I want to predict future temperature value in next hour.
I used LSTM to predict future temperature value.
But when I run the model it showed up this error Error when checking input: expected lstm_132_input to have 3 dimensions, but got array with shape (23, 1, 3, 1)
Can anyone help me to solve this problem?
Here is my code:
import datetime
import time
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn import preprocessing
from keras.layers.core import Dense, Dropout, Activation
from keras.activations import linear
from keras.layers.recurrent import LSTM
from keras.models import Sequential
from sklearn.preprocessing import MinMaxScaler
data = pd.read_csv('data6.csv' , sep=',')
data['date'] = pd.to_datetime(data['date'] + " " + data['time'], format='%m/%d/%Y %H:%M:%S')
data.set_index('time', inplace=True)
data = data.values
data = data.astype('float32')
# normalize the dataset
def create_data(train,X,n_out=1):
#data = np.reshape(train, (train.shape[0], train_shape[1], train_shape[2]))
x,y=list(),list()
start =0
for _ in range(len(data)):
in_end = start+X
out_end= in_end + n_out
if out_end < len(data):
x_input = data[start:in_end]
x.append(x_input)
y.append(data[in_end:out_end,0])
start +=1
return np.array(x),np.array(y)
scaler = MinMaxScaler()
data = scaler.fit_transform(data)
# split into train and test sets
train = int(len(data) * 0.6)
test = len(data) - train
train, test = data[0:train,:], data[train:len(data),:]
X=1
x_train, y_train = create_data(train,X)
x_test, y_test = create_data(test,X)
x_train=x_train.reshape(x_train.shape +(1,))
x_test=x_test.reshape(x_test.shape + (1,))
n_timesteps, n_features, n_outputs = x_train.shape[1], x_train.shape[2], x_train.shape[1]
model = Sequential()
model.add(LSTM(8, activation='relu', input_shape=(n_timesteps, n_features)))
model.add(Dense(8,activation='relu'))
model.add(Dense(n_outputs))
model.compile(loss='mse', optimizer='adam')
# fit network
model.fit(x_train,y_train, epochs=10,batch_size=1, verbose=0)
My csv file:
My csv file.
My error:
model summary :
you need to add activation to your last layer
model = Sequential()
model.add(LSTM(8, activation='relu', input_shape=(n_timesteps, n_features)))
model.add(Dense(8,activation='relu'))
# here
model.add(Dense(n_outputs,activation='relu'))
model.compile(loss='mse', optimizer='adam')
# fit network
model.fit(x_train,y_train, epochs=10,batch_size=1, verbose=0)

keras gridSearchCV on sklearn One hot Encoded Data

The problem with this code is that I am giving classifier,
One hot encoded data:
Means:
X-train, X-test, y_train, y_test is one hot encoded.
But the classifier is predicting the output:
y_pred_test, y_pred_train in Numerical form
(which I think is incorrect as well). Can anyone help with this?
This is a dummy example so no concern over low accuracy but just to know why it's predicting the output in not One Hot encoded form.
Thanks !
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
x=pd.DataFrame()
x['names']= np.arange(1,10)
x['Age'] = np.arange(1,10)
y=pd.DataFrame()
y['target'] = np.arange(1,10)
from sklearn.preprocessing import OneHotEncoder, Normalizer
ohX= OneHotEncoder()
x_enc = ohX.fit_transform(x).toarray()
ohY = OneHotEncoder()
y_enc = ohY.fit_transform(y).toarray()
print (x_enc)
print("____")
print (y_enc)
import keras
from keras import regularizers
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.models import load_model
from keras.layers.advanced_activations import LeakyReLU
marker="-------"
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
def create_model(learn_rate=0.001):
model = Sequential()
model.add(Dense(units = 15, input_dim =18,kernel_initializer= 'normal', activation="tanh"))
model.add(Dense(units=9, activation = "softmax"))
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=['accuracy'])
return model
if __name__=="__main__":
X_train, X_test, y_train, y_test = train_test_split(x_enc, y_enc, test_size=0.33, random_state=42)
print ("\n\n",marker*5," Classification\nX_train shape is: ",X_train.shape,"\tX_test shape is:",X_test.shape)
print ("\ny_train shape is: ",y_train.shape,"\t y_test shape is:",y_test.shape,"\n\n")
norm = Normalizer()
#model
X_train = norm.fit_transform(X_train)
X_test = norm.transform(X_test)
earlyStopping=keras.callbacks.EarlyStopping(monitor='val_loss', patience=0, verbose=0, mode='auto')
model = KerasClassifier(build_fn=create_model, verbose=0)
fit_params={'callbacks': [earlyStopping]}
#grid
# batch_size =[50,100,200, 300,400]
epochs = [2,5]
learn_rate=[0.1,0.001]
param_grid = dict( epochs = epochs, learn_rate = learn_rate)
grid = GridSearchCV(estimator = model, param_grid = param_grid, n_jobs=1)
#Predicting
print (np.shape(X_train), np.shape(y_train))
y_train = np.reshape(y_train, (-1,np.shape(y_train)[1]))
print ("y_train shape after reshaping", np.shape(y_train))
grid_result = grid.fit(X_train, y_train, callbacks=[earlyStopping])
print ("grid score using params: ", grid_result.best_score_, " ",grid_result.best_params_)
#scores
print("SCORES")
print (grid_result.score(X_test,y_test))
# summarize results
#print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
#means = grid_result.cv_results_['mean_test_score']
#stds = grid_result.cv_results_['std_test_score']
#params = grid_result.cv_results_['params']
#for mean, stdev, param in zip(means, stds, params):
# print("%f (%f) with: %r" % (mean, stdev, param))
print("\n\n")
print("y_test is",y_test)
y_hat_test = grid.predict(X_test)
y_hat_train = grid.predict(X_train)
print("y_hat_test is ", y_hat_test)

Resources