基于遗传算法的BP神经网络优化算法 | StriveZs的博客

基于遗传算法的BP神经网络优化算法

BP网络是一类多层的前馈神经网络,它的名字源于在网络训练的过程中,调整网络的权值的算法是误差反向传播的学习算法,即为BP学习算法。 它的学习规则是使用最速下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。BP神经网络模型拓扑结构包括输入层(input)、隐层(hide layer)和输出层(output layer)。   对于遗传算法的基本要素包含:染色体编码方法、适应度函数、遗传操作和运行参数。

  • 染色体编码方法是指个体的编码方法,目前包括二进制法、实数法等。二进制法是指把个体编码成为一个二进制串,实数法是指把个体编码成为一个实数。
  • 适应度函数是指根据进化目标编写的计算个体适应度值的函数,通过适应度函数计算每个个体的适应度值,提供给选择算子进行选择。
  • 遗传操作是指选择操作、交叉操作和变异操作。
  • 运行参数是遗传算法在初始化时确定的参数,主要包括群体大小M、遗传代数G、交叉概率Pl和变异概率Pm。

案例描述: 以某拖拉机的齿轮箱为工程背景,使用基于遗传算法的BP神经网络进行齿轮箱故障的诊断。统计表明,齿轮箱故障中60%左右都是有齿轮箱故障导致的,所以这里之研究齿轮的故障,这里选取频域中的几个特征量。频域中齿轮故障比较明显的是在啮合频率处的边缘带上。所以在频域特征信号的提取中选取了在2、4、6挡时,在1、2、3轴的边频带族fs±nfz处的幅值Ai,j1、Ai,j2和Ai,j3,其中fs为齿轮的啮合频率,fz为轴的转频,n=1,2,3,,i=2,4,6表示档位j=1,2,3表示轴的序号,由于在2轴和3轴上有两对齿轮啮合,所以1、2分别表示两个啮合频率。这样,网络的输入就是一个15维的向量。因为这些数据具有不同的量纲和量级所以在输入神经网络之前首先进行归一化处理。 齿轮箱状态数据样本: 从表中可以看出齿轮状态分为三种故障模式,因此可以采用如下的形式来表示输出。 无故障(1,0,0)、齿根裂纹(0,1,0)、断齿(0,0,1) 为了对训练好的网络进行测试,再增加三组测试数据 测试样本数据 算法流程: 因为遗传算法优化参数是BP神经网络的初始权值和阙值,只要网络结构已知,权值和阙值的个数就已知了。   神经元阙值介绍:阙值为一个范围,当外界的某个值超过阙值,就会引起某一变化,不超过阙值,则不会引起变化,一般输入层是没有阙值的因为它只负责处理数据,阙值一般在隐含层和输出层等处理数据的层数有。   神经网络算法实现:

  • 网络创建

BP网络结构的确定有以下两条比较重要的指导原则。

  • 对于一般的模式识别问题,三层网络可以很好地解决问题。
  • 在三层网络中,隐含层神经网络个数n2和输入层神经元个数n1之间有近似关系:

n2 = 2 * n1 +1 本案例中,由于样本有15个输入参数,3个输出参数,所以这里n2取值为31,设置的BP神经网络 结构为15-31-3,即输入层有15个节点,隐含层有31个节点,输出层有3个节点,因此总有15*31+31*3=558个权值(边),31+3=34个阙值,所以遗传算法优化参数的个数为558+34=592.使用训练数据进行网络训练,使用测试数据对训练后的网络进行测试。把测试样本的测试误差的范数作为衡量网络的一个泛化能力,再通过误差范数计算个体的适应度值,个体的误差范数越小,个体适应度值越大,该个体越优。 神经网络的隐含层神经元的传递函数采用S型正切函数tansig(),输出层神经元的传递函数采用S型对数函数logsig(),这是由于输出模式为0-1,正好满足网络的输出要求。假定输入样本矩阵为P,创建网络可以使用如下代码: Net=newff(minmax(P),[31,3],(‘tansig’,’logsig’),‘trainlm’)

  • 网络训练和测试

网络训练是一个不断修正权值和阙值的过程,使得网络的输出误差越来越小。   遗传算法实现 遗传算法优化BP神经网络是用遗传算法来优化BP神经网络的初始权重值和阙值,使优化后的BP神经网络能够更好地进行样本预测。

  • 种群初始化

