Building a model that uses harmony search algorithm for hyperparamenters tuning, combined with CNN-LSTM layer.

Setting the parameters seems okay, upon running it gives an error related to 'custom-objects' which is peculiar to tensorflow.

ValueError: Unknown optimizer: binary_crossentropy. Please ensure this object is passed to the custom_objects argument. See https://www.tensorflow.org/guide/keras/save_and_serialize#registering_the_custom_object for details.

here is the code

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
from keras.layers import Input, Embedding, LSTM, Dense
from keras.layers import Conv1D, MaxPooling1D, Flatten
from keras.models import Model
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error

# Define the CNN-LSTM model
inputs = Input(shape=(X_train.shape[1], X_train.shape[2]))
x = Conv1D(filters=32, kernel_size=2, activation='relu')(inputs)
x = MaxPooling1D(pool_size=1)(x)
x = Flatten()(x)
x = Embedding(input_dim=24, output_dim=128, input_length=24)(x)
x = LSTM(units=128, dropout=0.2, recurrent_dropout=0.2)(x)
outputs = Dense(1, activation='sigmoid')(x)
model = Model(inputs, outputs)

# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy',
              metrics=['accuracy'])

# Fit the model on the training data
model.fit(X_train, y_train, epochs=10, batch_size=32)

# Evaluate the model on the test data
results = model.evaluate(X_test, y_test)
print(results)

# Define the harmony search algorithm


def harmony_search(model, X_train, y_train, X_test, y_test, n_iterations=10):
    best_score = 0
    for i in range(n_iterations):
        # Randomly select a set of model parameters
        params = {
            'optimizer': np.random.choice(['adam', 'rmsprop', 'sgd']),
            'loss': 'binary_crossentropy',
            'metrics': np.random.choice(['accuracy', 'mae'])
        }

        # Compile the model with the selected parameters
        model.compile(params)
        

        # Fit the model on the training data
        model.fit(X_train, y_train, epochs=10, batch_size=32)

        # Evaluate the model on the test data
        score = model.evaluate(X_test, y_test)[1]

        # Update the best score if necessary
        if score > best_score:
            best_score = score
            best_params = params

    # Return the best set of model parameters
    return best_params


# Find the best set of model parameters using the harmony search algorithm
best_params = harmony_search(model, X_train, y_train, X_test, y_test)

# Print the best set of model parameters
print(best_params)

I have tried adding the specific parameter at the class level, same error.

ValueError: Unknown optimizer: binary_crossentropy. Please ensure this object is passed to the custom_objects argument. See https://www.tensorflow.org/guide/keras/save_and_serialize#registering_the_custom_object for details.

1

There are 1 answers

2
Georgios Livanos On

the params is a dict of values and u pass this dict to the first argument of .compile which, from documentation has these arguments.

compile(
    optimizer='rmsprop',
    loss=None,
    metrics=None,
    loss_weights=None,
    weighted_metrics=None,
    run_eagerly=None,
    steps_per_execution=None,
    jit_compile=None,
    **kwargs
)

Which means that .compile on a step tries to resolve this dict to optimizers. What you really should do is to pass the dict['key'] value to the correct argument. For example, using the params dict:

# metrics get a list of values
compile(optimizer=params['optimizer'], loss=params['loss'], metrics=[params['metrics']])