秋田小鼠 2018-08-25
遗传算法是优化问题的一种解决方案,例如,如果你需要找到最佳的参数集来最小化损失函数。遗传算法是进化算法的一部分。这个想法受到自然和自然选择的启发。
在自然界中,进化至少需要三个条件:
现在想象一下,你在一个特定的编程环境中编码了一些对象,而不是生物体。例如,如果你有一个机器学习(ML)模型的种群,它会如何工作?
遗传算法并不完美,您仍然需要指定您的损失函数、您的种群大小、具有变化参数的后代比例等等。
可能是对遗传超参数调优最友好的库。
GitHub:https://github.com/EpistasisLab/tpot
以下是我从TPOT中提取最佳超参数的方法,Python代码如下:
#Search for best hyperparameters for XGBoost
from xgboost import XGBClassifier
from tpot import TPOTClassifier, TPOTRegressor
from deap.gp import Primitive
#Define your hyperparameters
params = {'max_depth': np.arange(1,200,1),
'learning_rate': np.arange(0.0001,0.1,0.0001),
'n_estimators': np.arange(1,200,1),
'nthread':[6],
'gamma':np.arange(0.00001,0.1,0.00001),
'subsample':np.arange(0.1,2,0.1),
'reg_lambda': np.arange(0.1,200,1),
'reg_alpha': np.arange(1,200,1),
'min_child_weight': np.arange(1,200,1),
'gamma': np.arange(0.1,2,0.1),
'colsample_bytree': np.arange(0.1,2,0.1),
'colsample_bylevel': np.arange(0.1,2,0.1)
}
#Run TPOT
tpot_classifier = TPOTClassifier(generations=20, population_size=500, offspring_size=250,
verbosity=2, early_stop=8,
config_dict={'xgboost.XGBClassifier': params}, cv = 10, scoring = 'accuracy')
tpot_classifier.fit(X, Y)
#Extract best parameters
args = {}
for arg in tpot_classifier._optimized_pipeline:
if type(arg) != Primitive:
try:
if arg.value.split('__')[1].split('=')[0] in ['max_depth', 'n_estimators', 'nthread','min_child_weigh']:
args[arg.value.split('__')[1].split('=')[0]] = int(arg.value.split('__')[1].split('=')[1])
else:
args[arg.value.split('__')[1].split('=')[0]] = float(arg.value.split('__')[1].split('=')[1])
except:
pass
params = args
#Now you can use XGBoost with best hyperparameters
xgbxgb == XGBClassifierXGBClas (**params)
在神经网络的情况下,您还可以使用遗传算法,它们的工作速度比基于网格搜索的方法快得多。
我找到了这个GitHub存储库 - 使用遗传算法演化神经网络(https://github.com/harvitronix/neural-network-genetic-algorithm),并且非常喜欢这种方法。
用法示例:
from evolution import NeuroEvolution
params = {
"epochs": [10, 20, 35],
"batch_size": [10, 20, 40],
"n_layers": [1, 2, 3, 4],
"n_neurons": [20, 40, 60],
"dropout": [0.1, 0.2, 0.5],
"optimizers": ["nadam", "adam"],
"activations": ["relu", "sigmoid"],
"last_layer_activations": ["sigmoid"],
"losses": ["binary_crossentropy"],
"metrics": ["accuracy"]
}
....
# x_train, y_train, x_test, y_test - prepared data
search = NeuroEvolution(generations = 10, population = 10, params=params)
search.evolve(x_train, y_train, x_test, y_test)
100%|██████████| 10/10 [05:37<00:00, 29.58s/it]
100%|██████████| 10/10 [03:55<00:00, 25.55s/it]
100%|██████████| 10/10 [02:05<00:00, 15.05s/it]
100%|██████████| 10/10 [01:37<00:00, 14.03s/it]
100%|██████████| 10/10 [02:49<00:00, 22.53s/it]
100%|██████████| 10/10 [02:37<00:00, 23.14s/it]
100%|██████████| 10/10 [02:36<00:00, 21.37s/it]
100%|██████████| 10/10 [01:57<00:00, 18.56s/it]
100%|██████████| 10/10 [02:42<00:00, 25.29s/it]
"best accuracy: 0.79, best params: {'epochs': 35, 'batch_size': 40, 'n_layers': 2, 'n_neurons': 20, 'dropout': 0.1, 'optimizers': 'nadam', 'activations': 'relu', 'last_layer_activations': 'sigmoid', 'losses': 'binary_crossentropy', 'metrics': 'accuracy'}"
# or you can call it with
search.best_params
它还可以搜索最佳数量的图层和神经元,以及您定义的超参数的位置。