个体编码使用二进制编码,每个个体均为一个二进制串,由输入层与隐含层连接权值、隐含层阙值与输出层连接权值、输出层阙值四部分组成,每个阙值和权值都使用二进制编码,将所有权值和阙值的编码连接起来即为一个个体的编码。 465+31+93+3=592,假设权值和阙值的编码均为10位二进制数,那么个体的总编码长度为5920位。前4650位为输入层与隐含层连接权值编码;45614960位为隐含层阙值编码;49615890位为隐含层与输出层连接权值编码;5890~5920位为输出层阙值编码。

  • 适应度函数

适应度函数采用排序的适应度分配函数:FitnV = ranking(obj),其中obj为目标函数的目标值。

  • 选择算子

采用随机遍历抽样(sus 轮盘赌算法)选择

  • 交叉算子

采用最简单的单点交叉算子

  • 变异算子

以一定的概率产生变异基因树,用随机方法选择发生变异的基因,如果所选的基因的编码为1,则变为0,反之。   遗传算法相关参数设定: 训练网络:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
function rep = BPfun(x,P,T,hiddennum,P\_test,T\_test)
%训练与测试BP网络
%输入
%x 一个个体的初始权值和阙值
%P 训练样本输入
%T 训练样本输出
% hiddennum:隐含层神经元数
% P_test 测试样本输入
% T_test 测试样本输出
% rep 预测样本的预测误差的范数

inputnum = size(P,1); %得到输入层神经元的个数
outputnum = size(T,1); %得到输出层神经元的个数

%建立BP网络
net = newff(minmax(P),\[hiddennum,outputnum\],{'tansig','logsig'},'trainlm');

%设置网络参数:训练次数为1000,训练目标为0.01,学习速率为0.1
net.trainParam.epochs = 1000;
net.trainParam.goal = 0.01;
LP.lr = 0.1;
net.trainParam.show = NaN;
net.trainParam.showwindow = false; %使用高版本matlab不显示图形框

%设置BP网络的初始权值和阙值
w1num = inputnum * hiddennum; %计算输入层到隐含层的权值个数
w2num = outputnum * hiddennum; %计算隐含层到输出层的权值个数
%按照编码规则分别给权值和阙值赋值(实质为解码得到权值和阙值)
w1 = x(1:w1num); %初始输入层到隐含层的权值
B1 = x(w1num+1:w1num+hiddennum); %隐含层神经元阙值
w2=x(w1num + hiddennum + 1:w1num + hiddennum + w2num); %初始隐含层到输出层的权值
B2=x(w1num + hiddennum + w2num + 1:w1num + hiddennum + w2num + outputnum); %输出层阙值
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} = reshape(B2,outputnum,1); %将输出层的阙值转换为对应的格式
%训练网络
net = train(net,P,T);
%测试网络
Y = sim(net,P_test);
rep = norm(Y-T_test);

**主函数:**

clc
clear all
close all
%%加载神经网络的训练样本,测试样本每列一个样本,输入P,输出T
%样本数据就是前面问题中列出的数据
P1 = \[0.2286 0.1292 0.0720 0.1592 0.1335 0.0733 0.1159 0.0940 0.0522 0.1345 0.0090 0.1260 0.3619 0.0690 0.1828 0.2090 0.0947 0.1393 0.1387 0.2558 0.0900 0.0771 0.0882 0.0393 0.1430 0.0126 0.1670 0.2450 0.0508 0.1328 0.0442 0.0880 0.1147 0.0563 0.3347 0.1150 0.1453 0.0429 0.1818 0.0378 0.0092 0.2251 0.1516 0.0858 0.0670 0.2603 0.1715 0.0702 0.2711 0.1491 0.1330 0.0986 0.1911 0.2545 0.0871 0.0060 0.1793 0.1002 0.0789 0.0909 0.3690 0.2222 0.0562 0.5157 0.1872 0.1614 0.1425 0.1506 0.1310 0.0500 0.0078 0.0348 0.0451 0.0707 0.0880 0.0359 0.1149 0.1230 0.5460 0.1977 0.1248 0.0624 0.0832 0.1640 0.1002 0.0059 0.1503 0.1837 0.1295 0.0700 0.1759 0.2347 0.1829 0.1811 0.2922 0.0655 0.0774 0.0227 0.2056 0.0925 0.0078 0.1852 0.3501 0.1680 0.2668 0.0724 0.1909 0.1340 0.2409 0.2842 0.0450 0.0824 0.1064 0.1909 0.1586 0.0116 0.1698 0.3644 0.2718 0.2494 0.2634 0.2258 0.1165 0.1154 0.1074 0.0657 0.0610 0.2623 0.2588 0.1155 0.0050 0.0978 0.1511 0.2273 0.3220\];
T1 = \[2 2 2 1 1 1 0 0 0\];%1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1
P1_test = \[0.2101 0.0950 0.1298 0.1359 0.2601 0.1001 0.0753 0.0890 0.0389 0.1451 0.0128 0.1590 0.2452 0.0512 0.1319 0.2593 0.1800 0.0711 0.2801 0.1501 0.1298 0.1001 0.1891 0.2531 0.0875 0.0058 0.1803 0.0992 0.0802 0.1002 0.2599 0.2235 0.1201 0.0071 0.1102 0.0683 0.0621 0.2597 0.2602 0.1167 0.0048 0.1002 0.1521 0.2881 0.3205\];
T1_test = \[2 1 0\];%1 0 0 0 1 0 0 0 1
P = reshape(P1,9,15);
T = reshape(T1,9,1);
P\_test = reshape(P1\_test,3,15);
T\_test = reshape(T1\_test,3,1);

