[BUG]: TypeError: Problem.init() missing 1 required positional argument: 'bounds'
Description of the bug
TypeError Traceback (most recent call last)
Cell In[34], line 48
41 bounds = [
42
43 FloatVar(lb=0., ub=1.0, name="learning-rate")]
47 gwo= OriginalGWO(epoch, pop_size)
---> 48 best_position, best_fitness = gwo.solve(svr_problem)
49 print(f"Solution: {best_position}, Fitness: {best_fitness}")
File c:\Users\FI\AppData\Local\Programs\Python\Python310\lib\site-packages\mealpy\optimizer.py:223, in Optimizer.solve(self, problem, mode, n_workers, termination, starting_solutions, seed) 202 def solve(self, problem: Union[Dict, Problem] = None, mode: str = 'single', n_workers: int = None, 203 termination: Union[Dict, Termination] = None, starting_solutions: Union[List, np.ndarray, Tuple] = None, 204 seed: int = None) -> Agent: 205 """ 206 Args: 207 problem: an instance of Problem class or a dictionary (...) 221 g_best: g_best, the best found agent, that hold the best solution and the best target. Access by: .g_best.solution, .g_best.target 222 """ --> 223 self.check_problem(problem, seed) 224 self.check_mode_and_workers(mode, n_workers) 225 self.check_termination("start", termination, None)
File c:\Users\FI\AppData\Local\Programs\Python\Python310\lib\site-packages\mealpy\optimizer.py:157, in Optimizer.check_problem(self, problem, seed) 155 elif type(problem) == dict: 156 problem["seed"] = seed --> 157 self.problem = Problem(**problem) 158 else: 159 raise ValueError("problem needs to be a dict or an instance of Problem class.")
TypeError: Problem.init() missing 1 required positional argument: 'bounds'
Steps To Reproduce
-
Define the model
def create_model(learning_rate, num_neurons): base_model = keras.applications.VGG16( weights='imagenet', input_shape=(224, 224, 3), include_top=False)
base_model.trainable = False
inputs = keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dense(num_neurons, activation='relu')(x)
outputs = keras.layers.Dense(6, activation='softmax')(x)
model = keras.Model(inputs, outputs)
model.compile(optimizer=keras.optimizers.RMSprop(learning_rate=learning_rate),
loss='categorical_crossentropy',
metrics=['accuracy'])
return model
2.# Fitness function for optimization def fitness_function(solution): learning_rate= 0.01 num_neurons= solution
model = create_model(learning_rate, int(num_neurons))
# Assuming train_it and valid_it are already defined
history = model.fit(train_it, validation_data=valid_it,
steps_per_epoch=train_it.samples/train_it.batch_size,
validation_steps=valid_it.samples/valid_it.batch_size,
epochs=1, verbose=0)
val_accuracy = history.history['val_accuracy'][-1]
return history.history['val_accuracy'][-1] #1 - val_accuracy # Minimize the inverse of accuracy
3.# number of neurons
problem_size = 2
lb = [10] # lower bounds: num_neurons
ub = [ 512] # upper bounds: num_neurons
epoch = 1
pop_size = 5 # Size of the population in each generation
pc = 0.95 # Crossover probability
pm = 0.05 # Mutation probability
svr_problem = { "fit_func": fitness_function, 'lb':[1], # Lower bound of our parameters 'ub':[6], # upper bound of our parameters "minmax": "min" }
gwo= OriginalGWO(epoch, pop_size) best_position, best_fitness = gwo.solve(svr_problem) print(f"Solution: {best_position}, Fitness: {best_fitness}")
Additional Information
Here is my code to use meaply with pretrained model to find best values of hyperpramters: from mealpy.evolutionary_based.GA import BaseGA from mealpy.evolutionary_based.GA import BaseGA from mealpy.utils.problem import Problem from mealpy.utils.space import FloatVar, IntegerVar from mealpy.swarm_based.GWO import OriginalGWO from tensorflow.keras.optimizers import Adam
from tensorflow import keras from mealpy.evolutionary_based import GA
Define the model as a function
def create_model(learning_rate, num_neurons): base_model = keras.applications.VGG16( weights='imagenet', input_shape=(224, 224, 3), include_top=False)
base_model.trainable = False
inputs = keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dense(num_neurons, activation='relu')(x)
outputs = keras.layers.Dense(6, activation='softmax')(x)
model = keras.Model(inputs, outputs)
model.compile(optimizer=keras.optimizers.RMSprop(learning_rate=learning_rate),
loss='categorical_crossentropy',
metrics=['accuracy'])
return model
Fitness function for optimization
def fitness_function(solution): learning_rate= 0.01 num_neurons= solution
model = create_model(learning_rate, int(num_neurons))
# Assuming train_it and valid_it are already defined
history = model.fit(train_it, validation_data=valid_it,
steps_per_epoch=train_it.samples/train_it.batch_size,
validation_steps=valid_it.samples/valid_it.batch_size,
epochs=1, verbose=0)
val_accuracy = history.history['val_accuracy'][-1]
return history.history['val_accuracy'][-1] #1 - val_accuracy # Minimize the inverse of accuracy
Define boundaries for learning rate and number of neurons
problem_size = 2
lb = [10] # lower bounds: num_neurons
ub = [ 512] # upper bounds: num_neurons
epoch = 1
pop_size = 5 # Size of the population in each generation
pc = 0.95 # Crossover probability
pm = 0.05 # Mutation probability
param_bounds = {
"num_neurons": list(range(10, 50))
} svr_problem = { "fit_func": fitness_function, 'lb':[1], # Lower bound of our parameters 'ub':[6], # upper bound of our parameters "minmax": "min" } bounds = [
FloatVar(lb=0., ub=1.0, name="learning-rate")]
gwo= OriginalGWO(epoch, pop_size) best_position, best_fitness = gwo.solve(svr_problem) print(f"Solution: {best_position}, Fitness: {best_fitness}")
@Fa20 Could you please put your code into a good format of "coding style". I can help you but with this format I don't know what are you doing with this code.
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from mealpy.utils.problem import Problem
from mealpy.utils.space import IntegerVar
from mealpy.swarm_based.GWO import OriginalGWO
from tensorflow import keras
import numpy as np
# Create the data generators with validation split
datagen_train = ImageDataGenerator(
samplewise_center=True,
rotation_range=10,
zoom_range=0.1,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=True,
validation_split=0.2
)
# Load the training data and split into train and validation sets
train_it = datagen_train.flow_from_directory(
"data/train/",
target_size=(224, 224),
color_mode="rgb",
class_mode="categorical",
subset='training'
)
valid_it = datagen_train.flow_from_directory(
"data/train/",
target_size=(224, 224),
color_mode="rgb",
class_mode="categorical",
subset='validation'
)
# Define the model as a function
def create_model(learning_rate, num_neurons):
base_model = keras.applications.VGG16(
weights='imagenet',
input_shape=(224, 224, 3),
include_top=False)
base_model.trainable = False
inputs = keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dense(num_neurons, activation='relu')(x)
outputs = keras.layers.Dense(6, activation='softmax')(x)
model = keras.Model(inputs, outputs)
model.compile(optimizer=keras.optimizers.RMSprop(learning_rate=learning_rate),
loss='categorical_crossentropy',
metrics=['accuracy'])
return model
# Define the objective (fitness) function
class NeuronOptimization(Problem):
def __init__(self, bounds=None, minmax="max", name=None, **kwargs):
super().__init__(bounds, minmax, **kwargs)
def obj_func(self, solution):
learning_rate = 0.01
num_neurons = int(solution[0]) # We assume one-dimensional solution (neurons)
# Create and train the model
model = create_model(learning_rate, num_neurons)
history = model.fit(train_it, validation_data=valid_it,
steps_per_epoch=train_it.samples // train_it.batch_size,
validation_steps=valid_it.samples // valid_it.batch_size,
epochs=1, verbose=1)
# Return the validation accuracy as fitness
val_accuracy = history.history['val_accuracy'][-1]
return val_accuracy # Maximizing accuracy, so returning as-is
# Define the search space for neurons
bounds = [IntegerVar(lb=10, ub=11, name='num_neurons')]
# Create the optimization problem instance
problem = NeuronOptimization(bounds=bounds, minmax="max", name="Neurons_Optimization")
# Set up the GWO optimizer
gwo = OriginalGWO(problem=problem, epoch=1, pop_size=5)
# Solve the optimization problem
best_position, best_fitness = gwo.solve()
# Output the result
print(f"Best number of neurons: {int(best_position[0])}, Best validation accuracy: {best_fitness}")
@thieu1995 Thank you so much I have updated the code but got differen error which I can not fix it
error I got ```
{ "name": "ValueError", "message": "problem needs to be a dict or an instance of Problem class.", "stack": "--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[65], line 86 83 gwo = OriginalGWO(problem=problem, epoch=1, pop_size=5) 85 # Solve the optimization problem ---> 86 best_position, best_fitness = gwo.solve() 88 # Output the result 89 print(f"Best number of neurons: {int(best_position[0])}, Best validation accuracy: {best_fitness}")
File c:\Users\FI\AppData\Local\Programs\Python\Python310\lib\site-packages\mealpy\optimizer.py:223, in Optimizer.solve(self, problem, mode, n_workers, termination, starting_solutions, seed) 202 def solve(self, problem: Union[Dict, Problem] = None, mode: str = 'single', n_workers: int = None, 203 termination: Union[Dict, Termination] = None, starting_solutions: Union[List, np.ndarray, Tuple] = None, 204 seed: int = None) -> Agent: 205 """ 206 Args: 207 problem: an instance of Problem class or a dictionary (...) 221 g_best: g_best, the best found agent, that hold the best solution and the best target. Access by: .g_best.solution, .g_best.target 222 """ --> 223 self.check_problem(problem, seed) 224 self.check_mode_and_workers(mode, n_workers) 225 self.check_termination("start", termination, None)
File c:\Users\FI\AppData\Local\Programs\Python\Python310\lib\site-packages\mealpy\optimizer.py:159, in Optimizer.check_problem(self, problem, seed) 157 self.problem = Problem(**problem) 158 else: --> 159 raise ValueError("problem needs to be a dict or an instance of Problem class.") 160 self.generator = np.random.default_rng(seed) 161 self.logger = Logger(self.problem.log_to, log_file=self.problem.log_file).create_logger(name=f"{self.module}.{self.class.name}")
ValueError: problem needs to be a dict or an instance of Problem class." }
@Fa20 , Hope that helps! There are several places that you messed it up. You need to define at least 2 parameters, if there is only 1 parameter you can use for loop instead of metaheuristics to optimize. When you define the bounds list, and define your own Problem, you need to call the decode_solution() and get parameter by name.
import numpy as np
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from mealpy import Problem, IntegerVar, FloatVar, OriginalGWO
# Create the data generators with validation split
datagen_train = ImageDataGenerator(
samplewise_center=True,
rotation_range=10,
zoom_range=0.1,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=True,
validation_split=0.2
)
# Load the training data and split into train and validation sets
train_it = datagen_train.flow_from_directory(
"data/train/",
target_size=(224, 224),
color_mode="rgb",
class_mode="categorical",
subset='training'
)
valid_it = datagen_train.flow_from_directory(
"data/train/",
target_size=(224, 224),
color_mode="rgb",
class_mode="categorical",
subset='validation'
)
# Define the model as a function
def create_model(learning_rate, num_neurons):
base_model = keras.applications.VGG16(
weights='imagenet',
input_shape=(224, 224, 3),
include_top=False)
base_model.trainable = False
inputs = keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dense(num_neurons, activation='relu')(x)
outputs = keras.layers.Dense(6, activation='softmax')(x)
model = keras.Model(inputs, outputs)
model.compile(optimizer=keras.optimizers.RMSprop(learning_rate=learning_rate),
loss='categorical_crossentropy',
metrics=['accuracy'])
return model
# Define the objective (fitness) function
class NeuronOptimization(Problem):
def __init__(self, bounds=None, minmax="max", **kwargs):
super().__init__(bounds, minmax, **kwargs)
def obj_func(self, solution):
x = self.decode_solution(solution)
lr, n_nodes = x["lr"], x["n_nodes"]
# Create and train the model
model = create_model(lr, n_nodes)
history = model.fit(train_it, validation_data=valid_it,
steps_per_epoch=train_it.samples // train_it.batch_size,
validation_steps=valid_it.samples // valid_it.batch_size,
epochs=1, verbose=1)
# Return the validation accuracy as fitness
val_accuracy = history.history['val_accuracy'][-1]
return val_accuracy # Maximizing accuracy, so returning as-is
# Define the search space for neurons
bounds = [
FloatVar(lb=0.0001, ub=0.5, name="lr"),
IntegerVar(lb=5, ub=100, name="n_nodes")
]
# Create the optimization problem instance
problem = NeuronOptimization(bounds=bounds, minmax="max", name="Neurons_Optimization")
# Set up the GWO optimizer
gwo = OriginalGWO(problem=problem, epoch=10, pop_size=20)
# Solve the optimization problem
best_position, best_fitness = gwo.solve()
# Output the result
print(f"Best number of neurons: {int(best_position[0])}, Best validation accuracy: {best_fitness}")
@thieu1995 thanks for your answer . I'm still getting the same error as before .I rung the above code you provied me but I replaced
from mealpy import Problem, IntegerVar, FloatVar, OriginalGWO
by
from mealpy import Problem, IntegerVar, FloatVar
from mealpy.swarm_based.GWO import OriginalGWO ```
and still have same error as before
ValueError Traceback (most recent call last) Cell In[67], line 91 88 gwo = OriginalGWO(problem=problem, epoch=1, pop_size=5) 90 # Solve the optimization problem ---> 91 best_position, best_fitness = gwo.solve() 93 # Output the result 94 print(f"Best number of neurons: {int(best_position[0])}, Best validation accuracy: {best_fitness}")
File c:\Users\FI\AppData\Local\Programs\Python\Python310\lib\site-packages\mealpy\optimizer.py:223, in Optimizer.solve(self, problem, mode, n_workers, termination, starting_solutions, seed) 202 def solve(self, problem: Union[Dict, Problem] = None, mode: str = 'single', n_workers: int = None, 203 termination: Union[Dict, Termination] = None, starting_solutions: Union[List, np.ndarray, Tuple] = None, 204 seed: int = None) -> Agent: 205 """ 206 Args: 207 problem: an instance of Problem class or a dictionary (...) 221 g_best: g_best, the best found agent, that hold the best solution and the best target. Access by: .g_best.solution, .g_best.target 222 """ --> 223 self.check_problem(problem, seed) 224 self.check_mode_and_workers(mode, n_workers) 225 self.check_termination("start", termination, None)
File c:\Users\FI\AppData\Local\Programs\Python\Python310\lib\site-packages\mealpy\optimizer.py:159, in Optimizer.check_problem(self, problem, seed) 157 self.problem = Problem(**problem) ... --> 159 raise ValueError("problem needs to be a dict or an instance of Problem class.") 160 self.generator = np.random.default_rng(seed) 161 self.logger = Logger(self.problem.log_to, log_file=self.problem.log_file).create_logger(name=f"{self.module}.{self.class.name}")
ValueError: problem needs to be a dict or an instance of Problem class.```
@Fa20 , OMG. My bad. I got so much attention to your code that I also forgot the syntax. lol. You need to put the Problem into the solve function. Not in the algorithm itself.
# Set up the GWO optimizer
gwo = OriginalGWO(epoch=10, pop_size=20)
# Solve the optimization problem
best_position, best_fitness = gwo.solve(problem=problem)
# Output the result
print(f"Best number of neurons: {int(best_position[0])}, Best validation accuracy: {best_fitness}")
@Fa20, again. Look like your code is from previous version. I correct it again.
# Solve the optimization problem
best_agent = gwo.solve(problem=problem)
# Output the result
print(f"Best agent: {model.g_best}")
print(f"Best solution: {model.g_best.solution}")
print(f"Best fitness: {model.g_best.target.fitness}")
print(f"Best real parameter: {model.problem.decode_solution(best_agent.solution)}")
@thieu1995 Thank you very much . what is model. ? print(f"Best agent: {model.g_best}")
@Fa20 , model is best_agent. My bad copy paste habit.
@thieu1995 still the code give me error : TypeError Traceback (most recent call last) Cell In[4], line 89 86 gwo = CSA.OriginalCSA(epoch=1, pop_size=5) 88 # Solve the optimization problem ---> 89 best_position, best_fitness = gwo.solve(problem=problem) 91 # Output the result 92 print(f"Best number of neurons: {int(best_position[0])}, Best validation accuracy: {best_fitness}")
TypeError: cannot unpack non-iterable Agent object
@Fa20,
You are using older version, please check out the documentation for the latest version 3.0.1 It should be: best_agent = gwo.solve(problem=problem)