使用思维进化算法(MEA)优化BP神经网络进行非线性函数拟合的步骤和代码:
步骤解析
问题定义
使用MEA优化BP的初始权重,解决非线性函数(如sin(x))拟合问题,克服BP易陷入局部最优的缺陷。BP神经网络结构
- 输入层:1节点(x)
- 隐藏层:10节点(可根据问题调整)
- 输出层:1节点(sin(x))
MEA优化流程
- 编码:将BP的权重和偏置编码为染色体。
- 适应度:用BP网络的均方误差(MSE)作为适应度。
- 进化操作:竞争、交流、变异生成新种群。
Python代码实现
import numpy as np
import matplotlib.pyplot as plt
# 生成数据
np.random.seed(42)
X = np.linspace(-np.pi, np.pi, 100).reshape(-1, 1)
Y = np.sin(X) + 0.1 * np.random.randn(100, 1)
# BP神经网络类
class BP_Net:
def __init__(self, input_size, hidden_size, output_size):
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
# 初始化权重和偏置
self.W1 = np.random.randn(input_size, hidden_size)
self.b1 = np.random.randn(hidden_size)
self.W2 = np.random.randn(hidden_size, output_size)
self.b2 = np.random.randn(output_size)
def forward(self, X):
self.z1 = np.dot(X, self.W1) + self.b1
self.a1 = np.tanh(self.z1)
self.z2 = np.dot(self.a1, self.W2) + self.b2
return self.z2
def mse_loss(self, y_true, y_pred):
return np.mean((y_true - y_pred)**2)
# 思维进化算法
class MEA:
def __init__(self, pop_size, mutation_rate, net_structure, X, Y, max_iter=50):
self.pop_size = pop_size
self.mutation_rate = mutation_rate
self.net_structure = net_structure
self.X = X
self.Y = Y
self.max_iter = max_iter
self.population = self.init_population()
def init_population(self):
# 每个个体是[weights1, bias1, weights2, bias2]
pop = []
input_size, hidden_size, output_size = self.net_structure
for _ in range(self.pop_size):
W1 = np.random.randn(input_size, hidden_size)
b1 = np.random.randn(hidden_size)
W2 = np.random.randn(hidden_size, output_size)
b2 = np.random.randn(output_size)
pop.append([W1, b1, W2, b2])
return pop
def fitness(self, individual):
# 计算适应度(MSE)
net = BP_Net(*self.net_structure)
net.W1, net.b1, net.W2, net.b2 = individual
y_pred = net.forward(self.X)
return net.mse_loss(self.Y, y_pred)
def evolve(self):
for iteration in range(self.max_iter):
# 计算适应度并排序
fitnesses = [self.fitness(ind) for ind in self.population]
sorted_indices = np.argsort(fitnesses)
self.population = [self.population[i] for i in sorted_indices]
# 竞争:保留前10%优秀个体
elite_size = int(0.1 * self.pop_size)
new_pop = self.population[:elite_size]
# 交流与变异
while len(new_pop) < self.pop_size:
parent1, parent2 = np.random.choice(self.population[:50], 2, replace=False)
child = self.crossover(parent1, parent2)
child = self.mutate(child)
new_pop.append(child)
self.population = new_pop
print(f"Iter {iteration}, Best Fitness: {fitnesses[0]:.4f}")
# 返回最优个体
best_idx = np.argmin(fitnesses)
return self.population[best_idx]
def crossover(self, parent1, parent2):
# 单点交叉
child = []
for p1, p2 in zip(parent1, parent2):
mask = np.random.rand(*p1.shape) > 0.5
c = p1.copy()
c[mask] = p2[mask]
child.append(c)
return child
def mutate(self, individual):
# 随机变异
mutated = []
for layer in individual:
if np.random.rand() < self.mutation_rate:
mutated.append(layer + np.random.randn(*layer.shape) * 0.1)
else:
mutated.append(layer)
return mutated
# 参数设置
input_size = 1
hidden_size = 10
output_size = 1
net_structure = (input_size, hidden_size, output_size)
mea = MEA(pop_size=50, mutation_rate=0.1, net_structure=net_structure, X=X, Y=Y, max_iter=20)
# 运行MEA优化
best_individual = mea.evolve()
# 使用最优权重训练BP网络
best_net = BP_Net(*net_structure)
best_net.W1, best_net.b1, best_net.W2, best_net.b2 = best_individual
# 完整训练BP网络(可调整epochs)
epochs = 1000
lr = 0.01
for _ in range(epochs):
y_pred = best_net.forward(X)
error = best_net.mse_loss(Y, y_pred)
dW2 = np.dot(best_net.a1.T, (y_pred - Y)) / len(X)
db2 = np.mean(y_pred - Y, axis=0)
dW1 = np.dot(X.T, np.dot((y_pred - Y), best_net.W2.T) * (1 - best_net.a1**2)) / len(X)
db1 = np.dot((y_pred - Y), best_net.W2.T) * (1 - best_net.a1**2)
best_net.W2 -= lr * dW2
best_net.b2 -= lr * db2
best_net.W1 -= lr * dW1
best_net.b1 -= lr * db1
# 绘制结果
plt.scatter(X, Y, label='Data')
plt.scatter(X, best_net.forward(X), label='Prediction', color='red')
plt.legend()
plt.show()
matlab实现 思维进化算法优化BP神经网络——非线性函数拟合
关键说明
- MEA优化:通过竞争保留精英个体,交流操作混合优秀基因,变异增加多样性。
- BP训练:使用MEA得到的最优初始权重,再进行梯度下降微调。
- 效果验证:对比随机初始化和MEA初始化的BP网络,观察拟合效果提升。
改进方向
- 调整MEA参数(种群大小、变异率)和网络结构(隐藏层节点数)。
- 引入自适应学习率或动量法加速BP收敛。
- 使用更复杂的数据集验证泛化能力。