%设置隐含层神经元的个数
hiddennum = 31;
%设置输入向量的最大值和最小值
threshold = \[0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1\];
inputnum = size(P,1); %输入层神经元个数
outputnum = size(T,1); %输出层神经元个数
w1num = inputnum * hiddennum; %计算输入层到隐含层的权值个数
w2num = outputnum * hiddennum; %计算隐含层到输出层的权值个数
N = w1num + hiddennum + w2num + outputnum; %总的变量个数

%%定义遗传算法参数
Nind = 40; %定义种群大小
MaxGen = 50; %最大遗传代数
Lind = 10; %每个个体的长度
GGAP = 0.95; %代沟
pl = 0.7; %交叉概率
pm = 0.01; %变异概率
trace = zeros(N+1,MaxGen); %寻优结果的初始值 为N+1的原因是最后一位用来存储对优值

%%构建区域描述器方便将个体基因转化为实值
FieldD = \[repmat(Lind,1,N);repmat(\[-0.5;0.5\],1,N);repmat(\[1;0;1;1\],1,N)\]; %难点
Chrom = crtbp(Nind,Lind*N); %创建任意离散的随机种群

%%优化
gen = 0; %种群迭代计数器
X = bs2rv(Chrom,FieldD); %将初始种群的基因转换为十进制
ObjV = Objfun(X,P,T,hiddennum,P\_test,T\_test); %计算目标值
while gen<MaxGen
fprintf('%d\\n',gen);
FitnV = ranking(ObjV); %计算适应度值
SelCh = select('sus',Chjrom,FitnV,GGAP); %采用轮盘赌算法选择下一代
SelCh = recombin('xovsp',SelCh,pl); %进行交叉
SelCh = mut(SelCh,pm); %进行变异
X = bs2rv(SelCh,FieldD); %将子代的二进制转换为十进制
ObjVSelCh = Objfun(X,P,T,hiddennum,P\_test,T\_test); %计算子代的目标函数值
\[Chrom,ObjV\] = reins(Chrom,SelCh,1,1,ObjV,ObjVSelCh); %将子代插入到父代中,得到新的种群
X = bs2rv(Chrom,FieldD); %将新的种群的二进制转换为十进制
gen = gen +1;
%获得每一代的最优解及其序号,Y为最优解,I为个体的序号
\[Y,I\] = min(ObjV);
trace(1:N,gen) = X(I,:);
trace(end,gen) = Y;
end
%%画出图像
figure(1);
plot(1:MaxGen,trace(end,:));
grid on
xlabel('遗传代数');
ylabel('误差变化');
besxtX = trace(1:end-1,end);
bestErr = trace(end,end);
fprintf('最优初始权值和阙值:\\nX=',num2str(bestX),'\\n最小误差err=',num2str(bestErr),'\\n');

调用神经网络的函数:
function rep = Objfun(X,P,T,hiddennum,P\_test,T\_test)
%用来分别求解种群中各个个体的目标值
% X 所有个体的初始权值和阙值
%P 训练样本输入
%T 训练样本输出
% hiddennum:隐含层神经元数
% P_test 测试样本输入
% T_test 测试样本输出
% Obj 所有个体预测样本预测误差的范数

\[M,N\] = size(X);
Obj = zeros(M,1);
for i = 1:M
Obj(i) = BPfun(X(i,:),P,T,hiddennum,P\_test,T\_test);
end
StriveZs wechat
Hobby lead  creation, technology change world.
  • Post author: StriveZs
  • Post link: 1488.html
  • Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.