Kuba Chrobociński
Kuba Chrobociński

Reputation: 11

Looking to optimize grid search for optimal parameters

I need to check 12 parameters to see what combination of those is best. Of course it could be done with nested loops but it would take ungodly amount of time but I don't have idea how to optimize this to run in resonable time, some gradient descent maybe? Number of different parameter values can be changed to lower number. Lower is code that you can use as general idea of what I'm trying to accomplish.

from make_segmentations import make_segmentations
from validation import score_all
import numpy as np

l_mean = np.arange(0, 101, 1)
l_std = np.arange(0, 101, 1)
a_mean = np.arange(0, 101, 1)
a_std = np.arange(0, 101, 1)
b_mean = np.arange(0, 101, 1)
b_std = np.arange(0, 101, 1)

h_mean = np.arange(0, 1.01, 0.01)
h_std = np.arange(0, 1.01, 0.01)
s_mean = np.arange(0, 1.01, 0.01)
s_std = np.arange(0, 1.01, 0.01)
v_mean = np.arange(0, 1.01, 0.01)
v_std = np.arange(0, 1.01, 0.01)

high_score = np.array((0,0))
best_params = np.array((0,0,0,0,0,0,0,0,0,0,0,0))

#%%
for l_m in l_mean:
    for l_s in l_std:
        for a_m in a_mean:
            for a_s in a_std:
                for b_m in b_mean:
                    for b_s in b_std:
                        for h_m in h_mean:
                            for h_s in h_std:
                                for s_m in s_mean:
                                    for s_s in s_std:
                                        for v_m in v_mean:
                                            for v_s in v_std:

                                                    
                                                make_segmentations(Lab_params = np.array((l_m,l_s,a_m,a_s,b_m,b_s)), Hsv_params= ((h_m,h_s,s_m,s_s,v_m,v_s)))
                                                score = score_all(number_of_cases = 30)
                                                
                                                if score[0] > high_score[0] and score[1] > high_score[1] :
                                                    high_score = score
                                                    best_params = np.array((l_m,l_s,a_m,a_s,b_m,b_s,h_m,h_s,s_m,s_s,v_m,v_s))

Upvotes: 0

Views: 368

Answers (2)

BurnNote
BurnNote

Reputation: 436

You can use the scipy.optimize function minimize on the (negative) score to optimize the parameters for the best fit.

Since your parameters seem to be statistical properties and you seem to have a number of datapoints available, I would also suggest just computing them directly. That will give you a good initial guess for the optimization, and also serve as a sanity check for the final value.

Sidenote, you can compress those nested loops using the product function from itertools to go through all possible combinations. That would look something like this (I only added the first four):

from itertools import product
for l_m, l_s, a_m, a_s in product(l_mean, l_std, a_mean, a_std):
   #do stuff

This won't improve performance (you're still searching through a parameter space with 100^12 points), but it will make you're code a whole lot more pleasent to look at and work with.

Upvotes: 1

Pranjal Doshi
Pranjal Doshi

Reputation: 1262

I think itertools.product is the one you are looking for you can use it as

from itertools import product 
a = [1,2,3]
b = [2,3,4]
c = [4,9,3]
combinations = list(list(product(a,b,c)))
# It's output is 
"""
[(1, 2, 4), (1, 2, 9), (1, 2, 3), (1, 3, 4), (1, 3, 9), (1, 3, 3), (1, 4, 4), (1, 4, 9), (1, 4, 3), (2, 2, 4), (2, 2, 9), (2, 2, 3), (2, 3, 4), (2, 3, 9), (2, 3, 3), (2, 4, 4), (2, 4, 9), (2, 4, 3), (3, 2, 4), (3, 2, 9), (3, 2, 3), (3, 3, 4), (3, 3, 9), (3, 3, 3), (3, 4, 4), (3, 4, 9), (3, 4, 3)]
"""

after generating combinations you can use it in your code

for tupl in combinations:
    #your function call and logic
    #required values can be extracted from tupl[index]

Upvotes: 0

Related Questions