Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: TypeError: Problem.init() missing 1 required positional argument: 'bounds' #167

Open
Fa20 opened this issue Sep 28, 2024 · 9 comments
Assignees
Labels
bug Something isn't working

Comments

@Fa20
Copy link

Fa20 commented Sep 28, 2024

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

  1. 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 Fa20 added the bug Something isn't working label Sep 28, 2024
@Fa20 Fa20 changed the title [BUG]: [BUG]: TypeError: Problem.init() missing 1 required positional argument: 'bounds' Sep 28, 2024
@thieu1995
Copy link
Owner

@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.

@Fa20
Copy link
Author

Fa20 commented Sep 28, 2024

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."
}

@thieu1995
Copy link
Owner

@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}")

@Fa20
Copy link
Author

Fa20 commented Sep 29, 2024

@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.```

@thieu1995
Copy link
Owner

thieu1995 commented Sep 29, 2024

@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}")

@thieu1995
Copy link
Owner

@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)}")

@Fa20
Copy link
Author

Fa20 commented Sep 29, 2024

@thieu1995 Thank you very much . what is model. ?
print(f"Best agent: {model.g_best}")

@thieu1995
Copy link
Owner

@Fa20 ,
model is best_agent. My bad copy paste habit.

@Fa20
Copy link
Author

Fa20 commented Oct 13, 2024

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants