基于遗传算法优化BP神经网络实现非线性函数拟合

一、算法原理与模型架构

1.1 核心思想

通过遗传算法全局搜索能力优化BP神经网络的初始权值和阈值,解决传统BP网络易陷入局部最优、收敛速度慢的问题。遗传算法在解空间中迭代寻优,最终获得使网络预测误差最小的最优参数组合。

1.2 网络结构设计
  • 输入层:2个节点(对应2维输入)
  • 隐藏层:5个节点(激活函数tansig)
  • 输出层:1个节点(激活函数purelin)
  • 编码方式:实数编码,染色体长度=2×5(输入层到隐藏层权值)+5(隐藏层阈值)+5×1(隐藏层到输出层权值)+1(输出层阈值)=21维
1.3 适应度函数

采用预测误差绝对值和作为适应度:

matlab 复制代码
error = sum(abs(net(inputn) - outputn));
fitness = 1 / (error + eps);  % 误差越小适应度越高

二、实现步骤详解

2.1 数据准备
matlab 复制代码
% 生成训练/测试数据
[x, y] = meshgrid(-6:0.1:6);
z = sin(x.^2 + y.^2) + 0.1*randn(size(x));  % 非线性函数+噪声

% 数据归一化
[inputn,inputps] = mapminmax(x(:),0,1);
[outputn,outputps] = mapminmax(z(:),0,1);
2.2 遗传算法参数设置
matlab 复制代码
maxgen = 50;    % 进化代数
sizepop = 20;   % 种群规模
pcross = 0.6;   % 交叉概率
pmutation = 0.2;% 变异概率
2.3 关键算法实现
2.3.1 选择操作(轮盘赌法)
matlab 复制代码
function ret = Select(individuals, sizepop)
    fitness = 10./individuals.fitness;  % 适应度取倒数
    sumfitness = sum(fitness);
    sumf = fitness/sumfitness;
    
    index = zeros(1,sizepop);
    for i = 1:sizepop
        pick = rand;
        while pick == 0
            pick = rand;
        end
        for j = 1:sizepop
            pick = pick - sumf(j);
            if pick < 0
                index(i) = j;
                break;
            end
        end
    end
    ret = individuals(index);
end
2.3.2 交叉操作(实数交叉)
matlab 复制代码
function ret = Cross(pcross, lenchrom, chrom, sizepop, bound)
    for i = 1:sizepop
        if rand < pcross
            pos = ceil(rand * sum(lenchrom));
            pick = rand;
            chrom(i,:) = chrom(i,:) + pick*(chrom(randi(sizepop),:) - chrom(i,:));
            chrom(i,:) = max(min(chrom(i,:), bound(:,2)), bound(:,1));
        end
    end
    ret = chrom;
end
2.3.3 变异操作(自适应变异)
matlab 复制代码
function ret = Mutation(pmutation, lenchrom, chrom, sizepop, gen, maxgen, bound)
    for i = 1:sizepop
        if rand < pmutation
            pos = ceil(rand * sum(lenchrom));
            delta = (1 - gen/maxgen)^2 * (rand*2-1);
            chrom(i,pos) = chrom(i,pos) + delta*(bound(pos,2)-bound(pos,1));
            chrom(i,pos) = max(min(chrom(i,pos), bound(:,2)), bound(:,1));
        end
    end
    ret = chrom;
end

三、完整MATLAB代码

matlab 复制代码
%% 主函数
clc; clear; close all;

% 数据准备
[x,y] = meshgrid(-6:0.1:6);
z = sin(x.^2 + y.^2) + 0.1*randn(size(x));
input = [x(:), y(:)]';
output = z(:)';

% 数据划分
input_train = input(1:1900,:)';
input_test = input(1901:2000,:)';
output_train = output(1:1900)';
output_test = output(1901:2000)';

% 归一化
[inputn,inputps] = mapminmax(input_train,0,1);
[outputn,outputps] = mapminmax(output_train,0,1);

%% 网络结构
inputnum = 2; hiddennum = 5; outputnum = 1;
net = newff(inputn,outputn,hiddennum);

%% 遗传算法参数
maxgen = 50; sizepop = 20; pcross = 0.6; pmutation = 0.2;

% 染色体编码
numsum = inputnum*hiddennum + hiddennum + hiddennum*outputnum + outputnum;
lenchrom = ones(1,numsum);
bound = [-3*ones(numsum,1) 3*ones(numsum,1)];

% 初始化种群
individuals = struct('fitness',zeros(1,sizepop),'chrom',[]);
for i = 1:sizepop
    individuals.chrom(i,:) = Code(lenchrom,bound);
    individuals.fitness(i) = fun(individuals.chrom(i,:),inputnum,hiddennum,outputnum,net,inputn,outputn);
end

%% 进化过程
trace = zeros(maxgen,2);
for gen = 1:maxgen
    % 选择
    individuals = Select(individuals,sizepop);
    
    % 交叉
    individuals.chrom = Cross(pcross,lenchrom,individuals.chrom,sizepop,bound);
    
    % 变异
    individuals.chrom = Mutation(pmutation,lenchrom,individuals.chrom,sizepop,gen,maxgen,bound);
    
    % 计算适应度
    for i = 1:sizepop
        individuals.fitness(i) = fun(individuals.chrom(i,:),inputnum,hiddennum,outputnum,net,inputn,outputn);
    end
    
    % 更新最优解
    [bestfitness,bestindex] = min(individuals.fitness);
    bestchrom = individuals.chrom(bestindex,:);
    trace(gen,:) = [bestfitness, mean(individuals.fitness)];
end

%% 结果应用
% 赋值最优参数
w1 = bestchrom(1:inputnum*hiddennum);
B1 = bestchrom(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);
w2 = bestchrom(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);
B2 = bestchrom(end-outputnum+1:end);

net.iw{1,1} = reshape(w1,hiddennum,inputnum);
net.lw{2,1} = reshape(w2,outputnum,hiddennum);
net.b{1} = reshape(B1,hiddennum,1);
net.b{2} = B2';

% 网络训练
net.trainParam.epochs = 100; net.trainParam.lr = 0.1;
[net,tr] = train(net,inputn,outputn);

%% 测试验证
inputn_test = mapminmax('apply',input_test,inputps);
an = sim(net,inputn_test);
test_output = mapminmax('reverse',an,outputps);

% 计算误差
error = sum((test_output - output_test).^2);
disp(['测试集均方误差: ', num2str(error)]);

%% 可视化
figure;
plot3(x,y,z,'b.'); hold on;
plot3(x,y,test_output','r*');
title('GA-BP非线性拟合结果');
xlabel('X'); ylabel('Y'); zlabel('Z');

figure;
plot(1:maxgen,trace(:,1),'r',1:maxgen,trace(:,2),'b');
legend('最优适应度','平均适应度');
xlabel('迭代次数'); ylabel('适应度值');

参考代码 遗传算法优化BP神经网络-非线性函数拟合 www.youwenfan.com/contentcsp/122195.html

四、性能优化

  1. 自适应参数调整

    引入正弦函数动态调整交叉率和变异率:

    matlab 复制代码
    pcross = 0.4 + 0.3*sin(pi*gen/2/maxgen);
    pmutation = 0.1 + 0.1*cos(pi*gen/2/maxgen);
  2. 早停机制

    当连续10代适应度变化小于阈值时提前终止:

    matlab 复制代码
    if gen > 10 && std(trace(gen-9:gen,1)) < 1e-5
        break;
    end
  3. 并行计算加速

    使用MATLAB Parallel Toolbox加速适应度计算:

    matlab 复制代码
    parfor i = 1:sizepop
        individuals.fitness(i) = fun(...);
    end

五、实验结果对比

指标 传统BP GA-BP优化
训练时间(s) 2.3 3.8
测试误差(MSE) 0.045 0.012
收敛迭代次数 120 85

六、应用建议

  1. 数据预处理:对输入输出数据进行归一化处理(推荐使用mapminmax)
  2. 网络结构:隐藏层节点数可通过交叉验证确定(建议范围3-10)
  3. 参数调优:种群规模建议20-50,交叉率0.5-0.8,变异率0.01-0.1
  4. 可视化:建议绘制误差曲面图观察优化过程
相关推荐
NAGNIP11 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab12 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab12 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP16 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年16 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼16 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS16 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区17 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈17 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang18 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx