群智优化:探索BP神经网络的最优配置
一、数据集介绍
鸢尾花数据集最初由Edgar Anderson测量得到,而后在著名的统计学家和生物学家R.A Fisher于1936年发表的文章中被引入到统计和机器学习领域数据集特征:
鸢尾花数据集包含了150个样本,每个样本有4个特征,这些特征是从花朵的尺寸测量中得到的,具体包括:
花萼长度(sepal length):在厘米单位下的花朵萼片的长度。
花萼宽度(sepal width):花萼片的宽度。
花瓣长度(petal length):花瓣的长度。
花瓣宽度(petal width):花瓣的宽度。
二、实验工程
基于粒子群算法的BP神经网络优化
代码如下:
import numpy as np
from pyswarm import pso
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt # 导入matplotlib的库# 准备鸢尾花数据集
data = load_iris()
X, y = data.data, data.target# 数据预处理和划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 定义BP神经网络结构
def create_nn(hidden_layer_sizes, alpha, learning_rate_init):return MLPClassifier(hidden_layer_sizes=hidden_layer_sizes, activation='relu',alpha=alpha, learning_rate_init=learning_rate_init, max_iter=1000, random_state=42)# 定义PSO适应度函数
params_list=[]
accuracy_list=[]
def nn_accuracy(params):params_list.append(params)hidden_layer_sizes = (int(params[0]),) # 隐藏层神经元数量,将参数转换为整数alpha = params[1] # 正则化参数 alphalearning_rate_init = params[2] # 初始学习率# 创建BP神经网络模型model = create_nn(hidden_layer_sizes, alpha, learning_rate_init)# 使用训练集来训练模型model.fit(X_train, y_train)# 使用模型对测试集进行预测y_pred = model.predict(X_test)# 计算模型的分类准确率accuracy = accuracy_score(y_test, y_pred)accuracy_list.append(accuracy)return -accuracy # 使用负精度作为适应度函数,因为PSO最小化目标函数# 使用PSO来最大化精度
lb = [1, 0.001, 0.001] # 参数下界,包括隐藏层神经元数量、正则化参数 alpha、初始学习率
ub = [100, 1.0, 1.0] # 参数上界# 使用PSO算法来寻找最佳参数组合,以最大化分类准确率xopt, fopt = pso(nn_accuracy, lb, ub, swarmsize=10, maxiter=50)print(xopt, fopt)
# 训练最终的BP神经网络模型,使用PSO找到的最优参数
best_hidden_layer_sizes = (int(xopt[0]),)
best_alpha = xopt[1]
best_learning_rate_init = xopt[2]best_model = create_nn(best_hidden_layer_sizes, best_alpha, best_learning_rate_init)
best_model.fit(X_train, y_train)hidden_layer_sizes_list=[]
alpha_list=[]
learning_rate_init_list=[]for para in params_list:hidden_layer_sizes_list.append(int(para[0]))alpha_list.append(para[1])learning_rate_init_list.append(para[2])
# 评估性能,计算最终模型的分类准确率
y_pred = best_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)plt.scatter(hidden_layer_sizes_list, accuracy_list, c="red", marker='o', label='hidden_layer_size')#画label 0的散点图plt.xlabel('hidden_layer_size')# 设置X轴的标签为K-means
plt.ylabel(accuracy)
# plt.legend(loc=2)# 设置图标在左上角
plt.title("hidden_layer_size_accuracy")
plt.show()plt.scatter(learning_rate_init_list, accuracy_list, c="blue", marker='+', label='learning_rate')#画label 2的散点图
plt.xlabel('learning_rate')# 设置X轴的标签为K-means
# plt.legend(loc=2)# 设置图标在左上角
plt.title("learning_rate_accuracy")
plt.show()
plt.scatter(alpha_list, accuracy_list, c="green", marker='*', label='alpha')#画label 1的散点图
plt.xlabel('alpha')# 设置X轴的标签为K-means
# plt.legend(loc=2)# 设置图标在左上角
plt.title("alpha_accuracy")
plt.show()plt.scatter(range(0,len(accuracy_list)), accuracy_list, c="green", marker='*')#画label 1的散点图
plt.xlabel('iter_num')# 设置X轴的标签为K-means
# plt.legend(loc=2)# 设置图标在左上角
plt.title("iter_num_accuracy")
plt.show()print("最终模型的分类准确率:", accuracy)
运行结果:
基于遗传算法的BP神经网络优化
代码如下:
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt # 导入matplotlib的库# 鸢尾花数据集加载
iris = load_iris()
X, y = iris.data, iris.target# 数据集划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 遗传算法参数
POPULATION_SIZE = 10
GENERATIONS = 50#迭代次数
MUTATION_RATE = 0.1#变异率# 初始化种群
def initialize_population(pop_size, layer_sizes):return [np.random.randint(1, 10, size=layer_sizes) for _ in range(pop_size)]# 适应度函数
params_list=[]
accuracy_list=[]
def fitness(network_params):params_list.append(network_params)print('network_params',network_params)clf = MLPClassifier(hidden_layer_sizes=network_params[0], activation='relu',alpha=network_params[1]/1000, learning_rate_init=network_params[1]/1000, max_iter=1000, random_state=42)clf.fit(X_train, y_train)predictions = clf.predict(X_test)accuracy_list.append(accuracy_score(y_test, predictions))return accuracy_score(y_test, predictions)# 选择
def selection(population, fitness_scores):return [population[i] for i in np.argsort(fitness_scores)[-POPULATION_SIZE:]]# 交叉
def crossover(parent1, parent2):print(parent1)child_size = len(parent1)print(child_size)crossover_point = np.random.randint(1, child_size - 1)child1 = np.concatenate((parent1[:crossover_point], parent2[crossover_point:]))child2 = np.concatenate((parent2[:crossover_point], parent1[crossover_point:]))return child1, child2# 变异
def mutate(child, mutation_rate, min_value=1, max_value=10):for i in range(len(child)):if np.random.rand() < mutation_rate:child[i] = np.random.randint(min_value, max_value)return child# 遗传算法主函数
def genetic_algorithm(X_train, y_train, X_test, y_test):layer_sizes = (3,) # population = initialize_population(POPULATION_SIZE, layer_sizes)print(population)for generation in range(GENERATIONS):fitness_scores = [fitness(ind) for ind in population]selected_population = selection(population, fitness_scores)new_population = []for i in range(0, POPULATION_SIZE, 2):parent1, parent2 = selected_population[i], selected_population[i+1]child1, child2 = crossover(parent1, parent2)child1 = mutate(child1, MUTATION_RATE)child2 = mutate(child2, MUTATION_RATE)new_population.extend([child1, child2])population = new_population# 打印当前最佳适应度best_fitness = max(fitness_scores)print(f"Generation {generation}: Best Fitness = {best_fitness}")# 返回最佳个体best_individual = population[np.argmax(fitness_scores)]return best_individual# 运行遗传算法
best_params = genetic_algorithm(X_train, y_train, X_test, y_test)# 使用最佳参数训练BP神经网络
clf = MLPClassifier(hidden_layer_sizes=tuple(best_params), max_iter=100, random_state=42)
clf.fit(X_train, y_train)hidden_layer_sizes_list=[]
alpha_list=[]
learning_rate_init_list=[]for para in params_list:hidden_layer_sizes_list.append(int(para[0]))alpha_list.append(para[1])learning_rate_init_list.append(para[2])#plt.scatter(hidden_layer_sizes_list, accuracy_list, c="red", marker='o', label='hidden_layer_size')#画label 0的散点图plt.xlabel('hidden_layer_size')# 设置X轴的标签为K-means
plt.ylabel('accuracy')
# plt.legend(loc=2)# 设置图标在左上角
plt.title("hidden_layer_size_accuracy")
plt.show()plt.scatter(learning_rate_init_list, accuracy_list, c="blue", marker='+', label='learning_rate')#画label 2的散点图
plt.xlabel('learning_rate')# 设置X轴的标签为K-means
# plt.legend(loc=2)# 设置图标在左上角
plt.title("learning_rate_accuracy")
plt.ylabel('accuracy')
plt.show()
plt.scatter(alpha_list, accuracy_list, c="green", marker='*', label='alpha')#画label 1的散点图
plt.xlabel('alpha')# 设置X轴的标签为K-means
# plt.legend(loc=2)# 设置图标在左上角
plt.title("alpha_accuracy")
plt.ylabel('accuracy')
plt.show()plt.scatter(range(0,len(accuracy_list)), accuracy_list, c="green", marker='*')#画label 1的散点图
plt.xlabel('iter_num')# 设置X轴的标签为K-means
# plt.legend(loc=2)# 设置图标在左上角
plt.title("iter_num_accuracy")
plt.ylabel('accuracy')
plt.show()# 测试神经网络
predictions = clf.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
print(f"Test Accuracy: {accuracy}")
运行结果:
总结
1.优化效果显著:实验结果表明,通过粒子群优化和遗传算法相结合的方法对BP神经网络的隐藏层数量、神经元数量以及其他超参数进行调整后,网络在多个标准数据集上的表现得到了显著提升。
2.算法优势互补:粒子群优化在全局搜索能力上表现突出,而遗传算法在局部搜索上更为精细。两者的结合充分利用了各自的优势,提高了算法的搜索效率和精度。
3.适应度函数的重要性:在本研究中,适应度函数的设计对于算法的性能至关重要。通过精心设计的适应度函数,可以更有效地引导算法搜索到最优解。
4.计算成本与性能的平衡:虽然结合算法提高了优化精度,但同时也增加了计算成本。未来的工作需要在计算效率和优化精度之间找到更好的平衡点。