RandomSearch в KerasTuner

Рейтинг: 1Ответов: 1Опубликовано: 10.03.2023

Нужно использовать Random Search для поиска оптимальных гиперпараметров модели для датасета https://github.com/catauggie/SunBattery/blob/main/dataset.xlsx:

import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

from sklearn.model_selection import train_test_split

df = pd.read_excel("dataset.xlsx", sheet_name='dataset', header=0)
X = df.drop(['Дата',
             'I БС3 отн.',
             'I БС4 отн.',
             'Uхх БС3 отн.',
             'Uхх БС4 отн.'], axis=1)
Y = df.drop(['Дата',
             'Протоны >1 MeV',
             'Протоны >10 MeV',
             'Протоны >100 MeV',
             'Электроны >0.6 MeV',
             'Электроны >2 MeV',
             'К осв-ти'], axis=1)

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.1, random_state=1)
normalizer = tf.keras.layers.Normalization(axis=-1)
normalizer.adapt(np.array(X))

def build_and_compile_model_params(norm, #нормализованный датасет
                                   Optimizer,
                                   Loss, # opt_params,
                                   active_fun,
                                   Metric,
                                   n_neurons,
                                   n_out):

    Model = keras.Sequential([
      norm,
        layers.Dense(n_neurons, activation=active_fun),
        
    ])

    Model.add(layers.Dense(n_out))
    

    Model.compile(loss = Loss,
                  optimizer = Optimizer,#tf.keras.optimizers.optimizer(opt_params)
                   metrics = Metric)
    return Model

#RandomSearch
from keras_tuner import RandomSearch
from keras_tuner import Objective

tuner1 =  RandomSearch(hypermodel=build_and_compile_model_params,
                      objective="val_mean_squared_error",
                      #objective=Objective(name="val_mean_squared_error",direction="min"),
                      max_trials=5,
                      #seed=123,
                      project_name="Regression",
                      overwrite=True
                    )

tuner1.search(X_train, Y_train, batch_size=32, epochs=10, validation_data=(X_test, Y_test))

При этом выдается ошибка:

TypeError: The added layer must be an instance of class Layer. Received: layer=<keras_tuner.engine.hyperparameters.hyperparameters.HyperParameters object at 0x0000021B9677AE50> of type <class 'keras_tuner.engine.hyperparameters.hyperparameters.HyperParameters'>.

Подскажите, что это такое и как это можно исправить?

Ответы

▲ 3

Ответ есть в самой ошибке, переданный в качестве первого аргумента метода Sequential.add(), не является экземпляром класса Layer.

import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

from sklearn.model_selection import train_test_split

df = pd.read_excel("dataset.xlsx", sheet_name='dataset', header=0)
X = df.drop(['Дата',
             'I БС3 отн.',
             'I БС4 отн.',
             'Uхх БС3 отн.',
             'Uхх БС4 отн.'], axis=1)
Y = df.drop(['Дата',
             'Протоны >1 MeV',
             'Протоны >10 MeV',
             'Протоны >100 MeV',
             'Электроны >0.6 MeV',
             'Электроны >2 MeV',
             'К осв-ти'], axis=1)

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.1, random_state=1)
normalizer = tf.keras.layers.Normalization(axis=-1)
normalizer.adapt(np.array(X))

def build_and_compile_model_params(hp):

    n_neurons = hp.Int('n_neurons', min_value=32, max_value=512, step=32)
    n_out = hp.Int('n_out', min_value=1, max_value=4, step=1)
    activation = hp.Choice('activation', values=['relu', 'tanh', 'sigmoid'])
    optimizer = hp.Choice('optimizer', values=['adam', 'rmsprop'])
    learning_rate = hp.Float('learning_rate', min_value=1e-4, max_value=1e-2, sampling='LOG')
    loss = hp.Choice('loss', values=['mse', 'mae', 'mape'])
    metric = hp.Choice('metric', values=['mse', 'mae'])

    model = keras.Sequential([
        normalizer,
        layers.Dense(n_neurons, activation=activation),
        layers.Dense(n_out)
    ])

    model.compile(
        optimizer=getattr(tf.keras.optimizers, optimizer)(learning_rate=learning_rate),
        loss=loss,
        metrics=[metric]
    )

    return model

# RandomSearch
from kerastuner.tuners import RandomSearch

tuner = RandomSearch(
    build_and_compile_model_params,
    objective='val_loss',
    max_trials=5,
    executions_per_trial=1,
    directory='random_search',
    project_name='battery_regression'
)

tuner.search(X_train, Y_train, epochs=10, validation_data=(X_test, Y_test))