Krishnang K Dalal
Krishnang K Dalal

Reputation: 2556

Keras-Tuner RuntimeError

I'm getting following error and I'm not able to figure out why:

RuntimeError: Model-building function did not return a valid Keras Model instance, found (<tensorflow.python.keras.engine.functional.Functional object at 0x7f74d8b849d0>, <tensorflow.python.keras.engine.functional.Functional object at 0x7f74d8b80810>)

I have read the answers here and here which seem to telling to import keras from tensorflow instead of stand alone keras which I'm doing but still getting the error. I would very much appreciate your help in figuring this out. Below is my entire code:

from tensorflow.keras.layers import Input, Dense, BatchNormalization, Dropout, Concatenate, Lambda, GaussianNoise, Activation
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.losses import BinaryCrossentropy
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
from numba import njit
import tensorflow as tf
import numpy as np
from sklearn.model_selection import KFold
from sklearn.model_selection._split import _BaseKFold, indexable, _num_samples
from sklearn.utils.validation import _deprecate_positional_args
import pandas as pd
import kerastuner as kt
import gc
from tqdm import tqdm
from random import choices
import warnings
warnings.filterwarnings('ignore')

class MyTuner(kt.Tuner):
    def run_trial(self, trial, x, y):
        cv = PurgedGroupTimeSeriesSplit(n_splits=5, group_gap = 20)
        val_losses = []
        
        for train_indices, test_indices in cv.split(x, groups=x[0]):
            x_train, y_train = x[train_indices, 1:], y[train_indices]
            x_test, y_test = x[test_indices, 1:], y[test_indices]
            
            x_train = apply_transformation(x_train)
            x_test = apply_transformation(x_test)
            
            model = self.hypermodel.build(trial.hyperparameters)
            model.fit(x_train, y_train, batch_size = hp.Int('batch_size', 500, 5000, step=500, default=4000),
                      epochs = hp.Int('epochs', 100, 1000, step=200, default=500))
            
            val_losses.append(model.evaluate(x_test, y_test))
            
        self.oracle.update_trial(trial.trial_id, {'val_loss': np.mean(val_losses)})
        self.save_model(trial.trial_id, model)

def create_autoencoder(hp, input_dim, output_dim):
    i = Input(input_dim)
    encoded = BatchNormalization()(i)
    encoded = GaussianNoise(hp.Float('gaussian_noise', 1e-2, 1, sampling='log', default=5e-2))(encoded)
    encoded = Dense(hp.Int('encoder_dense', 100, 300, step=50, default=64), activation='relu')(encoded)
    decoded = Dropout(hp.Float('decoder_dropout_1', 1e-1, 1, sampling='log', default=0.2))(encoded)
    decoded = Dense(input_dim,name='decoded')(decoded)
    x = Dense(hp.Int('output_x', 32, 100, step=10, default=32),activation='relu')(decoded)
    x = BatchNormalization()(x)
    x = Dropout(hp.Float('x_dropout_1', 1e-1, 1, sampling='log', default=0.2))(x)
    x = Dense(hp.Int('output_x', 32, 100, step=10, default=32),activation='relu')(x)
    x = BatchNormalization()(x)
    x = Dropout(hp.Float('x_dropout_2', 1e-1, 1, sampling='log', default=0.2))(x)    
    x = Dense(output_dim,activation='sigmoid',name='label_output')(x)
    
    encoder = Model(inputs=i,outputs=encoded)
    autoencoder = Model(inputs=i,outputs=[decoded, x])
    
#     optimizer = hp.Choice('optimizer', ['adam', 'sgd'])
    
    autoencoder.compile(optimizer=Adam(hp.Float('lr', 0.00001, 0.1, default=0.001)), 
                        loss='sparse_binary_crossentropy',
                        metrics=['accuracy'])
    
    return autoencoder, encoder


build_model = lambda hp: create_autoencoder(hp, X[:, 1:].shape[1], y.shape[1])

tuner = MyTuner(
            oracle=kt.oracles.BayesianOptimization(
                    objective=kt.Objective('val_loss', 'min'),
                    max_trials=20),
            hypermodel=build_model,
            directory='./',
            project_name='autoencoders')
    
tuner.search(X, (X,y), callbacks=[EarlyStopping('val_loss',patience=5),
                                  ReduceLROnPlateau('val_loss',patience=3)])

encoder_hp  = tuner.get_best_hyperparameters(1)[0]
print("Best Encoder Hyper-parameter:", encoder_hp)

best_autoencoder = tuner.get_best_models(1)[0]

Upvotes: 0

Views: 621

Answers (1)

dinhanhx
dinhanhx

Reputation: 197

RuntimeError: Model-building function did not return a valid Keras Model instance, found (<tensorflow.python.keras.engine.functional.Functional object at 0x7f74d8b849d0>, <tensorflow.python.keras.engine.functional.Functional object at 0x7f74d8b80810>)

(<tensorflow.python.keras.engine.functional.Functional object at 0x7f74d8b849d0>, <tensorflow.python.keras.engine.functional.Functional object at 0x7f74d8b80810>)

As you can see this a tuple of two Keras Model instance. This is output of create_autoencoder(hp, input_dim, output_dim).

def create_autoencoder(hp, input_dim, output_dim): 
    # some lines of codes
    return autoencoder, encoder

From my understanding, you are not using encoder. Therefore, you can remove it in your function.

That function will be look like this

def create_autoencoder(hp, input_dim, output_dim): 
    # some lines of codes
    return autoencoder

It will only return a Keras Model Instance.

Upvotes: 1

Related Questions